From e9fab29f2df0670650b4b844f2eff08873e8d74f Mon Sep 17 00:00:00 2001 From: 0xkenj1 Date: Wed, 24 Jul 2024 17:10:21 -0300 Subject: [PATCH 1/7] feat: base class for protocol provider & getCurrentEpoch --- packages/automated-dispute/.prettierignore | 3 + packages/automated-dispute/package.json | 22 + .../src/abis/epochManager.ts | 355 +++++ packages/automated-dispute/src/abis/index.ts | 2 + packages/automated-dispute/src/abis/oracle.ts | 1403 +++++++++++++++++ packages/automated-dispute/src/constants.ts | 1 + packages/automated-dispute/src/index.ts | 1 + .../automated-dispute/src/protocolProvider.ts | 77 + packages/automated-dispute/src/types/index.ts | 2 + .../src/types/protocolProvider.ts | 5 + .../tests/protocolProvider.spec.ts | 90 ++ .../automated-dispute/tsconfig.build.json | 9 + packages/automated-dispute/tsconfig.json | 4 + packages/automated-dispute/vitest.config.ts | 22 + packages/blocknumber/package.json | 2 +- pnpm-lock.yaml | 139 ++ 16 files changed, 2136 insertions(+), 1 deletion(-) create mode 100644 packages/automated-dispute/.prettierignore create mode 100644 packages/automated-dispute/package.json create mode 100644 packages/automated-dispute/src/abis/epochManager.ts create mode 100644 packages/automated-dispute/src/abis/index.ts create mode 100644 packages/automated-dispute/src/abis/oracle.ts create mode 100644 packages/automated-dispute/src/constants.ts create mode 100644 packages/automated-dispute/src/index.ts create mode 100644 packages/automated-dispute/src/protocolProvider.ts create mode 100644 packages/automated-dispute/src/types/index.ts create mode 100644 packages/automated-dispute/src/types/protocolProvider.ts create mode 100644 packages/automated-dispute/tests/protocolProvider.spec.ts create mode 100644 packages/automated-dispute/tsconfig.build.json create mode 100644 packages/automated-dispute/tsconfig.json create mode 100644 packages/automated-dispute/vitest.config.ts diff --git a/packages/automated-dispute/.prettierignore b/packages/automated-dispute/.prettierignore new file mode 100644 index 0000000..3da65e6 --- /dev/null +++ b/packages/automated-dispute/.prettierignore @@ -0,0 +1,3 @@ +# Generated files +node_modules +dist \ No newline at end of file diff --git a/packages/automated-dispute/package.json b/packages/automated-dispute/package.json new file mode 100644 index 0000000..aa463d5 --- /dev/null +++ b/packages/automated-dispute/package.json @@ -0,0 +1,22 @@ +{ + "name": "@ebo-agent/automated-dispute", + "version": "1.0.0", + "description": "", + "main": "index.ts", + "type": "module", + "scripts": { + "build": "tsc -p tsconfig.build.json", + "lint": "eslint .", + "lint:fix": "pnpm lint --fix", + "format": "prettier --check .", + "format:fix": "prettier --write .", + "test": "vitest run", + "coverage": "vitest run --coverage" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "viem": "2.17.11" + } +} diff --git a/packages/automated-dispute/src/abis/epochManager.ts b/packages/automated-dispute/src/abis/epochManager.ts new file mode 100644 index 0000000..0d963b6 --- /dev/null +++ b/packages/automated-dispute/src/abis/epochManager.ts @@ -0,0 +1,355 @@ +export const epochManagerAbi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "nameHash", + type: "bytes32", + }, + { + indexed: false, + internalType: "address", + name: "contractAddress", + type: "address", + }, + ], + name: "ContractSynced", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "epoch", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "epochLength", + type: "uint256", + }, + ], + name: "EpochLengthUpdate", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "epoch", + type: "uint256", + }, + { + indexed: false, + internalType: "address", + name: "caller", + type: "address", + }, + ], + name: "EpochRun", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "param", + type: "string", + }, + ], + name: "ParameterUpdated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "controller", + type: "address", + }, + ], + name: "SetController", + type: "event", + }, + { + inputs: [ + { + internalType: "contract IGraphProxy", + name: "_proxy", + type: "address", + }, + ], + name: "acceptProxy", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IGraphProxy", + name: "_proxy", + type: "address", + }, + { + internalType: "bytes", + name: "_data", + type: "bytes", + }, + ], + name: "acceptProxyAndCall", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_block", + type: "uint256", + }, + ], + name: "blockHash", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "blockNum", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "controller", + outputs: [ + { + internalType: "contract IController", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "currentEpoch", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "currentEpochBlock", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "currentEpochBlockSinceStart", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "epochLength", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_epoch", + type: "uint256", + }, + ], + name: "epochsSince", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "epochsSinceUpdate", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_controller", + type: "address", + }, + { + internalType: "uint256", + name: "_epochLength", + type: "uint256", + }, + ], + name: "initialize", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "isCurrentEpochRun", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "lastLengthUpdateBlock", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "lastLengthUpdateEpoch", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "lastRunEpoch", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "runEpoch", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_controller", + type: "address", + }, + ], + name: "setController", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_epochLength", + type: "uint256", + }, + ], + name: "setEpochLength", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "syncAllContracts", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; diff --git a/packages/automated-dispute/src/abis/index.ts b/packages/automated-dispute/src/abis/index.ts new file mode 100644 index 0000000..b4a23ae --- /dev/null +++ b/packages/automated-dispute/src/abis/index.ts @@ -0,0 +1,2 @@ +export * from "./oracle.js"; +export * from "./epochManager.js"; diff --git a/packages/automated-dispute/src/abis/oracle.ts b/packages/automated-dispute/src/abis/oracle.ts new file mode 100644 index 0000000..81a3e94 --- /dev/null +++ b/packages/automated-dispute/src/abis/oracle.ts @@ -0,0 +1,1403 @@ +export const oracleAbi = [ + { + inputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + }, + ], + type: "error", + name: "Oracle_AlreadyFinalized", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + }, + ], + type: "error", + name: "Oracle_CannotEscalate", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + }, + ], + type: "error", + name: "Oracle_CannotResolve", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_responseId", + type: "bytes32", + }, + ], + type: "error", + name: "Oracle_FinalizableResponseExists", + }, + { inputs: [], type: "error", name: "Oracle_InvalidDisputeBody" }, + { + inputs: [ + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + }, + ], + type: "error", + name: "Oracle_InvalidDisputeId", + }, + { + inputs: [], + type: "error", + name: "Oracle_InvalidFinalizedResponse", + }, + { inputs: [], type: "error", name: "Oracle_InvalidRequestBody" }, + { inputs: [], type: "error", name: "Oracle_InvalidResponseBody" }, + { + inputs: [ + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + }, + ], + type: "error", + name: "Oracle_NoResolutionModule", + }, + { + inputs: [{ internalType: "address", name: "_caller", type: "address" }], + type: "error", + name: "Oracle_NotDisputeOrResolutionModule", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_responseId", + type: "bytes32", + }, + ], + type: "error", + name: "Oracle_ResponseAlreadyDisputed", + }, + { + inputs: [ + { + internalType: "address", + name: "_caller", + type: "address", + indexed: true, + }, + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + indexed: true, + }, + { + internalType: "uint256", + name: "_blockNumber", + type: "uint256", + indexed: false, + }, + ], + type: "event", + name: "DisputeEscalated", + anonymous: false, + }, + { + inputs: [ + { + internalType: "address", + name: "_caller", + type: "address", + indexed: true, + }, + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + indexed: true, + }, + { + internalType: "uint256", + name: "_blockNumber", + type: "uint256", + indexed: false, + }, + ], + type: "event", + name: "DisputeResolved", + anonymous: false, + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + indexed: true, + }, + { + internalType: "enum IOracle.DisputeStatus", + name: "_status", + type: "uint8", + indexed: false, + }, + { + internalType: "uint256", + name: "_blockNumber", + type: "uint256", + indexed: false, + }, + ], + type: "event", + name: "DisputeStatusUpdated", + anonymous: false, + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + indexed: true, + }, + { + internalType: "bytes32", + name: "_responseId", + type: "bytes32", + indexed: true, + }, + { + internalType: "address", + name: "_caller", + type: "address", + indexed: true, + }, + { + internalType: "uint256", + name: "_blockNumber", + type: "uint256", + indexed: false, + }, + ], + type: "event", + name: "OracleRequestFinalized", + anonymous: false, + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + indexed: true, + }, + { + internalType: "struct IOracle.Request", + name: "_request", + type: "tuple", + components: [ + { internalType: "uint96", name: "nonce", type: "uint96" }, + { + internalType: "address", + name: "requester", + type: "address", + }, + { + internalType: "address", + name: "requestModule", + type: "address", + }, + { + internalType: "address", + name: "responseModule", + type: "address", + }, + { + internalType: "address", + name: "disputeModule", + type: "address", + }, + { + internalType: "address", + name: "resolutionModule", + type: "address", + }, + { + internalType: "address", + name: "finalityModule", + type: "address", + }, + { + internalType: "bytes", + name: "requestModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "responseModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "disputeModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "resolutionModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "finalityModuleData", + type: "bytes", + }, + ], + indexed: false, + }, + { + internalType: "bytes32", + name: "_ipfsHash", + type: "bytes32", + indexed: false, + }, + { + internalType: "uint256", + name: "_blockNumber", + type: "uint256", + indexed: false, + }, + ], + type: "event", + name: "RequestCreated", + anonymous: false, + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_responseId", + type: "bytes32", + indexed: true, + }, + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + indexed: true, + }, + { + internalType: "struct IOracle.Dispute", + name: "_dispute", + type: "tuple", + components: [ + { + internalType: "address", + name: "disputer", + type: "address", + }, + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "responseId", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + ], + indexed: false, + }, + { + internalType: "uint256", + name: "_blockNumber", + type: "uint256", + indexed: false, + }, + ], + type: "event", + name: "ResponseDisputed", + anonymous: false, + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + indexed: true, + }, + { + internalType: "bytes32", + name: "_responseId", + type: "bytes32", + indexed: true, + }, + { + internalType: "struct IOracle.Response", + name: "_response", + type: "tuple", + components: [ + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + ], + indexed: false, + }, + { + internalType: "uint256", + name: "_blockNumber", + type: "uint256", + indexed: false, + }, + ], + type: "event", + name: "ResponseProposed", + anonymous: false, + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + }, + { internalType: "address", name: "_module", type: "address" }, + ], + stateMutability: "view", + type: "function", + name: "allowedModule", + outputs: [{ internalType: "bool", name: "_allowedModule", type: "bool" }], + }, + { + inputs: [ + { + internalType: "struct IOracle.Request", + name: "_request", + type: "tuple", + components: [ + { internalType: "uint96", name: "nonce", type: "uint96" }, + { + internalType: "address", + name: "requester", + type: "address", + }, + { + internalType: "address", + name: "requestModule", + type: "address", + }, + { + internalType: "address", + name: "responseModule", + type: "address", + }, + { + internalType: "address", + name: "disputeModule", + type: "address", + }, + { + internalType: "address", + name: "resolutionModule", + type: "address", + }, + { + internalType: "address", + name: "finalityModule", + type: "address", + }, + { + internalType: "bytes", + name: "requestModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "responseModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "disputeModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "resolutionModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "finalityModuleData", + type: "bytes", + }, + ], + }, + { + internalType: "bytes32", + name: "_ipfsHash", + type: "bytes32", + }, + ], + stateMutability: "nonpayable", + type: "function", + name: "createRequest", + outputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + }, + ], + }, + { + inputs: [ + { + internalType: "struct IOracle.Request[]", + name: "_requestsData", + type: "tuple[]", + components: [ + { internalType: "uint96", name: "nonce", type: "uint96" }, + { + internalType: "address", + name: "requester", + type: "address", + }, + { + internalType: "address", + name: "requestModule", + type: "address", + }, + { + internalType: "address", + name: "responseModule", + type: "address", + }, + { + internalType: "address", + name: "disputeModule", + type: "address", + }, + { + internalType: "address", + name: "resolutionModule", + type: "address", + }, + { + internalType: "address", + name: "finalityModule", + type: "address", + }, + { + internalType: "bytes", + name: "requestModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "responseModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "disputeModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "resolutionModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "finalityModuleData", + type: "bytes", + }, + ], + }, + { + internalType: "bytes32[]", + name: "_ipfsHashes", + type: "bytes32[]", + }, + ], + stateMutability: "nonpayable", + type: "function", + name: "createRequests", + outputs: [ + { + internalType: "bytes32[]", + name: "_batchRequestsIds", + type: "bytes32[]", + }, + ], + }, + { + inputs: [{ internalType: "bytes32", name: "_id", type: "bytes32" }], + stateMutability: "view", + type: "function", + name: "disputeCreatedAt", + outputs: [ + { + internalType: "uint128", + name: "_disputeCreatedAt", + type: "uint128", + }, + ], + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_responseId", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + name: "disputeOf", + outputs: [ + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + }, + ], + }, + { + inputs: [ + { + internalType: "struct IOracle.Request", + name: "_request", + type: "tuple", + components: [ + { internalType: "uint96", name: "nonce", type: "uint96" }, + { + internalType: "address", + name: "requester", + type: "address", + }, + { + internalType: "address", + name: "requestModule", + type: "address", + }, + { + internalType: "address", + name: "responseModule", + type: "address", + }, + { + internalType: "address", + name: "disputeModule", + type: "address", + }, + { + internalType: "address", + name: "resolutionModule", + type: "address", + }, + { + internalType: "address", + name: "finalityModule", + type: "address", + }, + { + internalType: "bytes", + name: "requestModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "responseModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "disputeModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "resolutionModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "finalityModuleData", + type: "bytes", + }, + ], + }, + { + internalType: "struct IOracle.Response", + name: "_response", + type: "tuple", + components: [ + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + ], + }, + { + internalType: "struct IOracle.Dispute", + name: "_dispute", + type: "tuple", + components: [ + { + internalType: "address", + name: "disputer", + type: "address", + }, + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "responseId", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + ], + }, + ], + stateMutability: "nonpayable", + type: "function", + name: "disputeResponse", + outputs: [ + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + }, + ], + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_disputeId", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + name: "disputeStatus", + outputs: [ + { + internalType: "enum IOracle.DisputeStatus", + name: "_status", + type: "uint8", + }, + ], + }, + { + inputs: [ + { + internalType: "struct IOracle.Request", + name: "_request", + type: "tuple", + components: [ + { internalType: "uint96", name: "nonce", type: "uint96" }, + { + internalType: "address", + name: "requester", + type: "address", + }, + { + internalType: "address", + name: "requestModule", + type: "address", + }, + { + internalType: "address", + name: "responseModule", + type: "address", + }, + { + internalType: "address", + name: "disputeModule", + type: "address", + }, + { + internalType: "address", + name: "resolutionModule", + type: "address", + }, + { + internalType: "address", + name: "finalityModule", + type: "address", + }, + { + internalType: "bytes", + name: "requestModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "responseModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "disputeModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "resolutionModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "finalityModuleData", + type: "bytes", + }, + ], + }, + { + internalType: "struct IOracle.Response", + name: "_response", + type: "tuple", + components: [ + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + ], + }, + { + internalType: "struct IOracle.Dispute", + name: "_dispute", + type: "tuple", + components: [ + { + internalType: "address", + name: "disputer", + type: "address", + }, + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "responseId", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + ], + }, + ], + stateMutability: "nonpayable", + type: "function", + name: "escalateDispute", + }, + { + inputs: [ + { + internalType: "struct IOracle.Request", + name: "_request", + type: "tuple", + components: [ + { internalType: "uint96", name: "nonce", type: "uint96" }, + { + internalType: "address", + name: "requester", + type: "address", + }, + { + internalType: "address", + name: "requestModule", + type: "address", + }, + { + internalType: "address", + name: "responseModule", + type: "address", + }, + { + internalType: "address", + name: "disputeModule", + type: "address", + }, + { + internalType: "address", + name: "resolutionModule", + type: "address", + }, + { + internalType: "address", + name: "finalityModule", + type: "address", + }, + { + internalType: "bytes", + name: "requestModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "responseModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "disputeModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "resolutionModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "finalityModuleData", + type: "bytes", + }, + ], + }, + { + internalType: "struct IOracle.Response", + name: "_response", + type: "tuple", + components: [ + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + ], + }, + ], + stateMutability: "nonpayable", + type: "function", + name: "finalize", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + name: "finalizedAt", + outputs: [ + { + internalType: "uint128", + name: "_finalizedAt", + type: "uint128", + }, + ], + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + name: "finalizedResponseId", + outputs: [ + { + internalType: "bytes32", + name: "_finalizedResponseId", + type: "bytes32", + }, + ], + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + name: "getResponseIds", + outputs: [{ internalType: "bytes32[]", name: "_ids", type: "bytes32[]" }], + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + }, + { internalType: "address", name: "_user", type: "address" }, + ], + stateMutability: "view", + type: "function", + name: "isParticipant", + outputs: [{ internalType: "bool", name: "_isParticipant", type: "bool" }], + }, + { + inputs: [ + { + internalType: "uint256", + name: "_startFrom", + type: "uint256", + }, + { + internalType: "uint256", + name: "_batchSize", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + name: "listRequestIds", + outputs: [ + { + internalType: "bytes32[]", + name: "_list", + type: "bytes32[]", + }, + ], + }, + { + inputs: [{ internalType: "uint256", name: "_nonce", type: "uint256" }], + stateMutability: "view", + type: "function", + name: "nonceToRequestId", + outputs: [ + { + internalType: "bytes32", + name: "_requestId", + type: "bytes32", + }, + ], + }, + { + inputs: [ + { + internalType: "struct IOracle.Request", + name: "_request", + type: "tuple", + components: [ + { internalType: "uint96", name: "nonce", type: "uint96" }, + { + internalType: "address", + name: "requester", + type: "address", + }, + { + internalType: "address", + name: "requestModule", + type: "address", + }, + { + internalType: "address", + name: "responseModule", + type: "address", + }, + { + internalType: "address", + name: "disputeModule", + type: "address", + }, + { + internalType: "address", + name: "resolutionModule", + type: "address", + }, + { + internalType: "address", + name: "finalityModule", + type: "address", + }, + { + internalType: "bytes", + name: "requestModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "responseModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "disputeModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "resolutionModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "finalityModuleData", + type: "bytes", + }, + ], + }, + { + internalType: "struct IOracle.Response", + name: "_response", + type: "tuple", + components: [ + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + ], + }, + ], + stateMutability: "nonpayable", + type: "function", + name: "proposeResponse", + outputs: [ + { + internalType: "bytes32", + name: "_responseId", + type: "bytes32", + }, + ], + }, + { + inputs: [{ internalType: "bytes32", name: "_id", type: "bytes32" }], + stateMutability: "view", + type: "function", + name: "requestCreatedAt", + outputs: [ + { + internalType: "uint128", + name: "_requestCreatedAt", + type: "uint128", + }, + ], + }, + { + inputs: [ + { + internalType: "struct IOracle.Request", + name: "_request", + type: "tuple", + components: [ + { internalType: "uint96", name: "nonce", type: "uint96" }, + { + internalType: "address", + name: "requester", + type: "address", + }, + { + internalType: "address", + name: "requestModule", + type: "address", + }, + { + internalType: "address", + name: "responseModule", + type: "address", + }, + { + internalType: "address", + name: "disputeModule", + type: "address", + }, + { + internalType: "address", + name: "resolutionModule", + type: "address", + }, + { + internalType: "address", + name: "finalityModule", + type: "address", + }, + { + internalType: "bytes", + name: "requestModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "responseModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "disputeModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "resolutionModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "finalityModuleData", + type: "bytes", + }, + ], + }, + { + internalType: "struct IOracle.Response", + name: "_response", + type: "tuple", + components: [ + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + ], + }, + { + internalType: "struct IOracle.Dispute", + name: "_dispute", + type: "tuple", + components: [ + { + internalType: "address", + name: "disputer", + type: "address", + }, + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "responseId", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + ], + }, + ], + stateMutability: "nonpayable", + type: "function", + name: "resolveDispute", + }, + { + inputs: [{ internalType: "bytes32", name: "_id", type: "bytes32" }], + stateMutability: "view", + type: "function", + name: "responseCreatedAt", + outputs: [ + { + internalType: "uint128", + name: "_responseCreatedAt", + type: "uint128", + }, + ], + }, + { + inputs: [], + stateMutability: "view", + type: "function", + name: "totalRequestCount", + outputs: [{ internalType: "uint256", name: "_count", type: "uint256" }], + }, + { + inputs: [ + { + internalType: "struct IOracle.Request", + name: "_request", + type: "tuple", + components: [ + { internalType: "uint96", name: "nonce", type: "uint96" }, + { + internalType: "address", + name: "requester", + type: "address", + }, + { + internalType: "address", + name: "requestModule", + type: "address", + }, + { + internalType: "address", + name: "responseModule", + type: "address", + }, + { + internalType: "address", + name: "disputeModule", + type: "address", + }, + { + internalType: "address", + name: "resolutionModule", + type: "address", + }, + { + internalType: "address", + name: "finalityModule", + type: "address", + }, + { + internalType: "bytes", + name: "requestModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "responseModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "disputeModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "resolutionModuleData", + type: "bytes", + }, + { + internalType: "bytes", + name: "finalityModuleData", + type: "bytes", + }, + ], + }, + { + internalType: "struct IOracle.Response", + name: "_response", + type: "tuple", + components: [ + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + ], + }, + { + internalType: "struct IOracle.Dispute", + name: "_dispute", + type: "tuple", + components: [ + { + internalType: "address", + name: "disputer", + type: "address", + }, + { + internalType: "address", + name: "proposer", + type: "address", + }, + { + internalType: "bytes32", + name: "responseId", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + ], + }, + { + internalType: "enum IOracle.DisputeStatus", + name: "_status", + type: "uint8", + }, + ], + stateMutability: "nonpayable", + type: "function", + name: "updateDisputeStatus", + }, +] as const; diff --git a/packages/automated-dispute/src/constants.ts b/packages/automated-dispute/src/constants.ts new file mode 100644 index 0000000..55948ff --- /dev/null +++ b/packages/automated-dispute/src/constants.ts @@ -0,0 +1 @@ +export const ProtocolContractsNames = ["oracle", "epochManager"] as const; diff --git a/packages/automated-dispute/src/index.ts b/packages/automated-dispute/src/index.ts new file mode 100644 index 0000000..f38655f --- /dev/null +++ b/packages/automated-dispute/src/index.ts @@ -0,0 +1 @@ +export * from "./protocolProvider.js"; diff --git a/packages/automated-dispute/src/protocolProvider.ts b/packages/automated-dispute/src/protocolProvider.ts new file mode 100644 index 0000000..1c53c0a --- /dev/null +++ b/packages/automated-dispute/src/protocolProvider.ts @@ -0,0 +1,77 @@ +import { + createPublicClient, + fallback, + FallbackTransport, + getContract, + GetContractReturnType, + http, + HttpTransport, + PublicClient, +} from "viem"; +import { arbitrum } from "viem/chains"; + +import { epochManagerAbi, oracleAbi } from "./abis/index.js"; +import { ProtocolContractsAddresses } from "./types/protocolProvider.js"; + +export class ProtocolProvider { + private client: PublicClient>; + private oracleContract: GetContractReturnType< + typeof oracleAbi, + typeof this.client, + `0x${string}` + >; + private epochManagerContract: GetContractReturnType< + typeof epochManagerAbi, + typeof this.client, + `0x${string}` + >; + + /** + * Creates a new ProtocolProvider instance + * @param rpcUrls The RPC URLs to connect to the Arbitrum chain + * @param contracts The addresses of the protocol contracts that will be instantiated + */ + constructor(rpcUrls: string[], contracts: ProtocolContractsAddresses) { + this.client = createPublicClient({ + chain: arbitrum, + transport: fallback(rpcUrls.map((url) => http(url))), + }); + // Instantiate all the protocol contracts + this.oracleContract = getContract({ + address: contracts.oracle, + abi: oracleAbi, + client: this.client, + }); + this.epochManagerContract = getContract({ + address: contracts.epochManager, + abi: epochManagerAbi, + client: this.client, + }); + } + + /** + * Gets the current epoch and the block number of the current epoch + * @returns The current epoch and the block number of the current epoch + */ + async getCurrentEpoch(): Promise<{ currentEpoch: bigint; currentEpochBlock: bigint }> { + const [currentEpoch, currentEpochBlock] = await Promise.all([ + this.epochManagerContract.read.currentEpoch(), + this.epochManagerContract.read.currentEpochBlock(), + ]); + return { + currentEpoch, + currentEpochBlock, + }; + } + + // createRequest(chains[]); + // getEvents(fromBlock,toBlock): Queue; + // hasStakedAssets(address):boolean; + // getAvailableChains(args): CAIP2[]; + // proposeResponse(args): void; + // dispute(args): void; + // pledgeForDispute(args): void; + // pledgeAgaintsDispute(args): void; + // releasePledge(args):void; + // finalize(args): void; +} diff --git a/packages/automated-dispute/src/types/index.ts b/packages/automated-dispute/src/types/index.ts new file mode 100644 index 0000000..c81d829 --- /dev/null +++ b/packages/automated-dispute/src/types/index.ts @@ -0,0 +1,2 @@ +export type Address = `0x${string}`; +export * from "./protocolProvider.js"; diff --git a/packages/automated-dispute/src/types/protocolProvider.ts b/packages/automated-dispute/src/types/protocolProvider.ts new file mode 100644 index 0000000..d2a5c43 --- /dev/null +++ b/packages/automated-dispute/src/types/protocolProvider.ts @@ -0,0 +1,5 @@ +import { ProtocolContractsNames } from "../constants.js"; +import { Address } from "./index.js"; + +export type ProtocolContract = (typeof ProtocolContractsNames)[number]; +export type ProtocolContractsAddresses = Record; diff --git a/packages/automated-dispute/tests/protocolProvider.spec.ts b/packages/automated-dispute/tests/protocolProvider.spec.ts new file mode 100644 index 0000000..827da11 --- /dev/null +++ b/packages/automated-dispute/tests/protocolProvider.spec.ts @@ -0,0 +1,90 @@ +import { createPublicClient, fallback, getContract, http } from "viem"; +import { arbitrum } from "viem/chains"; +import { afterEach, beforeEach, describe, expect, it, Mock, vi } from "vitest"; + +import { epochManagerAbi } from "../src/abis/epochManager.js"; +import { oracleAbi } from "../src/abis/oracle.js"; +import { ProtocolProvider } from "../src/index.js"; +import { ProtocolContractsAddresses } from "../src/types/index.js"; + +vi.mock("viem", async () => { + const actual = await vi.importActual("viem"); + return { + ...actual, + http: vi.fn(), + fallback: vi.fn(), + createPublicClient: vi.fn(), + getContract: vi.fn(), + }; +}); + +describe("ProtocolProvider", () => { + const mockRpcUrls = ["http://localhost:8545"]; + const mockContractAddress: ProtocolContractsAddresses = { + oracle: "0x1234567890123456789012345678901234567890", + epochManager: "0x1234567890123456789012345678901234567890", + }; + beforeEach(() => { + (getContract as Mock).mockImplementation(({ address, abi }) => { + if (abi == oracleAbi && address == mockContractAddress.oracle) { + return {}; + } + if (abi == epochManagerAbi && address == mockContractAddress.epochManager) { + return { + read: { + currentEpoch: vi.fn(), + currentEpochBlock: vi.fn(), + }, + }; + } + throw new Error("Invalid contract address or ABI"); + }); + (http as Mock).mockImplementation((url) => url); + (fallback as Mock).mockImplementation((transports) => transports); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + describe("constructor", () => { + it("should create a new ProtocolProvider instance successfully", () => { + const protocolProvider = new ProtocolProvider(mockRpcUrls, mockContractAddress); + + expect(createPublicClient).toHaveBeenCalledWith({ + chain: arbitrum, + transport: fallback(mockRpcUrls.map((url) => http(url))), + }); + expect(getContract).toHaveBeenCalledWith({ + address: mockContractAddress.oracle, + abi: oracleAbi, + client: protocolProvider["client"], + }); + expect(getContract).toHaveBeenCalledWith({ + address: mockContractAddress.epochManager, + abi: epochManagerAbi, + client: protocolProvider["client"], + }); + }); + }); + describe("getCurrentEpoch", () => { + it("should return currentEpoch and currentEpochBlock successfully", async () => { + const protocolProvider = new ProtocolProvider(mockRpcUrls, mockContractAddress); + + const mockEpoch = BigInt(1); + const mockEpochBlock = BigInt(12345); + + (protocolProvider["epochManagerContract"].read.currentEpoch as Mock).mockResolvedValue( + mockEpoch, + ); + ( + protocolProvider["epochManagerContract"].read.currentEpochBlock as Mock + ).mockResolvedValue(mockEpochBlock); + + const result = await protocolProvider.getCurrentEpoch(); + + expect(result.currentEpoch).toBe(mockEpoch); + expect(result.currentEpochBlock).toBe(mockEpochBlock); + }); + }); +}); diff --git a/packages/automated-dispute/tsconfig.build.json b/packages/automated-dispute/tsconfig.build.json new file mode 100644 index 0000000..4b3e8f3 --- /dev/null +++ b/packages/automated-dispute/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.build.json", + "compilerOptions": { + "declaration": true, + "outDir": "dist" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "build", "tests", "vitest.config.ts"] +} diff --git a/packages/automated-dispute/tsconfig.json b/packages/automated-dispute/tsconfig.json new file mode 100644 index 0000000..66bb87a --- /dev/null +++ b/packages/automated-dispute/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src/**/*"] +} diff --git a/packages/automated-dispute/vitest.config.ts b/packages/automated-dispute/vitest.config.ts new file mode 100644 index 0000000..371ae0a --- /dev/null +++ b/packages/automated-dispute/vitest.config.ts @@ -0,0 +1,22 @@ +import path from "path"; +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + globals: true, // Use Vitest's global API without importing it in each file + environment: "node", // Use the Node.js environment + include: ["tests/**/*.spec.ts"], // Include test files + exclude: ["node_modules", "dist"], // Exclude certain directories + coverage: { + provider: "v8", + reporter: ["text", "json", "html"], // Coverage reporters + exclude: ["node_modules", "dist", "src/**/*.d.ts"], // Files to exclude from coverage + }, + }, + resolve: { + alias: { + // Setup path alias based on tsconfig paths + "@": path.resolve(__dirname, "src"), + }, + }, +}); diff --git a/packages/blocknumber/package.json b/packages/blocknumber/package.json index 90949f5..2d6415b 100644 --- a/packages/blocknumber/package.json +++ b/packages/blocknumber/package.json @@ -1,5 +1,5 @@ { - "name": "blocknumber", + "name": "@ebo-agent/blocknumber", "version": "1.0.0", "description": "", "main": "index.ts", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 56d01ae..c091e41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -53,9 +53,21 @@ importers: specifier: 2.0.3 version: 2.0.3(@types/node@20.14.11) + packages/automated-dispute: + dependencies: + viem: + specifier: ^2.17.11 + version: 2.17.11(typescript@5.5.3) + packages/blocknumber: {} packages: + "@adraffy/ens-normalize@1.10.0": + resolution: + { + integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==, + } + "@ampproject/remapping@2.3.0": resolution: { @@ -657,6 +669,19 @@ packages: integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, } + "@noble/curves@1.4.0": + resolution: + { + integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==, + } + + "@noble/hashes@1.4.0": + resolution: + { + integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==, + } + engines: { node: ">= 16" } + "@nodelib/fs.scandir@2.1.5": resolution: { @@ -820,6 +845,24 @@ packages: cpu: [x64] os: [win32] + "@scure/base@1.1.7": + resolution: + { + integrity: sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==, + } + + "@scure/bip32@1.4.0": + resolution: + { + integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==, + } + + "@scure/bip39@1.3.0": + resolution: + { + integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==, + } + "@types/conventional-commits-parser@5.0.0": resolution: { @@ -977,6 +1020,20 @@ packages: } hasBin: true + abitype@1.0.5: + resolution: + { + integrity: sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==, + } + peerDependencies: + typescript: ">=5.0.4" + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + acorn-jsx@5.3.2: resolution: { @@ -1890,6 +1947,14 @@ packages: integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, } + isows@1.0.4: + resolution: + { + integrity: sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==, + } + peerDependencies: + ws: "*" + istanbul-lib-coverage@3.2.2: resolution: { @@ -2891,6 +2956,17 @@ packages: integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, } + viem@2.17.11: + resolution: + { + integrity: sha512-4dqMQyLVx0dWzuzVNPKzru6qrzHc4opD1WxeL/+NEtQaHcVGfE6f2uAqfoo0k0wwzWgLXbYLkODZ3s/3GDFXYA==, + } + peerDependencies: + typescript: ">=5.0.4" + peerDependenciesMeta: + typescript: + optional: true + vite-node@2.0.3: resolution: { @@ -3008,6 +3084,21 @@ packages: integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, } + ws@8.17.1: + resolution: + { + integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==, + } + engines: { node: ">=10.0.0" } + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + y18n@5.0.8: resolution: { @@ -3058,6 +3149,8 @@ packages: engines: { node: ">=12.20" } snapshots: + "@adraffy/ens-normalize@1.10.0": {} + "@ampproject/remapping@2.3.0": dependencies: "@jridgewell/gen-mapping": 0.3.5 @@ -3453,6 +3546,12 @@ snapshots: "@jridgewell/resolve-uri": 3.1.2 "@jridgewell/sourcemap-codec": 1.5.0 + "@noble/curves@1.4.0": + dependencies: + "@noble/hashes": 1.4.0 + + "@noble/hashes@1.4.0": {} + "@nodelib/fs.scandir@2.1.5": dependencies: "@nodelib/fs.stat": 2.0.5 @@ -3518,6 +3617,19 @@ snapshots: "@rollup/rollup-win32-x64-msvc@4.18.1": optional: true + "@scure/base@1.1.7": {} + + "@scure/bip32@1.4.0": + dependencies: + "@noble/curves": 1.4.0 + "@noble/hashes": 1.4.0 + "@scure/base": 1.1.7 + + "@scure/bip39@1.3.0": + dependencies: + "@noble/hashes": 1.4.0 + "@scure/base": 1.1.7 + "@types/conventional-commits-parser@5.0.0": dependencies: "@types/node": 20.14.11 @@ -3668,6 +3780,10 @@ snapshots: jsonparse: 1.3.1 through: 2.3.8 + abitype@1.0.5(typescript@5.5.3): + optionalDependencies: + typescript: 5.5.3 + acorn-jsx@5.3.2(acorn@8.12.1): dependencies: acorn: 8.12.1 @@ -4191,6 +4307,10 @@ snapshots: isexe@2.0.0: {} + isows@1.0.4(ws@8.17.1): + dependencies: + ws: 8.17.1 + istanbul-lib-coverage@3.2.2: {} istanbul-lib-report@3.0.1: @@ -4686,6 +4806,23 @@ snapshots: dependencies: punycode: 2.3.1 + viem@2.17.11(typescript@5.5.3): + dependencies: + "@adraffy/ens-normalize": 1.10.0 + "@noble/curves": 1.4.0 + "@noble/hashes": 1.4.0 + "@scure/bip32": 1.4.0 + "@scure/bip39": 1.3.0 + abitype: 1.0.5(typescript@5.5.3) + isows: 1.0.4(ws@8.17.1) + ws: 8.17.1 + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + vite-node@2.0.3(@types/node@20.14.11): dependencies: cac: 6.7.14 @@ -4775,6 +4912,8 @@ snapshots: wrappy@1.0.2: {} + ws@8.17.1: {} + y18n@5.0.8: {} yallist@3.1.1: {} From 15d349398a76522822aeb0345abf051d423d1fd4 Mon Sep 17 00:00:00 2001 From: 0xkenj1 Date: Wed, 24 Jul 2024 17:36:28 -0300 Subject: [PATCH 2/7] feat: add ts-node & console.log --- package.json | 1 + pnpm-lock.yaml | 155 ++++++++++++++++++++++++++++++++++++++++++++- tsconfig.base.json | 2 +- 3 files changed, 156 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index abfffdc..6e6c17c 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "lint-staged": "15.2.7", "prettier": "3.3.3", "turbo": "2.0.7", + "ts-node": "10.9.2", "typescript": "5.5.3", "vitest": "2.0.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c091e41..dd9a318 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,6 +43,9 @@ importers: prettier: specifier: 3.3.3 version: 3.3.3 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) turbo: specifier: 2.0.7 version: 2.0.7 @@ -56,7 +59,7 @@ importers: packages/automated-dispute: dependencies: viem: - specifier: ^2.17.11 + specifier: 2.17.11 version: 2.17.11(typescript@5.5.3) packages/blocknumber: {} @@ -351,6 +354,13 @@ packages: } engines: { node: ">=v18" } + "@cspotcode/source-map-support@0.8.1": + resolution: + { + integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, + } + engines: { node: ">=12" } + "@esbuild/aix-ppc64@0.21.5": resolution: { @@ -669,6 +679,12 @@ packages: integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, } + "@jridgewell/trace-mapping@0.3.9": + resolution: + { + integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, + } + "@noble/curves@1.4.0": resolution: { @@ -863,6 +879,30 @@ packages: integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==, } + "@tsconfig/node10@1.0.11": + resolution: + { + integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==, + } + + "@tsconfig/node12@1.0.11": + resolution: + { + integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, + } + + "@tsconfig/node14@1.0.3": + resolution: + { + integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, + } + + "@tsconfig/node16@1.0.4": + resolution: + { + integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==, + } + "@types/conventional-commits-parser@5.0.0": resolution: { @@ -1042,6 +1082,13 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-walk@8.3.3: + resolution: + { + integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==, + } + engines: { node: ">=0.4.0" } + acorn@8.12.1: resolution: { @@ -1104,6 +1151,12 @@ packages: } engines: { node: ">=12" } + arg@4.1.3: + resolution: + { + integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, + } + argparse@2.0.1: resolution: { @@ -1340,6 +1393,12 @@ packages: typescript: optional: true + create-require@1.1.1: + resolution: + { + integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, + } + cross-spawn@7.0.3: resolution: { @@ -1379,6 +1438,13 @@ packages: integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, } + diff@4.0.2: + resolution: + { + integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, + } + engines: { node: ">=0.3.1" } + dir-glob@3.0.1: resolution: { @@ -2221,6 +2287,12 @@ packages: } engines: { node: ">=10" } + make-error@1.3.6: + resolution: + { + integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, + } + meow@12.1.1: resolution: { @@ -2845,6 +2917,23 @@ packages: peerDependencies: typescript: ">=4.2.0" + ts-node@10.9.2: + resolution: + { + integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==, + } + hasBin: true + peerDependencies: + "@swc/core": ">=1.2.50" + "@swc/wasm": ">=1.2.50" + "@types/node": "*" + typescript: ">=2.7" + peerDependenciesMeta: + "@swc/core": + optional: true + "@swc/wasm": + optional: true + tslib@2.6.3: resolution: { @@ -2956,6 +3045,12 @@ packages: integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, } + v8-compile-cache-lib@3.0.1: + resolution: + { + integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, + } + viem@2.17.11: resolution: { @@ -3134,6 +3229,13 @@ packages: } engines: { node: ">=12" } + yn@3.1.1: + resolution: + { + integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, + } + engines: { node: ">=6" } + yocto-queue@0.1.0: resolution: { @@ -3402,6 +3504,10 @@ snapshots: "@types/conventional-commits-parser": 5.0.0 chalk: 5.3.0 + "@cspotcode/source-map-support@0.8.1": + dependencies: + "@jridgewell/trace-mapping": 0.3.9 + "@esbuild/aix-ppc64@0.21.5": optional: true @@ -3546,6 +3652,11 @@ snapshots: "@jridgewell/resolve-uri": 3.1.2 "@jridgewell/sourcemap-codec": 1.5.0 + "@jridgewell/trace-mapping@0.3.9": + dependencies: + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.0 + "@noble/curves@1.4.0": dependencies: "@noble/hashes": 1.4.0 @@ -3630,6 +3741,14 @@ snapshots: "@noble/hashes": 1.4.0 "@scure/base": 1.1.7 + "@tsconfig/node10@1.0.11": {} + + "@tsconfig/node12@1.0.11": {} + + "@tsconfig/node14@1.0.3": {} + + "@tsconfig/node16@1.0.4": {} + "@types/conventional-commits-parser@5.0.0": dependencies: "@types/node": 20.14.11 @@ -3788,6 +3907,10 @@ snapshots: dependencies: acorn: 8.12.1 + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.1 + acorn@8.12.1: {} ajv@6.12.6: @@ -3820,6 +3943,8 @@ snapshots: ansi-styles@6.2.1: {} + arg@4.1.3: {} + argparse@2.0.1: {} array-ify@1.0.0: {} @@ -3950,6 +4075,8 @@ snapshots: optionalDependencies: typescript: 5.5.3 + create-require@1.1.1: {} + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -3966,6 +4093,8 @@ snapshots: deep-is@0.1.4: {} + diff@4.0.2: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -4459,6 +4588,8 @@ snapshots: dependencies: semver: 7.6.3 + make-error@1.3.6: {} + meow@12.1.1: {} merge-stream@2.0.0: {} @@ -4755,6 +4886,24 @@ snapshots: dependencies: typescript: 5.5.3 + ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3): + dependencies: + "@cspotcode/source-map-support": 0.8.1 + "@tsconfig/node10": 1.0.11 + "@tsconfig/node12": 1.0.11 + "@tsconfig/node14": 1.0.3 + "@tsconfig/node16": 1.0.4 + "@types/node": 20.14.11 + acorn: 8.12.1 + acorn-walk: 8.3.3 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + tslib@2.6.3: {} turbo-darwin-64@2.0.7: @@ -4806,6 +4955,8 @@ snapshots: dependencies: punycode: 2.3.1 + v8-compile-cache-lib@3.0.1: {} + viem@2.17.11(typescript@5.5.3): dependencies: "@adraffy/ens-normalize": 1.10.0 @@ -4932,6 +5083,8 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yn@3.1.1: {} + yocto-queue@0.1.0: {} yocto-queue@1.1.1: {} diff --git a/tsconfig.base.json b/tsconfig.base.json index 14527c8..90edd86 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -18,6 +18,6 @@ "module": "NodeNext", "sourceMap": true, /* If your code doesn't run in the DOM: */ - "lib": ["es2022"] + "lib": ["es2022", "DOM"] } } From 8b6d09f96555f46adf02853e57d434f23e8466fb Mon Sep 17 00:00:00 2001 From: 0xkenj1 Date: Thu, 25 Jul 2024 00:10:29 -0300 Subject: [PATCH 3/7] fix: add validation for rpcUrls on ProtocolProvider constructor --- packages/automated-dispute/src/exceptions/index.ts | 1 + .../src/exceptions/rpcUrlsEmpty.exception.ts | 6 ++++++ packages/automated-dispute/src/protocolProvider.ts | 4 ++++ packages/automated-dispute/tests/protocolProvider.spec.ts | 8 +++++++- 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 packages/automated-dispute/src/exceptions/index.ts create mode 100644 packages/automated-dispute/src/exceptions/rpcUrlsEmpty.exception.ts diff --git a/packages/automated-dispute/src/exceptions/index.ts b/packages/automated-dispute/src/exceptions/index.ts new file mode 100644 index 0000000..7e1aa47 --- /dev/null +++ b/packages/automated-dispute/src/exceptions/index.ts @@ -0,0 +1 @@ +export * from "./rpcUrlsEmpty.exception.js"; diff --git a/packages/automated-dispute/src/exceptions/rpcUrlsEmpty.exception.ts b/packages/automated-dispute/src/exceptions/rpcUrlsEmpty.exception.ts new file mode 100644 index 0000000..4981e44 --- /dev/null +++ b/packages/automated-dispute/src/exceptions/rpcUrlsEmpty.exception.ts @@ -0,0 +1,6 @@ +export class RpcUrlsEmptyException extends Error { + constructor() { + super("The rpcUrls array cannot be empty."); + this.name = "RpcUrlsEmptyException"; + } +} diff --git a/packages/automated-dispute/src/protocolProvider.ts b/packages/automated-dispute/src/protocolProvider.ts index 1c53c0a..c1a0b2d 100644 --- a/packages/automated-dispute/src/protocolProvider.ts +++ b/packages/automated-dispute/src/protocolProvider.ts @@ -11,6 +11,7 @@ import { import { arbitrum } from "viem/chains"; import { epochManagerAbi, oracleAbi } from "./abis/index.js"; +import { RpcUrlsEmptyException } from "./exceptions/rpcUrlsEmpty.exception.js"; import { ProtocolContractsAddresses } from "./types/protocolProvider.js"; export class ProtocolProvider { @@ -32,6 +33,9 @@ export class ProtocolProvider { * @param contracts The addresses of the protocol contracts that will be instantiated */ constructor(rpcUrls: string[], contracts: ProtocolContractsAddresses) { + if (rpcUrls.length === 0) { + throw new RpcUrlsEmptyException(); + } this.client = createPublicClient({ chain: arbitrum, transport: fallback(rpcUrls.map((url) => http(url))), diff --git a/packages/automated-dispute/tests/protocolProvider.spec.ts b/packages/automated-dispute/tests/protocolProvider.spec.ts index 827da11..2193f19 100644 --- a/packages/automated-dispute/tests/protocolProvider.spec.ts +++ b/packages/automated-dispute/tests/protocolProvider.spec.ts @@ -4,6 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, Mock, vi } from "vitest"; import { epochManagerAbi } from "../src/abis/epochManager.js"; import { oracleAbi } from "../src/abis/oracle.js"; +import { RpcUrlsEmptyException } from "../src/exceptions/rpcUrlsEmpty.exception.js"; import { ProtocolProvider } from "../src/index.js"; import { ProtocolContractsAddresses } from "../src/types/index.js"; @@ -48,7 +49,7 @@ describe("ProtocolProvider", () => { }); describe("constructor", () => { - it("should create a new ProtocolProvider instance successfully", () => { + it("create a new ProtocolProvider instance successfully", () => { const protocolProvider = new ProtocolProvider(mockRpcUrls, mockContractAddress); expect(createPublicClient).toHaveBeenCalledWith({ @@ -66,6 +67,11 @@ describe("ProtocolProvider", () => { client: protocolProvider["client"], }); }); + it("throws if rpcUrls are empty", () => { + expect(() => new ProtocolProvider([], mockContractAddress)).toThrowError( + RpcUrlsEmptyException, + ); + }); }); describe("getCurrentEpoch", () => { it("should return currentEpoch and currentEpochBlock successfully", async () => { From ebdf78765f9cde7b001adba7e457987963643307 Mon Sep 17 00:00:00 2001 From: 0xkenj1 Date: Thu, 25 Jul 2024 00:23:32 -0300 Subject: [PATCH 4/7] fix: exception naming --- .../src/exceptions/rpcUrlsEmpty.exception.ts | 4 ++-- packages/automated-dispute/src/protocolProvider.ts | 4 ++-- packages/automated-dispute/tests/protocolProvider.spec.ts | 6 ++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/automated-dispute/src/exceptions/rpcUrlsEmpty.exception.ts b/packages/automated-dispute/src/exceptions/rpcUrlsEmpty.exception.ts index 4981e44..8bdf433 100644 --- a/packages/automated-dispute/src/exceptions/rpcUrlsEmpty.exception.ts +++ b/packages/automated-dispute/src/exceptions/rpcUrlsEmpty.exception.ts @@ -1,6 +1,6 @@ -export class RpcUrlsEmptyException extends Error { +export class RpcUrlsEmpty extends Error { constructor() { super("The rpcUrls array cannot be empty."); - this.name = "RpcUrlsEmptyException"; + this.name = "RpcUrlsEmpty"; } } diff --git a/packages/automated-dispute/src/protocolProvider.ts b/packages/automated-dispute/src/protocolProvider.ts index c1a0b2d..db91364 100644 --- a/packages/automated-dispute/src/protocolProvider.ts +++ b/packages/automated-dispute/src/protocolProvider.ts @@ -11,7 +11,7 @@ import { import { arbitrum } from "viem/chains"; import { epochManagerAbi, oracleAbi } from "./abis/index.js"; -import { RpcUrlsEmptyException } from "./exceptions/rpcUrlsEmpty.exception.js"; +import { RpcUrlsEmpty } from "./exceptions/rpcUrlsEmpty.exception.js"; import { ProtocolContractsAddresses } from "./types/protocolProvider.js"; export class ProtocolProvider { @@ -34,7 +34,7 @@ export class ProtocolProvider { */ constructor(rpcUrls: string[], contracts: ProtocolContractsAddresses) { if (rpcUrls.length === 0) { - throw new RpcUrlsEmptyException(); + throw new RpcUrlsEmpty(); } this.client = createPublicClient({ chain: arbitrum, diff --git a/packages/automated-dispute/tests/protocolProvider.spec.ts b/packages/automated-dispute/tests/protocolProvider.spec.ts index 2193f19..692a526 100644 --- a/packages/automated-dispute/tests/protocolProvider.spec.ts +++ b/packages/automated-dispute/tests/protocolProvider.spec.ts @@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, Mock, vi } from "vitest"; import { epochManagerAbi } from "../src/abis/epochManager.js"; import { oracleAbi } from "../src/abis/oracle.js"; -import { RpcUrlsEmptyException } from "../src/exceptions/rpcUrlsEmpty.exception.js"; +import { RpcUrlsEmpty } from "../src/exceptions/rpcUrlsEmpty.exception.js"; import { ProtocolProvider } from "../src/index.js"; import { ProtocolContractsAddresses } from "../src/types/index.js"; @@ -68,9 +68,7 @@ describe("ProtocolProvider", () => { }); }); it("throws if rpcUrls are empty", () => { - expect(() => new ProtocolProvider([], mockContractAddress)).toThrowError( - RpcUrlsEmptyException, - ); + expect(() => new ProtocolProvider([], mockContractAddress)).toThrowError(RpcUrlsEmpty); }); }); describe("getCurrentEpoch", () => { From a7dd68bd2269a92d5196dc5ef3134b475c199ab8 Mon Sep 17 00:00:00 2001 From: 0xkenj1 Date: Thu, 25 Jul 2024 11:53:04 -0300 Subject: [PATCH 5/7] fix: tests --- .../tests/protocolProvider.spec.ts | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/packages/automated-dispute/tests/protocolProvider.spec.ts b/packages/automated-dispute/tests/protocolProvider.spec.ts index 692a526..e2dc066 100644 --- a/packages/automated-dispute/tests/protocolProvider.spec.ts +++ b/packages/automated-dispute/tests/protocolProvider.spec.ts @@ -49,7 +49,7 @@ describe("ProtocolProvider", () => { }); describe("constructor", () => { - it("create a new ProtocolProvider instance successfully", () => { + it("creates a new ProtocolProvider instance successfully", () => { const protocolProvider = new ProtocolProvider(mockRpcUrls, mockContractAddress); expect(createPublicClient).toHaveBeenCalledWith({ @@ -72,7 +72,7 @@ describe("ProtocolProvider", () => { }); }); describe("getCurrentEpoch", () => { - it("should return currentEpoch and currentEpochBlock successfully", async () => { + it("returns currentEpoch and currentEpochBlock successfully", async () => { const protocolProvider = new ProtocolProvider(mockRpcUrls, mockContractAddress); const mockEpoch = BigInt(1); @@ -90,5 +90,47 @@ describe("ProtocolProvider", () => { expect(result.currentEpoch).toBe(mockEpoch); expect(result.currentEpochBlock).toBe(mockEpochBlock); }); + it("throws when current epoch request fails", async () => { + const protocolProvider = new ProtocolProvider(mockRpcUrls, mockContractAddress); + const error = new Error("Failed to get current epoch"); + const mockEpochBlock = BigInt(12345); + + (protocolProvider["epochManagerContract"].read.currentEpoch as Mock).mockRejectedValue( + error, + ); + ( + protocolProvider["epochManagerContract"].read.currentEpochBlock as Mock + ).mockResolvedValue(mockEpochBlock); + + await expect(protocolProvider.getCurrentEpoch()).rejects.toThrow(error); + }); + it("throws when current epoch block request fails", async () => { + const protocolProvider = new ProtocolProvider(mockRpcUrls, mockContractAddress); + const error = new Error("Failed to get current epoch block"); + const mockEpoch = BigInt(12345); + + (protocolProvider["epochManagerContract"].read.currentEpoch as Mock).mockResolvedValue( + mockEpoch, + ); + ( + protocolProvider["epochManagerContract"].read.currentEpochBlock as Mock + ).mockRejectedValue(error); + + await expect(protocolProvider.getCurrentEpoch()).rejects.toThrow(error); + }); + it("throws when current epoch block request fails", async () => { + const protocolProvider = new ProtocolProvider(mockRpcUrls, mockContractAddress); + const currentEpochError = new Error("Failed to get current epoch"); + const currentEpochBlockError = new Error("Failed to get current epoch block"); + + (protocolProvider["epochManagerContract"].read.currentEpoch as Mock).mockRejectedValue( + currentEpochError, + ); + ( + protocolProvider["epochManagerContract"].read.currentEpochBlock as Mock + ).mockRejectedValue(currentEpochBlockError); + + await expect(protocolProvider.getCurrentEpoch()).rejects.toThrow(currentEpochError); + }); }); }); From 5a25cf16675d7fa8b8eba35f820ca2cea1063fdf Mon Sep 17 00:00:00 2001 From: 0xkenj1 Date: Fri, 26 Jul 2024 15:11:46 -0300 Subject: [PATCH 6/7] fix: pr comments --- packages/automated-dispute/src/protocolProvider.ts | 9 +++------ packages/automated-dispute/src/types/index.ts | 1 - .../tests/protocolProvider.spec.ts | 14 -------------- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/packages/automated-dispute/src/protocolProvider.ts b/packages/automated-dispute/src/protocolProvider.ts index db91364..22d21e8 100644 --- a/packages/automated-dispute/src/protocolProvider.ts +++ b/packages/automated-dispute/src/protocolProvider.ts @@ -1,4 +1,5 @@ import { + Address, createPublicClient, fallback, FallbackTransport, @@ -16,15 +17,11 @@ import { ProtocolContractsAddresses } from "./types/protocolProvider.js"; export class ProtocolProvider { private client: PublicClient>; - private oracleContract: GetContractReturnType< - typeof oracleAbi, - typeof this.client, - `0x${string}` - >; + private oracleContract: GetContractReturnType; private epochManagerContract: GetContractReturnType< typeof epochManagerAbi, typeof this.client, - `0x${string}` + Address >; /** diff --git a/packages/automated-dispute/src/types/index.ts b/packages/automated-dispute/src/types/index.ts index c81d829..f38655f 100644 --- a/packages/automated-dispute/src/types/index.ts +++ b/packages/automated-dispute/src/types/index.ts @@ -1,2 +1 @@ -export type Address = `0x${string}`; export * from "./protocolProvider.js"; diff --git a/packages/automated-dispute/tests/protocolProvider.spec.ts b/packages/automated-dispute/tests/protocolProvider.spec.ts index e2dc066..2d46da2 100644 --- a/packages/automated-dispute/tests/protocolProvider.spec.ts +++ b/packages/automated-dispute/tests/protocolProvider.spec.ts @@ -118,19 +118,5 @@ describe("ProtocolProvider", () => { await expect(protocolProvider.getCurrentEpoch()).rejects.toThrow(error); }); - it("throws when current epoch block request fails", async () => { - const protocolProvider = new ProtocolProvider(mockRpcUrls, mockContractAddress); - const currentEpochError = new Error("Failed to get current epoch"); - const currentEpochBlockError = new Error("Failed to get current epoch block"); - - (protocolProvider["epochManagerContract"].read.currentEpoch as Mock).mockRejectedValue( - currentEpochError, - ); - ( - protocolProvider["epochManagerContract"].read.currentEpochBlock as Mock - ).mockRejectedValue(currentEpochBlockError); - - await expect(protocolProvider.getCurrentEpoch()).rejects.toThrow(currentEpochError); - }); }); }); From bec87f3ec0c31f1168a452d96b320fb44d308f05 Mon Sep 17 00:00:00 2001 From: 0xkenj1 Date: Fri, 26 Jul 2024 15:28:24 -0300 Subject: [PATCH 7/7] fix: pr comments --- package.json | 1 + .../src/types/protocolProvider.ts | 3 +- pnpm-lock.yaml | 55 ++++++++++--------- tsconfig.base.json | 2 +- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 971e881..31c7f69 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@commitlint/cli": "19.3.0", "@commitlint/config-conventional": "19.2.2", "@ianvs/prettier-plugin-sort-imports": "4.3.1", + "@types/node": "20.14.12", "@typescript-eslint/eslint-plugin": "7.16.1", "@typescript-eslint/parser": "7.16.1", "@vitest/coverage-v8": "^2.0.3", diff --git a/packages/automated-dispute/src/types/protocolProvider.ts b/packages/automated-dispute/src/types/protocolProvider.ts index d2a5c43..a4387ee 100644 --- a/packages/automated-dispute/src/types/protocolProvider.ts +++ b/packages/automated-dispute/src/types/protocolProvider.ts @@ -1,5 +1,6 @@ +import { Address } from "viem"; + import { ProtocolContractsNames } from "../constants.js"; -import { Address } from "./index.js"; export type ProtocolContract = (typeof ProtocolContractsNames)[number]; export type ProtocolContractsAddresses = Record; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f4c13c..d9056ea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,13 +13,16 @@ importers: devDependencies: "@commitlint/cli": specifier: 19.3.0 - version: 19.3.0(@types/node@20.14.11)(typescript@5.5.3) + version: 19.3.0(@types/node@20.14.12)(typescript@5.5.3) "@commitlint/config-conventional": specifier: 19.2.2 version: 19.2.2 "@ianvs/prettier-plugin-sort-imports": specifier: 4.3.1 version: 4.3.1(prettier@3.3.3) + "@types/node": + specifier: 20.14.12 + version: 20.14.12 "@typescript-eslint/eslint-plugin": specifier: 7.16.1 version: 7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) @@ -28,7 +31,7 @@ importers: version: 7.16.1(eslint@8.57.0)(typescript@5.5.3) "@vitest/coverage-v8": specifier: ^2.0.3 - version: 2.0.3(vitest@2.0.3(@types/node@20.14.11)) + version: 2.0.3(vitest@2.0.3(@types/node@20.14.12)) eslint: specifier: 8.57.0 version: 8.57.0 @@ -49,7 +52,7 @@ importers: version: 3.3.3 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.14.12)(typescript@5.5.3) turbo: specifier: 2.0.7 version: 2.0.7 @@ -58,7 +61,7 @@ importers: version: 5.5.3 vitest: specifier: 2.0.3 - version: 2.0.3(@types/node@20.14.11) + version: 2.0.3(@types/node@20.14.12) packages/automated-dispute: dependencies: @@ -936,10 +939,10 @@ packages: integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==, } - "@types/node@20.14.11": + "@types/node@20.14.12": resolution: { - integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==, + integrity: sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==, } "@types/triple-beam@1.3.5": @@ -3578,11 +3581,11 @@ snapshots: "@colors/colors@1.6.0": {} - "@commitlint/cli@19.3.0(@types/node@20.14.11)(typescript@5.5.3)": + "@commitlint/cli@19.3.0(@types/node@20.14.12)(typescript@5.5.3)": dependencies: "@commitlint/format": 19.3.0 "@commitlint/lint": 19.2.2 - "@commitlint/load": 19.2.0(@types/node@20.14.11)(typescript@5.5.3) + "@commitlint/load": 19.2.0(@types/node@20.14.12)(typescript@5.5.3) "@commitlint/read": 19.2.1 "@commitlint/types": 19.0.3 execa: 8.0.1 @@ -3629,7 +3632,7 @@ snapshots: "@commitlint/rules": 19.0.3 "@commitlint/types": 19.0.3 - "@commitlint/load@19.2.0(@types/node@20.14.11)(typescript@5.5.3)": + "@commitlint/load@19.2.0(@types/node@20.14.12)(typescript@5.5.3)": dependencies: "@commitlint/config-validator": 19.0.3 "@commitlint/execute-rule": 19.0.0 @@ -3637,7 +3640,7 @@ snapshots: "@commitlint/types": 19.0.3 chalk: 5.3.0 cosmiconfig: 9.0.0(typescript@5.5.3) - cosmiconfig-typescript-loader: 5.0.0(@types/node@20.14.11)(cosmiconfig@9.0.0(typescript@5.5.3))(typescript@5.5.3) + cosmiconfig-typescript-loader: 5.0.0(@types/node@20.14.12)(cosmiconfig@9.0.0(typescript@5.5.3))(typescript@5.5.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -3942,11 +3945,11 @@ snapshots: "@types/conventional-commits-parser@5.0.0": dependencies: - "@types/node": 20.14.11 + "@types/node": 20.14.12 "@types/estree@1.0.5": {} - "@types/node@20.14.11": + "@types/node@20.14.12": dependencies: undici-types: 5.26.5 @@ -4035,7 +4038,7 @@ snapshots: "@ungap/structured-clone@1.2.0": {} - "@vitest/coverage-v8@2.0.3(vitest@2.0.3(@types/node@20.14.11))": + "@vitest/coverage-v8@2.0.3(vitest@2.0.3(@types/node@20.14.12))": dependencies: "@ampproject/remapping": 2.3.0 "@bcoe/v8-coverage": 0.2.3 @@ -4050,7 +4053,7 @@ snapshots: strip-literal: 2.1.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.0.3(@types/node@20.14.11) + vitest: 2.0.3(@types/node@20.14.12) transitivePeerDependencies: - supports-color @@ -4269,9 +4272,9 @@ snapshots: convert-source-map@2.0.0: {} - cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.11)(cosmiconfig@9.0.0(typescript@5.5.3))(typescript@5.5.3): + cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.12)(cosmiconfig@9.0.0(typescript@5.5.3))(typescript@5.5.3): dependencies: - "@types/node": 20.14.11 + "@types/node": 20.14.12 cosmiconfig: 9.0.0(typescript@5.5.3) jiti: 1.21.6 typescript: 5.5.3 @@ -5145,14 +5148,14 @@ snapshots: dependencies: typescript: 5.5.3 - ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3): + ts-node@10.9.2(@types/node@20.14.12)(typescript@5.5.3): dependencies: "@cspotcode/source-map-support": 0.8.1 "@tsconfig/node10": 1.0.11 "@tsconfig/node12": 1.0.11 "@tsconfig/node14": 1.0.3 "@tsconfig/node16": 1.0.4 - "@types/node": 20.14.11 + "@types/node": 20.14.12 acorn: 8.12.1 acorn-walk: 8.3.3 arg: 4.1.3 @@ -5252,13 +5255,13 @@ snapshots: - utf-8-validate - zod - vite-node@2.0.3(@types/node@20.14.11): + vite-node@2.0.3(@types/node@20.14.12): dependencies: cac: 6.7.14 debug: 4.3.5 pathe: 1.1.2 tinyrainbow: 1.2.0 - vite: 5.3.4(@types/node@20.14.11) + vite: 5.3.4(@types/node@20.14.12) transitivePeerDependencies: - "@types/node" - less @@ -5269,16 +5272,16 @@ snapshots: - supports-color - terser - vite@5.3.4(@types/node@20.14.11): + vite@5.3.4(@types/node@20.14.12): dependencies: esbuild: 0.21.5 postcss: 8.4.39 rollup: 4.18.1 optionalDependencies: - "@types/node": 20.14.11 + "@types/node": 20.14.12 fsevents: 2.3.3 - vitest@2.0.3(@types/node@20.14.11): + vitest@2.0.3(@types/node@20.14.12): dependencies: "@ampproject/remapping": 2.3.0 "@vitest/expect": 2.0.3 @@ -5296,11 +5299,11 @@ snapshots: tinybench: 2.8.0 tinypool: 1.0.0 tinyrainbow: 1.2.0 - vite: 5.3.4(@types/node@20.14.11) - vite-node: 2.0.3(@types/node@20.14.11) + vite: 5.3.4(@types/node@20.14.12) + vite-node: 2.0.3(@types/node@20.14.12) why-is-node-running: 2.3.0 optionalDependencies: - "@types/node": 20.14.11 + "@types/node": 20.14.12 transitivePeerDependencies: - less - lightningcss diff --git a/tsconfig.base.json b/tsconfig.base.json index 90edd86..14527c8 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -18,6 +18,6 @@ "module": "NodeNext", "sourceMap": true, /* If your code doesn't run in the DOM: */ - "lib": ["es2022", "DOM"] + "lib": ["es2022"] } }