From 14a0d40549c36d3c50e7ecc5c074b09220695fb5 Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Wed, 6 Nov 2024 15:12:55 +0300 Subject: [PATCH 01/15] Automated Orders: add a layer to work with blockchains --- automated-orders/.gitignore | 1 + automated-orders/.vscode/launch.json | 25 + automated-orders/README.md | 19 + .../packages/blockchain-library/package.json | 25 + .../blockchain-library/src/clients/evm.ts | 15 + .../blockchain-library/src/clients/warden.ts | 51 + .../packages/blockchain-library/src/index.ts | 4 + .../src/processors/newSignatureProcessor.ts | 29 + .../src/processors/processor.ts | 30 + .../src/types/evm/configuration.ts | 3 + .../src/types/registry/events.ts | 9 + .../src/types/warden/configuration.ts | 4 + .../src/types/warden/newSignatureRequest.ts | 3 + .../packages/blockchain-library/tsconfig.json | 21 + .../packages/relayer/package.json | 1 + .../packages/relayer/src/config/config.ts | 18 + .../packages/relayer/src/config/env.ts | 5 + .../packages/relayer/src/index.ts | 26 +- .../packages/scheduler/package.json | 1 + .../packages/scheduler/src/config/config.ts | 17 + .../packages/scheduler/src/config/env.ts | 4 + .../packages/scheduler/src/index.ts | 5 +- automated-orders/tsconfig.json | 3 + automated-orders/yarn.lock | 1060 ++++++++++++++++- 24 files changed, 1373 insertions(+), 6 deletions(-) create mode 100644 automated-orders/.vscode/launch.json create mode 100644 automated-orders/packages/blockchain-library/package.json create mode 100644 automated-orders/packages/blockchain-library/src/clients/evm.ts create mode 100644 automated-orders/packages/blockchain-library/src/clients/warden.ts create mode 100644 automated-orders/packages/blockchain-library/src/index.ts create mode 100644 automated-orders/packages/blockchain-library/src/processors/newSignatureProcessor.ts create mode 100644 automated-orders/packages/blockchain-library/src/processors/processor.ts create mode 100644 automated-orders/packages/blockchain-library/src/types/evm/configuration.ts create mode 100644 automated-orders/packages/blockchain-library/src/types/registry/events.ts create mode 100644 automated-orders/packages/blockchain-library/src/types/warden/configuration.ts create mode 100644 automated-orders/packages/blockchain-library/src/types/warden/newSignatureRequest.ts create mode 100644 automated-orders/packages/blockchain-library/tsconfig.json create mode 100644 automated-orders/packages/relayer/src/config/config.ts create mode 100644 automated-orders/packages/relayer/src/config/env.ts create mode 100644 automated-orders/packages/scheduler/src/config/config.ts create mode 100644 automated-orders/packages/scheduler/src/config/env.ts diff --git a/automated-orders/.gitignore b/automated-orders/.gitignore index 4ff756be7..5a8b1d3ce 100644 --- a/automated-orders/.gitignore +++ b/automated-orders/.gitignore @@ -27,4 +27,5 @@ lib-cov *.env # exceptions +!.vscode/launch.json !.vscode/settings.json \ No newline at end of file diff --git a/automated-orders/.vscode/launch.json b/automated-orders/.vscode/launch.json new file mode 100644 index 000000000..629ceb5a2 --- /dev/null +++ b/automated-orders/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "launch scheduler", + "program": "${workspaceFolder}/packages/scheduler/src/index.ts", + "preLaunchTask": "tsc: build - tsconfig.json", + "outFiles": [ + "${workspaceFolder}/packages/scheduler/dist/**/*.js" + ] + }, + { + "type": "node", + "request": "launch", + "name": "launch relayer", + "program": "${workspaceFolder}/packages/relayer/src/index.ts", + "preLaunchTask": "tsc: build - tsconfig.json", + "outFiles": [ + "${workspaceFolder}/packages/relayer/dist/**/*.js" + ] + } + ] +} \ No newline at end of file diff --git a/automated-orders/README.md b/automated-orders/README.md index 1ed0fb135..7e187ec2c 100644 --- a/automated-orders/README.md +++ b/automated-orders/README.md @@ -1 +1,20 @@ # Environment variables + +## @warden-automated-orders/scheduler + +```bash +# example below + +ETHEREUM_NODE_RPC=https://localhost:1122 +ETHEREUM_REGISTRY_ADDRESS=0x +``` + +## @warden-automated-orders/relayer + +```bash +# example below + +ETHEREUM_NODE_RPC=https://localhost:1122 +WARDEN_RPC_URL=https://localhost:1133 +WARDEN_POLLING_INTERVAL_MSEC=100 +``` diff --git a/automated-orders/packages/blockchain-library/package.json b/automated-orders/packages/blockchain-library/package.json new file mode 100644 index 000000000..4a1d4b888 --- /dev/null +++ b/automated-orders/packages/blockchain-library/package.json @@ -0,0 +1,25 @@ +{ + "name": "@warden-automated-orders/blockchain", + "version": "1.0.0", + "author": "", + "license": "ISC", + "private": true, + "main": "dist/index.js", + "type": "module", + "files": [ + "dist" + ], + "scripts": { + "build": "tsc --build" + }, + "dependencies": { + "@wardenprotocol/wardenjs": "0.0.11", + "@tanstack/react-query": "^4.36.1", + "web3": "^4.14.0" + }, + "devDependencies": { + "react": "^18.2.0", + "react-dom": "^18.3.1", + "typescript": "^5.6.3" + } +} diff --git a/automated-orders/packages/blockchain-library/src/clients/evm.ts b/automated-orders/packages/blockchain-library/src/clients/evm.ts new file mode 100644 index 000000000..68c5d19cd --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/clients/evm.ts @@ -0,0 +1,15 @@ +import { Web3 } from 'web3'; + +import { IEvmConfiguration } from '../types/evm/configuration.js'; + +export class EvmClient { + web3: Web3; + + constructor(private configuration: IEvmConfiguration) { + this.web3 = new Web3(this.configuration.rpcURL); + } + + async broadcastTx(): Promise { + // TODO: implementation + } +} diff --git a/automated-orders/packages/blockchain-library/src/clients/warden.ts b/automated-orders/packages/blockchain-library/src/clients/warden.ts new file mode 100644 index 000000000..1e6bfae18 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/clients/warden.ts @@ -0,0 +1,51 @@ +import * as utils from '@warden-automated-orders/utils'; +import { warden } from '@wardenprotocol/wardenjs'; +import { SignRequest, SignRequestStatus } from '@wardenprotocol/wardenjs/codegen/warden/warden/v1beta3/signature'; + +import { IWardenConfiguration } from '../types/warden/configuration.js'; +import { INewSignatureRequest } from '../types/warden/newSignatureRequest.js'; + +const { delay } = utils; +const { createRPCQueryClient } = warden.ClientFactory; + +export class WardenClient { + constructor(private configuration: IWardenConfiguration) {} + + async query() { + return await createRPCQueryClient({ rpcEndpoint: this.configuration.rpcURL }); + } + + async *pollPendingSignatureRequests(): AsyncGenerator { + while (true) { + await delay(this.configuration.pollingIntervalMsec); + + // TODO: query paged fulfilled sign requests + // const query = (await this.query()).warden.warden.v1beta3; + const signRequests: SignRequest[] = [ + { + id: 1n, + creator: 'string', + keyId: 1n, + dataForSigning: new Uint8Array(), + status: SignRequestStatus.SIGN_REQUEST_STATUS_FULFILLED, + signedData: new Uint8Array(), + rejectReason: 'string', + encryptionKey: new Uint8Array(), + deductedKeychainFees: [], + }, + ]; + + for (let i = 0; i < signRequests.length; i++) { + const request = signRequests[i]; + + if (!request.signedData) { + continue; + } + + yield { + signedData: request.signedData!, + }; + } + } + } +} diff --git a/automated-orders/packages/blockchain-library/src/index.ts b/automated-orders/packages/blockchain-library/src/index.ts new file mode 100644 index 000000000..00445a26b --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/index.ts @@ -0,0 +1,4 @@ +export { WardenClient } from './clients/warden.js'; +export { EvmClient } from './clients/evm.js'; +export { NewSignatureProcessor } from './processors/newSignatureProcessor.js'; +export { INewSignatureRequest } from './types/warden/newSignatureRequest.js'; diff --git a/automated-orders/packages/blockchain-library/src/processors/newSignatureProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/newSignatureProcessor.ts new file mode 100644 index 000000000..86dd5fe49 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/processors/newSignatureProcessor.ts @@ -0,0 +1,29 @@ +import { logError, logInfo, serialize } from '@warden-automated-orders/utils'; + +import { EvmClient } from '../clients/evm.js'; +import { INewSignatureRequest } from '../types/warden/newSignatureRequest.js'; +import { Processor } from './processor.js'; + +export class NewSignatureProcessor extends Processor { + constructor( + private evm: EvmClient, + generator: () => AsyncGenerator, + ) { + super(generator); + } + + async handle(data: INewSignatureRequest): Promise { + try { + logInfo(`New Signature request ${serialize(data)}`); + + // TODO: implementation + await this.evm.broadcastTx(); + + return true; + } catch (error) { + logError(`New Signature error ${serialize(data)}. Error: ${error}, Stack trace: ${error.stack}`); + + return false; + } + } +} diff --git a/automated-orders/packages/blockchain-library/src/processors/processor.ts b/automated-orders/packages/blockchain-library/src/processors/processor.ts new file mode 100644 index 000000000..684726679 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/processors/processor.ts @@ -0,0 +1,30 @@ +import { delay, logError } from '@warden-automated-orders/utils'; + +export abstract class Processor { + constructor(private generator: () => AsyncGenerator) {} + + async start(): Promise { + // eslint-disable-next-line no-constant-condition + while (true) { + try { + for await (const request of this.generator()) { + let result = false; + + while (result !== true) { + result = await this.handle(request); + + if (!result) { + await delay(1_000); + } + } + } + } catch (error) { + logError(error); + + await delay(5_000); + } + } + } + + abstract handle(data: T): Promise; +} diff --git a/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts b/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts new file mode 100644 index 000000000..d9f7bb896 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts @@ -0,0 +1,3 @@ +export interface IEvmConfiguration { + rpcURL: string; +} diff --git a/automated-orders/packages/blockchain-library/src/types/registry/events.ts b/automated-orders/packages/blockchain-library/src/types/registry/events.ts new file mode 100644 index 000000000..dc83e74d0 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/types/registry/events.ts @@ -0,0 +1,9 @@ +import { EventLog } from 'web3'; + +export interface OrderCreated extends EventLog { + type: 'OrderCreated'; + returnValues: { + creator: string; + order: string; + }; +} diff --git a/automated-orders/packages/blockchain-library/src/types/warden/configuration.ts b/automated-orders/packages/blockchain-library/src/types/warden/configuration.ts new file mode 100644 index 000000000..208fefb46 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/types/warden/configuration.ts @@ -0,0 +1,4 @@ +export interface IWardenConfiguration { + rpcURL: string; + pollingIntervalMsec: number; +} diff --git a/automated-orders/packages/blockchain-library/src/types/warden/newSignatureRequest.ts b/automated-orders/packages/blockchain-library/src/types/warden/newSignatureRequest.ts new file mode 100644 index 000000000..1f60c49c1 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/types/warden/newSignatureRequest.ts @@ -0,0 +1,3 @@ +export interface INewSignatureRequest { + signedData: Uint8Array; +} diff --git a/automated-orders/packages/blockchain-library/tsconfig.json b/automated-orders/packages/blockchain-library/tsconfig.json new file mode 100644 index 000000000..bddccf642 --- /dev/null +++ b/automated-orders/packages/blockchain-library/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "removeComments": true, + "allowSyntheticDefaultImports": true, + "noImplicitAny": false, + "strictBindCallApply": false, + "noFallthroughCasesInSwitch": false, + "outDir": "dist", + "rootDir": "src", + "composite": true + }, + "include": [ + "src" + ], + "exclude": [ + "dist", + "node_modules" + ], + "compileOnSave": true +} \ No newline at end of file diff --git a/automated-orders/packages/relayer/package.json b/automated-orders/packages/relayer/package.json index ab2347eea..b75fa2c80 100644 --- a/automated-orders/packages/relayer/package.json +++ b/automated-orders/packages/relayer/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@warden-automated-orders/utils": "1.0.0", + "@warden-automated-orders/blockchain": "1.0.0", "dotenv": "^16.4.5", "env-schema": "^6.0.0" }, diff --git a/automated-orders/packages/relayer/src/config/config.ts b/automated-orders/packages/relayer/src/config/config.ts new file mode 100644 index 000000000..b0b64bf5f --- /dev/null +++ b/automated-orders/packages/relayer/src/config/config.ts @@ -0,0 +1,18 @@ +import { JSONSchemaType, envSchema } from 'env-schema'; + +import { Env } from './env.js'; + +const schema: JSONSchemaType = { + type: 'object', + required: ['ETHEREUM_NODE_RPC', 'WARDEN_RPC_URL', 'WARDEN_POLLING_INTERVAL_MSEC'], + properties: { + ETHEREUM_NODE_RPC: { type: 'string' }, + WARDEN_RPC_URL: { type: 'string' }, + WARDEN_POLLING_INTERVAL_MSEC: { type: 'number' }, + }, +}; + +export const config = envSchema({ + schema, + dotenv: true, +}); diff --git a/automated-orders/packages/relayer/src/config/env.ts b/automated-orders/packages/relayer/src/config/env.ts new file mode 100644 index 000000000..f016d7af4 --- /dev/null +++ b/automated-orders/packages/relayer/src/config/env.ts @@ -0,0 +1,5 @@ +export interface Env { + ETHEREUM_NODE_RPC: string; + WARDEN_RPC_URL: string; + WARDEN_POLLING_INTERVAL_MSEC: number; +} diff --git a/automated-orders/packages/relayer/src/index.ts b/automated-orders/packages/relayer/src/index.ts index 9799a6135..7d3ba90ba 100644 --- a/automated-orders/packages/relayer/src/index.ts +++ b/automated-orders/packages/relayer/src/index.ts @@ -1,9 +1,29 @@ -import { logError, logInfo } from '@warden-automated-orders/utils'; +import { EvmClient, NewSignatureProcessor, WardenClient } from '@warden-automated-orders/blockchain'; +import { logError } from '@warden-automated-orders/utils'; + +import { config } from './config/config.js'; async function main() { - logInfo('main'); + const warden = new WardenClient({ + rpcURL: config.WARDEN_RPC_URL, + pollingIntervalMsec: config.WARDEN_POLLING_INTERVAL_MSEC, + }); + + const ethereum = new EvmClient({ + rpcURL: config.ETHEREUM_NODE_RPC, + }); + + const newSignatureRequestProcess = new NewSignatureProcessor( + ethereum, + warden.pollPendingSignatureRequests.bind(warden), + ).start(); + + await Promise.all([newSignatureRequestProcess]); } main() - .catch((e) => logError(e)) + .catch((e) => { + logError(e); + process.exit(1); + }) .finally(() => process.exit()); diff --git a/automated-orders/packages/scheduler/package.json b/automated-orders/packages/scheduler/package.json index 05679c360..079ac2d0f 100644 --- a/automated-orders/packages/scheduler/package.json +++ b/automated-orders/packages/scheduler/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@warden-automated-orders/utils": "1.0.0", + "@warden-automated-orders/blockchain": "1.0.0", "dotenv": "^16.4.5", "env-schema": "^6.0.0" }, diff --git a/automated-orders/packages/scheduler/src/config/config.ts b/automated-orders/packages/scheduler/src/config/config.ts new file mode 100644 index 000000000..94557b22e --- /dev/null +++ b/automated-orders/packages/scheduler/src/config/config.ts @@ -0,0 +1,17 @@ +import { JSONSchemaType, envSchema } from 'env-schema'; + +import { Env } from './env.js'; + +const schema: JSONSchemaType = { + type: 'object', + required: ['ETHEREUM_NODE_RPC', 'ETHEREUM_REGISTRY_ADDRESS'], + properties: { + ETHEREUM_NODE_RPC: { type: 'string' }, + ETHEREUM_REGISTRY_ADDRESS: { type: 'string' }, + }, +}; + +export const config = envSchema({ + schema, + dotenv: true, +}); diff --git a/automated-orders/packages/scheduler/src/config/env.ts b/automated-orders/packages/scheduler/src/config/env.ts new file mode 100644 index 000000000..2625cada5 --- /dev/null +++ b/automated-orders/packages/scheduler/src/config/env.ts @@ -0,0 +1,4 @@ +export interface Env { + ETHEREUM_NODE_RPC: string; + ETHEREUM_REGISTRY_ADDRESS: string; +} diff --git a/automated-orders/packages/scheduler/src/index.ts b/automated-orders/packages/scheduler/src/index.ts index 9799a6135..40d0082b3 100644 --- a/automated-orders/packages/scheduler/src/index.ts +++ b/automated-orders/packages/scheduler/src/index.ts @@ -5,5 +5,8 @@ async function main() { } main() - .catch((e) => logError(e)) + .catch((e) => { + logError(e); + process.exit(1); + }) .finally(() => process.exit()); diff --git a/automated-orders/tsconfig.json b/automated-orders/tsconfig.json index 16e33cec9..e8f64bec0 100644 --- a/automated-orders/tsconfig.json +++ b/automated-orders/tsconfig.json @@ -17,6 +17,9 @@ "dist" ], "references": [ + { + "path": "./packages/blockchain-library" + }, { "path": "./packages/utils-library" }, diff --git a/automated-orders/yarn.lock b/automated-orders/yarn.lock index 3cbc9006d..ebb4dc5e1 100644 --- a/automated-orders/yarn.lock +++ b/automated-orders/yarn.lock @@ -7,6 +7,11 @@ resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== +"@adraffy/ens-normalize@^1.8.8": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz#42cc67c5baa407ac25059fcd7d405cc5ecdb0c33" + integrity sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg== + "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": version "7.23.5" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz" @@ -127,6 +132,156 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" +"@confio/ics23@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@confio/ics23/-/ics23-0.6.8.tgz#2a6b4f1f2b7b20a35d9a0745bb5a446e72930b3d" + integrity sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w== + dependencies: + "@noble/hashes" "^1.0.0" + protobufjs "^6.8.8" + +"@cosmjs/amino@0.32.3": + version "0.32.3" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.32.3.tgz#b81d4a2b8d61568431a1afcd871e1344a19d97ff" + integrity sha512-G4zXl+dJbqrz1sSJ56H/25l5NJEk/pAPIr8piAHgbXYw88OdAOlpA26PQvk2IbSN/rRgVbvlLTNgX2tzz1dyUA== + dependencies: + "@cosmjs/crypto" "^0.32.3" + "@cosmjs/encoding" "^0.32.3" + "@cosmjs/math" "^0.32.3" + "@cosmjs/utils" "^0.32.3" + +"@cosmjs/amino@^0.32.3", "@cosmjs/amino@^0.32.4": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.32.4.tgz#3908946c0394e6d431694c8992c5147079a1c860" + integrity sha512-zKYOt6hPy8obIFtLie/xtygCkH9ZROiQ12UHfKsOkWaZfPQUvVbtgmu6R4Kn1tFLI/SRkw7eqhaogmW/3NYu/Q== + dependencies: + "@cosmjs/crypto" "^0.32.4" + "@cosmjs/encoding" "^0.32.4" + "@cosmjs/math" "^0.32.4" + "@cosmjs/utils" "^0.32.4" + +"@cosmjs/crypto@^0.32.3", "@cosmjs/crypto@^0.32.4": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.32.4.tgz#5d29633b661eaf092ddb3e7ea6299cfd6f4507a2" + integrity sha512-zicjGU051LF1V9v7bp8p7ovq+VyC91xlaHdsFOTo2oVry3KQikp8L/81RkXmUIT8FxMwdx1T7DmFwVQikcSDIw== + dependencies: + "@cosmjs/encoding" "^0.32.4" + "@cosmjs/math" "^0.32.4" + "@cosmjs/utils" "^0.32.4" + "@noble/hashes" "^1" + bn.js "^5.2.0" + elliptic "^6.5.4" + libsodium-wrappers-sumo "^0.7.11" + +"@cosmjs/encoding@^0.32.3", "@cosmjs/encoding@^0.32.4": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.32.4.tgz#646e0e809f7f4f1414d8fa991fb0ffe6c633aede" + integrity sha512-tjvaEy6ZGxJchiizzTn7HVRiyTg1i4CObRRaTRPknm5EalE13SV+TCHq38gIDfyUeden4fCuaBVEdBR5+ti7Hw== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + +"@cosmjs/json-rpc@^0.32.4": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.32.4.tgz#be91eb89ea78bd5dc02d0a9fa184dd6790790f0b" + integrity sha512-/jt4mBl7nYzfJ2J/VJ+r19c92mUKF0Lt0JxM3MXEJl7wlwW5haHAWtzRujHkyYMXOwIR+gBqT2S0vntXVBRyhQ== + dependencies: + "@cosmjs/stream" "^0.32.4" + xstream "^11.14.0" + +"@cosmjs/math@^0.32.3", "@cosmjs/math@^0.32.4": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.32.4.tgz#87ac9eadc06696e30a30bdb562a495974bfd0a1a" + integrity sha512-++dqq2TJkoB8zsPVYCvrt88oJWsy1vMOuSOKcdlnXuOA/ASheTJuYy4+oZlTQ3Fr8eALDLGGPhJI02W2HyAQaw== + dependencies: + bn.js "^5.2.0" + +"@cosmjs/proto-signing@0.32.3": + version "0.32.3" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.3.tgz#91ae149b747d18666a6ccc924165b306431f7c0d" + integrity sha512-kSZ0ZUY0DwcRT0NcIn2HkadH4NKlwjfZgbLj1ABwh/4l0RgeT84QCscZCu63tJYq3K6auwqTiZSZERwlO4/nbg== + dependencies: + "@cosmjs/amino" "^0.32.3" + "@cosmjs/crypto" "^0.32.3" + "@cosmjs/encoding" "^0.32.3" + "@cosmjs/math" "^0.32.3" + "@cosmjs/utils" "^0.32.3" + cosmjs-types "^0.9.0" + +"@cosmjs/proto-signing@^0.32.3": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.4.tgz#5a06e087c6d677439c8c9b25b5223d5e72c4cd93" + integrity sha512-QdyQDbezvdRI4xxSlyM1rSVBO2st5sqtbEIl3IX03uJ7YiZIQHyv6vaHVf1V4mapusCqguiHJzm4N4gsFdLBbQ== + dependencies: + "@cosmjs/amino" "^0.32.4" + "@cosmjs/crypto" "^0.32.4" + "@cosmjs/encoding" "^0.32.4" + "@cosmjs/math" "^0.32.4" + "@cosmjs/utils" "^0.32.4" + cosmjs-types "^0.9.0" + +"@cosmjs/socket@^0.32.4": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.32.4.tgz#86ab6adf3a442314774c0810b7a7cfcddf4f2082" + integrity sha512-davcyYziBhkzfXQTu1l5NrpDYv0K9GekZCC9apBRvL1dvMc9F/ygM7iemHjUA+z8tJkxKxrt/YPjJ6XNHzLrkw== + dependencies: + "@cosmjs/stream" "^0.32.4" + isomorphic-ws "^4.0.1" + ws "^7" + xstream "^11.14.0" + +"@cosmjs/stargate@0.32.3": + version "0.32.3" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.3.tgz#5a92b222ada960ebecea72cc9f366370763f4b66" + integrity sha512-OQWzO9YWKerUinPIxrO1MARbe84XkeXJAW0lyMIjXIEikajuXZ+PwftiKA5yA+8OyditVmHVLtPud6Pjna2s5w== + dependencies: + "@confio/ics23" "^0.6.8" + "@cosmjs/amino" "^0.32.3" + "@cosmjs/encoding" "^0.32.3" + "@cosmjs/math" "^0.32.3" + "@cosmjs/proto-signing" "^0.32.3" + "@cosmjs/stream" "^0.32.3" + "@cosmjs/tendermint-rpc" "^0.32.3" + "@cosmjs/utils" "^0.32.3" + cosmjs-types "^0.9.0" + xstream "^11.14.0" + +"@cosmjs/stream@^0.32.3", "@cosmjs/stream@^0.32.4": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.32.4.tgz#83e1f2285807467c56d9ea0e1113f79d9fa63802" + integrity sha512-Gih++NYHEiP+oyD4jNEUxU9antoC0pFSg+33Hpp0JlHwH0wXhtD3OOKnzSfDB7OIoEbrzLJUpEjOgpCp5Z+W3A== + dependencies: + xstream "^11.14.0" + +"@cosmjs/tendermint-rpc@^0.32.3": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.4.tgz#b36f9ec657498e42c97e21bb7368798ef6279752" + integrity sha512-MWvUUno+4bCb/LmlMIErLypXxy7ckUuzEmpufYYYd9wgbdCXaTaO08SZzyFM5PI8UJ/0S2AmUrgWhldlbxO8mw== + dependencies: + "@cosmjs/crypto" "^0.32.4" + "@cosmjs/encoding" "^0.32.4" + "@cosmjs/json-rpc" "^0.32.4" + "@cosmjs/math" "^0.32.4" + "@cosmjs/socket" "^0.32.4" + "@cosmjs/stream" "^0.32.4" + "@cosmjs/utils" "^0.32.4" + axios "^1.6.0" + readonly-date "^1.0.0" + xstream "^11.14.0" + +"@cosmjs/utils@^0.32.3", "@cosmjs/utils@^0.32.4": + version "0.32.4" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.4.tgz#a9a717c9fd7b1984d9cefdd0ef6c6f254060c671" + integrity sha512-D1Yc+Zy8oL/hkUkFUL/bwxvuDBzRGpc4cF7/SkdhxX4iHpSLgdOuTt1mhCh9+kl6NQREy9t7SYZ6xeW5gFe60w== + +"@cosmology/lcd@^0.13.3": + version "0.13.5" + resolved "https://registry.yarnpkg.com/@cosmology/lcd/-/lcd-0.13.5.tgz#1bc4d43d525ecd68d09211d2ce17332a149a1a00" + integrity sha512-CI8KFsJcgp0RINF8wHpv3Y9yR4Fb9ZnGucyoUICjtX2XT4NVBK+fvZuRFj5TP34km8TpEOb+WV2T7IN/pZsD7Q== + dependencies: + axios "1.7.4" + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -164,6 +319,16 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== +"@ethereumjs/rlp@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" + integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== + +"@ethereumjs/rlp@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-5.0.2.tgz#c89bd82f2f3bec248ab2d517ae25f5bbc4aac842" + integrity sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA== + "@humanwhocodes/config-array@^0.13.0": version "0.13.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" @@ -215,6 +380,23 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@noble/curves@1.4.2", "@noble/curves@~1.4.0": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9" + integrity sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw== + dependencies: + "@noble/hashes" "1.4.0" + +"@noble/hashes@1.4.0", "@noble/hashes@~1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + +"@noble/hashes@^1", "@noble/hashes@^1.0.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" + integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -236,6 +418,94 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@scure/base@~1.1.6": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" + integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== + +"@scure/bip32@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67" + integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg== + dependencies: + "@noble/curves" "~1.4.0" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" + +"@scure/bip39@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3" + integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ== + dependencies: + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" + +"@tanstack/query-core@4.36.1": + version "4.36.1" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.36.1.tgz#79f8c1a539d47c83104210be2388813a7af2e524" + integrity sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA== + +"@tanstack/react-query@^4.36.1": + version "4.36.1" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.36.1.tgz#acb589fab4085060e2e78013164868c9c785e5d2" + integrity sha512-y7ySVHFyyQblPl3J3eQBWpXZkliroki3ARnBKsdJchlgt7yJLRDUcf4B8soufgiYt3pEQIkBWBx1N9/ZPIeUWw== + dependencies: + "@tanstack/query-core" "4.36.1" + use-sync-external-store "^1.2.0" + "@trivago/prettier-plugin-sort-imports@^4.3.0": version "4.3.0" resolved "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz" @@ -248,6 +518,25 @@ javascript-natural-sort "0.7.1" lodash "^4.17.21" +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + +"@types/node@*", "@types/node@>=13.7.0": + version "22.9.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.0.tgz#b7f16e5c3384788542c72dc3d561a7ceae2c0365" + integrity sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ== + dependencies: + undici-types "~6.19.8" + +"@types/ws@8.5.3": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + "@typescript-eslint/eslint-plugin@^8.13.0": version "8.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.13.0.tgz#650c50b8c795b5d092189f139f6d00535b5b0f3d" @@ -334,6 +623,24 @@ resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== +"@wardenprotocol/wardenjs@0.0.11": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@wardenprotocol/wardenjs/-/wardenjs-0.0.11.tgz#0c3715a6ecb1e3f7c96494ee8663350909fb2e3f" + integrity sha512-x0xtyHgE6fO1G859cl//iqkrG/Jhz9JuxU6B9mubRUvriugTfURFfCPkEhUaL+gc7CZeeKYdvlhEJOUJO7RBfg== + dependencies: + "@cosmjs/amino" "0.32.3" + "@cosmjs/math" "^0.32.3" + "@cosmjs/proto-signing" "0.32.3" + "@cosmjs/stargate" "0.32.3" + "@cosmjs/tendermint-rpc" "^0.32.3" + "@cosmology/lcd" "^0.13.3" + protobufjs "^7.2.6" + +abitype@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.7.1.tgz#16db20abe67de80f6183cf75f3de1ff86453b745" + integrity sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ== + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" @@ -388,11 +695,61 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + +axios@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2" + integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + +axios@^1.6.0: + version "1.7.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bech32@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -415,6 +772,22 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +call-bind@^1.0.2, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" @@ -461,11 +834,35 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +cosmjs-types@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.9.0.tgz#c3bc482d28c7dfa25d1445093fdb2d9da1f6cfcc" + integrity sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ== + +crc-32@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== + +cross-fetch@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== + dependencies: + node-fetch "^2.6.12" + cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" @@ -487,6 +884,29 @@ deep-is@^0.1.3: resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +define-data-property@^1.0.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" @@ -504,6 +924,19 @@ dotenv@^16.4.5: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== +elliptic@^6.5.4: + version "6.6.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.0.tgz#5919ec723286c1edf28685aa89261d4761afa210" + integrity sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + env-schema@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/env-schema/-/env-schema-6.0.0.tgz#94be5a173306c10523c96fd1dd6ac986312f1532" @@ -513,6 +946,18 @@ env-schema@^6.0.0: dotenv "^16.4.5" dotenv-expand "10.0.0" +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" @@ -618,6 +1063,21 @@ esutils@^2.0.2: resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +ethereum-cryptography@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz#58f2810f8e020aecb97de8c8c76147600b0b8ccf" + integrity sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg== + dependencies: + "@noble/curves" "1.4.2" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.3.0" + +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -692,11 +1152,48 @@ flatted@^3.2.9: resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +form-data@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" @@ -735,6 +1232,21 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" +globalthis@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== + dependencies: + define-properties "^1.2.1" + gopd "^1.0.1" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graphemer@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" @@ -750,6 +1262,54 @@ has-flag@^4.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + ignore@^5.2.0: version "5.3.1" resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz" @@ -781,16 +1341,36 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.3: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" @@ -808,17 +1388,34 @@ is-path-inside@^3.0.3: resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-typed-array@^1.1.3: + version "1.1.13" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== + dependencies: + which-typed-array "^1.1.14" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== + javascript-natural-sort@0.7.1: version "0.7.1" resolved "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz" integrity sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw== -js-tokens@^4.0.0: +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -870,6 +1467,18 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +libsodium-sumo@^0.7.15: + version "0.7.15" + resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.15.tgz#91c1d863fe3fbce6d6b9db1aadaa622733a1d007" + integrity sha512-5tPmqPmq8T8Nikpm1Nqj0hBHvsLFCXvdhBFV7SGOitQPZAA6jso8XoL0r4L7vmfKXr486fiQInvErHtEvizFMw== + +libsodium-wrappers-sumo@^0.7.11: + version "0.7.15" + resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.15.tgz#0ef2a99b4b17e8385aa7e6850593660dbaf5fb40" + integrity sha512-aSWY8wKDZh5TC7rMvEdTHoyppVq/1dTSAeAR7H6pzd6QRT3vQWcT5pGwCotLcpPEOLXX6VvqihSPkpEhYAjANA== + dependencies: + libsodium-sumo "^0.7.15" + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" @@ -887,6 +1496,23 @@ lodash@^4.17.21: resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +long@^5.0.0: + version "5.2.3" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" + integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== + +loose-envify@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + merge2@^1.3.0: version "1.4.1" resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" @@ -900,6 +1526,28 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" @@ -924,6 +1572,18 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +node-fetch@^2.6.12: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + once@^1.3.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" @@ -984,6 +1644,11 @@ picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" @@ -994,6 +1659,48 @@ prettier@^3.2.4: resolved "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== +protobufjs@^6.8.8: + version "6.11.4" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" + integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + +protobufjs@^7.2.6: + version "7.4.0" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.4.0.tgz#7efe324ce9b3b61c82aae5de810d287bc08a248a" + integrity sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + punycode@^2.1.0: version "2.3.1" resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" @@ -1004,6 +1711,26 @@ queue-microtask@^1.2.2: resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +react-dom@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.2" + +react@^18.2.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + +readonly-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" + integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== + require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" @@ -1033,11 +1760,35 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + semver@^7.6.0: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -1081,6 +1832,11 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +symbol-observable@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" + integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" @@ -1098,6 +1854,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + ts-api-utils@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.0.tgz#709c6f2076e511a81557f3d07a0cbd566ae8195c" @@ -1125,6 +1886,11 @@ typescript@^5.6.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== +undici-types@~6.19.8: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" @@ -1132,6 +1898,273 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +use-sync-external-store@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz#c3b6390f3a30eba13200d2302dcdf1e7b57b2ef9" + integrity sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw== + +util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +web3-core@^4.4.0, web3-core@^4.5.0, web3-core@^4.5.1, web3-core@^4.6.0, web3-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-4.7.0.tgz#a109ed079e5f98a968487f4bb18c7aaf845f768a" + integrity sha512-skP4P56fhlrE+rIuS4WY9fTdja1DPml2xrrDmv+vQhPtmSFBs7CqesycIRLQh4dK1D4de/a23tkX6DLYdUt3nA== + dependencies: + web3-errors "^1.3.0" + web3-eth-accounts "^4.2.1" + web3-eth-iban "^4.0.7" + web3-providers-http "^4.2.0" + web3-providers-ws "^4.0.8" + web3-types "^1.8.1" + web3-utils "^4.3.2" + web3-validator "^2.0.6" + optionalDependencies: + web3-providers-ipc "^4.0.7" + +web3-errors@^1.1.3, web3-errors@^1.2.0, web3-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/web3-errors/-/web3-errors-1.3.0.tgz#504e4d3218899df108856940087a8022d6688d74" + integrity sha512-j5JkAKCtuVMbY3F5PYXBqg1vWrtF4jcyyMY1rlw8a4PV67AkqlepjGgpzWJZd56Mt+TvHy6DA1F/3Id8LatDSQ== + dependencies: + web3-types "^1.7.0" + +web3-eth-abi@^4.2.3, web3-eth-abi@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-4.3.0.tgz#9036541206418b9db6f1db295ad87a6f0fa0ed7d" + integrity sha512-OqZPGGxHmfKJt33BfpclEMmWvnnLJ/B+jVTnVagd2OIU1kIv09xf/E60ei0eGeG612uFy/pPq31u4RidF/gf6g== + dependencies: + abitype "0.7.1" + web3-errors "^1.3.0" + web3-types "^1.8.1" + web3-utils "^4.3.2" + web3-validator "^2.0.6" + +web3-eth-accounts@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-4.2.1.tgz#db27399137e1a26f9d467b9500019a70771f5724" + integrity sha512-aOlEZFzqAgKprKs7+DGArU4r9b+ILBjThpeq42aY7LAQcP+mSpsWcQgbIRK3r/n3OwTYZ3aLPk0Ih70O/LwnYA== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + crc-32 "^1.2.2" + ethereum-cryptography "^2.0.0" + web3-errors "^1.3.0" + web3-types "^1.7.0" + web3-utils "^4.3.1" + web3-validator "^2.0.6" + +web3-eth-contract@^4.5.0, web3-eth-contract@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-4.7.0.tgz#119a744e8a35f60fd7bc3e4f8637f0380a3d0e85" + integrity sha512-fdStoBOjFyMHwlyJmSUt/BTDL1ATwKGmG3zDXQ/zTKlkkW/F/074ut0Vry4GuwSBg9acMHc0ycOiZx9ZKjNHsw== + dependencies: + "@ethereumjs/rlp" "^5.0.2" + web3-core "^4.5.1" + web3-errors "^1.3.0" + web3-eth "^4.8.2" + web3-eth-abi "^4.2.3" + web3-types "^1.7.0" + web3-utils "^4.3.1" + web3-validator "^2.0.6" + +web3-eth-ens@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-4.4.0.tgz#bc0d11d755cb15ed4b82e38747c5104622d9a4b9" + integrity sha512-DeyVIS060hNV9g8dnTx92syqvgbvPricE3MerCxe/DquNZT3tD8aVgFfq65GATtpCgDDJffO2bVeHp3XBemnSQ== + dependencies: + "@adraffy/ens-normalize" "^1.8.8" + web3-core "^4.5.0" + web3-errors "^1.2.0" + web3-eth "^4.8.0" + web3-eth-contract "^4.5.0" + web3-net "^4.1.0" + web3-types "^1.7.0" + web3-utils "^4.3.0" + web3-validator "^2.0.6" + +web3-eth-iban@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-4.0.7.tgz#ee504f845d7b6315f0be78fcf070ccd5d38e4aaf" + integrity sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ== + dependencies: + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + web3-validator "^2.0.3" + +web3-eth-personal@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-4.1.0.tgz#f5b506a4570bf1241d1db2de12cb413ea0bb4486" + integrity sha512-RFN83uMuvA5cu1zIwwJh9A/bAj0OBxmGN3tgx19OD/9ygeUZbifOL06jgFzN0t+1ekHqm3DXYQM8UfHpXi7yDQ== + dependencies: + web3-core "^4.6.0" + web3-eth "^4.9.0" + web3-rpc-methods "^1.3.0" + web3-types "^1.8.0" + web3-utils "^4.3.1" + web3-validator "^2.0.6" + +web3-eth@^4.10.0, web3-eth@^4.8.0, web3-eth@^4.8.2, web3-eth@^4.9.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-4.10.0.tgz#a62017908e543fe1bae398e2384bd29d1ebbbacd" + integrity sha512-8d7epCOm1hv/xGnOW8pWNkO5Ze9b+LKl81Pa1VUdRi2xZKtBaQsk+4qg6EnqeDF6SPpL502wNmX6TAB69vGBWw== + dependencies: + setimmediate "^1.0.5" + web3-core "^4.7.0" + web3-errors "^1.3.0" + web3-eth-abi "^4.3.0" + web3-eth-accounts "^4.2.1" + web3-net "^4.1.0" + web3-providers-ws "^4.0.8" + web3-rpc-methods "^1.3.0" + web3-types "^1.8.1" + web3-utils "^4.3.2" + web3-validator "^2.0.6" + +web3-net@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-4.1.0.tgz#db7bde675e58b153339e4f149f29ec0410d6bab2" + integrity sha512-WWmfvHVIXWEoBDWdgKNYKN8rAy6SgluZ0abyRyXOL3ESr7ym7pKWbfP4fjApIHlYTh8tNqkrdPfM4Dyi6CA0SA== + dependencies: + web3-core "^4.4.0" + web3-rpc-methods "^1.3.0" + web3-types "^1.6.0" + web3-utils "^4.3.0" + +web3-providers-http@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-4.2.0.tgz#0f4bf424681a068d49994aa7fabc69bed45ac50b" + integrity sha512-IPMnDtHB7dVwaB7/mMxAZzyq7d5ezfO1+Vw0bNfAeIi7gaDlJiggp85SdyAfOgov8AMUA/dyiY72kQ0KmjXKvQ== + dependencies: + cross-fetch "^4.0.0" + web3-errors "^1.3.0" + web3-types "^1.7.0" + web3-utils "^4.3.1" + +web3-providers-ipc@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-4.0.7.tgz#9ec4c8565053af005a5170ba80cddeb40ff3e3d3" + integrity sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g== + dependencies: + web3-errors "^1.1.3" + web3-types "^1.3.0" + web3-utils "^4.0.7" + +web3-providers-ws@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-4.0.8.tgz#6de7b262f7ec6df1a2dff466ba91d7ebdac2c45e" + integrity sha512-goJdgata7v4pyzHRsg9fSegUG4gVnHZSHODhNnn6J93ykHkBI1nz4fjlGpcQLUMi4jAMz6SHl9Ibzs2jj9xqPw== + dependencies: + "@types/ws" "8.5.3" + isomorphic-ws "^5.0.0" + web3-errors "^1.2.0" + web3-types "^1.7.0" + web3-utils "^4.3.1" + ws "^8.17.1" + +web3-rpc-methods@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/web3-rpc-methods/-/web3-rpc-methods-1.3.0.tgz#d5ee299a69389d63822d354ddee2c6a121a6f670" + integrity sha512-/CHmzGN+IYgdBOme7PdqzF+FNeMleefzqs0LVOduncSaqsppeOEoskLXb2anSpzmQAP3xZJPaTrkQPWSJMORig== + dependencies: + web3-core "^4.4.0" + web3-types "^1.6.0" + web3-validator "^2.0.6" + +web3-rpc-providers@^1.0.0-rc.2: + version "1.0.0-rc.2" + resolved "https://registry.yarnpkg.com/web3-rpc-providers/-/web3-rpc-providers-1.0.0-rc.2.tgz#2f3bf62415708ce09ffd5c77d197046e7d5fefb1" + integrity sha512-ocFIEXcBx/DYQ90HhVepTBUVnL9pGsZw8wyPb1ZINSenwYus9SvcFkjU1Hfvd/fXjuhAv2bUVch9vxvMx1mXAQ== + dependencies: + web3-errors "^1.3.0" + web3-providers-http "^4.2.0" + web3-providers-ws "^4.0.8" + web3-types "^1.7.0" + web3-utils "^4.3.1" + web3-validator "^2.0.6" + +web3-types@^1.3.0, web3-types@^1.6.0, web3-types@^1.7.0, web3-types@^1.8.0, web3-types@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/web3-types/-/web3-types-1.8.1.tgz#6379aca0f99330eb0f8f6ca80a3de93129b58339" + integrity sha512-isspsvQbBJFUkJYz2Badb7dz/BrLLLpOop/WmnL5InyYMr7kYYc8038NYO7Vkp1M7Bupa/wg+yALvBm7EGbyoQ== + +web3-utils@^4.0.7, web3-utils@^4.3.0, web3-utils@^4.3.1, web3-utils@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-4.3.2.tgz#a952428d677b635fd0c16044ae4c534807a39639" + integrity sha512-bEFpYEBMf6ER78Uvj2mdsCbaLGLK9kABOsa3TtXOEEhuaMy/RK0KlRkKoZ2vmf/p3hB8e1q5erknZ6Hy7AVp7A== + dependencies: + ethereum-cryptography "^2.0.0" + eventemitter3 "^5.0.1" + web3-errors "^1.3.0" + web3-types "^1.8.1" + web3-validator "^2.0.6" + +web3-validator@^2.0.3, web3-validator@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/web3-validator/-/web3-validator-2.0.6.tgz#a0cdaa39e1d1708ece5fae155b034e29d6a19248" + integrity sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg== + dependencies: + ethereum-cryptography "^2.0.0" + util "^0.12.5" + web3-errors "^1.2.0" + web3-types "^1.6.0" + zod "^3.21.4" + +web3@^4.14.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/web3/-/web3-4.14.0.tgz#9d69e3a8a64da9377fbec416dfe4d260ddfa2711" + integrity sha512-LohqxtSXXl4uA3abPK0bB91dziA5GygOLtO83p8bQzY+CYxp1fgGfiD8ahDRcu+WBttUhRFZmCsOhmrmP7HtTA== + dependencies: + web3-core "^4.7.0" + web3-errors "^1.3.0" + web3-eth "^4.10.0" + web3-eth-abi "^4.3.0" + web3-eth-accounts "^4.2.1" + web3-eth-contract "^4.7.0" + web3-eth-ens "^4.4.0" + web3-eth-iban "^4.0.7" + web3-eth-personal "^4.1.0" + web3-net "^4.1.0" + web3-providers-http "^4.2.0" + web3-providers-ws "^4.0.8" + web3-rpc-methods "^1.3.0" + web3-rpc-providers "^1.0.0-rc.2" + web3-types "^1.8.1" + web3-utils "^4.3.2" + web3-validator "^2.0.6" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which-typed-array@^1.1.14, which-typed-array@^1.1.2: + version "1.1.15" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.2" + which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -1144,7 +2177,30 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +ws@^7: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== + +ws@^8.17.1: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + +xstream@^11.14.0: + version "11.14.0" + resolved "https://registry.yarnpkg.com/xstream/-/xstream-11.14.0.tgz#2c071d26b18310523b6877e86b4e54df068a9ae5" + integrity sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw== + dependencies: + globalthis "^1.0.1" + symbol-observable "^2.0.3" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zod@^3.21.4: + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== From 7fd60a6da0314f1d00879be645862bc44bb471c3 Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Wed, 6 Nov 2024 15:25:02 +0300 Subject: [PATCH 02/15] Fix namings --- .../packages/blockchain-library/src/clients/warden.ts | 2 +- automated-orders/packages/relayer/src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/automated-orders/packages/blockchain-library/src/clients/warden.ts b/automated-orders/packages/blockchain-library/src/clients/warden.ts index 1e6bfae18..efe2a043f 100644 --- a/automated-orders/packages/blockchain-library/src/clients/warden.ts +++ b/automated-orders/packages/blockchain-library/src/clients/warden.ts @@ -15,7 +15,7 @@ export class WardenClient { return await createRPCQueryClient({ rpcEndpoint: this.configuration.rpcURL }); } - async *pollPendingSignatureRequests(): AsyncGenerator { + async *pollSignatureRequests(): AsyncGenerator { while (true) { await delay(this.configuration.pollingIntervalMsec); diff --git a/automated-orders/packages/relayer/src/index.ts b/automated-orders/packages/relayer/src/index.ts index 7d3ba90ba..0082e73da 100644 --- a/automated-orders/packages/relayer/src/index.ts +++ b/automated-orders/packages/relayer/src/index.ts @@ -15,7 +15,7 @@ async function main() { const newSignatureRequestProcess = new NewSignatureProcessor( ethereum, - warden.pollPendingSignatureRequests.bind(warden), + warden.pollSignatureRequests.bind(warden), ).start(); await Promise.all([newSignatureRequestProcess]); From 15c83590ec51b10cd8d70f6d50a202db52298cb1 Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Thu, 7 Nov 2024 10:21:22 +0300 Subject: [PATCH 03/15] Add event polling --- .../blockchain-library/src/clients/evm.ts | 51 ++++++++++++++++++- .../packages/blockchain-library/src/index.ts | 2 + .../src/processors/orderProcessor.ts | 30 +++++++++++ .../src/types/evm/pollingConfiguration.ts | 4 ++ .../src/types/registry/events.ts | 19 +++++-- .../packages/scheduler/src/config/config.ts | 13 +++-- .../packages/scheduler/src/config/env.ts | 7 ++- .../packages/scheduler/src/index.ts | 19 ++++++- 8 files changed, 133 insertions(+), 12 deletions(-) create mode 100644 automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts create mode 100644 automated-orders/packages/blockchain-library/src/types/evm/pollingConfiguration.ts diff --git a/automated-orders/packages/blockchain-library/src/clients/evm.ts b/automated-orders/packages/blockchain-library/src/clients/evm.ts index 68c5d19cd..b6ce9516c 100644 --- a/automated-orders/packages/blockchain-library/src/clients/evm.ts +++ b/automated-orders/packages/blockchain-library/src/clients/evm.ts @@ -1,6 +1,8 @@ -import { Web3 } from 'web3'; +import { delay } from '@warden-automated-orders/utils'; +import { AbiEventFragment, EventLog, Web3 } from 'web3'; import { IEvmConfiguration } from '../types/evm/configuration.js'; +import { IEventPollingConfiguration } from '../types/evm/pollingConfiguration.js'; export class EvmClient { web3: Web3; @@ -12,4 +14,51 @@ export class EvmClient { async broadcastTx(): Promise { // TODO: implementation } + + async *pollEvents( + contract: string, + startBlock: bigint, + eventAbi: AbiEventFragment, + config: IEventPollingConfiguration, + ): AsyncGenerator { + while (true) { + await delay(config.pollingIntervalMsec); + + const myContract = new this.web3.eth.Contract([eventAbi], contract); + const endBlock = await this.web3.eth.getBlockNumber(); + + let currentBlock = startBlock; + + do { + let nextBlock: bigint; + + if (currentBlock + config.pollingBlocks > endBlock) { + nextBlock = endBlock; + } else { + nextBlock = currentBlock + config.pollingBlocks; + } + + const logs = (await myContract.getPastEvents({ + fromBlock: startBlock, + toBlock: endBlock, + })) as EventLog[]; + + for (const log of logs) { + if (log.event !== eventAbi.name) { + continue; + } + + const event = log as T; + + if (!event) { + continue; + } + + yield event; + } + + currentBlock = nextBlock; + } while (currentBlock < endBlock); + } + } } diff --git a/automated-orders/packages/blockchain-library/src/index.ts b/automated-orders/packages/blockchain-library/src/index.ts index 00445a26b..3922c2cb0 100644 --- a/automated-orders/packages/blockchain-library/src/index.ts +++ b/automated-orders/packages/blockchain-library/src/index.ts @@ -1,4 +1,6 @@ export { WardenClient } from './clients/warden.js'; export { EvmClient } from './clients/evm.js'; export { NewSignatureProcessor } from './processors/newSignatureProcessor.js'; +export { OrderProcessor } from './processors/orderProcessor.js'; export { INewSignatureRequest } from './types/warden/newSignatureRequest.js'; +export { OrderCreated, OrderCreatedAbi } from './types/registry/events.js'; diff --git a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts new file mode 100644 index 000000000..f53192006 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts @@ -0,0 +1,30 @@ +import { logError, logInfo, serialize } from '@warden-automated-orders/utils'; + +import { EvmClient } from '../clients/evm.js'; +import { INewSignatureRequest } from '../types/warden/newSignatureRequest.js'; +import { Processor } from './processor.js'; + +export class OrderProcessor extends Processor { + + + constructor( + private evm: EvmClient, + generator: () => AsyncGenerator, + ) { + super(generator); + } + + async handle(data: INewSignatureRequest): Promise { + try { + logInfo(`New Signature request ${serialize(data)}`); + + // TODO: implementation + + return true; + } catch (error) { + logError(`New Signature error ${serialize(data)}. Error: ${error}, Stack trace: ${error.stack}`); + + return false; + } + } +} diff --git a/automated-orders/packages/blockchain-library/src/types/evm/pollingConfiguration.ts b/automated-orders/packages/blockchain-library/src/types/evm/pollingConfiguration.ts new file mode 100644 index 000000000..bcd8e3901 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/types/evm/pollingConfiguration.ts @@ -0,0 +1,4 @@ +export interface IEventPollingConfiguration { + pollingBlocks: bigint; + pollingIntervalMsec: number; +} diff --git a/automated-orders/packages/blockchain-library/src/types/registry/events.ts b/automated-orders/packages/blockchain-library/src/types/registry/events.ts index dc83e74d0..ed883da4b 100644 --- a/automated-orders/packages/blockchain-library/src/types/registry/events.ts +++ b/automated-orders/packages/blockchain-library/src/types/registry/events.ts @@ -1,9 +1,20 @@ -import { EventLog } from 'web3'; +import { AbiEventFragment, EventLog } from 'web3'; export interface OrderCreated extends EventLog { - type: 'OrderCreated'; returnValues: { - creator: string; - order: string; + from: string; + to: string; + amount: bigint; }; } + +export const OrderCreatedAbi: AbiEventFragment = { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', +}; diff --git a/automated-orders/packages/scheduler/src/config/config.ts b/automated-orders/packages/scheduler/src/config/config.ts index 94557b22e..cdba9a182 100644 --- a/automated-orders/packages/scheduler/src/config/config.ts +++ b/automated-orders/packages/scheduler/src/config/config.ts @@ -4,10 +4,17 @@ import { Env } from './env.js'; const schema: JSONSchemaType = { type: 'object', - required: ['ETHEREUM_NODE_RPC', 'ETHEREUM_REGISTRY_ADDRESS'], + required: [ + 'EVMOS_NODE_RPC', + 'EVMOS_REGISTRY_ADDRESS', + 'ETHEREUM_EVENTS_POLLING_BLOCKS', + 'ETHEREUM_EVENTS_POLLING_INTERVAL_MSEC', + ], properties: { - ETHEREUM_NODE_RPC: { type: 'string' }, - ETHEREUM_REGISTRY_ADDRESS: { type: 'string' }, + EVMOS_NODE_RPC: { type: 'string' }, + EVMOS_REGISTRY_ADDRESS: { type: 'string' }, + ETHEREUM_EVENTS_POLLING_BLOCKS: { type: 'number' }, + ETHEREUM_EVENTS_POLLING_INTERVAL_MSEC: { type: 'number' }, }, }; diff --git a/automated-orders/packages/scheduler/src/config/env.ts b/automated-orders/packages/scheduler/src/config/env.ts index 2625cada5..cd4594d72 100644 --- a/automated-orders/packages/scheduler/src/config/env.ts +++ b/automated-orders/packages/scheduler/src/config/env.ts @@ -1,4 +1,7 @@ export interface Env { - ETHEREUM_NODE_RPC: string; - ETHEREUM_REGISTRY_ADDRESS: string; + EVMOS_NODE_RPC: string; + EVMOS_REGISTRY_ADDRESS: string; + + ETHEREUM_EVENTS_POLLING_BLOCKS: number; + ETHEREUM_EVENTS_POLLING_INTERVAL_MSEC: number; } diff --git a/automated-orders/packages/scheduler/src/index.ts b/automated-orders/packages/scheduler/src/index.ts index 40d0082b3..e9ceab4c9 100644 --- a/automated-orders/packages/scheduler/src/index.ts +++ b/automated-orders/packages/scheduler/src/index.ts @@ -1,7 +1,22 @@ -import { logError, logInfo } from '@warden-automated-orders/utils'; +import { EvmClient, OrderCreatedAbi, OrderProcessor } from '@warden-automated-orders/blockchain'; +import { logError } from '@warden-automated-orders/utils'; + +import { config } from './config/config.js'; async function main() { - logInfo('main'); + const evmos = new EvmClient({ + rpcURL: config.EVMOS_NODE_RPC, + }); + + const processor = new OrderProcessor( + evmos, + evmos.pollEvents.bind(config.EVMOS_REGISTRY_ADDRESS, 0n, OrderCreatedAbi, { + pollingBlocks: BigInt(config.ETHEREUM_EVENTS_POLLING_BLOCKS), + pollingIntervalMsec: config.ETHEREUM_EVENTS_POLLING_INTERVAL_MSEC, + }), + ).start(); + + await Promise.all([processor]); } main() From ed9db87e21578619a8edf33270ddda4f1d8a6e16 Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Thu, 7 Nov 2024 16:24:46 +0300 Subject: [PATCH 04/15] Start adding handler for OrderCreated events --- .../blockchain-library/src/clients/evm.ts | 29 ++++++++++++++----- .../src/processors/orderProcessor.ts | 21 ++++++++++---- .../src/types/registry/events.ts | 12 ++------ .../src/types/registry/functions.ts | 16 ++++++++++ .../packages/scheduler/src/config/config.ts | 10 ++++--- .../packages/scheduler/src/config/env.ts | 6 ++-- .../packages/scheduler/src/index.ts | 14 ++++++--- 7 files changed, 75 insertions(+), 33 deletions(-) create mode 100644 automated-orders/packages/blockchain-library/src/types/registry/functions.ts diff --git a/automated-orders/packages/blockchain-library/src/clients/evm.ts b/automated-orders/packages/blockchain-library/src/clients/evm.ts index b6ce9516c..31c6d94fb 100644 --- a/automated-orders/packages/blockchain-library/src/clients/evm.ts +++ b/automated-orders/packages/blockchain-library/src/clients/evm.ts @@ -1,5 +1,5 @@ import { delay } from '@warden-automated-orders/utils'; -import { AbiEventFragment, EventLog, Web3 } from 'web3'; +import { AbiEventFragment, AbiFunctionFragment, EventLog, Web3 } from 'web3'; import { IEvmConfiguration } from '../types/evm/configuration.js'; import { IEventPollingConfiguration } from '../types/evm/pollingConfiguration.js'; @@ -11,12 +11,12 @@ export class EvmClient { this.web3 = new Web3(this.configuration.rpcURL); } - async broadcastTx(): Promise { + public async broadcastTx(): Promise { // TODO: implementation } - async *pollEvents( - contract: string, + public async *pollEvents( + contractAddress: string, startBlock: bigint, eventAbi: AbiEventFragment, config: IEventPollingConfiguration, @@ -24,10 +24,10 @@ export class EvmClient { while (true) { await delay(config.pollingIntervalMsec); - const myContract = new this.web3.eth.Contract([eventAbi], contract); + const contract = new this.web3.eth.Contract([eventAbi], contractAddress); const endBlock = await this.web3.eth.getBlockNumber(); - let currentBlock = startBlock; + let currentBlock = BigInt(startBlock); do { let nextBlock: bigint; @@ -38,7 +38,7 @@ export class EvmClient { nextBlock = currentBlock + config.pollingBlocks; } - const logs = (await myContract.getPastEvents({ + const logs = (await contract.getPastEvents({ fromBlock: startBlock, toBlock: endBlock, })) as EventLog[]; @@ -61,4 +61,19 @@ export class EvmClient { } while (currentBlock < endBlock); } } + + public async isContract(address: string): Promise { + return (await this.web3.eth.getCode(address)).length > 0; + } + + public async callView( + contractAddress: string, + functionAbi: AbiFunctionFragment, + ...args: unknown[] + ): Promise { + const contract = new this.web3.eth.Contract([functionAbi], contractAddress); + const method = contract.methods[functionAbi.name].call(this, args); + + return await method.call(); + } } diff --git a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts index f53192006..af7bc697b 100644 --- a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts @@ -1,23 +1,32 @@ import { logError, logInfo, serialize } from '@warden-automated-orders/utils'; import { EvmClient } from '../clients/evm.js'; -import { INewSignatureRequest } from '../types/warden/newSignatureRequest.js'; +import { OrderCreated } from '../types/registry/events.js'; +import { CanExecuteOrderAbi } from '../types/registry/functions.js'; import { Processor } from './processor.js'; -export class OrderProcessor extends Processor { - - +export class OrderProcessor extends Processor { constructor( private evm: EvmClient, - generator: () => AsyncGenerator, + generator: () => AsyncGenerator, ) { super(generator); } - async handle(data: INewSignatureRequest): Promise { + async handle(data: OrderCreated): Promise { try { logInfo(`New Signature request ${serialize(data)}`); + const exist = this.evm.isContract(data.returnValues.order); + + if (!exist) { + return true; + } + + const canExecute = await this.evm.callView(data.returnValues.order, CanExecuteOrderAbi, []); + + logInfo(`${canExecute}`); + // TODO: implementation return true; diff --git a/automated-orders/packages/blockchain-library/src/types/registry/events.ts b/automated-orders/packages/blockchain-library/src/types/registry/events.ts index ed883da4b..62ddba96e 100644 --- a/automated-orders/packages/blockchain-library/src/types/registry/events.ts +++ b/automated-orders/packages/blockchain-library/src/types/registry/events.ts @@ -2,19 +2,13 @@ import { AbiEventFragment, EventLog } from 'web3'; export interface OrderCreated extends EventLog { returnValues: { - from: string; - to: string; - amount: bigint; + order: string; }; } export const OrderCreatedAbi: AbiEventFragment = { anonymous: false, - inputs: [ - { indexed: true, internalType: 'address', name: 'from', type: 'address' }, - { indexed: true, internalType: 'address', name: 'to', type: 'address' }, - { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' }, - ], - name: 'Transfer', + inputs: [{ indexed: true, internalType: 'address', name: 'order', type: 'address' }], + name: 'OrderCreated', type: 'event', }; diff --git a/automated-orders/packages/blockchain-library/src/types/registry/functions.ts b/automated-orders/packages/blockchain-library/src/types/registry/functions.ts new file mode 100644 index 000000000..67b0ffaf2 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/types/registry/functions.ts @@ -0,0 +1,16 @@ +import { AbiFunctionFragment } from 'web3'; + +export const CanExecuteOrderAbi: AbiFunctionFragment = { + constant: true, + inputs: [], + name: 'canExecute', + outputs: [ + { + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', +}; diff --git a/automated-orders/packages/scheduler/src/config/config.ts b/automated-orders/packages/scheduler/src/config/config.ts index cdba9a182..52ce1f730 100644 --- a/automated-orders/packages/scheduler/src/config/config.ts +++ b/automated-orders/packages/scheduler/src/config/config.ts @@ -7,14 +7,16 @@ const schema: JSONSchemaType = { required: [ 'EVMOS_NODE_RPC', 'EVMOS_REGISTRY_ADDRESS', - 'ETHEREUM_EVENTS_POLLING_BLOCKS', - 'ETHEREUM_EVENTS_POLLING_INTERVAL_MSEC', + 'EVMOS_EVENTS_POLLING_BLOCKS', + 'EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK', + 'EVMOS_EVENTS_POLLING_INTERVAL_MSEC', ], properties: { EVMOS_NODE_RPC: { type: 'string' }, EVMOS_REGISTRY_ADDRESS: { type: 'string' }, - ETHEREUM_EVENTS_POLLING_BLOCKS: { type: 'number' }, - ETHEREUM_EVENTS_POLLING_INTERVAL_MSEC: { type: 'number' }, + EVMOS_EVENTS_POLLING_BLOCKS: { type: 'number' }, + EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: { type: 'number' }, + EVMOS_EVENTS_POLLING_INTERVAL_MSEC: { type: 'number' }, }, }; diff --git a/automated-orders/packages/scheduler/src/config/env.ts b/automated-orders/packages/scheduler/src/config/env.ts index cd4594d72..2c126a02d 100644 --- a/automated-orders/packages/scheduler/src/config/env.ts +++ b/automated-orders/packages/scheduler/src/config/env.ts @@ -1,7 +1,7 @@ export interface Env { EVMOS_NODE_RPC: string; EVMOS_REGISTRY_ADDRESS: string; - - ETHEREUM_EVENTS_POLLING_BLOCKS: number; - ETHEREUM_EVENTS_POLLING_INTERVAL_MSEC: number; + EVMOS_EVENTS_POLLING_BLOCKS: number; + EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: number; + EVMOS_EVENTS_POLLING_INTERVAL_MSEC: number; } diff --git a/automated-orders/packages/scheduler/src/index.ts b/automated-orders/packages/scheduler/src/index.ts index e9ceab4c9..fc521530d 100644 --- a/automated-orders/packages/scheduler/src/index.ts +++ b/automated-orders/packages/scheduler/src/index.ts @@ -10,10 +10,16 @@ async function main() { const processor = new OrderProcessor( evmos, - evmos.pollEvents.bind(config.EVMOS_REGISTRY_ADDRESS, 0n, OrderCreatedAbi, { - pollingBlocks: BigInt(config.ETHEREUM_EVENTS_POLLING_BLOCKS), - pollingIntervalMsec: config.ETHEREUM_EVENTS_POLLING_INTERVAL_MSEC, - }), + evmos.pollEvents.bind( + evmos, + config.EVMOS_REGISTRY_ADDRESS, + config.EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK, + OrderCreatedAbi, + { + pollingBlocks: BigInt(config.EVMOS_EVENTS_POLLING_BLOCKS), + pollingIntervalMsec: config.EVMOS_EVENTS_POLLING_INTERVAL_MSEC, + }, + ), ).start(); await Promise.all([processor]); From 5a15393dee88d68f5177408c4458ac182810bf61 Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Thu, 7 Nov 2024 16:52:06 +0300 Subject: [PATCH 05/15] Some fixes --- .../blockchain-library/src/clients/evm.ts | 26 +++++++++++-------- .../src/processors/orderProcessor.ts | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/automated-orders/packages/blockchain-library/src/clients/evm.ts b/automated-orders/packages/blockchain-library/src/clients/evm.ts index 31c6d94fb..a2b0fdd8a 100644 --- a/automated-orders/packages/blockchain-library/src/clients/evm.ts +++ b/automated-orders/packages/blockchain-library/src/clients/evm.ts @@ -6,9 +6,11 @@ import { IEventPollingConfiguration } from '../types/evm/pollingConfiguration.js export class EvmClient { web3: Web3; + eventsFromBlocks: Map; constructor(private configuration: IEvmConfiguration) { this.web3 = new Web3(this.configuration.rpcURL); + this.eventsFromBlocks = new Map(); } public async broadcastTx(): Promise { @@ -27,20 +29,19 @@ export class EvmClient { const contract = new this.web3.eth.Contract([eventAbi], contractAddress); const endBlock = await this.web3.eth.getBlockNumber(); - let currentBlock = BigInt(startBlock); + let fromBlock = BigInt(this.eventsFromBlocks.get(eventAbi.name) ?? startBlock); + let toBlock = endBlock; do { - let nextBlock: bigint; - - if (currentBlock + config.pollingBlocks > endBlock) { - nextBlock = endBlock; + if (fromBlock + config.pollingBlocks > endBlock) { + toBlock = endBlock; } else { - nextBlock = currentBlock + config.pollingBlocks; + toBlock = fromBlock + config.pollingBlocks; } const logs = (await contract.getPastEvents({ - fromBlock: startBlock, - toBlock: endBlock, + fromBlock: fromBlock, + toBlock: toBlock, })) as EventLog[]; for (const log of logs) { @@ -57,13 +58,16 @@ export class EvmClient { yield event; } - currentBlock = nextBlock; - } while (currentBlock < endBlock); + fromBlock = toBlock; + + this.eventsFromBlocks.set(eventAbi.name, fromBlock); + } while (fromBlock < endBlock); } } public async isContract(address: string): Promise { - return (await this.web3.eth.getCode(address)).length > 0; + const code = await this.web3.eth.getCode(address); + return Buffer.from(code.replace('0x', ''), 'hex').length > 0; } public async callView( diff --git a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts index af7bc697b..a938c9ca3 100644 --- a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts @@ -17,7 +17,7 @@ export class OrderProcessor extends Processor { try { logInfo(`New Signature request ${serialize(data)}`); - const exist = this.evm.isContract(data.returnValues.order); + const exist = await this.evm.isContract(data.returnValues.order); if (!exist) { return true; From 2f69fd1f513d761a79634e713a2c758739b60a5f Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Thu, 7 Nov 2024 17:40:21 +0300 Subject: [PATCH 06/15] Add check for isExecuted --- .../src/processors/orderProcessor.ts | 8 +++++++- .../src/types/registry/functions.ts | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts index a938c9ca3..37fff9517 100644 --- a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts @@ -2,7 +2,7 @@ import { logError, logInfo, serialize } from '@warden-automated-orders/utils'; import { EvmClient } from '../clients/evm.js'; import { OrderCreated } from '../types/registry/events.js'; -import { CanExecuteOrderAbi } from '../types/registry/functions.js'; +import { CanExecuteOrderAbi, IsExecutedOrderAbi } from '../types/registry/functions.js'; import { Processor } from './processor.js'; export class OrderProcessor extends Processor { @@ -23,6 +23,12 @@ export class OrderProcessor extends Processor { return true; } + const isExecuted = await this.evm.callView(data.returnValues.order, IsExecutedOrderAbi, []); + + if (isExecuted) { + return true; + } + const canExecute = await this.evm.callView(data.returnValues.order, CanExecuteOrderAbi, []); logInfo(`${canExecute}`); diff --git a/automated-orders/packages/blockchain-library/src/types/registry/functions.ts b/automated-orders/packages/blockchain-library/src/types/registry/functions.ts index 67b0ffaf2..8db598734 100644 --- a/automated-orders/packages/blockchain-library/src/types/registry/functions.ts +++ b/automated-orders/packages/blockchain-library/src/types/registry/functions.ts @@ -14,3 +14,18 @@ export const CanExecuteOrderAbi: AbiFunctionFragment = { stateMutability: 'view', type: 'function', }; + +export const IsExecutedOrderAbi: AbiFunctionFragment = { + constant: true, + inputs: [], + name: 'isExecuted', + outputs: [ + { + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', +}; From e5f8818b69bc225810488d67b89d9dd3d9d520a0 Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Fri, 8 Nov 2024 16:43:44 +0300 Subject: [PATCH 07/15] Add ABI and more logic --- .../blockchain-library/src/clients/evm.ts | 51 ++++++++++++-- .../src/processors/orderProcessor.ts | 45 +++++++++--- .../src/types/evm/configuration.ts | 1 + .../src/types/registry/functions.ts | 68 ++++++++++++++++--- .../packages/scheduler/src/config/config.ts | 2 + .../packages/scheduler/src/config/env.ts | 1 + .../packages/scheduler/src/index.ts | 1 + 7 files changed, 148 insertions(+), 21 deletions(-) diff --git a/automated-orders/packages/blockchain-library/src/clients/evm.ts b/automated-orders/packages/blockchain-library/src/clients/evm.ts index a2b0fdd8a..2fe627060 100644 --- a/automated-orders/packages/blockchain-library/src/clients/evm.ts +++ b/automated-orders/packages/blockchain-library/src/clients/evm.ts @@ -1,15 +1,17 @@ import { delay } from '@warden-automated-orders/utils'; -import { AbiEventFragment, AbiFunctionFragment, EventLog, Web3 } from 'web3'; +import { AbiEventFragment, AbiFunctionFragment, EventLog, Transaction, Web3 } from 'web3'; import { IEvmConfiguration } from '../types/evm/configuration.js'; import { IEventPollingConfiguration } from '../types/evm/pollingConfiguration.js'; export class EvmClient { web3: Web3; + events: Map; eventsFromBlocks: Map; constructor(private configuration: IEvmConfiguration) { this.web3 = new Web3(this.configuration.rpcURL); + this.events = new Map(); this.eventsFromBlocks = new Map(); } @@ -26,6 +28,10 @@ export class EvmClient { while (true) { await delay(config.pollingIntervalMsec); + for (const event of this.events) { + yield event[1] as T; + } + const contract = new this.web3.eth.Contract([eventAbi], contractAddress); const endBlock = await this.web3.eth.getBlockNumber(); @@ -55,6 +61,8 @@ export class EvmClient { continue; } + this.events.set(this.getEventId(event), event); + yield event; } @@ -70,14 +78,47 @@ export class EvmClient { return Buffer.from(code.replace('0x', ''), 'hex').length > 0; } - public async callView( + public async callView(contractAddress: string, functionAbi: AbiFunctionFragment, ...args: unknown[]): Promise { + const contract = new this.web3.eth.Contract([functionAbi], contractAddress); + const method = contract.methods[functionAbi.name].call(this, args); + + return (await method.call()) as T; + } + + public getEventId(event: EventLog): string { + return `${event.blockNumber}${event.logIndex}`; + } + + public async getNextNonce(account: string): Promise { + const transactionsCount = await this.web3.eth.getTransactionCount(account); + + return transactionsCount + 1n; + } + + public async sendTransaction( contractAddress: string, functionAbi: AbiFunctionFragment, ...args: unknown[] - ): Promise { + ): Promise { const contract = new this.web3.eth.Contract([functionAbi], contractAddress); - const method = contract.methods[functionAbi.name].call(this, args); + const data = contract.methods[functionAbi.name].call(this, args).encodeABI(); + + // TODO: must be calculated for Ethereum + const feeData = await this.web3.eth.calculateFeeData(); + const account = this.web3.eth.accounts.privateKeyToAccount(this.configuration.callerPrivateKey!); + + const tx: Transaction = { + from: account.address, + to: contractAddress, + data: data, + maxFeePerGas: feeData.maxFeePerGas, + maxPriorityFeePerGas: feeData.maxPriorityFeePerGas, + }; + + const signedTx = await this.web3.eth.accounts.signTransaction(tx, this.configuration.callerPrivateKey!); + const receipt = await this.web3.eth.sendSignedTransaction(signedTx.rawTransaction!); - return await method.call(); + // TODO: check status + return receipt.status == 0; } } diff --git a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts index 37fff9517..abf5b1cb4 100644 --- a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts @@ -2,7 +2,13 @@ import { logError, logInfo, serialize } from '@warden-automated-orders/utils'; import { EvmClient } from '../clients/evm.js'; import { OrderCreated } from '../types/registry/events.js'; -import { CanExecuteOrderAbi, IsExecutedOrderAbi } from '../types/registry/functions.js'; +import { + CanExecuteOrderAbi, + ExecuteAbi, + ExecutionDataAbi, + IExecutionData, + IsExecutedOrderAbi, +} from '../types/registry/functions.js'; import { Processor } from './processor.js'; export class OrderProcessor extends Processor { @@ -13,31 +19,54 @@ export class OrderProcessor extends Processor { super(generator); } - async handle(data: OrderCreated): Promise { + async handle(event: OrderCreated): Promise { try { - logInfo(`New Signature request ${serialize(data)}`); + logInfo(`New Signature request ${serialize(event)}`); - const exist = await this.evm.isContract(data.returnValues.order); + const exist = await this.evm.isContract(event.returnValues.order); if (!exist) { + this.evm.events.delete(this.evm.getEventId(event)); + return true; } - const isExecuted = await this.evm.callView(data.returnValues.order, IsExecutedOrderAbi, []); + const isExecuted = await this.evm.callView(event.returnValues.order, IsExecutedOrderAbi, []); if (isExecuted) { + this.evm.events.delete(this.evm.getEventId(event)); + return true; } - const canExecute = await this.evm.callView(data.returnValues.order, CanExecuteOrderAbi, []); + const canExecute = await this.evm.callView(event.returnValues.order, CanExecuteOrderAbi, []); + + if (!canExecute) { + // TODO: cache and try check later + return true; + } logInfo(`${canExecute}`); - // TODO: implementation + const orderDetails = await this.evm.callView(event.returnValues.order, ExecutionDataAbi, []); + + logInfo(`${serialize(orderDetails.caller)}`); + + const nonce = this.evm.getNextNonce(orderDetails.caller); + + // TODO: add missing args (gas settings) + const executed = await this.evm.sendTransaction(event.returnValues.order, ExecuteAbi, [nonce]); + + if (!executed) { + return true; + } + + // TODO: 3 attempts to execute() + this.evm.events.delete(this.evm.getEventId(event)); return true; } catch (error) { - logError(`New Signature error ${serialize(data)}. Error: ${error}, Stack trace: ${error.stack}`); + logError(`New Signature error ${serialize(event)}. Error: ${error}, Stack trace: ${error.stack}`); return false; } diff --git a/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts b/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts index d9f7bb896..75d030240 100644 --- a/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts +++ b/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts @@ -1,3 +1,4 @@ export interface IEvmConfiguration { rpcURL: string; + callerPrivateKey?: string | undefined; } diff --git a/automated-orders/packages/blockchain-library/src/types/registry/functions.ts b/automated-orders/packages/blockchain-library/src/types/registry/functions.ts index 8db598734..39c968299 100644 --- a/automated-orders/packages/blockchain-library/src/types/registry/functions.ts +++ b/automated-orders/packages/blockchain-library/src/types/registry/functions.ts @@ -1,31 +1,83 @@ import { AbiFunctionFragment } from 'web3'; +export interface IExecutionData { + caller: string; + chainId: bigint; +} + export const CanExecuteOrderAbi: AbiFunctionFragment = { - constant: true, - inputs: [], + type: 'function', name: 'canExecute', + inputs: [], outputs: [ { name: '', type: 'bool', + internalType: 'bool', }, ], - payable: false, stateMutability: 'view', - type: 'function', }; export const IsExecutedOrderAbi: AbiFunctionFragment = { - constant: true, - inputs: [], + type: 'function', name: 'isExecuted', + inputs: [], outputs: [ { name: '', type: 'bool', + internalType: 'bool', }, ], - payable: false, - stateMutability: 'view', + stateMutability: 'nonpayable', +}; + +export const ExecutionDataAbi: AbiFunctionFragment = { + type: 'function', + name: 'executionData', + inputs: [], + outputs: [ + { + name: 'caller', + type: 'address', + internalType: 'address', + }, + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', +}; + +export const ExecuteAbi: AbiFunctionFragment = { type: 'function', + name: 'execute', + inputs: [ + { + name: 'nonce', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'maxPriorityFeePerGas', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'maxFeePerGas', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'nonpayable', }; diff --git a/automated-orders/packages/scheduler/src/config/config.ts b/automated-orders/packages/scheduler/src/config/config.ts index 52ce1f730..fde137783 100644 --- a/automated-orders/packages/scheduler/src/config/config.ts +++ b/automated-orders/packages/scheduler/src/config/config.ts @@ -10,6 +10,7 @@ const schema: JSONSchemaType = { 'EVMOS_EVENTS_POLLING_BLOCKS', 'EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK', 'EVMOS_EVENTS_POLLING_INTERVAL_MSEC', + 'EVMOS_CALLER_PRIVATE_KEY', ], properties: { EVMOS_NODE_RPC: { type: 'string' }, @@ -17,6 +18,7 @@ const schema: JSONSchemaType = { EVMOS_EVENTS_POLLING_BLOCKS: { type: 'number' }, EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: { type: 'number' }, EVMOS_EVENTS_POLLING_INTERVAL_MSEC: { type: 'number' }, + EVMOS_CALLER_PRIVATE_KEY: { type: 'string' }, }, }; diff --git a/automated-orders/packages/scheduler/src/config/env.ts b/automated-orders/packages/scheduler/src/config/env.ts index 2c126a02d..4c3949113 100644 --- a/automated-orders/packages/scheduler/src/config/env.ts +++ b/automated-orders/packages/scheduler/src/config/env.ts @@ -4,4 +4,5 @@ export interface Env { EVMOS_EVENTS_POLLING_BLOCKS: number; EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: number; EVMOS_EVENTS_POLLING_INTERVAL_MSEC: number; + EVMOS_CALLER_PRIVATE_KEY: string; } diff --git a/automated-orders/packages/scheduler/src/index.ts b/automated-orders/packages/scheduler/src/index.ts index fc521530d..b46f8eb75 100644 --- a/automated-orders/packages/scheduler/src/index.ts +++ b/automated-orders/packages/scheduler/src/index.ts @@ -6,6 +6,7 @@ import { config } from './config/config.js'; async function main() { const evmos = new EvmClient({ rpcURL: config.EVMOS_NODE_RPC, + callerPrivateKey: config.EVMOS_CALLER_PRIVATE_KEY, }); const processor = new OrderProcessor( From 2669230a9ae5db821b531e36f61eadb89e28e7bd Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Mon, 11 Nov 2024 18:32:42 +0300 Subject: [PATCH 08/15] Fixes --- .../blockchain-library/src/clients/evm.ts | 58 +++++++++++++++---- .../packages/blockchain-library/src/index.ts | 3 +- .../src/processors/orderProcessor.ts | 54 ++++++++++++----- .../src/types/evm/constants.ts | 3 + .../src/types/{registry => order}/events.ts | 0 .../types/{registry => order}/functions.ts | 53 ++++++++++++++--- .../packages/scheduler/src/config/config.ts | 2 + .../packages/scheduler/src/config/env.ts | 1 + .../packages/scheduler/src/index.ts | 9 ++- 9 files changed, 146 insertions(+), 37 deletions(-) create mode 100644 automated-orders/packages/blockchain-library/src/types/evm/constants.ts rename automated-orders/packages/blockchain-library/src/types/{registry => order}/events.ts (100%) rename automated-orders/packages/blockchain-library/src/types/{registry => order}/functions.ts (60%) diff --git a/automated-orders/packages/blockchain-library/src/clients/evm.ts b/automated-orders/packages/blockchain-library/src/clients/evm.ts index 2fe627060..db084670c 100644 --- a/automated-orders/packages/blockchain-library/src/clients/evm.ts +++ b/automated-orders/packages/blockchain-library/src/clients/evm.ts @@ -1,5 +1,5 @@ -import { delay } from '@warden-automated-orders/utils'; -import { AbiEventFragment, AbiFunctionFragment, EventLog, Transaction, Web3 } from 'web3'; +import { delay, logError } from '@warden-automated-orders/utils'; +import { AbiEventFragment, AbiFunctionFragment, Bytes, EventLog, FeeData, Transaction, Web3 } from 'web3'; import { IEvmConfiguration } from '../types/evm/configuration.js'; import { IEventPollingConfiguration } from '../types/evm/pollingConfiguration.js'; @@ -78,9 +78,9 @@ export class EvmClient { return Buffer.from(code.replace('0x', ''), 'hex').length > 0; } - public async callView(contractAddress: string, functionAbi: AbiFunctionFragment, ...args: unknown[]): Promise { + public async callView(contractAddress: string, functionAbi: AbiFunctionFragment, args: unknown[]): Promise { const contract = new this.web3.eth.Contract([functionAbi], contractAddress); - const method = contract.methods[functionAbi.name].call(this, args); + const method = contract.methods[functionAbi.name].call(this, ...args); return (await method.call()) as T; } @@ -95,30 +95,64 @@ export class EvmClient { return transactionsCount + 1n; } + public async getGasFees( + from: string, + to: string, + data: Bytes, + nonce: bigint, + value: bigint, + ): Promise<{ feeData: FeeData | undefined; gasLimit: bigint | undefined }> { + const feeData = await this.web3.eth.calculateFeeData().catch((err) => { + logError(`Failed to caldulate fee data, ${err}`); + return undefined; + }); + + const gasLimit = await this.web3.eth + .estimateGas({ + from: from, + to: to, + value: value, + nonce: nonce, + data: data, + type: '0x2', + }) + .catch((err) => { + logError(`Failed to estimate gas, ${err}`); + return undefined; + }); + + return { feeData, gasLimit }; + } + public async sendTransaction( contractAddress: string, functionAbi: AbiFunctionFragment, - ...args: unknown[] + args: unknown[], ): Promise { const contract = new this.web3.eth.Contract([functionAbi], contractAddress); - const data = contract.methods[functionAbi.name].call(this, args).encodeABI(); - - // TODO: must be calculated for Ethereum - const feeData = await this.web3.eth.calculateFeeData(); + const data = contract.methods[functionAbi.name].call(this, ...args).encodeABI(); const account = this.web3.eth.accounts.privateKeyToAccount(this.configuration.callerPrivateKey!); + const nonce = await this.getNextNonce(account.address); + + const gas = await this.getGasFees(account.address, contractAddress, data, nonce, 0n); + + if (!gas.gasLimit || !gas.feeData) { + return false; + } + const tx: Transaction = { from: account.address, to: contractAddress, data: data, - maxFeePerGas: feeData.maxFeePerGas, - maxPriorityFeePerGas: feeData.maxPriorityFeePerGas, + gas: gas.gasLimit, + maxFeePerGas: gas.feeData.maxFeePerGas, + maxPriorityFeePerGas: gas.feeData.maxPriorityFeePerGas, }; const signedTx = await this.web3.eth.accounts.signTransaction(tx, this.configuration.callerPrivateKey!); const receipt = await this.web3.eth.sendSignedTransaction(signedTx.rawTransaction!); - // TODO: check status return receipt.status == 0; } } diff --git a/automated-orders/packages/blockchain-library/src/index.ts b/automated-orders/packages/blockchain-library/src/index.ts index 3922c2cb0..427ab6199 100644 --- a/automated-orders/packages/blockchain-library/src/index.ts +++ b/automated-orders/packages/blockchain-library/src/index.ts @@ -1,6 +1,7 @@ export { WardenClient } from './clients/warden.js'; export { EvmClient } from './clients/evm.js'; +export { ChainIds } from './types/evm/constants.js'; export { NewSignatureProcessor } from './processors/newSignatureProcessor.js'; export { OrderProcessor } from './processors/orderProcessor.js'; export { INewSignatureRequest } from './types/warden/newSignatureRequest.js'; -export { OrderCreated, OrderCreatedAbi } from './types/registry/events.js'; +export { OrderCreated, OrderCreatedAbi } from './types/order/events.js'; diff --git a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts index abf5b1cb4..53300ab11 100644 --- a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts @@ -1,19 +1,21 @@ import { logError, logInfo, serialize } from '@warden-automated-orders/utils'; import { EvmClient } from '../clients/evm.js'; -import { OrderCreated } from '../types/registry/events.js'; +import { OrderCreated } from '../types/order/events.js'; import { CanExecuteOrderAbi, ExecuteAbi, ExecutionDataAbi, IExecutionData, IsExecutedOrderAbi, -} from '../types/registry/functions.js'; +} from '../types/order/functions.js'; import { Processor } from './processor.js'; export class OrderProcessor extends Processor { constructor( - private evm: EvmClient, + private evmos: EvmClient, + private ethereum: EvmClient, + private supportedChainIds: Map, generator: () => AsyncGenerator, ) { super(generator); @@ -23,23 +25,23 @@ export class OrderProcessor extends Processor { try { logInfo(`New Signature request ${serialize(event)}`); - const exist = await this.evm.isContract(event.returnValues.order); + const exist = await this.evmos.isContract(event.returnValues.order); if (!exist) { - this.evm.events.delete(this.evm.getEventId(event)); + this.evmos.events.delete(this.evmos.getEventId(event)); return true; } - const isExecuted = await this.evm.callView(event.returnValues.order, IsExecutedOrderAbi, []); + const isExecuted = await this.evmos.callView(event.returnValues.order, IsExecutedOrderAbi, []); if (isExecuted) { - this.evm.events.delete(this.evm.getEventId(event)); + this.evmos.events.delete(this.evmos.getEventId(event)); return true; } - const canExecute = await this.evm.callView(event.returnValues.order, CanExecuteOrderAbi, []); + const canExecute = await this.evmos.callView(event.returnValues.order, CanExecuteOrderAbi, []); if (!canExecute) { // TODO: cache and try check later @@ -48,21 +50,45 @@ export class OrderProcessor extends Processor { logInfo(`${canExecute}`); - const orderDetails = await this.evm.callView(event.returnValues.order, ExecutionDataAbi, []); + const orderDetails = await this.evmos.callView(event.returnValues.order, ExecutionDataAbi, []); - logInfo(`${serialize(orderDetails.caller)}`); + logInfo(`${serialize(orderDetails)}`); - const nonce = this.evm.getNextNonce(orderDetails.caller); + if (!this.supportedChainIds.has(orderDetails.chainId)) { + this.evmos.events.delete(this.evmos.getEventId(event)); - // TODO: add missing args (gas settings) - const executed = await this.evm.sendTransaction(event.returnValues.order, ExecuteAbi, [nonce]); + logError(`Chain id = ${orderDetails.chainId} is not supported`); + + return true; + } + + const nonce = await this.ethereum.getNextNonce(orderDetails.caller); + const gas = await this.ethereum.getGasFees( + orderDetails.caller, + orderDetails.to, + orderDetails.data, + nonce, + orderDetails.value, + ); + + if (!gas.gasLimit || !gas.feeData) { + return true; + } + + const executed = await this.evmos.sendTransaction(event.returnValues.order, ExecuteAbi, [ + nonce, + gas.gasLimit, + gas.feeData.gasPrice, + gas.feeData.maxPriorityFeePerGas, + gas.feeData.maxFeePerGas, + ]); if (!executed) { return true; } // TODO: 3 attempts to execute() - this.evm.events.delete(this.evm.getEventId(event)); + this.evmos.events.delete(this.evmos.getEventId(event)); return true; } catch (error) { diff --git a/automated-orders/packages/blockchain-library/src/types/evm/constants.ts b/automated-orders/packages/blockchain-library/src/types/evm/constants.ts new file mode 100644 index 000000000..73ef04101 --- /dev/null +++ b/automated-orders/packages/blockchain-library/src/types/evm/constants.ts @@ -0,0 +1,3 @@ +export enum ChainIds { + Sepolia = 11155111, +} diff --git a/automated-orders/packages/blockchain-library/src/types/registry/events.ts b/automated-orders/packages/blockchain-library/src/types/order/events.ts similarity index 100% rename from automated-orders/packages/blockchain-library/src/types/registry/events.ts rename to automated-orders/packages/blockchain-library/src/types/order/events.ts diff --git a/automated-orders/packages/blockchain-library/src/types/registry/functions.ts b/automated-orders/packages/blockchain-library/src/types/order/functions.ts similarity index 60% rename from automated-orders/packages/blockchain-library/src/types/registry/functions.ts rename to automated-orders/packages/blockchain-library/src/types/order/functions.ts index 39c968299..6df66d08b 100644 --- a/automated-orders/packages/blockchain-library/src/types/registry/functions.ts +++ b/automated-orders/packages/blockchain-library/src/types/order/functions.ts @@ -1,8 +1,11 @@ -import { AbiFunctionFragment } from 'web3'; +import { AbiFunctionFragment, Bytes } from 'web3'; export interface IExecutionData { caller: string; + to: string; chainId: bigint; + data: Bytes; + value: bigint; } export const CanExecuteOrderAbi: AbiFunctionFragment = { @@ -39,14 +42,36 @@ export const ExecutionDataAbi: AbiFunctionFragment = { inputs: [], outputs: [ { - name: 'caller', - type: 'address', - internalType: 'address', - }, - { - name: 'chainId', - type: 'uint256', - internalType: 'uint256', + name: 'executionData', + type: 'tuple', + internalType: 'struct ExecutionData', + components: [ + { + name: 'caller', + type: 'address', + internalType: 'address', + }, + { + name: 'to', + type: 'address', + internalType: 'address', + }, + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + ], }, ], stateMutability: 'nonpayable', @@ -61,6 +86,16 @@ export const ExecuteAbi: AbiFunctionFragment = { type: 'uint256', internalType: 'uint256', }, + { + name: 'gas', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'gasPrice', + type: 'uint256', + internalType: 'uint256', + }, { name: 'maxPriorityFeePerGas', type: 'uint256', diff --git a/automated-orders/packages/scheduler/src/config/config.ts b/automated-orders/packages/scheduler/src/config/config.ts index fde137783..3b7eb6ccf 100644 --- a/automated-orders/packages/scheduler/src/config/config.ts +++ b/automated-orders/packages/scheduler/src/config/config.ts @@ -11,6 +11,7 @@ const schema: JSONSchemaType = { 'EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK', 'EVMOS_EVENTS_POLLING_INTERVAL_MSEC', 'EVMOS_CALLER_PRIVATE_KEY', + 'ETHEREUM_NODE_RPC', ], properties: { EVMOS_NODE_RPC: { type: 'string' }, @@ -19,6 +20,7 @@ const schema: JSONSchemaType = { EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: { type: 'number' }, EVMOS_EVENTS_POLLING_INTERVAL_MSEC: { type: 'number' }, EVMOS_CALLER_PRIVATE_KEY: { type: 'string' }, + ETHEREUM_NODE_RPC: { type: 'string' }, }, }; diff --git a/automated-orders/packages/scheduler/src/config/env.ts b/automated-orders/packages/scheduler/src/config/env.ts index 4c3949113..e1b7cecfe 100644 --- a/automated-orders/packages/scheduler/src/config/env.ts +++ b/automated-orders/packages/scheduler/src/config/env.ts @@ -5,4 +5,5 @@ export interface Env { EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: number; EVMOS_EVENTS_POLLING_INTERVAL_MSEC: number; EVMOS_CALLER_PRIVATE_KEY: string; + ETHEREUM_NODE_RPC: string; } diff --git a/automated-orders/packages/scheduler/src/index.ts b/automated-orders/packages/scheduler/src/index.ts index b46f8eb75..660ee9cf7 100644 --- a/automated-orders/packages/scheduler/src/index.ts +++ b/automated-orders/packages/scheduler/src/index.ts @@ -1,4 +1,4 @@ -import { EvmClient, OrderCreatedAbi, OrderProcessor } from '@warden-automated-orders/blockchain'; +import { ChainIds, EvmClient, OrderCreatedAbi, OrderProcessor } from '@warden-automated-orders/blockchain'; import { logError } from '@warden-automated-orders/utils'; import { config } from './config/config.js'; @@ -8,9 +8,16 @@ async function main() { rpcURL: config.EVMOS_NODE_RPC, callerPrivateKey: config.EVMOS_CALLER_PRIVATE_KEY, }); + const etheruem = new EvmClient({ + rpcURL: config.ETHEREUM_NODE_RPC, + }); + + const chainIds = new Map([[BigInt(ChainIds.Sepolia), undefined]]); const processor = new OrderProcessor( evmos, + etheruem, + chainIds, evmos.pollEvents.bind( evmos, config.EVMOS_REGISTRY_ADDRESS, From fc8203a6796c976111dbd9b5ee0316128668b3f5 Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Wed, 13 Nov 2024 13:11:32 +0300 Subject: [PATCH 09/15] Add logic to execute Order --- automated-orders/Dockerfile | 30 ++++++++++ automated-orders/README.md | 14 +++-- automated-orders/package.json | 9 ++- .../packages/blockchain-library/package.json | 1 + .../blockchain-library/src/clients/evm.ts | 60 +++++++++---------- .../blockchain-library/src/clients/warden.ts | 46 -------------- .../packages/blockchain-library/src/index.ts | 2 +- .../src/processors/orderProcessor.ts | 59 ++++++++++-------- .../src/types/evm/configuration.ts | 1 + .../src/types/order/events.ts | 12 ++-- .../packages/relayer/src/index.ts | 21 +------ .../packages/scheduler/src/config/config.ts | 4 ++ .../packages/scheduler/src/config/env.ts | 2 + .../packages/scheduler/src/index.ts | 6 +- automated-orders/yarn.lock | 5 ++ 15 files changed, 138 insertions(+), 134 deletions(-) create mode 100644 automated-orders/Dockerfile diff --git a/automated-orders/Dockerfile b/automated-orders/Dockerfile new file mode 100644 index 000000000..d26c1b4b9 --- /dev/null +++ b/automated-orders/Dockerfile @@ -0,0 +1,30 @@ +# syntax=docker/dockerfile:1 + +FROM node:20-slim AS base +WORKDIR /app +COPY ./yarn.lock yarn.lock +COPY ./package.json package.json +COPY ./tsconfig.json tsconfig.json + +FROM base AS libs +COPY ./packages/utils-library packages/utils-library +COPY ./packages/blockchain-library packages/blockchain-library +RUN yarn install --frozen-lockfile +RUN yarn build:libs +RUN rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* + +FROM base AS scheduler +COPY ./packages/scheduler packages/scheduler +COPY --from=libs ["/app/packages", "./packages"] +RUN yarn install --frozen-lockfile +RUN yarn build:scheduler +RUN rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* +CMD ["yarn", "scheduler"] + +FROM base AS relayer +COPY ./packages/relayer packages/relayer +COPY --from=libs ["/app/packages", "./packages"] +RUN yarn install --frozen-lockfile +RUN yarn build:relayer +RUN rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* +CMD ["yarn", "relayer"] diff --git a/automated-orders/README.md b/automated-orders/README.md index 7e187ec2c..ca97b435f 100644 --- a/automated-orders/README.md +++ b/automated-orders/README.md @@ -5,8 +5,15 @@ ```bash # example below -ETHEREUM_NODE_RPC=https://localhost:1122 -ETHEREUM_REGISTRY_ADDRESS=0x +ETHEREUM_NODE_RPC="https://localhost:1133" +EVMOS_NODE_RPC="https://localhost:1122" +EVMOS_REGISTRY_ADDRESS="0x0000000000000000000000000000000000000000" +EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK=7055543 +EVMOS_EVENTS_POLLING_INTERVAL_MSEC=100 +EVMOS_EVENTS_POLLING_BLOCKS=1000 +EVMOS_EVENTS_ORDER_RETRY_ATTEMPTS=3 +EVMOS_EVENTS_CACHE_SIZE=1000000 +EVMOS_CALLER_PRIVATE_KEY="CALLER_PRIVATE_KEY" ``` ## @warden-automated-orders/relayer @@ -14,7 +21,4 @@ ETHEREUM_REGISTRY_ADDRESS=0x ```bash # example below -ETHEREUM_NODE_RPC=https://localhost:1122 -WARDEN_RPC_URL=https://localhost:1133 -WARDEN_POLLING_INTERVAL_MSEC=100 ``` diff --git a/automated-orders/package.json b/automated-orders/package.json index 76d80051e..4ced3376d 100644 --- a/automated-orders/package.json +++ b/automated-orders/package.json @@ -11,7 +11,14 @@ ], "scripts": { "build": "yarn lint && tsc --build --force --verbose", - "lint": "eslint --ext .ts --ignore-path .eslintignore ." + "lint": "eslint --ext .ts --ignore-path .eslintignore .", + "build:blockchain-lib": "yarn workspace @warden-automated-orders/blockchain build", + "build:utils": "yarn workspace @warden-automated-orders/utils build", + "build:libs": "yarn build:utils && yarn build:blockchain-lib", + "build:scheduler": "yarn workspace @warden-automated-orders/scheduler build", + "build:relayer": "yarn workspace @warden-automated-orders/relayer build", + "scheduler": "yarn workspace @warden-automated-orders/scheduler start", + "relayer": "yarn workspace @warden-automated-orders/relayer start" }, "devDependencies": { "@trivago/prettier-plugin-sort-imports": "^4.3.0", diff --git a/automated-orders/packages/blockchain-library/package.json b/automated-orders/packages/blockchain-library/package.json index 4a1d4b888..23b196281 100644 --- a/automated-orders/packages/blockchain-library/package.json +++ b/automated-orders/packages/blockchain-library/package.json @@ -15,6 +15,7 @@ "dependencies": { "@wardenprotocol/wardenjs": "0.0.11", "@tanstack/react-query": "^4.36.1", + "lru-cache": "^11.0.2", "web3": "^4.14.0" }, "devDependencies": { diff --git a/automated-orders/packages/blockchain-library/src/clients/evm.ts b/automated-orders/packages/blockchain-library/src/clients/evm.ts index db084670c..52281d892 100644 --- a/automated-orders/packages/blockchain-library/src/clients/evm.ts +++ b/automated-orders/packages/blockchain-library/src/clients/evm.ts @@ -1,4 +1,5 @@ -import { delay, logError } from '@warden-automated-orders/utils'; +import { delay } from '@warden-automated-orders/utils'; +import { LRUCache } from 'lru-cache'; import { AbiEventFragment, AbiFunctionFragment, Bytes, EventLog, FeeData, Transaction, Web3 } from 'web3'; import { IEvmConfiguration } from '../types/evm/configuration.js'; @@ -6,13 +7,23 @@ import { IEventPollingConfiguration } from '../types/evm/pollingConfiguration.js export class EvmClient { web3: Web3; - events: Map; + signer: string; eventsFromBlocks: Map; + events: LRUCache; constructor(private configuration: IEvmConfiguration) { this.web3 = new Web3(this.configuration.rpcURL); - this.events = new Map(); this.eventsFromBlocks = new Map(); + + if (this.configuration.eventsCacheSize) { + this.events = new LRUCache({ + max: this.configuration.eventsCacheSize, + }); + } + + if (this.configuration.callerPrivateKey) { + this.signer = this.web3.eth.accounts.privateKeyToAccount(this.configuration.callerPrivateKey!).address; + } } public async broadcastTx(): Promise { @@ -86,7 +97,7 @@ export class EvmClient { } public getEventId(event: EventLog): string { - return `${event.blockNumber}${event.logIndex}`; + return `bk_${event.blockNumber}_ix_${event.logIndex}`; } public async getNextNonce(account: string): Promise { @@ -101,26 +112,17 @@ export class EvmClient { data: Bytes, nonce: bigint, value: bigint, - ): Promise<{ feeData: FeeData | undefined; gasLimit: bigint | undefined }> { - const feeData = await this.web3.eth.calculateFeeData().catch((err) => { - logError(`Failed to caldulate fee data, ${err}`); - return undefined; + ): Promise<{ feeData: FeeData; gasLimit: bigint }> { + const feeData = await this.web3.eth.calculateFeeData(); + + const gasLimit = await this.web3.eth.estimateGas({ + from: from, + to: to, + value: value, + nonce: nonce, + data: data, }); - const gasLimit = await this.web3.eth - .estimateGas({ - from: from, - to: to, - value: value, - nonce: nonce, - data: data, - type: '0x2', - }) - .catch((err) => { - logError(`Failed to estimate gas, ${err}`); - return undefined; - }); - return { feeData, gasLimit }; } @@ -131,18 +133,12 @@ export class EvmClient { ): Promise { const contract = new this.web3.eth.Contract([functionAbi], contractAddress); const data = contract.methods[functionAbi.name].call(this, ...args).encodeABI(); - const account = this.web3.eth.accounts.privateKeyToAccount(this.configuration.callerPrivateKey!); - - const nonce = await this.getNextNonce(account.address); - const gas = await this.getGasFees(account.address, contractAddress, data, nonce, 0n); - - if (!gas.gasLimit || !gas.feeData) { - return false; - } + const nonce = await this.getNextNonce(this.signer); + const gas = await this.getGasFees(this.signer, contractAddress, data, nonce, 0n); const tx: Transaction = { - from: account.address, + from: this.signer, to: contractAddress, data: data, gas: gas.gasLimit, @@ -153,6 +149,6 @@ export class EvmClient { const signedTx = await this.web3.eth.accounts.signTransaction(tx, this.configuration.callerPrivateKey!); const receipt = await this.web3.eth.sendSignedTransaction(signedTx.rawTransaction!); - return receipt.status == 0; + return receipt.status == 1; } } diff --git a/automated-orders/packages/blockchain-library/src/clients/warden.ts b/automated-orders/packages/blockchain-library/src/clients/warden.ts index efe2a043f..6ef580350 100644 --- a/automated-orders/packages/blockchain-library/src/clients/warden.ts +++ b/automated-orders/packages/blockchain-library/src/clients/warden.ts @@ -1,51 +1,5 @@ -import * as utils from '@warden-automated-orders/utils'; -import { warden } from '@wardenprotocol/wardenjs'; -import { SignRequest, SignRequestStatus } from '@wardenprotocol/wardenjs/codegen/warden/warden/v1beta3/signature'; - import { IWardenConfiguration } from '../types/warden/configuration.js'; -import { INewSignatureRequest } from '../types/warden/newSignatureRequest.js'; - -const { delay } = utils; -const { createRPCQueryClient } = warden.ClientFactory; export class WardenClient { constructor(private configuration: IWardenConfiguration) {} - - async query() { - return await createRPCQueryClient({ rpcEndpoint: this.configuration.rpcURL }); - } - - async *pollSignatureRequests(): AsyncGenerator { - while (true) { - await delay(this.configuration.pollingIntervalMsec); - - // TODO: query paged fulfilled sign requests - // const query = (await this.query()).warden.warden.v1beta3; - const signRequests: SignRequest[] = [ - { - id: 1n, - creator: 'string', - keyId: 1n, - dataForSigning: new Uint8Array(), - status: SignRequestStatus.SIGN_REQUEST_STATUS_FULFILLED, - signedData: new Uint8Array(), - rejectReason: 'string', - encryptionKey: new Uint8Array(), - deductedKeychainFees: [], - }, - ]; - - for (let i = 0; i < signRequests.length; i++) { - const request = signRequests[i]; - - if (!request.signedData) { - continue; - } - - yield { - signedData: request.signedData!, - }; - } - } - } } diff --git a/automated-orders/packages/blockchain-library/src/index.ts b/automated-orders/packages/blockchain-library/src/index.ts index 427ab6199..1c1268751 100644 --- a/automated-orders/packages/blockchain-library/src/index.ts +++ b/automated-orders/packages/blockchain-library/src/index.ts @@ -4,4 +4,4 @@ export { ChainIds } from './types/evm/constants.js'; export { NewSignatureProcessor } from './processors/newSignatureProcessor.js'; export { OrderProcessor } from './processors/orderProcessor.js'; export { INewSignatureRequest } from './types/warden/newSignatureRequest.js'; -export { OrderCreated, OrderCreatedAbi } from './types/order/events.js'; +export { OrderCreated, OrderRegisteredAbi } from './types/order/events.js'; diff --git a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts index 53300ab11..499217ba5 100644 --- a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts @@ -1,4 +1,4 @@ -import { logError, logInfo, serialize } from '@warden-automated-orders/utils'; +import { logError, logInfo, logWarning, serialize } from '@warden-automated-orders/utils'; import { EvmClient } from '../clients/evm.js'; import { OrderCreated } from '../types/order/events.js'; @@ -16,46 +16,58 @@ export class OrderProcessor extends Processor { private evmos: EvmClient, private ethereum: EvmClient, private supportedChainIds: Map, + private retryAttempts: number, generator: () => AsyncGenerator, ) { super(generator); } - async handle(event: OrderCreated): Promise { + async handle(event: OrderCreated, retryAttempt?: number): Promise { + if (retryAttempt && retryAttempt >= this.retryAttempts) { + return true; + } + try { - logInfo(`New Signature request ${serialize(event)}`); + logInfo(`New order: ${serialize(event)}`); + + const id = this.evmos.getEventId(event); - const exist = await this.evmos.isContract(event.returnValues.order); + const exist = await this.evmos.isContract(event.returnValues.execution); if (!exist) { - this.evmos.events.delete(this.evmos.getEventId(event)); + logWarning(`Order is not a contract: ${id}`); + + this.evmos.events.delete(id); return true; } - const isExecuted = await this.evmos.callView(event.returnValues.order, IsExecutedOrderAbi, []); + const isExecuted = await this.evmos.callView(event.returnValues.execution, IsExecutedOrderAbi, []); if (isExecuted) { - this.evmos.events.delete(this.evmos.getEventId(event)); + logWarning(`Order was already executed: ${id}`); + + this.evmos.events.delete(id); return true; } - const canExecute = await this.evmos.callView(event.returnValues.order, CanExecuteOrderAbi, []); + const canExecute = await this.evmos.callView(event.returnValues.execution, CanExecuteOrderAbi, []); if (!canExecute) { - // TODO: cache and try check later + logWarning(`Order is not ready yet: ${id}`); + return true; } - logInfo(`${canExecute}`); - - const orderDetails = await this.evmos.callView(event.returnValues.order, ExecutionDataAbi, []); - - logInfo(`${serialize(orderDetails)}`); + const orderDetails = await this.evmos.callView( + event.returnValues.execution, + ExecutionDataAbi, + [], + ); if (!this.supportedChainIds.has(orderDetails.chainId)) { - this.evmos.events.delete(this.evmos.getEventId(event)); + this.evmos.events.delete(id); logError(`Chain id = ${orderDetails.chainId} is not supported`); @@ -71,11 +83,7 @@ export class OrderProcessor extends Processor { orderDetails.value, ); - if (!gas.gasLimit || !gas.feeData) { - return true; - } - - const executed = await this.evmos.sendTransaction(event.returnValues.order, ExecuteAbi, [ + const executed = await this.evmos.sendTransaction(event.returnValues.execution, ExecuteAbi, [ nonce, gas.gasLimit, gas.feeData.gasPrice, @@ -84,17 +92,20 @@ export class OrderProcessor extends Processor { ]); if (!executed) { + logError(`Failed to execute order: ${id}`); + return true; } - // TODO: 3 attempts to execute() - this.evmos.events.delete(this.evmos.getEventId(event)); + this.evmos.events.delete(id); return true; } catch (error) { - logError(`New Signature error ${serialize(event)}. Error: ${error}, Stack trace: ${error.stack}`); + logError(`New order error ${serialize(event)}. Error: ${error}, Stack trace: ${error.stack}`); + + retryAttempt = retryAttempt ?? 1; - return false; + return await this.handle(event, ++retryAttempt); } } } diff --git a/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts b/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts index 75d030240..959d1bf11 100644 --- a/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts +++ b/automated-orders/packages/blockchain-library/src/types/evm/configuration.ts @@ -1,4 +1,5 @@ export interface IEvmConfiguration { rpcURL: string; + eventsCacheSize?: number | undefined; callerPrivateKey?: string | undefined; } diff --git a/automated-orders/packages/blockchain-library/src/types/order/events.ts b/automated-orders/packages/blockchain-library/src/types/order/events.ts index 62ddba96e..ceefb6942 100644 --- a/automated-orders/packages/blockchain-library/src/types/order/events.ts +++ b/automated-orders/packages/blockchain-library/src/types/order/events.ts @@ -2,13 +2,17 @@ import { AbiEventFragment, EventLog } from 'web3'; export interface OrderCreated extends EventLog { returnValues: { - order: string; + creator: string; + execution: string; }; } -export const OrderCreatedAbi: AbiEventFragment = { +export const OrderRegisteredAbi: AbiEventFragment = { anonymous: false, - inputs: [{ indexed: true, internalType: 'address', name: 'order', type: 'address' }], - name: 'OrderCreated', + inputs: [ + { indexed: true, internalType: 'address', name: 'creator', type: 'address' }, + { indexed: false, internalType: 'address', name: 'execution', type: 'address' }, + ], + name: 'Registered', type: 'event', }; diff --git a/automated-orders/packages/relayer/src/index.ts b/automated-orders/packages/relayer/src/index.ts index 0082e73da..5794bf56d 100644 --- a/automated-orders/packages/relayer/src/index.ts +++ b/automated-orders/packages/relayer/src/index.ts @@ -1,24 +1,7 @@ -import { EvmClient, NewSignatureProcessor, WardenClient } from '@warden-automated-orders/blockchain'; -import { logError } from '@warden-automated-orders/utils'; - -import { config } from './config/config.js'; +import { logError, logInfo } from '@warden-automated-orders/utils'; async function main() { - const warden = new WardenClient({ - rpcURL: config.WARDEN_RPC_URL, - pollingIntervalMsec: config.WARDEN_POLLING_INTERVAL_MSEC, - }); - - const ethereum = new EvmClient({ - rpcURL: config.ETHEREUM_NODE_RPC, - }); - - const newSignatureRequestProcess = new NewSignatureProcessor( - ethereum, - warden.pollSignatureRequests.bind(warden), - ).start(); - - await Promise.all([newSignatureRequestProcess]); + logInfo('todo: implementation'); } main() diff --git a/automated-orders/packages/scheduler/src/config/config.ts b/automated-orders/packages/scheduler/src/config/config.ts index 3b7eb6ccf..1f64f0fea 100644 --- a/automated-orders/packages/scheduler/src/config/config.ts +++ b/automated-orders/packages/scheduler/src/config/config.ts @@ -11,6 +11,8 @@ const schema: JSONSchemaType = { 'EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK', 'EVMOS_EVENTS_POLLING_INTERVAL_MSEC', 'EVMOS_CALLER_PRIVATE_KEY', + 'EVMOS_EVENTS_ORDER_RETRY_ATTEMPTS', + 'EVMOS_EVENTS_CACHE_SIZE', 'ETHEREUM_NODE_RPC', ], properties: { @@ -20,6 +22,8 @@ const schema: JSONSchemaType = { EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: { type: 'number' }, EVMOS_EVENTS_POLLING_INTERVAL_MSEC: { type: 'number' }, EVMOS_CALLER_PRIVATE_KEY: { type: 'string' }, + EVMOS_EVENTS_ORDER_RETRY_ATTEMPTS: { type: 'number' }, + EVMOS_EVENTS_CACHE_SIZE: { type: 'number' }, ETHEREUM_NODE_RPC: { type: 'string' }, }, }; diff --git a/automated-orders/packages/scheduler/src/config/env.ts b/automated-orders/packages/scheduler/src/config/env.ts index e1b7cecfe..d7487efc7 100644 --- a/automated-orders/packages/scheduler/src/config/env.ts +++ b/automated-orders/packages/scheduler/src/config/env.ts @@ -5,5 +5,7 @@ export interface Env { EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: number; EVMOS_EVENTS_POLLING_INTERVAL_MSEC: number; EVMOS_CALLER_PRIVATE_KEY: string; + EVMOS_EVENTS_ORDER_RETRY_ATTEMPTS: number; + EVMOS_EVENTS_CACHE_SIZE: number; ETHEREUM_NODE_RPC: string; } diff --git a/automated-orders/packages/scheduler/src/index.ts b/automated-orders/packages/scheduler/src/index.ts index 660ee9cf7..57caa91a6 100644 --- a/automated-orders/packages/scheduler/src/index.ts +++ b/automated-orders/packages/scheduler/src/index.ts @@ -1,4 +1,4 @@ -import { ChainIds, EvmClient, OrderCreatedAbi, OrderProcessor } from '@warden-automated-orders/blockchain'; +import { ChainIds, EvmClient, OrderProcessor, OrderRegisteredAbi } from '@warden-automated-orders/blockchain'; import { logError } from '@warden-automated-orders/utils'; import { config } from './config/config.js'; @@ -6,6 +6,7 @@ import { config } from './config/config.js'; async function main() { const evmos = new EvmClient({ rpcURL: config.EVMOS_NODE_RPC, + eventsCacheSize: config.EVMOS_EVENTS_CACHE_SIZE, callerPrivateKey: config.EVMOS_CALLER_PRIVATE_KEY, }); const etheruem = new EvmClient({ @@ -18,11 +19,12 @@ async function main() { evmos, etheruem, chainIds, + config.EVMOS_EVENTS_ORDER_RETRY_ATTEMPTS, evmos.pollEvents.bind( evmos, config.EVMOS_REGISTRY_ADDRESS, config.EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK, - OrderCreatedAbi, + OrderRegisteredAbi, { pollingBlocks: BigInt(config.EVMOS_EVENTS_POLLING_BLOCKS), pollingIntervalMsec: config.EVMOS_EVENTS_POLLING_INTERVAL_MSEC, diff --git a/automated-orders/yarn.lock b/automated-orders/yarn.lock index ebb4dc5e1..57c42bbac 100644 --- a/automated-orders/yarn.lock +++ b/automated-orders/yarn.lock @@ -1513,6 +1513,11 @@ loose-envify@^1.1.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@^11.0.2: + version "11.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.2.tgz#fbd8e7cf8211f5e7e5d91905c415a3f55755ca39" + integrity sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA== + merge2@^1.3.0: version "1.4.1" resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" From dd2bd6524d078ae65b14ef688184bd9cc37dbf2e Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Thu, 14 Nov 2024 10:30:39 +0300 Subject: [PATCH 10/15] Coderabbit fixes --- .../blockchain-library/src/clients/evm.ts | 13 +++++----- .../packages/blockchain-library/src/index.ts | 2 +- .../src/processors/newSignatureProcessor.ts | 6 +---- .../src/processors/orderProcessor.ts | 25 ++++++++----------- .../src/processors/processor.ts | 12 ++------- .../src/types/order/events.ts | 2 +- .../src/types/order/functions.ts | 4 +-- .../src/types/registry/events.ts | 9 ------- .../packages/relayer/src/index.ts | 9 +------ .../packages/scheduler/src/config/config.ts | 10 ++++---- .../packages/scheduler/src/index.ts | 4 +-- 11 files changed, 32 insertions(+), 64 deletions(-) delete mode 100644 automated-orders/packages/blockchain-library/src/types/registry/events.ts diff --git a/automated-orders/packages/blockchain-library/src/clients/evm.ts b/automated-orders/packages/blockchain-library/src/clients/evm.ts index 52281d892..dbd0d2320 100644 --- a/automated-orders/packages/blockchain-library/src/clients/evm.ts +++ b/automated-orders/packages/blockchain-library/src/clients/evm.ts @@ -91,9 +91,9 @@ export class EvmClient { public async callView(contractAddress: string, functionAbi: AbiFunctionFragment, args: unknown[]): Promise { const contract = new this.web3.eth.Contract([functionAbi], contractAddress); - const method = contract.methods[functionAbi.name].call(this, ...args); + const result = await contract.methods[functionAbi.name](...args).call(); - return (await method.call()) as T; + return result as T; } public getEventId(event: EventLog): string { @@ -103,14 +103,13 @@ export class EvmClient { public async getNextNonce(account: string): Promise { const transactionsCount = await this.web3.eth.getTransactionCount(account); - return transactionsCount + 1n; + return transactionsCount; } public async getGasFees( from: string, to: string, data: Bytes, - nonce: bigint, value: bigint, ): Promise<{ feeData: FeeData; gasLimit: bigint }> { const feeData = await this.web3.eth.calculateFeeData(); @@ -119,7 +118,6 @@ export class EvmClient { from: from, to: to, value: value, - nonce: nonce, data: data, }); @@ -132,10 +130,10 @@ export class EvmClient { args: unknown[], ): Promise { const contract = new this.web3.eth.Contract([functionAbi], contractAddress); - const data = contract.methods[functionAbi.name].call(this, ...args).encodeABI(); + const data = contract.methods[functionAbi.name](...args).encodeABI(); const nonce = await this.getNextNonce(this.signer); - const gas = await this.getGasFees(this.signer, contractAddress, data, nonce, 0n); + const gas = await this.getGasFees(this.signer, contractAddress, data, 0n); const tx: Transaction = { from: this.signer, @@ -144,6 +142,7 @@ export class EvmClient { gas: gas.gasLimit, maxFeePerGas: gas.feeData.maxFeePerGas, maxPriorityFeePerGas: gas.feeData.maxPriorityFeePerGas, + nonce: nonce, }; const signedTx = await this.web3.eth.accounts.signTransaction(tx, this.configuration.callerPrivateKey!); diff --git a/automated-orders/packages/blockchain-library/src/index.ts b/automated-orders/packages/blockchain-library/src/index.ts index 1c1268751..f80da1be3 100644 --- a/automated-orders/packages/blockchain-library/src/index.ts +++ b/automated-orders/packages/blockchain-library/src/index.ts @@ -4,4 +4,4 @@ export { ChainIds } from './types/evm/constants.js'; export { NewSignatureProcessor } from './processors/newSignatureProcessor.js'; export { OrderProcessor } from './processors/orderProcessor.js'; export { INewSignatureRequest } from './types/warden/newSignatureRequest.js'; -export { OrderCreated, OrderRegisteredAbi } from './types/order/events.js'; +export { OrderRegistered, OrderRegisteredAbi } from './types/order/events.js'; diff --git a/automated-orders/packages/blockchain-library/src/processors/newSignatureProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/newSignatureProcessor.ts index 86dd5fe49..7ba0f3f0a 100644 --- a/automated-orders/packages/blockchain-library/src/processors/newSignatureProcessor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/newSignatureProcessor.ts @@ -12,18 +12,14 @@ export class NewSignatureProcessor extends Processor { super(generator); } - async handle(data: INewSignatureRequest): Promise { + async handle(data: INewSignatureRequest): Promise { try { logInfo(`New Signature request ${serialize(data)}`); // TODO: implementation await this.evm.broadcastTx(); - - return true; } catch (error) { logError(`New Signature error ${serialize(data)}. Error: ${error}, Stack trace: ${error.stack}`); - - return false; } } } diff --git a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts index 499217ba5..8543e9870 100644 --- a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts @@ -1,7 +1,7 @@ import { logError, logInfo, logWarning, serialize } from '@warden-automated-orders/utils'; import { EvmClient } from '../clients/evm.js'; -import { OrderCreated } from '../types/order/events.js'; +import { OrderRegistered } from '../types/order/events.js'; import { CanExecuteOrderAbi, ExecuteAbi, @@ -11,20 +11,20 @@ import { } from '../types/order/functions.js'; import { Processor } from './processor.js'; -export class OrderProcessor extends Processor { +export class OrderProcessor extends Processor { constructor( private evmos: EvmClient, private ethereum: EvmClient, private supportedChainIds: Map, private retryAttempts: number, - generator: () => AsyncGenerator, + generator: () => AsyncGenerator, ) { super(generator); } - async handle(event: OrderCreated, retryAttempt?: number): Promise { + async handle(event: OrderRegistered, retryAttempt?: number): Promise { if (retryAttempt && retryAttempt >= this.retryAttempts) { - return true; + return; } try { @@ -39,7 +39,7 @@ export class OrderProcessor extends Processor { this.evmos.events.delete(id); - return true; + return; } const isExecuted = await this.evmos.callView(event.returnValues.execution, IsExecutedOrderAbi, []); @@ -49,7 +49,7 @@ export class OrderProcessor extends Processor { this.evmos.events.delete(id); - return true; + return; } const canExecute = await this.evmos.callView(event.returnValues.execution, CanExecuteOrderAbi, []); @@ -57,7 +57,7 @@ export class OrderProcessor extends Processor { if (!canExecute) { logWarning(`Order is not ready yet: ${id}`); - return true; + return; } const orderDetails = await this.evmos.callView( @@ -71,7 +71,7 @@ export class OrderProcessor extends Processor { logError(`Chain id = ${orderDetails.chainId} is not supported`); - return true; + return; } const nonce = await this.ethereum.getNextNonce(orderDetails.caller); @@ -79,7 +79,6 @@ export class OrderProcessor extends Processor { orderDetails.caller, orderDetails.to, orderDetails.data, - nonce, orderDetails.value, ); @@ -94,18 +93,16 @@ export class OrderProcessor extends Processor { if (!executed) { logError(`Failed to execute order: ${id}`); - return true; + return; } this.evmos.events.delete(id); - - return true; } catch (error) { logError(`New order error ${serialize(event)}. Error: ${error}, Stack trace: ${error.stack}`); retryAttempt = retryAttempt ?? 1; - return await this.handle(event, ++retryAttempt); + await this.handle(event, ++retryAttempt); } } } diff --git a/automated-orders/packages/blockchain-library/src/processors/processor.ts b/automated-orders/packages/blockchain-library/src/processors/processor.ts index 684726679..d58d01c7a 100644 --- a/automated-orders/packages/blockchain-library/src/processors/processor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/processor.ts @@ -8,15 +8,7 @@ export abstract class Processor { while (true) { try { for await (const request of this.generator()) { - let result = false; - - while (result !== true) { - result = await this.handle(request); - - if (!result) { - await delay(1_000); - } - } + await this.handle(request); } } catch (error) { logError(error); @@ -26,5 +18,5 @@ export abstract class Processor { } } - abstract handle(data: T): Promise; + abstract handle(data: T): Promise; } diff --git a/automated-orders/packages/blockchain-library/src/types/order/events.ts b/automated-orders/packages/blockchain-library/src/types/order/events.ts index ceefb6942..f5ca737cc 100644 --- a/automated-orders/packages/blockchain-library/src/types/order/events.ts +++ b/automated-orders/packages/blockchain-library/src/types/order/events.ts @@ -1,6 +1,6 @@ import { AbiEventFragment, EventLog } from 'web3'; -export interface OrderCreated extends EventLog { +export interface OrderRegistered extends EventLog { returnValues: { creator: string; execution: string; diff --git a/automated-orders/packages/blockchain-library/src/types/order/functions.ts b/automated-orders/packages/blockchain-library/src/types/order/functions.ts index 6df66d08b..0af80fdff 100644 --- a/automated-orders/packages/blockchain-library/src/types/order/functions.ts +++ b/automated-orders/packages/blockchain-library/src/types/order/functions.ts @@ -33,7 +33,7 @@ export const IsExecutedOrderAbi: AbiFunctionFragment = { internalType: 'bool', }, ], - stateMutability: 'nonpayable', + stateMutability: 'view', }; export const ExecutionDataAbi: AbiFunctionFragment = { @@ -74,7 +74,7 @@ export const ExecutionDataAbi: AbiFunctionFragment = { ], }, ], - stateMutability: 'nonpayable', + stateMutability: 'view', }; export const ExecuteAbi: AbiFunctionFragment = { diff --git a/automated-orders/packages/blockchain-library/src/types/registry/events.ts b/automated-orders/packages/blockchain-library/src/types/registry/events.ts deleted file mode 100644 index dc83e74d0..000000000 --- a/automated-orders/packages/blockchain-library/src/types/registry/events.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { EventLog } from 'web3'; - -export interface OrderCreated extends EventLog { - type: 'OrderCreated'; - returnValues: { - creator: string; - order: string; - }; -} diff --git a/automated-orders/packages/relayer/src/index.ts b/automated-orders/packages/relayer/src/index.ts index bf7591b02..5794bf56d 100644 --- a/automated-orders/packages/relayer/src/index.ts +++ b/automated-orders/packages/relayer/src/index.ts @@ -1,17 +1,10 @@ -import { EvmClient, NewSignatureProcessor, WardenClient } from '@warden-automated-orders/blockchain'; -import { logError } from '@warden-automated-orders/utils'; - -import { config } from './config/config.js'; +import { logError, logInfo } from '@warden-automated-orders/utils'; async function main() { logInfo('todo: implementation'); } main() - .catch((e) => { - logError(e); - process.exit(1); - }) .catch((e) => { logError(e); process.exit(1); diff --git a/automated-orders/packages/scheduler/src/config/config.ts b/automated-orders/packages/scheduler/src/config/config.ts index 1f64f0fea..589c2ada7 100644 --- a/automated-orders/packages/scheduler/src/config/config.ts +++ b/automated-orders/packages/scheduler/src/config/config.ts @@ -18,12 +18,12 @@ const schema: JSONSchemaType = { properties: { EVMOS_NODE_RPC: { type: 'string' }, EVMOS_REGISTRY_ADDRESS: { type: 'string' }, - EVMOS_EVENTS_POLLING_BLOCKS: { type: 'number' }, - EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: { type: 'number' }, - EVMOS_EVENTS_POLLING_INTERVAL_MSEC: { type: 'number' }, + EVMOS_EVENTS_POLLING_BLOCKS: { type: 'number', minimum: 1 }, + EVMOS_EVENTS_REGISTRY_START_POLLING_BLOCK: { type: 'number', minimum: 1 }, + EVMOS_EVENTS_POLLING_INTERVAL_MSEC: { type: 'number', minimum: 1 }, EVMOS_CALLER_PRIVATE_KEY: { type: 'string' }, - EVMOS_EVENTS_ORDER_RETRY_ATTEMPTS: { type: 'number' }, - EVMOS_EVENTS_CACHE_SIZE: { type: 'number' }, + EVMOS_EVENTS_ORDER_RETRY_ATTEMPTS: { type: 'number', minimum: 1 }, + EVMOS_EVENTS_CACHE_SIZE: { type: 'number', minimum: 1 }, ETHEREUM_NODE_RPC: { type: 'string' }, }, }; diff --git a/automated-orders/packages/scheduler/src/index.ts b/automated-orders/packages/scheduler/src/index.ts index 57caa91a6..c9b74ac44 100644 --- a/automated-orders/packages/scheduler/src/index.ts +++ b/automated-orders/packages/scheduler/src/index.ts @@ -9,7 +9,7 @@ async function main() { eventsCacheSize: config.EVMOS_EVENTS_CACHE_SIZE, callerPrivateKey: config.EVMOS_CALLER_PRIVATE_KEY, }); - const etheruem = new EvmClient({ + const ethereum = new EvmClient({ rpcURL: config.ETHEREUM_NODE_RPC, }); @@ -17,7 +17,7 @@ async function main() { const processor = new OrderProcessor( evmos, - etheruem, + ethereum, chainIds, config.EVMOS_EVENTS_ORDER_RETRY_ATTEMPTS, evmos.pollEvents.bind( From a6ac8d33f442d4e95fba754aa1219aa0a87b4f26 Mon Sep 17 00:00:00 2001 From: Mikolaj Sobolewksi Date: Thu, 14 Nov 2024 15:40:18 +0300 Subject: [PATCH 11/15] Feat(automated-orders): Added CI --- .github/workflows/build_push.yml | 2 ++ .github/workflows/relayer.yml | 58 ++++++++++++++++++++++++++++++++ .github/workflows/scheduler.yml | 58 ++++++++++++++++++++++++++++++++ Dockerfile | 39 +++++++++++++++++++++ automated-orders/Dockerfile | 30 ----------------- 5 files changed, 157 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/relayer.yml create mode 100644 .github/workflows/scheduler.yml delete mode 100644 automated-orders/Dockerfile diff --git a/.github/workflows/build_push.yml b/.github/workflows/build_push.yml index 308cf59c4..b1b75b998 100644 --- a/.github/workflows/build_push.yml +++ b/.github/workflows/build_push.yml @@ -14,6 +14,8 @@ on: - faucet - wardenkms - spaceward-relay + - scheduler + - relayer workflow_call: inputs: service_name: diff --git a/.github/workflows/relayer.yml b/.github/workflows/relayer.yml new file mode 100644 index 000000000..9e40c15bd --- /dev/null +++ b/.github/workflows/relayer.yml @@ -0,0 +1,58 @@ +--- +name: relayer + +on: + push: + branches: + - main + paths: + - "automated-orders/package.json" + - "automated-orders/tsconfig.json" + - "automated-orders/yarn.lock" + - "automated-orders/packages/blockchain-library/**" + - "automated-orders/packages/relayer/**" + - "automated-orders/packages/utils-library/**" + tags: + - "relayer/v*" + pull_request: + paths: + - "automated-orders/package.json" + - "automated-orders/tsconfig.json" + - "automated-orders/yarn.lock" + - "automated-orders/packages/blockchain-library/**" + - "automated-orders/packages/relayer/**" + - "automated-orders/packages/utils-library/**" +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + cache-dependency-path: "automated-orders/yarn.lock" + + - name: Install dependencies + run: yarn install + working-directory: "automated-orders/" + + - name: Run linter + working-directory: ./automated-orders + run: yarn lint + + - name: TypeScript build + working-directory: ./automated-orders + run: tsc --build --force --verbose + + build-and-push: + if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/relayer/v') + needs: [build] + uses: ./.github/workflows/build_push.yml + with: + service_name: relayer + secrets: inherit diff --git a/.github/workflows/scheduler.yml b/.github/workflows/scheduler.yml new file mode 100644 index 000000000..77a2379f8 --- /dev/null +++ b/.github/workflows/scheduler.yml @@ -0,0 +1,58 @@ +--- +name: scheduler + +on: + push: + branches: + - main + paths: + - "automated-orders/package.json" + - "automated-orders/tsconfig.json" + - "automated-orders/yarn.lock" + - "automated-orders/packages/blockchain-library/**" + - "automated-orders/packages/scheduler/**" + - "automated-orders/packages/utils-library/**" + tags: + - "scheduler/v*" + pull_request: + paths: + - "automated-orders/package.json" + - "automated-orders/tsconfig.json" + - "automated-orders/yarn.lock" + - "automated-orders/packages/blockchain-library/**" + - "automated-orders/packages/scheduler/**" + - "automated-orders/packages/utils-library/**" +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + cache-dependency-path: "automated-orders/yarn.lock" + + - name: Install dependencies + run: yarn install + working-directory: "automated-orders/" + + - name: Run linter + working-directory: ./automated-orders + run: yarn lint + + - name: TypeScript build + working-directory: ./automated-orders + run: tsc --build --force --verbose + + build-and-push: + if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/scheduler/v') + needs: [build] + uses: ./.github/workflows/build_push.yml + with: + service_name: scheduler + secrets: inherit diff --git a/Dockerfile b/Dockerfile index b6c4a469f..43997fabb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -84,6 +84,19 @@ FROM node:lts-alpine AS node-build-env RUN apk add --no-cache python3 build-base RUN npm install -g pnpm@9 +## automated-orders libs +FROM node-build-env AS automated-orders-libs +USER node +WORKDIR /app +COPY --chown=node:node automated-orders/yarn.lock yarn.lock +COPY --chown=node:node automated-orders/package.json package.json +COPY --chown=node:node automated-orders/tsconfig.json tsconfig.json +COPY --chown=node:node automated-orders/packages/utils-library packages/utils-library +COPY --chown=node:node automated-orders/packages/blockchain-library packages/blockchain-library +RUN yarn install --frozen-lockfile && \ + yarn build:libs && \ + rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* + ## snap FROM node-build-env AS snap-builder WORKDIR /snap @@ -158,3 +171,29 @@ COPY --chown=nobody:nogroup --from=wardenjs-builder /wardenjs /wardenprotocol/wa RUN pnpm install USER nobody ENTRYPOINT ["pnpm", "relay"] + +FROM node-build-env AS scheduler +USER node +WORKDIR /app +COPY --chown=node:node automated-orders/yarn.lock yarn.lock +COPY --chown=node:node automated-orders/package.json package.json +COPY --chown=node:node automated-orders/tsconfig.json tsconfig.json +COPY --chown=node:node automated-orders/packages/scheduler packages/scheduler +COPY --chown=node:node --from=automated-orders-libs ["/app/packages", "./packages"] +RUN yarn install --frozen-lockfile && \ + yarn build:scheduler && \ + rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* +CMD ["yarn", "scheduler"] + +FROM node-build-env AS relayer +USER node +WORKDIR /app +COPY --chown=node:node automated-orders/yarn.lock yarn.lock +COPY --chown=node:node automated-orders/package.json package.json +COPY --chown=node:node automated-orders/tsconfig.json tsconfig.json +COPY --chown=node:node automated-orders/packages/relayer packages/relayer +COPY --chown=node:node --from=automated-orders-libs ["/app/packages", "./packages"] +RUN yarn install --frozen-lockfile && \ + yarn build:relayer && \ + rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* +CMD ["yarn", "relayer"] diff --git a/automated-orders/Dockerfile b/automated-orders/Dockerfile deleted file mode 100644 index d26c1b4b9..000000000 --- a/automated-orders/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -# syntax=docker/dockerfile:1 - -FROM node:20-slim AS base -WORKDIR /app -COPY ./yarn.lock yarn.lock -COPY ./package.json package.json -COPY ./tsconfig.json tsconfig.json - -FROM base AS libs -COPY ./packages/utils-library packages/utils-library -COPY ./packages/blockchain-library packages/blockchain-library -RUN yarn install --frozen-lockfile -RUN yarn build:libs -RUN rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* - -FROM base AS scheduler -COPY ./packages/scheduler packages/scheduler -COPY --from=libs ["/app/packages", "./packages"] -RUN yarn install --frozen-lockfile -RUN yarn build:scheduler -RUN rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* -CMD ["yarn", "scheduler"] - -FROM base AS relayer -COPY ./packages/relayer packages/relayer -COPY --from=libs ["/app/packages", "./packages"] -RUN yarn install --frozen-lockfile -RUN yarn build:relayer -RUN rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* -CMD ["yarn", "relayer"] From edfd67cecf62c08b6b9d2c8dc38870bb5d455af1 Mon Sep 17 00:00:00 2001 From: Mikolaj Sobolewksi Date: Thu, 14 Nov 2024 16:22:54 +0300 Subject: [PATCH 12/15] Chore(automated-orders): Added prefix automated-orders --- ...{relayer.yml => automated-orders-relayer.yml} | 16 ++++++---------- ...eduler.yml => automated-orders-scheduler.yml} | 8 ++++---- .github/workflows/build_push.yml | 4 ++-- Dockerfile | 4 ++-- 4 files changed, 14 insertions(+), 18 deletions(-) rename .github/workflows/{relayer.yml => automated-orders-relayer.yml} (83%) rename .github/workflows/{scheduler.yml => automated-orders-scheduler.yml} (89%) diff --git a/.github/workflows/relayer.yml b/.github/workflows/automated-orders-relayer.yml similarity index 83% rename from .github/workflows/relayer.yml rename to .github/workflows/automated-orders-relayer.yml index 9e40c15bd..3b07a0945 100644 --- a/.github/workflows/relayer.yml +++ b/.github/workflows/automated-orders-relayer.yml @@ -1,5 +1,5 @@ --- -name: relayer +name: Automated Orders Relayer on: push: @@ -13,7 +13,7 @@ on: - "automated-orders/packages/relayer/**" - "automated-orders/packages/utils-library/**" tags: - - "relayer/v*" + - "automated-orders-relayer/v*" pull_request: paths: - "automated-orders/package.json" @@ -41,18 +41,14 @@ jobs: run: yarn install working-directory: "automated-orders/" - - name: Run linter + - name: Yarn build working-directory: ./automated-orders - run: yarn lint - - - name: TypeScript build - working-directory: ./automated-orders - run: tsc --build --force --verbose + run: yarn build build-and-push: - if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/relayer/v') + if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/automated-orders-relayer/v') needs: [build] uses: ./.github/workflows/build_push.yml with: - service_name: relayer + service_name: automated-orders-relayer secrets: inherit diff --git a/.github/workflows/scheduler.yml b/.github/workflows/automated-orders-scheduler.yml similarity index 89% rename from .github/workflows/scheduler.yml rename to .github/workflows/automated-orders-scheduler.yml index 77a2379f8..bd1d74a14 100644 --- a/.github/workflows/scheduler.yml +++ b/.github/workflows/automated-orders-scheduler.yml @@ -1,5 +1,5 @@ --- -name: scheduler +name: Automated Orders Scheduler on: push: @@ -13,7 +13,7 @@ on: - "automated-orders/packages/scheduler/**" - "automated-orders/packages/utils-library/**" tags: - - "scheduler/v*" + - "automated-orders-scheduler/v*" pull_request: paths: - "automated-orders/package.json" @@ -50,9 +50,9 @@ jobs: run: tsc --build --force --verbose build-and-push: - if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/scheduler/v') + if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/automated-orders-scheduler/v') needs: [build] uses: ./.github/workflows/build_push.yml with: - service_name: scheduler + service_name: automated-orders-scheduler secrets: inherit diff --git a/.github/workflows/build_push.yml b/.github/workflows/build_push.yml index b1b75b998..8de37e8c7 100644 --- a/.github/workflows/build_push.yml +++ b/.github/workflows/build_push.yml @@ -14,8 +14,8 @@ on: - faucet - wardenkms - spaceward-relay - - scheduler - - relayer + - automated-orders-scheduler + - automated-orders-relayer workflow_call: inputs: service_name: diff --git a/Dockerfile b/Dockerfile index 43997fabb..52736f6b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -172,7 +172,7 @@ RUN pnpm install USER nobody ENTRYPOINT ["pnpm", "relay"] -FROM node-build-env AS scheduler +FROM node-build-env AS automated-orders-scheduler USER node WORKDIR /app COPY --chown=node:node automated-orders/yarn.lock yarn.lock @@ -185,7 +185,7 @@ RUN yarn install --frozen-lockfile && \ rm -rf packages/*/src packages/*/node_modules packages/*/tsconfig* CMD ["yarn", "scheduler"] -FROM node-build-env AS relayer +FROM node-build-env AS automated-orders-relayer USER node WORKDIR /app COPY --chown=node:node automated-orders/yarn.lock yarn.lock From 1a88dfe06c8ce3a99ee2bdb55dfbbb455ddbc8d9 Mon Sep 17 00:00:00 2001 From: Mikolaj Sobolewksi Date: Fri, 15 Nov 2024 09:59:21 +0300 Subject: [PATCH 13/15] Fix(automated-orders): fixed scheduler CI --- .github/workflows/automated-orders-scheduler.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/automated-orders-scheduler.yml b/.github/workflows/automated-orders-scheduler.yml index bd1d74a14..c4defd47b 100644 --- a/.github/workflows/automated-orders-scheduler.yml +++ b/.github/workflows/automated-orders-scheduler.yml @@ -1,5 +1,5 @@ --- -name: Automated Orders Scheduler +name: Automated Orders Scheduler on: push: @@ -41,13 +41,9 @@ jobs: run: yarn install working-directory: "automated-orders/" - - name: Run linter + - name: Yarn build working-directory: ./automated-orders - run: yarn lint - - - name: TypeScript build - working-directory: ./automated-orders - run: tsc --build --force --verbose + run: yarn build build-and-push: if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/automated-orders-scheduler/v') From 09a75cced9c5ee6f7b17341fa0d12ca77dc88108 Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Fri, 15 Nov 2024 11:57:07 +0300 Subject: [PATCH 14/15] Fix tsconfig --- automated-orders/tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/automated-orders/tsconfig.json b/automated-orders/tsconfig.json index e8f64bec0..077d7f9d3 100644 --- a/automated-orders/tsconfig.json +++ b/automated-orders/tsconfig.json @@ -18,10 +18,10 @@ ], "references": [ { - "path": "./packages/blockchain-library" + "path": "./packages/utils-library" }, { - "path": "./packages/utils-library" + "path": "./packages/blockchain-library" }, { "path": "./packages/relayer" From 7afcb9a07a60cf81e3dd1455cf2d6529438dde8c Mon Sep 17 00:00:00 2001 From: Artur Abliazimov Date: Fri, 15 Nov 2024 12:22:26 +0300 Subject: [PATCH 15/15] Fix PR comments --- .../packages/blockchain-library/src/clients/warden.ts | 5 ----- automated-orders/packages/blockchain-library/src/index.ts | 1 - .../blockchain-library/src/processors/orderProcessor.ts | 2 +- automated-orders/packages/scheduler/src/index.ts | 2 +- 4 files changed, 2 insertions(+), 8 deletions(-) delete mode 100644 automated-orders/packages/blockchain-library/src/clients/warden.ts diff --git a/automated-orders/packages/blockchain-library/src/clients/warden.ts b/automated-orders/packages/blockchain-library/src/clients/warden.ts deleted file mode 100644 index 6ef580350..000000000 --- a/automated-orders/packages/blockchain-library/src/clients/warden.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { IWardenConfiguration } from '../types/warden/configuration.js'; - -export class WardenClient { - constructor(private configuration: IWardenConfiguration) {} -} diff --git a/automated-orders/packages/blockchain-library/src/index.ts b/automated-orders/packages/blockchain-library/src/index.ts index f80da1be3..9da8f8c04 100644 --- a/automated-orders/packages/blockchain-library/src/index.ts +++ b/automated-orders/packages/blockchain-library/src/index.ts @@ -1,4 +1,3 @@ -export { WardenClient } from './clients/warden.js'; export { EvmClient } from './clients/evm.js'; export { ChainIds } from './types/evm/constants.js'; export { NewSignatureProcessor } from './processors/newSignatureProcessor.js'; diff --git a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts index 8543e9870..0527e3165 100644 --- a/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts +++ b/automated-orders/packages/blockchain-library/src/processors/orderProcessor.ts @@ -15,7 +15,7 @@ export class OrderProcessor extends Processor { constructor( private evmos: EvmClient, private ethereum: EvmClient, - private supportedChainIds: Map, + private supportedChainIds: Set, private retryAttempts: number, generator: () => AsyncGenerator, ) { diff --git a/automated-orders/packages/scheduler/src/index.ts b/automated-orders/packages/scheduler/src/index.ts index c9b74ac44..049f27791 100644 --- a/automated-orders/packages/scheduler/src/index.ts +++ b/automated-orders/packages/scheduler/src/index.ts @@ -13,7 +13,7 @@ async function main() { rpcURL: config.ETHEREUM_NODE_RPC, }); - const chainIds = new Map([[BigInt(ChainIds.Sepolia), undefined]]); + const chainIds = new Set([BigInt(ChainIds.Sepolia)]); const processor = new OrderProcessor( evmos,