diff --git a/.changeset/big-squids-serve.md b/.changeset/big-squids-serve.md new file mode 100644 index 0000000000..18883a8e60 --- /dev/null +++ b/.changeset/big-squids-serve.md @@ -0,0 +1,8 @@ +--- +'@hyperlane-xyz/helloworld': patch +'@hyperlane-xyz/widgets': patch +'@hyperlane-xyz/cli': patch +'@hyperlane-xyz/sdk': patch +--- + +Bump registry version to v6.3.0. diff --git a/.changeset/empty-lemons-explode.md b/.changeset/empty-lemons-explode.md new file mode 100644 index 0000000000..1116888e23 --- /dev/null +++ b/.changeset/empty-lemons-explode.md @@ -0,0 +1,5 @@ +--- +'@hyperlane-xyz/cli': minor +--- + +Add support for deploying Hooks using a HookConfig within a WarpConfig diff --git a/.changeset/fresh-fishes-bake.md b/.changeset/fresh-fishes-bake.md new file mode 100644 index 0000000000..92b4dfdd2d --- /dev/null +++ b/.changeset/fresh-fishes-bake.md @@ -0,0 +1,6 @@ +--- +'@hyperlane-xyz/sdk': major +--- + +Rename TokenConfig related types and utilities for clarity. E.g. `CollateralConfig` to `CollateralTokenConfig`. +Export more config types and zod schemas diff --git a/.changeset/metal-clocks-count.md b/.changeset/metal-clocks-count.md deleted file mode 100644 index ccea6b73e1..0000000000 --- a/.changeset/metal-clocks-count.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@hyperlane-xyz/infra': minor -'@hyperlane-xyz/sdk': minor ---- - -Add Zerion deployments: WBTC, POL, BNB, USDB diff --git a/.codespell/ignore.txt b/.codespell/ignore.txt index 85cd6f56a9..ec0437cb91 100644 --- a/.codespell/ignore.txt +++ b/.codespell/ignore.txt @@ -5,3 +5,4 @@ receivedFrom ser readded re-use +superseed diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 4d284e827e..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -dist -coverage -*.cts \ No newline at end of file diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index a23e3c2f93..0000000000 --- a/.eslintrc +++ /dev/null @@ -1,65 +0,0 @@ -{ - "env": { - "node": true, - "browser": true, - "es2021": true - }, - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 12, - "sourceType": "module", - "project": "./tsconfig.json" - }, - "plugins": ["@typescript-eslint","jest"], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "prettier" - ], - "rules": { - "no-console": ["error"], - "no-eval": ["error"], - "no-extra-boolean-cast": ["error"], - "no-ex-assign": ["error"], - "no-constant-condition": ["off"], - "no-return-await": ["error"], - "no-restricted-imports": ["error", { - "name": "console", - "message": "Please use a logger and/or the utils' package assert" - }, { - "name": "fs", - "message": "Avoid use of node-specific libraries" - }], - "guard-for-in": ["error"], - "@typescript-eslint/ban-ts-comment": ["off"], - "@typescript-eslint/explicit-module-boundary-types": ["off"], - "@typescript-eslint/no-explicit-any": ["off"], - "@typescript-eslint/no-floating-promises": ["error"], - "@typescript-eslint/no-non-null-assertion": ["off"], - "@typescript-eslint/no-require-imports": ["warn"], - "@typescript-eslint/no-unused-vars": [ - "error", - { - "argsIgnorePattern": "^_", - "varsIgnorePattern": "^_", - "caughtErrorsIgnorePattern": "^_" - } - ], - "@typescript-eslint/ban-types": [ - "error", - { - "types": { - // Unban the {} type which is a useful shorthand for non-nullish value - "{}": false - }, - "extendDefaults": true - } - ], - "jest/no-disabled-tests": "warn", - "jest/no-focused-tests": "error", - "jest/no-identical-title": "error", - "jest/prefer-to-have-length": "warn", - "jest/valid-expect": "error" - } -} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 52410ecd6f..98426a76a6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,6 +54,10 @@ jobs: exit 1 fi + # Check for mismatched dep versions across the monorepo + - name: syncpack + run: yarn syncpack list-mismatches + lint-prettier: runs-on: ubuntu-latest needs: [yarn-install] @@ -73,6 +77,12 @@ jobs: key: ${{ runner.os }}-yarn-4.5.1-cache-${{ hashFiles('./yarn.lock') }} fail-on-cache-miss: true + # Build required before linting or the intra-monorepo package cycle checking won't work + - name: yarn-build + uses: ./.github/actions/yarn-build-with-cache + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + - name: lint run: yarn lint @@ -116,7 +126,9 @@ jobs: fail-fast: false matrix: test: - - core + - core-apply + - core-deploy + - core-read - relay - warp-read - warp-apply diff --git a/.registryrc b/.registryrc index 19d87576f4..ed389daa94 100644 --- a/.registryrc +++ b/.registryrc @@ -1 +1 @@ -82013508db45dcd55b44d2721414d26817686c8f +c7891cdf0fc6a1541c41e19251611c9152ee8bf9 diff --git a/.syncpackrc b/.syncpackrc new file mode 100644 index 0000000000..7c4fd6c9d4 --- /dev/null +++ b/.syncpackrc @@ -0,0 +1,3 @@ +{ + "dependencyTypes": ["prod", "dev"] +} \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000000..3be951d450 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,115 @@ +import { FlatCompat } from '@eslint/eslintrc'; +import js from '@eslint/js'; +import typescriptEslint from '@typescript-eslint/eslint-plugin'; +import tsParser from '@typescript-eslint/parser'; +import importPlugin from 'eslint-plugin-import'; +import jest from 'eslint-plugin-jest'; +import globals from 'globals'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +export const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +export default [ + { + ignores: [ + '**/node_modules', + '**/dist', + '**/coverage', + '**/*.cjs', + '**/*.cts', + '**/*.mjs', + 'jest.config.js', + ], + }, + ...compat.extends( + 'eslint:recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:@typescript-eslint/recommended', + 'prettier', + ), + { + plugins: { + import: importPlugin, + '@typescript-eslint': typescriptEslint, + jest, + }, + + languageOptions: { + globals: { + ...globals.node, + ...globals.browser, + }, + + parser: tsParser, + ecmaVersion: 12, + sourceType: 'module', + + parserOptions: { + project: './tsconfig.json', + }, + }, + + settings: { + 'import/resolver': { + typescript: true, + node: true, + }, + }, + + rules: { + 'guard-for-in': ['error'], + 'import/no-cycle': ['error'], + 'import/no-self-import': ['error'], + 'import/no-named-as-default-member': ['off'], + 'no-console': ['error'], + 'no-eval': ['error'], + 'no-extra-boolean-cast': ['error'], + 'no-ex-assign': ['error'], + 'no-constant-condition': ['off'], + 'no-return-await': ['error'], + + 'no-restricted-imports': [ + 'error', + { + name: 'console', + message: 'Please use a logger and/or the utils package assert', + }, + { + name: 'fs', + message: 'Avoid use of node-specific libraries', + }, + ], + + '@typescript-eslint/ban-ts-comment': ['off'], + '@typescript-eslint/explicit-module-boundary-types': ['off'], + '@typescript-eslint/no-explicit-any': ['off'], + '@typescript-eslint/no-floating-promises': ['error'], + '@typescript-eslint/no-non-null-assertion': ['off'], + '@typescript-eslint/no-require-imports': ['warn'], + '@typescript-eslint/no-unused-expressions': ['off'], + '@typescript-eslint/no-empty-object-type': ['off'], + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + + 'jest/no-disabled-tests': 'warn', + 'jest/no-focused-tests': 'error', + 'jest/no-identical-title': 'error', + 'jest/prefer-to-have-length': 'warn', + 'jest/valid-expect': 'error', + }, + }, +]; diff --git a/package.json b/package.json index 2a2400e965..92d5b4b5d2 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,20 @@ "description": "A yarn workspace of core Hyperlane packages", "version": "0.0.0", "devDependencies": { + "@eslint/js": "^9.15.0", "@trivago/prettier-plugin-sort-imports": "^4.2.1", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", - "eslint": "^8.57.0", + "@typescript-eslint/eslint-plugin": "^8.1.6", + "@typescript-eslint/parser": "^8.1.6", + "eslint": "^9.15.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-jest": "^28.2.0", "husky": "^8.0.0", "lint-staged": "^12.4.3", "prettier": "^2.8.8", - "tsx": "^4.7.1" + "syncpack": "^13.0.0", + "tsx": "^4.19.1" }, "dependencies": { "@changesets/cli": "^2.26.2" @@ -41,6 +45,7 @@ "async": "^2.6.4", "fetch-ponyfill": "^7.1", "flat": "^5.0.2", + "globals": "^14.0.0", "lodash": "^4.17.21", "recursive-readdir": "^2.2.3", "underscore": "^1.13", diff --git a/rust/README.md b/rust/README.md index 289d1dc1d7..35050b1e79 100644 --- a/rust/README.md +++ b/rust/README.md @@ -15,6 +15,15 @@ info: This is the version for the rustup toolchain manager, not the rustc compil info: The currently active `rustc` version is `rustc 1.72.1 (d5c2e9c34 2023-09-13)` ``` +### Overview of Rust Workspaces + +There are two Rust workspaces in this directory: + +- [main](https://github.com/hyperlane-xyz/hyperlane-monorepo/tree/main/rust/main): The offchain agents workspace, most notably comprised of the relayer, validator, scraper and the Rust end-to-end tests (in `utils/run-locally`) +- [sealevel](https://github.com/hyperlane-xyz/hyperlane-monorepo/tree/main/rust/sealevel): Hyperlane smart contracts and tooling for the SVM, implemented in native Rust. + +You can only run `cargo build` after `cd`-ing into one of these workspaces. + #### Apple Silicon If your device has an Apple Silicon processor, you may need to install Rosetta 2: @@ -23,7 +32,9 @@ If your device has an Apple Silicon processor, you may need to install Rosetta 2 softwareupdate --install-rosetta --agree-to-license ``` -### Running Locally +### Running Agents Locally + +Make sure you're in the `main` workspace. To run the validator, run: @@ -174,7 +185,7 @@ For Ethereum and Celo connections we use We use the tokio async runtime environment. Please see the docs [here](https://docs.rs/tokio/1.1.0/tokio/). -### Repo layout +### `main` workspace layout - `hyperlane-base` - lowest dependency hyperlane utilities @@ -190,11 +201,9 @@ We use the tokio async runtime environment. Please see the docs - traits (interfaces) for the on-chain contracts - model implementations of the contracts in rust - merkle tree implementations (for provers) -- `chains/hyperlane-ethereum` +- `chains/hyperlane-*` + - VM-specific integration of the agents - depends on hyperlane-core (and transitively hyperlane-base) - - interfaces to the ethereum contracts -- `chains/hyperlane-fuel` - - depends on hyperlane-core - - interfaces to the fuel contracts + - interfaces with the contracts of that VM (e.g `ethereum`, `sealevel`, `cosmos`, `fuel`, etc) - `agents` - each of the off-chain agents implemented thus far diff --git a/rust/main/Cargo.lock b/rust/main/Cargo.lock index 6dfcb67cee..e8831b6029 100644 --- a/rust/main/Cargo.lock +++ b/rust/main/Cargo.lock @@ -2564,7 +2564,8 @@ dependencies = [ [[package]] name = "ed25519-dalek" version = "1.0.1" -source = "git+https://github.com/Eclipse-Laboratories-Inc/ed25519-dalek?branch=main#7529d65506147b6cb24ca6d8f4fc062cac33b395" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek 3.2.2", "ed25519 1.5.3", @@ -2900,7 +2901,7 @@ dependencies = [ [[package]] name = "ethers" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -2914,7 +2915,7 @@ dependencies = [ [[package]] name = "ethers-addressbook" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "ethers-core", "once_cell", @@ -2925,7 +2926,7 @@ dependencies = [ [[package]] name = "ethers-contract" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", @@ -2943,7 +2944,7 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "Inflector", "cfg-if", @@ -2967,7 +2968,7 @@ dependencies = [ [[package]] name = "ethers-contract-derive" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "ethers-contract-abigen", "ethers-core", @@ -2981,7 +2982,7 @@ dependencies = [ [[package]] name = "ethers-core" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "arrayvec", "bytes", @@ -3011,7 +3012,7 @@ dependencies = [ [[package]] name = "ethers-etherscan" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "ethers-core", "getrandom 0.2.15", @@ -3027,7 +3028,7 @@ dependencies = [ [[package]] name = "ethers-middleware" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "async-trait", "auto_impl 0.5.0", @@ -3075,7 +3076,7 @@ dependencies = [ [[package]] name = "ethers-providers" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "async-trait", "auto_impl 1.2.0", @@ -3111,7 +3112,7 @@ dependencies = [ [[package]] name = "ethers-signers" version = "1.0.2" -source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-04-25#361b69b9561e11eb3cf8000a51de1985e2571785" +source = "git+https://github.com/hyperlane-xyz/ethers-rs?tag=2024-12-03-3#edf703a6e515266245b88bb4f1daad24f7c6566c" dependencies = [ "async-trait", "coins-bip32 0.7.0", @@ -8353,7 +8354,7 @@ dependencies = [ [[package]] name = "solana-account-decoder" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "Inflector", "base64 0.13.1", @@ -8377,7 +8378,7 @@ dependencies = [ [[package]] name = "solana-address-lookup-table-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "bytemuck", @@ -8397,7 +8398,7 @@ dependencies = [ [[package]] name = "solana-clap-utils" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "chrono", "clap 2.34.0", @@ -8414,7 +8415,7 @@ dependencies = [ [[package]] name = "solana-cli-config" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "dirs-next", "lazy_static", @@ -8429,7 +8430,7 @@ dependencies = [ [[package]] name = "solana-client" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "async-mutex", "async-trait", @@ -8482,7 +8483,7 @@ dependencies = [ [[package]] name = "solana-config-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "chrono", @@ -8495,7 +8496,7 @@ dependencies = [ [[package]] name = "solana-faucet" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "byteorder", @@ -8518,7 +8519,7 @@ dependencies = [ [[package]] name = "solana-frozen-abi" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "ahash 0.7.8", "blake3", @@ -8551,7 +8552,7 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "proc-macro2 1.0.86", "quote 1.0.37", @@ -8562,7 +8563,7 @@ dependencies = [ [[package]] name = "solana-logger" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "env_logger", "lazy_static", @@ -8572,7 +8573,7 @@ dependencies = [ [[package]] name = "solana-measure" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "log", "solana-sdk", @@ -8581,7 +8582,7 @@ dependencies = [ [[package]] name = "solana-metrics" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "crossbeam-channel", "gethostname", @@ -8594,7 +8595,7 @@ dependencies = [ [[package]] name = "solana-net-utils" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "clap 3.2.25", @@ -8615,7 +8616,7 @@ dependencies = [ [[package]] name = "solana-perf" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "ahash 0.7.8", "bincode", @@ -8641,7 +8642,7 @@ dependencies = [ [[package]] name = "solana-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "base64 0.13.1", "bincode", @@ -8689,7 +8690,7 @@ dependencies = [ [[package]] name = "solana-program-runtime" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "base64 0.13.1", "bincode", @@ -8715,7 +8716,7 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "lazy_static", "num_cpus", @@ -8724,7 +8725,7 @@ dependencies = [ [[package]] name = "solana-remote-wallet" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "console", "dialoguer", @@ -8742,7 +8743,7 @@ dependencies = [ [[package]] name = "solana-sdk" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "assert_matches", "base64 0.13.1", @@ -8792,7 +8793,7 @@ dependencies = [ [[package]] name = "solana-sdk-macro" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bs58 0.4.0", "proc-macro2 1.0.86", @@ -8804,7 +8805,7 @@ dependencies = [ [[package]] name = "solana-streamer" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "crossbeam-channel", "futures-util", @@ -8832,7 +8833,7 @@ dependencies = [ [[package]] name = "solana-transaction-status" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "Inflector", "base64 0.13.1", @@ -8860,7 +8861,7 @@ dependencies = [ [[package]] name = "solana-version" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "log", "rustc_version", @@ -8875,7 +8876,7 @@ dependencies = [ [[package]] name = "solana-vote-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "log", @@ -8895,7 +8896,7 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "aes-gcm-siv", "arrayref", diff --git a/rust/main/Cargo.toml b/rust/main/Cargo.toml index e9192b7f0f..3fcdfa294c 100644 --- a/rust/main/Cargo.toml +++ b/rust/main/Cargo.toml @@ -126,24 +126,9 @@ sha2 = { version = "0.10.6", default-features = false } sha256 = "1.1.4" sha3 = "0.10" solana-account-decoder = "=1.14.13" -solana-banks-client = "=1.14.13" -solana-banks-interface = "=1.14.13" -solana-banks-server = "=1.14.13" -solana-clap-utils = "=1.14.13" -solana-cli-config = "=1.14.13" solana-client = "=1.14.13" -solana-program = "=1.14.13" -solana-program-test = "=1.14.13" solana-sdk = "=1.14.13" solana-transaction-status = "=1.14.13" -solana-zk-token-sdk = "=1.14.13" -spl-associated-token-account = { version = "=1.1.2", features = [ - "no-entrypoint", -] } -spl-noop = { version = "=0.1.3", features = ["no-entrypoint"] } -spl-token = { version = "=3.5.0", features = ["no-entrypoint"] } -spl-token-2022 = { version = "=0.5.0", features = ["no-entrypoint"] } -spl-type-length-value = "=0.1.0" static_assertions = "1.1" strum = "0.26.2" strum_macros = "0.26.2" @@ -212,38 +197,33 @@ overflow-checks = true [workspace.dependencies.ethers] features = [] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-12-03-3" [workspace.dependencies.ethers-contract] features = ["legacy"] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-12-03-3" [workspace.dependencies.ethers-core] features = [] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-12-03-3" [workspace.dependencies.ethers-providers] features = [] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-12-03-3" [workspace.dependencies.ethers-signers] features = ["aws"] git = "https://github.com/hyperlane-xyz/ethers-rs" -tag = "2024-04-25" +tag = "2024-12-03-3" [patch.crates-io.curve25519-dalek] branch = "v3.2.2-relax-zeroize" git = "https://github.com/Eclipse-Laboratories-Inc/curve25519-dalek" version = "3.2.2" -[patch.crates-io.ed25519-dalek] -branch = "main" -git = "https://github.com/Eclipse-Laboratories-Inc/ed25519-dalek" -version = "1.0.1" - [patch.crates-io.primitive-types] branch = "hyperlane" git = "https://github.com/hyperlane-xyz/parity-common.git" @@ -256,42 +236,42 @@ version = "=0.5.2" [patch.crates-io.solana-account-decoder] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-clap-utils] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-cli-config] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-client] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-program] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-sdk] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-transaction-status] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-zk-token-sdk] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.spl-associated-token-account] diff --git a/rust/main/agents/relayer/src/relayer.rs b/rust/main/agents/relayer/src/relayer.rs index 1ac619792c..6bd1a63a8d 100644 --- a/rust/main/agents/relayer/src/relayer.rs +++ b/rust/main/agents/relayer/src/relayer.rs @@ -152,6 +152,7 @@ impl BaseAgent for Relayer { dbs.iter() .map(|(d, db)| (d.clone(), Arc::new(db.clone()))) .collect(), + false, ) .await? .into_iter() @@ -166,6 +167,7 @@ impl BaseAgent for Relayer { dbs.iter() .map(|(d, db)| (d.clone(), Arc::new(db.clone()))) .collect(), + false, ) .await? .into_iter() @@ -180,6 +182,7 @@ impl BaseAgent for Relayer { dbs.iter() .map(|(d, db)| (d.clone(), Arc::new(db.clone()))) .collect(), + false, ) .await? .into_iter() diff --git a/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs b/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs index 848bb05e48..606a16c5da 100644 --- a/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs +++ b/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs @@ -14,6 +14,7 @@ use sea_orm_migration::prelude::*; /// This is why it does not use the domain id lookup tools in the library which /// are subject to change as we deprecate and add new ones. const DOMAINS: &[RawDomain] = &[ + // ---------- Begin: Mainnets and Testnets (alphabetically sorted) ------------- RawDomain { name: "alfajores", token: "CELO", @@ -38,6 +39,14 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: false, is_deprecated: false, }, + RawDomain { + name: "arbitrumsepolia", + token: "ETH", + domain: 421614, + chain_id: 421614, + is_test_net: true, + is_deprecated: false, + }, RawDomain { name: "avalanche", token: "AVAX", @@ -54,6 +63,14 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: false, is_deprecated: false, }, + RawDomain { + name: "basesepolia", + token: "ETH", + domain: 84532, + chain_id: 84532, + is_test_net: true, + is_deprecated: false, + }, RawDomain { name: "blast", token: "ETH", @@ -102,6 +119,38 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: false, is_deprecated: false, }, + RawDomain { + name: "connextsepolia", + token: "ETH", + domain: 6398, + chain_id: 6398, + is_test_net: true, + is_deprecated: false, + }, + RawDomain { + name: "eclipsemainnet", + token: "ETH", + domain: 1408864445, + chain_id: 1408864445, + is_test_net: false, + is_deprecated: false, + }, + RawDomain { + name: "eclipsetestnet", + token: "ETH", + domain: 239092742, + chain_id: 239092742, + is_test_net: true, + is_deprecated: false, + }, + RawDomain { + name: "ecotestnet", + token: "ETH", + domain: 471923, + chain_id: 471923, + is_test_net: true, + is_deprecated: false, + }, RawDomain { name: "endurance", token: "ETH", @@ -158,6 +207,22 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: false, is_deprecated: false, }, + RawDomain { + name: "inevm", + token: "INJ", + domain: 2525, + chain_id: 2525, + is_test_net: false, + is_deprecated: false, + }, + RawDomain { + name: "injective", + token: "INJ", + domain: 6909546, + chain_id: 6909546, + is_test_net: false, + is_deprecated: false, + }, RawDomain { name: "linea", token: "ETH", @@ -206,6 +271,14 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: false, is_deprecated: false, }, + RawDomain { + name: "neutron", + token: "NTRN", + domain: 1853125230, + chain_id: 1853125230, + is_test_net: false, + is_deprecated: false, + }, RawDomain { name: "optimism", token: "ETH", @@ -214,6 +287,22 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: false, is_deprecated: false, }, + RawDomain { + name: "optimismsepolia", + token: "ETH", + domain: 11155420, + chain_id: 11155420, + is_test_net: true, + is_deprecated: false, + }, + RawDomain { + name: "osmosis", + token: "OSMO", + domain: 875, + chain_id: 875, + is_test_net: false, + is_deprecated: false, + }, RawDomain { name: "polygon", token: "MATIC", @@ -222,6 +311,14 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: false, is_deprecated: false, }, + RawDomain { + name: "polygonanoy", + token: "MATIC", + domain: 80002, + chain_id: 80002, + is_test_net: true, + is_deprecated: false, + }, RawDomain { name: "polygonzkevm", token: "ETH", @@ -271,13 +368,29 @@ const DOMAINS: &[RawDomain] = &[ is_deprecated: false, }, RawDomain { - name: "eclipsemainnet", - token: "ETH", - domain: 1408864445, - chain_id: 1408864445, + name: "solanatestnet", + token: "SOL", + domain: 1399811150, + chain_id: 1399811150, + is_test_net: true, + is_deprecated: false, + }, + RawDomain { + name: "stride", + token: "STRD", + domain: 745, + chain_id: 745, is_test_net: false, is_deprecated: false, }, + RawDomain { + name: "superpositiontestnet", + token: "SPN", + domain: 98985, + chain_id: 98985, + is_test_net: true, + is_deprecated: false, + }, RawDomain { name: "taiko", token: "ETH", @@ -294,14 +407,6 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: false, is_deprecated: false, }, - RawDomain { - name: "inevm", - token: "INJ", - domain: 2525, - chain_id: 2525, - is_test_net: false, - is_deprecated: false, - }, RawDomain { name: "xlayer", token: "OKB", @@ -334,62 +439,8 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: false, is_deprecated: false, }, - RawDomain { - name: "connextsepolia", - token: "ETH", - domain: 6398, - chain_id: 6398, - is_test_net: true, - is_deprecated: false, - }, - RawDomain { - name: "superpositiontestnet", - token: "SPN", - domain: 98985, - chain_id: 98985, - is_test_net: true, - is_deprecated: false, - }, - RawDomain { - name: "arbitrumsepolia", - token: "ETH", - domain: 421614, - chain_id: 421614, - is_test_net: true, - is_deprecated: false, - }, - RawDomain { - name: "basesepolia", - token: "ETH", - domain: 84532, - chain_id: 84532, - is_test_net: true, - is_deprecated: false, - }, - RawDomain { - name: "ecotestnet", - token: "ETH", - domain: 471923, - chain_id: 471923, - is_test_net: true, - is_deprecated: false, - }, - RawDomain { - name: "optimismsepolia", - token: "ETH", - domain: 11155420, - chain_id: 11155420, - is_test_net: true, - is_deprecated: false, - }, - RawDomain { - name: "polygonanoy", - token: "MATIC", - domain: 80002, - chain_id: 80002, - is_test_net: true, - is_deprecated: false, - }, + // ---------- End: Mainnets and Testnets (alphabetically sorted) --------------- + // ---------- Begin: E2E tests chains ------------------------------------------ RawDomain { name: "test1", token: "ETH", @@ -414,38 +465,6 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: true, is_deprecated: false, }, - RawDomain { - name: "injective", - token: "INJ", - domain: 6909546, - chain_id: 6909546, - is_test_net: false, - is_deprecated: false, - }, - RawDomain { - name: "neutron", - token: "NTRN", - domain: 1853125230, - chain_id: 1853125230, - is_test_net: false, - is_deprecated: false, - }, - RawDomain { - name: "osmosis", - token: "OSMO", - domain: 875, - chain_id: 875, - is_test_net: false, - is_deprecated: false, - }, - RawDomain { - name: "stride", - token: "STRD", - domain: 745, - chain_id: 745, - is_test_net: false, - is_deprecated: false, - }, RawDomain { name: "cosmostest99990", token: "OSMO", @@ -462,6 +481,23 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: true, is_deprecated: false, }, + RawDomain { + name: "sealeveltest1", + token: "SOL", + domain: 13375, + chain_id: 13375, + is_test_net: true, + is_deprecated: false, + }, + RawDomain { + name: "sealeveltest2", + token: "SOL", + domain: 13376, + chain_id: 13376, + is_test_net: true, + is_deprecated: false, + }, + // ---------- End: E2E tests chains ---------------- ]; #[derive(DeriveMigrationName)] diff --git a/rust/main/agents/scraper/migration/src/m20230309_000003_create_table_cursor.rs b/rust/main/agents/scraper/migration/src/m20230309_000003_create_table_cursor.rs index 2b50414f81..dd8c1d2e96 100644 --- a/rust/main/agents/scraper/migration/src/m20230309_000003_create_table_cursor.rs +++ b/rust/main/agents/scraper/migration/src/m20230309_000003_create_table_cursor.rs @@ -35,7 +35,20 @@ impl MigrationTrait for Migration { ) .to_owned(), ) - .await + .await?; + + manager + .create_index( + Index::create() + .table(Cursor::Table) + .name("cursor_domain_idx") + .col(Cursor::Domain) + .index_type(IndexType::BTree) + .to_owned(), + ) + .await?; + + Ok(()) } async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { diff --git a/rust/main/agents/scraper/migration/src/m20230309_000004_create_table_delivered_message.rs b/rust/main/agents/scraper/migration/src/m20230309_000004_create_table_delivered_message.rs index c7e4a1dc59..45cb71ec47 100644 --- a/rust/main/agents/scraper/migration/src/m20230309_000004_create_table_delivered_message.rs +++ b/rust/main/agents/scraper/migration/src/m20230309_000004_create_table_delivered_message.rs @@ -47,6 +47,7 @@ impl MigrationTrait for Migration { .big_integer() .not_null(), ) + .col(ColumnDef::new(DeliveredMessage::Sequence).big_integer()) .foreign_key( ForeignKey::create() .from_col(DeliveredMessage::Domain) @@ -105,4 +106,6 @@ pub enum DeliveredMessage { DestinationMailbox, /// Transaction the delivery was included in DestinationTxId, + /// Sequence when message was delivered + Sequence, } diff --git a/rust/main/agents/scraper/migration/src/m20230309_000004_create_table_gas_payment.rs b/rust/main/agents/scraper/migration/src/m20230309_000004_create_table_gas_payment.rs index 7f3da9a780..9285c83468 100644 --- a/rust/main/agents/scraper/migration/src/m20230309_000004_create_table_gas_payment.rs +++ b/rust/main/agents/scraper/migration/src/m20230309_000004_create_table_gas_payment.rs @@ -39,6 +39,17 @@ impl MigrationTrait for Migration { .big_unsigned() .not_null(), ) + .col(ColumnDef::new(GasPayment::Origin).unsigned().not_null()) + .col( + ColumnDef::new(GasPayment::Destination) + .unsigned() + .not_null(), + ) + .col( + ColumnDef::new_with_type(GasPayment::InterchainGasPaymaster, Address) + .not_null(), + ) + .col(ColumnDef::new(GasPayment::Sequence).big_integer()) .foreign_key( ForeignKey::create() .from_col(GasPayment::TxId) @@ -49,6 +60,11 @@ impl MigrationTrait for Migration { .from_col(GasPayment::Domain) .to(Domain::Table, Domain::Id), ) + .foreign_key( + ForeignKey::create() + .from_col(GasPayment::Origin) + .to(Domain::Table, Domain::Id), + ) .index( Index::create() // don't need domain because TxId includes it @@ -71,6 +87,19 @@ impl MigrationTrait for Migration { ) .await?; + manager + .create_index( + Index::create() + .table(GasPayment::Table) + .name("gas_payment_origin_interchain_gas_paymaster_sequence_idx") + .col(GasPayment::Origin) + .col(GasPayment::InterchainGasPaymaster) + .col(GasPayment::Sequence) + .index_type(IndexType::BTree) + .to_owned(), + ) + .await?; + manager .get_connection() .execute_unprepared(&format!( @@ -136,6 +165,16 @@ pub enum GasPayment { /// Used to disambiguate duplicate payments from multiple payments made in /// same transaction. LogIndex, + /// Domain ID of the chain the payment was made on; technically duplicating + /// field Domain, but Domain becomes ambiguous as we add Destination domain as well. + Origin, + /// Domain ID of the chain the payment was made for. + Destination, + /// Interchain Gas Paymaster contract address + InterchainGasPaymaster, + /// Sequence of this payment for indexing by agent. It can be null if agent + /// does not use sequence-aware indexing. + Sequence, } #[derive(Iden)] diff --git a/rust/main/agents/scraper/src/agent.rs b/rust/main/agents/scraper/src/agent.rs index 97f6bd3db1..d1ded9010e 100644 --- a/rust/main/agents/scraper/src/agent.rs +++ b/rust/main/agents/scraper/src/agent.rs @@ -5,7 +5,7 @@ use derive_more::AsRef; use futures::future::try_join_all; use hyperlane_core::{Delivery, HyperlaneDomain, HyperlaneMessage, InterchainGasPayment, H512}; use tokio::{sync::mpsc::Receiver as MpscReceiver, task::JoinHandle}; -use tracing::{info_span, instrument::Instrumented, trace, Instrument}; +use tracing::{info, info_span, instrument::Instrumented, trace, Instrument}; use hyperlane_base::{ broadcast::BroadcastMpscSender, metrics::AgentMetrics, settings::IndexSettings, AgentMetadata, @@ -59,18 +59,24 @@ impl BaseAgent for Scraper { let mut scrapers: HashMap = HashMap::new(); for domain in settings.chains_to_scrape.iter() { + info!(domain = domain.name(), "create chain scraper for domain"); let chain_setup = settings.chain_setup(domain).expect("Missing chain config"); + info!(domain = domain.name(), "create HyperlaneProvider"); + let provider = settings + .build_provider(domain, &metrics.clone()) + .await? + .into(); + info!(domain = domain.name(), "create HyperlaneDbStore"); let store = HyperlaneDbStore::new( db.clone(), - chain_setup.addresses.mailbox, domain.clone(), - settings - .build_provider(domain, &metrics.clone()) - .await? - .into(), + chain_setup.addresses.mailbox, + chain_setup.addresses.interchain_gas_paymaster, + provider, &chain_setup.index.clone(), ) .await?; + info!(domain = domain.name(), "insert chain scraper"); scrapers.insert( domain.id(), ChainScraper { @@ -198,6 +204,7 @@ impl Scraper { &metrics.clone(), &contract_sync_metrics.clone(), store.into(), + true, ) .await .unwrap(); @@ -224,11 +231,12 @@ impl Scraper { let sync = self .as_ref() .settings - .watermark_contract_sync::( + .contract_sync::( &domain, &metrics.clone(), &contract_sync_metrics.clone(), Arc::new(store.clone()) as _, + true, ) .await .unwrap(); @@ -256,11 +264,12 @@ impl Scraper { let sync = self .as_ref() .settings - .watermark_contract_sync::( + .contract_sync::( &domain, &metrics.clone(), &contract_sync_metrics.clone(), - Arc::new(store.clone()), + Arc::new(store.clone()) as _, + true, ) .await .unwrap(); diff --git a/rust/main/agents/scraper/src/conversions.rs b/rust/main/agents/scraper/src/conversions.rs index 9252d5cd44..33bbbc229e 100644 --- a/rust/main/agents/scraper/src/conversions.rs +++ b/rust/main/agents/scraper/src/conversions.rs @@ -8,3 +8,31 @@ pub fn u256_to_decimal(v: U256) -> BigDecimal { v.to_little_endian(&mut buf); BigDecimal::from(BigInt::from_bytes_le(Sign::Plus, &buf as &[u8])) } + +pub fn decimal_to_u256(v: BigDecimal) -> U256 { + let (i, _) = v.into_bigint_and_exponent(); + let (_, b) = i.to_bytes_le(); + U256::from_little_endian(&b) +} + +#[cfg(test)] +mod tests { + use hyperlane_core::U256; + + use crate::conversions::{decimal_to_u256, u256_to_decimal}; + + #[test] + fn test() { + // given + let u = U256::from_dec_str( + "76418673493495739447102571088210420170780567439841463646292940247514478199569", + ) + .unwrap(); + + // when + let r = decimal_to_u256(u256_to_decimal(u)); + + // then + assert_eq!(u, r); + } +} diff --git a/rust/main/agents/scraper/src/db/generated/delivered_message.rs b/rust/main/agents/scraper/src/db/generated/delivered_message.rs index 542d1c8e78..a3da2fe6de 100644 --- a/rust/main/agents/scraper/src/db/generated/delivered_message.rs +++ b/rust/main/agents/scraper/src/db/generated/delivered_message.rs @@ -19,6 +19,7 @@ pub struct Model { pub domain: i32, pub destination_mailbox: Vec, pub destination_tx_id: i64, + pub sequence: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] @@ -29,6 +30,7 @@ pub enum Column { Domain, DestinationMailbox, DestinationTxId, + Sequence, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] @@ -59,6 +61,7 @@ impl ColumnTrait for Column { Self::Domain => ColumnType::Integer.def(), Self::DestinationMailbox => ColumnType::Binary(BlobSize::Blob(None)).def(), Self::DestinationTxId => ColumnType::BigInteger.def(), + Self::Sequence => ColumnType::BigInteger.def().null(), } } } diff --git a/rust/main/agents/scraper/src/db/generated/gas_payment.rs b/rust/main/agents/scraper/src/db/generated/gas_payment.rs index d4e3d53ace..5df74b084a 100644 --- a/rust/main/agents/scraper/src/db/generated/gas_payment.rs +++ b/rust/main/agents/scraper/src/db/generated/gas_payment.rs @@ -21,6 +21,10 @@ pub struct Model { pub gas_amount: BigDecimal, pub tx_id: i64, pub log_index: i64, + pub origin: i32, + pub destination: i32, + pub interchain_gas_paymaster: Vec, + pub sequence: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] @@ -33,6 +37,10 @@ pub enum Column { GasAmount, TxId, LogIndex, + Origin, + Destination, + InterchainGasPaymaster, + Sequence, } #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] @@ -50,6 +58,7 @@ impl PrimaryKeyTrait for PrimaryKey { #[derive(Copy, Clone, Debug, EnumIter)] pub enum Relation { Domain, + Origin, Transaction, } @@ -65,6 +74,12 @@ impl ColumnTrait for Column { Self::GasAmount => ColumnType::Decimal(Some((78u32, 0u32))).def(), Self::TxId => ColumnType::BigInteger.def(), Self::LogIndex => ColumnType::BigInteger.def(), + Self::Origin => ColumnType::Integer.def(), + Self::Destination => ColumnType::Integer.def(), + Self::InterchainGasPaymaster => { + ColumnType::Binary(sea_orm::sea_query::BlobSize::Blob(None)).def() + } + Self::Sequence => ColumnType::BigInteger.def().null(), } } } @@ -76,6 +91,10 @@ impl RelationTrait for Relation { .from(Column::Domain) .to(super::domain::Column::Id) .into(), + Self::Origin => Entity::belongs_to(super::domain::Entity) + .from(Column::Origin) + .to(super::domain::Column::Id) + .into(), Self::Transaction => Entity::belongs_to(super::transaction::Entity) .from(Column::TxId) .to(super::transaction::Column::Id) diff --git a/rust/main/agents/scraper/src/db/message.rs b/rust/main/agents/scraper/src/db/message.rs index 0796400f6b..fc39049049 100644 --- a/rust/main/agents/scraper/src/db/message.rs +++ b/rust/main/agents/scraper/src/db/message.rs @@ -6,7 +6,7 @@ use sea_orm::{prelude::*, ActiveValue::*, DeriveColumn, EnumIter, Insert, QueryS use tracing::{debug, instrument, trace}; use hyperlane_core::{ - address_to_bytes, bytes_to_address, h256_to_bytes, HyperlaneMessage, LogMeta, H256, + address_to_bytes, bytes_to_address, h256_to_bytes, Delivery, HyperlaneMessage, LogMeta, H256, }; use migration::OnConflict; @@ -18,6 +18,7 @@ use super::generated::{delivered_message, message}; #[derive(Debug, Clone)] pub struct StorableDelivery<'a> { pub message_id: H256, + pub sequence: Option, pub meta: &'a LogMeta, /// The database id of the transaction the delivery event occurred in pub txn_id: i64, @@ -31,64 +32,54 @@ pub struct StorableMessage<'a> { } impl ScraperDb { - /// Get the dispatched message associated with a nonce. + /// Get the delivered message associated with a sequence. #[instrument(skip(self))] - pub async fn retrieve_message_by_nonce( + pub async fn retrieve_delivery_by_sequence( &self, - origin_domain: u32, - origin_mailbox: &H256, - nonce: u32, - ) -> Result> { - #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] - enum QueryAs { - Nonce, - } - if let Some(message) = message::Entity::find() - .filter(message::Column::Origin.eq(origin_domain)) - .filter(message::Column::OriginMailbox.eq(address_to_bytes(origin_mailbox))) - .filter(message::Column::Nonce.eq(nonce)) + destination_domain: u32, + destination_mailbox: &H256, + sequence: u32, + ) -> Result> { + if let Some(delivery) = delivered_message::Entity::find() + .filter(delivered_message::Column::Domain.eq(destination_domain)) + .filter( + delivered_message::Column::DestinationMailbox + .eq(address_to_bytes(destination_mailbox)), + ) + .filter(delivered_message::Column::Sequence.eq(sequence)) .one(&self.0) .await? { - Ok(Some(HyperlaneMessage { - // We do not write version to the DB. - version: 3, - origin: message.origin as u32, - destination: message.destination as u32, - nonce: message.nonce as u32, - sender: bytes_to_address(message.sender)?, - recipient: bytes_to_address(message.recipient)?, - body: message.msg_body.unwrap_or(Vec::new()), - })) + let delivery = H256::from_slice(&delivery.msg_id); + Ok(Some(delivery)) } else { Ok(None) } } - /// Get the tx id associated with a dispatched message. + /// Get the tx id of a delivered message associated with a sequence. #[instrument(skip(self))] - pub async fn retrieve_dispatched_tx_id( + pub async fn retrieve_delivered_message_tx_id( &self, - origin_domain: u32, - origin_mailbox: &H256, - nonce: u32, + destination_domain: u32, + destination_mailbox: &H256, + sequence: u32, ) -> Result> { - #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] - enum QueryAs { - Nonce, - } - - let tx_id = message::Entity::find() - .filter(message::Column::Origin.eq(origin_domain)) - .filter(message::Column::OriginMailbox.eq(address_to_bytes(origin_mailbox))) - .filter(message::Column::Nonce.eq(nonce)) - .select_only() - .column_as(message::Column::OriginTxId.max(), QueryAs::Nonce) - .group_by(message::Column::Origin) - .into_values::() + if let Some(delivery) = delivered_message::Entity::find() + .filter(delivered_message::Column::Domain.eq(destination_domain)) + .filter( + delivered_message::Column::DestinationMailbox + .eq(address_to_bytes(destination_mailbox)), + ) + .filter(delivered_message::Column::Sequence.eq(sequence)) .one(&self.0) - .await?; - Ok(tx_id) + .await? + { + let txn_id = delivery.destination_tx_id; + Ok(Some(txn_id)) + } else { + Ok(None) + } } async fn latest_deliveries_id(&self, domain: u32, destination_mailbox: Vec) -> Result { @@ -147,6 +138,7 @@ impl ScraperDb { domain: Unchanged(domain as i32), destination_mailbox: Unchanged(destination_mailbox.clone()), destination_tx_id: Set(delivery.txn_id), + sequence: Set(delivery.sequence), }) .collect_vec(); @@ -180,6 +172,66 @@ impl ScraperDb { Ok(new_deliveries_count) } + /// Get the dispatched message associated with a nonce. + #[instrument(skip(self))] + pub async fn retrieve_dispatched_message_by_nonce( + &self, + origin_domain: u32, + origin_mailbox: &H256, + nonce: u32, + ) -> Result> { + #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] + enum QueryAs { + Nonce, + } + if let Some(message) = message::Entity::find() + .filter(message::Column::Origin.eq(origin_domain)) + .filter(message::Column::OriginMailbox.eq(address_to_bytes(origin_mailbox))) + .filter(message::Column::Nonce.eq(nonce)) + .one(&self.0) + .await? + { + Ok(Some(HyperlaneMessage { + // We do not write version to the DB. + version: 3, + origin: message.origin as u32, + destination: message.destination as u32, + nonce: message.nonce as u32, + sender: bytes_to_address(message.sender)?, + recipient: bytes_to_address(message.recipient)?, + body: message.msg_body.unwrap_or(Vec::new()), + })) + } else { + Ok(None) + } + } + + /// Get the tx id associated with a dispatched message. + #[instrument(skip(self))] + pub async fn retrieve_dispatched_tx_id( + &self, + origin_domain: u32, + origin_mailbox: &H256, + nonce: u32, + ) -> Result> { + #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] + enum QueryAs { + Nonce, + } + + let tx_id = message::Entity::find() + .filter(message::Column::Origin.eq(origin_domain)) + .filter(message::Column::OriginMailbox.eq(address_to_bytes(origin_mailbox))) + .filter(message::Column::Nonce.eq(nonce)) + .select_only() + .column_as(message::Column::OriginTxId.max(), QueryAs::Nonce) + .group_by(message::Column::Origin) + .into_values::() + .one(&self.0) + .await?; + Ok(tx_id) + } + async fn latest_dispatched_id(&self, domain: u32, origin_mailbox: Vec) -> Result { let result = message::Entity::find() .select_only() diff --git a/rust/main/agents/scraper/src/db/payment.rs b/rust/main/agents/scraper/src/db/payment.rs index 498128c34b..61f521aa27 100644 --- a/rust/main/agents/scraper/src/db/payment.rs +++ b/rust/main/agents/scraper/src/db/payment.rs @@ -1,35 +1,95 @@ use eyre::{eyre, Result}; use itertools::Itertools; use sea_orm::{prelude::*, ActiveValue::*, Insert, QuerySelect}; -use tracing::{debug, instrument, trace}; +use tracing::{debug, instrument}; -use hyperlane_core::{h256_to_bytes, InterchainGasPayment, LogMeta}; +use hyperlane_core::{address_to_bytes, h256_to_bytes, InterchainGasPayment, LogMeta, H256}; use migration::OnConflict; -use crate::conversions::u256_to_decimal; +use crate::conversions::{decimal_to_u256, u256_to_decimal}; use crate::date_time; use crate::db::ScraperDb; use super::generated::gas_payment; +#[derive(Debug)] pub struct StorablePayment<'a> { pub payment: &'a InterchainGasPayment, + pub sequence: Option, pub meta: &'a LogMeta, /// The database id of the transaction the payment was made in pub txn_id: i64, } impl ScraperDb { + /// Get the payment associated with a sequence. + #[instrument(skip(self))] + pub async fn retrieve_payment_by_sequence( + &self, + origin: u32, + interchain_gas_paymaster: &H256, + sequence: u32, + ) -> Result> { + if let Some(payment) = gas_payment::Entity::find() + .filter(gas_payment::Column::Origin.eq(origin)) + .filter( + gas_payment::Column::InterchainGasPaymaster + .eq(address_to_bytes(interchain_gas_paymaster)), + ) + .filter(gas_payment::Column::Sequence.eq(sequence)) + .one(&self.0) + .await? + { + let payment = InterchainGasPayment { + message_id: H256::from_slice(&payment.msg_id), + destination: payment.destination as u32, + payment: decimal_to_u256(payment.payment), + gas_amount: decimal_to_u256(payment.gas_amount), + }; + Ok(Some(payment)) + } else { + Ok(None) + } + } + + /// Get the transaction id of the gas payment associated with a sequence. + #[instrument(skip(self))] + pub async fn retrieve_payment_tx_id( + &self, + origin: u32, + interchain_gas_paymaster: &H256, + sequence: u32, + ) -> Result> { + if let Some(payment) = gas_payment::Entity::find() + .filter(gas_payment::Column::Origin.eq(origin)) + .filter( + gas_payment::Column::InterchainGasPaymaster + .eq(address_to_bytes(interchain_gas_paymaster)), + ) + .filter(gas_payment::Column::Sequence.eq(sequence)) + .one(&self.0) + .await? + { + let txn_id = payment.tx_id; + Ok(Some(txn_id)) + } else { + Ok(None) + } + } + #[instrument(skip_all)] pub async fn store_payments( &self, domain: u32, - payments: impl Iterator>, + interchain_gas_paymaster: &H256, + payments: &[StorablePayment<'_>], ) -> Result { let latest_id_before = self.latest_payment_id(domain).await?; + let interchain_gas_paymaster = address_to_bytes(interchain_gas_paymaster); // we have a race condition where a message may not have been scraped yet even let models = payments + .iter() .map(|storable| gas_payment::ActiveModel { id: NotSet, time_created: Set(date_time::now()), @@ -39,10 +99,14 @@ impl ScraperDb { gas_amount: Set(u256_to_decimal(storable.payment.gas_amount)), tx_id: Unchanged(storable.txn_id), log_index: Unchanged(storable.meta.log_index.as_u64() as i64), + origin: Set(domain as i32), + destination: Set(storable.payment.destination as i32), + interchain_gas_paymaster: Set(interchain_gas_paymaster.clone()), + sequence: Set(storable.sequence), }) .collect_vec(); - trace!(?models, "Writing gas payments to database"); + debug!(?models, "Writing gas payments to database"); if models.is_empty() { debug!("Wrote zero new gas payments to database"); @@ -61,6 +125,10 @@ impl ScraperDb { gas_payment::Column::TimeCreated, gas_payment::Column::Payment, gas_payment::Column::GasAmount, + gas_payment::Column::Origin, + gas_payment::Column::Destination, + gas_payment::Column::InterchainGasPaymaster, + gas_payment::Column::Sequence, ]) .to_owned(), ) diff --git a/rust/main/agents/scraper/src/store/deliveries.rs b/rust/main/agents/scraper/src/store/deliveries.rs index dc805baaa2..5238cfa960 100644 --- a/rust/main/agents/scraper/src/store/deliveries.rs +++ b/rust/main/agents/scraper/src/store/deliveries.rs @@ -3,7 +3,10 @@ use std::collections::HashMap; use async_trait::async_trait; use eyre::Result; -use hyperlane_core::{Delivery, HyperlaneLogStore, Indexed, LogMeta, H512}; +use hyperlane_core::{ + unwrap_or_none_result, Delivery, HyperlaneLogStore, HyperlaneSequenceAwareIndexerStoreReader, + Indexed, LogMeta, H512, +}; use crate::db::StorableDelivery; use crate::store::storage::{HyperlaneDbStore, TxnWithId}; @@ -25,11 +28,18 @@ impl HyperlaneLogStore for HyperlaneDbStore { let storable = deliveries .iter() .filter_map(|(message_id, meta)| { - txns.get(&meta.transaction_id) - .map(|txn| (*message_id.inner(), meta, txn.id)) + txns.get(&meta.transaction_id).map(|txn| { + ( + *message_id.inner(), + message_id.sequence.map(|v| v as i64), + meta, + txn.id, + ) + }) }) - .map(|(message_id, meta, txn_id)| StorableDelivery { + .map(|(message_id, sequence, meta, txn_id)| StorableDelivery { message_id, + sequence, meta, txn_id, }); @@ -41,3 +51,26 @@ impl HyperlaneLogStore for HyperlaneDbStore { Ok(stored as u32) } } + +#[async_trait] +impl HyperlaneSequenceAwareIndexerStoreReader for HyperlaneDbStore { + /// Gets a delivered message by its sequence. + async fn retrieve_by_sequence(&self, sequence: u32) -> Result> { + let delivery = self + .db + .retrieve_delivery_by_sequence(self.domain.id(), &self.mailbox_address, sequence) + .await?; + Ok(delivery) + } + + /// Gets the block number at which the log occurred. + async fn retrieve_log_block_number_by_sequence(&self, sequence: u32) -> Result> { + let tx_id = unwrap_or_none_result!( + self.db + .retrieve_delivered_message_tx_id(self.domain.id(), &self.mailbox_address, sequence) + .await? + ); + let block_id = unwrap_or_none_result!(self.db.retrieve_block_id(tx_id).await?); + Ok(self.db.retrieve_block_number(block_id).await?) + } +} diff --git a/rust/main/agents/scraper/src/store/dispatches.rs b/rust/main/agents/scraper/src/store/dispatches.rs index 31aecedd97..b9c98f0473 100644 --- a/rust/main/agents/scraper/src/store/dispatches.rs +++ b/rust/main/agents/scraper/src/store/dispatches.rs @@ -46,7 +46,7 @@ impl HyperlaneSequenceAwareIndexerStoreReader for HyperlaneDbS async fn retrieve_by_sequence(&self, sequence: u32) -> Result> { let message = self .db - .retrieve_message_by_nonce(self.domain.id(), &self.mailbox_address, sequence) + .retrieve_dispatched_message_by_nonce(self.domain.id(), &self.mailbox_address, sequence) .await?; Ok(message) } diff --git a/rust/main/agents/scraper/src/store/payments.rs b/rust/main/agents/scraper/src/store/payments.rs index 4c5ee465f0..9fe4888c8b 100644 --- a/rust/main/agents/scraper/src/store/payments.rs +++ b/rust/main/agents/scraper/src/store/payments.rs @@ -2,8 +2,13 @@ use std::collections::HashMap; use async_trait::async_trait; use eyre::Result; +use itertools::Itertools; +use tracing::debug; -use hyperlane_core::{HyperlaneLogStore, Indexed, InterchainGasPayment, LogMeta, H512}; +use hyperlane_core::{ + unwrap_or_none_result, HyperlaneLogStore, HyperlaneSequenceAwareIndexerStoreReader, Indexed, + InterchainGasPayment, LogMeta, H512, +}; use crate::db::StorablePayment; use crate::store::storage::HyperlaneDbStore; @@ -28,16 +33,69 @@ impl HyperlaneLogStore for HyperlaneDbStore { let storable = payments .iter() .filter_map(|(payment, meta)| { - txns.get(&meta.transaction_id) - .map(|txn| (payment.inner(), meta, txn.id)) + txns.get(&meta.transaction_id).map(|txn| { + ( + payment.inner(), + payment.sequence.map(|v| v as i64), + meta, + txn.id, + ) + }) }) - .map(|(payment, meta, txn_id)| StorablePayment { + .map(|(payment, sequence, meta, txn_id)| StorablePayment { payment, + sequence, meta, txn_id, - }); + }) + .collect_vec(); + + debug!( + domain = self.domain.id(), + interchain_gas_paymaster_address = ?self.interchain_gas_paymaster_address, + ?storable, + "storable payments", + ); - let stored = self.db.store_payments(self.domain.id(), storable).await?; + let stored = self + .db + .store_payments( + self.domain.id(), + &self.interchain_gas_paymaster_address, + &storable, + ) + .await?; Ok(stored as u32) } } + +#[async_trait] +impl HyperlaneSequenceAwareIndexerStoreReader for HyperlaneDbStore { + /// Gets a gas payment by sequence + async fn retrieve_by_sequence(&self, sequence: u32) -> Result> { + let message = self + .db + .retrieve_payment_by_sequence( + self.domain.id(), + &self.interchain_gas_paymaster_address, + sequence, + ) + .await?; + Ok(message) + } + + /// Gets the block number at which the log occurred. + async fn retrieve_log_block_number_by_sequence(&self, sequence: u32) -> Result> { + let tx_id = unwrap_or_none_result!( + self.db + .retrieve_payment_tx_id( + self.domain.id(), + &self.interchain_gas_paymaster_address, + sequence, + ) + .await? + ); + let block_id = unwrap_or_none_result!(self.db.retrieve_block_id(tx_id).await?); + Ok(self.db.retrieve_block_number(block_id).await?) + } +} diff --git a/rust/main/agents/scraper/src/store/storage.rs b/rust/main/agents/scraper/src/store/storage.rs index 5dcde4ed3b..e73d07bd54 100644 --- a/rust/main/agents/scraper/src/store/storage.rs +++ b/rust/main/agents/scraper/src/store/storage.rs @@ -28,9 +28,10 @@ const CHUNK_SIZE: usize = 50; /// connections needed to scrape the contracts on a single blockchain. #[derive(Clone, Debug)] pub struct HyperlaneDbStore { - pub(crate) mailbox_address: H256, - pub(crate) domain: HyperlaneDomain, pub(crate) db: ScraperDb, + pub(crate) domain: HyperlaneDomain, + pub(crate) mailbox_address: H256, + pub(crate) interchain_gas_paymaster_address: H256, provider: Arc, cursor: Arc, } @@ -39,8 +40,9 @@ pub struct HyperlaneDbStore { impl HyperlaneDbStore { pub async fn new( db: ScraperDb, - mailbox_address: H256, domain: HyperlaneDomain, + mailbox_address: H256, + interchain_gas_paymaster_address: H256, provider: Arc, index_settings: &IndexSettings, ) -> Result { @@ -51,8 +53,9 @@ impl HyperlaneDbStore { Ok(Self { db, domain, - provider, mailbox_address, + interchain_gas_paymaster_address, + provider, cursor, }) } diff --git a/rust/main/agents/validator/src/validator.rs b/rust/main/agents/validator/src/validator.rs index 2d09bd93ff..f7a8b43f59 100644 --- a/rust/main/agents/validator/src/validator.rs +++ b/rust/main/agents/validator/src/validator.rs @@ -109,6 +109,7 @@ impl BaseAgent for Validator { &metrics, &contract_sync_metrics, msg_db.clone().into(), + false, ) .await?; diff --git a/rust/main/chains/hyperlane-ethereum/src/contracts/mailbox.rs b/rust/main/chains/hyperlane-ethereum/src/contracts/mailbox.rs index cec2b9b45f..1e9bfaa041 100644 --- a/rust/main/chains/hyperlane-ethereum/src/contracts/mailbox.rs +++ b/rust/main/chains/hyperlane-ethereum/src/contracts/mailbox.rs @@ -2,7 +2,7 @@ #![allow(missing_docs)] use std::collections::HashMap; -use std::ops::RangeInclusive; +use std::ops::{Mul, RangeInclusive}; use std::sync::Arc; use async_trait::async_trait; @@ -11,6 +11,7 @@ use ethers::abi::{AbiEncode, Detokenize}; use ethers::prelude::Middleware; use ethers_contract::builders::ContractCall; use ethers_contract::{Multicall, MulticallResult}; +use ethers_core::utils::WEI_IN_ETHER; use futures_util::future::join_all; use hyperlane_core::rpc_clients::call_and_retry_indefinitely; use hyperlane_core::{BatchResult, QueueOperation, ReorgPeriod, H512}; @@ -560,8 +561,8 @@ where arbitrum_node_interface .estimate_retryable_ticket( H160::zero().into(), - // Give the sender a deposit, otherwise it reverts - U256::MAX.into(), + // Give the sender a deposit (100 ETH), otherwise it reverts + WEI_IN_ETHER.mul(100u32), self.contract.address(), U256::zero().into(), H160::zero().into(), diff --git a/rust/main/chains/hyperlane-ethereum/src/rpc_clients/trait_builder.rs b/rust/main/chains/hyperlane-ethereum/src/rpc_clients/trait_builder.rs index 67bad08930..45ad0638d6 100644 --- a/rust/main/chains/hyperlane-ethereum/src/rpc_clients/trait_builder.rs +++ b/rust/main/chains/hyperlane-ethereum/src/rpc_clients/trait_builder.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use std::time::Duration; use async_trait::async_trait; +use ethers::middleware::gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice}; use ethers::middleware::gas_oracle::{ GasCategory, GasOracle, GasOracleMiddleware, Polygon, ProviderOracle, }; @@ -10,6 +11,8 @@ use ethers::prelude::{ Http, JsonRpcClient, Middleware, NonceManagerMiddleware, Provider, Quorum, QuorumProvider, SignerMiddleware, WeightedProvider, Ws, WsClientError, }; +use ethers::types::Address; +use ethers_signers::Signer; use hyperlane_core::rpc_clients::FallbackProvider; use reqwest::{Client, Url}; use thiserror::Error; @@ -22,6 +25,7 @@ use ethers_prometheus::middleware::{MiddlewareMetrics, PrometheusMiddlewareConf} use hyperlane_core::{ ChainCommunicationError, ChainResult, ContractLocator, HyperlaneDomain, KnownHyperlaneDomain, }; +use tracing::instrument; use crate::signer::Signers; use crate::{ConnectionConf, EthereumFallbackProvider, RetryingProvider, RpcConnectionConf}; @@ -195,13 +199,13 @@ pub trait BuildableWithProvider { where P: JsonRpcClient + 'static, { - let provider = wrap_with_gas_oracle(Provider::new(client), locator.domain)?; - self.build_with_signer(provider, conn, locator, signer) + self.build_with_signer(Provider::new(client), conn, locator, signer) .await } /// Wrap the provider creation with a signing provider if signers were /// provided, and then create the associated trait. + #[instrument(skip(self, provider, conn, locator, signer), fields(domain=locator.domain.name()), level = "debug")] async fn build_with_signer( &self, provider: M, @@ -213,10 +217,20 @@ pub trait BuildableWithProvider { M: Middleware + 'static, { Ok(if let Some(signer) = signer { - let signing_provider = wrap_with_signer(provider, signer) + // The signing provider is used for sending txs, which may end up stuck in the mempool due to + // gas pricing issues. We first wrap the provider in a signer middleware, to sign any new txs sent by the gas escalator middleware. + // We keep nonce manager as the outermost middleware, so that every new tx with a higher gas price reuses the same nonce. + let signing_provider = wrap_with_signer(provider, signer.clone()) .await .map_err(ChainCommunicationError::from_other)?; - self.build_with_provider(signing_provider, conn, locator) + let gas_escalator_provider = wrap_with_gas_escalator(signing_provider); + let gas_oracle_provider = wrap_with_gas_oracle(gas_escalator_provider, locator.domain)?; + let nonce_manager_provider = + wrap_with_nonce_manager(gas_oracle_provider, signer.address()) + .await + .map_err(ChainCommunicationError::from_other)?; + + self.build_with_provider(nonce_manager_provider, conn, locator) } else { self.build_with_provider(provider, conn, locator) } @@ -237,15 +251,19 @@ pub trait BuildableWithProvider { async fn wrap_with_signer( provider: M, signer: Signers, -) -> Result, Signers>, M::Error> { +) -> Result, M::Error> { let provider_chain_id = provider.get_chainid().await?; let signer = ethers::signers::Signer::with_chain_id(signer, provider_chain_id.as_u64()); - let address = ethers::prelude::Signer::address(&signer); - let provider = NonceManagerMiddleware::new(provider, address); + Ok(SignerMiddleware::new(provider, signer)) +} - let signing_provider = SignerMiddleware::new(provider, signer); - Ok(signing_provider) +async fn wrap_with_nonce_manager( + provider: M, + signer_address: Address, +) -> Result, M::Error> { + let nonce_manager_provider = NonceManagerMiddleware::new(provider, signer_address); + Ok(nonce_manager_provider) } fn build_polygon_gas_oracle(chain: ethers_core::types::Chain) -> ChainResult> { @@ -277,3 +295,20 @@ where }; Ok(GasOracleMiddleware::new(provider, gas_oracle)) } + +fn wrap_with_gas_escalator(provider: M) -> GasEscalatorMiddleware +where + M: Middleware + 'static, +{ + // Increase the gas price by 12.5% every 90 seconds + // (These are the default values from ethers doc comments) + const COEFFICIENT: f64 = 1.125; + const EVERY_SECS: u64 = 90u64; + // 550 gwei is the limit we also use for polygon, so we reuse for consistency + const MAX_GAS_PRICE: u128 = 550 * 10u128.pow(9); + let escalator = GeometricGasPrice::new(COEFFICIENT, EVERY_SECS, MAX_GAS_PRICE.into()); + // Check the status of sent txs every eth block or so. The alternative is to subscribe to new blocks and check then, + // which adds unnecessary load on the provider. + const FREQUENCY: Frequency = Frequency::Duration(Duration::from_secs(12).as_millis() as _); + GasEscalatorMiddleware::new(provider, escalator, FREQUENCY) +} diff --git a/rust/main/chains/hyperlane-ethereum/src/tx.rs b/rust/main/chains/hyperlane-ethereum/src/tx.rs index 31975643b3..e989be11d6 100644 --- a/rust/main/chains/hyperlane-ethereum/src/tx.rs +++ b/rust/main/chains/hyperlane-ethereum/src/tx.rs @@ -31,7 +31,7 @@ pub const GAS_ESTIMATE_MULTIPLIER_NUMERATOR: u32 = 11; pub const GAS_ESTIMATE_MULTIPLIER_DENOMINATOR: u32 = 10; pub fn apply_gas_estimate_buffer(gas: U256, domain: &HyperlaneDomain) -> ChainResult { - // Arbitrum Nitro chains use 2d fees are are especially prone to costs increasing + // Arbitrum Nitro chains use 2d fees are especially prone to costs increasing // by the time the transaction lands on chain, requiring a higher gas limit. // In this case, we apply a multiplier to the gas estimate. let gas = if domain.is_arbitrum_nitro() { @@ -68,8 +68,7 @@ where .cloned() .unwrap_or_else(|| NameOrAddress::Address(Default::default())); - info!(?to, %data, "Dispatching transaction"); - // We can set the gas higher here! + info!(?to, %data, tx=?tx.tx, "Dispatching transaction"); let dispatch_fut = tx.send(); let dispatched = dispatch_fut .await? diff --git a/rust/main/chains/hyperlane-sealevel/src/interchain_gas.rs b/rust/main/chains/hyperlane-sealevel/src/interchain_gas.rs index e415e9bc76..4d5e819de3 100644 --- a/rust/main/chains/hyperlane-sealevel/src/interchain_gas.rs +++ b/rust/main/chains/hyperlane-sealevel/src/interchain_gas.rs @@ -91,7 +91,8 @@ impl InterchainGasPaymaster for SealevelInterchainGasPaymaster {} pub struct SealevelInterchainGasPaymasterIndexer { rpc_client: SealevelRpcClient, igp: SealevelInterchainGasPaymaster, - _log_meta_composer: LogMetaComposer, + log_meta_composer: LogMetaComposer, + advanced_log_meta: bool, } /// IGP payment data on Sealevel @@ -107,6 +108,7 @@ impl SealevelInterchainGasPaymasterIndexer { pub async fn new( conf: &ConnectionConf, igp_account_locator: ContractLocator<'_>, + advanced_log_meta: bool, ) -> ChainResult { // Set the `processed` commitment at rpc level let rpc_client = SealevelRpcClient::new(conf.url.to_string()); @@ -122,7 +124,8 @@ impl SealevelInterchainGasPaymasterIndexer { Ok(Self { rpc_client, igp, - _log_meta_composer: log_meta_composer, + log_meta_composer, + advanced_log_meta, }) } @@ -168,23 +171,24 @@ impl SealevelInterchainGasPaymasterIndexer { gas_amount: gas_payment_account.gas_amount.into(), }; - // let log_meta = self - // .interchain_payment_log_meta( - // U256::from(sequence_number), - // &valid_payment_pda_pubkey, - // &gas_payment_account.slot, - // ) - // .await?; - - let log_meta = LogMeta { - address: self.igp.program_id.to_bytes().into(), - block_number: gas_payment_account.slot, - // TODO: get these when building out scraper support. - // It's inconvenient to get these :| - block_hash: H256::zero(), - transaction_id: H512::zero(), - transaction_index: 0, - log_index: sequence_number.into(), + let log_meta = if self.advanced_log_meta { + self.interchain_payment_log_meta( + U256::from(sequence_number), + &valid_payment_pda_pubkey, + &gas_payment_account.slot, + ) + .await? + } else { + LogMeta { + address: self.igp.program_id.to_bytes().into(), + block_number: gas_payment_account.slot, + // TODO: get these when building out scraper support. + // It's inconvenient to get these :| + block_hash: H256::zero(), + transaction_id: H512::zero(), + transaction_index: 0, + log_index: sequence_number.into(), + } }; Ok(SealevelGasPayment::new( @@ -212,7 +216,7 @@ impl SealevelInterchainGasPaymasterIndexer { Ok(expected_pubkey) } - async fn _interchain_payment_log_meta( + async fn interchain_payment_log_meta( &self, log_index: U256, payment_pda_pubkey: &Pubkey, @@ -220,7 +224,7 @@ impl SealevelInterchainGasPaymasterIndexer { ) -> ChainResult { let block = self.rpc_client.get_block(*payment_pda_slot).await?; - self._log_meta_composer + self.log_meta_composer .log_meta(block, log_index, payment_pda_pubkey, payment_pda_slot) .map_err(Into::::into) } diff --git a/rust/main/chains/hyperlane-sealevel/src/mailbox.rs b/rust/main/chains/hyperlane-sealevel/src/mailbox.rs index d376801fe0..d64963e242 100644 --- a/rust/main/chains/hyperlane-sealevel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-sealevel/src/mailbox.rs @@ -9,7 +9,7 @@ use hyperlane_sealevel_interchain_security_module_interface::{ }; use hyperlane_sealevel_mailbox::{ accounts::{ - DispatchedMessageAccount, InboxAccount, OutboxAccount, ProcessedMessage, + DispatchedMessageAccount, Inbox, InboxAccount, OutboxAccount, ProcessedMessage, ProcessedMessageAccount, DISPATCHED_MESSAGE_DISCRIMINATOR, PROCESSED_MESSAGE_DISCRIMINATOR, }, instruction, @@ -53,12 +53,12 @@ use solana_transaction_status::{ use tracing::{debug, info, instrument, warn}; use hyperlane_core::{ - accumulator::incremental::IncrementalMerkle, BatchItem, ChainCommunicationError, - ChainCommunicationError::ContractError, ChainResult, Checkpoint, ContractLocator, Decode as _, - Encode as _, FixedPointNumber, HyperlaneAbi, HyperlaneChain, HyperlaneContract, - HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Indexed, Indexer, KnownHyperlaneDomain, - LogMeta, Mailbox, MerkleTreeHook, ReorgPeriod, SequenceAwareIndexer, TxCostEstimate, TxOutcome, - H256, H512, U256, + accumulator::incremental::IncrementalMerkle, config::StrOrIntParseError, BatchItem, + ChainCommunicationError, ChainCommunicationError::ContractError, ChainResult, Checkpoint, + ContractLocator, Decode as _, Encode as _, FixedPointNumber, HyperlaneAbi, HyperlaneChain, + HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Indexed, Indexer, + KnownHyperlaneDomain, LogMeta, Mailbox, MerkleTreeHook, ReorgPeriod, SequenceAwareIndexer, + TxCostEstimate, TxOutcome, H256, H512, U256, }; use crate::account::{search_accounts_by_discriminator, search_and_validate_account}; @@ -400,6 +400,17 @@ impl SealevelMailbox { ), )) } + + async fn get_inbox(&self) -> ChainResult> { + let account = self + .rpc() + .get_account_with_finalized_commitment(&self.inbox.0) + .await?; + let inbox = InboxAccount::fetch(&mut account.data.as_ref()) + .map_err(ChainCommunicationError::from_other)? + .into_inner(); + Ok(inbox) + } } impl HyperlaneContract for SealevelMailbox { @@ -451,11 +462,7 @@ impl Mailbox for SealevelMailbox { #[instrument(err, ret, skip(self))] async fn default_ism(&self) -> ChainResult { - let inbox_account = self.rpc().get_account(&self.inbox.0).await?; - let inbox = InboxAccount::fetch(&mut inbox_account.data.as_ref()) - .map_err(ChainCommunicationError::from_other)? - .into_inner(); - + let inbox = self.get_inbox().await?; Ok(inbox.default_ism.to_bytes().into()) } @@ -501,6 +508,11 @@ impl Mailbox for SealevelMailbox { // If we're using Jito, we need to send a tip to the Jito fee account. // Otherwise, we need to set the compute unit price. if self.use_jito() { + let tip: u64 = std::env::var("JITO_TIP_LAMPORTS") + .ok() + .and_then(|s| s.parse::().ok()) + .unwrap_or(PROCESS_DESIRED_PRIORITIZATION_FEE_LAMPORTS_PER_TX); + // The tip is a standalone transfer to a Jito fee account. // See https://github.com/jito-labs/mev-protos/blob/master/json_rpc/http.md#sendbundle. instructions.push(solana_sdk::system_instruction::transfer( @@ -508,7 +520,7 @@ impl Mailbox for SealevelMailbox { // A random Jito fee account, taken from the getFeeAccount RPC response: // https://github.com/jito-labs/mev-protos/blob/master/json_rpc/http.md#gettipaccounts &solana_sdk::pubkey!("DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh"), - PROCESS_DESIRED_PRIORITIZATION_FEE_LAMPORTS_PER_TX, + tip, )); } // "processed" level commitment does not guarantee finality. @@ -648,10 +660,15 @@ pub struct SealevelMailboxIndexer { program_id: Pubkey, dispatch_message_log_meta_composer: LogMetaComposer, delivery_message_log_meta_composer: LogMetaComposer, + advanced_log_meta: bool, } impl SealevelMailboxIndexer { - pub fn new(conf: &ConnectionConf, locator: ContractLocator) -> ChainResult { + pub fn new( + conf: &ConnectionConf, + locator: ContractLocator, + advanced_log_meta: bool, + ) -> ChainResult { let program_id = Pubkey::from(<[u8; 32]>::from(locator.address)); let mailbox = SealevelMailbox::new(conf, locator, None)?; @@ -672,6 +689,7 @@ impl SealevelMailboxIndexer { mailbox, dispatch_message_log_meta_composer, delivery_message_log_meta_composer, + advanced_log_meta, }) } @@ -712,23 +730,24 @@ impl SealevelMailboxIndexer { let hyperlane_message = HyperlaneMessage::read_from(&mut &dispatched_message_account.encoded_message[..])?; - // let log_meta = self - // .dispatch_message_log_meta( - // U256::from(nonce), - // &valid_message_storage_pda_pubkey, - // &dispatched_message_account.slot, - // ) - // .await?; - - let log_meta = LogMeta { - address: self.program_id.to_bytes().into(), - block_number: dispatched_message_account.slot, - // TODO: get these when building out scraper support. - // It's inconvenient to get these :| - block_hash: H256::zero(), - transaction_id: H512::zero(), - transaction_index: 0, - log_index: U256::zero(), + let log_meta = if self.advanced_log_meta { + self.dispatch_message_log_meta( + U256::from(nonce), + &valid_message_storage_pda_pubkey, + &dispatched_message_account.slot, + ) + .await? + } else { + LogMeta { + address: self.program_id.to_bytes().into(), + block_number: dispatched_message_account.slot, + // TODO: get these when building out scraper support. + // It's inconvenient to get these :| + block_hash: H256::zero(), + transaction_id: H512::zero(), + transaction_index: 0, + log_index: U256::zero(), + } }; Ok((hyperlane_message.into(), log_meta)) @@ -748,7 +767,7 @@ impl SealevelMailboxIndexer { Ok(expected_pubkey) } - async fn _dispatch_message_log_meta( + async fn dispatch_message_log_meta( &self, log_index: U256, message_storage_pda_pubkey: &Pubkey, @@ -771,18 +790,18 @@ impl SealevelMailboxIndexer { .map_err(Into::::into) } - async fn get_delivered_message_with_nonce( + async fn get_delivered_message_with_sequence( &self, - nonce: u32, + sequence: u32, ) -> ChainResult<(Indexed, LogMeta)> { - let nonce_bytes = nonce.to_le_bytes(); + let sequence_bytes = sequence.to_le_bytes(); let delivered_message_id_offset = 1 + 8 + 8; // the offset to get the `message_id` field let delivered_message_id_length = 32; let accounts = search_accounts_by_discriminator( self.rpc(), &self.program_id, &PROCESSED_MESSAGE_DISCRIMINATOR, - &nonce_bytes, + &sequence_bytes, delivered_message_id_offset, delivered_message_id_length, ) @@ -805,26 +824,30 @@ impl SealevelMailboxIndexer { .into_inner(); let message_id = delivered_message_account.message_id; - // let log_meta = self - // .delivered_message_log_meta( - // U256::from(nonce), - // &valid_message_storage_pda_pubkey, - // &delivered_message_account.slot, - // ) - // .await?; - - let log_meta = LogMeta { - address: self.program_id.to_bytes().into(), - block_number: delivered_message_account.slot, - // TODO: get these when building out scraper support. - // It's inconvenient to get these :| - block_hash: H256::zero(), - transaction_id: H512::zero(), - transaction_index: 0, - log_index: U256::zero(), + let log_meta = if self.advanced_log_meta { + self.delivered_message_log_meta( + U256::from(sequence), + &valid_message_storage_pda_pubkey, + &delivered_message_account.slot, + ) + .await? + } else { + LogMeta { + address: self.program_id.to_bytes().into(), + block_number: delivered_message_account.slot, + // TODO: get these when building out scraper support. + // It's inconvenient to get these :| + block_hash: H256::zero(), + transaction_id: H512::zero(), + transaction_index: 0, + log_index: U256::zero(), + } }; - Ok((message_id.into(), log_meta)) + let mut indexed = Indexed::from(message_id); + indexed.sequence = Some(sequence); + + Ok((indexed, log_meta)) } fn delivered_message_account(&self, account: &Account) -> ChainResult { @@ -839,7 +862,7 @@ impl SealevelMailboxIndexer { Ok(expected_pubkey) } - async fn _delivered_message_log_meta( + async fn delivered_message_log_meta( &self, log_index: U256, message_storage_pda_pubkey: &Pubkey, @@ -915,7 +938,7 @@ impl Indexer for SealevelMailboxIndexer { let message_capacity = range.end().saturating_sub(*range.start()); let mut message_ids = Vec::with_capacity(message_capacity as usize); for nonce in range { - message_ids.push(self.get_delivered_message_with_nonce(nonce).await?); + message_ids.push(self.get_delivered_message_with_sequence(nonce).await?); } Ok(message_ids) } @@ -931,10 +954,15 @@ impl Indexer for SealevelMailboxIndexer { #[async_trait] impl SequenceAwareIndexer for SealevelMailboxIndexer { async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { - // TODO: implement when sealevel scraper support is implemented - info!("Message delivery indexing not implemented"); + let inbox = self.mailbox.get_inbox().await?; + let sequence = inbox + .processed_count + .try_into() + .map_err(StrOrIntParseError::from)?; + let tip = self.mailbox.provider.rpc().get_slot().await?; - Ok((Some(1), tip)) + + Ok((Some(sequence), tip)) } } diff --git a/rust/main/chains/hyperlane-sealevel/src/rpc/client.rs b/rust/main/chains/hyperlane-sealevel/src/rpc/client.rs index 6186bf31ee..59adb671f3 100644 --- a/rust/main/chains/hyperlane-sealevel/src/rpc/client.rs +++ b/rust/main/chains/hyperlane-sealevel/src/rpc/client.rs @@ -47,13 +47,6 @@ impl SealevelRpcClient { .map_err(Into::into) } - pub async fn get_account(&self, pubkey: &Pubkey) -> ChainResult { - self.0 - .get_account(pubkey) - .await - .map_err(ChainCommunicationError::from_other) - } - /// Simulates an Instruction that will return a list of AccountMetas. pub async fn get_account_metas( &self, @@ -112,14 +105,14 @@ impl SealevelRpcClient { Ok(balance.into()) } - pub async fn get_block(&self, height: u64) -> ChainResult { + pub async fn get_block(&self, slot: u64) -> ChainResult { let config = RpcBlockConfig { commitment: Some(CommitmentConfig::finalized()), max_supported_transaction_version: Some(0), ..Default::default() }; self.0 - .get_block_with_config(height, config) + .get_block_with_config(slot, config) .await .map_err(HyperlaneSealevelError::ClientError) .map_err(Into::into) @@ -273,3 +266,6 @@ impl std::fmt::Debug for SealevelRpcClient { f.write_str("RpcClient { ... }") } } + +#[cfg(test)] +mod tests; diff --git a/rust/main/chains/hyperlane-sealevel/src/rpc/client/tests.rs b/rust/main/chains/hyperlane-sealevel/src/rpc/client/tests.rs new file mode 100644 index 0000000000..81859559c2 --- /dev/null +++ b/rust/main/chains/hyperlane-sealevel/src/rpc/client/tests.rs @@ -0,0 +1,14 @@ +use crate::SealevelRpcClient; + +//#[tokio::test] +async fn _test_get_block() { + // given + let client = SealevelRpcClient::new("".to_string()); + + // when + let slot = 301337842; // block which requires latest version of solana-client + let result = client.get_block(slot).await; + + // then + assert!(result.is_ok()); +} diff --git a/rust/main/config/mainnet_config.json b/rust/main/config/mainnet_config.json index 6e0da5be3e..dc66d22345 100644 --- a/rust/main/config/mainnet_config.json +++ b/rust/main/config/mainnet_config.json @@ -34,7 +34,7 @@ "interchainAccountIsm": "0xd766e7C7517f2d0D92754b2fe4aE7AdEf7bDEC3e", "interchainAccountRouter": "0x25C87e735021F72d8728438C2130b02E3141f2cb", "interchainGasPaymaster": "0x8F1E22d309baa69D398a03cc88E9b46037e988AA", - "interchainSecurityModule": "0xECd85a9d1215eab1a53364dA71A57634b1a0e1C8", + "interchainSecurityModule": "0x7115c77E844E301693d78F1B19e796083eB0b680", "isTestnet": false, "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x811808Dd29ba8B0FC6C0ec0b5537035E59745162", @@ -100,7 +100,7 @@ "interchainAccountIsm": "0x2A7574358Ec53522CE2452887661AB4c86F7d400", "interchainAccountRouter": "0x91874Dbed74925dFe6059B90385EEb90DdE0B2E6", "interchainGasPaymaster": "0x3b6044acd6767f017e99318AA6Ef93b7B06A5a22", - "interchainSecurityModule": "0x25ebF66b71a3De55D25CcFea5C0d4f974931CeeA", + "interchainSecurityModule": "0xB51De3e8BCE366a871d5ba631ACa843D18d9Bc60", "mailbox": "0x979Ca5202784112f4738403dBec5D0F3B9daabB9", "merkleTreeHook": "0x748040afB89B8FdBb992799808215419d36A0930", "name": "arbitrum", @@ -172,7 +172,7 @@ "interchainAccountIsm": "0x27a3233c05C1Df7c163123301D14bE9349E3Cb48", "interchainAccountRouter": "0xa82a0227e6d6db53AF4B264A852bfF91C6504a51", "interchainGasPaymaster": "0x95519ba800BBd0d34eeAE026fEc620AD978176C0", - "interchainSecurityModule": "0x57576C0A653d3E9697E16f331ef8aBd8f9c9f64e", + "interchainSecurityModule": "0xEc016e4DB2ca7EdB65F40AEF59DdFe12a28344ed", "mailbox": "0xFf06aFcaABaDDd1fb08371f9ccA15D73D51FeBD6", "merkleTreeHook": "0x84eea61D679F42D92145fA052C89900CBAccE95A", "name": "avalanche", @@ -223,7 +223,7 @@ } ], "blocks": { - "confirmations": 1, + "confirmations": 3, "estimateBlockTime": 2, "reorgPeriod": 10 }, @@ -316,7 +316,7 @@ "interchainAccountIsm": "0xe93f2f409ad8B5000431D234472973fe848dcBEC", "interchainAccountRouter": "0x2f4Eb04189e11Af642237Da62d163Ab714614498", "interchainGasPaymaster": "0xB3fCcD379ad66CED0c91028520C64226611A48c9", - "interchainSecurityModule": "0x91c650094f876498B544cFbF47bDf4AD5762571f", + "interchainSecurityModule": "0xdc01bf0D464460bD383B5C81d5962451204ec28b", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0xC9B8ea6230d6687a4b13fD3C0b8f0Ec607B26465", "name": "blast", @@ -384,7 +384,7 @@ "interchainAccountIsm": "0x451dF8AB0936D85526D816f0b4dCaDD934A034A4", "interchainAccountRouter": "0x5C02157068a52cEcfc98EDb6115DE6134EcB4764", "interchainGasPaymaster": "0x62B7592C1B6D1E43f4630B8e37f4377097840C05", - "interchainSecurityModule": "0xCE12fcDAA985D84CBb9e17EA81AFa23e5756ECf9", + "interchainSecurityModule": "0x6a32F3789Ba8880742d1fB6Cb51aed5EcfdE702C", "mailbox": "0x8358D8291e3bEDb04804975eEa0fe9fe0fAfB147", "merkleTreeHook": "0x781bE492F1232E66990d83a9D3AC3Ec26f56DAfB", "name": "bob", @@ -450,7 +450,7 @@ "interchainAccountIsm": "0x9e22945bE593946618383B108CC5bce09eBA4C26", "interchainAccountRouter": "0x32A07c1B7a7fe8D4A0e44B0181873aB9d64C16c1", "interchainGasPaymaster": "0x78E25e7f84416e69b9339B0A6336EB6EFfF6b451", - "interchainSecurityModule": "0x08b98B5a7ef4AF12c87Efb6848AC56F13072Acc1", + "interchainSecurityModule": "0x0c461142ac54Fa4d24Fe5Ff6643A8386d2C03b29", "mailbox": "0x2971b9Aec44bE4eb673DF1B88cDB57b96eefe8a4", "merkleTreeHook": "0xFDb9Cd5f9daAA2E4474019405A328a88E7484f26", "name": "bsc", @@ -531,7 +531,7 @@ "interchainAccountIsm": "0xB732c83aeE29596E3163Da2260710eAB67Bc0B29", "interchainAccountRouter": "0x27a6cAe33378bB6A6663b382070427A01fc9cB37", "interchainGasPaymaster": "0x571f1435613381208477ac5d6974310d88AC7cB7", - "interchainSecurityModule": "0x75EEa329FAD5680f386d586Ac453b62e858C1CA8", + "interchainSecurityModule": "0x324fedE5dba4729760514913bfD29f626F487e35", "mailbox": "0x50da3B3907A08a24fe4999F4Dcf337E8dC7954bb", "merkleTreeHook": "0x04dB778f05854f26E67e0a66b740BBbE9070D366", "name": "celo", @@ -596,7 +596,7 @@ "interchainAccountIsm": "0x4Eb82Ee35b0a1c1d776E3a3B547f9A9bA6FCC9f2", "interchainAccountRouter": "0xEF9A332Ec1fD233Bf9344A58be56ff9E104B4f60", "interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503", - "interchainSecurityModule": "0x15f859523466132580AB74Fd27c920CE5372a1b0", + "interchainSecurityModule": "0x53D92225b49932471E6CA7bf1089203e49f5E51E", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD", "name": "cheesechain", @@ -659,7 +659,7 @@ "from": 4842212 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xf563C8347b0b03542d1027e0450166A9E56Ce4b0", + "interchainSecurityModule": "0x3203B23145Cc21f6ba1c9AA49401fa66fBDB113E", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "cyber", @@ -726,7 +726,7 @@ "from": 23783929 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xc6282b9525b43E373BdE5B8C018a486502552B73", + "interchainSecurityModule": "0xf0bE03F3176EA2dEA8b614C5695EF0eF795e79eF", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "degenchain", @@ -839,7 +839,7 @@ "interchainAccountIsm": "0xCeafc098e5c3c7768b9229Be2FEC275862A81Abd", "interchainAccountRouter": "0xed9a722c543883FB7e07E78F3879762DE09eA7D5", "interchainGasPaymaster": "0xB30EAB08aa87138D57168D0e236850A530f49921", - "interchainSecurityModule": "0x48Be1A244EbFEe8E66D220004f93e2aa42CC3463", + "interchainSecurityModule": "0xC4F35559a1FBD1ACb7Ba88cEdC157754477FC047", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xC831271c1fB212012811a91Dd43e5926C1020563", "name": "endurance", @@ -910,7 +910,7 @@ "interchainAccountIsm": "0x292C614ED53DaaDBf971521bc2C652d1ca51cB47", "interchainAccountRouter": "0x5E532F7B610618eE73C2B462978e94CB1F7995Ce", "interchainGasPaymaster": "0x9e6B1022bE9BBF5aFd152483DAD9b88911bC8611", - "interchainSecurityModule": "0x0DCb0e2ceDB8828Ab1809d742C3621c7FE169E5B", + "interchainSecurityModule": "0xcFF5f9d69343f4200100dbA755C794012518Ed38", "mailbox": "0xc005dc82818d67AF737725bD4bf75435d065D239", "merkleTreeHook": "0x48e6c30B97748d1e2e03bf3e9FbE3890ca5f8CCA", "name": "ethereum", @@ -979,7 +979,7 @@ "interchainAccountIsm": "0x7C012DCA02C42cfA3Fd7Da3B0ED7234B52AE68eF", "interchainAccountRouter": "0xbed53B5C5BCE9433f25A2A702e6df13E22d84Ae9", "interchainGasPaymaster": "0x2Fca7f6eC3d4A0408900f2BB30004d4616eE985E", - "interchainSecurityModule": "0xF80aaED3e93c02ceEE812cCAe6d15BDB68e62F4D", + "interchainSecurityModule": "0x7D24f9d82BCC10ab4A02F48D2Aae1AD00Ea47dC3", "mailbox": "0x2f9DB5616fa3fAd1aB06cB2C906830BA63d135e3", "merkleTreeHook": "0x8358D8291e3bEDb04804975eEa0fe9fe0fAfB147", "name": "fraxtal", @@ -1047,7 +1047,7 @@ "interchainAccountIsm": "0x9629c28990F11c31735765A6FD59E1E1bC197DbD", "interchainAccountRouter": "0x2351FBe24C1212F253b7a300ff0cBCFd97952a19", "interchainGasPaymaster": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", - "interchainSecurityModule": "0x58f85b68c664017247E6A65290409953a10adbd8", + "interchainSecurityModule": "0xff36B9B99338CAe60fd794741B5e02a3D92254C2", "mailbox": "0x3071D4DA6020C956Fe15Bfd0a9Ca8D4574f16696", "merkleTreeHook": "0xfBc08389224d23b79cb21cDc16c5d42F0ad0F57f", "name": "fusemainnet", @@ -1121,7 +1121,7 @@ "interchainAccountIsm": "0x07E2062A1bC66a2C1d05cb5C3870a4AF86e0056E", "interchainAccountRouter": "0xBE70Ab882D1F7E37e04a70CDd9Ec23b37a234064", "interchainGasPaymaster": "0xDd260B99d302f0A3fF885728c086f729c06f227f", - "interchainSecurityModule": "0x4845d050F06482960435499e88286808c181F913", + "interchainSecurityModule": "0x8fC6e2011050ccC99B7f8460C23Cc85402D78e85", "mailbox": "0xaD09d78f4c6b9dA2Ae82b1D34107802d380Bb74f", "merkleTreeHook": "0x2684C6F89E901987E1FdB7649dC5Be0c57C61645", "name": "gnosis", @@ -1192,7 +1192,7 @@ "interchainAccountIsm": "0x708E002637792FDC031E6B62f23DD60014AC976a", "interchainAccountRouter": "0xfB8cea1c7F45608Da30655b50bbF355D123A4358", "interchainGasPaymaster": "0x19dc38aeae620380430C200a6E990D5Af5480117", - "interchainSecurityModule": "0xf7CaC1C661fe307CD4Eadb08EE5E64bb34623c11", + "interchainSecurityModule": "0xaee1F6685b0495cc2bFa4F5E5c096466fC9873b8", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x0972954923a1e2b2aAb04Fa0c4a0797e5989Cd65", "name": "inevm", @@ -1320,7 +1320,7 @@ "from": 14616307 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xf6AB62267aA88f7219CB9d77e361687e090b224F", + "interchainSecurityModule": "0x66c540f566a52F46931FaBbcED90d7d669da7303", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "kroma", @@ -1393,7 +1393,7 @@ "interchainAccountIsm": "0xdcA646C56E7768DD11654956adE24bfFf9Ba4893", "interchainAccountRouter": "0xD59dA396F162Ed93a41252Cebb8d5DD4F093238C", "interchainGasPaymaster": "0x8105a095368f1a184CceA86cCe21318B5Ee5BE28", - "interchainSecurityModule": "0x914E4A88Be1e835b17B6f2F259861989fCB27978", + "interchainSecurityModule": "0x93c9fEeC4Dd4935a65029A4BF03fB6df1130FBB9", "mailbox": "0x02d16BC51af6BfD153d67CA61754cF912E82C4d9", "merkleTreeHook": "0xC077A0Cc408173349b1c9870C667B40FE3C01dd7", "name": "linea", @@ -1464,7 +1464,7 @@ "from": 4195553 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xEED58BC374386596a848856aDCD07f597B70e2d9", + "interchainSecurityModule": "0xDbe54a99c9550BF6EB7F510b62cfe2d5E74F072e", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "lisk", @@ -1528,7 +1528,7 @@ "from": 3088760 }, "interchainGasPaymaster": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", - "interchainSecurityModule": "0xf660731c69aF0E1C441bEE544595dbBEE652ebb6", + "interchainSecurityModule": "0x5997a574AbfED0506a5319b669b5f328b1C391A3", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x062200d92dF6bB7bA89Ce4D6800110450f94784e", "name": "lukso", @@ -1602,7 +1602,7 @@ "interchainAccountIsm": "0x8Ea50255C282F89d1A14ad3F159437EE5EF0507f", "interchainAccountRouter": "0x693A4cE39d99e46B04cb562329e3F0141cA17331", "interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4", - "interchainSecurityModule": "0x4cD0894d9277e62906c788c2F39Ab04610e577B7", + "interchainSecurityModule": "0xF9fecfeAA2A20744eAb207f7c01CA245C49Bab9e", "isTestnet": false, "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112", @@ -1672,7 +1672,7 @@ "interchainAccountIsm": "0xe039DA3A0071BEd087A12660D7b03cf669c7776E", "interchainAccountRouter": "0x45285463352c53a481e882cD5E2AF2E25BBdAd0D", "interchainGasPaymaster": "0x8105a095368f1a184CceA86cCe21318B5Ee5BE28", - "interchainSecurityModule": "0xA5c6193F340F05feD2064a9e56Bb7b3c6242E21E", + "interchainSecurityModule": "0x244BbF1B35C67De0367E4A02C63bFD4269976A92", "mailbox": "0x398633D19f4371e1DB5a8EFE90468eB70B1176AA", "merkleTreeHook": "0x5332D1AC0A626D265298c14ff681c0A8D28dB86d", "name": "mantle", @@ -1734,7 +1734,7 @@ "from": 13523607 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xF16b870563cbb181A53D5e8152cAAa3bF4c356D6", + "interchainSecurityModule": "0x3C5672Af5874D2ea59B73edF4489Db73bCE743D0", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "merlin", @@ -1801,7 +1801,7 @@ "from": 17966274 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0x015c05e7bCeAB0D16912667cC03282C6276aC7d7", + "interchainSecurityModule": "0xb54D5F3905422BcD7f8d4627ad60c9F3196dEF66", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "metis", @@ -1839,7 +1839,7 @@ "aggregationHook": "0xF6C1769d5390Be0f77080eF7791fBbA7eF4D5659", "blockExplorers": [ { - "apiUrl": "https://explorer.mintchain.io/api/eth-rpc", + "apiUrl": "https://explorer.mintchain.io/api", "family": "blockscout", "name": "Mint Explorer", "url": "https://explorer.mintchain.io" @@ -1866,7 +1866,7 @@ "from": 3752032 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xe5E2224EaF5488Cbc992a35C828Ae0006dFbfE27", + "interchainSecurityModule": "0xda17325c9f34cedc06728707eD95eC79d26386a7", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "mint", @@ -1933,7 +1933,7 @@ "interchainAccountIsm": "0xa377b8269e0A47cdd2fD5AAeAe860b45623c6d82", "interchainAccountRouter": "0x6e1B9f776bd415d7cC3C7458A5f0d801016918f8", "interchainGasPaymaster": "0x931dFCc8c1141D6F532FD023bd87DAe0080c835d", - "interchainSecurityModule": "0xBE3E3bAe7b14098111dC0bBD0dFce251217E386A", + "interchainSecurityModule": "0xB484705Abc1F351b94B63C93Af83B6d108351137", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xE2ee936bEa8e42671c400aC96dE198E06F2bA2A6", "name": "mode", @@ -2001,7 +2001,7 @@ "interchainAccountIsm": "0x79b3730CE3685f65802aF1771319992bA960EB9D", "interchainAccountRouter": "0xc4482f66191754a8629D35289043C4EB0285F10E", "interchainGasPaymaster": "0x14760E32C0746094cF14D97124865BC7F0F7368F", - "interchainSecurityModule": "0x0F016E98B570D263cb5E37948bF4D92F328fcA4A", + "interchainSecurityModule": "0xFc907245E3c91cFE8aFFDcCb01ef7053a76C7eDb", "mailbox": "0x094d03E751f49908080EFf000Dd6FD177fd44CC3", "merkleTreeHook": "0x87403b85f6f316e7ba91ba1fa6C3Fb7dD4095547", "name": "moonbeam", @@ -2143,7 +2143,7 @@ "interchainAccountIsm": "0x2c46BF14641d00549ECa4779BF5CBf91602C1DEd", "interchainAccountRouter": "0x03D6cC17d45E9EA27ED757A8214d1F07F7D901aD", "interchainGasPaymaster": "0xD8A76C4D91fCbB7Cc8eA795DFDF870E48368995C", - "interchainSecurityModule": "0x3f8b6df0282D9fAF0d12752cD40166298A67f29B", + "interchainSecurityModule": "0xe12A4A59080320aBC854FE647761D83D00883807", "mailbox": "0xd4C1905BB1D26BC93DAC913e13CaCC278CdCC80D", "merkleTreeHook": "0x68eE9bec9B4dbB61f69D9D293Ae26a5AACb2e28f", "name": "optimism", @@ -2278,7 +2278,7 @@ "interchainAccountIsm": "0xBAC4529cdfE7CCe9E858BF706e41F8Ed096C1BAd", "interchainAccountRouter": "0xF163949AD9F88977ebF649D0461398Ca752E64B9", "interchainGasPaymaster": "0x0071740Bf129b05C4684abfbBeD248D80971cce2", - "interchainSecurityModule": "0x40249639D8b148EBD66FE5b110DEbcE2fa06D683", + "interchainSecurityModule": "0xD94CaFdBe8c9C2C05fD5992B087bc30F237001D2", "mailbox": "0x5d934f4e2f797775e53561bB72aca21ba36B96BB", "merkleTreeHook": "0x73FbD25c3e817DC4B4Cd9d00eff6D83dcde2DfF6", "name": "polygon", @@ -2355,7 +2355,7 @@ "interchainAccountIsm": "0xc1198e241DAe48BF5AEDE5DCE49Fe4A6064cF7a7", "interchainAccountRouter": "0x20a0A32a110362920597F72974E1E0d7e25cA20a", "interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4", - "interchainSecurityModule": "0xAaBb015A97a49eCEa506A3D7b831BFF8458B7421", + "interchainSecurityModule": "0xAbD84C24bC17b3733D094Cf911561F3c088bA8E0", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112", "name": "polygonzkevm", @@ -2423,7 +2423,7 @@ "from": 32018468 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0x015c05e7bCeAB0D16912667cC03282C6276aC7d7", + "interchainSecurityModule": "0x1C516BB0B775B2EDF3fA26beb547f2634F23bB11", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "proofofplay", @@ -2487,7 +2487,7 @@ "from": 363159 }, "interchainGasPaymaster": "0x3071D4DA6020C956Fe15Bfd0a9Ca8D4574f16696", - "interchainSecurityModule": "0xbFA199Fae108dF18860D847c881EF5F8a7745e85", + "interchainSecurityModule": "0x342766bc19A0bcd47d4269D1804AF4Ad27D4372C", "mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", "merkleTreeHook": "0x55E4F0bc6b7Bb493D50839A8592e7ad8d5e93cf7", "name": "real", @@ -2554,7 +2554,7 @@ "interchainAccountIsm": "0x5DA60220C5dDe35b7aE91c042ff5979047FA0785", "interchainAccountRouter": "0x7a4d31a686A36285d68e14EDD53631417eB19603", "interchainGasPaymaster": "0x2Fa570E83009eaEef3a1cbd496a9a30F05266634", - "interchainSecurityModule": "0xA3A88Cf5b9eB22a9a192d8fC592ac769B1EA150A", + "interchainSecurityModule": "0x020f0b3691383B662Fb0D5799D5516652eFE5124", "mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", "merkleTreeHook": "0x8F1E22d309baa69D398a03cc88E9b46037e988AA", "name": "redstone", @@ -2616,7 +2616,7 @@ "from": 937117 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xAA379b1f1B425b8174e1bF1614A40845053A86cF", + "interchainSecurityModule": "0x798BC62c7E991c908A7c18131324Eb413ac61cc6", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "sanko", @@ -2684,7 +2684,7 @@ "interchainAccountIsm": "0x32af5Df81fEd5E26119F6640FBB13f3d63a94CDe", "interchainAccountRouter": "0x0B48a744698ba8dFa514742dFEB6728f52fD66f7", "interchainGasPaymaster": "0xBF12ef4B9f307463D3FB59c3604F294dDCe287E2", - "interchainSecurityModule": "0x2C63D8BA06b341E73392E4d6ef069064D6fE4CDc", + "interchainSecurityModule": "0x35b219Ee7824b0DB8d0bE01a97Cb88cFC4d8aB22", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x6119E37Bd66406A1Db74920aC79C15fB8411Ba76", "name": "scroll", @@ -2752,7 +2752,7 @@ "interchainAccountIsm": "0xf35dc7B9eE4Ebf0cd3546Bd6EE3b403dE2b9F5D6", "interchainAccountRouter": "0xBcaedE97a98573A88242B3b0CB0A255F3f90d4d5", "interchainGasPaymaster": "0xFC62DeF1f08793aBf0E67f69257c6be258194F72", - "interchainSecurityModule": "0x9b8e185A2e166e6E2357d23b4626220C656aD8dF", + "interchainSecurityModule": "0x7329fEFd101560d0e56F54768dB5c7f095148a9b", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xca1b69fA4c4a7c7fD839bC50867c589592bcfe49", "name": "sei", @@ -2867,7 +2867,7 @@ "interchainAccountIsm": "0xAE557e108b3336130370aC74836f1356B4b30Cf2", "interchainAccountRouter": "0x1F8CF09F060A2AE962c0Bb1F92e209a1E7b0E10B", "interchainGasPaymaster": "0x273Bc6b01D9E88c064b6E5e409BdF998246AEF42", - "interchainSecurityModule": "0x68Ea629559Df7041adCf61569576023695C4A76b", + "interchainSecurityModule": "0x38ab08a7cb19757Ba6dc870277780519380DED32", "mailbox": "0x28EFBCadA00A7ed6772b3666F3898d276e88CAe3", "merkleTreeHook": "0x6A55822cf11f9fcBc4c75BC2638AfE8Eb942cAdd", "name": "taiko", @@ -2929,7 +2929,7 @@ "from": 1678063 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xAA379b1f1B425b8174e1bF1614A40845053A86cF", + "interchainSecurityModule": "0x798BC62c7E991c908A7c18131324Eb413ac61cc6", "isTestnet": false, "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", @@ -2997,7 +2997,7 @@ "interchainAccountIsm": "0x551BbEc45FD665a8C95ca8731CbC32b7653Bc59B", "interchainAccountRouter": "0xc11f8Cf2343d3788405582F65B8af6A4F7a6FfC8", "interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4", - "interchainSecurityModule": "0x00cd5A9d087E1a87779252487c35ba37C399808D", + "interchainSecurityModule": "0x8c5D31F910a08E8ae72a1Ea28c77609be3774e29", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112", "name": "viction", @@ -3065,7 +3065,7 @@ "interchainAccountIsm": "0xCB9f90EE5d83Ea52ABd922BD70898f0155D54798", "interchainAccountRouter": "0x473884010F0C1742DA8Ad01E7E295624B931076b", "interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503", - "interchainSecurityModule": "0x34aD800C9e56D75655680401B8c5140ce4cACDBa", + "interchainSecurityModule": "0x586bB821b040491EA7822317cA2316c3B217F9AA", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD", "name": "worldchain", @@ -3127,7 +3127,7 @@ "from": 24395308 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xd69d8FBC4d716d902f40d041596f024B705CE394", + "interchainSecurityModule": "0xb26302055D46090B299b7c01041f246FEEdcE559", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "xai", @@ -3195,7 +3195,7 @@ "interchainAccountIsm": "0x29B37088724B745C0ABcE591449Cf042772160C2", "interchainAccountRouter": "0x03cF708E42C89623bd83B281A56935cB562b9258", "interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503", - "interchainSecurityModule": "0xe88402C8346b055644E9dBBf6125131F73d89763", + "interchainSecurityModule": "0xae69dcB077234da706C6228756Ffb13B8B332970", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD", "name": "xlayer", @@ -3263,7 +3263,7 @@ "interchainAccountIsm": "0x2b6d3F7d28B5EC8C3C028fBCAdcf774D9709Dd29", "interchainAccountRouter": "0x3AdCBc94ab8C48EC52D06dc65Bb787fD1981E3d5", "interchainGasPaymaster": "0x931dFCc8c1141D6F532FD023bd87DAe0080c835d", - "interchainSecurityModule": "0xA20Df62dEC7B82ea026CDcaD99774cB667F75d88", + "interchainSecurityModule": "0xFa772A78594a65458B7A6934DA1fA83930B0F51b", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xE2ee936bEa8e42671c400aC96dE198E06F2bA2A6", "name": "zetachain", @@ -3329,7 +3329,7 @@ "from": 1511458 }, "interchainGasPaymaster": "0x03cF708E42C89623bd83B281A56935cB562b9258", - "interchainSecurityModule": "0x9f5eFA37Aa96676A634eDbBd2E2132a75557a19e", + "interchainSecurityModule": "0x41792A9E3FD2883F5bD6fd38a209483Fc21082f8", "mailbox": "0xc2FbB9411186AB3b1a6AFCCA702D1a80B48b197c", "merkleTreeHook": "0x4C97D35c668EE5194a13c8DE8Afc18cce40C9F28", "name": "zircuit", @@ -3402,7 +3402,7 @@ "interchainAccountIsm": "0xb2674E213019972f937CCFc5e23BF963D915809e", "interchainAccountRouter": "0x11b76D93a9D39Eb51F54eBf5566308640cDe882b", "interchainGasPaymaster": "0x18B0688990720103dB63559a3563f7E8d0f63EDb", - "interchainSecurityModule": "0xB4F0a46314954446aeEb27254569510226ecd3c2", + "interchainSecurityModule": "0xD1Ce8d18B61AfE53D63ba7DC359F0bD3eA915235", "mailbox": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0x886BB0f329781b98f98FDeb1ce7a8957F2d43B9F", "name": "zoramainnet", @@ -3473,7 +3473,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x4b1EF66EB03743D243dca2024af3B6C4BB2afCAC", + "interchainSecurityModule": "0x5d315fD2F9ce3F538F76c2f6b9516495B0a1bCEb", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3540,7 +3540,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x55bD770A3220A745B62600e3BEE6e6F944948c5B", + "interchainSecurityModule": "0x24326Ebe336Fa9d48615697B39845B6B2F098174", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3610,7 +3610,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x2D78569De74146D7CDB5A8aabD8Bd451Da641c92", + "interchainSecurityModule": "0x4bD8927F13cCCe50B2bB3603B5Eaf484A56f1638", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3686,7 +3686,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x574A030c4636De291C42537d1dc0B9079318F839", + "interchainSecurityModule": "0xF53b96635A3e7c57fe481c94efe0F658990E5040", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3750,7 +3750,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x376F482e4dF14f7d497Ee5bF827Cf7BC7688F9DD", + "interchainSecurityModule": "0x071aeFd19DD91AB9E63ED3BDa36d0b7097A7459f", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3823,7 +3823,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x53245370532d36e57B2Ef87fAF7Fb389A88aC57e", + "interchainSecurityModule": "0x2769f9B495692BC6135BA71255EeD04A995e74E2", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3891,7 +3891,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0xe8b432a77F1195bD7F27d54f0D354D25E014c1DE", + "interchainSecurityModule": "0xB2fB0a0b676B75cf6Af1ab517023f88Ea90EDd2E", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3954,7 +3954,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x60DE73a356E9bEFBC73Ca55799ab4AE18d9f0574", + "interchainSecurityModule": "0x604F761705Cf5D1682dD17356b84d96CD41B0734", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -4024,7 +4024,7 @@ "interchainAccountIsm": "0xcd9D3744512F07AE844c40E27912092d7c503565", "interchainAccountRouter": "0x92cdbF0Ccdf8E93467FA858fb986fa650A02f2A8", "interchainGasPaymaster": "0xb58257cc81E47EC72fD38aE16297048de23163b4", - "interchainSecurityModule": "0x099c96B148fC39c449884D7ABEC6837e51BF7fA9", + "interchainSecurityModule": "0x80D7DDC0b7d8dae6F9CcB0D78558291118815349", "mailbox": "0x7f50C5776722630a0024fAE05fDe8b47571D7B39", "merkleTreeHook": "0xCC3D1659D50461d27a2F025dDb2c9B06B584B7e1", "pausableHook": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", @@ -4084,7 +4084,7 @@ "interchainAccountIsm": "0xc23BaF5Eb5848D19701BbE7f139645e6bd58a319", "interchainAccountRouter": "0x7c58Cadcc2b60ACF794eE1843488d6f5703f76BE", "interchainGasPaymaster": "0xb4fc9B5fD57499Ef6FfF3995728a55F7A618ef86", - "interchainSecurityModule": "0x6aF9a16aa08e3ae6B3Cd898407dEfCF1de469783", + "interchainSecurityModule": "0x64bdb8Bfb9DbAc2FD2fD28a9B37605CE73D4410f", "mailbox": "0xb129828B9EDa48192D0B2db35D0E40dCF51B3594", "merkleTreeHook": "0x3E969bA938E6A993eeCD6F65b0dd8712B07dFe59", "pausableHook": "0x6Fb36672365C7c797028C400A61c58c0ECc53cD2", @@ -4215,7 +4215,7 @@ "interchainAccountIsm": "0x6119B76720CcfeB3D256EC1b91218EEfFD6756E1", "interchainAccountRouter": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", "interchainGasPaymaster": "0x18B0688990720103dB63559a3563f7E8d0f63EDb", - "interchainSecurityModule": "0x03426Cf05E862B4702391Ff7E005E7cDB71cC789", + "interchainSecurityModule": "0x9386BadA88dF2b034614Dcf3CC82aB0dC6C63849", "mailbox": "0x7f50C5776722630a0024fAE05fDe8b47571D7B39", "merkleTreeHook": "0x886BB0f329781b98f98FDeb1ce7a8957F2d43B9F", "pausableHook": "0x2F619Ac5122689180AeBB930ADccdae215d538a9", @@ -4279,7 +4279,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0xD70e68A8CBEff2349b3F0455B45d58D555256633", + "interchainSecurityModule": "0xf10dB7FBC4B5d79d217881aB7FeC71A4a33449af", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -4340,7 +4340,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0xD91a9416ffd488eEfFD8F3E1dF884d54eaD87673", + "interchainSecurityModule": "0xf48D165f545221766DbEB9D92b1187DD1322170b", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -4419,7 +4419,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0xC601666Ca22649b20d642c0eb36047d265928D04", + "interchainSecurityModule": "0x78E7691458EA3Ca38a56fD4eFBE54D30dDDa72Ac", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -4486,7 +4486,7 @@ "interchainAccountIsm": "0x783EC5e105234a570eB90f314284E5dBe53bdd90", "interchainAccountRouter": "0xc5D6aCaafBCcEC6D7fD7d92F4509befce641c563", "interchainGasPaymaster": "0xf3dFf6747E7FC74B431C943961054B7BF6309d8a", - "interchainSecurityModule": "0x1738cd8652a324DD9781D5Ce0f609827761D48dA", + "interchainSecurityModule": "0x3Eb3273A92B6b1653f64CD945506dd67F478C9bd", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x5090dF2FBDa7127c7aDa41f60B79F5c55D380Dd8", "pausableHook": "0x886BB0f329781b98f98FDeb1ce7a8957F2d43B9F", @@ -4557,7 +4557,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x9e92E451b71378aBf1cd4769f34528af9C0e97Fd", + "interchainSecurityModule": "0x3428158e7D0D9AD25653ea390EE9a9aA43628a48", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -4622,7 +4622,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0xD91a9416ffd488eEfFD8F3E1dF884d54eaD87673", + "interchainSecurityModule": "0xFeAE4cdACEc5E2aC50A0357eed6c13A5d76c88cD", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -4686,7 +4686,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x330063B36D40D1d77DBAd7e9552b97433f281090", + "interchainSecurityModule": "0x18545b46Df0A6cd81FA05C663FAc4ee26a750ad0", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -4753,7 +4753,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0xD70e68A8CBEff2349b3F0455B45d58D555256633", + "interchainSecurityModule": "0xc3FFEd2a525a487cfe805193c463CB7BdD704CE9", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -4817,7 +4817,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x0197F4a7ED6db49Ad345214C710206aCfFBA241a", + "interchainSecurityModule": "0xb5813484CD3027FCb4B908a3bD2D9c118423a14B", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -4879,7 +4879,7 @@ "fallbackDomainRoutingHook": "0x671836d35BB15E21ECc92c4936F0e3131efe12B4", "fallbackRoutingHook": "0x671836d35BB15E21ECc92c4936F0e3131efe12B4", "interchainGasPaymaster": "0x318FbdB17d4e743aBF3183658a4730777101B75C", - "interchainSecurityModule": "0x307A9dBD1df2329c3c597aF6853de60660baFFb5", + "interchainSecurityModule": "0xd60690A755C070817AacF88d1FD3F64451D80149", "mailbox": "0xd7b351D2dE3495eA259DD10ab4b9300A378Afbf3", "merkleTreeHook": "0x55379421409961Ef129738c24261379ef8A547Df", "proxyAdmin": "0x72e2A678442Edc65f14476A0E4c94312C0469f4A", @@ -4937,7 +4937,7 @@ "fallbackDomainRoutingHook": "0xe4e98Cc5D0318aBFD2adA8A3C6817b727063F500", "fallbackRoutingHook": "0xe4e98Cc5D0318aBFD2adA8A3C6817b727063F500", "interchainGasPaymaster": "0xf44AdA86a1f765A938d404699B8070Dd47bD2431", - "interchainSecurityModule": "0xec650696FDAE2355A928520AD7d6491c6072cf7f", + "interchainSecurityModule": "0xB3A8a3270D59Ef267E188c40d29FA0d9072796aD", "mailbox": "0x6bD0A2214797Bc81e0b006F7B74d6221BcD8cb6E", "merkleTreeHook": "0x823500D69D77A52212DC93f8836E9c08581487eE", "proxyAdmin": "0xD01274DC164D32F8595bE707F221375E68cE300C", @@ -5003,7 +5003,7 @@ "interchainAccountIsm": "0x4d264424905535E97396Db83bd553D0d73A4EF9d", "interchainAccountRouter": "0x26A29486480BD74f9B830a9B8dB33cb43C40f496", "interchainGasPaymaster": "0x9c2214467Daf9e2e1F45b36d08ce0b9C65BFeA88", - "interchainSecurityModule": "0x28Ce6b8aB49e37f2B386056bB7D9779Ecc89f4EE", + "interchainSecurityModule": "0x5e7Ff7Cb6C828DFda4Ce8934A6f8F4C7B33E2217", "mailbox": "0x5bdADEAD721Eb4C4038fF7c989E3C7BbBA302435", "merkleTreeHook": "0x2684C6F89E901987E1FdB7649dC5Be0c57C61645", "pausableHook": "0xC8E323036AAFB4B4201e7B640E79C4Db285A3FC8", @@ -5067,7 +5067,7 @@ "interchainAccountIsm": "0x545E289B88c6d97b74eC0B96e308cae46Bf5f832", "interchainAccountRouter": "0x4ef363Da5bb09CC6aeA16973786963d0C8820778", "interchainGasPaymaster": "0x561BcA8D862536CD9C88f332C1A1Da0fC8F96e40", - "interchainSecurityModule": "0x5Cd2d33b51b3394A14C11ea79E5E0Ba6bCC81e83", + "interchainSecurityModule": "0x14bF825eE8FaD180d379280963FBB66F6c256a6E", "mailbox": "0x248aDe14C0489E20C9a7Fea5F86DBfC3702208eF", "merkleTreeHook": "0x9c2214467Daf9e2e1F45b36d08ce0b9C65BFeA88", "pausableHook": "0x2f536FB7a37bd817Af644072a904Ddc02Dae429f", @@ -5134,7 +5134,7 @@ "interchainAccountIsm": "0x60bB6D060393D3C206719A7bD61844cC82891cfB", "interchainAccountRouter": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", "interchainGasPaymaster": "0x61374178e45F65fF9D6252d017Cd580FC60B7654", - "interchainSecurityModule": "0xE97f143373BA2f424a67FC3fc5cf7EfE2095aF0A", + "interchainSecurityModule": "0x969179b1330226bC861aE726Aa1D2Bba03cc5576", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0xEe08043cf22c80b27BF24d19999231dF4a3fC256", "pausableHook": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", @@ -5199,7 +5199,7 @@ "interchainAccountIsm": "0xcdc31BA959DE8C035A03167ebAE1961208CDf172", "interchainAccountRouter": "0x349831a180eE4265008C5FFB9465Ff97c1CF0028", "interchainGasPaymaster": "0x6AA10748a036a49Cb290C0e12B77319b76792D5E", - "interchainSecurityModule": "0xBB7E1A95C63cc745b6e51127d04e9a957966591e", + "interchainSecurityModule": "0x1Be73077A341D517AcAa2516c0BE356b6444134B", "mailbox": "0xd9Cc2e652A162bb93173d1c44d46cd2c0bbDA59D", "merkleTreeHook": "0x2783D98CC073dbcDa90241C804d16982D3d75821", "pausableHook": "0x3bb2D0a828f7dD91bA786091F421f6d7cF376445", @@ -5269,7 +5269,7 @@ "interchainAccountIsm": "0x545E289B88c6d97b74eC0B96e308cae46Bf5f832", "interchainAccountRouter": "0x4ef363Da5bb09CC6aeA16973786963d0C8820778", "interchainGasPaymaster": "0xc6835e52C1b976F1ebC71Bc8919738E02849FdA9", - "interchainSecurityModule": "0xc622B32Da6Bc983B7aE6Ea7253D39396512e5F70", + "interchainSecurityModule": "0x8021F7b95A9354619c22a3bed3a6549d07Ac34B4", "mailbox": "0x1c6f404800bA49Ed581af734eA0d25c0c7d017B2", "merkleTreeHook": "0xdAa1B65547fB969c9ff5678956AB2FF9771B883D", "pausableHook": "0xA0e0829DA397CcF55d5B779C31728f21Cb8219DF", @@ -5381,7 +5381,7 @@ "interchainAccountIsm": "0x8c794a781327b819416E7b67908f1D22397f1E67", "interchainAccountRouter": "0x16625230dD6cFe1B2bec3eCaEc7d43bA3A902CD6", "interchainGasPaymaster": "0x2b79328DA089E89A9E9c08732b56dd31F01011Db", - "interchainSecurityModule": "0xFdd7f8b8CBe3612609Fe5bf0332B280182dcB74F", + "interchainSecurityModule": "0x14663E42b9b66F79103c5824230CC79a26E24BfD", "mailbox": "0x730f8a4128Fa8c53C777B62Baa1abeF94cAd34a9", "merkleTreeHook": "0x9c64f327F0140DeBd430aab3E2F1d6cbcA921227", "pausableHook": "0x2684C6F89E901987E1FdB7649dC5Be0c57C61645", @@ -5445,7 +5445,7 @@ "interchainAccountIsm": "0xE67Dc24970B482579923551Ede52BD35a2858989", "interchainAccountRouter": "0xDDE46032Baf4da13fDD79BF9dfbaA2749615C409", "interchainGasPaymaster": "0x2f536FB7a37bd817Af644072a904Ddc02Dae429f", - "interchainSecurityModule": "0xcCe65dffEc65798B986969EE9A490AC096d0E54e", + "interchainSecurityModule": "0x846856eeD85eBc6C5FBf94F17e0c9cC76dF6c86E", "mailbox": "0x2f0E57527Bb37E5E064EF243fad56CCE6241906c", "merkleTreeHook": "0xC8E323036AAFB4B4201e7B640E79C4Db285A3FC8", "pausableHook": "0xdAa1B65547fB969c9ff5678956AB2FF9771B883D", @@ -5509,7 +5509,7 @@ "interchainAccountIsm": "0x20a0A32a110362920597F72974E1E0d7e25cA20a", "interchainAccountRouter": "0x5b3EeADcc0E2d4284eA6816e2E503c24d30a9E54", "interchainGasPaymaster": "0x282629Af1A2f9b8e2c5Cbc54C35C7989f21950c6", - "interchainSecurityModule": "0x7B891Aec2e7edA0215Be884f2396615a231A1502", + "interchainSecurityModule": "0xa1080587BA36750d90746A147Ee79F8589Ac0099", "mailbox": "0x5C02157068a52cEcfc98EDb6115DE6134EcB4764", "merkleTreeHook": "0xf147bBD944C610F86DaE6C7668497D22932C1E4A", "pausableHook": "0x872Bd98057931c8809927c6dE2ef39738a80Eb0C", @@ -5576,7 +5576,7 @@ "interchainAccountIsm": "0xf40eE9FF75Fa34910b7C4C8d68d4850B3bD184D3", "interchainAccountRouter": "0xf6fB78dc009C1A4286c0E7d90C10c9E8906a62Ea", "interchainGasPaymaster": "0xDDE46032Baf4da13fDD79BF9dfbaA2749615C409", - "interchainSecurityModule": "0xc09E4b2C7b3884609dded73571a27B8F6D05aA66", + "interchainSecurityModule": "0x008FED472F8d4634C5701B3bEc2380C30064BEb5", "mailbox": "0x65dCf8F6b3f6a0ECEdf3d0bdCB036AEa47A1d615", "merkleTreeHook": "0x8c794a781327b819416E7b67908f1D22397f1E67", "pausableHook": "0x4d264424905535E97396Db83bd553D0d73A4EF9d", @@ -5643,7 +5643,7 @@ "interchainAccountIsm": "0xd9Cc2e652A162bb93173d1c44d46cd2c0bbDA59D", "interchainAccountRouter": "0x7279B1e11142078b8dC9e69620200f4C84FB8aaa", "interchainGasPaymaster": "0x5ae1ECA065aC8ee92Ce98E584fc3CE43070020e7", - "interchainSecurityModule": "0xE367092A59d558a9Ee8894D12f4Fa363A168870e", + "interchainSecurityModule": "0x54BF1a8c5584E844a6b4F9F98e2770A415921f66", "mailbox": "0x96D51cc3f7500d501bAeB1A2a62BB96fa03532F8", "merkleTreeHook": "0x086c3947F71BE98A0bDf4AB7239955e7542b0CbA", "pausableHook": "0x9C6e8d989ea7F212e679191BEb44139d83ac927a", @@ -5713,7 +5713,7 @@ "interchainAccountIsm": "0x8a733038eF4BbC314eE0F7595257D8d3799B6aA9", "interchainAccountRouter": "0xCE8260c1b5cF2fAD15bb4B6542716b050Fdf35c9", "interchainGasPaymaster": "0xa1c3884EbE24Cccb120B2E98a55f85140563aa4C", - "interchainSecurityModule": "0x5D26b61F665FabFF52D6f5260072dc20BC9b0652", + "interchainSecurityModule": "0xBCc50A4e5690251aFF052b415251DfBc634002C7", "mailbox": "0x5e8a0fCc0D1DF583322943e01F02cB243e5300f6", "merkleTreeHook": "0x2f536FB7a37bd817Af644072a904Ddc02Dae429f", "pausableHook": "0xc6835e52C1b976F1ebC71Bc8919738E02849FdA9", @@ -5731,6 +5731,713 @@ "testRecipient": "0x545E289B88c6d97b74eC0B96e308cae46Bf5f832", "timelockController": "0x0000000000000000000000000000000000000000", "validatorAnnounce": "0x26A29486480BD74f9B830a9B8dB33cb43C40f496" + }, + "boba": { + "blockExplorers": [ + { + "apiUrl": "https://api.routescan.io/v2/network/mainnet/evm/288/etherscan/api", + "family": "routescan", + "name": "bobascan", + "url": "https://bobascan.com" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 2, + "reorgPeriod": 5 + }, + "chainId": 288, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "Boba Mainnet", + "domainId": 288, + "gasCurrencyCoinGeckoId": "ethereum", + "name": "boba", + "nativeToken": { + "decimals": 18, + "name": "Ether", + "symbol": "ETH" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://mainnet.boba.network" + } + ], + "technicalStack": "opstack", + "aggregationHook": "0x4533B9ff84bE4f4009409414aF8b8e9c3f4F52a8", + "domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730", + "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "fallbackRoutingHook": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "interchainAccountIsm": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "interchainAccountRouter": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "interchainGasPaymaster": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "interchainSecurityModule": "0x0cF15af1385776F0f853C3525cC9A9eba600c209", + "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "merkleTreeHook": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "pausableHook": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "pausableIsm": "0xc5D6aCaafBCcEC6D7fD7d92F4509befce641c563", + "protocolFee": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "proxyAdmin": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "staticAggregationHookFactory": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "staticAggregationIsm": "0x46De8b87577624b9ce63201238982b95ad0d7Ea4", + "staticAggregationIsmFactory": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "staticMerkleRootMultisigIsmFactory": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "staticMessageIdMultisigIsmFactory": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "staticMessageIdWeightedMultisigIsmFactory": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "storageGasOracle": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "testRecipient": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE", + "timelockController": "0x0000000000000000000000000000000000000000", + "validatorAnnounce": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e", + "index": { + "from": 10598389 + } + }, + "duckchain": { + "blockExplorers": [ + { + "apiUrl": "https://scan.duckchain.io/api", + "family": "blockscout", + "name": "DuckChain Explorer", + "url": "https://scan.duckchain.io" + } + ], + "blocks": { + "confirmations": 3, + "estimateBlockTime": 1, + "reorgPeriod": 5 + }, + "chainId": 5545, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "DuckChain", + "domainId": 5545, + "gasCurrencyCoinGeckoId": "the-open-network", + "index": { + "from": 1149918 + }, + "name": "duckchain", + "nativeToken": { + "decimals": 18, + "name": "Toncoin", + "symbol": "TON" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://rpc.duckchain.io" + }, + { + "http": "https://rpc-hk.duckchain.io" + } + ], + "technicalStack": "arbitrumnitro", + "aggregationHook": "0x4533B9ff84bE4f4009409414aF8b8e9c3f4F52a8", + "domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730", + "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "fallbackRoutingHook": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "interchainAccountIsm": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "interchainAccountRouter": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "interchainGasPaymaster": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "interchainSecurityModule": "0x319310239BC5c43808Ff1008d0db3B38067F7Ce9", + "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "merkleTreeHook": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "pausableHook": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "pausableIsm": "0xc5D6aCaafBCcEC6D7fD7d92F4509befce641c563", + "protocolFee": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "proxyAdmin": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "staticAggregationHookFactory": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "staticAggregationIsm": "0x46De8b87577624b9ce63201238982b95ad0d7Ea4", + "staticAggregationIsmFactory": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "staticMerkleRootMultisigIsmFactory": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "staticMessageIdMultisigIsmFactory": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "staticMessageIdWeightedMultisigIsmFactory": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "storageGasOracle": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "testRecipient": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE", + "timelockController": "0x0000000000000000000000000000000000000000", + "validatorAnnounce": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e" + }, + "superseed": { + "blockExplorers": [ + { + "apiUrl": "https://explorer.superseed.xyz/api", + "family": "blockscout", + "name": "Superseed Explorer", + "url": "https://explorer.superseed.xyz" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 2, + "reorgPeriod": 5 + }, + "chainId": 5330, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "Superseed", + "domainId": 5330, + "gasCurrencyCoinGeckoId": "ethereum", + "name": "superseed", + "nativeToken": { + "decimals": 18, + "name": "Ether", + "symbol": "ETH" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://mainnet.superseed.xyz" + } + ], + "technicalStack": "opstack", + "aggregationHook": "0x4533B9ff84bE4f4009409414aF8b8e9c3f4F52a8", + "domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730", + "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "fallbackRoutingHook": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "interchainAccountIsm": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "interchainAccountRouter": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "interchainGasPaymaster": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "interchainSecurityModule": "0x773daCf7C9944fE6e1Fa740eeC7FD4ae820a9cbb", + "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "merkleTreeHook": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "pausableHook": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "pausableIsm": "0xc5D6aCaafBCcEC6D7fD7d92F4509befce641c563", + "protocolFee": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "proxyAdmin": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "staticAggregationHookFactory": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "staticAggregationIsm": "0x46De8b87577624b9ce63201238982b95ad0d7Ea4", + "staticAggregationIsmFactory": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "staticMerkleRootMultisigIsmFactory": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "staticMessageIdMultisigIsmFactory": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "staticMessageIdWeightedMultisigIsmFactory": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "storageGasOracle": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "testRecipient": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE", + "timelockController": "0x0000000000000000000000000000000000000000", + "validatorAnnounce": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e", + "index": { + "from": 3010957 + } + }, + "unichain": { + "blockExplorers": [ + { + "apiUrl": "https://unichain.blockscout.com/api", + "family": "blockscout", + "name": "Unichain Explorer", + "url": "https://unichain.blockscout.com" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 1, + "reorgPeriod": 5 + }, + "chainId": 130, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "Unichain", + "domainId": 130, + "gasCurrencyCoinGeckoId": "ethereum", + "name": "unichain", + "nativeToken": { + "decimals": 18, + "name": "Ether", + "symbol": "ETH" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://mainnet.unichain.org" + } + ], + "technicalStack": "opstack", + "aggregationHook": "0x4533B9ff84bE4f4009409414aF8b8e9c3f4F52a8", + "domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730", + "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "fallbackRoutingHook": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "interchainAccountIsm": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "interchainAccountRouter": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "interchainGasPaymaster": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "interchainSecurityModule": "0x555b95e85640aeE885236327aB91946827ebdB57", + "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "merkleTreeHook": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "pausableHook": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "pausableIsm": "0xc5D6aCaafBCcEC6D7fD7d92F4509befce641c563", + "protocolFee": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "proxyAdmin": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "staticAggregationHookFactory": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "staticAggregationIsm": "0x46De8b87577624b9ce63201238982b95ad0d7Ea4", + "staticAggregationIsmFactory": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "staticMerkleRootMultisigIsmFactory": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "staticMessageIdMultisigIsmFactory": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "staticMessageIdWeightedMultisigIsmFactory": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "storageGasOracle": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "testRecipient": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE", + "timelockController": "0x0000000000000000000000000000000000000000", + "validatorAnnounce": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e", + "index": { + "from": 1453239 + } + }, + "vana": { + "blockExplorers": [ + { + "apiUrl": "https://vanascan.io/api/eth-rpc", + "family": "blockscout", + "name": "Vana Explorer", + "url": "https://vanascan.io" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 6, + "reorgPeriod": 5 + }, + "chainId": 1480, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "Vana", + "domainId": 1480, + "gasCurrencyCoinGeckoId": "vana", + "name": "vana", + "nativeToken": { + "decimals": 18, + "name": "Vana", + "symbol": "VANA" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://rpc.vana.org" + } + ], + "technicalStack": "other", + "aggregationHook": "0x4533B9ff84bE4f4009409414aF8b8e9c3f4F52a8", + "domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730", + "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "fallbackRoutingHook": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "interchainAccountIsm": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "interchainAccountRouter": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "interchainGasPaymaster": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "interchainSecurityModule": "0x555b95e85640aeE885236327aB91946827ebdB57", + "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "merkleTreeHook": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "pausableHook": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "pausableIsm": "0xc5D6aCaafBCcEC6D7fD7d92F4509befce641c563", + "protocolFee": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "proxyAdmin": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "staticAggregationHookFactory": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "staticAggregationIsm": "0x46De8b87577624b9ce63201238982b95ad0d7Ea4", + "staticAggregationIsmFactory": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "staticMerkleRootMultisigIsmFactory": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "staticMessageIdMultisigIsmFactory": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "staticMessageIdWeightedMultisigIsmFactory": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "storageGasOracle": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "testRecipient": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE", + "timelockController": "0x0000000000000000000000000000000000000000", + "validatorAnnounce": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e", + "index": { + "from": 629917 + } + }, + "bsquared": { + "blockExplorers": [ + { + "apiUrl": "https://explorer.bsquared.network/api", + "family": "etherscan", + "name": "B² Network Explorer", + "url": "https://explorer.bsquared.network" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 3, + "reorgPeriod": 5 + }, + "chainId": 223, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "B² Network", + "domainId": 223, + "gasCurrencyCoinGeckoId": "bitcoin", + "name": "bsquared", + "nativeToken": { + "decimals": 18, + "name": "Bitcoin", + "symbol": "BTC" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://rpc.bsquared.network" + }, + { + "http": "https://rpc.ankr.com/b2" + }, + { + "http": "https://mainnet.b2-rpc.com" + }, + { + "http": "https://b2-mainnet.alt.technology" + } + ], + "technicalStack": "other", + "aggregationHook": "0x03D610d916D5D274e4A31c026fd6884281A35d9C", + "domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730", + "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "fallbackRoutingHook": "0x60bB6D060393D3C206719A7bD61844cC82891cfB", + "interchainAccountIsm": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "interchainAccountRouter": "0x4D50044335dc1d4D26c343AdeDf6E47808475Deb", + "interchainGasPaymaster": "0x70EbA87Cd15616f32C736B3f3BdCfaeD0713a82B", + "interchainSecurityModule": "0x6d29ffb859D867Faf2705f39b168331960438f31", + "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "merkleTreeHook": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "pausableHook": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de", + "pausableIsm": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "protocolFee": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE", + "proxyAdmin": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "staticAggregationHookFactory": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "staticAggregationIsm": "0x7dBb82188F553161d4B4ac3a2362Bff3a57e21D2", + "staticAggregationIsmFactory": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "staticMerkleRootMultisigIsmFactory": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "staticMessageIdMultisigIsmFactory": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "staticMessageIdWeightedMultisigIsmFactory": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "storageGasOracle": "0x451dF8AB0936D85526D816f0b4dCaDD934A034A4", + "testRecipient": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597", + "timelockController": "0x0000000000000000000000000000000000000000", + "validatorAnnounce": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "index": { + "from": 9687363 + } + }, + "lumiaprism": { + "blockExplorers": [ + { + "apiUrl": "https://explorer.lumia.org/api/eth-rpc", + "family": "blockscout", + "name": "Lumia Prism Explorer", + "url": "https://explorer.lumia.org" + } + ], + "blocks": { + "confirmations": 3, + "estimateBlockTime": 4, + "reorgPeriod": 5 + }, + "chainId": 994873017, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "Lumia Prism", + "domainId": 1000073017, + "gasCurrencyCoinGeckoId": "lumia", + "name": "lumiaprism", + "nativeToken": { + "decimals": 18, + "name": "Lumia", + "symbol": "LUMIA" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://mainnet-rpc.lumia.org" + } + ], + "technicalStack": "polygoncdk", + "aggregationHook": "0xB090349B613577E10A908D7A3ac822ac0310c8fe", + "domainRoutingIsm": "0x30f96591A3A57D76ad4c071fD857d4D1022e886b", + "domainRoutingIsmFactory": "0x8eC5f0239C77295452Ed899FDB851e785cA5FC31", + "fallbackRoutingHook": "0x850615dF99FEc6edffC77Ff246f604a6f7Df6a78", + "interchainAccountIsm": "0x31Bb27f6007C33acD1be83ACEd3164C60f8F7b13", + "interchainAccountRouter": "0xEeb5a99a75585fe137c83E7b62b74f87264A5481", + "interchainGasPaymaster": "0xb7C9307fE90B9AB093c6D3EdeE3259f5378D5f03", + "interchainSecurityModule": "0x833005B52Ea2785178752f91b51614E40eF56891", + "mailbox": "0x0dF25A2d59F03F039b56E90EdC5B89679Ace28Bc", + "merkleTreeHook": "0xC88636fFdFAc7cb87b7A76310B7a62AF0A000595", + "pausableHook": "0x2AF32cF8e3Cf42d221eDa0c843818fA5ee129E27", + "pausableIsm": "0xd6ba5e6c82E173EC8FB1f6CD8b2b9C111A0982a7", + "protocolFee": "0x14891ce5AF49fb21182C1dc8B81853f3493B1B5B", + "proxyAdmin": "0x200183De44bf765ECB73cD62A74010EaaBC43146", + "staticAggregationHookFactory": "0xf40eE9FF75Fa34910b7C4C8d68d4850B3bD184D3", + "staticAggregationIsm": "0x3BCCc97eD209a7D8ad4A14e20f3A5C37Ff0eFaD4", + "staticAggregationIsmFactory": "0xD7777efaC7241E63f0c7708aA912AEd8CFAfee69", + "staticMerkleRootMultisigIsmFactory": "0xf376247BdE9763808034567E7E87c84970e81E8F", + "staticMerkleRootWeightedMultisigIsmFactory": "0x408F58D25003001C7e5F30259217F1040b8F5AaD", + "staticMessageIdMultisigIsmFactory": "0x280626Ea62fBB3C1A38641D5e735c1d0EE3F28cF", + "staticMessageIdWeightedMultisigIsmFactory": "0xf6fB78dc009C1A4286c0E7d90C10c9E8906a62Ea", + "storageGasOracle": "0x3c38fC01159E7BE0685653A0C896eA49F2BAa7c1", + "testRecipient": "0x128Ff1d24665d55f4b77B1FDbb6d8D0Ec4a0c0a1", + "timelockController": "0x0000000000000000000000000000000000000000", + "validatorAnnounce": "0x803d2A87429E20d4B52266bF97Ca1c7e4f4F5Dfa", + "index": { + "from": 3144538 + } + }, + "swell": { + "blockExplorers": [ + { + "apiUrl": "https://explorer.swellnetwork.io/api", + "family": "blockscout", + "name": "Swell Explorer", + "url": "https://explorer.swellnetwork.io" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 2, + "reorgPeriod": 5 + }, + "chainId": 1923, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "Swell", + "domainId": 1923, + "gasCurrencyCoinGeckoId": "ethereum", + "name": "swell", + "nativeToken": { + "decimals": 18, + "name": "Ether", + "symbol": "ETH" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://swell-mainnet.alt.technology" + } + ], + "technicalStack": "opstack", + "aggregationHook": "0x2e4d4189a24fa484Aad5D7Cd6ebe3A80cDAAB068", + "domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730", + "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "fallbackRoutingHook": "0x70EbA87Cd15616f32C736B3f3BdCfaeD0713a82B", + "interchainAccountIsm": "0x28291a7062afA569104bEd52F7AcCA3dD2FafD11", + "interchainAccountRouter": "0xe9E3444DDD80c50276c0Fcf316026f6d7fEc2c47", + "interchainGasPaymaster": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "interchainSecurityModule": "0xd8d54AA2d31De782C76170328eB3Dca412F171ae", + "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "merkleTreeHook": "0x5C02157068a52cEcfc98EDb6115DE6134EcB4764", + "pausableHook": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "pausableIsm": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "protocolFee": "0x7CE76f5f0C469bBB4cd7Ea6EbabB54437A093127", + "proxyAdmin": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "staticAggregationHookFactory": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "staticAggregationIsm": "0xEa325c513Bd54A3d4a04D98843d0523B1477751D", + "staticAggregationIsmFactory": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "staticMerkleRootMultisigIsmFactory": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "staticMessageIdMultisigIsmFactory": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "staticMessageIdWeightedMultisigIsmFactory": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "storageGasOracle": "0xCDeb368Db32ecCefaf7018e152DA9120565cb572", + "testRecipient": "0xBC53dACd8c0ac0d2bAC461479EAaf5519eCC8853", + "timelockController": "0x0000000000000000000000000000000000000000", + "validatorAnnounce": "0x4D50044335dc1d4D26c343AdeDf6E47808475Deb", + "index": { + "from": 57794 + }, + "gnosisSafeTransactionServiceUrl": "https://trx-swell.safe.protofire.io" + }, + "appchain": { + "blockExplorers": [ + { + "apiUrl": "https://explorer.appchain.xyz/api", + "family": "blockscout", + "name": "AppChain Explorer", + "url": "https://explorer.appchain.xyz" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 2, + "reorgPeriod": 0 + }, + "chainId": 466, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "AppChain", + "domainId": 466, + "gasCurrencyCoinGeckoId": "ethereum", + "index": { + "from": 190 + }, + "name": "appchain", + "nativeToken": { + "decimals": 18, + "name": "Ether", + "symbol": "ETH" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://appchain.calderachain.xyz/http" + } + ], + "technicalStack": "arbitrumnitro", + "aggregationHook": "0xD67829Ba73A4287a870f67280DFb86DB6cA1cC46", + "domainRoutingIsm": "0xBD70Ea9D599a0FC8158B026797177773C3445730", + "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "fallbackRoutingHook": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "interchainAccountIsm": "0x027eFD1695941969435AA640542B690044dF7E06", + "interchainAccountRouter": "0x65F1343AC23D4fF48bf6c7E0c55872d245397567", + "interchainGasPaymaster": "0x28291a7062afA569104bEd52F7AcCA3dD2FafD11", + "interchainSecurityModule": "0xAf8AA677016ee577268Ab6ad19483075605a5671", + "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "merkleTreeHook": "0xcd90D49b046772F710250b9119117169CB2e4D8b", + "pausableHook": "0x7CE76f5f0C469bBB4cd7Ea6EbabB54437A093127", + "pausableIsm": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "protocolFee": "0xD35Aa652C1F808d3f87DA3DC7974fea888D7d625", + "proxyAdmin": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "staticAggregationHookFactory": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "staticAggregationIsm": "0xAf8AA677016ee577268Ab6ad19483075605a5671", + "staticAggregationIsmFactory": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "staticMerkleRootMultisigIsmFactory": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "staticMessageIdMultisigIsmFactory": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "staticMessageIdWeightedMultisigIsmFactory": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "storageGasOracle": "0xA376b27212D608324808923Add679A2c9FAFe9Da", + "testRecipient": "0xeF7F4367703cdf4863AD6Be34C1627d8b1C2D67a", + "timelockController": "0x0000000000000000000000000000000000000000", + "validatorAnnounce": "0x1196055C61af3e3DA6f8458B07b255a72b64Bcf7" + }, + "treasure": { + "blockExplorers": [ + { + "apiUrl": "https://rpc-explorer-verify.treasure.lol/contract_verification", + "family": "etherscan", + "name": "Treasurescan", + "url": "https://treasurescan.io" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 1, + "reorgPeriod": 0 + }, + "chainId": 61166, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "Treasure", + "domainId": 61166, + "gasCurrencyCoinGeckoId": "magic", + "name": "treasure", + "nativeToken": { + "decimals": 18, + "name": "MAGIC", + "symbol": "MAGIC" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://rpc.treasure.lol" + } + ], + "technicalStack": "zksync", + "domainRoutingIsm": "0xCDfE1782fDC9E74810D3B69E971d752bC4b4D6E6", + "domainRoutingIsmFactory": "0x0000000000000000000000000000000000000000", + "fallbackDomainRoutingHook": "0x697a90753B7dCf6512189c239E612fC12baaE500", + "fallbackRoutingHook": "0x697a90753B7dCf6512189c239E612fC12baaE500", + "interchainGasPaymaster": "0x388289cd5862e17AAfD6ffF7F46A9Ec48a969bCd", + "interchainSecurityModule": "0xCDfE1782fDC9E74810D3B69E971d752bC4b4D6E6", + "mailbox": "0x9BbDf86b272d224323136E15594fdCe487F40ce7", + "merkleTreeHook": "0xc1FC99Ea4D8B2b06b674A2e91b5A4617c1dcFd22", + "proxyAdmin": "0x038F9F4e93e88Af2C688da265222FdE80e455aA4", + "staticAggregationHookFactory": "0x0000000000000000000000000000000000000000", + "staticAggregationIsmFactory": "0x0000000000000000000000000000000000000000", + "staticMerkleRootMultisigIsmFactory": "0x0000000000000000000000000000000000000000", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0000000000000000000000000000000000000000", + "staticMessageIdMultisigIsmFactory": "0x0000000000000000000000000000000000000000", + "staticMessageIdWeightedMultisigIsmFactory": "0x0000000000000000000000000000000000000000", + "storageGasOracle": "0xc364cfedefE854c1275B0f4088EaFA9695e1FC56", + "testRecipient": "0x54E88f2ab58E0Ab4B7Ce081FB20D85b16af041d2", + "validatorAnnounce": "0x73a82061Cd258d02BEa145fe183120456e718c2A", + "index": { + "from": 1552 + } + }, + "zklink": { + "blockExplorers": [ + { + "apiUrl": "https://explorer.zklink.io/contract_verification", + "family": "etherscan", + "name": "zkLink Nova Block Explorer", + "url": "https://explorer.zklink.io" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 1, + "reorgPeriod": 0 + }, + "chainId": 810180, + "deployer": { + "name": "Abacus Works", + "url": "https://www.hyperlane.xyz" + }, + "displayName": "zkLink Nova", + "displayNameShort": "zkLink", + "domainId": 810180, + "gasCurrencyCoinGeckoId": "ethereum", + "name": "zklink", + "nativeToken": { + "decimals": 18, + "name": "Ethereum", + "symbol": "ETH" + }, + "protocol": "ethereum", + "rpcUrls": [ + { + "http": "https://rpc.zklink.io" + }, + { + "http": "https://rpc.zklink.network" + } + ], + "technicalStack": "zksync", + "domainRoutingIsm": "0xc364cfedefE854c1275B0f4088EaFA9695e1FC56", + "domainRoutingIsmFactory": "0x0000000000000000000000000000000000000000", + "fallbackDomainRoutingHook": "0x388289cd5862e17AAfD6ffF7F46A9Ec48a969bCd", + "fallbackRoutingHook": "0x388289cd5862e17AAfD6ffF7F46A9Ec48a969bCd", + "interchainGasPaymaster": "0xB35eCb9714e8f48332Af22B48C18ca21E2607438", + "interchainSecurityModule": "0xc364cfedefE854c1275B0f4088EaFA9695e1FC56", + "mailbox": "0x9BbDf86b272d224323136E15594fdCe487F40ce7", + "merkleTreeHook": "0xA1ADFCa9666Bcd68b7b5C8b55e3ecC465DcDfE65", + "proxyAdmin": "0x038F9F4e93e88Af2C688da265222FdE80e455aA4", + "staticAggregationHookFactory": "0x0000000000000000000000000000000000000000", + "staticAggregationIsmFactory": "0x0000000000000000000000000000000000000000", + "staticMerkleRootMultisigIsmFactory": "0x0000000000000000000000000000000000000000", + "staticMerkleRootWeightedMultisigIsmFactory": "0x0000000000000000000000000000000000000000", + "staticMessageIdMultisigIsmFactory": "0x0000000000000000000000000000000000000000", + "staticMessageIdWeightedMultisigIsmFactory": "0x0000000000000000000000000000000000000000", + "storageGasOracle": "0x73a82061Cd258d02BEa145fe183120456e718c2A", + "testRecipient": "0x58e8699b8e0a2A3ba40b380038f64F0B3ef4f2e5", + "validatorAnnounce": "0xf5626c0f33Ca102eb3ca1633A410cd8aa92909e4", + "index": { + "from": 7286869 + } } }, "defaultRpcConsensusType": "fallback" diff --git a/rust/main/config/test_sealevel_config.json b/rust/main/config/test_sealevel_config.json index 5eebd592a3..7b7cc1c8a7 100644 --- a/rust/main/config/test_sealevel_config.json +++ b/rust/main/config/test_sealevel_config.json @@ -15,7 +15,7 @@ }, "rpcUrls": [ { - "http": "http://localhost:8899" + "http": "http://127.0.0.1:8899" } ], "index": { @@ -38,7 +38,7 @@ }, "rpcUrls": [ { - "http": "http://localhost:8899" + "http": "http://127.0.0.1:8899" } ], "index": { diff --git a/rust/main/ethers-prometheus/src/middleware/mod.rs b/rust/main/ethers-prometheus/src/middleware/mod.rs index cb3fd16cf4..5b82912cbf 100644 --- a/rust/main/ethers-prometheus/src/middleware/mod.rs +++ b/rust/main/ethers-prometheus/src/middleware/mod.rs @@ -227,7 +227,6 @@ impl Middleware for PrometheusMiddleware { ) -> Result, Self::Error> { let start = Instant::now(); let tx: TypedTransaction = tx.into(); - let chain = { let data = self.conf.read().await; chain_name(&data.chain).to_owned() diff --git a/rust/main/hyperlane-base/src/settings/base.rs b/rust/main/hyperlane-base/src/settings/base.rs index 0320e4eb71..7024d67cc6 100644 --- a/rust/main/hyperlane-base/src/settings/base.rs +++ b/rust/main/hyperlane-base/src/settings/base.rs @@ -151,13 +151,14 @@ impl Settings { build_contract_fns!(build_validator_announce, build_validator_announces -> dyn ValidatorAnnounce); build_contract_fns!(build_provider, build_providers -> dyn HyperlaneProvider); - /// Build a contract sync for type `T` using log store `D` + /// Build a contract sync for type `T` using log store `S` pub async fn sequenced_contract_sync( &self, domain: &HyperlaneDomain, metrics: &CoreMetrics, sync_metrics: &ContractSyncMetrics, store: Arc, + advanced_log_meta: bool, ) -> eyre::Result>> where T: Indexable + Debug, @@ -166,7 +167,8 @@ impl Settings { { let setup = self.chain_setup(domain)?; // Currently, all indexers are of the `SequenceIndexer` type - let indexer = SequenceIndexer::::try_from_with_metrics(setup, metrics).await?; + let indexer = + SequenceIndexer::::try_from_with_metrics(setup, metrics, advanced_log_meta).await?; Ok(Arc::new(ContractSync::new( domain.clone(), store.clone() as SequenceAwareLogStore<_>, @@ -175,13 +177,14 @@ impl Settings { ))) } - /// Build a contract sync for type `T` using log store `D` + /// Build a contract sync for type `T` using log store `S` pub async fn watermark_contract_sync( &self, domain: &HyperlaneDomain, metrics: &CoreMetrics, sync_metrics: &ContractSyncMetrics, store: Arc, + advanced_log_meta: bool, ) -> eyre::Result>> where T: Indexable + Debug, @@ -190,7 +193,8 @@ impl Settings { { let setup = self.chain_setup(domain)?; // Currently, all indexers are of the `SequenceIndexer` type - let indexer = SequenceIndexer::::try_from_with_metrics(setup, metrics).await?; + let indexer = + SequenceIndexer::::try_from_with_metrics(setup, metrics, advanced_log_meta).await?; Ok(Arc::new(ContractSync::new( domain.clone(), store.clone() as WatermarkLogStore<_>, @@ -208,6 +212,7 @@ impl Settings { metrics: &CoreMetrics, sync_metrics: &ContractSyncMetrics, stores: HashMap>, + advanced_log_meta: bool, ) -> Result>>> where T: Indexable + Debug + Send + Sync + Clone + Eq + Hash + 'static, @@ -220,26 +225,10 @@ impl Settings { // TODO: parallelize these calls again let mut syncs = vec![]; for domain in domains { - let sync = match T::indexing_cursor(domain.domain_protocol()) { - CursorType::SequenceAware => self - .sequenced_contract_sync( - domain, - metrics, - sync_metrics, - stores.get(domain).unwrap().clone(), - ) - .await - .map(|r| r as Arc>)?, - CursorType::RateLimited => self - .watermark_contract_sync( - domain, - metrics, - sync_metrics, - stores.get(domain).unwrap().clone(), - ) - .await - .map(|r| r as Arc>)?, - }; + let store = stores.get(domain).unwrap().clone(); + let sync = self + .contract_sync(domain, metrics, sync_metrics, store, advanced_log_meta) + .await?; syncs.push(sync); } @@ -248,4 +237,36 @@ impl Settings { .map(|i| Ok((i.domain().clone(), i))) .collect() } + + /// Build single contract sync. + /// All contracts have to implement both sequenced and + /// watermark trait bounds + pub async fn contract_sync( + &self, + domain: &HyperlaneDomain, + metrics: &CoreMetrics, + sync_metrics: &ContractSyncMetrics, + store: Arc, + advanced_log_meta: bool, + ) -> Result>> + where + T: Indexable + Debug + Send + Sync + Clone + Eq + Hash + 'static, + SequenceIndexer: TryFromWithMetrics, + S: HyperlaneLogStore + + HyperlaneSequenceAwareIndexerStoreReader + + HyperlaneWatermarkedLogStore + + 'static, + { + let sync = match T::indexing_cursor(domain.domain_protocol()) { + CursorType::SequenceAware => self + .sequenced_contract_sync(domain, metrics, sync_metrics, store, advanced_log_meta) + .await + .map(|r| r as Arc>)?, + CursorType::RateLimited => self + .watermark_contract_sync(domain, metrics, sync_metrics, store, advanced_log_meta) + .await + .map(|r| r as Arc>)?, + }; + Ok(sync) + } } diff --git a/rust/main/hyperlane-base/src/settings/chains.rs b/rust/main/hyperlane-base/src/settings/chains.rs index 0e08b2d156..33600418bb 100644 --- a/rust/main/hyperlane-base/src/settings/chains.rs +++ b/rust/main/hyperlane-base/src/settings/chains.rs @@ -33,7 +33,11 @@ use super::ChainSigner; #[async_trait] pub trait TryFromWithMetrics: Sized { /// Try to convert the chain configuration into the type - async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result; + async fn try_from_with_metrics( + conf: &ChainConf, + metrics: &CoreMetrics, + advanced_log_meta: bool, + ) -> Result; } /// A chain setup is a domain ID, an address on that chain (where the mailbox is @@ -72,22 +76,38 @@ pub type MerkleTreeHookIndexer = Arc for MessageIndexer { - async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result { - conf.build_message_indexer(metrics).await.map(Into::into) + async fn try_from_with_metrics( + conf: &ChainConf, + metrics: &CoreMetrics, + advanced_log_meta: bool, + ) -> Result { + conf.build_message_indexer(metrics, advanced_log_meta) + .await + .map(Into::into) } } #[async_trait] impl TryFromWithMetrics for DeliveryIndexer { - async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result { - conf.build_delivery_indexer(metrics).await.map(Into::into) + async fn try_from_with_metrics( + conf: &ChainConf, + metrics: &CoreMetrics, + advanced_log_meta: bool, + ) -> Result { + conf.build_delivery_indexer(metrics, advanced_log_meta) + .await + .map(Into::into) } } #[async_trait] impl TryFromWithMetrics for IgpIndexer { - async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result { - conf.build_interchain_gas_payment_indexer(metrics) + async fn try_from_with_metrics( + conf: &ChainConf, + metrics: &CoreMetrics, + advanced_log_meta: bool, + ) -> Result { + conf.build_interchain_gas_payment_indexer(metrics, advanced_log_meta) .await .map(Into::into) } @@ -95,8 +115,12 @@ impl TryFromWithMetrics for IgpIndexer { #[async_trait] impl TryFromWithMetrics for MerkleTreeHookIndexer { - async fn try_from_with_metrics(conf: &ChainConf, metrics: &CoreMetrics) -> Result { - conf.build_merkle_tree_hook_indexer(metrics) + async fn try_from_with_metrics( + conf: &ChainConf, + metrics: &CoreMetrics, + advanced_log_meta: bool, + ) -> Result { + conf.build_merkle_tree_hook_indexer(metrics, advanced_log_meta) .await .map(Into::into) } @@ -266,6 +290,7 @@ impl ChainConf { pub async fn build_message_indexer( &self, metrics: &CoreMetrics, + advanced_log_meta: bool, ) -> Result>> { let ctx = "Building delivery indexer"; let locator = self.locator(self.addresses.mailbox); @@ -284,7 +309,11 @@ impl ChainConf { } ChainConnectionConf::Fuel(_) => todo!(), ChainConnectionConf::Sealevel(conf) => { - let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?); + let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new( + conf, + locator, + advanced_log_meta, + )?); Ok(indexer as Box>) } ChainConnectionConf::Cosmos(conf) => { @@ -306,6 +335,7 @@ impl ChainConf { pub async fn build_delivery_indexer( &self, metrics: &CoreMetrics, + advanced_log_meta: bool, ) -> Result>> { let ctx = "Building delivery indexer"; let locator = self.locator(self.addresses.mailbox); @@ -324,7 +354,11 @@ impl ChainConf { } ChainConnectionConf::Fuel(_) => todo!(), ChainConnectionConf::Sealevel(conf) => { - let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?); + let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new( + conf, + locator, + advanced_log_meta, + )?); Ok(indexer as Box>) } ChainConnectionConf::Cosmos(conf) => { @@ -385,6 +419,7 @@ impl ChainConf { pub async fn build_interchain_gas_payment_indexer( &self, metrics: &CoreMetrics, + advanced_log_meta: bool, ) -> Result>> { let ctx = "Building IGP indexer"; let locator = self.locator(self.addresses.interchain_gas_paymaster); @@ -407,7 +442,12 @@ impl ChainConf { ChainConnectionConf::Fuel(_) => todo!(), ChainConnectionConf::Sealevel(conf) => { let indexer = Box::new( - h_sealevel::SealevelInterchainGasPaymasterIndexer::new(conf, locator).await?, + h_sealevel::SealevelInterchainGasPaymasterIndexer::new( + conf, + locator, + advanced_log_meta, + ) + .await?, ); Ok(indexer as Box>) } @@ -428,6 +468,7 @@ impl ChainConf { pub async fn build_merkle_tree_hook_indexer( &self, metrics: &CoreMetrics, + advanced_log_meta: bool, ) -> Result>> { let ctx = "Building merkle tree hook indexer"; let locator = self.locator(self.addresses.merkle_tree_hook); @@ -446,8 +487,11 @@ impl ChainConf { } ChainConnectionConf::Fuel(_) => todo!(), ChainConnectionConf::Sealevel(conf) => { - let mailbox_indexer = - Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?); + let mailbox_indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new( + conf, + locator, + advanced_log_meta, + )?); let indexer = Box::new(h_sealevel::SealevelMerkleTreeHookIndexer::new( *mailbox_indexer, )); diff --git a/rust/main/hyperlane-base/src/settings/signers.rs b/rust/main/hyperlane-base/src/settings/signers.rs index 459a6337be..4233a5c692 100644 --- a/rust/main/hyperlane-base/src/settings/signers.rs +++ b/rust/main/hyperlane-base/src/settings/signers.rs @@ -126,10 +126,9 @@ impl BuildableWithSignerConf for Keypair { if let SignerConf::HexKey { key } = conf { let secret = SecretKey::from_bytes(key.as_bytes()) .context("Invalid sealevel ed25519 secret key")?; - Ok( - Keypair::from_bytes(&ed25519_dalek::Keypair::from(secret).to_bytes()) - .context("Unable to create Keypair")?, - ) + let public = ed25519_dalek::PublicKey::from(&secret); + let dalek = ed25519_dalek::Keypair { secret, public }; + Ok(Keypair::from_bytes(&dalek.to_bytes()).context("Unable to create Keypair")?) } else { bail!(format!("{conf:?} key is not supported by sealevel")); } diff --git a/rust/main/utils/run-locally/src/config.rs b/rust/main/utils/run-locally/src/config.rs index 476a10725d..c03f859ba8 100644 --- a/rust/main/utils/run-locally/src/config.rs +++ b/rust/main/utils/run-locally/src/config.rs @@ -1,6 +1,7 @@ use std::env; use std::sync::Arc; +#[derive(Debug)] pub struct Config { pub is_ci_env: bool, pub ci_mode: bool, diff --git a/rust/main/utils/run-locally/src/invariants/termination_invariants.rs b/rust/main/utils/run-locally/src/invariants/termination_invariants.rs index 248daec844..cb851af8d2 100644 --- a/rust/main/utils/run-locally/src/invariants/termination_invariants.rs +++ b/rust/main/utils/run-locally/src/invariants/termination_invariants.rs @@ -92,9 +92,12 @@ pub fn termination_invariants_met( // EDIT: Having had a quick look, it seems like there are some legitimate reverts happening in the confirm step // (`Transaction attempting to process message either reverted or was reorged`) // in which case more gas expenditure logs than messages are expected. + let gas_expenditure_log_count = log_counts.get(GAS_EXPENDITURE_LOG_MESSAGE).unwrap(); assert!( - log_counts.get(GAS_EXPENDITURE_LOG_MESSAGE).unwrap() >= &total_messages_expected, - "Didn't record gas payment for all delivered messages" + gas_expenditure_log_count >= &total_messages_expected, + "Didn't record gas payment for all delivered messages. Got {} gas payment logs, expected at least {}", + gas_expenditure_log_count, + total_messages_expected ); // These tests check that we fixed https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/3915, where some logs would not show up assert!( @@ -123,16 +126,6 @@ pub fn termination_invariants_met( "Verbose logs not expected at the log level set in e2e" ); - let gas_payment_sealevel_events_count = fetch_metric( - RELAYER_METRICS_PORT, - "hyperlane_contract_sync_stored_events", - &hashmap! { - "data_type" => "gas_payments", - "chain" => "sealeveltest", - }, - )? - .iter() - .sum::(); // TestSendReceiver randomly breaks gas payments up into // two. So we expect at least as many gas payments as messages. if gas_payment_events_count < total_messages_expected { @@ -160,11 +153,12 @@ pub fn termination_invariants_met( )? .iter() .sum::(); - if dispatched_messages_scraped != eth_messages_expected + ZERO_MERKLE_INSERTION_KATHY_MESSAGES { + if dispatched_messages_scraped != total_messages_expected + ZERO_MERKLE_INSERTION_KATHY_MESSAGES + { log!( "Scraper has scraped {} dispatched messages, expected {}", dispatched_messages_scraped, - eth_messages_expected + total_messages_expected + ZERO_MERKLE_INSERTION_KATHY_MESSAGES, ); return Ok(false); } @@ -176,15 +170,11 @@ pub fn termination_invariants_met( )? .iter() .sum::(); - // The relayer and scraper should have the same number of gas payments. - // TODO: Sealevel gas payments are not yet included in the event count. - // For now, treat as an exception in the invariants. - let expected_gas_payments = gas_payment_events_count - gas_payment_sealevel_events_count; - if gas_payments_scraped != expected_gas_payments { + if gas_payments_scraped != gas_payment_events_count { log!( "Scraper has scraped {} gas payments, expected {}", gas_payments_scraped, - expected_gas_payments + gas_payment_events_count ); return Ok(false); } @@ -196,11 +186,11 @@ pub fn termination_invariants_met( )? .iter() .sum::(); - if delivered_messages_scraped != eth_messages_expected { + if delivered_messages_scraped != total_messages_expected { log!( "Scraper has scraped {} delivered messages, expected {}", delivered_messages_scraped, - eth_messages_expected + total_messages_expected ); return Ok(false); } diff --git a/rust/main/utils/run-locally/src/main.rs b/rust/main/utils/run-locally/src/main.rs index ac91660633..4686c15446 100644 --- a/rust/main/utils/run-locally/src/main.rs +++ b/rust/main/utils/run-locally/src/main.rs @@ -153,6 +153,8 @@ fn main() -> ExitCode { .unwrap(); let config = Config::load(); + log!("Running with config: {:?}", config); + let mut validator_origin_chains = ["test1", "test2", "test3"].to_vec(); let mut validator_keys = ETH_VALIDATOR_KEYS.to_vec(); let mut validator_count: usize = validator_keys.len(); @@ -286,12 +288,19 @@ fn main() -> ExitCode { .hyp_env("CHAINS_TEST2_CUSTOMRPCURLS", "http://127.0.0.1:8545") .hyp_env("CHAINS_TEST3_RPCCONSENSUSTYPE", "quorum") .hyp_env("CHAINS_TEST3_CUSTOMRPCURLS", "http://127.0.0.1:8545") - .hyp_env("CHAINSTOSCRAPE", "test1,test2,test3") .hyp_env("METRICSPORT", SCRAPER_METRICS_PORT) .hyp_env( "DB", "postgresql://postgres:47221c18c610@localhost:5432/postgres", ); + let scraper_env = if config.sealevel_enabled { + scraper_env.hyp_env( + "CHAINSTOSCRAPE", + "test1,test2,test3,sealeveltest1,sealeveltest2", + ) + } else { + scraper_env.hyp_env("CHAINSTOSCRAPE", "test1,test2,test3") + }; let mut state = State::default(); diff --git a/rust/rust-toolchain b/rust/rust-toolchain deleted file mode 100644 index 83e24cc566..0000000000 --- a/rust/rust-toolchain +++ /dev/null @@ -1,3 +0,0 @@ -[toolchain] -channel = "1.72.1" -profile = "default" diff --git a/rust/sealevel/Cargo.lock b/rust/sealevel/Cargo.lock index 81beeb35b3..7462ad6c98 100644 --- a/rust/sealevel/Cargo.lock +++ b/rust/sealevel/Cargo.lock @@ -743,9 +743,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -1254,6 +1254,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "dialoguer" version = "0.10.4" @@ -1405,7 +1425,8 @@ dependencies = [ [[package]] name = "ed25519-dalek" version = "1.0.1" -source = "git+https://github.com/Eclipse-Laboratories-Inc/ed25519-dalek?branch=main#7529d65506147b6cb24ca6d8f4fc062cac33b395" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", "ed25519", @@ -2385,7 +2406,7 @@ dependencies = [ "bytes", "convert_case 0.6.0", "derive-new", - "derive_more", + "derive_more 0.99.17", "eyre", "fixed-hash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "getrandom 0.2.15", @@ -4538,26 +4559,26 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.3" +version = "2.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" +checksum = "1aa7ffc1c0ef49b0452c6e2986abf2b07743320641ffd5fc63d552458e3b779b" dependencies = [ "cfg-if", - "derive_more", + "derive_more 1.0.0", "parity-scale-codec", "scale-info-derive", ] [[package]] name = "scale-info-derive" -version = "2.11.3" +version = "2.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" +checksum = "46385cc24172cf615450267463f937c10072516359b3ff1cb24228a4a08bf951" dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2 1.0.86", "quote 1.0.37", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -4903,7 +4924,7 @@ dependencies = [ [[package]] name = "solana-account-decoder" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "Inflector", "base64 0.13.1", @@ -4927,7 +4948,7 @@ dependencies = [ [[package]] name = "solana-address-lookup-table-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "bytemuck", @@ -4947,7 +4968,7 @@ dependencies = [ [[package]] name = "solana-banks-client" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "borsh", "futures", @@ -4963,7 +4984,7 @@ dependencies = [ [[package]] name = "solana-banks-interface" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "serde", "solana-sdk", @@ -4973,7 +4994,7 @@ dependencies = [ [[package]] name = "solana-banks-server" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "crossbeam-channel", @@ -4992,7 +5013,7 @@ dependencies = [ [[package]] name = "solana-bpf-loader-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "byteorder", @@ -5010,7 +5031,7 @@ dependencies = [ [[package]] name = "solana-bucket-map" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "log", "memmap2", @@ -5024,7 +5045,7 @@ dependencies = [ [[package]] name = "solana-clap-utils" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "chrono", "clap 2.34.0", @@ -5041,7 +5062,7 @@ dependencies = [ [[package]] name = "solana-cli-config" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "dirs-next", "lazy_static", @@ -5056,7 +5077,7 @@ dependencies = [ [[package]] name = "solana-client" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "async-mutex", "async-trait", @@ -5109,7 +5130,7 @@ dependencies = [ [[package]] name = "solana-compute-budget-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "solana-program-runtime", "solana-sdk", @@ -5118,7 +5139,7 @@ dependencies = [ [[package]] name = "solana-config-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "chrono", @@ -5131,7 +5152,7 @@ dependencies = [ [[package]] name = "solana-faucet" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "byteorder", @@ -5154,7 +5175,7 @@ dependencies = [ [[package]] name = "solana-frozen-abi" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "ahash", "blake3", @@ -5187,7 +5208,7 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "proc-macro2 1.0.86", "quote 1.0.37", @@ -5198,7 +5219,7 @@ dependencies = [ [[package]] name = "solana-logger" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "env_logger 0.9.3", "lazy_static", @@ -5208,7 +5229,7 @@ dependencies = [ [[package]] name = "solana-measure" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "log", "solana-sdk", @@ -5217,7 +5238,7 @@ dependencies = [ [[package]] name = "solana-metrics" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "crossbeam-channel", "gethostname", @@ -5230,7 +5251,7 @@ dependencies = [ [[package]] name = "solana-net-utils" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "clap 3.2.25", @@ -5251,7 +5272,7 @@ dependencies = [ [[package]] name = "solana-perf" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "ahash", "bincode", @@ -5277,7 +5298,7 @@ dependencies = [ [[package]] name = "solana-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "base64 0.13.1", "bincode", @@ -5325,7 +5346,7 @@ dependencies = [ [[package]] name = "solana-program-runtime" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "base64 0.13.1", "bincode", @@ -5351,7 +5372,7 @@ dependencies = [ [[package]] name = "solana-program-test" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "assert_matches", "async-trait", @@ -5375,7 +5396,7 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "lazy_static", "num_cpus", @@ -5384,7 +5405,7 @@ dependencies = [ [[package]] name = "solana-remote-wallet" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "console", "dialoguer", @@ -5402,7 +5423,7 @@ dependencies = [ [[package]] name = "solana-runtime" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "arrayref", "bincode", @@ -5462,7 +5483,7 @@ dependencies = [ [[package]] name = "solana-sdk" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "assert_matches", "base64 0.13.1", @@ -5512,7 +5533,7 @@ dependencies = [ [[package]] name = "solana-sdk-macro" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bs58 0.4.0", "proc-macro2 1.0.86", @@ -5524,7 +5545,7 @@ dependencies = [ [[package]] name = "solana-send-transaction-service" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "crossbeam-channel", "log", @@ -5538,7 +5559,7 @@ dependencies = [ [[package]] name = "solana-stake-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "log", @@ -5560,7 +5581,7 @@ dependencies = [ [[package]] name = "solana-streamer" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "crossbeam-channel", "futures-util", @@ -5588,7 +5609,7 @@ dependencies = [ [[package]] name = "solana-transaction-status" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "Inflector", "base64 0.13.1", @@ -5616,7 +5637,7 @@ dependencies = [ [[package]] name = "solana-version" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "log", "rustc_version", @@ -5631,7 +5652,7 @@ dependencies = [ [[package]] name = "solana-vote-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bincode", "log", @@ -5651,7 +5672,7 @@ dependencies = [ [[package]] name = "solana-zk-token-proof-program" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bytemuck", "getrandom 0.1.16", @@ -5665,7 +5686,7 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" version = "1.14.13" -source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2023-07-04#62a6421cab862c77b9ac7a8d93f54f8b5b223af7" +source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "aes-gcm-siv", "arrayref", @@ -6304,9 +6325,9 @@ checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.5.0", "toml_datetime", @@ -6943,9 +6964,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] diff --git a/rust/sealevel/Cargo.toml b/rust/sealevel/Cargo.toml index 5887dc8d17..145b9bfcc2 100644 --- a/rust/sealevel/Cargo.toml +++ b/rust/sealevel/Cargo.toml @@ -256,11 +256,6 @@ branch = "v3.2.2-relax-zeroize" git = "https://github.com/Eclipse-Laboratories-Inc/curve25519-dalek" version = "3.2.2" -[patch.crates-io.ed25519-dalek] -branch = "main" -git = "https://github.com/Eclipse-Laboratories-Inc/ed25519-dalek" -version = "1.0.1" - [patch.crates-io.primitive-types] branch = "hyperlane" git = "https://github.com/hyperlane-xyz/parity-common.git" @@ -273,62 +268,52 @@ version = "=0.5.2" [patch.crates-io.solana-account-decoder] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-banks-client] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" -version = "=1.14.13" - -[patch.crates-io.solana-banks-interface] -git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" -version = "=1.14.13" - -[patch.crates-io.solana-banks-server] -git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-clap-utils] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-cli-config] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-client] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-program] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-program-test] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-sdk] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-transaction-status] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.solana-zk-token-sdk] git = "https://github.com/hyperlane-xyz/solana.git" -tag = "hyperlane-1.14.13-2023-07-04" +tag = "hyperlane-1.14.13-2024-11-20" version = "=1.14.13" [patch.crates-io.spl-associated-token-account] diff --git a/rust/sealevel/client/src/cmd_utils.rs b/rust/sealevel/client/src/cmd_utils.rs index e0cd3ff686..f387d3c4fd 100644 --- a/rust/sealevel/client/src/cmd_utils.rs +++ b/rust/sealevel/client/src/cmd_utils.rs @@ -17,6 +17,23 @@ use solana_sdk::{ const SOLANA_DOMAIN: u32 = 1399811149; +pub(crate) fn get_compute_unit_price_micro_lamports_for_id(domain: u32) -> u64 { + get_compute_unit_price(domain == SOLANA_DOMAIN) +} + +pub(crate) fn get_compute_unit_price_micro_lamports_for_chain_name(chain_name: &str) -> u64 { + get_compute_unit_price(chain_name == "solanamainnet") +} + +fn get_compute_unit_price(is_solanamainnet: bool) -> u64 { + if is_solanamainnet { + // Generally taking a low/medium value from https://www.quicknode.com/gas-tracker/solana + 500_000 + } else { + 0 + } +} + pub(crate) fn account_exists(client: &RpcClient, account: &Pubkey) -> Result { // Using `get_account_with_commitment` instead of `get_account` so we get Ok(None) when the account // doesn't exist, rather than an error @@ -73,9 +90,9 @@ pub(crate) fn deploy_program( program_keypair_path, ]; + let compute_unit_price = get_compute_unit_price_micro_lamports_for_id(local_domain).to_string(); if local_domain.eq(&SOLANA_DOMAIN) { - // May need tweaking depending on gas prices / available balance - command.append(&mut vec!["--with-compute-unit-price", "550000"]); + command.extend(vec!["--with-compute-unit-price", &compute_unit_price]); } build_cmd(command.as_slice(), None, None); diff --git a/rust/sealevel/client/src/core.rs b/rust/sealevel/client/src/core.rs index 44cf9cb529..e3abedf035 100644 --- a/rust/sealevel/client/src/core.rs +++ b/rust/sealevel/client/src/core.rs @@ -9,26 +9,21 @@ use solana_sdk::{compute_budget, compute_budget::ComputeBudgetInstruction}; use std::collections::HashMap; use std::{fs::File, path::Path}; +use crate::cmd_utils::get_compute_unit_price_micro_lamports_for_chain_name; +use crate::ONE_SOL_IN_LAMPORTS; use crate::{ artifacts::{read_json, write_json}, cmd_utils::{create_and_write_keypair, create_new_directory, deploy_program}, multisig_ism::deploy_multisig_ism_message_id, Context, CoreCmd, CoreDeploy, CoreSubCmd, }; -use crate::{DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT, ONE_SOL_IN_LAMPORTS}; use hyperlane_core::H256; use hyperlane_sealevel_igp::accounts::{SOL_DECIMALS, TOKEN_EXCHANGE_RATE_SCALE}; pub(crate) fn adjust_gas_price_if_needed(chain_name: &str, ctx: &mut Context) { if chain_name.eq("solanamainnet") { + let compute_unit_price = get_compute_unit_price_micro_lamports_for_chain_name(chain_name); let mut initial_instructions = ctx.initial_instructions.borrow_mut(); - const PROCESS_DESIRED_PRIORITIZATION_FEE_LAMPORTS_PER_TX: u64 = 50_000_000; - const MICRO_LAMPORT_FEE_PER_LIMIT: u64 = - // Convert to micro-lamports - (PROCESS_DESIRED_PRIORITIZATION_FEE_LAMPORTS_PER_TX * 1_000_000) - // Divide by the max compute units - / DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64; - for i in initial_instructions.iter_mut() { if i.instruction.program_id != compute_budget::id() { continue; @@ -41,9 +36,8 @@ pub(crate) fn adjust_gas_price_if_needed(chain_name: &str, ctx: &mut Context) { ComputeBudgetInstruction::SetComputeUnitPrice { .. } ) { // The compute unit price has already been set, so we override it and return early - i.instruction = ComputeBudgetInstruction::set_compute_unit_price( - MICRO_LAMPORT_FEE_PER_LIMIT, - ); + i.instruction = + ComputeBudgetInstruction::set_compute_unit_price(compute_unit_price); return; } } @@ -51,10 +45,10 @@ pub(crate) fn adjust_gas_price_if_needed(chain_name: &str, ctx: &mut Context) { initial_instructions.push( ( - ComputeBudgetInstruction::set_compute_unit_price(MICRO_LAMPORT_FEE_PER_LIMIT), + ComputeBudgetInstruction::set_compute_unit_price(compute_unit_price), Some(format!( - "Set compute unit price to {}", - MICRO_LAMPORT_FEE_PER_LIMIT + "Set compute unit price to {} micro-lamports", + compute_unit_price )), ) .into(), diff --git a/rust/sealevel/environments/local-e2e/chain-config.json b/rust/sealevel/environments/local-e2e/chain-config.json index eadbdf9404..5dd2834a36 100644 --- a/rust/sealevel/environments/local-e2e/chain-config.json +++ b/rust/sealevel/environments/local-e2e/chain-config.json @@ -4,7 +4,7 @@ "name": "sealeveltest1", "rpcUrls": [ { - "http": "http://localhost:8899" + "http": "http://127.0.0.1:8899" } ] }, @@ -13,7 +13,7 @@ "name": "sealeveltest2", "rpcUrls": [ { - "http": "http://localhost:8899" + "http": "http://127.0.0.1:8899" } ] } diff --git a/rust/sealevel/environments/mainnet3/warp-routes/apxETH-eclipse-ethereum/program-ids.json b/rust/sealevel/environments/mainnet3/warp-routes/apxETH-eclipse-ethereum/program-ids.json new file mode 100644 index 0000000000..683a275abb --- /dev/null +++ b/rust/sealevel/environments/mainnet3/warp-routes/apxETH-eclipse-ethereum/program-ids.json @@ -0,0 +1,10 @@ +{ + "eclipsemainnet": { + "hex": "0x82f7445ccda6396092998c8f841f0d4eb63cca29ba23cfd2609d283f3ee9d13f", + "base58": "9pEgj7m2VkwLtJHPtTw5d8vbB7kfjzcXXCRgdwruW7C2" + }, + "ethereum": { + "hex": "0x000000000000000000000000d34fe1685c28a68bb4b8faaadcb2769962ae737c", + "base58": "1111111111113wkPRLXCJuj9539UEURsN3qhoaYb" + } +} diff --git a/rust/sealevel/environments/mainnet3/warp-routes/apxETH-eclipse-ethereum/token-config.json b/rust/sealevel/environments/mainnet3/warp-routes/apxETH-eclipse-ethereum/token-config.json new file mode 100644 index 0000000000..1634a20d35 --- /dev/null +++ b/rust/sealevel/environments/mainnet3/warp-routes/apxETH-eclipse-ethereum/token-config.json @@ -0,0 +1,17 @@ +{ + "eclipsemainnet": { + "type": "synthetic", + "decimals": 9, + "remoteDecimals": 18, + "name": "Autocompounding Pirex Ether", + "symbol": "apxETH", + "uri": "https://raw.githubusercontent.com/hyperlane-xyz/hyperlane-registry/ae7df1bc00af19f8ba692c14e4df3acdbf30497d/deployments/warp_routes/APXETH/metadata.json", + "interchainGasPaymaster": "3Wp4qKkgf4tjXz1soGyTSndCgBPLZFSrZkiDZ8Qp9EEj" + }, + "ethereum": { + "type": "collateral", + "decimals": 18, + "token": "0x9ba021b0a9b958b5e75ce9f6dff97c7ee52cb3e6", + "foreignDeployment": "0xd34FE1685c28A68Bb4B8fAaadCb2769962AE737c" + } +} diff --git a/rust/sealevel/environments/mainnet3/warp-routes/ezSOL-eclipse-solana/program-ids.json b/rust/sealevel/environments/mainnet3/warp-routes/ezSOL-eclipse-solana/program-ids.json new file mode 100644 index 0000000000..5a914d4f2c --- /dev/null +++ b/rust/sealevel/environments/mainnet3/warp-routes/ezSOL-eclipse-solana/program-ids.json @@ -0,0 +1,10 @@ +{ + "eclipsemainnet": { + "hex": "0xb06d58417c929a624e9b689e604e6d60ca652168ee76b9a290bd5b974b22b306", + "base58": "CshTfxXWMvnRAwBTCjQ4577bkP5po5ZuNG1QTuQxA5Au" + }, + "solanamainnet": { + "hex": "0x08bb318b88b38cc6f450b185e51a9c42402dc9d36fa6741c19c2aa62464a5eb3", + "base58": "b5pMgizA9vrGRt3hVqnU7vUVGBQUnLpwPzcJhG1ucyQ" + } +} diff --git a/rust/sealevel/environments/mainnet3/warp-routes/ezSOL-eclipse-solana/token-config.json b/rust/sealevel/environments/mainnet3/warp-routes/ezSOL-eclipse-solana/token-config.json new file mode 100644 index 0000000000..eef5c8349b --- /dev/null +++ b/rust/sealevel/environments/mainnet3/warp-routes/ezSOL-eclipse-solana/token-config.json @@ -0,0 +1,17 @@ +{ + "solanamainnet": { + "type": "collateral", + "decimals": 9, + "interchainGasPaymaster": "AkeHBbE5JkwVppujCQQ6WuxsVsJtruBAjUo6fDCFp6fF", + "token": "ezSoL6fY1PVdJcJsUpe5CM3xkfmy3zoVCABybm5WtiC", + "splTokenProgram": "token" + }, + "eclipsemainnet": { + "type": "synthetic", + "decimals": 9, + "name": "Renzo Restaked SOL", + "symbol": "ezSOL", + "uri": "https://raw.githubusercontent.com/hyperlane-xyz/hyperlane-registry/ae7df1bc00af19f8ba692c14e4df3acdbf30497d/deployments/warp_routes/EZSOL/metadata.json", + "interchainGasPaymaster": "3Wp4qKkgf4tjXz1soGyTSndCgBPLZFSrZkiDZ8Qp9EEj" + } +} diff --git a/rust/sealevel/libraries/test-utils/src/igp.rs b/rust/sealevel/libraries/test-utils/src/igp.rs index 70e5100067..3ff20da1b3 100644 --- a/rust/sealevel/libraries/test-utils/src/igp.rs +++ b/rust/sealevel/libraries/test-utils/src/igp.rs @@ -49,7 +49,7 @@ pub async fn initialize_igp_accounts( GasOracle::RemoteGasData(RemoteGasData { token_exchange_rate: TOKEN_EXCHANGE_RATE_SCALE, gas_price: 1u128, - /// The number of decimals for the remote token. + // The number of decimals for the remote token. token_decimals: SOL_DECIMALS, }), None, diff --git a/rust/sealevel/rust-toolchain b/rust/sealevel/rust-toolchain index 83e24cc566..1c8cfba9f5 100644 --- a/rust/sealevel/rust-toolchain +++ b/rust/sealevel/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "1.72.1" +channel = "1.75.0" profile = "default" diff --git a/solidity/CHANGELOG.md b/solidity/CHANGELOG.md index 0ba5c201ec..a0babee028 100644 --- a/solidity/CHANGELOG.md +++ b/solidity/CHANGELOG.md @@ -1,5 +1,18 @@ # @hyperlane-xyz/core +## 5.8.3 + +### Patch Changes + +- @hyperlane-xyz/utils@7.3.0 + +## 5.8.2 + +### Patch Changes + +- Updated dependencies [fa6d5f5c6] + - @hyperlane-xyz/utils@7.2.0 + ## 5.8.1 ### Patch Changes diff --git a/solidity/contracts/PackageVersioned.sol b/solidity/contracts/PackageVersioned.sol index 476985336d..ced404fe92 100644 --- a/solidity/contracts/PackageVersioned.sol +++ b/solidity/contracts/PackageVersioned.sol @@ -7,5 +7,5 @@ pragma solidity >=0.6.11; **/ abstract contract PackageVersioned { // GENERATED CODE - DO NOT EDIT - string public constant PACKAGE_VERSION = "5.8.1"; + string public constant PACKAGE_VERSION = "5.8.3"; } diff --git a/solidity/package.json b/solidity/package.json index 3133af1718..b80646bd24 100644 --- a/solidity/package.json +++ b/solidity/package.json @@ -1,14 +1,14 @@ { "name": "@hyperlane-xyz/core", "description": "Core solidity contracts for Hyperlane", - "version": "5.8.1", + "version": "5.8.3", "dependencies": { "@arbitrum/nitro-contracts": "^1.2.1", "@eth-optimism/contracts": "^0.6.0", - "@hyperlane-xyz/utils": "7.1.0", + "@hyperlane-xyz/utils": "7.3.0", "@layerzerolabs/lz-evm-oapp-v2": "2.0.2", "@openzeppelin/contracts": "^4.9.3", - "@openzeppelin/contracts-upgradeable": "^v4.9.3", + "@openzeppelin/contracts-upgradeable": "^4.9.3", "fx-portal": "^1.0.3" }, "devDependencies": { @@ -19,7 +19,7 @@ "@typechain/ethers-v6": "^0.5.1", "@typechain/hardhat": "^9.1.0", "@types/node": "^18.14.5", - "chai": "4.5.0", + "chai": "^4.5.0", "ethereum-waffle": "^4.0.10", "ethers": "^5.7.2", "hardhat": "^2.22.2", diff --git a/typescript/ccip-server/.eslintrc b/typescript/ccip-server/.eslintrc deleted file mode 100644 index 05936cd4e4..0000000000 --- a/typescript/ccip-server/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "no-console": ["off"] - } - } - \ No newline at end of file diff --git a/typescript/ccip-server/CHANGELOG.md b/typescript/ccip-server/CHANGELOG.md index 5bfabb5d48..a259236246 100644 --- a/typescript/ccip-server/CHANGELOG.md +++ b/typescript/ccip-server/CHANGELOG.md @@ -1,5 +1,9 @@ # @hyperlane-xyz/ccip-server +## 7.3.0 + +## 7.2.0 + ## 7.1.0 ## 7.0.0 diff --git a/typescript/ccip-server/eslint.config.mjs b/typescript/ccip-server/eslint.config.mjs new file mode 100644 index 0000000000..17cd27a740 --- /dev/null +++ b/typescript/ccip-server/eslint.config.mjs @@ -0,0 +1,17 @@ +import MonorepoDefaults from '../../eslint.config.mjs'; + +export default [ + ...MonorepoDefaults, + { + files: ['./src/**/*.ts'], + }, + { + rules: { + 'no-console': ['off'], + 'no-restricted-imports': ['off'], + }, + }, + { + ignores: ['**/__mocks__/*','**/tests/*',] + } +]; diff --git a/typescript/ccip-server/package.json b/typescript/ccip-server/package.json index 9089365167..0795edf956 100644 --- a/typescript/ccip-server/package.json +++ b/typescript/ccip-server/package.json @@ -1,6 +1,6 @@ { "name": "@hyperlane-xyz/ccip-server", - "version": "7.1.0", + "version": "7.3.0", "description": "CCIP server", "typings": "dist/index.d.ts", "typedocMain": "src/index.ts", @@ -12,27 +12,30 @@ "node": ">=16" }, "scripts": { + "build": "tsc -p tsconfig.json", "start": "tsx src/server.ts", "dev": "nodemon src/server.ts", "test": "jest", + "lint": "eslint -c ./eslint.config.mjs", "prettier": "prettier --write ./src/* ./tests/" }, "author": "brolee", "license": "Apache-2.0", "devDependencies": { "@jest/globals": "^29.7.0", - "@types/node": "^16.9.1", + "@types/node": "^18.14.5", + "eslint": "^9.15.0", "jest": "^29.7.0", "nodemon": "^3.0.3", "prettier": "^2.8.8", "ts-jest": "^29.1.2", "ts-node": "^10.8.0", - "tsx": "^4.7.1", + "tsx": "^4.19.1", "typescript": "5.3.3" }, "dependencies": { "@chainlink/ccip-read-server": "^0.2.1", "dotenv-flow": "^4.1.0", - "ethers": "5.7.2" + "ethers": "^5.7.2" } } diff --git a/typescript/ccip-server/src/server.ts b/typescript/ccip-server/src/server.ts index 0f69c499f4..4151b98644 100644 --- a/typescript/ccip-server/src/server.ts +++ b/typescript/ccip-server/src/server.ts @@ -6,12 +6,14 @@ import { ProofsService } from './services/ProofsService'; // Initialize Services const proofsService = new ProofsService( - config.LIGHT_CLIENT_ADDR, - config.RPC_ADDRESS, - config.STEP_FN_ID, - config.CHAIN_ID, - config.SUCCINCT_PLATFORM_URL, - config.SUCCINCT_API_KEY, + { + lightClientAddress: config.LIGHT_CLIENT_ADDR, + stepFunctionId: config.STEP_FN_ID, + platformUrl: config.SUCCINCT_PLATFORM_URL, + apiKey: config.SUCCINCT_API_KEY, + }, + { url: config.RPC_ADDRESS, chainId: config.CHAIN_ID }, + { url: `${config.SERVER_URL_PREFIX}:${config.SERVER_PORT}` }, ); // Initialize Server and add Service handlers diff --git a/typescript/ccip-server/src/services/LightClientService.ts b/typescript/ccip-server/src/services/LightClientService.ts index f3aae5b097..4511229669 100644 --- a/typescript/ccip-server/src/services/LightClientService.ts +++ b/typescript/ccip-server/src/services/LightClientService.ts @@ -27,8 +27,8 @@ class LightClientService { * @param slot * @returns */ - async getSyncCommitteePoseidons(slot: bigint): Promise { - return await this.lightClientContract.syncCommitteePoseidons( + getSyncCommitteePoseidons(slot: bigint): Promise { + return this.lightClientContract.syncCommitteePoseidons( this.getSyncCommitteePeriod(slot), ); } diff --git a/typescript/ccip-server/src/services/ProofsService.ts b/typescript/ccip-server/src/services/ProofsService.ts index 1d05e7a3f7..5db40c5648 100644 --- a/typescript/ccip-server/src/services/ProofsService.ts +++ b/typescript/ccip-server/src/services/ProofsService.ts @@ -4,8 +4,7 @@ import { TelepathyCcipReadIsmAbi } from '../abis/TelepathyCcipReadIsmAbi'; import { HyperlaneService } from './HyperlaneService'; import { LightClientService, SuccinctConfig } from './LightClientService'; -import { RPCService } from './RPCService'; -import { ProofResult } from './RPCService'; +import { ProofResult, RPCService } from './RPCService'; import { ProofStatus } from './common/ProofStatusEnum'; type RPCConfig = { @@ -100,10 +99,7 @@ class ProofsService { ); const slot = await this.lightClientService.calculateSlot(BigInt(timestamp)); const syncCommitteePoseidon = ''; // TODO get from LC - return await this.lightClientService.requestProof( - syncCommitteePoseidon, - slot, - ); + return this.lightClientService.requestProof(syncCommitteePoseidon, slot); } /** diff --git a/typescript/ccip-server/tsconfig.json b/typescript/ccip-server/tsconfig.json new file mode 100644 index 0000000000..793d16b8e4 --- /dev/null +++ b/typescript/ccip-server/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "./dist/", + "rootDir": "./src" + }, + "exclude": ["./node_modules/", "./dist/"], + "include": ["./src/*.ts"] +} diff --git a/typescript/cli/.eslintignore b/typescript/cli/.eslintignore deleted file mode 100644 index 76add878f8..0000000000 --- a/typescript/cli/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -dist \ No newline at end of file diff --git a/typescript/cli/.eslintrc b/typescript/cli/.eslintrc deleted file mode 100644 index 4d2a6fe74f..0000000000 --- a/typescript/cli/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "no-console": ["off"], - "no-restricted-imports": ["off"] - } -} diff --git a/typescript/cli/CHANGELOG.md b/typescript/cli/CHANGELOG.md index 9e82984e47..a7d9962b84 100644 --- a/typescript/cli/CHANGELOG.md +++ b/typescript/cli/CHANGELOG.md @@ -1,5 +1,48 @@ # @hyperlane-xyz/cli +## 7.3.0 + +### Minor Changes + +- aa1ea9a48: updates the warp deployment config schema to be closer to the ica routing schema +- 323f0f158: Add ICAs management in core apply command + +### Patch Changes + +- 455a897fb: Fix a bug where it would try to relay the incorrect message from a transaction that dispatches multiple messages. +- Updated dependencies [2054f4f5b] +- Updated dependencies [a96448fa6] +- Updated dependencies [170a0fc73] +- Updated dependencies [9a09afcc7] +- Updated dependencies [24784af95] +- Updated dependencies [3e8dd70ac] +- Updated dependencies [aa1ea9a48] +- Updated dependencies [665a7b8d8] +- Updated dependencies [f0b98fdef] +- Updated dependencies [ff9e8a72b] +- Updated dependencies [97c1f80b7] +- Updated dependencies [323f0f158] +- Updated dependencies [61157097b] + - @hyperlane-xyz/sdk@7.3.0 + - @hyperlane-xyz/utils@7.3.0 + +## 7.2.0 + +### Minor Changes + +- d51815760: Support using the CLI to deploy warp routes that involve foreign deployments +- 81ab4332f: Remove ismFactoryAddresses from warpConfig +- 4b3537470: Changed the type of defaultMultisigConfigs, to track validator aliases in addition to their addresses. + +### Patch Changes + +- Updated dependencies [81ab4332f] +- Updated dependencies [4b3537470] +- Updated dependencies [fa6d5f5c6] +- Updated dependencies [fa6d5f5c6] + - @hyperlane-xyz/sdk@7.2.0 + - @hyperlane-xyz/utils@7.2.0 + ## 7.1.0 ### Minor Changes diff --git a/typescript/cli/eslint.config.mjs b/typescript/cli/eslint.config.mjs new file mode 100644 index 0000000000..30f5895c6a --- /dev/null +++ b/typescript/cli/eslint.config.mjs @@ -0,0 +1,20 @@ +import MonorepoDefaults from '../../eslint.config.mjs'; + +export default [ + ...MonorepoDefaults, + { + files: ['./src/**/*.ts', './cli.ts', './env.ts'], + }, + { + rules: { + 'no-console': ['off'], + 'no-restricted-imports': ['off'], + }, + }, + { + ignores: ['./src/tests/**/*.ts'], + rules: { + 'import/no-cycle': ['off'], + }, + }, +]; diff --git a/typescript/cli/package.json b/typescript/cli/package.json index aead4269af..48f7d80596 100644 --- a/typescript/cli/package.json +++ b/typescript/cli/package.json @@ -1,16 +1,16 @@ { "name": "@hyperlane-xyz/cli", - "version": "7.1.0", + "version": "7.3.0", "description": "A command-line utility for common Hyperlane operations", "dependencies": { "@aws-sdk/client-kms": "^3.577.0", "@aws-sdk/client-s3": "^3.577.0", - "@hyperlane-xyz/registry": "6.1.0", - "@hyperlane-xyz/sdk": "7.1.0", - "@hyperlane-xyz/utils": "7.1.0", + "@hyperlane-xyz/registry": "6.3.0", + "@hyperlane-xyz/sdk": "7.3.0", + "@hyperlane-xyz/utils": "7.3.0", "@inquirer/core": "9.0.10", "@inquirer/figures": "1.0.5", - "@inquirer/prompts": "^3.0.0", + "@inquirer/prompts": "3.3.2", "ansi-escapes": "^7.0.0", "asn1.js": "^5.4.1", "bignumber.js": "^9.1.1", @@ -18,7 +18,7 @@ "ethers": "^5.7.2", "latest-version": "^8.0.0", "terminal-link": "^3.0.0", - "tsx": "^4.7.1", + "tsx": "^4.19.1", "yaml": "2.4.5", "yargs": "^17.7.2", "zod": "^3.21.2", @@ -26,18 +26,21 @@ "zx": "^8.1.4" }, "devDependencies": { + "@eslint/js": "^9.15.0", "@ethersproject/abi": "*", "@ethersproject/providers": "*", "@types/chai-as-promised": "^8", "@types/mocha": "^10.0.1", "@types/node": "^18.14.5", "@types/yargs": "^17.0.24", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", + "@typescript-eslint/eslint-plugin": "^8.1.6", + "@typescript-eslint/parser": "^8.1.6", "chai": "^4.5.0", "chai-as-promised": "^8.0.0", - "eslint": "^8.57.0", + "eslint": "^9.15.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import": "^2.31.0", "mocha": "^10.2.0", "prettier": "^2.8.8", "typescript": "5.3.3" @@ -47,7 +50,7 @@ "build": "yarn version:update && tsc", "dev": "yarn version:update && tsc --watch", "clean": "rm -rf ./dist", - "lint": "eslint . --ext .ts", + "lint": "eslint -c ./eslint.config.mjs", "prettier": "prettier --write ./src ./examples", "test:ci": "yarn mocha --config .mocharc.json", "test:e2e": "./scripts/run-e2e-test.sh", diff --git a/typescript/cli/src/avs/check.ts b/typescript/cli/src/avs/check.ts index 6730463e62..27055c6848 100644 --- a/typescript/cli/src/avs/check.ts +++ b/typescript/cli/src/avs/check.ts @@ -429,7 +429,7 @@ const getEcdsaStakeRegistryAddress = ( ): Address | undefined => { try { return avsAddresses[chain]['ecdsaStakeRegistry']; - } catch (err) { + } catch { topLevelErrors.push( `❗️ EcdsaStakeRegistry address not found for ${chain}`, ); diff --git a/typescript/cli/src/check/warp.ts b/typescript/cli/src/check/warp.ts index a31fac62e4..f0d147a468 100644 --- a/typescript/cli/src/check/warp.ts +++ b/typescript/cli/src/check/warp.ts @@ -4,7 +4,6 @@ import { WarpRouteDeployConfig, normalizeConfig } from '@hyperlane-xyz/sdk'; import { ObjectDiff, diffObjMerge } from '@hyperlane-xyz/utils'; import { log, logGreen } from '../logger.js'; -import '../utils/output.js'; import { formatYamlViolationsOutput } from '../utils/output.js'; export async function runWarpRouteCheck({ diff --git a/typescript/cli/src/commands/core.ts b/typescript/cli/src/commands/core.ts index 60d84f8776..a75f6ae61e 100644 --- a/typescript/cli/src/commands/core.ts +++ b/typescript/cli/src/commands/core.ts @@ -82,7 +82,7 @@ export const apply: CommandModuleWithWriteContext<{ )) as DeployedCoreAddresses; DeployedCoreAddressesSchema.parse(addresses); - const config = await readCoreDeployConfigs(configFilePath); + const config = readCoreDeployConfigs(configFilePath); await runCoreApply({ context, @@ -171,6 +171,7 @@ export const read: CommandModuleWithContext<{ chain: string; config: string; mailbox?: string; + interchainAccountRouter?: string; }> = { command: 'read', describe: 'Reads onchain Core configuration for a given mailbox address', @@ -192,7 +193,11 @@ export const read: CommandModuleWithContext<{ handler: async ({ context, chain, mailbox, config: configFilePath }) => { logCommandHeader('Hyperlane Core Read'); - const coreConfig = await executeCoreRead({ context, chain, mailbox }); + const coreConfig = await executeCoreRead({ + context, + chain, + mailbox, + }); writeYamlOrJson(configFilePath, coreConfig, 'yaml'); logGreen(`✅ Core config written successfully to ${configFilePath}:\n`); @@ -222,7 +227,7 @@ export const check: CommandModuleWithContext<{ }, config: inputFileCommandOption({ defaultPath: DEFAULT_CORE_DEPLOYMENT_CONFIG_PATH, - description: 'The path to a a Core Config JSON or YAML file.', + description: 'The path to a Core Config JSON or YAML file.', demandOption: false, }), }, diff --git a/typescript/cli/src/commands/relayer.ts b/typescript/cli/src/commands/relayer.ts index 0d7672e734..c07a4d4120 100644 --- a/typescript/cli/src/commands/relayer.ts +++ b/typescript/cli/src/commands/relayer.ts @@ -9,7 +9,7 @@ import { Address } from '@hyperlane-xyz/utils'; import { CommandModuleWithContext } from '../context/types.js'; import { log } from '../logger.js'; import { tryReadJson, writeJson } from '../utils/files.js'; -import { getWarpCoreConfigOrExit } from '../utils/input.js'; +import { getWarpCoreConfigOrExit } from '../utils/warp.js'; import { agentTargetsCommandOption, diff --git a/typescript/cli/src/commands/warp.ts b/typescript/cli/src/commands/warp.ts index c2f4916b01..3cd99fe6a0 100644 --- a/typescript/cli/src/commands/warp.ts +++ b/typescript/cli/src/commands/warp.ts @@ -23,8 +23,8 @@ import { removeEndingSlash, writeYamlOrJson, } from '../utils/files.js'; -import { getWarpCoreConfigOrExit } from '../utils/input.js'; import { selectRegistryWarpRoute } from '../utils/tokens.js'; +import { getWarpCoreConfigOrExit } from '../utils/warp.js'; import { runVerifyWarpRoute } from '../verify/warp.js'; import { diff --git a/typescript/cli/src/config/agent.ts b/typescript/cli/src/config/agent.ts index 05fa165596..a176a6f040 100644 --- a/typescript/cli/src/config/agent.ts +++ b/typescript/cli/src/config/agent.ts @@ -99,7 +99,7 @@ async function getStartBlocks( try { const deployedBlock = await mailbox.deployedBlock(); return deployedBlock.toNumber(); - } catch (err) { + } catch { errorRed( `❌ Failed to get deployed block to set an index for ${chain}, this is potentially an issue with rpc provider or a misconfiguration`, ); diff --git a/typescript/cli/src/config/core.ts b/typescript/cli/src/config/core.ts index 92e6fc6882..c7161f6b4b 100644 --- a/typescript/cli/src/config/core.ts +++ b/typescript/cli/src/config/core.ts @@ -1,6 +1,7 @@ import { stringify as yamlStringify } from 'yaml'; import { + CoreConfig, CoreConfigSchema, HookConfig, IsmConfig, @@ -95,7 +96,7 @@ export async function createCoreDeployConfig({ } } -export async function readCoreDeployConfigs(filePath: string) { +export function readCoreDeployConfigs(filePath: string): CoreConfig { const config = readYamlOrJson(filePath); return CoreConfigSchema.parse(config); } diff --git a/typescript/cli/src/config/multisig.ts b/typescript/cli/src/config/multisig.ts index 28648b2717..ae645de80f 100644 --- a/typescript/cli/src/config/multisig.ts +++ b/typescript/cli/src/config/multisig.ts @@ -1,7 +1,7 @@ import { confirm, input } from '@inquirer/prompts'; import { z } from 'zod'; -import { ChainMap, MultisigConfig, ZHash } from '@hyperlane-xyz/sdk'; +import { ChainMap, MultisigIsmConfig, ZHash } from '@hyperlane-xyz/sdk'; import { Address, isValidAddress, @@ -33,7 +33,7 @@ export function readMultisigConfig(filePath: string) { ); } const parsedConfig = result.data; - const formattedConfig: ChainMap = objMap( + const formattedConfig: ChainMap> = objMap( parsedConfig, (_, config) => { if (config.threshold > config.validators.length) @@ -50,7 +50,7 @@ export function readMultisigConfig(filePath: string) { return { threshold: config.threshold, validators: validators, - } as MultisigConfig; + }; }, ); logGreen(`All multisig configs in ${filePath} are valid`); diff --git a/typescript/cli/src/config/submit.ts b/typescript/cli/src/config/submit.ts index 3b7e3c59e7..6ce067a8a0 100644 --- a/typescript/cli/src/config/submit.ts +++ b/typescript/cli/src/config/submit.ts @@ -3,9 +3,8 @@ import { stringify as yamlStringify } from 'yaml'; import { AnnotatedEV5Transaction, SubmissionStrategy, - getChainIdFromTxs, } from '@hyperlane-xyz/sdk'; -import { assert, errorToString } from '@hyperlane-xyz/utils'; +import { ProtocolType, assert, errorToString } from '@hyperlane-xyz/utils'; import { WriteCommandContext } from '../context/types.js'; import { logGray, logRed } from '../logger.js'; @@ -27,17 +26,15 @@ export async function runSubmit({ receiptsFilepath: string; submissionStrategy: SubmissionStrategy; }) { - const { chainMetadata, multiProvider } = context; + const { multiProvider } = context; assert( submissionStrategy, 'Submission strategy required to submit transactions.\nPlease create a submission strategy. See examples in cli/examples/submit/strategy/*.', ); const transactions = getTransactions(transactionsFilepath); - const chainId = getChainIdFromTxs(transactions); - const protocol = chainMetadata[chainId].protocol; - const submitterBuilder = await getSubmitterBuilder({ + const submitterBuilder = await getSubmitterBuilder({ submissionStrategy, multiProvider, }); diff --git a/typescript/cli/src/deploy/core.ts b/typescript/cli/src/deploy/core.ts index 28ff4d50e5..06d08b13cd 100644 --- a/typescript/cli/src/deploy/core.ts +++ b/typescript/cli/src/deploy/core.ts @@ -1,12 +1,12 @@ import { stringify as yamlStringify } from 'yaml'; import { buildArtifact as coreBuildArtifact } from '@hyperlane-xyz/core/buildArtifact.js'; -import { DeployedCoreAddresses } from '@hyperlane-xyz/sdk'; import { ChainMap, ChainName, ContractVerifier, CoreConfig, + DeployedCoreAddresses, EvmCoreModule, ExplorerLicenseType, } from '@hyperlane-xyz/sdk'; @@ -127,7 +127,11 @@ export async function runCoreApply(params: ApplyParams) { if (transactions.length) { logGray('Updating deployed core contracts'); for (const transaction of transactions) { - await multiProvider.sendTransaction(chain, transaction); + await multiProvider.sendTransaction( + // Using the provided chain id because there might be remote chain transactions included in the batch + transaction.chainId ?? chain, + transaction, + ); } logGreen(`Core config updated on ${chain}.`); diff --git a/typescript/cli/src/deploy/dry-run.ts b/typescript/cli/src/deploy/dry-run.ts index f821dc179f..fa0c309725 100644 --- a/typescript/cli/src/deploy/dry-run.ts +++ b/typescript/cli/src/deploy/dry-run.ts @@ -5,12 +5,11 @@ import { resetFork, setFork, } from '@hyperlane-xyz/sdk'; +import { toUpperCamelCase } from '@hyperlane-xyz/utils'; import { logGray, logGreen, warnYellow } from '../logger.js'; import { ENV } from '../utils/env.js'; -import { toUpperCamelCase } from './utils.js'; - /** * Forks a provided network onto MultiProvider * @param multiProvider the MultiProvider to be prepared diff --git a/typescript/cli/src/deploy/utils.ts b/typescript/cli/src/deploy/utils.ts index d8ced32dc7..125e7b1e77 100644 --- a/typescript/cli/src/deploy/utils.ts +++ b/typescript/cli/src/deploy/utils.ts @@ -169,10 +169,6 @@ export async function completeDeploy( if (isDryRun) await completeDryRun(command); } -export function toUpperCamelCase(string: string) { - return string.charAt(0).toUpperCase() + string.slice(1); -} - function transformChainMetadataForDisplay(chainMetadata: ChainMetadata) { return { Name: chainMetadata.name, diff --git a/typescript/cli/src/deploy/warp.ts b/typescript/cli/src/deploy/warp.ts index 508e18f69e..018244700a 100644 --- a/typescript/cli/src/deploy/warp.ts +++ b/typescript/cli/src/deploy/warp.ts @@ -2,8 +2,9 @@ import { confirm } from '@inquirer/prompts'; import { groupBy } from 'lodash-es'; import { stringify as yamlStringify } from 'yaml'; +import { ProxyAdmin__factory } from '@hyperlane-xyz/core'; import { buildArtifact as coreBuildArtifact } from '@hyperlane-xyz/core/buildArtifact.js'; -import { IRegistry } from '@hyperlane-xyz/registry'; +import { ChainAddresses } from '@hyperlane-xyz/registry'; import { AggregationIsmConfig, AnnotatedEV5Transaction, @@ -15,22 +16,24 @@ import { DestinationGas, EvmERC20WarpModule, EvmERC20WarpRouteReader, + EvmHookModule, EvmIsmModule, ExplorerLicenseType, + HookConfig, HypERC20Deployer, HypERC20Factories, HypERC721Deployer, HypERC721Factories, - HyperlaneAddresses, + HypTokenRouterConfig, HyperlaneContracts, HyperlaneContractsMap, HyperlaneProxyFactoryDeployer, + IsmConfig, IsmType, MultiProvider, MultisigIsmConfig, OpStackIsmConfig, PausableIsmConfig, - ProxyFactoryFactoriesAddresses, RemoteRouters, RoutingIsmConfig, SubmissionStrategy, @@ -47,9 +50,8 @@ import { connectContractsMap, getTokenConnectionId, hypERC20factories, - isCollateralConfig, + isCollateralTokenConfig, isTokenMetadata, - serializeContracts, } from '@hyperlane-xyz/sdk'; import { Address, @@ -136,16 +138,24 @@ export async function runWarpRouteDeploy({ await runDeployPlanStep(deploymentParams); + // Some of the below functions throw if passed non-EVM chains + const ethereumChains = chains.filter( + (chain) => chainMetadata[chain].protocol === ProtocolType.Ethereum, + ); + await runPreflightChecksForChains({ context, - chains, + chains: ethereumChains, minGas: MINIMUM_WARP_DEPLOY_GAS, }); const userAddress = await signer.getAddress(); - const initialBalances = await prepareDeploy(context, userAddress, chains); - + const initialBalances = await prepareDeploy( + context, + userAddress, + ethereumChains, + ); const deployedContracts = await executeDeploy(deploymentParams, apiKeys); const warpCoreConfig = await getWarpCoreConfig( @@ -155,7 +165,13 @@ export async function runWarpRouteDeploy({ await writeDeploymentArtifacts(warpCoreConfig, context); - await completeDeploy(context, 'warp', initialBalances, userAddress, chains); + await completeDeploy( + context, + 'warp', + initialBalances, + userAddress, + ethereumChains, + ); } async function runDeployPlanStep({ context, warpDeployConfig }: DeployParams) { @@ -179,7 +195,7 @@ async function executeDeploy( const { warpDeployConfig, - context: { registry, multiProvider, isDryRun, dryRunChain }, + context: { multiProvider, isDryRun, dryRunChain }, } = params; const deployer = warpDeployConfig.isNft @@ -204,11 +220,10 @@ async function executeDeploy( ); // For each chain in WarpRouteConfig, deploy each Ism Factory, if it's not in the registry - // Then return a modified config with the ism address as a string - const modifiedConfig = await deployAndResolveWarpIsm( + // Then return a modified config with the ism and/or hook address as a string + const modifiedConfig = await resolveWarpIsmAndHook( config, - multiProvider, - registry, + params.context, ismFactoryDeployer, contractVerifier, ); @@ -230,71 +245,38 @@ async function writeDeploymentArtifacts( log(indentYamlOrJson(yamlStringify(warpCoreConfig, null, 2), 4)); } -async function deployAndResolveWarpIsm( +async function resolveWarpIsmAndHook( warpConfig: WarpRouteDeployConfig, - multiProvider: MultiProvider, - registry: IRegistry, + context: WriteCommandContext, ismFactoryDeployer: HyperlaneProxyFactoryDeployer, contractVerifier?: ContractVerifier, ): Promise { return promiseObjAll( objMap(warpConfig, async (chain, config) => { - if ( - !config.interchainSecurityModule || - typeof config.interchainSecurityModule === 'string' - ) { - logGray( - `Config Ism is ${ - !config.interchainSecurityModule - ? 'empty' - : config.interchainSecurityModule - }, skipping deployment.`, - ); - return config; - } - - logBlue(`Loading registry factory addresses for ${chain}...`); - let chainAddresses = await registry.getChainAddresses(chain); + const chainAddresses = await context.registry.getChainAddresses(chain); if (!chainAddresses) { - logGray( - `Registry factory addresses not found for ${chain}. Deploying...`, - ); - chainAddresses = serializeContracts( - await ismFactoryDeployer.deployContracts(chain), - ) as Record; + throw `Registry factory addresses not found for ${chain}.`; } - logGray( - `Creating ${config.interchainSecurityModule.type} ISM for ${config.type} token on ${chain} chain...`, - ); - - const deployedIsm = await createWarpIsm( + config.interchainSecurityModule = await createWarpIsm({ chain, - warpConfig, - multiProvider, - { - domainRoutingIsmFactory: chainAddresses.domainRoutingIsmFactory, - staticAggregationHookFactory: - chainAddresses.staticAggregationHookFactory, - staticAggregationIsmFactory: - chainAddresses.staticAggregationIsmFactory, - staticMerkleRootMultisigIsmFactory: - chainAddresses.staticMerkleRootMultisigIsmFactory, - staticMessageIdMultisigIsmFactory: - chainAddresses.staticMessageIdMultisigIsmFactory, - staticMerkleRootWeightedMultisigIsmFactory: - chainAddresses.staticMerkleRootWeightedMultisigIsmFactory, - staticMessageIdWeightedMultisigIsmFactory: - chainAddresses.staticMessageIdWeightedMultisigIsmFactory, - }, + chainAddresses, + context, contractVerifier, - ); + ismFactoryDeployer, + warpConfig: config, + }); // TODO write test - logGreen( - `Finished creating ${config.interchainSecurityModule.type} ISM for ${config.type} token on ${chain} chain.`, - ); - return { ...warpConfig[chain], interchainSecurityModule: deployedIsm }; + config.hook = await createWarpHook({ + chain, + chainAddresses, + context, + contractVerifier, + ismFactoryDeployer, + warpConfig: config, + }); + return config; }), ); } @@ -304,14 +286,45 @@ async function deployAndResolveWarpIsm( * * @returns The deployed ism address */ -async function createWarpIsm( - chain: string, - warpConfig: WarpRouteDeployConfig, - multiProvider: MultiProvider, - factoryAddresses: HyperlaneAddresses, - contractVerifier?: ContractVerifier, -): Promise { +async function createWarpIsm({ + chain, + chainAddresses, + context, + contractVerifier, + warpConfig, +}: { + chain: string; + chainAddresses: Record; + context: WriteCommandContext; + contractVerifier?: ContractVerifier; + warpConfig: HypTokenRouterConfig; + ismFactoryDeployer: HyperlaneProxyFactoryDeployer; +}): Promise { + const { interchainSecurityModule } = warpConfig; + if ( + !interchainSecurityModule || + typeof interchainSecurityModule === 'string' + ) { + logGray( + `Config Ism is ${ + !interchainSecurityModule ? 'empty' : interchainSecurityModule + }, skipping deployment.`, + ); + return interchainSecurityModule; + } + + logBlue(`Loading registry factory addresses for ${chain}...`); + + logGray( + `Creating ${interchainSecurityModule.type} ISM for token on ${chain} chain...`, + ); + + logGreen( + `Finished creating ${interchainSecurityModule.type} ISM for token on ${chain} chain.`, + ); + const { + mailbox, domainRoutingIsmFactory, staticAggregationHookFactory, staticAggregationIsmFactory, @@ -319,11 +332,11 @@ async function createWarpIsm( staticMessageIdMultisigIsmFactory, staticMerkleRootWeightedMultisigIsmFactory, staticMessageIdWeightedMultisigIsmFactory, - } = factoryAddresses; + } = chainAddresses; const evmIsmModule = await EvmIsmModule.create({ chain, - multiProvider, - mailbox: warpConfig[chain].mailbox, + mailbox, + multiProvider: context.multiProvider, proxyFactoryFactories: { domainRoutingIsmFactory, staticAggregationHookFactory, @@ -333,13 +346,85 @@ async function createWarpIsm( staticMerkleRootWeightedMultisigIsmFactory, staticMessageIdWeightedMultisigIsmFactory, }, - config: warpConfig[chain].interchainSecurityModule!, + config: interchainSecurityModule, contractVerifier, }); const { deployedIsm } = evmIsmModule.serialize(); return deployedIsm; } +async function createWarpHook({ + chain, + chainAddresses, + context, + contractVerifier, + warpConfig, +}: { + chain: string; + chainAddresses: Record; + context: WriteCommandContext; + contractVerifier?: ContractVerifier; + warpConfig: HypTokenRouterConfig; + ismFactoryDeployer: HyperlaneProxyFactoryDeployer; +}): Promise { + const { hook } = warpConfig; + + if (!hook || typeof hook === 'string') { + logGray(`Config Hook is ${!hook ? 'empty' : hook}, skipping deployment.`); + return hook; + } + + logBlue(`Loading registry factory addresses for ${chain}...`); + + logGray(`Creating ${hook.type} Hook for token on ${chain} chain...`); + + const { + mailbox, + domainRoutingIsmFactory, + staticAggregationHookFactory, + staticAggregationIsmFactory, + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, + } = chainAddresses; + const proxyFactoryFactories = { + domainRoutingIsmFactory, + staticAggregationHookFactory, + staticAggregationIsmFactory, + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, + }; + + // If config.proxyadmin.address exists, then use that. otherwise deploy a new proxyAdmin + const proxyAdminAddress: Address = + warpConfig.proxyAdmin?.address ?? + ( + await context.multiProvider.handleDeploy( + chain, + new ProxyAdmin__factory(), + [], + ) + ).address; + + const evmHookModule = await EvmHookModule.create({ + chain, + multiProvider: context.multiProvider, + coreAddresses: { + mailbox, + proxyAdmin: proxyAdminAddress, + }, + config: hook, + contractVerifier, + proxyFactoryFactories, + }); + logGreen(`Finished creating ${hook.type} Hook for token on ${chain} chain.`); + const { deployedHook } = evmHookModule.serialize(); + return deployedHook; +} + async function getWarpCoreConfig( { warpDeployConfig, context }: DeployParams, contracts: HyperlaneContractsMap, @@ -385,7 +470,7 @@ function generateTokenConfigs( ): void { for (const [chainName, contract] of Object.entries(contracts)) { const config = warpDeployConfig[chainName]; - const collateralAddressOrDenom = isCollateralConfig(config) + const collateralAddressOrDenom = isCollateralTokenConfig(config) ? config.token // gets set in the above deriveTokenMetadata() : undefined; @@ -505,7 +590,6 @@ async function extendWarpRoute( const newDeployedContracts = await executeDeploy( { - // TODO: use EvmERC20WarpModule when it's ready context: params.context, warpDeployConfig: extendedConfigs, }, @@ -534,7 +618,8 @@ async function updateExistingWarpRoute( ) { logBlue('Updating deployed Warp Routes'); const { multiProvider, registry } = params.context; - const addresses = await registry.getAddresses(); + const registryAddresses = + (await registry.getAddresses()) as ChainMap; const contractVerifier = new ContractVerifier( multiProvider, apiKeys, @@ -553,16 +638,31 @@ async function updateExistingWarpRoute( `Missing artifacts for ${chain}. Probably new deployment. Skipping update...`, ); - config.ismFactoryAddresses = addresses[ - chain - ] as ProxyFactoryFactoriesAddresses; + const deployedTokenRoute = deployedConfig.addressOrDenom!; + const { + domainRoutingIsmFactory, + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticAggregationIsmFactory, + staticAggregationHookFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, + } = registryAddresses[chain]; + const evmERC20WarpModule = new EvmERC20WarpModule( multiProvider, { config, chain, addresses: { - deployedTokenRoute: deployedConfig.addressOrDenom!, + deployedTokenRoute, + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticAggregationIsmFactory, + staticAggregationHookFactory, + domainRoutingIsmFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, }, }, contractVerifier, @@ -646,7 +746,8 @@ async function enrollRemoteRouters( deployedContractsMap: HyperlaneContractsMap, ): Promise { logBlue(`Enrolling deployed routers with each other...`); - const { multiProvider } = params.context; + const { multiProvider, registry } = params.context; + const registryAddresses = await registry.getAddresses(); const deployedRoutersAddresses: ChainMap
= objMap( deployedContractsMap, (_, contracts) => getRouter(contracts).address, @@ -663,18 +764,37 @@ async function enrollRemoteRouters( objMap(deployedContractsMap, async (chain, contracts) => { await retryAsync(async () => { const router = getRouter(contracts); // Assume deployedContract always has 1 value - + const deployedTokenRoute = router.address; // Mutate the config.remoteRouters by setting it to all other routers to update const warpRouteReader = new EvmERC20WarpRouteReader( multiProvider, chain, ); const mutatedWarpRouteConfig = - await warpRouteReader.deriveWarpRouteConfig(router.address); + await warpRouteReader.deriveWarpRouteConfig(deployedTokenRoute); + const { + domainRoutingIsmFactory, + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticAggregationIsmFactory, + staticAggregationHookFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, + } = registryAddresses[chain]; + const evmERC20WarpModule = new EvmERC20WarpModule(multiProvider, { config: mutatedWarpRouteConfig, chain, - addresses: { deployedTokenRoute: router.address }, + addresses: { + deployedTokenRoute, + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticAggregationIsmFactory, + staticAggregationHookFactory, + domainRoutingIsmFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, + }, }); const otherChains = multiProvider @@ -683,8 +803,9 @@ async function enrollRemoteRouters( mutatedWarpRouteConfig.remoteRouters = otherChains.reduce((remoteRouters, otherChain) => { - remoteRouters[multiProvider.getDomainId(otherChain)] = - deployedRoutersAddresses[otherChain]; + remoteRouters[multiProvider.getDomainId(otherChain)] = { + address: deployedRoutersAddresses[otherChain], + }; return remoteRouters; }, {}); @@ -769,7 +890,7 @@ function displayWarpDeployPlan(deployConfig: WarpRouteDeployConfig) { } /* only used for transformIsmForDisplay type-sense */ -type IsmConfig = +type IsmDisplayConfig = | RoutingIsmConfig // type, owner, ownerOverrides, domain | AggregationIsmConfig // type, modules, threshold | MultisigIsmConfig // type, validators, threshold @@ -782,7 +903,7 @@ function transformDeployConfigForDisplay(deployConfig: WarpRouteDeployConfig) { const transformedDeployConfig = objMap(deployConfig, (chain, config) => { if (config.interchainSecurityModule) transformedIsmConfigs[chain] = transformIsmConfigForDisplay( - config.interchainSecurityModule as IsmConfig, + config.interchainSecurityModule as IsmDisplayConfig, ); return { @@ -802,7 +923,7 @@ function transformDeployConfigForDisplay(deployConfig: WarpRouteDeployConfig) { }; } -function transformIsmConfigForDisplay(ismConfig: IsmConfig): any[] { +function transformIsmConfigForDisplay(ismConfig: IsmDisplayConfig): any[] { const ismConfigs: any[] = []; switch (ismConfig.type) { case IsmType.AGGREGATION: @@ -812,7 +933,9 @@ function transformIsmConfigForDisplay(ismConfig: IsmConfig): any[] { Modules: 'See table(s) below.', }); ismConfig.modules.forEach((module) => { - ismConfigs.push(...transformIsmConfigForDisplay(module as IsmConfig)); + ismConfigs.push( + ...transformIsmConfigForDisplay(module as IsmDisplayConfig), + ); }); return ismConfigs; case IsmType.ROUTING: @@ -937,7 +1060,7 @@ async function getWarpApplySubmitter({ context: WriteCommandContext; strategyUrl?: string; }): Promise> { - const { chainMetadata, multiProvider } = context; + const { multiProvider } = context; const submissionStrategy: SubmissionStrategy = strategyUrl ? readChainSubmissionStrategy(strategyUrl)[chain] @@ -948,8 +1071,7 @@ async function getWarpApplySubmitter({ }, }; - const protocol = chainMetadata[chain].protocol; - return getSubmitterBuilder({ + return getSubmitterBuilder({ submissionStrategy, multiProvider, }); diff --git a/typescript/cli/src/read/core.ts b/typescript/cli/src/read/core.ts index b7f1f94b2d..76daa8e918 100644 --- a/typescript/cli/src/read/core.ts +++ b/typescript/cli/src/read/core.ts @@ -13,8 +13,8 @@ export async function executeCoreRead({ chain: ChainName; mailbox?: Address; }): Promise { + const addresses = await context.registry.getChainAddresses(chain); if (!mailbox) { - const addresses = await context.registry.getChainAddresses(chain); mailbox = addresses?.mailbox; assert( @@ -25,7 +25,10 @@ export async function executeCoreRead({ const evmCoreReader = new EvmCoreReader(context.multiProvider, chain); try { - return evmCoreReader.deriveCoreConfig(mailbox); + return evmCoreReader.deriveCoreConfig({ + mailbox, + interchainAccountRouter: addresses?.interchainAccountRouter, + }); } catch (e: any) { errorRed( `❌ Failed to read core config for mailbox ${mailbox} on ${chain}:`, diff --git a/typescript/cli/src/read/warp.ts b/typescript/cli/src/read/warp.ts index 9139d890c2..bd5d01e95e 100644 --- a/typescript/cli/src/read/warp.ts +++ b/typescript/cli/src/read/warp.ts @@ -15,7 +15,7 @@ import { isAddressEvm, objMap, promiseObjAll } from '@hyperlane-xyz/utils'; import { CommandContext } from '../context/types.js'; import { logGray, logRed, logTable } from '../logger.js'; -import { getWarpCoreConfigOrExit } from '../utils/input.js'; +import { getWarpCoreConfigOrExit } from '../utils/warp.js'; export async function runWarpRouteRead({ context, diff --git a/typescript/cli/src/send/message.ts b/typescript/cli/src/send/message.ts index 430d3b7bcf..f7d5eb4e15 100644 --- a/typescript/cli/src/send/message.ts +++ b/typescript/cli/src/send/message.ts @@ -97,7 +97,7 @@ async function executeDelivery({ destination, formattedRecipient, messageBody, - // override the the default hook (with IGP) for self-relay to avoid race condition with the production relayer + // override the default hook (with IGP) for self-relay to avoid race condition with the production relayer selfRelay ? chainAddresses[origin].merkleTreeHook : undefined, ); logBlue(`Sent message from ${origin} to ${recipient} on ${destination}.`); diff --git a/typescript/cli/src/status/message.ts b/typescript/cli/src/status/message.ts index 2c1e9af96c..5e22aec7b0 100644 --- a/typescript/cli/src/status/message.ts +++ b/typescript/cli/src/status/message.ts @@ -52,7 +52,7 @@ export async function checkMessageStatus({ } else { try { dispatchedReceipt = await core.getDispatchTx(origin, messageId); - } catch (e) { + } catch { logRed(`Failed to infer dispatch transaction for message ${messageId}`); dispatchTx = await input({ @@ -94,7 +94,11 @@ export async function checkMessageStatus({ const merkleAddress = chainAddresses[origin].merkleTreeHook; stubMerkleTreeConfig(relayer, origin, hookAddress, merkleAddress); - deliveredTx = await relayer.relayMessage(dispatchedReceipt); + deliveredTx = await relayer.relayMessage( + dispatchedReceipt, + undefined, + message, + ); } logGreen( diff --git a/typescript/cli/src/tests/commands/core.ts b/typescript/cli/src/tests/commands/core.ts index 24c9109744..5feabbe2cb 100644 --- a/typescript/cli/src/tests/commands/core.ts +++ b/typescript/cli/src/tests/commands/core.ts @@ -1,6 +1,6 @@ import { $ } from 'zx'; -import { CoreConfig } from '@hyperlane-xyz/sdk'; +import { DerivedCoreConfig } from '@hyperlane-xyz/sdk'; import { readYamlOrJson } from '../../utils/files.js'; @@ -56,7 +56,7 @@ export async function hyperlaneCoreApply( export async function readCoreConfig( chain: string, coreConfigPath: string, -): Promise { +): Promise { await hyperlaneCoreRead(chain, coreConfigPath); return readYamlOrJson(coreConfigPath); } diff --git a/typescript/cli/src/tests/commands/helpers.ts b/typescript/cli/src/tests/commands/helpers.ts index 8cb6be0278..c6bfdc9a7c 100644 --- a/typescript/cli/src/tests/commands/helpers.ts +++ b/typescript/cli/src/tests/commands/helpers.ts @@ -3,7 +3,7 @@ import { $ } from 'zx'; import { ERC20Test__factory, ERC4626Test__factory } from '@hyperlane-xyz/core'; import { ChainAddresses } from '@hyperlane-xyz/registry'; import { - TokenRouterConfig, + HypTokenRouterConfig, WarpCoreConfig, WarpCoreConfigSchema, } from '@hyperlane-xyz/sdk'; @@ -19,11 +19,29 @@ import { readWarpConfig, } from './warp.js'; -export const TEST_CONFIGS_PATH = './test-configs'; -export const REGISTRY_PATH = `${TEST_CONFIGS_PATH}/anvil`; +export const E2E_TEST_CONFIGS_PATH = './test-configs'; +export const REGISTRY_PATH = `${E2E_TEST_CONFIGS_PATH}/anvil`; +export const TEMP_PATH = '/tmp'; // /temp gets removed at the end of all-test.sh export const ANVIL_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; +export const E2E_TEST_BURN_ADDRESS = + '0x0000000000000000000000000000000000000001'; + +export const CHAIN_NAME_2 = 'anvil2'; +export const CHAIN_NAME_3 = 'anvil3'; + +export const EXAMPLES_PATH = './examples'; +export const CORE_CONFIG_PATH = `${EXAMPLES_PATH}/core-config.yaml`; +export const CORE_READ_CONFIG_PATH_2 = `${TEMP_PATH}/${CHAIN_NAME_2}/core-config-read.yaml`; +export const CHAIN_2_METADATA_PATH = `${REGISTRY_PATH}/chains/${CHAIN_NAME_2}/metadata.yaml`; +export const CHAIN_3_METADATA_PATH = `${REGISTRY_PATH}/chains/${CHAIN_NAME_3}/metadata.yaml`; + +export const WARP_CONFIG_PATH_EXAMPLE = `${EXAMPLES_PATH}/warp-route-deployment.yaml`; +export const WARP_CONFIG_PATH_2 = `${TEMP_PATH}/${CHAIN_NAME_2}/warp-route-deployment-anvil2.yaml`; +export const WARP_CORE_CONFIG_PATH_2 = `${REGISTRY_PATH}/deployments/warp_routes/ETH/anvil2-config.yaml`; + +export const DEFAULT_E2E_TEST_TIMEOUT = 100_000; // Long timeout since these tests can take a while /** * Retrieves the deployed Warp address from the Warp core config. @@ -74,7 +92,7 @@ export async function updateOwner( export async function extendWarpConfig(params: { chain: string; chainToExtend: string; - extendedConfig: TokenRouterConfig; + extendedConfig: HypTokenRouterConfig; warpCorePath: string; warpDeployPath: string; strategyUrl?: string; diff --git a/typescript/cli/src/tests/core-apply.e2e-test.ts b/typescript/cli/src/tests/core-apply.e2e-test.ts new file mode 100644 index 0000000000..27667fd719 --- /dev/null +++ b/typescript/cli/src/tests/core-apply.e2e-test.ts @@ -0,0 +1,260 @@ +import { expect } from 'chai'; +import { Signer, Wallet, ethers } from 'ethers'; + +import { ProxyAdmin__factory } from '@hyperlane-xyz/core'; +import { + ChainMetadata, + CoreConfig, + DerivedCoreConfig, + ProtocolFeeHookConfig, + randomAddress, +} from '@hyperlane-xyz/sdk'; +import { Address, Domain, addressToBytes32 } from '@hyperlane-xyz/utils'; + +import { readYamlOrJson, writeYamlOrJson } from '../utils/files.js'; + +import { + hyperlaneCoreApply, + hyperlaneCoreDeploy, + readCoreConfig, +} from './commands/core.js'; +import { + ANVIL_KEY, + CHAIN_2_METADATA_PATH, + CHAIN_3_METADATA_PATH, + CHAIN_NAME_2, + CHAIN_NAME_3, + CORE_CONFIG_PATH, + CORE_READ_CONFIG_PATH_2, + DEFAULT_E2E_TEST_TIMEOUT, + TEMP_PATH, +} from './commands/helpers.js'; + +const CORE_READ_CHAIN_2_CONFIG_PATH = `${TEMP_PATH}/${CHAIN_NAME_2}/core-config-read.yaml`; +const CORE_READ_CHAIN_3_CONFIG_PATH = `${TEMP_PATH}/${CHAIN_NAME_3}/core-config-read.yaml`; + +describe('hyperlane core apply e2e tests', async function () { + this.timeout(2 * DEFAULT_E2E_TEST_TIMEOUT); + + let signer: Signer; + let initialOwnerAddress: Address; + let chain2DomainId: Domain; + let chain3DomainId: Domain; + + before(async () => { + const chain2Metadata: ChainMetadata = readYamlOrJson(CHAIN_2_METADATA_PATH); + const chain3Metadata: ChainMetadata = readYamlOrJson(CHAIN_3_METADATA_PATH); + + const provider = new ethers.providers.JsonRpcProvider( + chain2Metadata.rpcUrls[0].http, + ); + + chain2DomainId = chain2Metadata.domainId; + chain3DomainId = chain3Metadata.domainId; + const wallet = new Wallet(ANVIL_KEY); + signer = wallet.connect(provider); + + initialOwnerAddress = await signer.getAddress(); + }); + + it('should update the mailbox owner', async () => { + await hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_CONFIG_PATH); + const coreConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + expect(coreConfig.owner).to.equal(initialOwnerAddress); + const newOwner = randomAddress().toLowerCase(); + coreConfig.owner = newOwner; + writeYamlOrJson(CORE_READ_CONFIG_PATH_2, coreConfig); + await hyperlaneCoreApply(CHAIN_NAME_2, CORE_READ_CONFIG_PATH_2); + // Verify that the owner has been set correctly without modifying any other owner values + const updatedConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + expect(updatedConfig.owner.toLowerCase()).to.equal(newOwner); + expect(updatedConfig.proxyAdmin?.owner).to.equal(initialOwnerAddress); + // Assuming that the ProtocolFeeHook is used for deployment + expect( + (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, + ).to.equal(initialOwnerAddress); + }); + + it('should update the ProxyAdmin to a new one for the mailbox', async () => { + await hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_CONFIG_PATH); + const coreConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + expect(coreConfig.owner).to.equal(initialOwnerAddress); + + const proxyFactory = new ProxyAdmin__factory().connect(signer); + const deployTx = await proxyFactory.deploy(); + const newProxyAdmin = await deployTx.deployed(); + coreConfig.proxyAdmin!.address = newProxyAdmin.address; + + writeYamlOrJson(CORE_READ_CONFIG_PATH_2, coreConfig); + await hyperlaneCoreApply(CHAIN_NAME_2, CORE_READ_CONFIG_PATH_2); + + // Verify that the owner has been set correctly without modifying any other owner values + const updatedConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + expect(updatedConfig.owner).to.equal(initialOwnerAddress); + expect(updatedConfig.proxyAdmin?.address).to.equal(newProxyAdmin.address); + // Assuming that the ProtocolFeeHook is used for deployment + expect( + (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, + ).to.equal(initialOwnerAddress); + }); + + it('should update the ProxyAdmin owner for the mailbox', async () => { + await hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_CONFIG_PATH); + const coreConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + expect(coreConfig.owner).to.equal(initialOwnerAddress); + + const newOwner = randomAddress().toLowerCase(); + coreConfig.proxyAdmin!.owner = newOwner; + writeYamlOrJson(CORE_READ_CONFIG_PATH_2, coreConfig); + await hyperlaneCoreApply(CHAIN_NAME_2, CORE_READ_CONFIG_PATH_2); + + // Verify that the owner has been set correctly without modifying any other owner values + const updatedConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + expect(updatedConfig.owner).to.equal(initialOwnerAddress); + expect(updatedConfig.proxyAdmin?.owner.toLowerCase()).to.equal(newOwner); + // Assuming that the ProtocolFeeHook is used for deployment + expect( + (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, + ).to.equal(initialOwnerAddress); + }); + + it('should enroll a remote ICA Router and update the config on all involved chains', async () => { + await Promise.all([ + hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_CONFIG_PATH), + hyperlaneCoreDeploy(CHAIN_NAME_3, CORE_CONFIG_PATH), + ]); + + const [coreConfigChain2, coreConfigChain3]: DerivedCoreConfig[] = + await Promise.all([ + readCoreConfig(CHAIN_NAME_2, CORE_READ_CHAIN_2_CONFIG_PATH), + readCoreConfig(CHAIN_NAME_3, CORE_READ_CHAIN_3_CONFIG_PATH), + ]); + + expect(coreConfigChain2.owner).to.equal(initialOwnerAddress); + expect(coreConfigChain3.owner).to.equal(initialOwnerAddress); + + expect(coreConfigChain2.interchainAccountRouter).not.to.be.undefined; + expect(coreConfigChain3.interchainAccountRouter).not.to.be.undefined; + + const coreConfigChain2IcaConfig = coreConfigChain2.interchainAccountRouter!; + const coreConfigChain3IcaConfig = coreConfigChain3.interchainAccountRouter!; + + // Add the remote ica on chain anvil3 + coreConfigChain2IcaConfig.remoteIcaRouters = { + [chain3DomainId]: { + address: coreConfigChain3IcaConfig.address, + }, + }; + + const expectedChain2RemoteRoutersConfig = { + [chain3DomainId]: { + address: addressToBytes32(coreConfigChain3IcaConfig.address), + }, + }; + + const expectedChain3RemoteRoutersConfig = { + [chain2DomainId]: { + address: addressToBytes32(coreConfigChain2IcaConfig.address), + }, + }; + + writeYamlOrJson(CORE_READ_CHAIN_2_CONFIG_PATH, coreConfigChain2); + await hyperlaneCoreApply(CHAIN_NAME_2, CORE_READ_CHAIN_2_CONFIG_PATH); + + const [updatedChain2Config, updatedChain3Config]: DerivedCoreConfig[] = + await Promise.all([ + readCoreConfig(CHAIN_NAME_2, CORE_READ_CHAIN_2_CONFIG_PATH), + readCoreConfig(CHAIN_NAME_3, CORE_READ_CHAIN_3_CONFIG_PATH), + ]); + expect( + updatedChain2Config.interchainAccountRouter?.remoteIcaRouters, + ).to.deep.equal(expectedChain2RemoteRoutersConfig); + + expect( + updatedChain3Config.interchainAccountRouter?.remoteIcaRouters, + ).to.deep.equal(expectedChain3RemoteRoutersConfig); + }); + + it('should unenroll a remote ICA Router and update the config on all involved chains', async () => { + await Promise.all([ + hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_CONFIG_PATH), + hyperlaneCoreDeploy(CHAIN_NAME_3, CORE_CONFIG_PATH), + ]); + + const [coreConfigChain2, coreConfigChain3]: DerivedCoreConfig[] = + await Promise.all([ + readCoreConfig(CHAIN_NAME_2, CORE_READ_CHAIN_2_CONFIG_PATH), + readCoreConfig(CHAIN_NAME_3, CORE_READ_CHAIN_3_CONFIG_PATH), + ]); + + expect(coreConfigChain2.interchainAccountRouter).not.to.be.undefined; + expect(coreConfigChain3.interchainAccountRouter).not.to.be.undefined; + + const coreConfigChain2IcaConfig = coreConfigChain2.interchainAccountRouter!; + const coreConfigChain3IcaConfig = coreConfigChain3.interchainAccountRouter!; + + coreConfigChain2IcaConfig.remoteIcaRouters = { + [chain3DomainId]: { + address: coreConfigChain3IcaConfig.address, + }, + }; + + const expectedRemoteRoutersConfigAfterEnrollment = { + [chain3DomainId]: { + address: addressToBytes32(coreConfigChain3IcaConfig.address), + }, + }; + + writeYamlOrJson(CORE_READ_CHAIN_2_CONFIG_PATH, coreConfigChain2); + await hyperlaneCoreApply(CHAIN_NAME_2, CORE_READ_CHAIN_2_CONFIG_PATH); + + const updatedChain2ConfigAfterEnrollment: DerivedCoreConfig = + await readCoreConfig(CHAIN_NAME_2, CORE_READ_CHAIN_2_CONFIG_PATH); + expect( + updatedChain2ConfigAfterEnrollment.interchainAccountRouter + ?.remoteIcaRouters, + ).to.deep.equal(expectedRemoteRoutersConfigAfterEnrollment); + + // Remove all remote ICAs + updatedChain2ConfigAfterEnrollment.interchainAccountRouter!.remoteIcaRouters = + {}; + writeYamlOrJson( + CORE_READ_CHAIN_2_CONFIG_PATH, + updatedChain2ConfigAfterEnrollment, + ); + + await hyperlaneCoreApply(CHAIN_NAME_2, CORE_READ_CHAIN_2_CONFIG_PATH); + + const [updatedChain2Config, updatedChain3Config]: DerivedCoreConfig[] = + await Promise.all([ + readCoreConfig(CHAIN_NAME_2, CORE_READ_CHAIN_2_CONFIG_PATH), + readCoreConfig(CHAIN_NAME_3, CORE_READ_CHAIN_3_CONFIG_PATH), + ]); + + expect( + updatedChain2Config.interchainAccountRouter?.remoteIcaRouters, + ).to.deep.equal({}); + + expect( + updatedChain3Config.interchainAccountRouter?.remoteIcaRouters, + ).to.deep.equal({}); + }); +}); diff --git a/typescript/cli/src/tests/core-deploy.e2e-test.ts b/typescript/cli/src/tests/core-deploy.e2e-test.ts new file mode 100644 index 0000000000..192f0121b4 --- /dev/null +++ b/typescript/cli/src/tests/core-deploy.e2e-test.ts @@ -0,0 +1,108 @@ +import { expect } from 'chai'; +import { Signer, Wallet, ethers } from 'ethers'; + +import { + ChainMetadata, + CoreConfig, + ProtocolFeeHookConfig, + randomAddress, +} from '@hyperlane-xyz/sdk'; +import { Address } from '@hyperlane-xyz/utils'; + +import { readYamlOrJson, writeYamlOrJson } from '../utils/files.js'; + +import { hyperlaneCoreDeploy, readCoreConfig } from './commands/core.js'; +import { + ANVIL_KEY, + CHAIN_2_METADATA_PATH, + CHAIN_NAME_2, + CORE_CONFIG_PATH, + CORE_READ_CONFIG_PATH_2, + DEFAULT_E2E_TEST_TIMEOUT, +} from './commands/helpers.js'; + +describe('hyperlane core deploy e2e tests', async function () { + this.timeout(DEFAULT_E2E_TEST_TIMEOUT); + + let signer: Signer; + let initialOwnerAddress: Address; + + before(async () => { + const chainMetadata: ChainMetadata = readYamlOrJson(CHAIN_2_METADATA_PATH); + + const provider = new ethers.providers.JsonRpcProvider( + chainMetadata.rpcUrls[0].http, + ); + + const wallet = new Wallet(ANVIL_KEY); + signer = wallet.connect(provider); + + initialOwnerAddress = await signer.getAddress(); + }); + + it('should create a core deployment with the signer as the mailbox owner', async () => { + await hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_CONFIG_PATH); + + const coreConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + + expect(coreConfig.owner).to.equal(initialOwnerAddress); + expect(coreConfig.proxyAdmin?.owner).to.equal(initialOwnerAddress); + // Assuming that the ProtocolFeeHook is used for deployment + expect((coreConfig.requiredHook as ProtocolFeeHookConfig).owner).to.equal( + initialOwnerAddress, + ); + }); + + it('should create a core deployment with the mailbox owner set to the address in the config', async () => { + const coreConfig: CoreConfig = await readYamlOrJson(CORE_CONFIG_PATH); + + const newOwner = randomAddress().toLowerCase(); + + coreConfig.owner = newOwner; + writeYamlOrJson(CORE_READ_CONFIG_PATH_2, coreConfig); + + // Deploy the core contracts with the updated mailbox owner + await hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_READ_CONFIG_PATH_2); + + // Verify that the owner has been set correctly without modifying any other owner values + const updatedConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + + expect(updatedConfig.owner.toLowerCase()).to.equal(newOwner); + expect(updatedConfig.proxyAdmin?.owner).to.equal(initialOwnerAddress); + // Assuming that the ProtocolFeeHook is used for deployment + expect( + (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, + ).to.equal(initialOwnerAddress); + }); + + it('should create a core deployment with ProxyAdmin owner of the mailbox set to the address in the config', async () => { + const coreConfig: CoreConfig = await readYamlOrJson(CORE_CONFIG_PATH); + + const newOwner = randomAddress().toLowerCase(); + + coreConfig.proxyAdmin = { owner: newOwner }; + writeYamlOrJson(CORE_READ_CONFIG_PATH_2, coreConfig); + + // Deploy the core contracts with the updated mailbox owner + await hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_READ_CONFIG_PATH_2); + + // Verify that the owner has been set correctly without modifying any other owner values + const updatedConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + + expect(updatedConfig.owner).to.equal(initialOwnerAddress); + expect(updatedConfig.proxyAdmin?.owner.toLowerCase()).to.equal(newOwner); + // Assuming that the ProtocolFeeHook is used for deployment + expect( + (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, + ).to.equal(initialOwnerAddress); + }); +}); diff --git a/typescript/cli/src/tests/core-read.e2e-test.ts b/typescript/cli/src/tests/core-read.e2e-test.ts new file mode 100644 index 0000000000..7390e8dca4 --- /dev/null +++ b/typescript/cli/src/tests/core-read.e2e-test.ts @@ -0,0 +1,60 @@ +import { expect } from 'chai'; +import { Signer, Wallet, ethers } from 'ethers'; + +import { + ChainMetadata, + CoreConfig, + ProtocolFeeHookConfig, +} from '@hyperlane-xyz/sdk'; +import { Address } from '@hyperlane-xyz/utils'; + +import { readYamlOrJson } from '../utils/files.js'; + +import { hyperlaneCoreDeploy, readCoreConfig } from './commands/core.js'; +import { + ANVIL_KEY, + CHAIN_2_METADATA_PATH, + CHAIN_NAME_2, + CORE_CONFIG_PATH, + CORE_READ_CONFIG_PATH_2, + DEFAULT_E2E_TEST_TIMEOUT, +} from './commands/helpers.js'; + +describe('hyperlane core read e2e tests', async function () { + this.timeout(DEFAULT_E2E_TEST_TIMEOUT); + + let signer: Signer; + let initialOwnerAddress: Address; + + before(async () => { + const chainMetadata: ChainMetadata = readYamlOrJson(CHAIN_2_METADATA_PATH); + + const provider = new ethers.providers.JsonRpcProvider( + chainMetadata.rpcUrls[0].http, + ); + + const wallet = new Wallet(ANVIL_KEY); + signer = wallet.connect(provider); + + initialOwnerAddress = await signer.getAddress(); + }); + + it('should read a core deployment', async () => { + await hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_CONFIG_PATH); + + const coreConfig: CoreConfig = await readCoreConfig( + CHAIN_NAME_2, + CORE_READ_CONFIG_PATH_2, + ); + + expect(coreConfig.owner).to.equal(initialOwnerAddress); + expect(coreConfig.proxyAdmin?.owner).to.equal(initialOwnerAddress); + expect(coreConfig.requiredHook).not.to.be.undefined; + expect(coreConfig.defaultHook).not.to.be.undefined; + expect(coreConfig.defaultIsm).not.to.be.undefined; + // Assuming that the ProtocolFeeHook is used for deployment + expect((coreConfig.requiredHook as ProtocolFeeHookConfig).owner).to.equal( + initialOwnerAddress, + ); + }); +}); diff --git a/typescript/cli/src/tests/core.e2e-test.ts b/typescript/cli/src/tests/core.e2e-test.ts deleted file mode 100644 index 9d43244792..0000000000 --- a/typescript/cli/src/tests/core.e2e-test.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { expect } from 'chai'; -import { Signer, Wallet, ethers } from 'ethers'; - -import { ProxyAdmin__factory } from '@hyperlane-xyz/core'; -import { - CoreConfig, - ProtocolFeeHookConfig, - randomAddress, -} from '@hyperlane-xyz/sdk'; -import { Address } from '@hyperlane-xyz/utils'; - -import { readYamlOrJson, writeYamlOrJson } from '../utils/files.js'; - -import { - hyperlaneCoreApply, - hyperlaneCoreDeploy, - readCoreConfig, -} from './commands/core.js'; -import { ANVIL_KEY, REGISTRY_PATH } from './commands/helpers.js'; - -const CHAIN_NAME = 'anvil2'; - -const EXAMPLES_PATH = './examples'; -const CORE_CONFIG_PATH = `${EXAMPLES_PATH}/core-config.yaml`; - -const TEMP_PATH = '/tmp'; // /temp gets removed at the end of all-test.sh -const CORE_READ_CONFIG_PATH = `${TEMP_PATH}/anvil2/core-config-read.yaml`; - -const TEST_TIMEOUT = 100_000; // Long timeout since these tests can take a while -describe('hyperlane core e2e tests', async function () { - this.timeout(TEST_TIMEOUT); - - let signer: Signer; - let initialOwnerAddress: Address; - - before(async () => { - const chainMetadata: any = readYamlOrJson( - `${REGISTRY_PATH}/chains/${CHAIN_NAME}/metadata.yaml`, - ); - - const provider = new ethers.providers.JsonRpcProvider( - chainMetadata.rpcUrls[0].http, - ); - - const wallet = new Wallet(ANVIL_KEY); - signer = wallet.connect(provider); - - initialOwnerAddress = await signer.getAddress(); - }); - - describe('core.deploy', () => { - it('should create a core deployment with the signer as the mailbox owner', async () => { - await hyperlaneCoreDeploy(CHAIN_NAME, CORE_CONFIG_PATH); - - const coreConfig: CoreConfig = await readCoreConfig( - CHAIN_NAME, - CORE_READ_CONFIG_PATH, - ); - - expect(coreConfig.owner).to.equal(initialOwnerAddress); - expect(coreConfig.proxyAdmin?.owner).to.equal(initialOwnerAddress); - // Assuming that the ProtocolFeeHook is used for deployment - expect((coreConfig.requiredHook as ProtocolFeeHookConfig).owner).to.equal( - initialOwnerAddress, - ); - }); - - it('should create a core deployment with the mailbox owner set to the address in the config', async () => { - const coreConfig: CoreConfig = await readYamlOrJson(CORE_CONFIG_PATH); - - const newOwner = randomAddress().toLowerCase(); - - coreConfig.owner = newOwner; - writeYamlOrJson(CORE_READ_CONFIG_PATH, coreConfig); - - // Deploy the core contracts with the updated mailbox owner - await hyperlaneCoreDeploy(CHAIN_NAME, CORE_READ_CONFIG_PATH); - - // Verify that the owner has been set correctly without modifying any other owner values - const updatedConfig: CoreConfig = await readCoreConfig( - CHAIN_NAME, - CORE_READ_CONFIG_PATH, - ); - - expect(updatedConfig.owner.toLowerCase()).to.equal(newOwner); - expect(updatedConfig.proxyAdmin?.owner).to.equal(initialOwnerAddress); - // Assuming that the ProtocolFeeHook is used for deployment - expect( - (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, - ).to.equal(initialOwnerAddress); - }); - - it('should create a core deployment with ProxyAdmin owner of the mailbox set to the address in the config', async () => { - const coreConfig: CoreConfig = await readYamlOrJson(CORE_CONFIG_PATH); - - const newOwner = randomAddress().toLowerCase(); - - coreConfig.proxyAdmin = { owner: newOwner }; - writeYamlOrJson(CORE_READ_CONFIG_PATH, coreConfig); - - // Deploy the core contracts with the updated mailbox owner - await hyperlaneCoreDeploy(CHAIN_NAME, CORE_READ_CONFIG_PATH); - - // Verify that the owner has been set correctly without modifying any other owner values - const updatedConfig: CoreConfig = await readCoreConfig( - CHAIN_NAME, - CORE_READ_CONFIG_PATH, - ); - - expect(updatedConfig.owner).to.equal(initialOwnerAddress); - expect(updatedConfig.proxyAdmin?.owner.toLowerCase()).to.equal(newOwner); - // Assuming that the ProtocolFeeHook is used for deployment - expect( - (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, - ).to.equal(initialOwnerAddress); - }); - }); - - describe('core.apply', () => { - it('should update the mailbox owner', async () => { - await hyperlaneCoreDeploy(CHAIN_NAME, CORE_CONFIG_PATH); - const coreConfig: CoreConfig = await readCoreConfig( - CHAIN_NAME, - CORE_READ_CONFIG_PATH, - ); - expect(coreConfig.owner).to.equal(initialOwnerAddress); - const newOwner = randomAddress().toLowerCase(); - coreConfig.owner = newOwner; - writeYamlOrJson(CORE_READ_CONFIG_PATH, coreConfig); - await hyperlaneCoreApply(CHAIN_NAME, CORE_READ_CONFIG_PATH); - // Verify that the owner has been set correctly without modifying any other owner values - const updatedConfig: CoreConfig = await readCoreConfig( - CHAIN_NAME, - CORE_READ_CONFIG_PATH, - ); - expect(updatedConfig.owner.toLowerCase()).to.equal(newOwner); - expect(updatedConfig.proxyAdmin?.owner).to.equal(initialOwnerAddress); - // Assuming that the ProtocolFeeHook is used for deployment - expect( - (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, - ).to.equal(initialOwnerAddress); - }); - - it('should update the ProxyAdmin to a new one for the mailbox', async () => { - await hyperlaneCoreDeploy(CHAIN_NAME, CORE_CONFIG_PATH); - const coreConfig: CoreConfig = await readCoreConfig( - CHAIN_NAME, - CORE_READ_CONFIG_PATH, - ); - expect(coreConfig.owner).to.equal(initialOwnerAddress); - - const proxyFactory = new ProxyAdmin__factory().connect(signer); - const deployTx = await proxyFactory.deploy(); - const newProxyAdmin = await deployTx.deployed(); - coreConfig.proxyAdmin!.address = newProxyAdmin.address; - - writeYamlOrJson(CORE_READ_CONFIG_PATH, coreConfig); - await hyperlaneCoreApply(CHAIN_NAME, CORE_READ_CONFIG_PATH); - - // Verify that the owner has been set correctly without modifying any other owner values - const updatedConfig: CoreConfig = await readCoreConfig( - CHAIN_NAME, - CORE_READ_CONFIG_PATH, - ); - expect(updatedConfig.owner).to.equal(initialOwnerAddress); - expect(updatedConfig.proxyAdmin?.address).to.equal(newProxyAdmin.address); - // Assuming that the ProtocolFeeHook is used for deployment - expect( - (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, - ).to.equal(initialOwnerAddress); - }); - - it('should update the ProxyAdmin owner for the mailbox', async () => { - await hyperlaneCoreDeploy(CHAIN_NAME, CORE_CONFIG_PATH); - const coreConfig: CoreConfig = await readCoreConfig( - CHAIN_NAME, - CORE_READ_CONFIG_PATH, - ); - expect(coreConfig.owner).to.equal(initialOwnerAddress); - - const newOwner = randomAddress().toLowerCase(); - coreConfig.proxyAdmin!.owner = newOwner; - writeYamlOrJson(CORE_READ_CONFIG_PATH, coreConfig); - await hyperlaneCoreApply(CHAIN_NAME, CORE_READ_CONFIG_PATH); - - // Verify that the owner has been set correctly without modifying any other owner values - const updatedConfig: CoreConfig = await readCoreConfig( - CHAIN_NAME, - CORE_READ_CONFIG_PATH, - ); - expect(updatedConfig.owner).to.equal(initialOwnerAddress); - expect(updatedConfig.proxyAdmin?.owner.toLowerCase()).to.equal(newOwner); - // Assuming that the ProtocolFeeHook is used for deployment - expect( - (updatedConfig.requiredHook as ProtocolFeeHookConfig).owner, - ).to.equal(initialOwnerAddress); - }); - }); -}); diff --git a/typescript/cli/src/tests/relay.e2e-test.ts b/typescript/cli/src/tests/relay.e2e-test.ts index 3f970eed79..2dc5a1cabc 100644 --- a/typescript/cli/src/tests/relay.e2e-test.ts +++ b/typescript/cli/src/tests/relay.e2e-test.ts @@ -4,7 +4,12 @@ import { writeYamlOrJson } from '../utils/files.js'; import { hyperlaneCoreDeploy } from './commands/core.js'; import { + CHAIN_NAME_2, + CHAIN_NAME_3, + CORE_CONFIG_PATH, + DEFAULT_E2E_TEST_TIMEOUT, REGISTRY_PATH, + TEMP_PATH, hyperlaneRelayer, hyperlaneSendMessage, } from './commands/helpers.js'; @@ -13,23 +18,17 @@ import { hyperlaneWarpSendRelay, } from './commands/warp.js'; -const CHAIN_NAME_1 = 'anvil2'; -const CHAIN_NAME_2 = 'anvil3'; - const SYMBOL = 'ETH'; +const WARP_DEPLOY_OUTPUT = `${REGISTRY_PATH}/deployments/warp_routes/${SYMBOL}/${CHAIN_NAME_2}-${CHAIN_NAME_3}-config.yaml`; -const WARP_DEPLOY_OUTPUT = `${REGISTRY_PATH}/deployments/warp_routes/${SYMBOL}/${CHAIN_NAME_1}-${CHAIN_NAME_2}-config.yaml`; - -const EXAMPLES_PATH = './examples'; -const CORE_CONFIG_PATH = `${EXAMPLES_PATH}/core-config.yaml`; - -const TEST_TIMEOUT = 100_000; // Long timeout since these tests can take a while describe('hyperlane relayer e2e tests', async function () { - this.timeout(TEST_TIMEOUT); + this.timeout(2 * DEFAULT_E2E_TEST_TIMEOUT); before(async () => { - await hyperlaneCoreDeploy(CHAIN_NAME_1, CORE_CONFIG_PATH); - await hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_CONFIG_PATH); + await Promise.all([ + hyperlaneCoreDeploy(CHAIN_NAME_2, CORE_CONFIG_PATH), + hyperlaneCoreDeploy(CHAIN_NAME_3, CORE_CONFIG_PATH), + ]); const warpConfig = { anvil2: { @@ -42,36 +41,36 @@ describe('hyperlane relayer e2e tests', async function () { }, }; - const warpConfigPath = './tmp/warp-route-config.yaml'; + const warpConfigPath = `./${TEMP_PATH}/warp-route-config.yaml`; writeYamlOrJson(warpConfigPath, warpConfig); await hyperlaneWarpDeploy(warpConfigPath); }); describe('relayer', () => { it('should relay core messages', async () => { - const process = hyperlaneRelayer([CHAIN_NAME_1, CHAIN_NAME_2]); + const process = hyperlaneRelayer([CHAIN_NAME_2, CHAIN_NAME_3]); - await hyperlaneSendMessage(CHAIN_NAME_1, CHAIN_NAME_2); - await hyperlaneSendMessage(CHAIN_NAME_2, CHAIN_NAME_1); + await hyperlaneSendMessage(CHAIN_NAME_2, CHAIN_NAME_3); + await hyperlaneSendMessage(CHAIN_NAME_3, CHAIN_NAME_2); await process.kill('SIGINT'); }); it('should relay warp messages', async () => { const process = hyperlaneRelayer( - [CHAIN_NAME_1, CHAIN_NAME_2], + [CHAIN_NAME_2, CHAIN_NAME_3], WARP_DEPLOY_OUTPUT, ); await hyperlaneWarpSendRelay( - CHAIN_NAME_1, CHAIN_NAME_2, + CHAIN_NAME_3, WARP_DEPLOY_OUTPUT, false, ); await hyperlaneWarpSendRelay( + CHAIN_NAME_3, CHAIN_NAME_2, - CHAIN_NAME_1, WARP_DEPLOY_OUTPUT, false, ); diff --git a/typescript/cli/src/tests/warp-apply.e2e-test.ts b/typescript/cli/src/tests/warp-apply.e2e-test.ts index a97729c820..b5f9bab268 100644 --- a/typescript/cli/src/tests/warp-apply.e2e-test.ts +++ b/typescript/cli/src/tests/warp-apply.e2e-test.ts @@ -3,16 +3,29 @@ import { Wallet } from 'ethers'; import { ChainAddresses } from '@hyperlane-xyz/registry'; import { - TokenRouterConfig, + HookType, + HypTokenRouterConfig, TokenType, WarpRouteDeployConfig, + normalizeConfig, + randomAddress, } from '@hyperlane-xyz/sdk'; import { readYamlOrJson, writeYamlOrJson } from '../utils/files.js'; import { ANVIL_KEY, + CHAIN_NAME_2, + CHAIN_NAME_3, + CORE_CONFIG_PATH, + DEFAULT_E2E_TEST_TIMEOUT, + E2E_TEST_BURN_ADDRESS, + EXAMPLES_PATH, REGISTRY_PATH, + TEMP_PATH, + WARP_CONFIG_PATH_2, + WARP_CONFIG_PATH_EXAMPLE, + WARP_CORE_CONFIG_PATH_2, deployOrUseExistingCore, extendWarpConfig, getDomainId, @@ -24,22 +37,11 @@ import { readWarpConfig, } from './commands/warp.js'; -const CHAIN_NAME_2 = 'anvil2'; -const CHAIN_NAME_3 = 'anvil3'; +describe('hyperlane warp apply e2e tests', async function () { + this.timeout(2 * DEFAULT_E2E_TEST_TIMEOUT); -const BURN_ADDRESS = '0x0000000000000000000000000000000000000001'; -const EXAMPLES_PATH = './examples'; -const CORE_CONFIG_PATH = `${EXAMPLES_PATH}/core-config.yaml`; -const WARP_CONFIG_PATH_EXAMPLE = `${EXAMPLES_PATH}/warp-route-deployment.yaml`; - -const TEMP_PATH = '/tmp'; // /temp gets removed at the end of all-test.sh -const WARP_CONFIG_PATH_2 = `${TEMP_PATH}/anvil2/warp-route-deployment-anvil2.yaml`; -const WARP_CORE_CONFIG_PATH_2 = `${REGISTRY_PATH}/deployments/warp_routes/ETH/anvil2-config.yaml`; - -const TEST_TIMEOUT = 100_000; // Long timeout since these tests can take a while -describe('WarpApply e2e tests', async function () { let chain2Addresses: ChainAddresses = {}; - this.timeout(TEST_TIMEOUT); + before(async function () { await deployOrUseExistingCore(CHAIN_NAME_2, CORE_CONFIG_PATH, ANVIL_KEY); chain2Addresses = await deployOrUseExistingCore( @@ -63,7 +65,7 @@ describe('WarpApply e2e tests', async function () { it('should burn owner address', async function () { const warpConfigPath = `${TEMP_PATH}/warp-route-deployment-2.yaml`; await updateOwner( - BURN_ADDRESS, + E2E_TEST_BURN_ADDRESS, CHAIN_NAME_2, warpConfigPath, WARP_CORE_CONFIG_PATH_2, @@ -73,19 +75,21 @@ describe('WarpApply e2e tests', async function () { WARP_CORE_CONFIG_PATH_2, warpConfigPath, ); - expect(updatedWarpDeployConfig.anvil2.owner).to.equal(BURN_ADDRESS); + expect(updatedWarpDeployConfig.anvil2.owner).to.equal( + E2E_TEST_BURN_ADDRESS, + ); }); it('should not update the same owner', async () => { const warpConfigPath = `${TEMP_PATH}/warp-route-deployment-2.yaml`; await updateOwner( - BURN_ADDRESS, + E2E_TEST_BURN_ADDRESS, CHAIN_NAME_2, warpConfigPath, WARP_CORE_CONFIG_PATH_2, ); const { stdout } = await updateOwner( - BURN_ADDRESS, + E2E_TEST_BURN_ADDRESS, CHAIN_NAME_2, warpConfigPath, WARP_CORE_CONFIG_PATH_2, @@ -95,13 +99,52 @@ describe('WarpApply e2e tests', async function () { ); }); + it('should update hook configuration', async () => { + const warpDeployPath = `${TEMP_PATH}/warp-route-deployment-2.yaml`; + + // First read the existing config + const warpDeployConfig = await readWarpConfig( + CHAIN_NAME_2, + WARP_CORE_CONFIG_PATH_2, + warpDeployPath, + ); + + // Update with a new hook config + const owner = randomAddress(); + warpDeployConfig[CHAIN_NAME_2].hook = { + type: HookType.PROTOCOL_FEE, + beneficiary: owner, + maxProtocolFee: '1000000', + protocolFee: '100000', + owner, + }; + + // Write the updated config + await writeYamlOrJson(warpDeployPath, warpDeployConfig); + + // Apply the changes + await hyperlaneWarpApply(warpDeployPath, WARP_CORE_CONFIG_PATH_2); + + // Read back the config to verify changes + const updatedConfig = await readWarpConfig( + CHAIN_NAME_2, + WARP_CORE_CONFIG_PATH_2, + warpDeployPath, + ); + + // Verify the hook was updated with all properties + expect(normalizeConfig(updatedConfig[CHAIN_NAME_2].hook)).to.deep.equal( + normalizeConfig(warpDeployConfig[CHAIN_NAME_2].hook), + ); + }); + it('should extend an existing warp route', async () => { // Read existing config into a file const warpConfigPath = `${TEMP_PATH}/warp-route-deployment-2.yaml`; await readWarpConfig(CHAIN_NAME_2, WARP_CORE_CONFIG_PATH_2, warpConfigPath); // Extend with new config - const config: TokenRouterConfig = { + const config: HypTokenRouterConfig = { decimals: 18, mailbox: chain2Addresses!.mailbox, name: 'Ether', @@ -154,7 +197,7 @@ describe('WarpApply e2e tests', async function () { await readWarpConfig(CHAIN_NAME_2, WARP_CORE_CONFIG_PATH_2, warpConfigPath); // Extend with new config - const config: TokenRouterConfig = { + const config: HypTokenRouterConfig = { decimals: 18, mailbox: chain2Addresses!.mailbox, name: 'Ether', @@ -210,11 +253,11 @@ describe('WarpApply e2e tests', async function () { WARP_CORE_CONFIG_PATH_2, warpDeployPath, ); - warpDeployConfig[CHAIN_NAME_2].owner = BURN_ADDRESS; + warpDeployConfig[CHAIN_NAME_2].owner = E2E_TEST_BURN_ADDRESS; // Extend with new config const randomOwner = new Wallet(ANVIL_KEY).address; - const extendedConfig: TokenRouterConfig = { + const extendedConfig: HypTokenRouterConfig = { decimals: 18, mailbox: chain2Addresses!.mailbox, name: 'Ether', @@ -241,7 +284,9 @@ describe('WarpApply e2e tests', async function () { warpDeployPath, ); // Check that anvil2 owner is burned - expect(updatedWarpDeployConfig_2.anvil2.owner).to.equal(BURN_ADDRESS); + expect(updatedWarpDeployConfig_2.anvil2.owner).to.equal( + E2E_TEST_BURN_ADDRESS, + ); // Also, anvil3 owner is not burned expect(updatedWarpDeployConfig_3.anvil3.owner).to.equal(randomOwner); @@ -272,7 +317,7 @@ describe('WarpApply e2e tests', async function () { // Extend with new config const GAS = 694200; - const extendedConfig: TokenRouterConfig = { + const extendedConfig: HypTokenRouterConfig = { decimals: 18, mailbox: chain2Addresses!.mailbox, name: 'Ether', diff --git a/typescript/cli/src/tests/warp-deploy.e2e-test.ts b/typescript/cli/src/tests/warp-deploy.e2e-test.ts index 9971878eb0..d80508eb6a 100644 --- a/typescript/cli/src/tests/warp-deploy.e2e-test.ts +++ b/typescript/cli/src/tests/warp-deploy.e2e-test.ts @@ -2,14 +2,27 @@ import * as chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { ChainAddresses } from '@hyperlane-xyz/registry'; -import { TokenType, WarpRouteDeployConfig } from '@hyperlane-xyz/sdk'; +import { + HookConfig, + HookType, + IsmConfig, + IsmType, + TokenType, + WarpRouteDeployConfig, + normalizeConfig, +} from '@hyperlane-xyz/sdk'; import { WarpSendLogs } from '../send/transfer.js'; import { writeYamlOrJson } from '../utils/files.js'; import { ANVIL_KEY, + CHAIN_NAME_2, + CHAIN_NAME_3, + CORE_CONFIG_PATH, + DEFAULT_E2E_TEST_TIMEOUT, REGISTRY_PATH, + TEMP_PATH, deploy4626Vault, deployOrUseExistingCore, deployToken, @@ -21,37 +34,22 @@ chai.use(chaiAsPromised); const expect = chai.expect; chai.should(); -const CHAIN_NAME_2 = 'anvil2'; -const CHAIN_NAME_3 = 'anvil3'; - -const EXAMPLES_PATH = './examples'; -const TEMP_PATH = '/tmp'; // /temp gets removed at the end of all-test.sh - -const CORE_CONFIG_PATH = `${EXAMPLES_PATH}/core-config.yaml`; const WARP_CONFIG_PATH = `${TEMP_PATH}/warp-route-deployment-deploy.yaml`; const WARP_CORE_CONFIG_PATH_2_3 = `${REGISTRY_PATH}/deployments/warp_routes/VAULT/anvil2-anvil3-config.yaml`; -const TEST_TIMEOUT = 60_000; // Long timeout since these tests can take a while -describe('WarpDeploy e2e tests', async function () { +describe('hyperlane warp deploy e2e tests', async function () { + this.timeout(DEFAULT_E2E_TEST_TIMEOUT); + let chain2Addresses: ChainAddresses = {}; let chain3Addresses: ChainAddresses = {}; let token: any; let vault: any; - this.timeout(TEST_TIMEOUT); - before(async function () { - chain2Addresses = await deployOrUseExistingCore( - CHAIN_NAME_2, - CORE_CONFIG_PATH, - ANVIL_KEY, - ); - - chain3Addresses = await deployOrUseExistingCore( - CHAIN_NAME_3, - CORE_CONFIG_PATH, - ANVIL_KEY, - ); + [chain2Addresses, chain3Addresses] = await Promise.all([ + deployOrUseExistingCore(CHAIN_NAME_2, CORE_CONFIG_PATH, ANVIL_KEY), + deployOrUseExistingCore(CHAIN_NAME_3, CORE_CONFIG_PATH, ANVIL_KEY), + ]); token = await deployToken(ANVIL_KEY, CHAIN_NAME_2); vault = await deploy4626Vault(ANVIL_KEY, CHAIN_NAME_2, token.address); @@ -116,4 +114,88 @@ describe('WarpDeploy e2e tests', async function () { ); expect(stdout).to.include(WarpSendLogs.SUCCESS); }); + + it('should deploy with an ISM config', async () => { + // 1. Define ISM configuration + const ism: IsmConfig = { + type: IsmType.MESSAGE_ID_MULTISIG, + validators: [chain2Addresses.mailbox], // Using mailbox address as example validator + threshold: 1, + }; + + // 2. Create Warp configuration with ISM + const warpConfig: WarpRouteDeployConfig = { + [CHAIN_NAME_2]: { + type: TokenType.collateralVaultRebase, + token: vault.address, + mailbox: chain2Addresses.mailbox, + owner: chain2Addresses.mailbox, + interchainSecurityModule: ism, // Add ISM config here + }, + [CHAIN_NAME_3]: { + type: TokenType.syntheticRebase, + mailbox: chain3Addresses.mailbox, + owner: chain3Addresses.mailbox, + collateralChainName: CHAIN_NAME_2, + }, + }; + + // 3. Write config and deploy + writeYamlOrJson(WARP_CONFIG_PATH, warpConfig); + await hyperlaneWarpDeploy(WARP_CONFIG_PATH); + + // 4. Verify deployed ISM configuration + const collateralRebaseConfig = ( + await readWarpConfig( + CHAIN_NAME_2, + WARP_CORE_CONFIG_PATH_2_3, + WARP_CONFIG_PATH, + ) + )[CHAIN_NAME_2]; + + expect( + normalizeConfig(collateralRebaseConfig.interchainSecurityModule), + ).to.deep.equal(normalizeConfig(ism)); + }); + + it('should deploy with a hook config', async () => { + const hook: HookConfig = { + type: HookType.PROTOCOL_FEE, + beneficiary: chain2Addresses.mailbox, + owner: chain2Addresses.mailbox, + maxProtocolFee: '1337', + protocolFee: '1337', + }; + const warpConfig: WarpRouteDeployConfig = { + [CHAIN_NAME_2]: { + type: TokenType.collateralVaultRebase, + token: vault.address, + mailbox: chain2Addresses.mailbox, + owner: chain2Addresses.mailbox, + hook, + }, + [CHAIN_NAME_3]: { + type: TokenType.syntheticRebase, + mailbox: chain3Addresses.mailbox, + owner: chain3Addresses.mailbox, + collateralChainName: CHAIN_NAME_2, + }, + }; + + writeYamlOrJson(WARP_CONFIG_PATH, warpConfig); + await hyperlaneWarpDeploy(WARP_CONFIG_PATH); + + // Check collateralRebase + const collateralRebaseConfig = ( + await readWarpConfig( + CHAIN_NAME_2, + WARP_CORE_CONFIG_PATH_2_3, + WARP_CONFIG_PATH, + ) + )[CHAIN_NAME_2]; + + expect(normalizeConfig(collateralRebaseConfig.hook)).to.deep.equal( + normalizeConfig(hook), + ); + }); }); diff --git a/typescript/cli/src/tests/warp-read.e2e-test.ts b/typescript/cli/src/tests/warp-read.e2e-test.ts index 1cbf336d59..6b7096ad26 100644 --- a/typescript/cli/src/tests/warp-read.e2e-test.ts +++ b/typescript/cli/src/tests/warp-read.e2e-test.ts @@ -6,25 +6,22 @@ import { readYamlOrJson, writeYamlOrJson } from '../utils/files.js'; import { ANVIL_KEY, - REGISTRY_PATH, + CHAIN_NAME_2, + CORE_CONFIG_PATH, + DEFAULT_E2E_TEST_TIMEOUT, + TEMP_PATH, + WARP_CONFIG_PATH_2, + WARP_CONFIG_PATH_EXAMPLE, + WARP_CORE_CONFIG_PATH_2, deployOrUseExistingCore, } from './commands/helpers.js'; import { hyperlaneWarpDeploy, readWarpConfig } from './commands/warp.js'; -const CHAIN_NAME_2 = 'anvil2'; +describe('hyperlane warp read e2e tests', async function () { + this.timeout(DEFAULT_E2E_TEST_TIMEOUT); -const EXAMPLES_PATH = './examples'; -const CORE_CONFIG_PATH = `${EXAMPLES_PATH}/core-config.yaml`; -const WARP_CONFIG_PATH_EXAMPLE = `${EXAMPLES_PATH}/warp-route-deployment.yaml`; - -const TEMP_PATH = '/tmp'; // /temp gets removed at the end of all-test.sh -const WARP_CONFIG_PATH_2 = `${TEMP_PATH}/anvil2/warp-route-deployment-anvil2.yaml`; -const WARP_CORE_CONFIG_PATH_2 = `${REGISTRY_PATH}/deployments/warp_routes/ETH/anvil2-config.yaml`; - -const TEST_TIMEOUT = 60_000; // Long timeout since these tests can take a while -describe('WarpRead e2e tests', async function () { let anvil2Config: WarpRouteDeployConfig; - this.timeout(TEST_TIMEOUT); + before(async function () { await deployOrUseExistingCore(CHAIN_NAME_2, CORE_CONFIG_PATH, ANVIL_KEY); diff --git a/typescript/cli/src/utils/balances.ts b/typescript/cli/src/utils/balances.ts index 5cf8019771..4536353e57 100644 --- a/typescript/cli/src/utils/balances.ts +++ b/typescript/cli/src/utils/balances.ts @@ -2,8 +2,9 @@ import { confirm } from '@inquirer/prompts'; import { ethers } from 'ethers'; import { ChainName, MultiProvider } from '@hyperlane-xyz/sdk'; +import { ProtocolType } from '@hyperlane-xyz/utils'; -import { logGreen, logRed } from '../logger.js'; +import { logGray, logGreen, logRed } from '../logger.js'; export async function nativeBalancesAreSufficient( multiProvider: MultiProvider, @@ -15,6 +16,12 @@ export async function nativeBalancesAreSufficient( const sufficientBalances: boolean[] = []; for (const chain of chains) { + // Only Ethereum chains are supported + if (multiProvider.getProtocol(chain) !== ProtocolType.Ethereum) { + logGray(`Skipping balance check for non-EVM chain: ${chain}`); + continue; + } + const provider = multiProvider.getProvider(chain); const gasPrice = await provider.getGasPrice(); const minBalanceWei = gasPrice.mul(minGas).toString(); diff --git a/typescript/cli/src/utils/env.ts b/typescript/cli/src/utils/env.ts index 51ab1ce352..a0a5b232f1 100644 --- a/typescript/cli/src/utils/env.ts +++ b/typescript/cli/src/utils/env.ts @@ -1,4 +1,4 @@ -import z from 'zod'; +import { z } from 'zod'; const envScheme = z.object({ HYP_KEY: z.string().optional(), diff --git a/typescript/cli/src/utils/files.ts b/typescript/cli/src/utils/files.ts index 9c7cb6216e..50f56d1b77 100644 --- a/typescript/cli/src/utils/files.ts +++ b/typescript/cli/src/utils/files.ts @@ -42,7 +42,7 @@ export function isFile(filepath: string) { if (!filepath) return false; try { return fs.existsSync(filepath) && fs.lstatSync(filepath).isFile(); - } catch (error) { + } catch { log(`Error checking for file: ${filepath}`); return false; } @@ -70,7 +70,7 @@ export function readJson(filepath: string): T { export function tryReadJson(filepath: string): T | null { try { return readJson(filepath) as T; - } catch (error) { + } catch { return null; } } @@ -98,7 +98,7 @@ export function readYaml(filepath: string): T { export function tryReadYamlAtPath(filepath: string): T | null { try { return readYaml(filepath); - } catch (error) { + } catch { return null; } } diff --git a/typescript/cli/src/utils/input.ts b/typescript/cli/src/utils/input.ts index 2ccef32db8..eb197c1acd 100644 --- a/typescript/cli/src/utils/input.ts +++ b/typescript/cli/src/utils/input.ts @@ -14,24 +14,18 @@ import { } from '@inquirer/core'; import figures from '@inquirer/figures'; import { KeypressEvent, confirm, input, isSpaceKey } from '@inquirer/prompts'; -import type { PartialDeep } from '@inquirer/type'; +import type { PartialDeep, Prompt } from '@inquirer/type'; import ansiEscapes from 'ansi-escapes'; import chalk from 'chalk'; import { ProxyAdmin__factory } from '@hyperlane-xyz/core'; -import { - ChainName, - DeployedOwnableConfig, - WarpCoreConfig, -} from '@hyperlane-xyz/sdk'; +import { ChainName, DeployedOwnableConfig } from '@hyperlane-xyz/sdk'; import { Address, isAddress, rootLogger } from '@hyperlane-xyz/utils'; -import { readWarpCoreConfig } from '../config/warp.js'; import { CommandContext } from '../context/types.js'; -import { logGray, logRed } from '../logger.js'; +import { logGray } from '../logger.js'; import { indentYamlOrJson } from './files.js'; -import { selectRegistryWarpRoute } from './tokens.js'; export async function detectAndConfirmOrPrompt( detect: () => Promise, @@ -52,8 +46,9 @@ export async function detectAndConfirmOrPrompt( return detectedValue; } } - // eslint-disable-next-line no-empty - } catch (e) {} + } catch { + // Fallback to input prompt + } return input({ message: `${prompt} ${label}:`, default: detectedValue }); } @@ -136,34 +131,6 @@ export async function setProxyAdminConfig( } } -/** - * Gets a {@link WarpCoreConfig} based on the provided path or prompts the user to choose one: - * - if `symbol` is provided the user will have to select one of the available warp routes. - * - if `warp` is provided the config will be read by the provided file path. - * - if none is provided the CLI will exit. - */ -export async function getWarpCoreConfigOrExit({ - context, - symbol, - warp, -}: { - context: CommandContext; - symbol?: string; - warp?: string; -}): Promise { - let warpCoreConfig: WarpCoreConfig; - if (symbol) { - warpCoreConfig = await selectRegistryWarpRoute(context.registry, symbol); - } else if (warp) { - warpCoreConfig = readWarpCoreConfig(warp); - } else { - logRed(`Please specify either a symbol or warp config`); - process.exit(0); - } - - return warpCoreConfig; -} - /** * Searchable checkbox code * @@ -497,7 +464,10 @@ function isDownKey(key: KeypressEvent): boolean { return key.name === 'down'; } -export const searchableCheckBox = createPrompt( +export const searchableCheckBox: Prompt< + any, + SearchableCheckboxConfig +> = createPrompt( ( config: SearchableCheckboxConfig, done: (value: Array) => void, diff --git a/typescript/cli/src/utils/warp.ts b/typescript/cli/src/utils/warp.ts new file mode 100644 index 0000000000..08888628e5 --- /dev/null +++ b/typescript/cli/src/utils/warp.ts @@ -0,0 +1,35 @@ +import { WarpCoreConfig } from '@hyperlane-xyz/sdk'; + +import { readWarpCoreConfig } from '../config/warp.js'; +import { CommandContext } from '../context/types.js'; +import { logRed } from '../logger.js'; + +import { selectRegistryWarpRoute } from './tokens.js'; + +/** + * Gets a {@link WarpCoreConfig} based on the provided path or prompts the user to choose one: + * - if `symbol` is provided the user will have to select one of the available warp routes. + * - if `warp` is provided the config will be read by the provided file path. + * - if none is provided the CLI will exit. + */ +export async function getWarpCoreConfigOrExit({ + context, + symbol, + warp, +}: { + context: CommandContext; + symbol?: string; + warp?: string; +}): Promise { + let warpCoreConfig: WarpCoreConfig; + if (symbol) { + warpCoreConfig = await selectRegistryWarpRoute(context.registry, symbol); + } else if (warp) { + warpCoreConfig = readWarpCoreConfig(warp); + } else { + logRed(`Please specify either a symbol or warp config`); + process.exit(0); + } + + return warpCoreConfig; +} diff --git a/typescript/cli/src/validator/preFlightCheck.ts b/typescript/cli/src/validator/preFlightCheck.ts index ca0c4d8504..ba674b48b9 100644 --- a/typescript/cli/src/validator/preFlightCheck.ts +++ b/typescript/cli/src/validator/preFlightCheck.ts @@ -44,7 +44,7 @@ export const checkValidatorSetup = async ( try { validatorStorageLocations = await validatorAnnounce.getAnnouncedStorageLocations(validatorsArray); - } catch (e) { + } catch { errorSet.add('Failed to read announced storage locations on chain.'); } @@ -64,7 +64,7 @@ export const checkValidatorSetup = async ( let s3Validator: S3Validator; try { s3Validator = await S3Validator.fromStorageLocation(s3StorageLocation); - } catch (e) { + } catch { errorRed( `❌ Failed to fetch storage locations for validator ${validator}, this may be due to the storage location not being an S3 bucket\n\n`, ); diff --git a/typescript/cli/src/version.ts b/typescript/cli/src/version.ts index e882c3c6fe..af959132f7 100644 --- a/typescript/cli/src/version.ts +++ b/typescript/cli/src/version.ts @@ -1 +1 @@ -export const VERSION = '7.1.0'; +export const VERSION = '7.3.0'; diff --git a/typescript/github-proxy/CHANGELOG.md b/typescript/github-proxy/CHANGELOG.md index a522bb6d5c..a5237280ae 100644 --- a/typescript/github-proxy/CHANGELOG.md +++ b/typescript/github-proxy/CHANGELOG.md @@ -1,5 +1,9 @@ # @hyperlane-xyz/github-proxy +## 7.3.0 + +## 7.2.0 + ## 7.1.0 ## 7.0.0 diff --git a/typescript/github-proxy/package.json b/typescript/github-proxy/package.json index 1536432c7d..848f3dcafc 100644 --- a/typescript/github-proxy/package.json +++ b/typescript/github-proxy/package.json @@ -1,7 +1,7 @@ { "name": "@hyperlane-xyz/github-proxy", "description": "Github proxy that adds the API key to requests", - "version": "7.1.0", + "version": "7.3.0", "private": true, "scripts": { "deploy": "wrangler deploy", @@ -27,7 +27,7 @@ "@cloudflare/vitest-pool-workers": "^0.4.5", "@cloudflare/workers-types": "^4.20240821.1", "@faker-js/faker": "^8.4.1", - "chai": "4.5.0", + "chai": "^4.5.0", "prettier": "^2.8.8", "typescript": "5.3.3", "vitest": "1.4.0", diff --git a/typescript/helloworld/.eslintignore b/typescript/helloworld/.eslintignore deleted file mode 100644 index d461f0fa89..0000000000 --- a/typescript/helloworld/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules -dist -coverage -src/types -hardhat.config.ts \ No newline at end of file diff --git a/typescript/helloworld/.eslintrc b/typescript/helloworld/.eslintrc deleted file mode 100644 index 446616f52f..0000000000 --- a/typescript/helloworld/.eslintrc +++ /dev/null @@ -1,39 +0,0 @@ -{ - "env": { - "node": true, - "browser": true, - "es2021": true - }, - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 12, - "sourceType": "module", - "project": "./tsconfig.json" - }, - "plugins": ["@typescript-eslint"], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "prettier" - ], - "rules": { - "no-eval": ["error"], - "no-ex-assign": ["error"], - "no-constant-condition": ["off"], - "@typescript-eslint/ban-ts-comment": ["off"], - "@typescript-eslint/explicit-module-boundary-types": ["off"], - "@typescript-eslint/no-explicit-any": ["off"], - "@typescript-eslint/no-floating-promises": ["error"], - "@typescript-eslint/no-non-null-assertion": ["off"], - "@typescript-eslint/no-require-imports": ["warn"], - "@typescript-eslint/no-unused-vars": [ - "error", - { - "argsIgnorePattern": "^_", - "varsIgnorePattern": "^_", - "caughtErrorsIgnorePattern": "^_" - } - ] - } -} diff --git a/typescript/helloworld/CHANGELOG.md b/typescript/helloworld/CHANGELOG.md index fe9c0b3da1..89cedf4d32 100644 --- a/typescript/helloworld/CHANGELOG.md +++ b/typescript/helloworld/CHANGELOG.md @@ -1,5 +1,35 @@ # @hyperlane-xyz/helloworld +## 7.3.0 + +### Patch Changes + +- Updated dependencies [2054f4f5b] +- Updated dependencies [a96448fa6] +- Updated dependencies [170a0fc73] +- Updated dependencies [9a09afcc7] +- Updated dependencies [24784af95] +- Updated dependencies [3e8dd70ac] +- Updated dependencies [aa1ea9a48] +- Updated dependencies [665a7b8d8] +- Updated dependencies [f0b98fdef] +- Updated dependencies [ff9e8a72b] +- Updated dependencies [97c1f80b7] +- Updated dependencies [323f0f158] +- Updated dependencies [61157097b] + - @hyperlane-xyz/sdk@7.3.0 + - @hyperlane-xyz/core@5.8.3 + +## 7.2.0 + +### Patch Changes + +- Updated dependencies [81ab4332f] +- Updated dependencies [4b3537470] +- Updated dependencies [fa6d5f5c6] + - @hyperlane-xyz/sdk@7.2.0 + - @hyperlane-xyz/core@5.8.2 + ## 7.1.0 ### Patch Changes diff --git a/typescript/helloworld/eslint.config.mjs b/typescript/helloworld/eslint.config.mjs new file mode 100644 index 0000000000..f88d208157 --- /dev/null +++ b/typescript/helloworld/eslint.config.mjs @@ -0,0 +1,17 @@ +import MonorepoDefaults from '../../eslint.config.mjs'; + +export default [ + ...MonorepoDefaults, + { + files: ['./src/**/*.ts'], + }, + { + ignores: ["**/src/types/*"], + }, + { + ignores: ['./src/scripts'], + rules: { + 'no-console': ['off'], + }, + }, +]; \ No newline at end of file diff --git a/typescript/helloworld/package.json b/typescript/helloworld/package.json index 3191ce2134..a7fdc9bb28 100644 --- a/typescript/helloworld/package.json +++ b/typescript/helloworld/package.json @@ -1,26 +1,29 @@ { "name": "@hyperlane-xyz/helloworld", "description": "A basic skeleton of an Hyperlane app", - "version": "7.1.0", + "version": "7.3.0", "dependencies": { - "@hyperlane-xyz/core": "5.8.1", - "@hyperlane-xyz/registry": "6.1.0", - "@hyperlane-xyz/sdk": "7.1.0", + "@hyperlane-xyz/core": "5.8.3", + "@hyperlane-xyz/registry": "6.3.0", + "@hyperlane-xyz/sdk": "7.3.0", "@openzeppelin/contracts-upgradeable": "^4.9.3", "ethers": "^5.7.2" }, "devDependencies": { + "@eslint/js": "^9.15.0", "@nomiclabs/hardhat-ethers": "^2.2.3", "@nomiclabs/hardhat-waffle": "^2.0.6", "@trivago/prettier-plugin-sort-imports": "^4.2.1", "@typechain/ethers-v5": "^11.1.2", "@typechain/ethers-v6": "^0.5.1", "@typechain/hardhat": "^9.1.0", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", - "chai": "4.5.0", - "eslint": "^8.57.0", + "@typescript-eslint/eslint-plugin": "^8.1.6", + "@typescript-eslint/parser": "^8.1.6", + "chai": "^4.5.0", + "eslint": "^9.15.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import": "^2.31.0", "ethereum-waffle": "^4.0.10", "hardhat": "^2.22.2", "hardhat-gas-reporter": "^1.0.9", @@ -56,7 +59,9 @@ "build": "yarn hardhat-esm compile && tsc", "clean": "yarn hardhat-esm clean && rm -rf dist cache src/types", "coverage": "yarn hardhat-esm coverage", - "lint": "solhint contracts/**/*.sol && eslint . --ext .ts", + "lint": "yarn lint:sol && yarn lint:ts", + "lint:sol": "solhint contracts/**/*.sol", + "lint:ts": "eslint -c ./eslint.config.mjs", "hardhat-esm": "NODE_OPTIONS='--experimental-loader ts-node/esm/transpile-only --no-warnings=ExperimentalWarning' hardhat --config hardhat.config.cts", "prettier": "prettier --write ./contracts ./src", "test": "yarn hardhat-esm test ./src/test/**/*.test.ts", diff --git a/typescript/infra/CHANGELOG.md b/typescript/infra/CHANGELOG.md index d533e66b32..1e8ec17676 100644 --- a/typescript/infra/CHANGELOG.md +++ b/typescript/infra/CHANGELOG.md @@ -1,5 +1,43 @@ # @hyperlane-xyz/infra +## 7.3.0 + +### Minor Changes + +- 1ca857451: add USDC, USDT, cbBTC and ETH zeronetwork warp routes support in infra +- 323f0f158: Add ICAs management in core apply command + +### Patch Changes + +- Updated dependencies [2054f4f5b] +- Updated dependencies [a96448fa6] +- Updated dependencies [170a0fc73] +- Updated dependencies [9a09afcc7] +- Updated dependencies [24784af95] +- Updated dependencies [3e8dd70ac] +- Updated dependencies [aa1ea9a48] +- Updated dependencies [665a7b8d8] +- Updated dependencies [f0b98fdef] +- Updated dependencies [ff9e8a72b] +- Updated dependencies [97c1f80b7] +- Updated dependencies [323f0f158] +- Updated dependencies [61157097b] + - @hyperlane-xyz/sdk@7.3.0 + - @hyperlane-xyz/helloworld@7.3.0 + - @hyperlane-xyz/utils@7.3.0 + +## 7.2.0 + +### Patch Changes + +- Updated dependencies [81ab4332f] +- Updated dependencies [4b3537470] +- Updated dependencies [fa6d5f5c6] +- Updated dependencies [fa6d5f5c6] + - @hyperlane-xyz/sdk@7.2.0 + - @hyperlane-xyz/utils@7.2.0 + - @hyperlane-xyz/helloworld@7.2.0 + ## 7.1.0 ### Minor Changes diff --git a/typescript/infra/config/environments/mainnet3/agent.ts b/typescript/infra/config/environments/mainnet3/agent.ts index 892746c63e..58c42ffd81 100644 --- a/typescript/infra/config/environments/mainnet3/agent.ts +++ b/typescript/infra/config/environments/mainnet3/agent.ts @@ -22,6 +22,7 @@ import { getDomainId } from '../../registry.js'; import { environment } from './chains.js'; import { helloWorld } from './helloworld.js'; import aaveSenderAddresses from './misc-artifacts/aave-sender-addresses.json'; +import everclearSenderAddresses from './misc-artifacts/everclear-sender-addresses.json'; import merklyEthAddresses from './misc-artifacts/merkly-eth-addresses.json'; import merklyNftAddresses from './misc-artifacts/merkly-eth-addresses.json'; import merklyErc20Addresses from './misc-artifacts/merkly-eth-addresses.json'; @@ -53,6 +54,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< ancient8: true, alephzeroevmmainnet: true, apechain: true, + appchain: true, arbitrum: true, arbitrumnova: true, astar: true, @@ -64,7 +66,9 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< bitlayer: true, blast: true, bob: true, + boba: true, bsc: true, + bsquared: true, celo: true, cheesechain: true, chilizmainnet: true, @@ -72,6 +76,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< cyber: true, degenchain: true, dogechain: true, + duckchain: true, eclipsemainnet: true, endurance: true, ethereum: true, @@ -93,6 +98,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< lisk: true, lukso: true, lumia: true, + lumiaprism: true, mantapacific: true, mantle: true, merlin: true, @@ -124,9 +130,14 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< snaxchain: true, solanamainnet: true, stride: false, + superseed: true, superpositionmainnet: true, + swell: true, taiko: true, tangle: true, + treasure: true, + unichain: true, + vana: true, viction: true, worldchain: true, xai: true, @@ -134,6 +145,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< zeronetwork: true, zetachain: true, zircuit: true, + zklink: true, zksync: true, zoramainnet: true, }, @@ -141,6 +153,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< ancient8: true, alephzeroevmmainnet: true, apechain: true, + appchain: true, arbitrum: true, arbitrumnova: true, astar: true, @@ -152,7 +165,9 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< bitlayer: true, blast: true, bob: true, + boba: true, bsc: true, + bsquared: true, celo: true, cheesechain: true, chilizmainnet: true, @@ -160,6 +175,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< cyber: true, degenchain: true, dogechain: true, + duckchain: true, eclipsemainnet: true, endurance: true, ethereum: true, @@ -181,6 +197,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< lisk: true, lukso: true, lumia: true, + lumiaprism: true, mantapacific: true, mantle: true, merlin: true, @@ -213,9 +230,14 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< snaxchain: true, solanamainnet: true, stride: true, + superseed: true, superpositionmainnet: true, + swell: true, taiko: true, tangle: true, + treasure: true, + unichain: true, + vana: true, viction: true, worldchain: true, xai: true, @@ -223,6 +245,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< zeronetwork: true, zetachain: true, zircuit: true, + zklink: true, zksync: true, zoramainnet: true, }, @@ -230,6 +253,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< ancient8: true, alephzeroevmmainnet: true, apechain: true, + appchain: true, arbitrum: true, arbitrumnova: true, astar: true, @@ -241,7 +265,9 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< bitlayer: true, blast: true, bob: true, + boba: true, bsc: true, + bsquared: true, celo: true, cheesechain: true, chilizmainnet: true, @@ -249,6 +275,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< cyber: true, degenchain: true, dogechain: true, + duckchain: true, // Cannot scrape Sealevel chains eclipsemainnet: false, endurance: true, @@ -271,6 +298,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< lisk: true, lukso: true, lumia: true, + lumiaprism: true, mantapacific: true, mantle: true, merlin: true, @@ -303,9 +331,14 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< // Cannot scrape Sealevel chains solanamainnet: false, stride: true, + superseed: true, superpositionmainnet: true, + swell: true, taiko: true, tangle: true, + treasure: true, + unichain: true, + vana: true, // Has RPC non-compliance that breaks scraping. viction: false, worldchain: true, @@ -314,6 +347,7 @@ export const hyperlaneContextAgentChainConfig: AgentChainConfig< zeronetwork: true, zetachain: true, zircuit: true, + zklink: true, zksync: true, zoramainnet: true, }, @@ -395,6 +429,12 @@ const metricAppContextsGetter = (): MetricAppContext[] => { name: 'aave', matchingList: senderMatchingList(aaveSenderAddresses), }, + { + // https://docs.everclear.org/resources/contracts/mainnet + // Messages between HubGateway (Everclear hub) <> EverclearSpoke (all other spoke chains) + name: 'everclear_gateway', + matchingList: senderMatchingList(everclearSenderAddresses), + }, ]; }; @@ -402,7 +442,7 @@ const metricAppContextsGetter = (): MetricAppContext[] => { const relayerResources = { requests: { cpu: '14000m', - memory: '12Gi', + memory: '15Gi', }, }; @@ -429,7 +469,7 @@ const hyperlane: RootAgentConfig = { rpcConsensusType: RpcConsensusType.Fallback, docker: { repo, - tag: '25a927d-20241114-171323', + tag: 'a7f3967-20241205-163733', }, gasPaymentEnforcement: gasPaymentEnforcement, metricAppContextsGetter, @@ -438,7 +478,7 @@ const hyperlane: RootAgentConfig = { validators: { docker: { repo, - tag: '75d62ae-20241107-060707', + tag: 'a7f3967-20241205-163733', }, rpcConsensusType: RpcConsensusType.Quorum, chains: validatorChainConfig(Contexts.Hyperlane), @@ -448,7 +488,7 @@ const hyperlane: RootAgentConfig = { rpcConsensusType: RpcConsensusType.Fallback, docker: { repo, - tag: '75d62ae-20241107-060707', + tag: '4b280cd-20241206-130519', }, resources: scraperResources, }, @@ -463,7 +503,7 @@ const releaseCandidate: RootAgentConfig = { rpcConsensusType: RpcConsensusType.Fallback, docker: { repo, - tag: '25a927d-20241114-171323', + tag: '4cb2c9a-20241205-142854', }, // We're temporarily (ab)using the RC relayer as a way to increase // message throughput. diff --git a/typescript/infra/config/environments/mainnet3/aw-validators/hyperlane.json b/typescript/infra/config/environments/mainnet3/aw-validators/hyperlane.json index fddbdc762e..9e39d900ce 100644 --- a/typescript/infra/config/environments/mainnet3/aw-validators/hyperlane.json +++ b/typescript/infra/config/environments/mainnet3/aw-validators/hyperlane.json @@ -8,6 +8,9 @@ "apechain": { "validators": ["0x773d7fe6ffb1ba4de814c28044ff9a2d83a48221"] }, + "appchain": { + "validators": ["0x0531251bbadc1f9f19ccce3ca6b3f79f08eae1be"] + }, "arbitrum": { "validators": [ "0x4d966438fe9e2b1e7124c87bbb90cb4f0f6c59a1", @@ -53,6 +56,9 @@ "bob": { "validators": ["0x20f283be1eb0e81e22f51705dcb79883cfdd34aa"] }, + "boba": { + "validators": ["0xebeb92c94ca8408e73aa16fd554cb3a7df075c59"] + }, "bsc": { "validators": [ "0x570af9b7b36568c8877eebba6c6727aa9dab7268", @@ -60,6 +66,9 @@ "0x03047213365800f065356b4a2fe97c3c3a52296a" ] }, + "bsquared": { + "validators": ["0xcadc90933c9fbe843358a4e70e46ad2db78e28aa"] + }, "celo": { "validators": [ "0x63478422679303c3e4fc611b771fa4a707ef7f4a", @@ -85,6 +94,9 @@ "dogechain": { "validators": ["0xe43f742c37858746e6d7e458bc591180d0cba440"] }, + "duckchain": { + "validators": ["0x91d55fe6dac596a6735d96365e21ce4bca21d83c"] + }, "eclipsemainnet": { "validators": ["0xebb52d7eaa3ff7a5a6260bfe5111ce52d57401d0"] }, @@ -160,6 +172,9 @@ "lumia": { "validators": ["0x9e283254ed2cd2c80f007348c2822fc8e5c2fa5f"] }, + "lumiaprism": { + "validators": ["0xb69731640ffd4338a2c9358a935b0274c6463f85"] + }, "mantapacific": { "validators": [ "0x8e668c97ad76d0e28375275c41ece4972ab8a5bc", @@ -278,15 +293,30 @@ "solanamainnet": { "validators": ["0x28464752829b3ea59a497fca0bdff575c534c3ff"] }, + "superseed": { + "validators": ["0xdc2b87cb555411bb138d3a4e5f7832c87fae2b88"] + }, "superpositionmainnet": { "validators": ["0x3f489acdd341c6b4dd86293fa2cc5ecc8ccf4f84"] }, + "swell": { + "validators": ["0x4f51e4f4c7fb45d82f91568480a1a2cfb69216ed"] + }, "taiko": { "validators": ["0xa930073c8f2d0b2f7423ea32293e0d1362e65d79"] }, "tangle": { "validators": ["0x1ee52cbbfacd7dcb0ba4e91efaa6fbc61602b15b"] }, + "treasure": { + "validators": ["0x6ad994819185553e8baa01533f0cd2c7cadfe6cc"] + }, + "unichain": { + "validators": ["0x9773a382342ebf604a2e5de0a1f462fb499e28b1"] + }, + "vana": { + "validators": ["0xfdf3b0dfd4b822d10cacb15c8ae945ea269e7534"] + }, "viction": { "validators": ["0x1f87c368f8e05a85ef9126d984a980a20930cb9c"] }, @@ -308,6 +338,9 @@ "zircuit": { "validators": ["0x169ec400cc758fef3df6a0d6c51fbc6cdd1015bb"] }, + "zklink": { + "validators": ["0x217a8cb4789fc45abf56cb6e2ca96f251a5ac181"] + }, "zksync": { "validators": ["0xadd1d39ce7a687e32255ac457cf99a6d8c5b5d1a"] }, diff --git a/typescript/infra/config/environments/mainnet3/core.ts b/typescript/infra/config/environments/mainnet3/core.ts index 761c4f37de..b0655ae785 100644 --- a/typescript/infra/config/environments/mainnet3/core.ts +++ b/typescript/infra/config/environments/mainnet3/core.ts @@ -16,6 +16,7 @@ import { ProtocolFeeHookConfig, RoutingIsmConfig, defaultMultisigConfigs, + multisigConfigToIsmConfig, } from '@hyperlane-xyz/sdk'; import { Address, objMap } from '@hyperlane-xyz/utils'; @@ -32,15 +33,11 @@ export const core: ChainMap = objMap( .map((origin) => [origin, defaultMultisigConfigs[origin]]), ); - const merkleRoot = (multisig: MultisigConfig): MultisigIsmConfig => ({ - type: IsmType.MERKLE_ROOT_MULTISIG, - ...multisig, - }); + const merkleRoot = (multisig: MultisigConfig): MultisigIsmConfig => + multisigConfigToIsmConfig(IsmType.MERKLE_ROOT_MULTISIG, multisig); - const messageIdIsm = (multisig: MultisigConfig): MultisigIsmConfig => ({ - type: IsmType.MESSAGE_ID_MULTISIG, - ...multisig, - }); + const messageIdIsm = (multisig: MultisigConfig): MultisigIsmConfig => + multisigConfigToIsmConfig(IsmType.MESSAGE_ID_MULTISIG, multisig); const routingIsm: RoutingIsmConfig = { type: IsmType.ROUTING, diff --git a/typescript/infra/config/environments/mainnet3/core/verification.json b/typescript/infra/config/environments/mainnet3/core/verification.json index 0a9ab38bb5..44f999186b 100644 --- a/typescript/infra/config/environments/mainnet3/core/verification.json +++ b/typescript/infra/config/environments/mainnet3/core/verification.json @@ -5376,5 +5376,751 @@ "constructorArguments": "00000000000000000000000096d51cc3f7500d501baeb1a2a62bb96fa03532f8", "isProxy": false } + ], + "boba": [ + { + "name": "ProxyAdmin", + "address": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", + "constructorArguments": "0000000000000000000000000000000000000000000000000000000000000120", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "constructorArguments": "000000000000000000000000ea87ae93fa0019a82a727bfd3ebd1cfca8f64f1d0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D" + }, + { + "name": "MerkleTreeHook", + "address": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "FallbackRoutingHook", + "address": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba0000000000000000000000009eaac366bfd70430cfee6e70265fefff1cfc9e47", + "isProxy": false + }, + { + "name": "PausableHook", + "address": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "constructorArguments": "00000000000000000000000083475ca5beb2eaa59a2ff48a0544ebaa4a32c2de0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de" + }, + { + "name": "ProtocolFee", + "address": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba", + "isProxy": false + }, + { + "name": "ValidatorAnnounce", + "address": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + } + ], + "superseed": [ + { + "name": "ProxyAdmin", + "address": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", + "constructorArguments": "00000000000000000000000000000000000000000000000000000000000014d2", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "constructorArguments": "000000000000000000000000ea87ae93fa0019a82a727bfd3ebd1cfca8f64f1d0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D" + }, + { + "name": "MerkleTreeHook", + "address": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "FallbackRoutingHook", + "address": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba0000000000000000000000009eaac366bfd70430cfee6e70265fefff1cfc9e47", + "isProxy": false + }, + { + "name": "PausableHook", + "address": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "constructorArguments": "00000000000000000000000083475ca5beb2eaa59a2ff48a0544ebaa4a32c2de0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de" + }, + { + "name": "ProtocolFee", + "address": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba", + "isProxy": false + }, + { + "name": "ValidatorAnnounce", + "address": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + } + ], + "unichain": [ + { + "name": "ProxyAdmin", + "address": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", + "constructorArguments": "0000000000000000000000000000000000000000000000000000000000000082", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "constructorArguments": "000000000000000000000000ea87ae93fa0019a82a727bfd3ebd1cfca8f64f1d0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D" + }, + { + "name": "MerkleTreeHook", + "address": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "FallbackRoutingHook", + "address": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba0000000000000000000000009eaac366bfd70430cfee6e70265fefff1cfc9e47", + "isProxy": false + }, + { + "name": "PausableHook", + "address": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "constructorArguments": "00000000000000000000000083475ca5beb2eaa59a2ff48a0544ebaa4a32c2de0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de" + }, + { + "name": "ProtocolFee", + "address": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba", + "isProxy": false + }, + { + "name": "ValidatorAnnounce", + "address": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + } + ], + "duckchain": [ + { + "name": "ProxyAdmin", + "address": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", + "constructorArguments": "00000000000000000000000000000000000000000000000000000000000015a9", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "constructorArguments": "000000000000000000000000ea87ae93fa0019a82a727bfd3ebd1cfca8f64f1d0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D" + }, + { + "name": "MerkleTreeHook", + "address": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "FallbackRoutingHook", + "address": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba0000000000000000000000009eaac366bfd70430cfee6e70265fefff1cfc9e47", + "isProxy": false + }, + { + "name": "PausableHook", + "address": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "constructorArguments": "00000000000000000000000083475ca5beb2eaa59a2ff48a0544ebaa4a32c2de0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de" + }, + { + "name": "ProtocolFee", + "address": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba", + "isProxy": false + }, + { + "name": "ValidatorAnnounce", + "address": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + } + ], + "vana": [ + { + "name": "ProxyAdmin", + "address": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", + "constructorArguments": "00000000000000000000000000000000000000000000000000000000000005c8", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "constructorArguments": "000000000000000000000000ea87ae93fa0019a82a727bfd3ebd1cfca8f64f1d0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D" + }, + { + "name": "MerkleTreeHook", + "address": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "FallbackRoutingHook", + "address": "0x0D3bD9F1bcDA82bD1682b2C895a907d7aaE45849", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba0000000000000000000000009eaac366bfd70430cfee6e70265fefff1cfc9e47", + "isProxy": false + }, + { + "name": "PausableHook", + "address": "0x9eb56085DdbDA60aDf7d2B533AFeD90e38fC9666", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x9534122Aae7978dB8f5f10dF4432233c53e820A1", + "constructorArguments": "00000000000000000000000083475ca5beb2eaa59a2ff48a0544ebaa4a32c2de0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de" + }, + { + "name": "ProtocolFee", + "address": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba", + "isProxy": false + }, + { + "name": "ValidatorAnnounce", + "address": "0xD743801ABB6c7664B623D8534C0f5AF8cD2F1C5e", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + } + ], + "bsquared": [ + { + "name": "ProxyAdmin", + "address": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", + "constructorArguments": "00000000000000000000000000000000000000000000000000000000000000df", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "constructorArguments": "000000000000000000000000ea87ae93fa0019a82a727bfd3ebd1cfca8f64f1d0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D" + }, + { + "name": "MerkleTreeHook", + "address": "0xbb0AE51BCa526cF313b6a95BfaB020794af6C394", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "FallbackRoutingHook", + "address": "0x60bB6D060393D3C206719A7bD61844cC82891cfB", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000bb0ae51bca526cf313b6a95bfab020794af6c394", + "isProxy": false + }, + { + "name": "PausableHook", + "address": "0x83475ca5bEB2Eaa59A2FF48a0544ebaa4a32c2de", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0x451dF8AB0936D85526D816f0b4dCaDD934A034A4", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0x81EbEdfc1220BE33C3B9c5E09c1FCab849a392A6", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x70EbA87Cd15616f32C736B3f3BdCfaeD0713a82B", + "constructorArguments": "00000000000000000000000081ebedfc1220be33c3b9c5e09c1fcab849a392a60000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x81EbEdfc1220BE33C3B9c5E09c1FCab849a392A6" + }, + { + "name": "ProtocolFee", + "address": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba", + "isProxy": false + }, + { + "name": "ValidatorAnnounce", + "address": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + } + ], + "lumiaprism": [ + { + "name": "ProxyAdmin", + "address": "0x200183De44bf765ECB73cD62A74010EaaBC43146", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xcD78A32Da8cfe9452cD2F50F547c11B979Afcf1b", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9be739", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x0dF25A2d59F03F039b56E90EdC5B89679Ace28Bc", + "constructorArguments": "000000000000000000000000cd78a32da8cfe9452cd2f50f547c11b979afcf1b000000000000000000000000200183de44bf765ecb73cd62a74010eaabc4314600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xcD78A32Da8cfe9452cD2F50F547c11B979Afcf1b" + }, + { + "name": "MerkleTreeHook", + "address": "0xC88636fFdFAc7cb87b7A76310B7a62AF0A000595", + "constructorArguments": "0000000000000000000000000df25a2d59f03f039b56e90edc5b89679ace28bc", + "isProxy": false + }, + { + "name": "FallbackRoutingHook", + "address": "0x850615dF99FEc6edffC77Ff246f604a6f7Df6a78", + "constructorArguments": "0000000000000000000000000df25a2d59f03f039b56e90edc5b89679ace28bc000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000c88636ffdfac7cb87b7a76310b7a62af0a000595", + "isProxy": false + }, + { + "name": "PausableHook", + "address": "0x2AF32cF8e3Cf42d221eDa0c843818fA5ee129E27", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0x3c38fC01159E7BE0685653A0C896eA49F2BAa7c1", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0x89994F8289Eca4A209b8D768F25d48b090E60987", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0xb7C9307fE90B9AB093c6D3EdeE3259f5378D5f03", + "constructorArguments": "00000000000000000000000089994f8289eca4a209b8d768f25d48b090e60987000000000000000000000000200183de44bf765ecb73cd62a74010eaabc4314600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x89994F8289Eca4A209b8D768F25d48b090E60987" + }, + { + "name": "ProtocolFee", + "address": "0x14891ce5AF49fb21182C1dc8B81853f3493B1B5B", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba", + "isProxy": false + }, + { + "name": "ValidatorAnnounce", + "address": "0x803d2A87429E20d4B52266bF97Ca1c7e4f4F5Dfa", + "constructorArguments": "0000000000000000000000000df25a2d59f03f039b56e90edc5b89679ace28bc", + "isProxy": false + } + ], + "swell": [ + { + "name": "ProxyAdmin", + "address": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", + "constructorArguments": "0000000000000000000000000000000000000000000000000000000000000783", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "constructorArguments": "000000000000000000000000ea87ae93fa0019a82a727bfd3ebd1cfca8f64f1d0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D" + }, + { + "name": "MerkleTreeHook", + "address": "0x5C02157068a52cEcfc98EDb6115DE6134EcB4764", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "FallbackRoutingHook", + "address": "0x70EbA87Cd15616f32C736B3f3BdCfaeD0713a82B", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba0000000000000000000000005c02157068a52cecfc98edb6115de6134ecb4764", + "isProxy": false + }, + { + "name": "PausableHook", + "address": "0x99fEFc1119E86Ee0153eb887cF8E8ab2d92A16e8", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0xCDeb368Db32ecCefaf7018e152DA9120565cb572", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "constructorArguments": "000000000000000000000000bb88a31e4b709b645c06825c0e0b5cac906d97de0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xbB88a31E4b709b645c06825c0E0b5CAC906d97DE" + }, + { + "name": "ProtocolFee", + "address": "0x7CE76f5f0C469bBB4cd7Ea6EbabB54437A093127", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba", + "isProxy": false + }, + { + "name": "ValidatorAnnounce", + "address": "0x4D50044335dc1d4D26c343AdeDf6E47808475Deb", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + } + ], + "zklink": [ + { + "name": "ProxyAdmin", + "address": "0x038F9F4e93e88Af2C688da265222FdE80e455aA4", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xA3949b37109d64b10De93252EeFebBB2E6B8944F", + "constructorArguments": "00000000000000000000000000000000000000000000000000000000000c5cc4", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x9BbDf86b272d224323136E15594fdCe487F40ce7", + "constructorArguments": "000000000000000000000000a3949b37109d64b10de93252eefebbb2e6b8944f000000000000000000000000038f9f4e93e88af2c688da265222fde80e455aa400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xA3949b37109d64b10De93252EeFebBB2E6B8944F" + }, + { + "name": "MerkleTreeHook", + "address": "0xA1ADFCa9666Bcd68b7b5C8b55e3ecC465DcDfE65", + "constructorArguments": "0000000000000000000000009bbdf86b272d224323136e15594fdce487f40ce7", + "isProxy": false + }, + { + "name": "FallbackDomainRoutingHook", + "address": "0x388289cd5862e17AAfD6ffF7F46A9Ec48a969bCd", + "constructorArguments": "0000000000000000000000009bbdf86b272d224323136e15594fdce487f40ce7000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a1adfca9666bcd68b7b5c8b55e3ecc465dcdfe65", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0x73a82061Cd258d02BEa145fe183120456e718c2A", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0x54E88f2ab58E0Ab4B7Ce081FB20D85b16af041d2", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0xB35eCb9714e8f48332Af22B48C18ca21E2607438", + "constructorArguments": "00000000000000000000000054e88f2ab58e0ab4b7ce081fb20d85b16af041d2000000000000000000000000038f9f4e93e88af2c688da265222fde80e455aa400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x54E88f2ab58E0Ab4B7Ce081FB20D85b16af041d2" + }, + { + "name": "ValidatorAnnounce", + "address": "0xf5626c0f33Ca102eb3ca1633A410cd8aa92909e4", + "constructorArguments": "0000000000000000000000009bbdf86b272d224323136e15594fdce487f40ce7", + "isProxy": false + } + ], + "appchain": [ + { + "name": "ProxyAdmin", + "address": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", + "constructorArguments": "00000000000000000000000000000000000000000000000000000000000001d2", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", + "constructorArguments": "000000000000000000000000ea87ae93fa0019a82a727bfd3ebd1cfca8f64f1d0000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D" + }, + { + "name": "MerkleTreeHook", + "address": "0xcd90D49b046772F710250b9119117169CB2e4D8b", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "FallbackRoutingHook", + "address": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000cd90d49b046772f710250b9119117169cb2e4d8b", + "isProxy": false + }, + { + "name": "PausableHook", + "address": "0x7CE76f5f0C469bBB4cd7Ea6EbabB54437A093127", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0xA376b27212D608324808923Add679A2c9FAFe9Da", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0xBC53dACd8c0ac0d2bAC461479EAaf5519eCC8853", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x28291a7062afA569104bEd52F7AcCA3dD2FafD11", + "constructorArguments": "000000000000000000000000bc53dacd8c0ac0d2bac461479eaaf5519ecc88530000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xBC53dACd8c0ac0d2bAC461479EAaf5519eCC8853" + }, + { + "name": "ProtocolFee", + "address": "0xD35Aa652C1F808d3f87DA3DC7974fea888D7d625", + "constructorArguments": "000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba", + "isProxy": false + }, + { + "name": "ValidatorAnnounce", + "address": "0x1196055C61af3e3DA6f8458B07b255a72b64Bcf7", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + } + ], + "treasure": [ + { + "name": "ProxyAdmin", + "address": "0x038F9F4e93e88Af2C688da265222FdE80e455aA4", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "Mailbox", + "address": "0xA3949b37109d64b10De93252EeFebBB2E6B8944F", + "constructorArguments": "000000000000000000000000000000000000000000000000000000000000eeee", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x9BbDf86b272d224323136E15594fdCe487F40ce7", + "constructorArguments": "000000000000000000000000a3949b37109d64b10de93252eefebbb2e6b8944f000000000000000000000000038f9f4e93e88af2c688da265222fde80e455aa400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xA3949b37109d64b10De93252EeFebBB2E6B8944F" + }, + { + "name": "MerkleTreeHook", + "address": "0xc1FC99Ea4D8B2b06b674A2e91b5A4617c1dcFd22", + "constructorArguments": "0000000000000000000000009bbdf86b272d224323136e15594fdce487f40ce7", + "isProxy": false + }, + { + "name": "FallbackDomainRoutingHook", + "address": "0x697a90753B7dCf6512189c239E612fC12baaE500", + "constructorArguments": "0000000000000000000000009bbdf86b272d224323136e15594fdce487f40ce7000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000c1fc99ea4d8b2b06b674a2e91b5a4617c1dcfd22", + "isProxy": false + }, + { + "name": "StorageGasOracle", + "address": "0xc364cfedefE854c1275B0f4088EaFA9695e1FC56", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "InterchainGasPaymaster", + "address": "0xA1ADFCa9666Bcd68b7b5C8b55e3ecC465DcDfE65", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x388289cd5862e17AAfD6ffF7F46A9Ec48a969bCd", + "constructorArguments": "000000000000000000000000a1adfca9666bcd68b7b5c8b55e3ecc465dcdfe65000000000000000000000000038f9f4e93e88af2c688da265222fde80e455aa400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044485cc955000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xA1ADFCa9666Bcd68b7b5C8b55e3ecC465DcDfE65" + }, + { + "name": "ValidatorAnnounce", + "address": "0x73a82061Cd258d02BEa145fe183120456e718c2A", + "constructorArguments": "0000000000000000000000009bbdf86b272d224323136e15594fdce487f40ce7", + "isProxy": false + } ] } diff --git a/typescript/infra/config/environments/mainnet3/funding.ts b/typescript/infra/config/environments/mainnet3/funding.ts index 03803fefa2..74f624ed72 100644 --- a/typescript/infra/config/environments/mainnet3/funding.ts +++ b/typescript/infra/config/environments/mainnet3/funding.ts @@ -10,7 +10,7 @@ export const keyFunderConfig: KeyFunderConfig< > = { docker: { repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', - tag: '1ed620c-20241107-052148', + tag: 'a7f3967-20241205-163749', }, // We're currently using the same deployer/key funder key as mainnet2. // To minimize nonce clobbering we offset the key funder cron @@ -29,6 +29,7 @@ export const keyFunderConfig: KeyFunderConfig< ancient8: '0.5', alephzeroevmmainnet: '100', apechain: '50', + appchain: '0.05', arbitrum: '0.5', arbitrumnova: '0.05', astar: '100', @@ -40,7 +41,9 @@ export const keyFunderConfig: KeyFunderConfig< bitlayer: '0.002', blast: '0.2', bob: '0.2', + boba: '0.05', bsc: '5', + bsquared: '0.002', celo: '3', cheesechain: '50', chilizmainnet: '200', @@ -48,6 +51,7 @@ export const keyFunderConfig: KeyFunderConfig< cyber: '0.05', degenchain: '100', dogechain: '100', + duckchain: '5', endurance: '20', ethereum: '0.5', everclear: '0.05', @@ -67,6 +71,7 @@ export const keyFunderConfig: KeyFunderConfig< lisk: '0.05', lukso: '20', lumia: '1', + lumiaprism: '1', mantapacific: '0.2', mantle: '20', merlin: '0.002', @@ -96,9 +101,15 @@ export const keyFunderConfig: KeyFunderConfig< snaxchain: '0.05', // ignore non-evm chains stride: '0', + superseed: '0.05', superpositionmainnet: '0.05', + swell: '0.05', taiko: '0.2', tangle: '2', + treasure: '100', + unichain: '0.05', + // temporarily low until we're able to fund more + vana: '0.001', viction: '3', worldchain: '0.2', xai: '20', @@ -106,6 +117,7 @@ export const keyFunderConfig: KeyFunderConfig< zeronetwork: '0.05', zetachain: '20', zircuit: '0.02', + zklink: '0.05', zksync: '0.05', zoramainnet: '0.2', // ignore non-evm chains diff --git a/typescript/infra/config/environments/mainnet3/gasPrices.json b/typescript/infra/config/environments/mainnet3/gasPrices.json index e0eb030933..1009f5eee1 100644 --- a/typescript/infra/config/environments/mainnet3/gasPrices.json +++ b/typescript/infra/config/environments/mainnet3/gasPrices.json @@ -11,10 +11,14 @@ "amount": "25.42069", "decimals": 9 }, - "arbitrum": { + "appchain": { "amount": "0.01", "decimals": 9 }, + "arbitrum": { + "amount": "0.123544", + "decimals": 9 + }, "arbitrumnova": { "amount": "0.01", "decimals": 9 @@ -24,7 +28,7 @@ "decimals": 9 }, "astarzkevm": { - "amount": "0.078", + "amount": "0.24", "decimals": 9 }, "flame": { @@ -36,11 +40,11 @@ "decimals": 9 }, "b3": { - "amount": "0.001000254", + "amount": "0.001000252", "decimals": 9 }, "base": { - "amount": "0.004893247", + "amount": "0.060189299", "decimals": 9 }, "bitlayer": { @@ -48,17 +52,25 @@ "decimals": 9 }, "blast": { - "amount": "0.005018176", + "amount": "0.005892268", "decimals": 9 }, "bob": { "amount": "0.001000252", "decimals": 9 }, + "boba": { + "amount": "0.001000047", + "decimals": 9 + }, "bsc": { "amount": "1.0", "decimals": 9 }, + "bsquared": { + "amount": "0.001000252", + "decimals": 9 + }, "celo": { "amount": "10.0", "decimals": 9 @@ -87,6 +99,10 @@ "amount": "250.0", "decimals": 9 }, + "duckchain": { + "amount": "10.0", + "decimals": 9 + }, "eclipsemainnet": { "amount": "0.0000001", "decimals": 1 @@ -96,7 +112,7 @@ "decimals": 9 }, "ethereum": { - "amount": "15.0", + "amount": "30.088451558", "decimals": 9 }, "everclear": { @@ -124,7 +140,7 @@ "decimals": 9 }, "gnosis": { - "amount": "1.500000007", + "amount": "1.500000008", "decimals": 9 }, "gravity": { @@ -136,7 +152,7 @@ "decimals": 9 }, "immutablezkevmmainnet": { - "amount": "10.000000056", + "amount": "11.00000005", "decimals": 9 }, "inevm": { @@ -156,7 +172,7 @@ "decimals": 9 }, "linea": { - "amount": "0.160485013", + "amount": "0.548523195", "decimals": 9 }, "lisk": { @@ -164,15 +180,19 @@ "decimals": 9 }, "lukso": { - "amount": "0.475094399", + "amount": "0.921815267", "decimals": 9 }, "lumia": { "amount": "1.0", "decimals": 9 }, + "lumiaprism": { + "amount": "1.0", + "decimals": 9 + }, "mantapacific": { - "amount": "0.003001158", + "amount": "0.00300029", "decimals": 9 }, "mantle": { @@ -208,7 +228,7 @@ "decimals": 9 }, "morph": { - "amount": "0.002", + "amount": "0.201", "decimals": 9 }, "neutron": { @@ -220,7 +240,7 @@ "decimals": 9 }, "optimism": { - "amount": "0.001010111", + "amount": "0.001065045", "decimals": 9 }, "orderly": { @@ -232,11 +252,11 @@ "decimals": 1 }, "polygon": { - "amount": "47.07124319", + "amount": "260.197309239", "decimals": 9 }, "polygonzkevm": { - "amount": "0.146", + "amount": "0.451", "decimals": 9 }, "polynomialfi": { @@ -244,7 +264,7 @@ "decimals": 9 }, "prom": { - "amount": "13.1", + "amount": "546.0", "decimals": 9 }, "proofofplay": { @@ -280,7 +300,7 @@ "decimals": 9 }, "shibarium": { - "amount": "0.542811448", + "amount": "5.040876434", "decimals": 9 }, "snaxchain": { @@ -295,24 +315,44 @@ "amount": "0.005", "decimals": 1 }, + "superseed": { + "amount": "0.001000252", + "decimals": 9 + }, "superpositionmainnet": { "amount": "0.01", "decimals": 9 }, + "swell": { + "amount": "0.001000251", + "decimals": 9 + }, "taiko": { - "amount": "0.1323", + "amount": "0.200795266", "decimals": 9 }, "tangle": { "amount": "1.0", "decimals": 9 }, + "treasure": { + "amount": "10000.0", + "decimals": 9 + }, + "unichain": { + "amount": "0.001000252", + "decimals": 9 + }, + "vana": { + "amount": "0.002488334", + "decimals": 9 + }, "viction": { "amount": "0.25", "decimals": 9 }, "worldchain": { - "amount": "0.00100025", + "amount": "0.00100026", "decimals": 9 }, "xai": { @@ -320,7 +360,7 @@ "decimals": 9 }, "xlayer": { - "amount": "7.04", + "amount": "23.05", "decimals": 9 }, "zeronetwork": { @@ -335,12 +375,16 @@ "amount": "0.001000253", "decimals": 9 }, + "zklink": { + "amount": "0.125", + "decimals": 9 + }, "zksync": { "amount": "0.04525", "decimals": 9 }, "zoramainnet": { - "amount": "0.001000269", + "amount": "0.001000252", "decimals": 9 } } diff --git a/typescript/infra/config/environments/mainnet3/ism/verification.json b/typescript/infra/config/environments/mainnet3/ism/verification.json index 928bceb8b5..5cceb318f4 100644 --- a/typescript/infra/config/environments/mainnet3/ism/verification.json +++ b/typescript/infra/config/environments/mainnet3/ism/verification.json @@ -6916,5 +6916,779 @@ "constructorArguments": "", "isProxy": true } + ], + "superseed": [ + { + "name": "StaticMerkleRootMultisigIsmFactory", + "address": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootMultisigIsm", + "address": "0x4725F7b8037513915aAf6D6CBDE2920E28540dDc", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdMultisigIsmFactory", + "address": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdMultisigIsm", + "address": "0xAF03386044373E2fe26C5b1dCedF5a7e854a7a3F", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationIsmFactory", + "address": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationIsm", + "address": "0x882CD0C5D50b6dD74b36Da4BDb059507fddEDdf2", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationHookFactory", + "address": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationHook", + "address": "0x19930232E9aFC4f4F09d09fe2375680fAc2100D0", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "DomainRoutingIsmFactory", + "address": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "DomaingRoutingIsm", + "address": "0x12Ed1BbA182CbC63692F813651BD493B7445C874", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMerkleRootWeightedMultisigIsmFactory", + "address": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootWeightedMultisigIsm", + "address": "0x3b9f24fD2ecfed0d3A88fa7f0E4e5747671981D7", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdWeightedMultisigIsmFactory", + "address": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdWeightedMultisigIsm", + "address": "0x71DCcD21B912F7d4f636af0C9eA5DC0C10617354", + "constructorArguments": "", + "isProxy": true + } + ], + "unichain": [ + { + "name": "StaticMerkleRootMultisigIsmFactory", + "address": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootMultisigIsm", + "address": "0x4725F7b8037513915aAf6D6CBDE2920E28540dDc", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdMultisigIsmFactory", + "address": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdMultisigIsm", + "address": "0xAF03386044373E2fe26C5b1dCedF5a7e854a7a3F", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationIsmFactory", + "address": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationIsm", + "address": "0x882CD0C5D50b6dD74b36Da4BDb059507fddEDdf2", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationHookFactory", + "address": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationHook", + "address": "0x19930232E9aFC4f4F09d09fe2375680fAc2100D0", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "DomainRoutingIsmFactory", + "address": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "DomaingRoutingIsm", + "address": "0x12Ed1BbA182CbC63692F813651BD493B7445C874", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMerkleRootWeightedMultisigIsmFactory", + "address": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootWeightedMultisigIsm", + "address": "0x3b9f24fD2ecfed0d3A88fa7f0E4e5747671981D7", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdWeightedMultisigIsmFactory", + "address": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdWeightedMultisigIsm", + "address": "0x71DCcD21B912F7d4f636af0C9eA5DC0C10617354", + "constructorArguments": "", + "isProxy": true + } + ], + "duckchain": [ + { + "name": "StaticMerkleRootMultisigIsmFactory", + "address": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootMultisigIsm", + "address": "0x4725F7b8037513915aAf6D6CBDE2920E28540dDc", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdMultisigIsmFactory", + "address": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdMultisigIsm", + "address": "0xAF03386044373E2fe26C5b1dCedF5a7e854a7a3F", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationIsmFactory", + "address": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationIsm", + "address": "0x882CD0C5D50b6dD74b36Da4BDb059507fddEDdf2", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationHookFactory", + "address": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationHook", + "address": "0x19930232E9aFC4f4F09d09fe2375680fAc2100D0", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "DomainRoutingIsmFactory", + "address": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "DomaingRoutingIsm", + "address": "0x12Ed1BbA182CbC63692F813651BD493B7445C874", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMerkleRootWeightedMultisigIsmFactory", + "address": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootWeightedMultisigIsm", + "address": "0x3b9f24fD2ecfed0d3A88fa7f0E4e5747671981D7", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdWeightedMultisigIsmFactory", + "address": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdWeightedMultisigIsm", + "address": "0x71DCcD21B912F7d4f636af0C9eA5DC0C10617354", + "constructorArguments": "", + "isProxy": true + } + ], + "vana": [ + { + "name": "StaticMerkleRootMultisigIsmFactory", + "address": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootMultisigIsm", + "address": "0x4725F7b8037513915aAf6D6CBDE2920E28540dDc", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdMultisigIsmFactory", + "address": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdMultisigIsm", + "address": "0xAF03386044373E2fe26C5b1dCedF5a7e854a7a3F", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationIsmFactory", + "address": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationIsm", + "address": "0x882CD0C5D50b6dD74b36Da4BDb059507fddEDdf2", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationHookFactory", + "address": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationHook", + "address": "0x19930232E9aFC4f4F09d09fe2375680fAc2100D0", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "DomainRoutingIsmFactory", + "address": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "DomaingRoutingIsm", + "address": "0x12Ed1BbA182CbC63692F813651BD493B7445C874", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMerkleRootWeightedMultisigIsmFactory", + "address": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootWeightedMultisigIsm", + "address": "0x3b9f24fD2ecfed0d3A88fa7f0E4e5747671981D7", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdWeightedMultisigIsmFactory", + "address": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdWeightedMultisigIsm", + "address": "0x71DCcD21B912F7d4f636af0C9eA5DC0C10617354", + "constructorArguments": "", + "isProxy": true + } + ], + "boba": [ + { + "name": "StaticMerkleRootMultisigIsmFactory", + "address": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootMultisigIsm", + "address": "0x4725F7b8037513915aAf6D6CBDE2920E28540dDc", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdMultisigIsmFactory", + "address": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdMultisigIsm", + "address": "0xAF03386044373E2fe26C5b1dCedF5a7e854a7a3F", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationIsmFactory", + "address": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationIsm", + "address": "0x882CD0C5D50b6dD74b36Da4BDb059507fddEDdf2", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationHookFactory", + "address": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationHook", + "address": "0x19930232E9aFC4f4F09d09fe2375680fAc2100D0", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "DomainRoutingIsmFactory", + "address": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "DomaingRoutingIsm", + "address": "0x12Ed1BbA182CbC63692F813651BD493B7445C874", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMerkleRootWeightedMultisigIsmFactory", + "address": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootWeightedMultisigIsm", + "address": "0x3b9f24fD2ecfed0d3A88fa7f0E4e5747671981D7", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdWeightedMultisigIsmFactory", + "address": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdWeightedMultisigIsm", + "address": "0x71DCcD21B912F7d4f636af0C9eA5DC0C10617354", + "constructorArguments": "", + "isProxy": true + } + ], + "bsquared": [ + { + "name": "StaticMerkleRootMultisigIsmFactory", + "address": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootMultisigIsm", + "address": "0x4725F7b8037513915aAf6D6CBDE2920E28540dDc", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdMultisigIsmFactory", + "address": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdMultisigIsm", + "address": "0xAF03386044373E2fe26C5b1dCedF5a7e854a7a3F", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationIsmFactory", + "address": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationIsm", + "address": "0x882CD0C5D50b6dD74b36Da4BDb059507fddEDdf2", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationHookFactory", + "address": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationHook", + "address": "0x19930232E9aFC4f4F09d09fe2375680fAc2100D0", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "DomainRoutingIsmFactory", + "address": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "DomaingRoutingIsm", + "address": "0x12Ed1BbA182CbC63692F813651BD493B7445C874", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMerkleRootWeightedMultisigIsmFactory", + "address": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootWeightedMultisigIsm", + "address": "0x3b9f24fD2ecfed0d3A88fa7f0E4e5747671981D7", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdWeightedMultisigIsmFactory", + "address": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdWeightedMultisigIsm", + "address": "0x71DCcD21B912F7d4f636af0C9eA5DC0C10617354", + "constructorArguments": "", + "isProxy": true + } + ], + "lumiaprism": [ + { + "name": "StaticMerkleRootMultisigIsmFactory", + "address": "0xf376247BdE9763808034567E7E87c84970e81E8F", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootMultisigIsm", + "address": "0x918582303e7984Bc4c9ae4ac3Ff49883f4aCC8a2", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdMultisigIsmFactory", + "address": "0x280626Ea62fBB3C1A38641D5e735c1d0EE3F28cF", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdMultisigIsm", + "address": "0x5549d1353Ead03F61f1891BF540e7CcF95d8E8E8", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationIsmFactory", + "address": "0xD7777efaC7241E63f0c7708aA912AEd8CFAfee69", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationIsm", + "address": "0x4c75c9F10C42034D1A226A205E34f5E8abDF0310", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationHookFactory", + "address": "0xf40eE9FF75Fa34910b7C4C8d68d4850B3bD184D3", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationHook", + "address": "0x87A6623E709990358905c48a19F7912C4B3AAD26", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "DomainRoutingIsmFactory", + "address": "0x8eC5f0239C77295452Ed899FDB851e785cA5FC31", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "DomaingRoutingIsm", + "address": "0x0deb89922170b20AB549C25C93aAc67DeAEDFe14", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMerkleRootWeightedMultisigIsmFactory", + "address": "0x408F58D25003001C7e5F30259217F1040b8F5AaD", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootWeightedMultisigIsm", + "address": "0xF9Dd08bd70867b29154BBdA6c110F1d9145fc5A3", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdWeightedMultisigIsmFactory", + "address": "0xf6fB78dc009C1A4286c0E7d90C10c9E8906a62Ea", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdWeightedMultisigIsm", + "address": "0xa12bACe4d09cBf37a3c98CB18978E069360552F4", + "constructorArguments": "", + "isProxy": true + } + ], + "swell": [ + { + "name": "StaticMerkleRootMultisigIsmFactory", + "address": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootMultisigIsm", + "address": "0x4725F7b8037513915aAf6D6CBDE2920E28540dDc", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdMultisigIsmFactory", + "address": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdMultisigIsm", + "address": "0xAF03386044373E2fe26C5b1dCedF5a7e854a7a3F", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationIsmFactory", + "address": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationIsm", + "address": "0x882CD0C5D50b6dD74b36Da4BDb059507fddEDdf2", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationHookFactory", + "address": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationHook", + "address": "0x19930232E9aFC4f4F09d09fe2375680fAc2100D0", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "DomainRoutingIsmFactory", + "address": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "DomaingRoutingIsm", + "address": "0x12Ed1BbA182CbC63692F813651BD493B7445C874", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMerkleRootWeightedMultisigIsmFactory", + "address": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootWeightedMultisigIsm", + "address": "0x3b9f24fD2ecfed0d3A88fa7f0E4e5747671981D7", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdWeightedMultisigIsmFactory", + "address": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdWeightedMultisigIsm", + "address": "0x71DCcD21B912F7d4f636af0C9eA5DC0C10617354", + "constructorArguments": "", + "isProxy": true + } + ], + "appchain": [ + { + "name": "StaticMerkleRootMultisigIsmFactory", + "address": "0x2C1FAbEcd7bFBdEBF27CcdB67baADB38b6Df90fC", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootMultisigIsm", + "address": "0x4725F7b8037513915aAf6D6CBDE2920E28540dDc", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdMultisigIsmFactory", + "address": "0x8b83fefd896fAa52057798f6426E9f0B080FCCcE", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdMultisigIsm", + "address": "0xAF03386044373E2fe26C5b1dCedF5a7e854a7a3F", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationIsmFactory", + "address": "0x8F7454AC98228f3504Bb91eA3D8Adafe6406110A", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationIsm", + "address": "0x882CD0C5D50b6dD74b36Da4BDb059507fddEDdf2", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticAggregationHookFactory", + "address": "0xEb9FcFDC9EfDC17c1EC5E1dc085B98485da213D6", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticAggregationHook", + "address": "0x19930232E9aFC4f4F09d09fe2375680fAc2100D0", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "DomainRoutingIsmFactory", + "address": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "DomaingRoutingIsm", + "address": "0x12Ed1BbA182CbC63692F813651BD493B7445C874", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMerkleRootWeightedMultisigIsmFactory", + "address": "0x0761b0827849abbf7b0cC09CE14e1C93D87f5004", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMerkleRootWeightedMultisigIsm", + "address": "0x3b9f24fD2ecfed0d3A88fa7f0E4e5747671981D7", + "constructorArguments": "", + "isProxy": true + }, + { + "name": "StaticMessageIdWeightedMultisigIsmFactory", + "address": "0x4Ed7d626f1E96cD1C0401607Bf70D95243E3dEd1", + "constructorArguments": "", + "isProxy": false + }, + { + "name": "StaticMessageIdWeightedMultisigIsm", + "address": "0x71DCcD21B912F7d4f636af0C9eA5DC0C10617354", + "constructorArguments": "", + "isProxy": true + } ] } diff --git a/typescript/infra/config/environments/mainnet3/middleware/accounts/verification.json b/typescript/infra/config/environments/mainnet3/middleware/accounts/verification.json index b940665f2c..07944e2a41 100644 --- a/typescript/infra/config/environments/mainnet3/middleware/accounts/verification.json +++ b/typescript/infra/config/environments/mainnet3/middleware/accounts/verification.json @@ -1680,5 +1680,194 @@ "isProxy": true, "expectedimplementation": "0x28846fCb579747E8ddad9E93b55BE51b0A1Bf1f3" } + ], + "superseed": [ + { + "name": "InterchainAccountIsm", + "address": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "InterchainAccountRouter", + "address": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "constructorArguments": "0000000000000000000000000f9d4704e1fb25e416042524e594f1ceac6ff5970000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025eac2007b0d40e3f0af112fd346412321038719000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597" + } + ], + "boba": [ + { + "name": "InterchainAccountIsm", + "address": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "InterchainAccountRouter", + "address": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "constructorArguments": "0000000000000000000000000f9d4704e1fb25e416042524e594f1ceac6ff5970000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025eac2007b0d40e3f0af112fd346412321038719000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597" + } + ], + "unichain": [ + { + "name": "InterchainAccountIsm", + "address": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "InterchainAccountRouter", + "address": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "constructorArguments": "0000000000000000000000000f9d4704e1fb25e416042524e594f1ceac6ff5970000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025eac2007b0d40e3f0af112fd346412321038719000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597" + } + ], + "duckchain": [ + { + "name": "InterchainAccountIsm", + "address": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "InterchainAccountRouter", + "address": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "constructorArguments": "0000000000000000000000000f9d4704e1fb25e416042524e594f1ceac6ff5970000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025eac2007b0d40e3f0af112fd346412321038719000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597" + } + ], + "vana": [ + { + "name": "InterchainAccountIsm", + "address": "0x25EAC2007b0D40E3f0AF112FD346412321038719", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "InterchainAccountRouter", + "address": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "constructorArguments": "0000000000000000000000000f9d4704e1fb25e416042524e594f1ceac6ff5970000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025eac2007b0d40e3f0af112fd346412321038719000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x0F9d4704E1Fb25e416042524e594F1cEac6fF597" + } + ], + "bsquared": [ + { + "name": "InterchainAccountIsm", + "address": "0xfF26696DcDb6BbFD27e959b847D4f1399D5BcF64", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "InterchainAccountRouter", + "address": "0x7CE76f5f0C469bBB4cd7Ea6EbabB54437A093127", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x4D50044335dc1d4D26c343AdeDf6E47808475Deb", + "constructorArguments": "0000000000000000000000007ce76f5f0c469bbb4cd7ea6ebabb54437a0931270000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff26696dcdb6bbfd27e959b847d4f1399d5bcf64000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x7CE76f5f0C469bBB4cd7Ea6EbabB54437A093127" + } + ], + "lumiaprism": [ + { + "name": "InterchainAccountIsm", + "address": "0x31Bb27f6007C33acD1be83ACEd3164C60f8F7b13", + "constructorArguments": "0000000000000000000000000df25a2d59f03f039b56e90edc5b89679ace28bc", + "isProxy": false + }, + { + "name": "InterchainAccountRouter", + "address": "0x59EE0Ae1f527DEd5BcB1bF71aF027DdC996a50b6", + "constructorArguments": "0000000000000000000000000df25a2d59f03f039b56e90edc5b89679ace28bc", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0xEeb5a99a75585fe137c83E7b62b74f87264A5481", + "constructorArguments": "00000000000000000000000059ee0ae1f527ded5bcb1bf71af027ddc996a50b6000000000000000000000000200183de44bf765ecb73cd62a74010eaabc4314600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031bb27f6007c33acd1be83aced3164c60f8f7b13000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x59EE0Ae1f527DEd5BcB1bF71aF027DdC996a50b6" + } + ], + "swell": [ + { + "name": "InterchainAccountIsm", + "address": "0x28291a7062afA569104bEd52F7AcCA3dD2FafD11", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "InterchainAccountRouter", + "address": "0x6a77331cE28E47c3Cb9Fea48AB6cD1e9594ce0A9", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0xe9E3444DDD80c50276c0Fcf316026f6d7fEc2c47", + "constructorArguments": "0000000000000000000000006a77331ce28e47c3cb9fea48ab6cd1e9594ce0a90000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028291a7062afa569104bed52f7acca3dd2fafd11000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0x6a77331cE28E47c3Cb9Fea48AB6cD1e9594ce0A9" + } + ], + "appchain": [ + { + "name": "InterchainAccountIsm", + "address": "0x027eFD1695941969435AA640542B690044dF7E06", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "InterchainAccountRouter", + "address": "0xAE557e108b3336130370aC74836f1356B4b30Cf2", + "constructorArguments": "0000000000000000000000003a464f746d23ab22155710f44db16dca53e0775e", + "isProxy": false + }, + { + "name": "TransparentUpgradeableProxy", + "address": "0x65F1343AC23D4fF48bf6c7E0c55872d245397567", + "constructorArguments": "000000000000000000000000ae557e108b3336130370ac74836f1356b4b30cf20000000000000000000000002f2afae1139ce54fefc03593fee8ab2adf4a85a700000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064c0c53b8b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027efd1695941969435aa640542b690044df7e06000000000000000000000000a7eccdb9be08178f896c26b7bbd8c3d4e844d9ba00000000000000000000000000000000000000000000000000000000", + "isProxy": true, + "expectedimplementation": "0xAE557e108b3336130370aC74836f1356B4b30Cf2" + } ] } diff --git a/typescript/infra/config/environments/mainnet3/misc-artifacts/everclear-sender-addresses.json b/typescript/infra/config/environments/mainnet3/misc-artifacts/everclear-sender-addresses.json new file mode 100644 index 0000000000..10ccf021d1 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/misc-artifacts/everclear-sender-addresses.json @@ -0,0 +1,20 @@ +{ + "everclear": { + "sender": "0xEFfAB7cCEBF63FbEFB4884964b12259d4374FaAa" + }, + "ethereum": { + "sender": "0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7" + }, + "optimism": { + "sender": "0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7" + }, + "bsc": { + "sender": "0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7" + }, + "base": { + "sender": "0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7" + }, + "arbitrum": { + "sender": "0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7" + } +} diff --git a/typescript/infra/config/environments/mainnet3/misc-artifacts/velo-message-module-addresses.json b/typescript/infra/config/environments/mainnet3/misc-artifacts/velo-message-module-addresses.json index 3b9fc2fecd..9e2cc555b6 100644 --- a/typescript/infra/config/environments/mainnet3/misc-artifacts/velo-message-module-addresses.json +++ b/typescript/infra/config/environments/mainnet3/misc-artifacts/velo-message-module-addresses.json @@ -4,5 +4,11 @@ }, "mode": { "router": "0xF385603a12Be8b7B885222329c581FDD1C30071D" + }, + "lisk": { + "router": "0xF385603a12Be8b7B885222329c581FDD1C30071D" + }, + "fraxtal": { + "router": "0xF385603a12Be8b7B885222329c581FDD1C30071D" } } diff --git a/typescript/infra/config/environments/mainnet3/misc-artifacts/velo-token-bridge-addresses.json b/typescript/infra/config/environments/mainnet3/misc-artifacts/velo-token-bridge-addresses.json index 1988c9adb4..cd9fe51149 100644 --- a/typescript/infra/config/environments/mainnet3/misc-artifacts/velo-token-bridge-addresses.json +++ b/typescript/infra/config/environments/mainnet3/misc-artifacts/velo-token-bridge-addresses.json @@ -4,5 +4,11 @@ }, "mode": { "router": "0xA7287a56C01ac8Baaf8e7B662bDB41b10889C7A6" + }, + "lisk": { + "router": "0xA7287a56C01ac8Baaf8e7B662bDB41b10889C7A6" + }, + "fraxtal": { + "router": "0xA7287a56C01ac8Baaf8e7B662bDB41b10889C7A6" } } diff --git a/typescript/infra/config/environments/mainnet3/owners.ts b/typescript/infra/config/environments/mainnet3/owners.ts index 5fa21d9b65..f37ac77af8 100644 --- a/typescript/infra/config/environments/mainnet3/owners.ts +++ b/typescript/infra/config/environments/mainnet3/owners.ts @@ -157,6 +157,15 @@ export const icas: Partial< superpositionmainnet: '0x5F17Dc2e1fd1371dc6e694c51f22aBAF8E27667B', flame: '0x4F3d85360840497Cd1bc34Ca55f27629eee2AA2e', prom: '0x1cDd3C143387cD1FaE23e2B66bc3F409D073aC3D', + + // Nov 21, 2024 batch + // ---------------------------------------------------------- + boba: '0x29dfa34765e29ea353FC8aB70A19e32a5578E603', + duckchain: '0x29dfa34765e29ea353FC8aB70A19e32a5578E603', + unichain: '0x29dfa34765e29ea353FC8aB70A19e32a5578E603', + vana: '0x29dfa34765e29ea353FC8aB70A19e32a5578E603', + bsquared: '0xd9564EaaA68A327933f758A54450D3A0531E60BB', + superseed: '0x29dfa34765e29ea353FC8aB70A19e32a5578E603', } as const; export const DEPLOYER = '0xa7ECcdb9Be08178f896c26b7BbD8C3D4E844d9Ba'; diff --git a/typescript/infra/config/environments/mainnet3/supportedChainNames.ts b/typescript/infra/config/environments/mainnet3/supportedChainNames.ts index dddc793123..0b86151222 100644 --- a/typescript/infra/config/environments/mainnet3/supportedChainNames.ts +++ b/typescript/infra/config/environments/mainnet3/supportedChainNames.ts @@ -4,6 +4,7 @@ export const mainnet3SupportedChainNames = [ 'ancient8', 'alephzeroevmmainnet', 'apechain', + 'appchain', 'arbitrum', 'arbitrumnova', 'astar', @@ -15,7 +16,9 @@ export const mainnet3SupportedChainNames = [ 'bitlayer', 'blast', 'bob', + 'boba', 'bsc', + 'bsquared', 'celo', 'cheesechain', 'chilizmainnet', @@ -23,6 +26,7 @@ export const mainnet3SupportedChainNames = [ 'cyber', 'degenchain', 'dogechain', + 'duckchain', 'eclipsemainnet', 'endurance', 'ethereum', @@ -44,6 +48,7 @@ export const mainnet3SupportedChainNames = [ 'lisk', 'lukso', 'lumia', + 'lumiaprism', 'mantapacific', 'mantle', 'merlin', @@ -75,9 +80,14 @@ export const mainnet3SupportedChainNames = [ 'snaxchain', 'solanamainnet', 'stride', + 'superseed', 'superpositionmainnet', + 'swell', 'taiko', 'tangle', + 'treasure', + 'unichain', + 'vana', 'viction', 'worldchain', 'xai', @@ -85,6 +95,7 @@ export const mainnet3SupportedChainNames = [ 'zeronetwork', 'zetachain', 'zircuit', + 'zklink', 'zksync', 'zoramainnet', ] as const; diff --git a/typescript/infra/config/environments/mainnet3/tokenPrices.json b/typescript/infra/config/environments/mainnet3/tokenPrices.json index 106c5831fa..e340241632 100644 --- a/typescript/infra/config/environments/mainnet3/tokenPrices.json +++ b/typescript/infra/config/environments/mainnet3/tokenPrices.json @@ -1,88 +1,99 @@ { - "ancient8": "2901.97", - "alephzeroevmmainnet": "0.352558", - "apechain": "1.021", - "arbitrum": "2901.97", - "arbitrumnova": "2901.97", - "astar": "0.05516", - "astarzkevm": "2901.97", - "flame": "5.14", - "avalanche": "27.43", - "b3": "2901.97", - "base": "2901.97", - "bitlayer": "75858", - "blast": "2901.97", - "bob": "2901.97", - "bsc": "596.14", - "celo": "0.63787", - "cheesechain": "0.00211859", - "chilizmainnet": "0.061174", - "coredao": "0.886582", - "cyber": "2901.97", - "degenchain": "0.00776785", - "dogechain": "0.197113", - "eclipsemainnet": "2901.97", - "endurance": "2.02", - "ethereum": "2901.97", - "everclear": "2901.97", - "fantom": "0.708456", - "flare": "0.01303515", - "flowmainnet": "0.5289", - "fraxtal": "2892.2", - "fusemainnet": "0.02930522", - "gnosis": "1.001", - "gravity": "0.02864739", - "harmony": "0.01246587", - "immutablezkevmmainnet": "1.18", - "inevm": "21.99", - "injective": "21.99", - "kaia": "0.121813", - "kroma": "2901.97", - "linea": "2901.97", - "lisk": "2901.97", - "lukso": "1.48", - "lumia": "1.059", - "mantapacific": "2901.97", - "mantle": "0.651888", - "merlin": "75853", - "metal": "2901.97", - "metis": "44.6", - "mint": "2901.97", - "mode": "2901.97", - "molten": "0.25598", - "moonbeam": "0.169922", - "morph": "2901.97", - "neutron": "0.374494", - "oortmainnet": "0.092246", - "optimism": "2901.97", - "orderly": "2901.97", - "osmosis": "0.43997", - "polygon": "0.343626", - "polygonzkevm": "2901.97", - "polynomialfi": "2901.97", - "prom": "5.38", - "proofofplay": "2901.97", - "rarichain": "2901.97", + "ancient8": "3628.85", + "alephzeroevmmainnet": "0.61841", + "apechain": "1.52", + "appchain": "3628.85", + "arbitrum": "3628.85", + "arbitrumnova": "3628.85", + "astar": "0.078025", + "astarzkevm": "3628.85", + "flame": "7.36", + "avalanche": "48.31", + "b3": "3628.85", + "base": "3628.85", + "bitlayer": "95794", + "blast": "3628.85", + "bob": "3628.85", + "boba": "3628.85", + "bsc": "639.49", + "bsquared": "95794", + "celo": "0.983257", + "cheesechain": "0.00180324", + "chilizmainnet": "0.104233", + "coredao": "1.43", + "cyber": "3628.85", + "degenchain": "0.01711559", + "dogechain": "0.421781", + "duckchain": "6.5", + "eclipsemainnet": "3628.85", + "endurance": "3.09", + "ethereum": "3628.85", + "everclear": "3628.85", + "fantom": "1.034", + "flare": "0.03388989", + "flowmainnet": "1.01", + "fraxtal": "3614.4", + "fusemainnet": "0.03486937", + "gnosis": "0.997956", + "gravity": "0.03730451", + "harmony": "0.02834153", + "immutablezkevmmainnet": "1.94", + "inevm": "30.08", + "injective": "30.08", + "kaia": "0.357047", + "kroma": "3628.85", + "linea": "3628.85", + "lisk": "3628.85", + "lukso": "3.33", + "lumia": "1.7", + "lumiaprism": "1.7", + "mantapacific": "3628.85", + "mantle": "0.888186", + "merlin": "95787", + "metal": "3628.85", + "metis": "60.01", + "mint": "3628.85", + "mode": "3628.85", + "molten": "0.284308", + "moonbeam": "0.313413", + "morph": "3628.85", + "neutron": "0.523303", + "oortmainnet": "0.255252", + "optimism": "3628.85", + "orderly": "3628.85", + "osmosis": "0.589662", + "polygon": "0.621246", + "polygonzkevm": "3628.85", + "polynomialfi": "3628.85", + "prom": "6.5", + "proofofplay": "3628.85", + "rarichain": "3628.85", "real": "1", - "redstone": "2901.97", - "rootstockmainnet": "75541", - "sanko": "53.25", - "scroll": "2901.97", - "sei": "0.404683", - "shibarium": "0.407901", - "snaxchain": "2901.97", - "solanamainnet": "199.51", - "stride": "0.583853", - "superpositionmainnet": "2901.97", - "taiko": "2901.97", + "redstone": "3628.85", + "rootstockmainnet": "95652", + "sanko": "53.86", + "scroll": "3628.85", + "sei": "0.613723", + "shibarium": "0.59728", + "snaxchain": "3628.85", + "solanamainnet": "223.96", + "stride": "0.675504", + "superseed": "3628.85", + "superpositionmainnet": "3628.85", + "swell": "3628.85", + "taiko": "3628.85", "tangle": "1", - "viction": "0.340844", - "worldchain": "2901.97", - "xai": "0.2107", - "xlayer": "40.21", - "zeronetwork": "2901.97", - "zetachain": "0.680925", - "zircuit": "2901.97", - "zksync": "2901.97", - "zoramainnet": "2901.97" + "treasure": "0.64326", + "unichain": "3628.85", + "vana": "1", + "viction": "0.479042", + "worldchain": "3628.85", + "xai": "0.37142", + "xlayer": "53.81", + "zeronetwork": "3628.85", + "zetachain": "0.819612", + "zircuit": "3628.85", + "zklink": "3628.85", + "zksync": "3628.85", + "zoramainnet": "3628.85" } diff --git a/typescript/infra/config/environments/mainnet3/validators.ts b/typescript/infra/config/environments/mainnet3/validators.ts index 05673abf09..17500268ec 100644 --- a/typescript/infra/config/environments/mainnet3/validators.ts +++ b/typescript/infra/config/environments/mainnet3/validators.ts @@ -1140,5 +1140,119 @@ export const validatorChainConfig = ( 'prom', ), }, + + boba: { + interval: 5, + reorgPeriod: getReorgPeriod('boba'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0xebeb92c94ca8408e73aa16fd554cb3a7df075c59'], + }, + 'boba', + ), + }, + duckchain: { + interval: 5, + reorgPeriod: getReorgPeriod('duckchain'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0x91d55fe6dac596a6735d96365e21ce4bca21d83c'], + }, + 'duckchain', + ), + }, + superseed: { + interval: 5, + reorgPeriod: getReorgPeriod('superseed'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0xdc2b87cb555411bb138d3a4e5f7832c87fae2b88'], + }, + 'superseed', + ), + }, + unichain: { + interval: 5, + reorgPeriod: getReorgPeriod('unichain'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0x9773a382342ebf604a2e5de0a1f462fb499e28b1'], + }, + 'unichain', + ), + }, + vana: { + interval: 5, + reorgPeriod: getReorgPeriod('vana'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0xfdf3b0dfd4b822d10cacb15c8ae945ea269e7534'], + }, + 'vana', + ), + }, + + bsquared: { + interval: 5, + reorgPeriod: getReorgPeriod('bsquared'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0xcadc90933c9fbe843358a4e70e46ad2db78e28aa'], + }, + 'bsquared', + ), + }, + + lumiaprism: { + interval: 5, + reorgPeriod: getReorgPeriod('lumiaprism'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0xb69731640ffd4338a2c9358a935b0274c6463f85'], + }, + 'lumiaprism', + ), + }, + swell: { + interval: 5, + reorgPeriod: getReorgPeriod('swell'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0x4f51e4f4c7fb45d82f91568480a1a2cfb69216ed'], + }, + 'swell', + ), + }, + + treasure: { + interval: 5, + reorgPeriod: getReorgPeriod('treasure'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0x6ad994819185553e8baa01533f0cd2c7cadfe6cc'], + }, + 'treasure', + ), + }, + zklink: { + interval: 5, + reorgPeriod: getReorgPeriod('zklink'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0x217a8cb4789fc45abf56cb6e2ca96f251a5ac181'], + }, + 'zklink', + ), + }, + appchain: { + interval: 5, + reorgPeriod: getReorgPeriod('appchain'), + validators: validatorsConfig( + { + [Contexts.Hyperlane]: ['0x0531251bbadc1f9f19ccce3ca6b3f79f08eae1be'], + }, + 'appchain', + ), + }, }; }; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getAncient8EthereumUSDCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getAncient8EthereumUSDCWarpConfig.ts index 939bcc1ab2..d4b38bfb4f 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getAncient8EthereumUSDCWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getAncient8EthereumUSDCWarpConfig.ts @@ -2,26 +2,31 @@ import { ethers } from 'ethers'; import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, buildAggregationIsmConfigs, defaultMultisigConfigs, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; export const getAncient8EthereumUSDCWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { const ismConfig = buildAggregationIsmConfigs( 'ethereum', ['ancient8'], defaultMultisigConfigs, ).ancient8; - const ethereum: TokenRouterConfig = { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, type: TokenType.collateral, token: tokens.ethereum.USDC, interchainSecurityModule: ismConfig, @@ -31,12 +36,9 @@ export const getAncient8EthereumUSDCWarpConfig = async ( hook: '0x19b2cF952b70b217c90FC408714Fbc1acD29A6A8', }; - // @ts-ignore - The types as they stand require a synthetic to specify - // TokenMetadata, but in practice these are actually inferred from a - // collateral config. To avoid needing to specify the TokenMetadata, just - // ts-ignore for synthetic tokens. - const ancient8: TokenRouterConfig = { + const ancient8: HypTokenRouterConfig = { ...routerConfig.ancient8, + ...abacusWorksEnvOwnerConfig.ancient8, type: TokenType.synthetic, // Uses the default ISM interchainSecurityModule: ethers.constants.AddressZero, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumBaseBlastBscEthereumGnosisMantleModeOptimismPolygonScrollZeroNetworkZoraMainnetETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumBaseBlastBscEthereumGnosisMantleModeOptimismPolygonScrollZeroNetworkZoraMainnetETHWarpConfig.ts new file mode 100644 index 0000000000..3f2a52b221 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumBaseBlastBscEthereumGnosisMantleModeOptimismPolygonScrollZeroNetworkZoraMainnetETHWarpConfig.ts @@ -0,0 +1,197 @@ +import { ethers } from 'ethers'; + +import { + ChainMap, + HypTokenRouterConfig, + IsmConfig, + OwnableConfig, + TokenType, +} from '@hyperlane-xyz/sdk'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +export const getArbitrumBaseBlastBscEthereumGnosisMantleModeOptimismPolygonScrollZeroNetworkZoraMainnetETHWarpConfig = + async ( + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, + ): Promise> => { + const ISM_CONFIG: IsmConfig = ethers.constants.AddressZero; + + const arbitrum: HypTokenRouterConfig = { + ...routerConfig.arbitrum, + ...abacusWorksEnvOwnerConfig.arbitrum, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.arbitrum, + address: '0x544BC0f2B619a6920650B0469EA3b6d6Ef3B0b10', + }, + type: TokenType.native, + interchainSecurityModule: ISM_CONFIG, + }; + + const base: HypTokenRouterConfig = { + ...routerConfig.base, + ...abacusWorksEnvOwnerConfig.base, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.base, + address: '0x073235Fd88B04e3bA7fAC83146225c0de53E5c31', + }, + type: TokenType.native, + interchainSecurityModule: ISM_CONFIG, + }; + + const blast: HypTokenRouterConfig = { + ...routerConfig.blast, + ...abacusWorksEnvOwnerConfig.blast, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.blast, + address: '0x9775Dd30480D545b9bEd2A6a1DC344Ffbad9B223', + }, + type: TokenType.native, + interchainSecurityModule: ISM_CONFIG, + }; + + const bsc: HypTokenRouterConfig = { + ...routerConfig.bsc, + ...abacusWorksEnvOwnerConfig.bsc, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.bsc, + address: '0xa0B923456b08944bE30D0F237c041F191Eb0c9D0', + }, + type: TokenType.collateral, + token: tokens.bsc.WETH, + interchainSecurityModule: ISM_CONFIG, + }; + + const ethereum: HypTokenRouterConfig = { + ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.ethereum, + address: '0x5E76be0F4e09057D75140216F70fd4cE3365bb29', + }, + type: TokenType.native, + interchainSecurityModule: ISM_CONFIG, + }; + + const gnosis: HypTokenRouterConfig = { + ...routerConfig.gnosis, + ...abacusWorksEnvOwnerConfig.gnosis, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.gnosis, + address: '0xe516A113316cFdF8a44e125E4e3970dE6df0cC59', + }, + type: TokenType.collateral, + token: tokens.gnosis.WETH, + interchainSecurityModule: ISM_CONFIG, + }; + + const mantle: HypTokenRouterConfig = { + ...routerConfig.mantle, + ...abacusWorksEnvOwnerConfig.mantle, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.mantle, + address: '0xEaD68fD6e5A69136CD60De50bF22164658A8E04E', + }, + type: TokenType.collateral, + token: tokens.mantle.WETH, + interchainSecurityModule: ISM_CONFIG, + }; + + const mode: HypTokenRouterConfig = { + ...routerConfig.mode, + ...abacusWorksEnvOwnerConfig.mode, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.mode, + address: '0xEC1f2f8C42c8Ca4C8d15E6a0814667a379aB9b43', + }, + type: TokenType.native, + interchainSecurityModule: ISM_CONFIG, + }; + + const optimism: HypTokenRouterConfig = { + ...routerConfig.optimism, + ...abacusWorksEnvOwnerConfig.optimism, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.optimism, + address: '0xA900858116D7605a01AfC7595450d8D78555Bc83', + }, + type: TokenType.native, + interchainSecurityModule: ISM_CONFIG, + }; + + const polygon: HypTokenRouterConfig = { + ...routerConfig.polygon, + ...abacusWorksEnvOwnerConfig.polygon, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.polygon, + address: '0xcA11d580faaE3E6993aA230f437079ac21f3078a', + }, + type: TokenType.collateral, + token: tokens.polygon.WETH, + interchainSecurityModule: ISM_CONFIG, + }; + + const scroll: HypTokenRouterConfig = { + ...routerConfig.scroll, + ...abacusWorksEnvOwnerConfig.scroll, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.scroll, + address: '0xA452bDb132Cdf8d11E070786D78907ddB95C5120', + }, + type: TokenType.native, + interchainSecurityModule: ISM_CONFIG, + }; + + const zeronetwork: HypTokenRouterConfig = { + ...routerConfig.zeronetwork, + ...abacusWorksEnvOwnerConfig.zeronetwork, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.zeronetwork, + address: '0xc2caD038236ccDB113C9350EF2551633c65252eF', + }, + type: TokenType.native, + interchainSecurityModule: ISM_CONFIG, + }; + + const zoramainnet: HypTokenRouterConfig = { + ...routerConfig.zoramainnet, + ...abacusWorksEnvOwnerConfig.zoramainnet, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.zoramainnet, + address: '0x9775Dd30480D545b9bEd2A6a1DC344Ffbad9B223', + }, + type: TokenType.native, + interchainSecurityModule: ISM_CONFIG, + }; + + const lisk: HypTokenRouterConfig = { + ...routerConfig.lisk, + ...abacusWorksEnvOwnerConfig.lisk, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.lisk, + address: '0x5E76be0F4e09057D75140216F70fd4cE3365bb29', + }, + type: TokenType.synthetic, + interchainSecurityModule: ISM_CONFIG, + }; + + return { + arbitrum, + base, + blast, + bsc, + gnosis, + mantle, + mode, + optimism, + polygon, + scroll, + zeronetwork, + zoramainnet, + ethereum, + lisk, + }; + }; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumBaseEthereumOptimismPolygonZeroNetworkUSDCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumBaseEthereumOptimismPolygonZeroNetworkUSDCWarpConfig.ts new file mode 100644 index 0000000000..9dae492537 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumBaseEthereumOptimismPolygonZeroNetworkUSDCWarpConfig.ts @@ -0,0 +1,113 @@ +import { ethers } from 'ethers'; + +import { + ChainMap, + HypTokenRouterConfig, + OwnableConfig, + TokenType, +} from '@hyperlane-xyz/sdk'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +export const getArbitrumBaseEthereumOptimismPolygonZeroNetworkUSDC = async ( + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const ISM_CONFIG = ethers.constants.AddressZero; + + const arbitrum: HypTokenRouterConfig = { + ...routerConfig.arbitrum, + ...abacusWorksEnvOwnerConfig.arbitrum, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.arbitrum, + address: '0x02317D525FA7ceb5ea388244b4618f0c8Ac1CeC2', + }, + type: TokenType.collateral, + token: tokens.arbitrum.USDC, + interchainSecurityModule: ISM_CONFIG, + }; + + const base: HypTokenRouterConfig = { + ...routerConfig.base, + ...abacusWorksEnvOwnerConfig.base, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.base, + address: '0xB6E9331576C5aBF69376AF6989eA61b7C7ea67F1', + }, + type: TokenType.collateral, + token: tokens.base.USDC, + interchainSecurityModule: ISM_CONFIG, + }; + + const optimism: HypTokenRouterConfig = { + ...routerConfig.optimism, + ...abacusWorksEnvOwnerConfig.optimism, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.optimism, + address: '0xca9e64761C97b049901dF4E7a5926464969528b1', + }, + type: TokenType.collateral, + token: tokens.optimism.USDC, + interchainSecurityModule: ISM_CONFIG, + }; + + const polygon: HypTokenRouterConfig = { + ...routerConfig.polygon, + ...abacusWorksEnvOwnerConfig.polygon, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.polygon, + address: '0x7fd5be37d560626625f395A2e6E30eA89150cc98', + }, + type: TokenType.collateral, + token: tokens.polygon.USDC, + interchainSecurityModule: ISM_CONFIG, + }; + + const zeronetwork: HypTokenRouterConfig = { + ...routerConfig.zeronetwork, + ...abacusWorksEnvOwnerConfig.zeronetwork, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.zeronetwork, + address: '0x6E906d8AeEBE9025a410887EAafc58C2561705e0', + }, + type: TokenType.collateral, + token: tokens.zeronetwork.USDC, + interchainSecurityModule: ISM_CONFIG, + }; + + const ethereum: HypTokenRouterConfig = { + ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.ethereum, + address: '0x81063D413Ed6Eac3FCf0521eea14906fD27fEb1A', + }, + type: TokenType.collateral, + token: tokens.ethereum.USDC, + interchainSecurityModule: ISM_CONFIG, + }; + + const lisk: HypTokenRouterConfig = { + ...routerConfig.lisk, + ...abacusWorksEnvOwnerConfig.lisk, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.lisk, + address: '0x81Db8B4Bc6F2e95781eeA2a21D0A453Ac046eFc0', + }, + type: TokenType.synthetic, + interchainSecurityModule: ISM_CONFIG, + }; + + return { + arbitrum, + base, + ethereum, + optimism, + polygon, + zeronetwork, + lisk, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumBscEthereumMantleModePolygonScrollZeronetworkUSDTWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumBscEthereumMantleModePolygonScrollZeronetworkUSDTWarpConfig.ts new file mode 100644 index 0000000000..8de2710ee2 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumBscEthereumMantleModePolygonScrollZeronetworkUSDTWarpConfig.ts @@ -0,0 +1,115 @@ +import { ethers } from 'ethers'; + +import { + ChainMap, + HypTokenRouterConfig, + IsmConfig, + OwnableConfig, + TokenType, +} from '@hyperlane-xyz/sdk'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +export const getArbitrumEthereumMantleModePolygonScrollZeroNetworkUSDTWarpConfig = + async ( + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, + ): Promise> => { + const ISM_CONFIG: IsmConfig = ethers.constants.AddressZero; + + const arbitrum: HypTokenRouterConfig = { + ...routerConfig.arbitrum, + ...abacusWorksEnvOwnerConfig.arbitrum, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.arbitrum, + address: '0x6701d503369cf6aA9e5EdFfEBFA40A2ffdf3dB21', + }, + type: TokenType.collateral, + token: tokens.arbitrum.USDT, + interchainSecurityModule: ISM_CONFIG, + }; + + const ethereum: HypTokenRouterConfig = { + ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.ethereum, + address: '0xA92D6084709469A2B2339919FfC568b7C5D7888D', + }, + type: TokenType.collateral, + token: tokens.ethereum.USDT, + interchainSecurityModule: ISM_CONFIG, + }; + + const mantle: HypTokenRouterConfig = { + ...routerConfig.mantle, + ...abacusWorksEnvOwnerConfig.mantle, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.mantle, + address: '0x633268639892C73Fa7340Ec1da4e397cf3913c8C', + }, + type: TokenType.collateral, + token: tokens.mantle.USDT, + interchainSecurityModule: ISM_CONFIG, + }; + + const mode: HypTokenRouterConfig = { + ...routerConfig.mode, + ...abacusWorksEnvOwnerConfig.mode, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.mode, + address: '0x633268639892C73Fa7340Ec1da4e397cf3913c8C', + }, + type: TokenType.collateral, + token: tokens.mode.USDT, + interchainSecurityModule: ISM_CONFIG, + }; + + const polygon: HypTokenRouterConfig = { + ...routerConfig.polygon, + ...abacusWorksEnvOwnerConfig.polygon, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.polygon, + address: '0x5DBeAEC137d1ef9a240599656073Ae3E717fae3c', + }, + type: TokenType.collateral, + token: tokens.polygon.USDT, + interchainSecurityModule: ISM_CONFIG, + }; + + const scroll: HypTokenRouterConfig = { + ...routerConfig.scroll, + ...abacusWorksEnvOwnerConfig.scroll, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.scroll, + address: '0x81Db8B4Bc6F2e95781eeA2a21D0A453Ac046eFc0', + }, + type: TokenType.collateral, + token: tokens.scroll.USDT, + interchainSecurityModule: ISM_CONFIG, + }; + + const zeronetwork: HypTokenRouterConfig = { + ...routerConfig.zeronetwork, + ...abacusWorksEnvOwnerConfig.zeronetwork, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.zeronetwork, + address: '0xa3F188BDd6e3894b393e12396347545bC47E7B0e', + }, + type: TokenType.synthetic, + interchainSecurityModule: ISM_CONFIG, + }; + + return { + arbitrum, + ethereum, + mantle, + mode, + polygon, + scroll, + zeronetwork, + }; + }; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumEthereumZircuitAmphrETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumEthereumZircuitAmphrETHWarpConfig.ts index 1b81e81103..866e3bb9bc 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumEthereumZircuitAmphrETHWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumEthereumZircuitAmphrETHWarpConfig.ts @@ -2,49 +2,46 @@ import { ethers } from 'ethers'; import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; +import { getOwnerConfigForAddress } from '../../../../../src/config/environment.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; +// MEV Capital const arbitrumOwner = '0x008615770B588633265cB01Abd19740fAe67d0B9'; const ethereumOwner = '0x008615770B588633265cB01Abd19740fAe67d0B9'; const zircuitOwner = '0xD0673e7F3FB4037CA79F53d2d311D0e017d39963'; export const getArbitrumEthereumZircuitAmphrETHWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const arbitrum: TokenRouterConfig = { + routerConfig: ChainMap, + _abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const arbitrum: HypTokenRouterConfig = { ...routerConfig.arbitrum, + ...getOwnerConfigForAddress(arbitrumOwner), type: TokenType.synthetic, interchainSecurityModule: ethers.constants.AddressZero, - owner: arbitrumOwner, - ownerOverrides: { - proxyAdmin: arbitrumOwner, - }, }; - const ethereum: TokenRouterConfig = { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...getOwnerConfigForAddress(ethereumOwner), type: TokenType.collateral, token: tokens.ethereum.amphrETH, - owner: ethereumOwner, interchainSecurityModule: ethers.constants.AddressZero, - ownerOverrides: { - proxyAdmin: ethereumOwner, - }, }; - const zircuit: TokenRouterConfig = { + const zircuit: HypTokenRouterConfig = { ...routerConfig.zircuit, + ...getOwnerConfigForAddress(zircuitOwner), type: TokenType.synthetic, interchainSecurityModule: ethers.constants.AddressZero, - owner: zircuitOwner, - ownerOverrides: { - proxyAdmin: zircuitOwner, - }, }; return { diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumNeutronEclipWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumNeutronEclipWarpConfig.ts index daebd6c026..ad6b921951 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumNeutronEclipWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumNeutronEclipWarpConfig.ts @@ -1,23 +1,36 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; +import { getOwnerConfigForAddress } from '../../../../../src/config/environment.js'; +import { RouterConfigWithoutOwner } from '../../../../../src/config/warp.js'; + +// Eclipse Fi team +const arbitrumOwner = '0xfF07222cb0AC905304d6586Aabf13f497C07F0C8'; +const neutronOwner = + 'neutron1aud8lty0wwmyc86ugkzqrusnrku0ckm0ym62v4ve0jjjyepjjg6spssrwj'; + export const getArbitrumNeutronEclipWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { + routerConfig: ChainMap, + _abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { const neutronRouter = '6b04c49fcfd98bc4ea9c05cd5790462a39537c00028333474aebe6ddf20b73a3'; - // @ts-ignore - foreignDeployment configs dont conform to the TokenRouterConfig - const neutron: TokenRouterConfig = { + const neutron: HypTokenRouterConfig = { + ...routerConfig.neutron, + ...getOwnerConfigForAddress(neutronOwner), + type: TokenType.collateral, + token: 'factory/neutron10sr06r3qkhn7xzpw3339wuj77hu06mzna6uht0/eclip', foreignDeployment: neutronRouter, }; - const arbitrum: TokenRouterConfig = { + const arbitrum: HypTokenRouterConfig = { ...routerConfig.arbitrum, + ...getOwnerConfigForAddress(arbitrumOwner), type: TokenType.synthetic, name: 'Eclipse Fi', symbol: 'ECLIP', @@ -25,7 +38,6 @@ export const getArbitrumNeutronEclipWarpConfig = async ( totalSupply: 0, gas: 600_000, interchainSecurityModule: '0x676151bFB8D29690a359F99AE764860595504689', // This has diverged from the default ism on neutron, we cannot change as it is owned by the Eclip team - owner: '0xfF07222cb0AC905304d6586Aabf13f497C07F0C8', // Eclip team }; return { diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumNeutronTiaWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumNeutronTiaWarpConfig.ts index ce601ffc16..0618602550 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumNeutronTiaWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getArbitrumNeutronTiaWarpConfig.ts @@ -1,23 +1,31 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; +import { RouterConfigWithoutOwner } from '../../../../../src/config/warp.js'; + export const getArbitrumNeutronTiaWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { const neutronRouter = '910926c4cf95d107237a9cf0b3305fe9c81351ebcba3d218ceb0e4935d92ceac'; - // @ts-ignore - foreignDeployment configs dont conform to the TokenRouterConfig - const neutron: TokenRouterConfig = { + const neutron: HypTokenRouterConfig = { + ...routerConfig.neutron, + ...abacusWorksEnvOwnerConfig.neutron, + type: TokenType.collateral, + token: + 'ibc/773B4D0A3CD667B2275D5A4A7A2F0909C0BA0F4059C0B9181E680DDF4965DCC7', foreignDeployment: neutronRouter, }; - const arbitrum: TokenRouterConfig = { + const arbitrum: HypTokenRouterConfig = { ...routerConfig.arbitrum, + ...abacusWorksEnvOwnerConfig.arbitrum, type: TokenType.synthetic, name: 'TIA', symbol: 'TIA.n', diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseZeroNetworkCBBTCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseZeroNetworkCBBTCWarpConfig.ts new file mode 100644 index 0000000000..c61c25a9b5 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseZeroNetworkCBBTCWarpConfig.ts @@ -0,0 +1,49 @@ +import { ethers } from 'ethers'; + +import { + ChainMap, + HypTokenRouterConfig, + IsmConfig, + OwnableConfig, + TokenType, +} from '@hyperlane-xyz/sdk'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +export const getBaseZeroNetworkCBBTCWarpConfig = async ( + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const ISM_CONFIG: IsmConfig = ethers.constants.AddressZero; + + const base: HypTokenRouterConfig = { + ...routerConfig.base, + ...abacusWorksEnvOwnerConfig.base, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.base, + address: '0x0FC41a92F526A8CD22060A4052e156502D6B9db0', + }, + type: TokenType.collateral, + token: tokens.base.cbBTC, + interchainSecurityModule: ISM_CONFIG, + }; + + const zeronetwork: HypTokenRouterConfig = { + ...routerConfig.zeronetwork, + ...abacusWorksEnvOwnerConfig.zeronetwork, + proxyAdmin: { + ...abacusWorksEnvOwnerConfig.zeronetwork, + address: '0xDb0F69187750b52A637938Ea790fAE667123367c', + }, + type: TokenType.synthetic, + interchainSecurityModule: ISM_CONFIG, + }; + + return { + base, + zeronetwork, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getBlastZeroNetworkUSDBWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getBlastZeroNetworkUSDBWarpConfig.ts deleted file mode 100644 index 020ac765e5..0000000000 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getBlastZeroNetworkUSDBWarpConfig.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ethers } from 'ethers'; - -import { - ChainMap, - RouterConfig, - TokenRouterConfig, - TokenType, -} from '@hyperlane-xyz/sdk'; - -import { tokens } from '../../../../../src/config/warp.js'; - -export const getBlastZeroNetworkUSDBWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const blast: TokenRouterConfig = { - ...routerConfig.blast, - type: TokenType.collateral, - token: tokens.blast.usdb, - interchainSecurityModule: ethers.constants.AddressZero, - }; - - const zeronetwork: TokenRouterConfig = { - ...routerConfig.zeronetwork, - type: TokenType.synthetic, - interchainSecurityModule: ethers.constants.AddressZero, - }; - return { - blast, - zeronetwork, - }; -}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getBscZeroNetworkBNBConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getBscZeroNetworkBNBConfig.ts deleted file mode 100644 index 844e5ba94c..0000000000 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getBscZeroNetworkBNBConfig.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ethers } from 'ethers'; - -import { - ChainMap, - RouterConfig, - TokenRouterConfig, - TokenType, -} from '@hyperlane-xyz/sdk'; - -export const getBscZeroNetworkBNBWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const bsc: TokenRouterConfig = { - ...routerConfig.bsc, - type: TokenType.native, - interchainSecurityModule: ethers.constants.AddressZero, - }; - - const zeronetwork: TokenRouterConfig = { - ...routerConfig.zeronetwork, - type: TokenType.synthetic, - interchainSecurityModule: ethers.constants.AddressZero, - }; - return { - bsc, - zeronetwork, - }; -}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumApxETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumApxETHWarpConfig.ts new file mode 100644 index 0000000000..b27329279b --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumApxETHWarpConfig.ts @@ -0,0 +1,46 @@ +import { ethers } from 'ethers'; + +import { + ChainMap, + HypTokenRouterConfig, + OwnableConfig, + TokenType, +} from '@hyperlane-xyz/sdk'; + +import { getOwnerConfigForAddress } from '../../../../../src/config/environment.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; +import { SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT } from '../consts.js'; + +// Redacted / Dinero team +const ethereumOwner = '0xA52Fd396891E7A74b641a2Cb1A6999Fcf56B077e'; +const eclipseOwner = 'BwYL3jLky8oHLeQp1S48cVRfZPmcXtg1V33UPmnZK3Jk'; + +export async function getEclipseEthereumApxEthWarpConfig( + routerConfig: ChainMap, + _abacusWorksEnvOwnerConfig: ChainMap, +): Promise> { + const eclipsemainnet: HypTokenRouterConfig = { + ...routerConfig.eclipsemainnet, + ...getOwnerConfigForAddress(eclipseOwner), + type: TokenType.synthetic, + foreignDeployment: '9pEgj7m2VkwLtJHPtTw5d8vbB7kfjzcXXCRgdwruW7C2', + gas: SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + let ethereum: HypTokenRouterConfig = { + ...routerConfig.ethereum, + ...getOwnerConfigForAddress(ethereumOwner), + type: TokenType.collateral, + token: tokens.ethereum.apxETH, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + return { + eclipsemainnet, + ethereum, + }; +} diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDCWarpConfig.ts index 078c90776e..c5a537ca4e 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDCWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDCWarpConfig.ts @@ -2,24 +2,25 @@ import { ethers } from 'ethers'; import { ChainMap, + HypTokenRouterConfig, RouterConfig, - TokenRouterConfig, TokenType, } from '@hyperlane-xyz/sdk'; import { tokens } from '../../../../../src/config/warp.js'; +import { SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT } from '../consts.js'; export const getEclipseEthereumSolanaUSDCWarpConfig = async ( routerConfig: ChainMap, -): Promise> => { - const eclipsemainnet: TokenRouterConfig = { +): Promise> => { + const eclipsemainnet: HypTokenRouterConfig = { ...routerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'D6k6T3G74ij6atCtBiWBs5TbFa1hFVcrFUSGZHuV7q3Z', - gas: 300_000, + gas: SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT, }; - const ethereum: TokenRouterConfig = { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, type: TokenType.collateral, interchainSecurityModule: ethers.constants.AddressZero, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDTWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDTWarpConfig.ts index 781b3caa98..c6576138b5 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDTWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDTWarpConfig.ts @@ -2,25 +2,32 @@ import { ethers } from 'ethers'; import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; +import { SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT } from '../consts.js'; export const getEclipseEthereumSolanaUSDTWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const eclipsemainnet: TokenRouterConfig = { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const eclipsemainnet: HypTokenRouterConfig = { ...routerConfig.eclipsemainnet, + ...abacusWorksEnvOwnerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: '5g5ujyYUNvdydwyDVCpZwPpgYRqH5RYJRi156cxyE3me', - gas: 300_000, + gas: SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT, interchainSecurityModule: ethers.constants.AddressZero, }; - let ethereum: TokenRouterConfig = { + let ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, type: TokenType.collateral, token: tokens.ethereum.USDT, interchainSecurityModule: ethers.constants.AddressZero, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumTETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumTETHWarpConfig.ts index db149da15c..5f48724e6e 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumTETHWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumTETHWarpConfig.ts @@ -2,22 +2,24 @@ import { ethers } from 'ethers'; import { ChainMap, + HypTokenRouterConfig, RouterConfig, - TokenRouterConfig, TokenType, } from '@hyperlane-xyz/sdk'; +import { SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT } from '../consts.js'; + export const getEthereumEclipseTETHWarpConfig = async ( routerConfig: ChainMap, -): Promise> => { - const eclipsemainnet: TokenRouterConfig = { +): Promise> => { + const eclipsemainnet: HypTokenRouterConfig = { ...routerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'BJa3fPvvjKx8gRCWunoSrWBbsmieub37gsGpjp4BfTfW', - gas: 300_000, + gas: SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT, }; - const ethereum: TokenRouterConfig = { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, type: TokenType.collateral, interchainSecurityModule: ethers.constants.AddressZero, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.ts index 03bdd55b7d..011d151ba8 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.ts @@ -2,26 +2,33 @@ import { ethers } from 'ethers'; import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; +import { SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT } from '../consts.js'; export const getEclipseEthereumWBTCWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const eclipsemainnet: TokenRouterConfig = { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const eclipsemainnet: HypTokenRouterConfig = { ...routerConfig.eclipsemainnet, + ...abacusWorksEnvOwnerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'A7EGCDYFw5R7Jfm6cYtKvY8dmkrYMgwRCJFkyQwpHTYu', - gas: 300_000, + gas: SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT, interchainSecurityModule: ethers.constants.AddressZero, }; - let ethereum: TokenRouterConfig = { + let ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, type: TokenType.collateral, token: tokens.ethereum.WBTC, interchainSecurityModule: ethers.constants.AddressZero, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.ts index 34da322ad7..6ec12367dc 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.ts @@ -2,35 +2,46 @@ import { ethers } from 'ethers'; import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; -import { DEPLOYER } from '../../owners.js'; +import { getOwnerConfigForAddress } from '../../../../../src/config/environment.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; +import { SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT } from '../consts.js'; + +// Safe owned by Veda +const ethereumOwner = '0xCEA8039076E35a825854c5C2f85659430b06ec96'; +// Vault owned by Veda +const eclipseOwner = '4Cj1s2ipALjJk9foQV4oDaZYCZwSsVkAShQL1KFVJG9b'; -export const getEclipseEthereumWeEthsWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const eclipsemainnet: TokenRouterConfig = { +export async function getEclipseEthereumWeEthsWarpConfig( + routerConfig: ChainMap, + _abacusWorksEnvOwnerConfig: ChainMap, +): Promise> { + const eclipsemainnet: HypTokenRouterConfig = { ...routerConfig.eclipsemainnet, + ...getOwnerConfigForAddress(eclipseOwner), type: TokenType.synthetic, foreignDeployment: '7Zx4wU1QAw98MfvnPFqRh1oyumek7G5VAX6TKB3U1tcn', - gas: 300_000, + gas: SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT, interchainSecurityModule: ethers.constants.AddressZero, }; - let ethereum: TokenRouterConfig = { + let ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...getOwnerConfigForAddress(ethereumOwner), type: TokenType.collateral, token: tokens.ethereum.weETHs, interchainSecurityModule: ethers.constants.AddressZero, - owner: DEPLOYER, }; return { eclipsemainnet, ethereum, }; -}; +} diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.ts index 4d8db22a7b..5159a4ddb0 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.ts @@ -1,22 +1,32 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; +import { getOwnerConfigForAddress } from '../../../../../src/config/environment.js'; +import { RouterConfigWithoutOwner } from '../../../../../src/config/warp.js'; +import { SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT } from '../consts.js'; + +// Stride team +const strideOwner = 'stride1k8c2m5cn322akk5wy8lpt87dd2f4yh9azg7jlh'; + export const getEclipseStrideTiaWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const eclipsemainnet: TokenRouterConfig = { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const eclipsemainnet: HypTokenRouterConfig = { ...routerConfig.eclipsemainnet, + ...abacusWorksEnvOwnerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'BpXHAiktwjx7fN6M9ST9wr6qKAsH27wZFhdHEhReJsR6', - gas: 300_000, + gas: SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT, }; - const stride: TokenRouterConfig = { + const stride: HypTokenRouterConfig = { ...routerConfig.stride, + ...getOwnerConfigForAddress(strideOwner), type: TokenType.collateral, foreignDeployment: 'stride1pvtesu3ve7qn7ctll2x495mrqf2ysp6fws68grvcu6f7n2ajghgsh2jdj6', diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.ts index 9d5bdf5786..b486686040 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.ts @@ -1,22 +1,32 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; +import { getOwnerConfigForAddress } from '../../../../../src/config/environment.js'; +import { RouterConfigWithoutOwner } from '../../../../../src/config/warp.js'; +import { SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT } from '../consts.js'; + +// Stride team +const strideOwner = 'stride1k8c2m5cn322akk5wy8lpt87dd2f4yh9azg7jlh'; + export const getEclipseStrideStTiaWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const eclipsemainnet: TokenRouterConfig = { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const eclipsemainnet: HypTokenRouterConfig = { ...routerConfig.eclipsemainnet, + ...abacusWorksEnvOwnerConfig.eclipsemainnet, type: TokenType.synthetic, foreignDeployment: 'tKUHyJ5NxhnwU94JUmzh1ekukDcHHX8mZF6fqxbMwX6', - gas: 300_000, + gas: SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT, }; - const stride: TokenRouterConfig = { + const stride: HypTokenRouterConfig = { ...routerConfig.stride, + ...getOwnerConfigForAddress(strideOwner), type: TokenType.collateral, foreignDeployment: 'stride134axwdlam929m3mar3wv95nvkyep7mr87ravkqcpf8dfe3v0pjlqwrw6ee', diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumBscLumiaLUMIAWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumBscLumiaLUMIAWarpConfig.ts index 3ce50742a9..0551b09bad 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumBscLumiaLUMIAWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumBscLumiaLUMIAWarpConfig.ts @@ -1,59 +1,50 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; -import { objMap } from '@hyperlane-xyz/utils'; + +import { getOwnerConfigForAddress } from '../../../../../src/config/environment.js'; +import { RouterConfigWithoutOwner } from '../../../../../src/config/warp.js'; // Lumia Team const owner = '0x8bBA07Ddc72455b55530C17e6f6223EF6E156863'; - -const ownerConfig = { - owner, - // The proxyAdmins are warp-route specific - ownerOverrides: { - proxyAdmin: owner, - }, -}; +const ownerConfig = getOwnerConfigForAddress(owner); export const getEthereumBscLUMIAWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const ethereum = { + routerConfig: ChainMap, + _abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const ethereum: HypTokenRouterConfig = { + ...routerConfig.ethereum, + ...ownerConfig, type: TokenType.collateral, token: '0xD9343a049D5DBd89CD19DC6BcA8c48fB3a0a42a7', - ownerOverrides: { - proxyAdmin: owner, - }, }; - const bsc = { + const bsc: HypTokenRouterConfig = { + ...routerConfig.bsc, + ...ownerConfig, type: TokenType.synthetic, - ownerOverrides: { - proxyAdmin: owner, - }, }; - const lumia = { + const lumia: HypTokenRouterConfig = { + ...routerConfig.lumia, + ...ownerConfig, type: TokenType.native, // As this has been removed from the registry in https://github.com/hyperlane-xyz/hyperlane-registry/pull/348, // we must specify this explicitly. mailbox: '0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7', - proxyAdmin: '0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D', + proxyAdmin: { + owner: owner, + address: '0xBC53dACd8c0ac0d2bAC461479EAaf5519eCC8853', + }, }; - const configMap = { + return { ethereum, bsc, lumia, }; - - const merged = objMap(configMap, (chain, config) => ({ - ...routerConfig[chain], - ...config, - ...ownerConfig, - })); - - return merged as ChainMap; }; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFlowCbBTCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFlowCbBTCWarpConfig.ts new file mode 100644 index 0000000000..54acc7fbd4 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFlowCbBTCWarpConfig.ts @@ -0,0 +1,47 @@ +import { ethers } from 'ethers'; + +import { + ChainMap, + HypTokenRouterConfig, + OwnableConfig, + TokenType, +} from '@hyperlane-xyz/sdk'; + +import { getOwnerConfigForAddress } from '../../../../../src/config/environment.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +// Flow team Safe +const ethereumOwner = '0x58C3FB862a4F5f038C24F8506BE378e9415c5B6C'; +const ethereumOwnerConfig = getOwnerConfigForAddress(ethereumOwner); + +// Flow team Safe +const flowOwner = '0xa507DFccA02727B46cBdC600C57E89b2b55E5330'; +const flowOwnerConfig = getOwnerConfigForAddress(flowOwner); + +export const getEthereumFlowCbBTCWarpConfig = async ( + routerConfig: ChainMap, + _abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const ethereum: HypTokenRouterConfig = { + ...routerConfig.ethereum, + ...ethereumOwnerConfig, + type: TokenType.collateral, + token: tokens.ethereum.cbBTC, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + const flowmainnet: HypTokenRouterConfig = { + ...routerConfig.flowmainnet, + ...flowOwnerConfig, + type: TokenType.synthetic, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + return { + ethereum, + flowmainnet, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumInevmUSDCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumInevmUSDCWarpConfig.ts index aa4b19054f..d08e5fbbf2 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumInevmUSDCWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumInevmUSDCWarpConfig.ts @@ -2,25 +2,31 @@ import { ethers } from 'ethers'; import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; export const getEthereumInevmUSDCWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const ethereum: TokenRouterConfig = { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, type: TokenType.collateral, token: tokens.ethereum.USDC, hook: '0xb87AC8EA4533AE017604E44470F7c1E550AC6F10', // aggregation of IGP and Merkle, arbitrary config not supported for now, TODO: may want to move to zero address in future }; - const inevm: TokenRouterConfig = { + const inevm: HypTokenRouterConfig = { ...routerConfig.inevm, + ...abacusWorksEnvOwnerConfig.inevm, type: TokenType.synthetic, interchainSecurityModule: ethers.constants.AddressZero, }; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumInevmUSDTWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumInevmUSDTWarpConfig.ts index abe8fd14c5..59418498c4 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumInevmUSDTWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumInevmUSDTWarpConfig.ts @@ -2,25 +2,31 @@ import { ethers } from 'ethers'; import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; export const getEthereumInevmUSDTWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const ethereum: TokenRouterConfig = { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, type: TokenType.collateral, token: tokens.ethereum.USDT, hook: '0xb87AC8EA4533AE017604E44470F7c1E550AC6F10', // aggregation of IGP and Merkle, arbitrary config not supported for now, TODO: may want to move to zero address in future }; - const inevm: TokenRouterConfig = { + const inevm: HypTokenRouterConfig = { ...routerConfig.inevm, + ...abacusWorksEnvOwnerConfig.inevm, type: TokenType.synthetic, interchainSecurityModule: ethers.constants.AddressZero, }; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumModeScrollZeronetworkWBTCConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumModeScrollZeronetworkWBTCConfig.ts deleted file mode 100644 index fe47eb3211..0000000000 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumModeScrollZeronetworkWBTCConfig.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { ethers } from 'ethers'; - -import { - ChainMap, - RouterConfig, - TokenRouterConfig, - TokenType, -} from '@hyperlane-xyz/sdk'; -import { Address } from '@hyperlane-xyz/utils'; - -const collateralAddresses: ChainMap
= { - ethereum: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', - mode: '0xcDd475325D6F564d27247D1DddBb0DAc6fA0a5CF', - scroll: '0x3C1BCa5a656e69edCD0D4E36BEbb3FcDAcA60Cf1', -}; - -export const getEthereumModeScrollZeronetworkWBTCConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const ethereum: TokenRouterConfig = { - ...routerConfig.ethereum, - type: TokenType.collateral, - token: collateralAddresses.ethereum, - interchainSecurityModule: ethers.constants.AddressZero, - }; - - const mode: TokenRouterConfig = { - ...routerConfig.mode, - type: TokenType.collateral, - token: collateralAddresses.mode, - interchainSecurityModule: ethers.constants.AddressZero, - }; - - const scroll: TokenRouterConfig = { - ...routerConfig.scroll, - type: TokenType.collateral, - token: collateralAddresses.scroll, - interchainSecurityModule: ethers.constants.AddressZero, - }; - - const zeronetwork: TokenRouterConfig = { - ...routerConfig.zeronetwork, - type: TokenType.synthetic, - interchainSecurityModule: ethers.constants.AddressZero, - }; - - return { - ethereum, - mode, - scroll, - zeronetwork, - }; -}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumSeiFastUSDWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumSeiFastUSDWarpConfig.ts index 5bd4938d20..73c3a5655d 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumSeiFastUSDWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumSeiFastUSDWarpConfig.ts @@ -2,42 +2,42 @@ import { ethers } from 'ethers'; import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; +import { getOwnerConfigForAddress } from '../../../../../src/config/environment.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; // Elixir const owner = '0x00000000F51340906F767C6999Fe512b1275955C'; +const ownerConfig = getOwnerConfigForAddress(owner); export const getEthereumSeiFastUSDWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const sei: TokenRouterConfig = { + routerConfig: ChainMap, + _abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { + const sei: HypTokenRouterConfig = { ...routerConfig.viction, + ...ownerConfig, type: TokenType.XERC20, name: 'fastUSD', symbol: 'fastUSD', decimals: 18, token: tokens.sei.fastUSD, interchainSecurityModule: ethers.constants.AddressZero, - owner, - ownerOverrides: { - proxyAdmin: owner, - }, }; - const ethereum: TokenRouterConfig = { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...ownerConfig, type: TokenType.collateral, token: tokens.ethereum.deUSD, - owner, interchainSecurityModule: ethers.constants.AddressZero, - ownerOverrides: { - proxyAdmin: owner, - }, }; return { diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionETHWarpConfig.ts index 975483bc5a..4617aec50e 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionETHWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionETHWarpConfig.ts @@ -1,23 +1,27 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, buildAggregationIsmConfigs, defaultMultisigConfigs, } from '@hyperlane-xyz/sdk'; +import { RouterConfigWithoutOwner } from '../../../../../src/config/warp.js'; + export const getEthereumVictionETHWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { const ismConfig = buildAggregationIsmConfigs( 'ethereum', ['viction'], defaultMultisigConfigs, ).viction; - const viction: TokenRouterConfig = { + const viction: HypTokenRouterConfig = { ...routerConfig.viction, + ...abacusWorksEnvOwnerConfig.viction, type: TokenType.synthetic, name: 'ETH', symbol: 'ETH', @@ -26,8 +30,9 @@ export const getEthereumVictionETHWarpConfig = async ( gas: 50_000, }; - const ethereum: TokenRouterConfig = { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, type: TokenType.native, gas: 65_000, interchainSecurityModule: ismConfig, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionUSDCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionUSDCWarpConfig.ts index ae8ed54946..8ea4026b82 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionUSDCWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionUSDCWarpConfig.ts @@ -1,17 +1,21 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, buildAggregationIsmConfigs, defaultMultisigConfigs, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; export const getEthereumVictionUSDCWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { // commit that the config was copied from https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/3067/commits/7ed5b460034ea5e140c6ff86bcd6baf6ebb824c4#diff-fab5dd1a27c76e4310699c57ccf92ab6274ef0acf17e079b17270cedf4057775R109 const ismConfig = buildAggregationIsmConfigs( 'ethereum', @@ -19,8 +23,9 @@ export const getEthereumVictionUSDCWarpConfig = async ( defaultMultisigConfigs, ).viction; - const viction: TokenRouterConfig = { + const viction: HypTokenRouterConfig = { ...routerConfig.viction, + ...abacusWorksEnvOwnerConfig.viction, type: TokenType.synthetic, name: 'USDC', symbol: 'USDC', @@ -29,8 +34,9 @@ export const getEthereumVictionUSDCWarpConfig = async ( gas: 75_000, }; - const ethereum: TokenRouterConfig = { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, type: TokenType.collateral, token: tokens.ethereum.USDC, gas: 65_000, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionUSDTWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionUSDTWarpConfig.ts index 85abe405d5..3b98d5debc 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionUSDTWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumVictionUSDTWarpConfig.ts @@ -1,25 +1,30 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, buildAggregationIsmConfigs, defaultMultisigConfigs, } from '@hyperlane-xyz/sdk'; -import { tokens } from '../../../../../src/config/warp.js'; +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; export const getEthereumVictionUSDTWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { const ismConfig = buildAggregationIsmConfigs( 'ethereum', ['viction'], defaultMultisigConfigs, ).viction; - const viction: TokenRouterConfig = { + const viction: HypTokenRouterConfig = { ...routerConfig.viction, + ...abacusWorksEnvOwnerConfig.viction, type: TokenType.synthetic, name: 'USDT', symbol: 'USDT', @@ -28,8 +33,9 @@ export const getEthereumVictionUSDTWarpConfig = async ( gas: 75_000, }; - const ethereum: TokenRouterConfig = { + const ethereum: HypTokenRouterConfig = { ...routerConfig.ethereum, + ...abacusWorksEnvOwnerConfig.ethereum, type: TokenType.collateral, token: tokens.ethereum.USDT, gas: 65_000, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getInevmInjectiveINJWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getInevmInjectiveINJWarpConfig.ts index 438fe23e94..6938e4c739 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getInevmInjectiveINJWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getInevmInjectiveINJWarpConfig.ts @@ -1,23 +1,28 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; +import { RouterConfigWithoutOwner } from '../../../../../src/config/warp.js'; + export const getInevmInjectiveINJWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { const injectiveRouter = 'inj1mv9tjvkaw7x8w8y9vds8pkfq46g2vcfkjehc6k'; - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig - const injective: TokenRouterConfig = { + const injective: HypTokenRouterConfig = { + ...routerConfig.injective, + ...abacusWorksEnvOwnerConfig.injective, type: TokenType.native, foreignDeployment: injectiveRouter, }; - const inevm: TokenRouterConfig = { + const inevm: HypTokenRouterConfig = { ...routerConfig.inevm, + ...abacusWorksEnvOwnerConfig.inevm, type: TokenType.native, }; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getMantapacificNeutronTiaWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getMantapacificNeutronTiaWarpConfig.ts index e157552e62..82f5c78223 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getMantapacificNeutronTiaWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getMantapacificNeutronTiaWarpConfig.ts @@ -1,23 +1,27 @@ import { ChainMap, - RouterConfig, - TokenRouterConfig, + HypTokenRouterConfig, + OwnableConfig, TokenType, } from '@hyperlane-xyz/sdk'; +import { RouterConfigWithoutOwner } from '../../../../../src/config/warp.js'; + export const getMantapacificNeutronTiaWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +): Promise> => { const neutronRouter = '0xc5fc6899019cb4a7649981d89eb7b1a0929d0a85b2d41802f3315129ad4b581a'; - // @ts-ignore - foreignDeployment configs don't conform to the TokenRouterConfig - const neutron: TokenRouterConfig = { + // @ts-ignore - foreignDeployment configs don't conform to the HypTokenRouterConfig + const neutron: HypTokenRouterConfig = { foreignDeployment: neutronRouter, }; - const mantapacific: TokenRouterConfig = { + const mantapacific: HypTokenRouterConfig = { ...routerConfig.mantapacific, + ...abacusWorksEnvOwnerConfig.mantapacific, type: TokenType.synthetic, name: 'TIA', symbol: 'TIA', diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getPolygonZeroNetworkPolConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getPolygonZeroNetworkPolConfig.ts deleted file mode 100644 index 01a8b3a565..0000000000 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getPolygonZeroNetworkPolConfig.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ethers } from 'ethers'; - -import { - ChainMap, - RouterConfig, - TokenRouterConfig, - TokenType, -} from '@hyperlane-xyz/sdk'; - -export const getPolygonZeroNetworkPolWarpConfig = async ( - routerConfig: ChainMap, -): Promise> => { - const polygon: TokenRouterConfig = { - ...routerConfig.polygon, - type: TokenType.native, - interchainSecurityModule: ethers.constants.AddressZero, - }; - - const zeronetwork: TokenRouterConfig = { - ...routerConfig.zeronetwork, - type: TokenType.synthetic, - interchainSecurityModule: ethers.constants.AddressZero, - }; - return { - polygon, - zeronetwork, - }; -}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getRenzoEZETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getRenzoEZETHWarpConfig.ts index 7e6e31c6fe..8928f2fb58 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getRenzoEZETHWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getRenzoEZETHWarpConfig.ts @@ -1,7 +1,8 @@ import { ChainMap, + HypTokenRouterConfig, IsmType, - TokenRouterConfig, + MultisigConfig, TokenType, buildAggregationIsmConfigs, } from '@hyperlane-xyz/sdk'; @@ -42,89 +43,125 @@ const xERC20: Record<(typeof chainsToDeploy)[number], string> = { sei: '0x6DCfbF4729890043DFd34A93A2694E5303BA2703', // redEth }; -export const ezEthValidators = { +export const ezEthValidators: ChainMap = { arbitrum: { threshold: 1, validators: [ - '0x9bccfad3bd12ef0ee8ae839dd9ed7835bccadc9d', // Everclear - '0xc27032c6bbd48c20005f552af3aaa0dbf14260f3', // Renzo + { + address: '0x9bccfad3bd12ef0ee8ae839dd9ed7835bccadc9d', + alias: 'Everclear', + }, + { address: '0xc27032c6bbd48c20005f552af3aaa0dbf14260f3', alias: 'Renzo' }, ], }, optimism: { threshold: 1, validators: [ - '0x6f4cb8e96db5d44422a4495faa73fffb9d30e9e2', // Everclear - '0xe2593d205f5e7f74a50fa900824501084e092ebd', // Renzo + { + address: '0x6f4cb8e96db5d44422a4495faa73fffb9d30e9e2', + alias: 'Everclear', + }, + { address: '0xe2593d205f5e7f74a50fa900824501084e092ebd', alias: 'Renzo' }, ], }, base: { threshold: 1, validators: [ - '0x25ba4ee5268cbfb8d69bac531aa10368778702bd', // Renzo - '0x9ec803b503e9c7d2611e231521ef3fde73f7a21c', // Everclear + { address: '0x25ba4ee5268cbfb8d69bac531aa10368778702bd', alias: 'Renzo' }, + { + address: '0x9ec803b503e9c7d2611e231521ef3fde73f7a21c', + alias: 'Everclear', + }, ], }, blast: { threshold: 1, validators: [ - '0x1652d8ba766821cf01aeea34306dfc1cab964a32', // Everclear - '0x54bb0036f777202371429e062fe6aee0d59442f9', // Renzo + { + address: '0x1652d8ba766821cf01aeea34306dfc1cab964a32', + alias: 'Everclear', + }, + { address: '0x54bb0036f777202371429e062fe6aee0d59442f9', alias: 'Renzo' }, ], }, bsc: { threshold: 1, validators: [ - '0x3156db97a3b3e2dcc3d69fddfd3e12dc7c937b6d', // Renzo - '0x9a0326c43e4713ae2477f09e0f28ffedc24d8266', // Everclear + { address: '0x3156db97a3b3e2dcc3d69fddfd3e12dc7c937b6d', alias: 'Renzo' }, + { + address: '0x9a0326c43e4713ae2477f09e0f28ffedc24d8266', + alias: 'Everclear', + }, ], }, mode: { threshold: 1, validators: [ - '0x456fbbe05484fc9f2f38ea09648424f54d6872be', // Everclear - '0x7e29608c6e5792bbf9128599ca309be0728af7b4', // Renzo + { + address: '0x456fbbe05484fc9f2f38ea09648424f54d6872be', + alias: 'Everclear', + }, + { address: '0x7e29608c6e5792bbf9128599ca309be0728af7b4', alias: 'Renzo' }, ], }, linea: { threshold: 1, validators: [ - '0x06a5a2a429560034d38bf62ca6d470942535947e', // Everclear - '0xcb3e44edd2229860bdbaa58ba2c3817d111bee9a', // Renzo + { + address: '0x06a5a2a429560034d38bf62ca6d470942535947e', + alias: 'Everclear', + }, + { address: '0xcb3e44edd2229860bdbaa58ba2c3817d111bee9a', alias: 'Renzo' }, ], }, ethereum: { threshold: 1, validators: [ - '0x1fd889337f60986aa57166bc5ac121efd13e4fdd', // Everclear - '0xc7f7b94a6baf2fffa54dfe1dde6e5fcbb749e04f', // Renzo + { + address: '0x1fd889337f60986aa57166bc5ac121efd13e4fdd', + alias: 'Everclear', + }, + { address: '0xc7f7b94a6baf2fffa54dfe1dde6e5fcbb749e04f', alias: 'Renzo' }, ], }, fraxtal: { threshold: 1, validators: [ - '0x25b3a88f7cfd3c9f7d7e32b295673a16a6ddbd91', // luganodes - '0xe986f457965227a05dcf984c8d0c29e01253c44d', // Renzo + { + address: '0x25b3a88f7cfd3c9f7d7e32b295673a16a6ddbd91', + alias: 'Luganodes', + }, + { address: '0xe986f457965227a05dcf984c8d0c29e01253c44d', alias: 'Renzo' }, ], }, zircuit: { threshold: 1, validators: [ - '0x1da9176c2ce5cc7115340496fa7d1800a98911ce', // Renzo - '0x7ac6584c068eb2a72d4db82a7b7cd5ab34044061', // luganodes + { address: '0x1da9176c2ce5cc7115340496fa7d1800a98911ce', alias: 'Renzo' }, + { + address: '0x7ac6584c068eb2a72d4db82a7b7cd5ab34044061', + alias: 'Luganodes', + }, ], }, taiko: { threshold: 1, validators: [ - '0x2f007c82672f2bb97227d4e3f80ac481bfb40a2a', // luganodes - '0xd4F6000d8e1108bd4998215d51d5dF559BdB43a1', // Renzo + { + address: '0x2f007c82672f2bb97227d4e3f80ac481bfb40a2a', + alias: 'Luganodes', + }, + { address: '0xd4F6000d8e1108bd4998215d51d5dF559BdB43a1', alias: 'Renzo' }, ], }, sei: { threshold: 1, validators: [ - '0x7a0f4a8672f603e0c12468551db03f3956d10910', // luganodes - '0x952df7f0cb8611573a53dd7cbf29768871d9f8b0', // Renzo + { + address: '0x7a0f4a8672f603e0c12468551db03f3956d10910', + alias: 'Luganodes', + }, + { address: '0x952df7f0cb8611573a53dd7cbf29768871d9f8b0', alias: 'Renzo' }, ], }, }; @@ -145,7 +182,7 @@ export const ezEthSafes: Record = { }; export const getRenzoEZETHWarpConfig = async (): Promise< - ChainMap + ChainMap > => { const registry = await getMainnet3Registry(); @@ -181,11 +218,11 @@ export const getRenzoEZETHWarpConfig = async (): Promise< ); } - const tokenConfig = Object.fromEntries( + const tokenConfig = Object.fromEntries( await Promise.all( chainsToDeploy.map( - async (chain): Promise<[string, TokenRouterConfig]> => { - const ret: [string, TokenRouterConfig] = [ + async (chain): Promise<[string, HypTokenRouterConfig]> => { + const ret: [string, HypTokenRouterConfig] = [ chain, { isNft: false, diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getRenzoPZETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getRenzoPZETHWarpConfig.ts index b9e9b42bbd..9c269f5413 100644 --- a/typescript/infra/config/environments/mainnet3/warp/configGetters/getRenzoPZETHWarpConfig.ts +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getRenzoPZETHWarpConfig.ts @@ -1,7 +1,7 @@ import { ChainMap, + HypTokenRouterConfig, IsmType, - TokenRouterConfig, TokenType, buildAggregationIsmConfigs, } from '@hyperlane-xyz/sdk'; @@ -30,7 +30,7 @@ const pzEthSafes: Record = { }; export const getRenzoPZETHWarpConfig = async (): Promise< - ChainMap + ChainMap > => { const registry = await getMainnet3Registry(); @@ -55,11 +55,11 @@ export const getRenzoPZETHWarpConfig = async (): Promise< ); } - const tokenConfig = Object.fromEntries( + const tokenConfig = Object.fromEntries( await Promise.all( chainsToDeploy.map( - async (chain): Promise<[string, TokenRouterConfig]> => { - const ret: [string, TokenRouterConfig] = [ + async (chain): Promise<[string, HypTokenRouterConfig]> => { + const ret: [string, HypTokenRouterConfig] = [ chain, { isNft: false, diff --git a/typescript/infra/config/environments/mainnet3/warp/consts.ts b/typescript/infra/config/environments/mainnet3/warp/consts.ts new file mode 100644 index 0000000000..f201c1784e --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/consts.ts @@ -0,0 +1,2 @@ +// The amount of gas to pay for when performing a transferRemote to a Sealevel chain. +export const SEALEVEL_WARP_ROUTE_HANDLER_GAS_AMOUNT = 300_000; diff --git a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts index 5dbb3ef559..3d23bdc087 100644 --- a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts +++ b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts @@ -5,18 +5,19 @@ export enum WarpRouteIds { ArbitrumEthereumZircuitAMPHRETH = 'AMPHRETH/arbitrum-ethereum-zircuit', ArbitrumNeutronEclip = 'ECLIP/arbitrum-neutron', ArbitrumNeutronTIA = 'TIA/arbitrum-neutron', - BlastZeroNetworkUSDB = 'USDB/blast-zeronetwork', - BscZeroNetworkBNB = 'BNB/bsc-zeronetwork', + EclipseEthereumApxEth = 'APXETH/eclipsemainnet-ethereum', EclipseEthereumSolanaUSDC = 'USDC/eclipsemainnet-ethereum-solanamainnet', EclipseEthereumSolanaUSDT = 'USDT/eclipsemainnet-ethereum-solanamainnet', EclipseEthereumTETH = 'tETH/eclipsemainnet-ethereum', EclipseEthereumWBTC = 'WBTC/eclipsemainnet-ethereum', EclipseEthereumWeETHs = 'weETHs/eclipsemainnet-ethereum', + EclipseSolanaEzSOL = 'EZSOL/eclipsemainnet-solanamainnet', EclipseSolanaORCA = 'ORCA/eclipsemainnet-solanamainnet', EclipseSolanaSOL = 'SOL/eclipsemainnet-solanamainnet', EclipseSolanaWIF = 'WIF/eclipsemainnet-solanamainnet', EclipseStrideSTTIA = 'stTIA/eclipsemainnet-stride', EclipseStrideTIA = 'TIA/eclipsemainnet-stride', + EthereumFlowCbBTC = 'CBBTC/ethereum-flowmainnet', EthereumInevmUSDC = 'USDC/ethereum-inevm', EthereumInevmUSDT = 'USDT/ethereum-inevm', EthereumSeiFastUSD = 'FASTUSD/ethereum-sei', @@ -25,8 +26,10 @@ export enum WarpRouteIds { EthereumVictionUSDT = 'USDT/ethereum-viction', EthereumZircuitPZETH = 'PZETH/ethereum-zircuit', EthereumBscLumiaLUMIA = 'LUMIA/bsc-ethereum-lumia', - EthereumModeScrollZeroNetworkWBTC = 'WBTC/ethereum-mode-scroll-zeronetwork', InevmInjectiveINJ = 'INJ/inevm-injective', MantapacificNeutronTIA = 'TIA/mantapacific-neutron', - PolygonZeroNetworkPOL = 'POL/polygon-zeronetwork', + BaseZeroNetworkCBBTC = 'CBBTC/base-zeronetwork', + ArbitrumEthereumMantleModePolygonScrollZeroNetworkUSDT = 'USDT/arbitrum-ethereum-mantle-mode-polygon-scroll-zeronetwork', + ArbitrumBaseEthereumLiskOptimismPolygonZeroNetworkUSDC = 'USDC/arbitrum-base-ethereum-lisk-optimism-polygon-zeronetwork', + ArbitrumBaseBlastBscEthereumGnosisLiskMantleModeOptimismPolygonScrollZeroNetworkZoraMainnet = 'ETH/arbitrum-base-blast-bsc-ethereum-gnosis-lisk-mantle-mode-optimism-polygon-scroll-zeronetwork-zoramainnet', } diff --git a/typescript/infra/config/environments/testnet4/agent.ts b/typescript/infra/config/environments/testnet4/agent.ts index fbf6b4b885..4f984ebfe8 100644 --- a/typescript/infra/config/environments/testnet4/agent.ts +++ b/typescript/infra/config/environments/testnet4/agent.ts @@ -252,7 +252,7 @@ const hyperlane: RootAgentConfig = { rpcConsensusType: RpcConsensusType.Fallback, docker: { repo, - tag: 'bb4e82b-20241107-190434', + tag: '4b280cd-20241206-130519', }, resources: scraperResources, }, diff --git a/typescript/infra/config/environments/testnet4/core.ts b/typescript/infra/config/environments/testnet4/core.ts index 121bcc90e4..e40fafb051 100644 --- a/typescript/infra/config/environments/testnet4/core.ts +++ b/typescript/infra/config/environments/testnet4/core.ts @@ -16,6 +16,7 @@ import { ProtocolFeeHookConfig, RoutingIsmConfig, defaultMultisigConfigs, + multisigConfigToIsmConfig, } from '@hyperlane-xyz/sdk'; import { Address, ProtocolType, objMap } from '@hyperlane-xyz/utils'; @@ -35,15 +36,11 @@ export const core: ChainMap = objMap( .map((origin) => [origin, defaultMultisigConfigs[origin]]), ); - const merkleRoot = (multisig: MultisigConfig): MultisigIsmConfig => ({ - type: IsmType.MERKLE_ROOT_MULTISIG, - ...multisig, - }); + const merkleRoot = (multisig: MultisigConfig): MultisigIsmConfig => + multisigConfigToIsmConfig(IsmType.MERKLE_ROOT_MULTISIG, multisig); - const messageIdIsm = (multisig: MultisigConfig): MultisigIsmConfig => ({ - type: IsmType.MESSAGE_ID_MULTISIG, - ...multisig, - }); + const messageIdIsm = (multisig: MultisigConfig): MultisigIsmConfig => + multisigConfigToIsmConfig(IsmType.MESSAGE_ID_MULTISIG, multisig); const routingIsm: RoutingIsmConfig = { type: IsmType.ROUTING, diff --git a/typescript/infra/config/multisigIsm.ts b/typescript/infra/config/multisigIsm.ts index 418abd7e4f..d647018d97 100644 --- a/typescript/infra/config/multisigIsm.ts +++ b/typescript/infra/config/multisigIsm.ts @@ -4,6 +4,7 @@ import { MultisigIsmConfig, buildMultisigIsmConfigs, defaultMultisigConfigs, + multisigConfigToIsmConfig, } from '@hyperlane-xyz/sdk'; import { DeployEnvironment } from '../src/config/environment.js'; @@ -40,8 +41,5 @@ export const multisigIsm = ( ? rcMultisigIsmConfigs : defaultMultisigConfigs; - return { - ...configs[remote], - type, - }; + return multisigConfigToIsmConfig(type, configs[remote]); }; diff --git a/typescript/infra/config/rcMultisigIsmConfigs.ts b/typescript/infra/config/rcMultisigIsmConfigs.ts index 91222c0410..9f54880c67 100644 --- a/typescript/infra/config/rcMultisigIsmConfigs.ts +++ b/typescript/infra/config/rcMultisigIsmConfigs.ts @@ -1,84 +1,145 @@ -import { ChainMap, MultisigConfig } from '@hyperlane-xyz/sdk'; +import { + AW_VALIDATOR_ALIAS, + ChainMap, + MultisigConfig, +} from '@hyperlane-xyz/sdk'; export const rcMultisigIsmConfigs: ChainMap = { // ----------------- Mainnets ----------------- celo: { threshold: 1, validators: [ - '0xe7a82e210f512f8e9900d6bc2acbf7981c63e66e', // abacus + { + address: '0xe7a82e210f512f8e9900d6bc2acbf7981c63e66e', + alias: AW_VALIDATOR_ALIAS, + }, ], }, ethereum: { threshold: 1, validators: [ - '0xaea1adb1c687b061e5b60b9da84cb69e7b5fab44', // abacus + { + address: '0xaea1adb1c687b061e5b60b9da84cb69e7b5fab44', + alias: AW_VALIDATOR_ALIAS, + }, ], }, avalanche: { threshold: 1, validators: [ - '0x706976391e23dea28152e0207936bd942aba01ce', // abacus + { + address: '0x706976391e23dea28152e0207936bd942aba01ce', + alias: AW_VALIDATOR_ALIAS, + }, ], }, polygon: { threshold: 1, validators: [ - '0xef372f6ff7775989b3ac884506ee31c79638c989', // abacus + { + address: '0xef372f6ff7775989b3ac884506ee31c79638c989', + alias: AW_VALIDATOR_ALIAS, + }, ], }, bsc: { threshold: 1, validators: [ - '0x0823081031a4a6f97c6083775c191d17ca96d0ab', // abacus + { + address: '0x0823081031a4a6f97c6083775c191d17ca96d0ab', + alias: AW_VALIDATOR_ALIAS, + }, ], }, arbitrum: { threshold: 1, validators: [ - '0x1a95b35fb809d57faf1117c1cc29a6c5df289df1', // abacus + { + address: '0x1a95b35fb809d57faf1117c1cc29a6c5df289df1', + alias: AW_VALIDATOR_ALIAS, + }, ], }, optimism: { threshold: 1, validators: [ - '0x60e938bf280bbc21bacfd8bf435459d9003a8f98', // abacus + { + address: '0x60e938bf280bbc21bacfd8bf435459d9003a8f98', + alias: AW_VALIDATOR_ALIAS, + }, ], }, moonbeam: { threshold: 1, validators: [ - '0x0df7140811e309dc69638352545151ebb9d5e0fd', // abacus + { + address: '0x0df7140811e309dc69638352545151ebb9d5e0fd', + alias: AW_VALIDATOR_ALIAS, + }, ], }, gnosis: { threshold: 1, validators: [ - '0x15f48e78092a4f79febface509cfd76467c6cdbb', // abacus + { + address: '0x15f48e78092a4f79febface509cfd76467c6cdbb', + alias: AW_VALIDATOR_ALIAS, + }, ], }, // ----------------- Testnets ----------------- alfajores: { threshold: 1, - validators: ['0xace978aaa61d9ee44fe3ab147fd227e0e66b8909'], + validators: [ + { + address: '0xace978aaa61d9ee44fe3ab147fd227e0e66b8909', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, fuji: { threshold: 1, - validators: ['0xfc419f9ba3c56c55e28844ade491d428f5a77d55'], + validators: [ + { + address: '0xfc419f9ba3c56c55e28844ade491d428f5a77d55', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, chiado: { threshold: 1, - validators: ['0x7572ffd8af1abc02cc1d234ac750d387fd6768a0'], + validators: [ + { + address: '0x7572ffd8af1abc02cc1d234ac750d387fd6768a0', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, bsctestnet: { threshold: 1, - validators: ['0x6353c7402626054c824bd0eca721f82b725e2b4d'], + validators: [ + { + address: '0x6353c7402626054c824bd0eca721f82b725e2b4d', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, scrollsepolia: { threshold: 1, - validators: ['0x50d939d66f114350f322eb8b2e9f01fbc401d4c9'], + validators: [ + { + address: '0x50d939d66f114350f322eb8b2e9f01fbc401d4c9', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, sepolia: { threshold: 1, - validators: ['0x49f253c0dab33be1573d6c2769b3d9e584d91f82'], + validators: [ + { + address: '0x49f253c0dab33be1573d6c2769b3d9e584d91f82', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, }; diff --git a/typescript/infra/config/warp.ts b/typescript/infra/config/warp.ts index adb475b381..5c9049eb7d 100644 --- a/typescript/infra/config/warp.ts +++ b/typescript/infra/config/warp.ts @@ -1,52 +1,51 @@ import { ChainMap, + HypTokenRouterConfig, MultiProvider, - RouterConfig, - TokenRouterConfig, + OwnableConfig, } from '@hyperlane-xyz/sdk'; +import { objMap } from '@hyperlane-xyz/utils'; -import { getHyperlaneCore } from '../scripts/core-utils.js'; import { EnvironmentConfig, getRouterConfigsForAllVms, } from '../src/config/environment.js'; +import { RouterConfigWithoutOwner } from '../src/config/warp.js'; import { getAncient8EthereumUSDCWarpConfig } from './environments/mainnet3/warp/configGetters/getAncient8EthereumUSDCWarpConfig.js'; +import { getArbitrumBaseBlastBscEthereumGnosisMantleModeOptimismPolygonScrollZeroNetworkZoraMainnetETHWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumBaseBlastBscEthereumGnosisMantleModeOptimismPolygonScrollZeroNetworkZoraMainnetETHWarpConfig.js'; +import { getArbitrumBaseEthereumOptimismPolygonZeroNetworkUSDC } from './environments/mainnet3/warp/configGetters/getArbitrumBaseEthereumOptimismPolygonZeroNetworkUSDCWarpConfig.js'; +import { getArbitrumEthereumMantleModePolygonScrollZeroNetworkUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumBscEthereumMantleModePolygonScrollZeronetworkUSDTWarpConfig.js'; import { getArbitrumEthereumZircuitAmphrETHWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumEthereumZircuitAmphrETHWarpConfig.js'; import { getArbitrumNeutronEclipWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumNeutronEclipWarpConfig.js'; import { getArbitrumNeutronTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumNeutronTiaWarpConfig.js'; -import { getBlastZeroNetworkUSDBWarpConfig } from './environments/mainnet3/warp/configGetters/getBlastZeroNetworkUSDBWarpConfig.js'; -import { getBscZeroNetworkBNBWarpConfig } from './environments/mainnet3/warp/configGetters/getBscZeroNetworkBNBConfig.js'; +import { getBaseZeroNetworkCBBTCWarpConfig } from './environments/mainnet3/warp/configGetters/getBaseZeroNetworkCBBTCWarpConfig.js'; +import { getEclipseEthereumApxEthWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseEthereumApxETHWarpConfig.js'; import { getEclipseEthereumSolanaUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseEthereumSolanaUSDTWarpConfig.js'; import { getEclipseEthereumWBTCWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseEthereumWBTCWarpConfig.js'; import { getEclipseEthereumWeEthsWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseEthereumWeETHsWarpConfig.js'; import { getEclipseStrideTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseStrideSTTIAWarpConfig.js'; import { getEclipseStrideStTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.js'; import { getEthereumBscLUMIAWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumBscLumiaLUMIAWarpConfig.js'; +import { getEthereumFlowCbBTCWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumFlowCbBTCWarpConfig.js'; import { getEthereumInevmUSDCWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumInevmUSDCWarpConfig.js'; import { getEthereumInevmUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumInevmUSDTWarpConfig.js'; -import { getEthereumModeScrollZeronetworkWBTCConfig } from './environments/mainnet3/warp/configGetters/getEthereumModeScrollZeronetworkWBTCConfig.js'; import { getEthereumSeiFastUSDWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumSeiFastUSDWarpConfig.js'; import { getEthereumVictionETHWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumVictionETHWarpConfig.js'; import { getEthereumVictionUSDCWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumVictionUSDCWarpConfig.js'; import { getEthereumVictionUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumVictionUSDTWarpConfig.js'; import { getInevmInjectiveINJWarpConfig } from './environments/mainnet3/warp/configGetters/getInevmInjectiveINJWarpConfig.js'; import { getMantapacificNeutronTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getMantapacificNeutronTiaWarpConfig.js'; -import { getPolygonZeroNetworkPolWarpConfig } from './environments/mainnet3/warp/configGetters/getPolygonZeroNetworkPolConfig.js'; import { getRenzoEZETHWarpConfig } from './environments/mainnet3/warp/configGetters/getRenzoEZETHWarpConfig.js'; import { getRenzoPZETHWarpConfig } from './environments/mainnet3/warp/configGetters/getRenzoPZETHWarpConfig.js'; import { WarpRouteIds } from './environments/mainnet3/warp/warpIds.js'; -type WarpConfigGetterWithConfig = ( - routerConfig: ChainMap, -) => Promise>; +type WarpConfigGetter = ( + routerConfig: ChainMap, + abacusWorksEnvOwnerConfig: ChainMap, +) => Promise>; -type WarpConfigGetterWithoutConfig = () => Promise>; - -export const warpConfigGetterMap: Record< - string, - WarpConfigGetterWithConfig | WarpConfigGetterWithoutConfig -> = { +export const warpConfigGetterMap: Record = { [WarpRouteIds.Ancient8EthereumUSDC]: getAncient8EthereumUSDCWarpConfig, [WarpRouteIds.ArbitrumEthereumZircuitAMPHRETH]: getArbitrumEthereumZircuitAmphrETHWarpConfig, @@ -56,36 +55,53 @@ export const warpConfigGetterMap: Record< [WarpRouteIds.ArbitrumNeutronTIA]: getArbitrumNeutronTiaWarpConfig, [WarpRouteIds.ArbitrumBaseBlastBscEthereumFraxtalLineaModeOptimismSeiTaikoZircuitEZETH]: getRenzoEZETHWarpConfig, - [WarpRouteIds.BlastZeroNetworkUSDB]: getBlastZeroNetworkUSDBWarpConfig, - [WarpRouteIds.BscZeroNetworkBNB]: getBscZeroNetworkBNBWarpConfig, [WarpRouteIds.InevmInjectiveINJ]: getInevmInjectiveINJWarpConfig, + [WarpRouteIds.EthereumFlowCbBTC]: getEthereumFlowCbBTCWarpConfig, [WarpRouteIds.EthereumSeiFastUSD]: getEthereumSeiFastUSDWarpConfig, [WarpRouteIds.EthereumVictionETH]: getEthereumVictionETHWarpConfig, [WarpRouteIds.EthereumVictionUSDC]: getEthereumVictionUSDCWarpConfig, [WarpRouteIds.EthereumVictionUSDT]: getEthereumVictionUSDTWarpConfig, [WarpRouteIds.EthereumZircuitPZETH]: getRenzoPZETHWarpConfig, [WarpRouteIds.EthereumBscLumiaLUMIA]: getEthereumBscLUMIAWarpConfig, - [WarpRouteIds.EthereumModeScrollZeroNetworkWBTC]: - getEthereumModeScrollZeronetworkWBTCConfig, [WarpRouteIds.MantapacificNeutronTIA]: getMantapacificNeutronTiaWarpConfig, - [WarpRouteIds.EclipseStrideTIA]: getEclipseStrideTiaWarpConfig, - [WarpRouteIds.EclipseStrideSTTIA]: getEclipseStrideStTiaWarpConfig, + [WarpRouteIds.EclipseEthereumApxEth]: getEclipseEthereumApxEthWarpConfig, [WarpRouteIds.EclipseEthereumSolanaUSDT]: getEclipseEthereumSolanaUSDTWarpConfig, [WarpRouteIds.EclipseEthereumWBTC]: getEclipseEthereumWBTCWarpConfig, [WarpRouteIds.EclipseEthereumWeETHs]: getEclipseEthereumWeEthsWarpConfig, - [WarpRouteIds.PolygonZeroNetworkPOL]: getPolygonZeroNetworkPolWarpConfig, + [WarpRouteIds.BaseZeroNetworkCBBTC]: getBaseZeroNetworkCBBTCWarpConfig, + [WarpRouteIds.ArbitrumEthereumMantleModePolygonScrollZeroNetworkUSDT]: + getArbitrumEthereumMantleModePolygonScrollZeroNetworkUSDTWarpConfig, + [WarpRouteIds.ArbitrumBaseEthereumLiskOptimismPolygonZeroNetworkUSDC]: + getArbitrumBaseEthereumOptimismPolygonZeroNetworkUSDC, + [WarpRouteIds.ArbitrumBaseBlastBscEthereumGnosisLiskMantleModeOptimismPolygonScrollZeroNetworkZoraMainnet]: + getArbitrumBaseBlastBscEthereumGnosisMantleModeOptimismPolygonScrollZeroNetworkZoraMainnetETHWarpConfig, + [WarpRouteIds.EclipseStrideTIA]: getEclipseStrideTiaWarpConfig, + [WarpRouteIds.EclipseStrideSTTIA]: getEclipseStrideStTiaWarpConfig, }; export async function getWarpConfig( multiProvider: MultiProvider, envConfig: EnvironmentConfig, warpRouteId: string, -): Promise> { +): Promise> { const routerConfig = await getRouterConfigsForAllVms( envConfig, multiProvider, ); + // Strip the owners from the router config + const routerConfigWithoutOwner = objMap(routerConfig, (_chain, config) => { + const { owner, ownerOverrides, ...configWithoutOwner } = config; + return configWithoutOwner; + }); + // Isolate the owners from the router config + const abacusWorksEnvOwnerConfig = objMap(routerConfig, (_chain, config) => { + const { owner, ownerOverrides } = config; + return { + owner, + ownerOverrides, + }; + }); const warpConfigGetter = warpConfigGetterMap[warpRouteId]; if (!warpConfigGetter) { @@ -96,9 +112,5 @@ export async function getWarpConfig( ); } - if (warpConfigGetter.length === 1) { - return warpConfigGetter(routerConfig); - } else { - return (warpConfigGetter as WarpConfigGetterWithoutConfig)(); - } + return warpConfigGetter(routerConfigWithoutOwner, abacusWorksEnvOwnerConfig); } diff --git a/typescript/infra/package.json b/typescript/infra/package.json index b4fc7948ef..6f67d4ae23 100644 --- a/typescript/infra/package.json +++ b/typescript/infra/package.json @@ -1,29 +1,29 @@ { "name": "@hyperlane-xyz/infra", "description": "Infrastructure utilities for the Hyperlane Network", - "version": "7.1.0", + "version": "7.3.0", "dependencies": { - "@arbitrum/sdk": "^3.0.0", + "@arbitrum/sdk": "^4.0.0", "@aws-sdk/client-iam": "^3.74.0", - "@aws-sdk/client-kms": "3.48.0", - "@aws-sdk/client-s3": "^3.74.0", + "@aws-sdk/client-kms": "^3.577.0", + "@aws-sdk/client-s3": "^3.577.0", "@cosmjs/amino": "^0.32.4", "@eth-optimism/sdk": "^3.1.6", "@ethersproject/experimental": "^5.7.0", "@ethersproject/hardware-wallets": "^5.7.0", - "@ethersproject/providers": "^5.7.2", + "@ethersproject/providers": "*", "@google-cloud/secret-manager": "^5.5.0", - "@hyperlane-xyz/helloworld": "7.1.0", - "@hyperlane-xyz/registry": "6.1.0", - "@hyperlane-xyz/sdk": "7.1.0", - "@hyperlane-xyz/utils": "7.1.0", - "@inquirer/prompts": "^5.3.8", + "@hyperlane-xyz/helloworld": "7.3.0", + "@hyperlane-xyz/registry": "6.3.0", + "@hyperlane-xyz/sdk": "7.3.0", + "@hyperlane-xyz/utils": "7.3.0", + "@inquirer/prompts": "3.3.2", "@nomiclabs/hardhat-etherscan": "^3.0.3", "@safe-global/api-kit": "1.3.0", "@safe-global/protocol-kit": "1.3.0", "@safe-global/safe-core-sdk-types": "2.3.0", "@solana/web3.js": "^1.95.4", - "asn1.js": "5.4.1", + "asn1.js": "^5.4.1", "aws-kms-ethers-signer": "^0.1.3", "deep-object-diff": "^1.1.9", "dotenv": "^10.0.0", @@ -39,17 +39,17 @@ "@types/chai": "^4.2.21", "@types/json-stable-stringify": "^1.0.36", "@types/mocha": "^10.0.1", - "@types/node": "^16.9.1", + "@types/node": "^18.14.5", "@types/prompts": "^2.0.14", "@types/sinon-chai": "^3.2.12", "@types/yargs": "^17.0.24", - "chai": "4.5.0", + "chai": "^4.5.0", "ethereum-waffle": "^4.0.10", "ethers": "^5.7.2", "hardhat": "^2.22.2", "mocha": "^10.2.0", "prettier": "^2.8.8", - "tsx": "^4.7.1", + "tsx": "^4.19.1", "typescript": "5.3.3" }, "private": true, diff --git a/typescript/infra/scripts/agent-utils.ts b/typescript/infra/scripts/agent-utils.ts index 6f73005d3a..a1c214208e 100644 --- a/typescript/infra/scripts/agent-utils.ts +++ b/typescript/infra/scripts/agent-utils.ts @@ -1,11 +1,8 @@ +import { checkbox, select } from '@inquirer/prompts'; import path, { join } from 'path'; import yargs, { Argv } from 'yargs'; -import { - ChainAddresses, - IRegistry, - warpConfigToWarpAddresses, -} from '@hyperlane-xyz/registry'; +import { ChainAddresses, IRegistry } from '@hyperlane-xyz/registry'; import { ChainMap, ChainMetadata, @@ -27,6 +24,7 @@ import { import { Contexts } from '../config/contexts.js'; import { agents } from '../config/environments/agents.js'; +import { WarpRouteIds } from '../config/environments/mainnet3/warp/warpIds.js'; import { validatorBaseConfigsFn } from '../config/environments/utils.js'; import { getChain, @@ -157,20 +155,26 @@ export function withChain(args: Argv) { .alias('c', 'chain'); } -export function withChains(args: Argv) { +export function withChains(args: Argv, chainOptions?: ChainName[]) { return ( args .describe('chains', 'Set of chains to perform actions on.') .array('chains') - .choices('chains', getChains()) + .choices( + 'chains', + !chainOptions || chainOptions.length === 0 ? getChains() : chainOptions, + ) // Ensure chains are unique .coerce('chains', (chains: string[]) => Array.from(new Set(chains))) .alias('c', 'chains') ); } -export function withChainsRequired(args: Argv) { - return withChains(args).demandOption('chains'); +export function withChainsRequired( + args: Argv, + chainOptions?: ChainName[], +) { + return withChains(args, chainOptions).demandOption('chains'); } export function withWarpRouteId(args: Argv) { @@ -268,6 +272,49 @@ export function withRpcUrls(args: Argv) { .alias('r', 'rpcUrls'); } +export function withTxHashes(args: Argv) { + return args + .describe('txHashes', 'transaction hash') + .string('txHashes') + .array('txHashes') + .demandOption('txHashes') + .alias('t', 'txHashes'); +} + +// Interactively gets a single warp route ID +export async function getWarpRouteIdInteractive() { + const choices = Object.values(WarpRouteIds).map((id) => ({ + value: id, + })); + return select({ + message: 'Select Warp Route ID', + choices, + pageSize: 30, + }); +} + +// Interactively gets multiple warp route IDs +export async function getWarpRouteIdsInteractive() { + const choices = Object.values(WarpRouteIds).map((id) => ({ + value: id, + })); + + let selection: WarpRouteIds[] = []; + + while (!selection.length) { + selection = await checkbox({ + message: 'Select Warp Route IDs', + choices, + pageSize: 30, + }); + if (!selection.length) { + console.log('Please select at least one Warp Route ID'); + } + } + + return selection; +} + // not requiring to build coreConfig to get agentConfig export async function getAgentConfigsBasedOnArgs(argv?: { environment: DeployEnvironment; diff --git a/typescript/infra/scripts/check/check-utils.ts b/typescript/infra/scripts/check/check-utils.ts index 5925832fbd..a8289671a0 100644 --- a/typescript/infra/scripts/check/check-utils.ts +++ b/typescript/infra/scripts/check/check-utils.ts @@ -14,6 +14,7 @@ import { InterchainAccountConfig, InterchainQuery, InterchainQueryChecker, + MultiProvider, attachContractsMapAndGetForeignDeployments, hypERC20factories, proxiedFactories, @@ -37,6 +38,7 @@ import { logViolationDetails } from '../../src/utils/violation.js'; import { Modules, getArgs as getRootArgs, + getWarpRouteIdInteractive, withAsDeployer, withChains, withContext, @@ -72,9 +74,13 @@ export async function getGovernor( chains?: string[], fork?: string, govern?: boolean, + multiProvider: MultiProvider | undefined = undefined, ) { const envConfig = getEnvironmentConfig(environment); - let multiProvider = await envConfig.getMultiProvider(); + // If the multiProvider is not passed in, get it from the environment + if (!multiProvider) { + multiProvider = await envConfig.getMultiProvider(); + } // must rotate to forked provider before building core contracts if (fork) { @@ -187,7 +193,7 @@ export async function getGovernor( governor = new ProxiedRouterGovernor(checker); } else if (module === Modules.WARP) { if (!warpRouteId) { - throw new Error('Warp route id required for warp module'); + warpRouteId = await getWarpRouteIdInteractive(); } const config = await getWarpConfig(multiProvider, envConfig, warpRouteId); const warpAddresses = getWarpAddresses(warpRouteId); @@ -198,14 +204,17 @@ export async function getGovernor( ...warpAddresses[key], }; - // if the owner in the config is an AW account, set the proxyAdmin to the AW singleton proxyAdmin - // this will ensure that the checker will check that any proxies are owned by the singleton proxyAdmin - const proxyAdmin = eqAddress( - config[key].owner, - envConfig.owners[key]?.owner, - ) - ? chainAddresses[key]?.proxyAdmin - : undefined; + // Use the specified proxyAdmin if it is set in the config + let proxyAdmin = config[key].proxyAdmin?.address; + // If the owner in the config is an AW account and there is no proxyAdmin in the config, + // set the proxyAdmin to the AW singleton proxyAdmin. + // This will ensure that the checker will check that any proxies are owned by the singleton proxyAdmin. + if ( + !proxyAdmin && + eqAddress(config[key].owner, envConfig.owners[key]?.owner) + ) { + proxyAdmin = chainAddresses[key]?.proxyAdmin; + } if (proxyAdmin) { obj[key].proxyAdmin = proxyAdmin; diff --git a/typescript/infra/scripts/check/check-validator-announce.ts b/typescript/infra/scripts/check/check-validator-announce.ts index 0f484329f4..a57e89e8f7 100644 --- a/typescript/infra/scripts/check/check-validator-announce.ts +++ b/typescript/infra/scripts/check/check-validator-announce.ts @@ -36,7 +36,9 @@ async function main() { const announcedValidators = await validatorAnnounce.getAnnouncedValidators(); - const validators = defaultMultisigConfigs[chain].validators || []; + const defaultValidatorConfigs = + defaultMultisigConfigs[chain].validators || []; + const validators = defaultValidatorConfigs.map((v) => v.address); const unannouncedValidators = validators.filter( (validator) => !announcedValidators.some((x) => eqAddress(x, validator)), diff --git a/typescript/infra/scripts/check/check-validator-version.ts b/typescript/infra/scripts/check/check-validator-version.ts new file mode 100644 index 0000000000..72df04621d --- /dev/null +++ b/typescript/infra/scripts/check/check-validator-version.ts @@ -0,0 +1,215 @@ +import { execSync } from 'child_process'; + +import { ValidatorAnnounce__factory } from '@hyperlane-xyz/core'; +import { + ChainName, + defaultMultisigConfigs, + getValidatorFromStorageLocation, +} from '@hyperlane-xyz/sdk'; +import { Address } from '@hyperlane-xyz/utils'; + +import { isEthereumProtocolChain } from '../../src/utils/utils.js'; +import { getArgs, withChains } from '../agent-utils.js'; +import { getEnvironmentConfig, getHyperlaneCore } from '../core-utils.js'; + +// prettier-ignore +const acceptableValidatorVersions: Record = { + // Aug 27 deploy + '72d498fa984750b9137c1211fef6c80a3e594ce7': 'aug-27-batch', + // Sep 9 deploy + 'd71dd4e5ed7eb69cc4041813ef444e37d881cdda': 'sep-9-batch', + // Oct 27 deploy + '45399a314cec85723bbb5d2360531c96a3aa261e': 'oct-27-batch', + // Nov 7 deploy + '75d62ae7bbdeb77730c6d343c4fc1df97a08abe4': 'nov-7-batch', + // Nov 21 deploy + 'e70431a85965d8d21681e6f4856ed3ac9bd2ba27': 'nov-21-batch', + // Nov 21 bsquared deploy + 'd834d8147628584acd78a81e344bff76472d707e': 'nov-21-bsquared', + // Nov 21 swell/lumiaprism deploy + 'b35c105f197267072daa14bb3d83c62410b96fac': 'nov-21-swell', + // Rolled out only to AW infra before 1.0.0, just 1 commit behind 1.0.0 + 'a64af8be9a76120d0cfc727bb70660fa07e70cce': 'pre-1.0.0', + // 1.0.0 + 'ffbe1dd82e2452dbc111b6fb469a34fb870da8f1': '1.0.0', + // Tessellated's Own Build + '9b855686d3e2b3d6b81238ce51a576ff5e0f770f': 'tesselated-special-build', +}; + +type ValidatorInfo = { + chain: ChainName; + validator: Address; + alias: string; + version: string; + age?: string; +}; + +function sortValidatorInfo(a: ValidatorInfo, b: ValidatorInfo) { + // First sort by alias + if (a.alias && !b.alias) return -1; + if (!a.alias && b.alias) return 1; + if (a.alias && b.alias) { + const aliasCompare = a.alias.localeCompare(b.alias); + if (aliasCompare !== 0) return aliasCompare; + } + // Then sort by validator address + return a.chain.localeCompare(b.chain); +} + +function getCommitDate(sha: string): string | undefined { + try { + // Try to fetch the commit first if we don't have it + try { + execSync(`git fetch origin ${sha}`, { stdio: 'ignore' }); + } catch { + // Ignore fetch errors - commit might be local or unreachable + } + + // Use %cd for date and customize format with --date=format + const date = execSync( + `git show -s --date=format:'%Y-%m-%d %H:%M UTC' --format=%cd ${sha}`, + { encoding: 'utf-8' }, + ).trim(); + return date; + } catch { + return undefined; + } +} + +function getCommitAge(sha: string): string | undefined { + const commitDateString = getCommitDate(sha); + if (!commitDateString) { + return undefined; + } + + const commitDate = new Date(commitDateString); + if (isNaN(commitDate.getTime())) { + return undefined; + } + + const msToNow = Date.now() - commitDate.getTime(); + const days = Math.floor(msToNow / (1000 * 60 * 60 * 24)); + const hours = Math.floor( + (msToNow % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60), + ); + + const dayText = days === 1 ? 'day' : 'days'; + const hourText = hours === 1 ? 'hour' : 'hours'; + return days > 0 + ? `${days} ${dayText} ${hours} ${hourText} old` + : `${hours} ${hourText} old`; +} + +async function main() { + const { environment, chains, showUpdated } = await withChains(getArgs()) + .describe( + 'show-updated', + 'If enabled, prints a table with all updated validators', + ) + .boolean('show-updated') + .default('show-updated', false).argv; + + const config = getEnvironmentConfig(environment); + const { core } = await getHyperlaneCore(environment); + + const targetNetworks = ( + chains && chains.length > 0 ? chains : config.supportedChainNames + ).filter(isEthereumProtocolChain); + + const mismatchedValidators: ValidatorInfo[] = []; + const upgradedValidators: ValidatorInfo[] = []; + + // Manually add validator announce for OG Lumia chain deployment + const lumiaValidatorAnnounce = ValidatorAnnounce__factory.connect( + '0x989B7307d266151BE763935C856493D968b2affF', + core.multiProvider.getProvider('lumia'), + ); + + await Promise.all( + targetNetworks.map(async (chain) => { + const validatorAnnounce = + chain === 'lumia' + ? lumiaValidatorAnnounce + : core.getContracts(chain).validatorAnnounce; + const expectedValidators = defaultMultisigConfigs[chain].validators || []; + const storageLocations = + await validatorAnnounce.getAnnouncedStorageLocations( + expectedValidators.map((v) => v.address), + ); + + // For each validator on this chain + for (let i = 0; i < expectedValidators.length; i++) { + const { address: validator, alias } = expectedValidators[i]; + const location = storageLocations[i][0]; + + // Get metadata from each storage location + try { + const validatorInstance = await getValidatorFromStorageLocation( + location, + ); + + const metadata = await validatorInstance.getMetadata(); + const gitSha = metadata?.git_sha; + + if (Object.keys(acceptableValidatorVersions).includes(gitSha)) { + upgradedValidators.push({ + chain, + validator, + alias, + version: acceptableValidatorVersions[gitSha], + }); + } else { + mismatchedValidators.push({ + chain, + validator, + alias, + version: gitSha ? gitSha.slice(0, 7) : 'missing', + age: getCommitAge(gitSha), + }); + } + } catch (error) { + console.warn( + `Error getting metadata for ${validator} on chain ${chain}: ${error}`, + ); + mismatchedValidators.push({ + chain, + validator, + alias, + version: ` ??? `, + }); + } + } + }), + ); + + const showUpdatedValidators = () => { + if (showUpdated) { + console.log( + `\n✅ ${upgradedValidators.length} Validators with expected git SHA:`, + ); + console.table(upgradedValidators.sort(sortValidatorInfo)); + } + }; + + if (mismatchedValidators.length > 0) { + console.log( + '\nExpecting validators to have one of the following git SHA:\n' + + Object.entries(acceptableValidatorVersions) + .map(([key, value]) => ` • ${key} (${value})`) + .join('\n'), + ); + console.log( + `\n⚠️ ${mismatchedValidators.length} Validators with mismatched git SHA:`, + ); + console.table(mismatchedValidators.sort(sortValidatorInfo)); + + showUpdatedValidators(); + process.exit(1); + } + + showUpdatedValidators(); + console.log('\n✅ All validators running expected git SHA!'); + process.exit(0); +} + +main().catch(console.error); diff --git a/typescript/infra/scripts/check/check-warp-deploy.ts b/typescript/infra/scripts/check/check-warp-deploy.ts index aa51c70165..2cc11d8f0f 100644 --- a/typescript/infra/scripts/check/check-warp-deploy.ts +++ b/typescript/infra/scripts/check/check-warp-deploy.ts @@ -3,7 +3,8 @@ import { Gauge, Registry } from 'prom-client'; import { warpConfigGetterMap } from '../../config/warp.js'; import { submitMetrics } from '../../src/utils/metrics.js'; -import { Modules } from '../agent-utils.js'; +import { Modules, getWarpRouteIdsInteractive } from '../agent-utils.js'; +import { getEnvironmentConfig } from '../core-utils.js'; import { getCheckWarpDeployArgs, @@ -13,8 +14,19 @@ import { } from './check-utils.js'; async function main() { - const { environment, asDeployer, chains, fork, context, pushMetrics } = - await getCheckWarpDeployArgs().argv; + const { + environment, + asDeployer, + chains, + fork, + context, + pushMetrics, + interactive, + } = await getCheckWarpDeployArgs().argv; + + const envConfig = getEnvironmentConfig(environment); + // Get the multiprovider once to avoid recreating it for each warp route + const multiProvider = await envConfig.getMultiProvider(); const metricsRegister = new Registry(); const checkerViolationsGauge = new Gauge( @@ -24,8 +36,13 @@ async function main() { const failedWarpRoutesChecks: string[] = []; + let warpIdsToCheck = Object.keys(warpConfigGetterMap); + if (interactive) { + warpIdsToCheck = await getWarpRouteIdsInteractive(); + } + // TODO: consider retrying this if check throws an error - for (const warpRouteId of Object.keys(warpConfigGetterMap)) { + for (const warpRouteId of warpIdsToCheck) { console.log(`\nChecking warp route ${warpRouteId}...`); const warpModule = Modules.WARP; @@ -38,6 +55,8 @@ async function main() { warpRouteId, chains, fork, + false, + multiProvider, ); await governor.check(); diff --git a/typescript/infra/scripts/cosmos-helpers/deploy-ism-payload.ts b/typescript/infra/scripts/cosmos-helpers/deploy-ism-payload.ts index 9f35775cd1..36784e4576 100644 --- a/typescript/infra/scripts/cosmos-helpers/deploy-ism-payload.ts +++ b/typescript/infra/scripts/cosmos-helpers/deploy-ism-payload.ts @@ -47,7 +47,7 @@ async function main() { multiProvider.getDomainId(chain), { // Must strip 0x from addresses for compatibility with cosmos tooling - addrs: multisig.validators.map(strip0x), + addrs: multisig.validators.map(({ address }) => strip0x(address)), threshold: multisig.threshold, }, ]; diff --git a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts index 4601dc702f..e8522e2628 100644 --- a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts +++ b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts @@ -1,8 +1,7 @@ -import { EthBridger, getL2Network } from '@arbitrum/sdk'; +import { EthBridger, getArbitrumNetwork } from '@arbitrum/sdk'; import { CrossChainMessenger } from '@eth-optimism/sdk'; -import { Connection, PublicKey } from '@solana/web3.js'; import { BigNumber, ethers } from 'ethers'; -import { Gauge, Registry } from 'prom-client'; +import { Registry } from 'prom-client'; import { format } from 'util'; import { @@ -15,7 +14,6 @@ import { Address, objFilter, objMap, rootLogger } from '@hyperlane-xyz/utils'; import { Contexts } from '../../config/contexts.js'; import { getEnvAddresses } from '../../config/registry.js'; -import { getSecretRpcEndpoints } from '../../src/agents/index.js'; import { KeyAsAddress, fetchLocalKeyAddresses, @@ -33,7 +31,10 @@ import { KeyFunderConfig, } from '../../src/config/funding.js'; import { FundableRole, Role } from '../../src/roles.js'; -import { submitMetrics } from '../../src/utils/metrics.js'; +import { + getWalletBalanceGauge, + submitMetrics, +} from '../../src/utils/metrics.js'; import { assertContext, assertFundableRole, @@ -65,30 +66,19 @@ const L2ToL1: ChainMap = { base: 'ethereum', }; +// Manually adding these labels as we are using a push gateway, +// and ordinarily these labels would be added via K8s annotations const constMetricLabels = { - // this needs to get set in main because of async reasons hyperlane_deployment: '', hyperlane_context: 'hyperlane', }; const metricsRegister = new Registry(); -const walletBalanceGauge = new Gauge({ - // Mirror the rust/main/ethers-prometheus `wallet_balance` gauge metric. - name: 'hyperlane_wallet_balance', - help: 'Current balance of eth and other tokens in the `tokens` map for the wallet addresses in the `wallets` set', - registers: [metricsRegister], - labelNames: [ - 'chain', - 'wallet_address', - 'wallet_name', - 'token_address', - 'token_symbol', - 'token_name', - ...(Object.keys(constMetricLabels) as (keyof typeof constMetricLabels)[]), - ], -}); -metricsRegister.registerMetric(walletBalanceGauge); +const walletBalanceGauge = getWalletBalanceGauge( + metricsRegister, + Object.keys(constMetricLabels), +); // Min delta is 50% of the desired balance const MIN_DELTA_NUMERATOR = ethers.BigNumber.from(5); @@ -98,87 +88,8 @@ const MIN_DELTA_DENOMINATOR = ethers.BigNumber.from(10); const RC_FUNDING_DISCOUNT_NUMERATOR = ethers.BigNumber.from(2); const RC_FUNDING_DISCOUNT_DENOMINATOR = ethers.BigNumber.from(10); -interface SealevelAccount { - pubkey: PublicKey; - walletName: string; -} - -const sealevelAccountsToTrack: ChainMap = { - solanamainnet: [ - { - // WIF warp route ATA payer - pubkey: new PublicKey('R5oMfxcbjx4ZYK1B2Aic1weqwt2tQsRzFEGe5WJfAxh'), - walletName: 'WIF/eclipsemainnet-solanamainnet/ata-payer', - }, - { - // USDC warp route ATA payer - pubkey: new PublicKey('A1XtL9mAzkNEpBPinrCpDRrPqVAFjgaxDk4ATFVoQVyc'), - walletName: 'USDC/eclipsemainnet-ethereum-solanamainnet/ata-payer', - }, - { - // USDT warp route ATA payer - pubkey: new PublicKey('9i3kYQqMtkm4sw1w5SQ8ebKMmh4LPVYKZRMPaZeRfn37'), - walletName: 'USDT/eclipsemainnet-ethereum-solanamainnet/ata-payer', - }, - { - // ORCA warp route ATA payer - pubkey: new PublicKey('HqAVwQA6rh1TGdyUHi2XqmCtBSyG3DZjjsCLRXWqyNuU'), - walletName: 'ORCA/eclipsemainnet-solanamainnet/ata-payer', - }, - ], - eclipsemainnet: [ - { - // WIF warp route ATA payer - pubkey: new PublicKey('HCQAfDd5ytAEidzR9g7CipjEGv2ZrSSZq1UY34oDFv8h'), - walletName: 'WIF/eclipsemainnet-solanamainnet/ata-payer', - }, - { - // USDC warp route ATA payer - pubkey: new PublicKey('7arS1h8nwVVmmTVWSsu9rQ4WjLBN8iAi4DvHi8gWjBNC'), - walletName: 'USDC/eclipsemainnet-ethereum-solanamainnet/ata-payer', - }, - { - // tETH warp route ATA payer - pubkey: new PublicKey('Hyy4jryRxgZm5pvuSx29fXxJ9J55SuDtXiCo89kmNuz5'), - walletName: 'tETH/eclipsemainnet-ethereum/ata-payer', - }, - { - // SOL warp route ATA payer - pubkey: new PublicKey('CijxTbPs9JZxTUfo8Hmz2imxzHtKnDFD3kZP3RPy34uJ'), - walletName: 'SOL/eclipsemainnet-solanamainnet/ata-payer', - }, - { - // stTIA warp route ATA payer - pubkey: new PublicKey('Bg3bAM3gEhdam5mbPqkiMi3mLZkoAieakMRdMHo6mbcn'), - walletName: 'stTIA/eclipsemainnet-stride/ata-payer', - }, - { - // TIA warp route ATA payer - pubkey: new PublicKey('AZs4Rw6H6YwJBKoHBCfChCitHnHvQcVGgrJwGh4bKmAf'), - walletName: 'TIA/eclipsemainnet-stride/ata-payer', - }, - { - // USDT warp route ATA payer - pubkey: new PublicKey('78s5TD48q89EZqHNC2bfsswQXn6n3sn1ecGgqXgJe4hL'), - walletName: 'USDT/eclipsemainnet-ethereum-solanamainnet/ata-payer', - }, - { - // ORCA warp route ATA payer - pubkey: new PublicKey('3ZyZHoDRzfYg4ug6Tx4Zywe6M5Vt19vPZFx9Ag8qqnXu'), - walletName: 'ORCA/eclipsemainnet-solanamainnet/ata-payer', - }, - { - // WBTC warp route ATA payer - pubkey: new PublicKey('BH9VfgYaCWbwuupzsTfSy67yR4dwuCbXmFRrm6aAH2NQ'), - walletName: 'WBTC/eclipsemainnet-ethereum/ata-payer', - }, - // weETHs warp route ATA payer - { - pubkey: new PublicKey('F4Y6kHrq9qVnmkQhQibxh8nCU2quw5y25z7u8jSHMvtq'), - walletName: 'weETHs/eclipsemainnet-ethereum/ata-payer', - }, - ], -}; +const CONTEXT_FUNDING_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes +const CHAIN_FUNDING_TIMEOUT_MS = 1 * 60 * 1000; // 1 minute // Funds key addresses for multiple contexts from the deployer key of the context // specified via the `--context` flag. @@ -285,7 +196,25 @@ async function main() { let failureOccurred = false; for (const funder of contextFunders) { - failureOccurred ||= await funder.fund(); + const { promise, cleanup } = createTimeoutPromise( + CONTEXT_FUNDING_TIMEOUT_MS, + `Funding timed out for context ${funder.context} after ${ + CONTEXT_FUNDING_TIMEOUT_MS / 1000 + }s`, + ); + + try { + await Promise.race([funder.fund(), promise]); + } catch (error) { + logger.error('Error funding context', { + error: format(error), + context: funder.context, + timeoutMs: CONTEXT_FUNDING_TIMEOUT_MS, + }); + failureOccurred = true; + } finally { + cleanup(); + } } await submitMetrics(metricsRegister, `key-funder-${environment}`); @@ -506,103 +435,129 @@ class ContextFunder { igpClaimThresholdPerChain, ); } - - // Funds all the roles in this.rolesToFund - // Returns whether a failure occurred. - async fund(): Promise { + // Funds all the roles in this.keysToFundPerChain. + // Throws if any funding operations fail. + async fund(): Promise { const chainKeyEntries = Object.entries(this.keysToFundPerChain); - const promises = chainKeyEntries.map(async ([chain, keys]) => { - let failureOccurred = false; - - if (keys.length > 0) { - if (!this.skipIgpClaim) { - failureOccurred ||= await gracefullyHandleError( - () => this.attemptToClaimFromIgp(chain), - chain, - 'Error claiming from IGP', - ); - } + const results = await Promise.allSettled( + chainKeyEntries.map(([chain, keys]) => this.fundChain(chain, keys)), + ); - failureOccurred ||= await gracefullyHandleError( - () => this.bridgeIfL2(chain), - chain, - 'Error bridging to L2', - ); - } - for (const key of keys) { - const failure = await this.attemptToFundKey(key, chain); - failureOccurred ||= failure; - } - return failureOccurred; - }); + if (results.some((result) => result.status === 'rejected')) { + logger.error('One or more chains failed to fund'); + throw new Error('One or more chains failed to fund'); + } + } - // A failure occurred if any of the promises rejected or - // if any of them resolved with true, indicating a failure - // somewhere along the way - const failureOccurred = (await Promise.allSettled(promises)).reduce( - (failureAgg, result, i) => { - if (result.status === 'rejected') { - logger.error( - { - chain: chainKeyEntries[i][0], - error: format(result.reason), - }, - 'Funding promise for chain rejected', - ); - return true; - } - return result.value || failureAgg; - }, - false, + private async fundChain(chain: string, keys: BaseAgentKey[]): Promise { + const { promise, cleanup } = createTimeoutPromise( + CHAIN_FUNDING_TIMEOUT_MS, + `Timed out funding chain ${chain} after ${ + CHAIN_FUNDING_TIMEOUT_MS / 1000 + }s`, ); - if ( - this.environment === 'mainnet3' && - this.context === Contexts.Hyperlane - ) { - await this.updateSolanaWalletBalanceGauge(); + try { + await Promise.race([this.executeFundingOperations(chain, keys), promise]); + } catch (error) { + logger.error( + { + chain, + error: format(error), + timeoutMs: CHAIN_FUNDING_TIMEOUT_MS, + keysCount: keys.length, + }, + `Funding operations failed for chain ${chain}.`, + ); + throw error; + } finally { + cleanup(); } - - return failureOccurred; } - private async attemptToFundKey( - key: BaseAgentKey, - chain: ChainName, - ): Promise { - const provider = this.multiProvider.tryGetProvider(chain); - if (!provider) { - logger.error({ chain }, 'Cannot get chain connection'); - // Consider this an error, but don't throw and prevent all future funding attempts - return true; + private async executeFundingOperations( + chain: string, + keys: BaseAgentKey[], + ): Promise { + if (keys.length === 0) { + return; } - const desiredBalance = this.getDesiredBalanceForRole(chain, key.role); - let failureOccurred = false; + if (!this.skipIgpClaim) { + try { + await this.attemptToClaimFromIgp(chain); + } catch (err) { + logger.error( + { + chain, + error: err, + }, + `Error claiming from IGP on chain ${chain}`, + ); + } + } try { - await this.fundKeyIfRequired(chain, key, desiredBalance); + await this.bridgeIfL2(chain); } catch (err) { logger.error( { - key: await getKeyInfo( - key, - chain, - this.multiProvider.getProvider(chain), - ), - context: this.context, + chain, error: err, }, - 'Error funding key', + `Error bridging to L2 chain ${chain}`, ); - failureOccurred = true; + throw err; + } + + const failedKeys: BaseAgentKey[] = []; + for (const key of keys) { + try { + await this.attemptToFundKey(key, chain); + } catch (err) { + logger.error( + { + chain, + key: await getKeyInfo( + key, + chain, + this.multiProvider.getProvider(chain), + ), + context: this.context, + error: err, + }, + `Error funding key ${key.address} on chain ${chain}`, + ); + failedKeys.push(key); + } } - await this.updateWalletBalanceGauge(chain); - return failureOccurred; + if (failedKeys.length > 0) { + throw new Error( + `Failed to fund ${ + failedKeys.length + } keys on chain ${chain}: ${failedKeys + .map(({ address, role }) => `${address} (${role})`) + .join(', ')}`, + ); + } } - private async bridgeIfL2(chain: ChainName) { + private async attemptToFundKey( + key: BaseAgentKey, + chain: ChainName, + ): Promise { + const provider = this.multiProvider.tryGetProvider(chain); + if (!provider) { + throw new Error(`Cannot get chain connection for ${chain}`); + } + + const desiredBalance = this.getDesiredBalanceForRole(chain, key.role); + await this.fundKeyIfRequired(chain, key, desiredBalance); + await this.updateWalletBalanceGauge(chain); + } + + private async bridgeIfL2(chain: ChainName): Promise { if (L2Chains.includes(chain)) { const funderAddress = await this.multiProvider.getSignerAddress(chain)!; const desiredBalanceEther = ethers.utils.parseUnits( @@ -625,7 +580,7 @@ class ContextFunder { // Attempts to claim from the IGP if the balance exceeds the claim threshold. // If no threshold is set, infer it by reading the desired balance and dividing that by 5. - private async attemptToClaimFromIgp(chain: ChainName) { + private async attemptToClaimFromIgp(chain: ChainName): Promise { // Determine the IGP claim threshold in Ether for the given chain. // If a specific threshold is not set, use the desired balance for the chain. const igpClaimThresholdEther = @@ -794,6 +749,8 @@ class ContextFunder { const l1Chain = L2ToL1[l2Chain]; logger.info( { + l1Chain, + l2Chain, amount: ethers.utils.formatEther(amount), l1Funder: await getAddressInfo( await this.multiProvider.getSignerAddress(l1Chain), @@ -841,13 +798,13 @@ class ContextFunder { private async bridgeToArbitrum(l2Chain: ChainName, amount: BigNumber) { const l1Chain = L2ToL1[l2Chain]; - const l2Network = await getL2Network( + const l2Network = await getArbitrumNetwork( this.multiProvider.getEvmChainId(l2Chain), ); const ethBridger = new EthBridger(l2Network); return ethBridger.deposit({ amount, - l1Signer: this.multiProvider.getSigner(l1Chain), + parentSigner: this.multiProvider.getSigner(l1Chain), overrides: this.multiProvider.getTransactionOverrides(l1Chain), }); } @@ -909,54 +866,6 @@ class ContextFunder { ), ); } - - private async updateSolanaWalletBalanceGauge() { - for (const chain of Object.keys(sealevelAccountsToTrack) as ChainName[]) { - await this.updateSealevelWalletBalanceAccounts( - chain, - sealevelAccountsToTrack[chain], - ); - } - } - - private async updateSealevelWalletBalanceAccounts( - chain: ChainName, - accounts: SealevelAccount[], - ) { - const rpcUrls = await getSecretRpcEndpoints(this.environment, chain); - const provider = new Connection(rpcUrls[0], 'confirmed'); - - for (const { pubkey, walletName } of accounts) { - logger.info( - { - chain, - pubkey: pubkey.toString(), - walletName, - }, - 'Fetching sealevel wallet balance', - ); - const balance = await provider.getBalance(pubkey); - logger.info( - { - balance, - chain, - pubkey: pubkey.toString(), - walletName, - }, - 'Retrieved sealevel chain wallet balance', - ); - walletBalanceGauge - .labels({ - chain, - wallet_address: pubkey.toString(), - wallet_name: walletName, - token_symbol: 'Native', - token_name: 'Native', - ...constMetricLabels, - }) - .set(balance / 1e9); - } - } } async function getAddressInfo( @@ -1038,25 +947,20 @@ function parseBalancePerChain(strs: string[]): ChainMap { return balanceMap; } -// Returns whether an error occurred -async function gracefullyHandleError( - fn: () => Promise, - chain: ChainName, +// Utility function to create a timeout promise +function createTimeoutPromise( + timeoutMs: number, errorMessage: string, -): Promise { - try { - await fn(); - return false; - } catch (err) { - logger.error( - { - chain, - error: format(err), - }, - errorMessage, +): { promise: Promise; cleanup: () => void } { + let cleanup: () => void; + const promise = new Promise((_, reject) => { + const timeout = setTimeout( + () => reject(new Error(errorMessage)), + timeoutMs, ); - } - return true; + cleanup = () => clearTimeout(timeout); + }); + return { promise, cleanup: cleanup! }; } main().catch((err) => { diff --git a/typescript/infra/scripts/helloworld/kathy.ts b/typescript/infra/scripts/helloworld/kathy.ts index dfed8fe6b8..678e2bb75d 100644 --- a/typescript/infra/scripts/helloworld/kathy.ts +++ b/typescript/infra/scripts/helloworld/kathy.ts @@ -35,7 +35,10 @@ import { owners } from '../../config/environments/testnet4/owners.js'; import { CloudAgentKey } from '../../src/agents/keys.js'; import { DeployEnvironment } from '../../src/config/environment.js'; import { Role } from '../../src/roles.js'; -import { startMetricsServer } from '../../src/utils/metrics.js'; +import { + getWalletBalanceGauge, + startMetricsServer, +} from '../../src/utils/metrics.js'; import { assertChain, diagonalize } from '../../src/utils/utils.js'; import { getArgs, withContext } from '../agent-utils.js'; import { getEnvironmentConfig } from '../core-utils.js'; @@ -70,19 +73,7 @@ const messageReceiptSeconds = new Counter({ registers: [metricsRegister], labelNames: ['origin', 'remote'], }); -const walletBalance = new Gauge({ - name: 'hyperlane_wallet_balance', - help: 'Current balance of eth and other tokens in the `tokens` map for the wallet addresses in the `wallets` set', - registers: [metricsRegister], - labelNames: [ - 'chain', - 'wallet_address', - 'wallet_name', - 'token_address', - 'token_symbol', - 'token_name', - ], -}); +const walletBalance = getWalletBalanceGauge(metricsRegister); /** The maximum number of messages we will allow to get queued up if we are sending too slowly. */ const MAX_MESSAGES_ALLOWED_TO_SEND = 5; diff --git a/typescript/infra/scripts/safes/get-pending-txs.ts b/typescript/infra/scripts/safes/get-pending-txs.ts new file mode 100644 index 0000000000..13d8c15d88 --- /dev/null +++ b/typescript/infra/scripts/safes/get-pending-txs.ts @@ -0,0 +1,215 @@ +import { confirm } from '@inquirer/prompts'; +import chalk from 'chalk'; +import { formatUnits } from 'ethers/lib/utils.js'; +import yargs from 'yargs'; + +import { MultiProvider } from '@hyperlane-xyz/sdk'; +import { LogFormat, LogLevel, configureRootLogger } from '@hyperlane-xyz/utils'; + +import { Contexts } from '../../config/contexts.js'; +import { safes } from '../../config/environments/mainnet3/owners.js'; +import { Role } from '../../src/roles.js'; +import { executeTx, getSafeAndService } from '../../src/utils/safe.js'; +import { withChains } from '../agent-utils.js'; +import { getEnvironmentConfig } from '../core-utils.js'; + +export enum SafeTxStatus { + NO_CONFIRMATIONS = '🔴', + PENDING = '🟡', + ONE_AWAY = '🔵', + READY_TO_EXECUTE = '🟢', +} + +type SafeStatus = { + chain: string; + nonce: number; + submissionDate: string; + shortTxHash: string; + fullTxHash: string; + confs: number; + threshold: number; + status: string; + balance: string; +}; + +export async function getPendingTxsForChains( + chains: string[], + multiProvider: MultiProvider, +): Promise { + const txs: SafeStatus[] = []; + await Promise.all( + chains.map(async (chain) => { + if (!safes[chain]) { + console.error(chalk.red.bold(`No safe found for ${chain}`)); + return; + } + + if (chain === 'endurance') { + console.info( + chalk.gray.italic( + `Skipping chain ${chain} as it does not have a functional safe API`, + ), + ); + return; + } + + let safeSdk, safeService; + try { + ({ safeSdk, safeService } = await getSafeAndService( + chain, + multiProvider, + safes[chain], + )); + } catch (error) { + console.warn( + chalk.yellow( + `Skipping chain ${chain} as there was an error getting the safe service: ${error}`, + ), + ); + return; + } + + const threshold = await safeSdk.getThreshold(); + const pendingTxs = await safeService.getPendingTransactions(safes[chain]); + if (pendingTxs.results.length === 0) { + return; + } + + const balance = await safeSdk.getBalance(); + const nativeToken = await multiProvider.getNativeToken(chain); + const formattedBalance = formatUnits(balance, nativeToken.decimals); + + pendingTxs.results.forEach( + ({ nonce, submissionDate, safeTxHash, confirmations }) => { + const confs = confirmations?.length ?? 0; + const status = + confs >= threshold + ? SafeTxStatus.READY_TO_EXECUTE + : confs === 0 + ? SafeTxStatus.NO_CONFIRMATIONS + : threshold - confs + ? SafeTxStatus.ONE_AWAY + : SafeTxStatus.PENDING; + + txs.push({ + chain, + nonce, + submissionDate: new Date(submissionDate).toDateString(), + shortTxHash: `${safeTxHash.slice(0, 6)}...${safeTxHash.slice(-4)}`, + fullTxHash: safeTxHash, + confs, + threshold, + status, + balance: `${Number(formattedBalance).toFixed(5)} ${ + nativeToken.symbol + }`, + }); + }, + ); + }), + ); + return txs.sort( + (a, b) => a.chain.localeCompare(b.chain) || a.nonce - b.nonce, + ); +} + +async function main() { + const safeChains = Object.keys(safes); + configureRootLogger(LogFormat.Pretty, LogLevel.Info); + const { chains, fullTxHash } = await withChains( + yargs(process.argv.slice(2)), + safeChains, + ) + .describe( + 'fullTxHash', + 'If enabled, include the full tx hash in the output', + ) + .boolean('fullTxHash') + .default('fullTxHash', false).argv; + + const chainsToCheck = chains || safeChains; + if (chainsToCheck.length === 0) { + console.error('No chains provided'); + process.exit(1); + } + + const envConfig = getEnvironmentConfig('mainnet3'); + const multiProvider = await envConfig.getMultiProvider( + Contexts.Hyperlane, + Role.Deployer, + true, + chainsToCheck, + ); + + const pendingTxs = await getPendingTxsForChains(chainsToCheck, multiProvider); + if (pendingTxs.length === 0) { + console.info(chalk.green('No pending transactions found!')); + process.exit(0); + } + console.table(pendingTxs, [ + 'chain', + 'nonce', + 'submissionDate', + fullTxHash ? 'fullTxHash' : 'shortTxHash', + 'confs', + 'threshold', + 'status', + 'balance', + ]); + + const executableTxs = pendingTxs.filter( + (tx) => tx.status === SafeTxStatus.READY_TO_EXECUTE, + ); + if (executableTxs.length === 0) { + console.info(chalk.green('No transactions to execute!')); + process.exit(0); + } + + const shouldExecute = await confirm({ + message: 'Execute transactions?', + default: false, + }); + + if (!shouldExecute) { + console.info( + chalk.blue( + `${executableTxs.length} transactions available for execution`, + ), + ); + process.exit(0); + } + + console.info(chalk.blueBright('Executing transactions...')); + + for (const tx of executableTxs) { + const confirmExecuteTx = await confirm({ + message: `Execute transaction ${tx.shortTxHash} on chain ${tx.chain}?`, + default: false, + }); + if (confirmExecuteTx) { + console.log( + `Executing transaction ${tx.shortTxHash} on chain ${tx.chain}`, + ); + try { + await executeTx( + tx.chain, + multiProvider, + safes[tx.chain], + tx.fullTxHash, + ); + } catch (error) { + console.error(chalk.red(`Error executing transaction: ${error}`)); + return; + } + } + } + + process.exit(0); +} + +main() + .then() + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/typescript/infra/scripts/safes/parse-txs.ts b/typescript/infra/scripts/safes/parse-txs.ts new file mode 100644 index 0000000000..ac897cd279 --- /dev/null +++ b/typescript/infra/scripts/safes/parse-txs.ts @@ -0,0 +1,67 @@ +import { BigNumber } from 'ethers'; + +import { AnnotatedEV5Transaction } from '@hyperlane-xyz/sdk'; +import { stringifyObject } from '@hyperlane-xyz/utils'; + +import { GovernTransactionReader } from '../../src/tx/govern-transaction-reader.js'; +import { getSafeTx } from '../../src/utils/safe.js'; +import { getArgs, withChainsRequired, withTxHashes } from '../agent-utils.js'; +import { getEnvironmentConfig, getHyperlaneCore } from '../core-utils.js'; + +async function main() { + const { environment, chains, txHashes } = await withTxHashes( + withChainsRequired(getArgs()), + ).argv; + + const config = getEnvironmentConfig(environment); + const multiProvider = await config.getMultiProvider(); + const { chainAddresses } = await getHyperlaneCore(environment, multiProvider); + + const registry = await config.getRegistry(); + const warpRoutes = await registry.getWarpRoutes(); + + const reader = new GovernTransactionReader( + environment, + multiProvider, + chainAddresses, + config.core, + warpRoutes, + ); + + const chainResultEntries = await Promise.all( + chains.map(async (chain, chainIndex) => { + const txHash = txHashes[chainIndex]; + console.log(`Reading tx ${txHash} on ${chain}`); + const safeTx = await getSafeTx(chain, multiProvider, txHash); + const tx: AnnotatedEV5Transaction = { + to: safeTx.to, + data: safeTx.data, + value: BigNumber.from(safeTx.value), + }; + + try { + const results = await reader.read(chain, tx); + console.log(`Finished reading tx ${txHash} on ${chain}`); + return [chain, results]; + } catch (err) { + console.error('Error reading transaction', err, chain, tx); + process.exit(1); + } + }), + ); + + const chainResults = Object.fromEntries(chainResultEntries); + console.log(stringifyObject(chainResults, 'yaml', 2)); + + if (reader.errors.length) { + console.error('❌❌❌❌❌ Encountered fatal errors ❌❌❌❌❌'); + console.log(stringifyObject(reader.errors, 'yaml', 2)); + console.error('❌❌❌❌❌ Encountered fatal errors ❌❌❌❌❌'); + process.exit(1); + } +} + +main().catch((err) => { + console.error('Error:', err); + process.exit(1); +}); diff --git a/typescript/infra/scripts/warp-routes/deploy-warp-monitor.ts b/typescript/infra/scripts/warp-routes/deploy-warp-monitor.ts index e7714778ca..29fd16b9a9 100644 --- a/typescript/infra/scripts/warp-routes/deploy-warp-monitor.ts +++ b/typescript/infra/scripts/warp-routes/deploy-warp-monitor.ts @@ -1,5 +1,4 @@ import { checkbox } from '@inquirer/prompts'; -import yargs from 'yargs'; import { Contexts } from '../../config/contexts.js'; import { WarpRouteIds } from '../../config/environments/mainnet3/warp/warpIds.js'; @@ -9,6 +8,7 @@ import { assertCorrectKubeContext, getAgentConfig, getArgs, + getWarpRouteIdsInteractive, withWarpRouteId, } from '../agent-utils.js'; import { getEnvironmentConfig } from '../core-utils.js'; @@ -41,27 +41,6 @@ async function main() { } } -async function getWarpRouteIdsInteractive() { - const choices = Object.values(WarpRouteIds).map((id) => ({ - value: id, - })); - - let selection: WarpRouteIds[] = []; - - while (!selection.length) { - selection = await checkbox({ - message: 'Select Warp Route IDs to deploy', - choices, - pageSize: 30, - }); - if (!selection.length) { - console.log('Please select at least one Warp Route ID'); - } - } - - return selection; -} - main() .then(() => console.log('Deploy successful!')) .catch(console.error); diff --git a/typescript/infra/scripts/warp-routes/generate-warp-config.ts b/typescript/infra/scripts/warp-routes/generate-warp-config.ts index 61f1cd46f6..077cef0d4c 100644 --- a/typescript/infra/scripts/warp-routes/generate-warp-config.ts +++ b/typescript/infra/scripts/warp-routes/generate-warp-config.ts @@ -34,4 +34,4 @@ async function main() { } } -main().catch(console.error).then(console.log); +main().catch((err) => console.error('Error:', err)); diff --git a/typescript/infra/scripts/warp-routes/monitor/metrics.ts b/typescript/infra/scripts/warp-routes/monitor/metrics.ts index eec6738ab1..52c2604f96 100644 --- a/typescript/infra/scripts/warp-routes/monitor/metrics.ts +++ b/typescript/infra/scripts/warp-routes/monitor/metrics.ts @@ -3,7 +3,9 @@ import { Gauge, Registry } from 'prom-client'; import { createWarpRouteConfigId } from '@hyperlane-xyz/registry'; import { ChainName, Token, TokenStandard, WarpCore } from '@hyperlane-xyz/sdk'; -import { WarpRouteBalance, XERC20Limit } from './types.js'; +import { getWalletBalanceGauge } from '../../../src/utils/metrics.js'; + +import { NativeWalletBalance, WarpRouteBalance, XERC20Limit } from './types.js'; import { logger } from './utils.js'; export const metricsRegister = new Registry(); @@ -44,6 +46,8 @@ const warpRouteCollateralValue = new Gauge({ labelNames: warpRouteMetricLabels, }); +const walletBalanceGauge = getWalletBalanceGauge(metricsRegister); + const xERC20LimitsGauge = new Gauge({ name: 'hyperlane_xerc20_limits', help: 'Current minting and burning limits of xERC20 tokens', @@ -94,6 +98,21 @@ export function updateTokenBalanceMetrics( } } +export function updateNativeWalletBalanceMetrics(balance: NativeWalletBalance) { + walletBalanceGauge + .labels({ + chain: balance.chain, + wallet_address: balance.walletAddress, + wallet_name: balance.walletName, + token_symbol: 'Native', + token_name: 'Native', + }) + .set(balance.balance); + logger.info('Native wallet balance updated', { + balanceInfo: balance, + }); +} + export function updateXERC20LimitsMetrics(token: Token, limits: XERC20Limit) { for (const [limitType, limit] of Object.entries(limits)) { xERC20LimitsGauge diff --git a/typescript/infra/scripts/warp-routes/monitor/monitor-warp-route-balances.ts b/typescript/infra/scripts/warp-routes/monitor/monitor-warp-route-balances.ts index 7a8fdb645a..1591d92b3d 100644 --- a/typescript/infra/scripts/warp-routes/monitor/monitor-warp-route-balances.ts +++ b/typescript/infra/scripts/warp-routes/monitor/monitor-warp-route-balances.ts @@ -1,5 +1,6 @@ import { PopulatedTransaction } from 'ethers'; +import { createWarpRouteConfigId } from '@hyperlane-xyz/registry'; import { ChainMap, ChainMetadata, @@ -9,6 +10,7 @@ import { IHypXERC20Adapter, MultiProtocolProvider, RouterConfig, + SealevelHypTokenAdapter, Token, TokenStandard, WarpCore, @@ -22,25 +24,35 @@ import { } from '../../../src/config/environment.js'; import { fetchGCPSecret } from '../../../src/utils/gcloud.js'; import { startMetricsServer } from '../../../src/utils/metrics.js'; -import { getArgs, withWarpRouteIdRequired } from '../../agent-utils.js'; +import { + getArgs, + getWarpRouteIdInteractive, + withWarpRouteId, +} from '../../agent-utils.js'; import { getEnvironmentConfig } from '../../core-utils.js'; import { metricsRegister, + updateNativeWalletBalanceMetrics, updateTokenBalanceMetrics, updateXERC20LimitsMetrics, } from './metrics.js'; -import { WarpRouteBalance, XERC20Limit } from './types.js'; +import { NativeWalletBalance, WarpRouteBalance, XERC20Limit } from './types.js'; import { logger, tryFn } from './utils.js'; async function main() { - const { checkFrequency, environment, warpRouteId } = - await withWarpRouteIdRequired(getArgs()) - .describe('checkFrequency', 'frequency to check balances in ms') - .demandOption('checkFrequency') - .alias('v', 'checkFrequency') // v as in Greek letter nu - .number('checkFrequency') - .parse(); + const { + checkFrequency, + environment, + warpRouteId: warpRouteIdArg, + } = await withWarpRouteId(getArgs()) + .describe('checkFrequency', 'frequency to check balances in ms') + .demandOption('checkFrequency') + .alias('v', 'checkFrequency') // v as in Greek letter nu + .number('checkFrequency') + .parse(); + + const warpRouteId = warpRouteIdArg || (await getWarpRouteIdInteractive()); startMetricsServer(metricsRegister); @@ -110,6 +122,19 @@ async function updateTokenMetrics( }, 'Getting bridged balance and value'), ]; + // For Sealevel collateral and synthetic tokens, there is an + // "Associated Token Account" (ATA) rent payer that has a balance + // that's used to pay for rent for the accounts that store user balances. + // This is necessary if the recipient has never received any tokens before. + if (token.protocol === ProtocolType.Sealevel && !token.isNative()) { + promises.push( + tryFn(async () => { + const balance = await getSealevelAtaPayerBalance(warpCore, token); + updateNativeWalletBalanceMetrics(balance); + }, 'Getting ATA payer balance'), + ); + } + if (token.isXerc20()) { promises.push( tryFn(async () => { @@ -156,6 +181,44 @@ async function getTokenBridgedBalance( }; } +// Gets the native balance of the ATA payer, which is used to pay for +// rent when delivering tokens to an account that previously didn't +// have a balance. +// Only intended for Collateral or Synthetic Sealevel tokens. +async function getSealevelAtaPayerBalance( + warpCore: WarpCore, + token: Token, +): Promise { + if (token.protocol !== ProtocolType.Sealevel || token.isNative()) { + throw new Error( + `Unsupported ATA payer protocol type ${token.protocol} or standard ${token.standard}`, + ); + } + const adapter = token.getHypAdapter( + warpCore.multiProvider, + ) as SealevelHypTokenAdapter; + + const ataPayer = adapter.deriveAtaPayerAccount().toString(); + const nativeToken = Token.FromChainMetadataNativeToken( + warpCore.multiProvider.getChainMetadata(token.chainName), + ); + const ataPayerBalance = await nativeToken.getBalance( + warpCore.multiProvider, + ataPayer, + ); + + const warpRouteId = createWarpRouteConfigId( + token.symbol, + warpCore.getTokenChains(), + ); + return { + chain: token.chainName, + walletAddress: ataPayer.toString(), + walletName: `${warpRouteId}/ata-payer`, + balance: ataPayerBalance.getDecimalFormattedAmount(), + }; +} + async function getXERC20Limits( warpCore: WarpCore, token: Token, diff --git a/typescript/infra/scripts/warp-routes/monitor/types.ts b/typescript/infra/scripts/warp-routes/monitor/types.ts index 5a2d877492..976224d1c0 100644 --- a/typescript/infra/scripts/warp-routes/monitor/types.ts +++ b/typescript/infra/scripts/warp-routes/monitor/types.ts @@ -1,3 +1,6 @@ +import { ChainName } from '@hyperlane-xyz/sdk'; +import { Address } from '@hyperlane-xyz/utils'; + export interface XERC20Limit { mint: number; burn: number; @@ -9,3 +12,10 @@ export interface WarpRouteBalance { balance: number; valueUSD?: number; } + +export interface NativeWalletBalance { + chain: ChainName; + walletAddress: Address; + walletName: string; + balance: number; +} diff --git a/typescript/infra/src/agents/index.ts b/typescript/infra/src/agents/index.ts index b505bea1ae..b7be0e0098 100644 --- a/typescript/infra/src/agents/index.ts +++ b/typescript/infra/src/agents/index.ts @@ -2,7 +2,7 @@ import fs from 'fs'; import { join } from 'path'; import { ChainName, RelayerConfig, RpcConsensusType } from '@hyperlane-xyz/sdk'; -import { objFilter, objOmit, objOmitKeys, pick } from '@hyperlane-xyz/utils'; +import { objOmitKeys } from '@hyperlane-xyz/utils'; import { Contexts } from '../../config/contexts.js'; import { getChain } from '../../config/registry.js'; diff --git a/typescript/infra/src/config/chain.ts b/typescript/infra/src/config/chain.ts index a7bb7c9f95..49156cb125 100644 --- a/typescript/infra/src/config/chain.ts +++ b/typescript/infra/src/config/chain.ts @@ -24,6 +24,9 @@ export const chainsToSkip: ChainName[] = [ // mainnets 'zksync', 'zeronetwork', + 'zklink', + 'treasure', + // testnets 'abstracttestnet', 'treasuretopaz', diff --git a/typescript/infra/src/config/environment.ts b/typescript/infra/src/config/environment.ts index 25b17abff7..90761e1adc 100644 --- a/typescript/infra/src/config/environment.ts +++ b/typescript/infra/src/config/environment.ts @@ -104,3 +104,13 @@ export async function getRouterConfigsForAllVms( // Merge, giving evmRouterConfig precedence return objMerge(allRouterConfigs, evmRouterConfig); } + +export function getOwnerConfigForAddress(owner: string): OwnableConfig { + return { + owner, + // To ensure that any other overrides aren't applied + ownerOverrides: { + proxyAdmin: owner, + }, + }; +} diff --git a/typescript/infra/src/config/warp.ts b/typescript/infra/src/config/warp.ts index 99f0ee4a32..2ee4314cbe 100644 --- a/typescript/infra/src/config/warp.ts +++ b/typescript/infra/src/config/warp.ts @@ -1,20 +1,57 @@ -import { ChainMap } from '@hyperlane-xyz/sdk'; +import { ChainMap, OwnableConfig, RouterConfig } from '@hyperlane-xyz/sdk'; import { Address } from '@hyperlane-xyz/utils'; // Common collateral tokens to be used by warp route deployments. export const tokens: ChainMap> = { ethereum: { + amphrETH: '0x5fD13359Ba15A84B76f7F87568309040176167cd', + apxETH: '0x9ba021b0a9b958b5e75ce9f6dff97c7ee52cb3e6', + cbBTC: '0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf', + deUSD: '0x15700B564Ca08D9439C58cA5053166E8317aa138', USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', USDT: '0xdac17f958d2ee523a2206206994597c13d831ec7', - deUSD: '0x15700B564Ca08D9439C58cA5053166E8317aa138', - amphrETH: '0x5fD13359Ba15A84B76f7F87568309040176167cd', WBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', weETHs: '0x917cee801a67f933f2e6b33fc0cd1ed2d5909d88', }, sei: { fastUSD: '0x37a4dD9CED2b19Cfe8FAC251cd727b5787E45269', }, - blast: { - usdb: '0x4300000000000000000000000000000000000003', + base: { + cbBTC: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', + USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + }, + arbitrum: { + USDT: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + USDC: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + }, + bsc: { + USDT: '0x55d398326f99059fF775485246999027B3197955', + WETH: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + }, + mantle: { + USDT: '0x201EBa5CC46D216Ce6DC03F6a759e8E766e956aE', + WETH: '0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111', + }, + mode: { + USDT: '0xf0F161fDA2712DB8b566946122a5af183995e2eD', + }, + polygon: { + USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', + USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', + WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', + }, + scroll: { + USDT: '0xf55BEC9cafDbE8730f096Aa55dad6D22d44099Df', + }, + optimism: { + USDC: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', + }, + gnosis: { + WETH: '0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1', + }, + zeronetwork: { + USDC: '0x6a6394F47DD0BAF794808F2749C09bd4Ee874E70', }, }; + +export type RouterConfigWithoutOwner = Omit; diff --git a/typescript/infra/src/tx/govern-transaction-reader.ts b/typescript/infra/src/tx/govern-transaction-reader.ts new file mode 100644 index 0000000000..fadde0f87e --- /dev/null +++ b/typescript/infra/src/tx/govern-transaction-reader.ts @@ -0,0 +1,676 @@ +import { Result } from '@ethersproject/abi'; +import { decodeMultiSendData } from '@safe-global/protocol-kit/dist/src/utils/index.js'; +import { + MetaTransactionData, + OperationType, +} from '@safe-global/safe-core-sdk-types'; +import assert from 'assert'; +import chalk from 'chalk'; +import { BigNumber, ethers } from 'ethers'; + +import { TokenRouter__factory } from '@hyperlane-xyz/core'; +import { + AnnotatedEV5Transaction, + ChainMap, + ChainName, + CoreConfig, + DerivedIsmConfig, + EvmIsmReader, + InterchainAccount, + MultiProvider, + WarpCoreConfig, + coreFactories, + interchainAccountFactories, + normalizeConfig, +} from '@hyperlane-xyz/sdk'; +import { + addressToBytes32, + bytes32ToAddress, + deepEquals, + eqAddress, + rootLogger, +} from '@hyperlane-xyz/utils'; + +import { + icaOwnerChain, + icas, + safes, +} from '../../config/environments/mainnet3/owners.js'; +import { DeployEnvironment } from '../config/environment.js'; +import { getSafeAndService } from '../utils/safe.js'; + +interface GovernTransaction extends Record { + chain: ChainName; +} + +interface MultiSendTransaction { + index: number; + value: string; + operation: string; + decoded: GovernTransaction; +} + +interface MultiSendGovernTransactions extends GovernTransaction { + multisends: MultiSendTransaction[]; +} + +interface SetDefaultIsmInsight { + module: string; + insight: string; +} + +interface IcaRemoteCallInsight { + destination: { + domain: number; + chain: ChainName; + }; + router: { + address: string; + insight: string; + }; + ism: { + address: string; + insight: string; + }; + destinationIca: { + address: string; + insight: string; + }; + calls: GovernTransaction[]; +} + +export class GovernTransactionReader { + errors: any[] = []; + + protected readonly logger = rootLogger.child({ + module: 'GovernTransactionReader', + }); + + readonly warpRouteIndex: ChainMap< + Record + > = {}; + + constructor( + readonly environment: DeployEnvironment, + readonly multiProvider: MultiProvider, + readonly chainAddresses: ChainMap>, + readonly coreConfig: ChainMap, + warpRoutes: Record, + ) { + // Populate maps with warp route addresses and additional token details + for (const warpRoute of Object.values(warpRoutes)) { + for (const token of Object.values(warpRoute.tokens)) { + const address = token.addressOrDenom?.toLowerCase() ?? ''; + if (!this.warpRouteIndex[token.chainName]) { + this.warpRouteIndex[token.chainName] = {}; + } + this.warpRouteIndex[token.chainName][address] = token; + } + } + } + + async read( + chain: ChainName, + tx: AnnotatedEV5Transaction, + ): Promise { + // If it's to an ICA + if (this.isIcaTransaction(chain, tx)) { + return this.readIcaTransaction(chain, tx); + } + + // If it's to a Mailbox + if (this.isMailboxTransaction(chain, tx)) { + return this.readMailboxTransaction(chain, tx); + } + + // If it's a Multisend + if (await this.isMultisendTransaction(chain, tx)) { + return this.readMultisendTransaction(chain, tx); + } + + // If it's a Warp Module transaction + if (this.isWarpModuleTransaction(chain, tx)) { + return this.readWarpModuleTransaction(chain, tx); + } + + const insight = '⚠️ Unknown transaction type'; + // If we get here, it's an unknown transaction + this.errors.push({ + chain: chain, + tx, + info: insight, + }); + + return { + chain, + insight, + tx, + }; + } + + private isWarpModuleTransaction( + chain: ChainName, + tx: AnnotatedEV5Transaction, + ): boolean { + return ( + tx.to !== undefined && + this.warpRouteIndex[chain][tx.to.toLowerCase()] !== undefined + ); + } + + private async readWarpModuleTransaction( + chain: ChainName, + tx: AnnotatedEV5Transaction, + ): Promise { + if (!tx.data) { + throw new Error('No data in Warp Module transaction'); + } + + const { symbol } = await this.multiProvider.getNativeToken(chain); + const tokenRouterInterface = TokenRouter__factory.createInterface(); + + const decoded = tokenRouterInterface.parseTransaction({ + data: tx.data, + value: tx.value, + }); + + const args = formatFunctionFragmentArgs( + decoded.args, + decoded.functionFragment, + ); + + let insight = ''; + + if ( + decoded.functionFragment.name === + tokenRouterInterface.functions['setHook(address)'].name + ) { + const [hookAddress] = decoded.args; + insight = `Set hook to ${hookAddress}`; + } + + if ( + decoded.functionFragment.name === + tokenRouterInterface.functions['setInterchainSecurityModule(address)'] + .name + ) { + const [ismAddress] = decoded.args; + insight = `Set ISM to ${ismAddress}`; + } + + if ( + decoded.functionFragment.name === + tokenRouterInterface.functions['setDestinationGas((uint32,uint256)[])'] + .name + ) { + const [gasConfigs] = decoded.args; + const insights = gasConfigs.map( + (config: { domain: number; gas: BigNumber }) => { + const chainName = this.multiProvider.getChainName(config.domain); + return `domain ${ + config.domain + } (${chainName}) to ${config.gas.toString()}`; + }, + ); + insight = `Set destination gas for ${insights.join(', ')}`; + } + + if ( + decoded.functionFragment.name === + tokenRouterInterface.functions['enrollRemoteRouters(uint32[],bytes32[])'] + .name + ) { + const [domains, routers] = decoded.args; + const insights = domains.map((domain: number, index: number) => { + const chainName = this.multiProvider.getChainName(domain); + return `domain ${domain} (${chainName}) to ${routers[index]}`; + }); + insight = `Enroll remote routers for ${insights.join(', ')}`; + } + + if ( + decoded.functionFragment.name === + tokenRouterInterface.functions['unenrollRemoteRouter(uint32)'].name + ) { + const [domain] = decoded.args; + const chainName = this.multiProvider.getChainName(domain); + insight = `Unenroll remote router for domain ${domain} (${chainName})`; + } + + if ( + decoded.functionFragment.name === + tokenRouterInterface.functions['unenrollRemoteRouters(uint32[])'].name + ) { + const [domains] = decoded.args; + const insights = domains.map((domain: number) => { + const chainName = this.multiProvider.getChainName(domain); + return `domain ${domain} (${chainName})`; + }); + insight = `Unenroll remote routers for ${insights.join(', ')}`; + } + + assert(tx.to, 'Warp Module transaction must have a to address'); + const token = this.warpRouteIndex[chain][tx.to.toLowerCase()]; + + return { + chain, + to: `${token.symbol} (${token.name}, ${token.standard})`, + insight, + value: `${ethers.utils.formatEther(decoded.value)} ${symbol}`, + signature: decoded.signature, + args, + }; + } + + private async readIcaTransaction( + chain: ChainName, + tx: AnnotatedEV5Transaction, + ): Promise { + if (!tx.data) { + throw new Error('No data in ICA transaction'); + } + const { symbol } = await this.multiProvider.getNativeToken(chain); + const icaInterface = + interchainAccountFactories.interchainAccountRouter.interface; + const decoded = icaInterface.parseTransaction({ + data: tx.data, + value: tx.value, + }); + + const args = formatFunctionFragmentArgs( + decoded.args, + decoded.functionFragment, + ); + let prettyArgs = args; + + if ( + decoded.functionFragment.name === + icaInterface.functions['enrollRemoteRouter(uint32,bytes32)'].name + ) { + prettyArgs = await this.formatRouterEnrollments( + chain, + 'interchainAccountRouter', + args, + ); + } else if ( + decoded.functionFragment.name === + icaInterface.functions[ + 'callRemoteWithOverrides(uint32,bytes32,bytes32,(bytes32,uint256,bytes)[])' + ].name + ) { + prettyArgs = await this.readIcaRemoteCall(chain, args); + } + + return { + to: `ICA Router (${chain} ${this.chainAddresses[chain].interchainAccountRouter})`, + value: `${ethers.utils.formatEther(decoded.value)} ${symbol}`, + signature: decoded.signature, + args: prettyArgs, + chain, + }; + } + + private async formatRouterEnrollments( + chain: ChainName, + routerName: string, + args: Record, + ): Promise { + const { _domains: domains, _addresses: addresses } = args; + return domains.map((domain: number, index: number) => { + const remoteChainName = this.multiProvider.getChainName(domain); + const expectedRouter = this.chainAddresses[remoteChainName][routerName]; + const routerToBeEnrolled = addresses[index]; + const matchesExpectedRouter = + eqAddress(expectedRouter, bytes32ToAddress(routerToBeEnrolled)) && + // Poor man's check that the 12 byte padding is all zeroes + addressToBytes32(bytes32ToAddress(routerToBeEnrolled)) === + routerToBeEnrolled; + + let insight = '✅ matches expected router from artifacts'; + if (!matchesExpectedRouter) { + insight = `❌ fatal mismatch, expected ${expectedRouter}`; + this.errors.push({ + chain: chain, + remoteDomain: domain, + remoteChain: remoteChainName, + router: routerToBeEnrolled, + expected: expectedRouter, + info: 'Incorrect router getting enrolled', + }); + } + + return { + domain: domain, + chainName: remoteChainName, + router: routerToBeEnrolled, + insight, + }; + }); + } + + private async readMailboxTransaction( + chain: ChainName, + tx: AnnotatedEV5Transaction, + ): Promise { + if (!tx.data) { + throw new Error('⚠️ No data in mailbox transaction'); + } + const mailboxInterface = coreFactories.mailbox.interface; + const decoded = mailboxInterface.parseTransaction({ + data: tx.data, + value: tx.value, + }); + + const args = formatFunctionFragmentArgs( + decoded.args, + decoded.functionFragment, + ); + let prettyArgs = args; + if ( + decoded.functionFragment.name === + mailboxInterface.functions['setDefaultIsm(address)'].name + ) { + prettyArgs = await this.formatMailboxSetDefaultIsm(chain, args); + } + + return { + chain, + to: `Mailbox (${chain} ${this.chainAddresses[chain].mailbox})`, + signature: decoded.signature, + args: prettyArgs, + }; + } + + private ismDerivationsInProgress: ChainMap = {}; + + private async deriveIsmConfig( + chain: string, + module: string, + ): Promise { + const reader = new EvmIsmReader(this.multiProvider, chain); + + // Start recording some info about the deriving + const startTime = Date.now(); + this.logger.info(chalk.italic.gray(`Deriving ISM config for ${chain}...`)); + this.ismDerivationsInProgress[chain] = true; + + const derivedConfig = await reader.deriveIsmConfig(module); + + // Deriving is done, remove from in progress + delete this.ismDerivationsInProgress[chain]; + this.logger.info( + chalk.italic.blue( + 'Finished deriving ISM config', + chain, + 'in', + (Date.now() - startTime) / (1000 * 60), + 'mins', + ), + ); + const remainingInProgress = Object.keys(this.ismDerivationsInProgress); + this.logger.info( + chalk.italic.gray( + 'Remaining derivations in progress:', + remainingInProgress.length, + 'chains', + remainingInProgress, + ), + ); + + return derivedConfig; + } + + private async formatMailboxSetDefaultIsm( + chain: ChainName, + args: Record, + ): Promise { + const { _module: module } = args; + + const derivedConfig = await this.deriveIsmConfig(chain, module); + const expectedIsmConfig = this.coreConfig[chain].defaultIsm; + + let insight = '✅ matches expected ISM config'; + const normalizedDerived = normalizeConfig(derivedConfig); + const normalizedExpected = normalizeConfig(expectedIsmConfig); + if (!deepEquals(normalizedDerived, normalizedExpected)) { + this.errors.push({ + chain: chain, + module, + derivedConfig, + expectedIsmConfig, + info: 'Incorrect default ISM being set', + }); + insight = `❌ fatal mismatch of ISM config`; + this.logger.error( + chalk.bold.red(`Mismatch of ISM config for chain ${chain}!`), + ); + } + + return { + module, + insight, + }; + } + + private async readIcaRemoteCall( + chain: ChainName, + args: Record, + ): Promise { + const { + _destination: destination, + _router: router, + _ism: ism, + _calls: calls, + } = args; + const remoteChainName = this.multiProvider.getChainName(destination); + + const expectedRouter = + this.chainAddresses[remoteChainName].interchainAccountRouter; + const matchesExpectedRouter = + eqAddress(expectedRouter, bytes32ToAddress(router)) && + // Poor man's check that the 12 byte padding is all zeroes + addressToBytes32(bytes32ToAddress(router)) === router; + let routerInsight = '✅ matches expected router from artifacts'; + if (!matchesExpectedRouter) { + this.errors.push({ + chain: chain, + remoteDomain: destination, + remoteChain: remoteChainName, + router: router, + expected: expectedRouter, + info: 'Incorrect router in ICA call', + }); + routerInsight = `❌ fatal mismatch, expected ${expectedRouter}`; + } + + let ismInsight = '✅ matches expected ISM'; + if (ism !== ethers.constants.HashZero) { + this.errors.push({ + chain: chain, + remoteDomain: destination, + remoteChain: remoteChainName, + ism, + info: 'Incorrect ISM in ICA call, expected zero hash', + }); + ismInsight = `❌ fatal mismatch, expected zero hash`; + } + + const remoteIcaAddress = await InterchainAccount.fromAddressesMap( + this.chainAddresses, + this.multiProvider, + ).getAccount(remoteChainName, { + owner: safes[icaOwnerChain], + origin: icaOwnerChain, + routerOverride: router, + ismOverride: ism, + }); + const expectedRemoteIcaAddress = icas[remoteChainName as keyof typeof icas]; + let remoteIcaInsight = '✅ matches expected ICA'; + if ( + !expectedRemoteIcaAddress || + !eqAddress(remoteIcaAddress, expectedRemoteIcaAddress) + ) { + this.errors.push({ + chain: chain, + remoteDomain: destination, + remoteChain: remoteChainName, + ica: remoteIcaAddress, + expected: expectedRemoteIcaAddress, + info: 'Incorrect destination ICA in ICA call', + }); + remoteIcaInsight = `❌ fatal mismatch, expected ${remoteIcaAddress}`; + } + + const decodedCalls = await Promise.all( + calls.map((call: any) => { + const icaCallAsTx = { + to: bytes32ToAddress(call[0]), + value: BigNumber.from(call[1]), + data: call[2], + }; + return this.read(remoteChainName, icaCallAsTx); + }), + ); + + return { + destination: { + domain: destination, + chain: remoteChainName, + }, + router: { + address: router, + insight: routerInsight, + }, + ism: { + address: ism, + insight: ismInsight, + }, + destinationIca: { + address: remoteIcaAddress, + insight: remoteIcaInsight, + }, + calls: decodedCalls, + }; + } + + private async readMultisendTransaction( + chain: ChainName, + tx: AnnotatedEV5Transaction, + ): Promise { + if (!tx.data) { + throw new Error('No data in multisend transaction'); + } + const multisendDatas = decodeMultiSendData(tx.data); + + const { symbol } = await this.multiProvider.getNativeToken(chain); + + const multisends = await Promise.all( + multisendDatas.map(async (multisend, index) => { + const decoded = await this.read( + chain, + metaTransactionDataToEV5Transaction(multisend), + ); + return { + chain, + index, + value: `${ethers.utils.formatEther(multisend.value)} ${symbol}`, + operation: formatOperationType(multisend.operation), + decoded, + }; + }), + ); + + return { + chain, + multisends, + }; + } + + isIcaTransaction(chain: ChainName, tx: AnnotatedEV5Transaction): boolean { + return ( + tx.to !== undefined && + eqAddress(tx.to, this.chainAddresses[chain].interchainAccountRouter) + ); + } + + isMailboxTransaction(chain: ChainName, tx: AnnotatedEV5Transaction): boolean { + return ( + tx.to !== undefined && + eqAddress(tx.to, this.chainAddresses[chain].mailbox) + ); + } + + async isMultisendTransaction( + chain: ChainName, + tx: AnnotatedEV5Transaction, + ): Promise { + if (tx.to === undefined) { + return false; + } + const multiSendCallOnlyAddress = await this.getMultiSendCallOnlyAddress( + chain, + ); + if (!multiSendCallOnlyAddress) { + return false; + } + + return eqAddress(multiSendCallOnlyAddress, tx.to); + } + + private multiSendCallOnlyAddressCache: ChainMap = {}; + + async getMultiSendCallOnlyAddress( + chain: ChainName, + ): Promise { + if (this.multiSendCallOnlyAddressCache[chain]) { + return this.multiSendCallOnlyAddressCache[chain]; + } + + const safe = safes[chain]; + if (!safe) { + return undefined; + } + + const { safeSdk } = await getSafeAndService( + chain, + this.multiProvider, + safe, + ); + + this.multiSendCallOnlyAddressCache[chain] = + safeSdk.getMultiSendCallOnlyAddress(); + return this.multiSendCallOnlyAddressCache[chain]; + } +} + +function metaTransactionDataToEV5Transaction( + metaTransactionData: MetaTransactionData, +): AnnotatedEV5Transaction { + return { + to: metaTransactionData.to, + value: BigNumber.from(metaTransactionData.value), + data: metaTransactionData.data, + }; +} + +function formatFunctionFragmentArgs( + args: Result, + fragment: ethers.utils.FunctionFragment, +): Record { + const accumulator: Record = {}; + return fragment.inputs.reduce((acc, input, index) => { + acc[input.name] = args[index]; + return acc; + }, accumulator); +} + +function formatOperationType(operation: OperationType | undefined): string { + switch (operation) { + case OperationType.Call: + return 'Call'; + case OperationType.DelegateCall: + return 'Delegate Call'; + default: + return '⚠️ Unknown ⚠️'; + } +} diff --git a/typescript/infra/src/utils/metrics.ts b/typescript/infra/src/utils/metrics.ts index ace2fbf1b6..a9f274caa2 100644 --- a/typescript/infra/src/utils/metrics.ts +++ b/typescript/infra/src/utils/metrics.ts @@ -1,5 +1,5 @@ import http from 'http'; -import { Pushgateway, Registry } from 'prom-client'; +import { Gauge, Pushgateway, Registry } from 'prom-client'; import { format } from 'util'; import { rootLogger } from '@hyperlane-xyz/utils'; @@ -66,3 +66,24 @@ export function startMetricsServer(register: Registry): http.Server { }) .listen(parseInt(process.env['PROMETHEUS_PORT'] || '9090')); } + +export function getWalletBalanceGauge( + register: Registry, + additionalLabels: string[] = [], +) { + return new Gauge({ + // Mirror the rust/main/ethers-prometheus `wallet_balance` gauge metric. + name: 'hyperlane_wallet_balance', + help: 'Current balance of a wallet for a token', + registers: [register], + labelNames: [ + 'chain', + 'wallet_address', + 'wallet_name', + 'token_address', + 'token_symbol', + 'token_name', + ...additionalLabels, + ], + }); +} diff --git a/typescript/infra/src/utils/safe.ts b/typescript/infra/src/utils/safe.ts index 397e746c07..95e27c50e3 100644 --- a/typescript/infra/src/utils/safe.ts +++ b/typescript/infra/src/utils/safe.ts @@ -14,7 +14,7 @@ import { getSafe, getSafeService, } from '@hyperlane-xyz/sdk'; -import { Address, CallData, eqAddress } from '@hyperlane-xyz/utils'; +import { Address, CallData, eqAddress, retryAsync } from '@hyperlane-xyz/utils'; import safeSigners from '../../config/environments/mainnet3/safe/safeSigners.json' assert { type: 'json' }; import { AnnotatedCallData } from '../govern/HyperlaneAppGovernor.js'; @@ -24,10 +24,10 @@ export async function getSafeAndService( multiProvider: MultiProvider, safeAddress: Address, ) { - const safeSdk: Safe.default = await getSafe( - chain, - multiProvider, - safeAddress, + const safeSdk: Safe.default = await retryAsync( + () => getSafe(chain, multiProvider, safeAddress), + 5, + 1000, ); const safeService: SafeApiKit.default = getSafeService(chain, multiProvider); return { safeSdk, safeService }; @@ -41,6 +41,52 @@ export function createSafeTransactionData(call: CallData): MetaTransactionData { }; } +export async function executeTx( + chain: ChainNameOrId, + multiProvider: MultiProvider, + safeAddress: Address, + safeTxHash: string, +): Promise { + const { safeSdk, safeService } = await getSafeAndService( + chain, + multiProvider, + safeAddress, + ); + const safeTransaction = await safeService.getTransaction(safeTxHash); + if (!safeTransaction) { + throw new Error(`Failed to fetch transaction details for ${safeTxHash}`); + } + + // Throw if the safe doesn't have enough balance to cover the gas + let estimate; + try { + estimate = await safeService.estimateSafeTransaction( + safeAddress, + safeTransaction, + ); + } catch (error) { + throw new Error( + `Failed to estimate gas for Safe transaction ${safeTxHash} on chain ${chain}: ${error}`, + ); + } + const balance = await multiProvider + .getProvider(chain) + .getBalance(safeAddress); + if (balance.lt(estimate.safeTxGas)) { + throw new Error( + `Safe ${safeAddress} on ${chain} has insufficient balance (${balance.toString()}) for estimated gas (${ + estimate.safeTxGas + })`, + ); + } + + await safeSdk.executeTransaction(safeTransaction); + + console.log( + chalk.green.bold(`Executed transaction ${safeTxHash} on ${chain}`), + ); +} + export async function createSafeTransaction( safeSdk: Safe.default, safeService: SafeApiKit.default, @@ -115,6 +161,31 @@ export async function deleteAllPendingSafeTxs( ); } +export async function getSafeTx( + chain: ChainNameOrId, + multiProvider: MultiProvider, + safeTxHash: string, +): Promise { + const txServiceUrl = + multiProvider.getChainMetadata(chain).gnosisSafeTransactionServiceUrl; + + // Fetch the transaction details to get the proposer + const txDetailsUrl = `${txServiceUrl}/api/v1/multisig-transactions/${safeTxHash}/`; + const txDetailsResponse = await fetch(txDetailsUrl, { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + }); + + if (!txDetailsResponse.ok) { + console.error( + chalk.red(`Failed to fetch transaction details for ${safeTxHash}`), + ); + return; + } + + return txDetailsResponse.json(); +} + export async function deleteSafeTx( chain: ChainNameOrId, multiProvider: MultiProvider, diff --git a/typescript/infra/src/warp/helm.ts b/typescript/infra/src/warp/helm.ts index 2b0123c3bb..ce6c901203 100644 --- a/typescript/infra/src/warp/helm.ts +++ b/typescript/infra/src/warp/helm.ts @@ -22,7 +22,7 @@ export class WarpRouteMonitorHelmManager extends HelmManager { return { image: { repository: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', - tag: '7544b99-20241119-162215', + tag: 'aac6787-20241128-103715', }, warpRouteId: this.warpRouteId, fullnameOverride: this.helmReleaseName, diff --git a/typescript/infra/test/warpIds.test.ts b/typescript/infra/test/warpIds.test.ts index ba171c5bab..11f8a2dd15 100644 --- a/typescript/infra/test/warpIds.test.ts +++ b/typescript/infra/test/warpIds.test.ts @@ -8,8 +8,10 @@ describe('Warp IDs', () => { const registry = getRegistry(); for (const warpId of Object.values(WarpRouteIds)) { // That's a long sentence! - expect(registry.getWarpRoute(warpId), `Warp ID ${warpId} not in registry`) - .to.not.be.null.and.not.be.undefined; + expect( + registry.getWarpRoute(warpId), + `Warp ID ${warpId} not in registry, the .registryrc or your local registry may be out of date`, + ).to.not.be.null.and.not.be.undefined; } }); }); diff --git a/typescript/sdk/.eslintrc b/typescript/sdk/.eslintrc deleted file mode 100644 index a0a6842678..0000000000 --- a/typescript/sdk/.eslintrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "rules": { - "@typescript-eslint/explicit-module-boundary-types": ["warn", { - "allowArgumentsExplicitlyTypedAsAny": true - }] - } -} diff --git a/typescript/sdk/CHANGELOG.md b/typescript/sdk/CHANGELOG.md index 2395e197fe..97f1f2a252 100644 --- a/typescript/sdk/CHANGELOG.md +++ b/typescript/sdk/CHANGELOG.md @@ -1,5 +1,42 @@ # @hyperlane-xyz/sdk +## 7.3.0 + +### Minor Changes + +- 2054f4f5b: Require Sealevel native transfers to cover the rent of the recipient +- a96448fa6: Add logic into SDK to enable warp route unenrollment +- 170a0fc73: Add `createHookUpdateTxs()` to `WarpModule.update()` such that it 1) deploys a hook for a warp route _without_ an existing hook, or 2) update an existing hook. +- 9a09afcc7: Deploy to appchain, treasure, zklink. +- 24784af95: Introduce GcpValidator for retrieving announcements, checkpoints and metadata for a Validator posting to a GCP bucket. Uses GcpStorageWrapper for bucket operations. +- 3e8dd70ac: Update validators for boba, duckchain, unichain, vana, bsquared, superseed. Update oort's own validator. Update blockpi's viction validator. Adad luganodes/dsrv to flame validator set. +- aa1ea9a48: updates the warp deployment config schema to be closer to the ica routing schema +- f0b98fdef: Updated the derivation logic to enable ICA ISM metadata building from on chain data to enable self relaying of ICA messages +- ff9e8a72b: Added a getter to derive ATA payer accounts on Sealevel warp routes +- 97c1f80b7: Implement Sealevel IGP quoting +- 323f0f158: Add ICAs management in core apply command +- 61157097b: Deploy to swell & lumiaprism. Parallelise router enrollment in HyperlaneRouterDeployer. + +### Patch Changes + +- 665a7b8d8: Added decimal consistency checks to the Token checker + - @hyperlane-xyz/utils@7.3.0 + - @hyperlane-xyz/core@5.8.3 + +## 7.2.0 + +### Minor Changes + +- 81ab4332f: Remove ismFactoryAddresses from warpConfig +- 4b3537470: Changed the type of defaultMultisigConfigs, to track validator aliases in addition to their addresses. +- fa6d5f5c6: Add decodeIsmMetadata function + +### Patch Changes + +- Updated dependencies [fa6d5f5c6] + - @hyperlane-xyz/utils@7.2.0 + - @hyperlane-xyz/core@5.8.2 + ## 7.1.0 ### Minor Changes diff --git a/typescript/sdk/eslint.config.mjs b/typescript/sdk/eslint.config.mjs new file mode 100644 index 0000000000..2855488799 --- /dev/null +++ b/typescript/sdk/eslint.config.mjs @@ -0,0 +1,25 @@ +import MonorepoDefaults from '../../eslint.config.mjs'; + +export default [ + ...MonorepoDefaults, + { + files: ['./src/**/*.ts'], + rules: { + '@typescript-eslint/explicit-module-boundary-types': [ + 'warn', + { + allowArgumentsExplicitlyTypedAsAny: true, + }, + ], + }, + }, + { + ignores: ['./src/ism/metadata/**/*.ts'], + rules: { + 'import/no-cycle': ['off'], + }, + }, + { + ignores: ['src/**/*.js'], + }, +]; diff --git a/typescript/sdk/package.json b/typescript/sdk/package.json index 9f4fd06159..47bb713b13 100644 --- a/typescript/sdk/package.json +++ b/typescript/sdk/package.json @@ -1,15 +1,16 @@ { "name": "@hyperlane-xyz/sdk", "description": "The official SDK for the Hyperlane Network", - "version": "7.1.0", + "version": "7.3.0", "dependencies": { "@arbitrum/sdk": "^4.0.0", - "@aws-sdk/client-s3": "^3.74.0", + "@aws-sdk/client-s3": "^3.577.0", "@chain-registry/types": "^0.50.14", "@cosmjs/cosmwasm-stargate": "^0.32.4", "@cosmjs/stargate": "^0.32.4", - "@hyperlane-xyz/core": "5.8.1", - "@hyperlane-xyz/utils": "7.1.0", + "@google-cloud/storage": "7.14.0", + "@hyperlane-xyz/core": "5.8.3", + "@hyperlane-xyz/utils": "7.3.0", "@safe-global/api-kit": "1.3.0", "@safe-global/protocol-kit": "1.3.0", "@safe-global/safe-deployments": "1.37.8", @@ -24,23 +25,29 @@ "zod": "^3.21.2" }, "devDependencies": { + "@eslint/js": "^9.15.0", "@nomiclabs/hardhat-ethers": "^2.2.3", "@nomiclabs/hardhat-waffle": "^2.0.6", "@types/mocha": "^10.0.1", - "@types/node": "^16.9.1", + "@types/node": "^18.14.5", "@types/sinon": "^17.0.1", "@types/sinon-chai": "^3.2.12", "@types/ws": "^8.5.5", - "chai": "4.5.0", + "@typescript-eslint/eslint-plugin": "^8.1.6", + "@typescript-eslint/parser": "^8.1.6", + "chai": "^4.5.0", "dotenv": "^10.0.0", - "eslint": "^8.57.0", + "eslint": "^9.15.0", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import": "^2.31.0", "ethereum-waffle": "^4.0.10", "hardhat": "^2.22.2", "mocha": "^10.2.0", "prettier": "^2.8.8", "sinon": "^13.0.2", "ts-node": "^10.8.0", - "tsx": "^4.7.1", + "tsx": "^4.19.1", "typescript": "5.3.3", "yaml": "2.4.5" }, @@ -70,7 +77,7 @@ "dev": "tsc --watch", "check": "tsc --noEmit", "clean": "rm -rf ./dist ./cache", - "lint": "eslint src --ext .ts", + "lint": "eslint -c ./eslint.config.mjs", "prepublishOnly": "yarn build", "prettier": "prettier --write ./src", "test": "yarn test:unit && yarn test:hardhat && yarn test:foundry", diff --git a/typescript/sdk/src/aws/validator.ts b/typescript/sdk/src/aws/validator.ts index 32ae9613c1..008584c3e5 100644 --- a/typescript/sdk/src/aws/validator.ts +++ b/typescript/sdk/src/aws/validator.ts @@ -4,6 +4,7 @@ import { S3Announcement, S3CheckpointWithId, ValidatorConfig, + ValidatorMetadata, isS3CheckpointWithId, } from '@hyperlane-xyz/utils'; @@ -13,7 +14,8 @@ const checkpointWithMessageIdKey = (checkpointIndex: number) => `checkpoint_${checkpointIndex}_with_id.json`; const LATEST_KEY = 'checkpoint_latest_index.json'; const ANNOUNCEMENT_KEY = 'announcement.json'; -const LOCATION_PREFIX = 's3://'; +const METADATA_KEY = 'metadata_latest.json'; +export const S3_LOCATION_PREFIX = 's3://'; /** * Extension of BaseValidator that includes AWS S3 utilities. @@ -32,8 +34,8 @@ export class S3Validator extends BaseValidator { static async fromStorageLocation( storageLocation: string, ): Promise { - if (storageLocation.startsWith(LOCATION_PREFIX)) { - const suffix = storageLocation.slice(LOCATION_PREFIX.length); + if (storageLocation.startsWith(S3_LOCATION_PREFIX)) { + const suffix = storageLocation.slice(S3_LOCATION_PREFIX.length); const pieces = suffix.split('/'); if (pieces.length >= 2) { const s3Config = { @@ -76,6 +78,15 @@ export class S3Validator extends BaseValidator { return resp.data; } + async getMetadata(): Promise { + const resp = await this.s3Bucket.getS3Obj(METADATA_KEY); + if (!resp) { + throw new Error(`No metadata found for ${this.config.localDomain}`); + } + + return resp.data; + } + async getCheckpoint(index: number): Promise { const key = checkpointWithMessageIdKey(index); const s3Object = await this.s3Bucket.getS3Obj(key); @@ -101,7 +112,7 @@ export class S3Validator extends BaseValidator { } storageLocation(): string { - return `${LOCATION_PREFIX}/${this.s3Bucket.config.bucket}/${this.s3Bucket.config.region}`; + return `${S3_LOCATION_PREFIX}/${this.s3Bucket.config.bucket}/${this.s3Bucket.config.region}`; } getLatestCheckpointUrl(): string { diff --git a/typescript/sdk/src/consts/.eslintrc b/typescript/sdk/src/consts/.eslintrc deleted file mode 100644 index 7242f12412..0000000000 --- a/typescript/sdk/src/consts/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "sort-keys": ["error"] - } -} diff --git a/typescript/sdk/src/consts/multisigIsm.test.ts b/typescript/sdk/src/consts/multisigIsm.test.ts index 53f93dc161..aae80376c1 100644 --- a/typescript/sdk/src/consts/multisigIsm.test.ts +++ b/typescript/sdk/src/consts/multisigIsm.test.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { isAddress } from '@hyperlane-xyz/utils'; +import { isAddress, isZeroishAddress } from '@hyperlane-xyz/utils'; import { defaultMultisigConfigs } from './multisigIsm.js'; @@ -28,12 +28,31 @@ describe('MultisigIsm', () => { it('has valid EVM addresses for each validator', async () => { for (const [chain, config] of Object.entries(defaultMultisigConfigs)) { for (const validator of config.validators) { - expect(isAddress(validator)).to.equal( + expect(isAddress(validator.address)).to.equal( true, - `Validator address ${validator} for ${chain} is not a valid EVM address`, + `Validator address ${validator.address} for ${chain} is not a valid EVM address`, ); } } }); + + it('has no zeroish addresses for validators', async () => { + for (const [chain, config] of Object.entries(defaultMultisigConfigs)) { + for (const validator of config.validators) { + expect(isZeroishAddress(validator.address)).to.equal( + false, + `Validator address ${validator.address} for ${chain} is a zeroish address`, + ); + } + } + }); + + it('has valid aliases for each validator', async () => { + for (const config of Object.values(defaultMultisigConfigs)) { + for (const validator of config.validators) { + expect(validator.alias).to.not.be.empty; + } + } + }); }); }); diff --git a/typescript/sdk/src/consts/multisigIsm.ts b/typescript/sdk/src/consts/multisigIsm.ts index 5f80ff91ab..eaa675b327 100644 --- a/typescript/sdk/src/consts/multisigIsm.ts +++ b/typescript/sdk/src/consts/multisigIsm.ts @@ -1,1021 +1,1825 @@ -import { MultisigConfig } from '../ism/types.js'; +import { MultisigConfig, ValidatorConfig } from '../ism/types.js'; import { ChainMap } from '../types.js'; +export const AW_VALIDATOR_ALIAS = 'Abacus Works'; + +const DEFAULT_MERKLY_VALIDATOR: ValidatorConfig = { + address: '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', + alias: 'Merkly', +}; +const DEFAULT_MITOSIS_VALIDATOR: ValidatorConfig = { + address: '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', + alias: 'Mitosis', +}; +const DEFAULT_ZEE_PRIME_VALIDATOR: ValidatorConfig = { + address: '0x5450447aee7b544c462c9352bef7cad049b0c2dc', + alias: 'Zee Prime', +}; +const DEFAULT_EVERSTAKE_VALIDATOR: ValidatorConfig = { + address: '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', + alias: 'Everstake', +}; +const DEFAULT_STAKED_VALIDATOR: ValidatorConfig = { + address: '0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b', + alias: 'Staked', +}; +const DEFAULT_TESSELLATED_VALIDATOR: ValidatorConfig = { + address: '0x0d4c1394a255568ec0ecd11795b28d1bda183ca4', + alias: 'Tessellated', +}; +const DEFAULT_BWARE_LABS_VALIDATOR: ValidatorConfig = { + address: '0x14d0B24d3a8F3aAD17DB4b62cBcEC12821c98Cb3', + alias: 'Bware Labs', +}; + // TODO: consider migrating these to the registry too export const defaultMultisigConfigs: ChainMap = { abstracttestnet: { threshold: 1, - validators: ['0x7655bc4c9802bfcb3132b8822155b60a4fbbce3e'], + validators: [ + { + address: '0x7655bc4c9802bfcb3132b8822155b60a4fbbce3e', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, alephzeroevmmainnet: { threshold: 2, validators: [ - '0x33f20e6e775747d60301c6ea1c50e51f0389740c', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x33f20e6e775747d60301c6ea1c50e51f0389740c', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, alephzeroevmtestnet: { threshold: 1, - validators: ['0x556cd94bcb6e5773e8df75e7eb3f91909d266a26'], + validators: [ + { + address: '0x556cd94bcb6e5773e8df75e7eb3f91909d266a26', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, alfajores: { threshold: 2, validators: [ - '0x2233a5ce12f814bd64c9cdd73410bb8693124d40', - '0xba279f965489d90f90490e3c49e860e0b43c2ae6', - '0x86485dcec5f7bb8478dd251676372d054dea6653', + { + address: '0x2233a5ce12f814bd64c9cdd73410bb8693124d40', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0xba279f965489d90f90490e3c49e860e0b43c2ae6', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x86485dcec5f7bb8478dd251676372d054dea6653', + alias: AW_VALIDATOR_ALIAS, + }, ], }, ancient8: { threshold: 2, validators: [ - '0xbb5842ae0e05215b53df4787a29144efb7e67551', - '0xa5a56e97fb46f0ac3a3d261e404acb998d9a6969', // coin98 - '0x95c7bf235837cb5a609fe6c95870410b9f68bcff', // ancient8 + { + address: '0xbb5842ae0e05215b53df4787a29144efb7e67551', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0xa5a56e97fb46f0ac3a3d261e404acb998d9a6969', + alias: 'Coin98', + }, + { + address: '0x95c7bf235837cb5a609fe6c95870410b9f68bcff', + alias: 'Ancient8', + }, ], }, apechain: { threshold: 2, validators: [ - '0x773d7fe6ffb1ba4de814c28044ff9a2d83a48221', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x773d7fe6ffb1ba4de814c28044ff9a2d83a48221', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + ], + }, + + appchain: { + threshold: 1, + validators: [ + { + address: '0x0531251bbadc1f9f19ccce3ca6b3f79f08eae1be', + alias: AW_VALIDATOR_ALIAS, + }, ], }, arbitrum: { threshold: 3, validators: [ - '0x4d966438fe9e2b1e7124c87bbb90cb4f0f6c59a1', - '0xec68258a7c882ac2fc46b81ce80380054ffb4ef2', // dsrv - '0x5450447aee7b544c462c9352bef7cad049b0c2dc', // zeeprime - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b', // staked + { + address: '0x4d966438fe9e2b1e7124c87bbb90cb4f0f6c59a1', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0xec68258a7c882ac2fc46b81ce80380054ffb4ef2', alias: 'DSRV' }, + DEFAULT_ZEE_PRIME_VALIDATOR, + DEFAULT_EVERSTAKE_VALIDATOR, + DEFAULT_STAKED_VALIDATOR, ], }, arbitrumnova: { threshold: 2, validators: [ - '0xd2a5e9123308d187383c87053811a2c21bd8af1f', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xd2a5e9123308d187383c87053811a2c21bd8af1f', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, arbitrumsepolia: { threshold: 1, - validators: ['0x09fabfbca0b8bf042e2a1161ee5010d147b0f603'], + validators: [ + { + address: '0x09fabfbca0b8bf042e2a1161ee5010d147b0f603', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, arcadiatestnet2: { threshold: 1, - validators: ['0xd39cd388ce3f616bc81be6dd3ec9348d7cdf4dff'], + validators: [ + { + address: '0xd39cd388ce3f616bc81be6dd3ec9348d7cdf4dff', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, astar: { threshold: 2, validators: [ - '0x4d1b2cade01ee3493f44304653d8e352c66ec3e7', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x4d1b2cade01ee3493f44304653d8e352c66ec3e7', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, astarzkevm: { threshold: 2, validators: [ - '0x89ecdd6caf138934bf3a2fb7b323984d72fd66de', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x89ecdd6caf138934bf3a2fb7b323984d72fd66de', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, avalanche: { threshold: 2, validators: [ - '0x3fb8263859843bffb02950c492d492cae169f4cf', - '0x402e0f8c6e4210d408b6ac00d197d4a099fcd25a', // dsrv - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake + { + address: '0x3fb8263859843bffb02950c492d492cae169f4cf', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0x402e0f8c6e4210d408b6ac00d197d4a099fcd25a', alias: 'DSRV' }, + DEFAULT_EVERSTAKE_VALIDATOR, ], }, b3: { threshold: 2, validators: [ - '0xd77b516730a836fc41934e7d5864e72c165b934e', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xd77b516730a836fc41934e7d5864e72c165b934e', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, base: { threshold: 3, validators: [ - '0xb9453d675e0fa3c178a17b4ce1ad5b1a279b3af9', - '0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b', // staked - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0xcff391b4e516452d424db66beb9052b041a9ed79', // dsrv - '0x5450447aee7b544c462c9352bef7cad049b0c2dc', // zeeprime + { + address: '0xb9453d675e0fa3c178a17b4ce1ad5b1a279b3af9', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_STAKED_VALIDATOR, + DEFAULT_EVERSTAKE_VALIDATOR, + { address: '0xcff391b4e516452d424db66beb9052b041a9ed79', alias: 'DSRV' }, + DEFAULT_ZEE_PRIME_VALIDATOR, ], }, basesepolia: { threshold: 1, - validators: ['0x82e3b437a2944e3ff00258c93e72cd1ba5e0e921'], + validators: [ + { + address: '0x82e3b437a2944e3ff00258c93e72cd1ba5e0e921', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, berabartio: { threshold: 1, - validators: ['0x541dd3cb282cf869d72883557badae245b63e1fd'], + validators: [ + { + address: '0x541dd3cb282cf869d72883557badae245b63e1fd', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, bitlayer: { threshold: 2, validators: [ - '0x1d9b0f4ea80dbfc71cb7d64d8005eccf7c41e75f', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x1d9b0f4ea80dbfc71cb7d64d8005eccf7c41e75f', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, blast: { threshold: 2, validators: [ - '0xf20c0b09f597597c8d2430d3d72dfddaf09177d1', - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis - '0xae53467a5c2a9d9420c188d10fef5e1d9b9a5b80', // superform + { + address: '0xf20c0b09f597597c8d2430d3d72dfddaf09177d1', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MITOSIS_VALIDATOR, + { + address: '0xae53467a5c2a9d9420c188d10fef5e1d9b9a5b80', + alias: 'Superform', + }, ], }, bob: { threshold: 2, validators: [ - '0x20f283be1eb0e81e22f51705dcb79883cfdd34aa', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x20f283be1eb0e81e22f51705dcb79883cfdd34aa', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + ], + }, + + boba: { + threshold: 2, + validators: [ + { + address: '0xebeb92c94ca8408e73aa16fd554cb3a7df075c59', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, bsc: { threshold: 3, validators: [ - '0x570af9b7b36568c8877eebba6c6727aa9dab7268', - '0x8292b1a53907ece0f76af8a50724e9492bcdc8a3', // dsrv - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0x5450447aee7b544c462c9352bef7cad049b0c2dc', // zeeprime + { + address: '0x570af9b7b36568c8877eebba6c6727aa9dab7268', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0x8292b1a53907ece0f76af8a50724e9492bcdc8a3', alias: 'DSRV' }, + DEFAULT_EVERSTAKE_VALIDATOR, + DEFAULT_ZEE_PRIME_VALIDATOR, ], }, bsctestnet: { threshold: 2, validators: [ - '0x242d8a855a8c932dec51f7999ae7d1e48b10c95e', - '0xf620f5e3d25a3ae848fec74bccae5de3edcd8796', - '0x1f030345963c54ff8229720dd3a711c15c554aeb', + { + address: '0x242d8a855a8c932dec51f7999ae7d1e48b10c95e', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0xf620f5e3d25a3ae848fec74bccae5de3edcd8796', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x1f030345963c54ff8229720dd3a711c15c554aeb', + alias: AW_VALIDATOR_ALIAS, + }, + ], + }, + + bsquared: { + threshold: 2, + validators: [ + { + address: '0xcadc90933c9fbe843358a4e70e46ad2db78e28aa', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, camptestnet: { threshold: 1, - validators: ['0x238f40f055a7ff697ea6dbff3ae943c9eae7a38e'], + validators: [ + { + address: '0x238f40f055a7ff697ea6dbff3ae943c9eae7a38e', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, celo: { threshold: 3, validators: [ - '0x63478422679303c3e4fc611b771fa4a707ef7f4a', - '0x622e43baf06ad808ca8399360d9a2d9a1a12688b', // dsrv - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b', // staked - '0x5450447aee7b544c462c9352bef7cad049b0c2dc', // zeeprime + { + address: '0x63478422679303c3e4fc611b771fa4a707ef7f4a', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0x622e43baf06ad808ca8399360d9a2d9a1a12688b', alias: 'DSRV' }, + DEFAULT_EVERSTAKE_VALIDATOR, + DEFAULT_STAKED_VALIDATOR, + DEFAULT_ZEE_PRIME_VALIDATOR, ], }, cheesechain: { threshold: 2, validators: [ - '0x478fb53c6860ae8fc35235ba0d38d49b13128226', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x101cE77261245140A0871f9407d6233C8230Ec47', // blockhunters + { + address: '0x478fb53c6860ae8fc35235ba0d38d49b13128226', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + { + address: '0x101cE77261245140A0871f9407d6233C8230Ec47', + alias: 'Blockhunters', + }, ], }, chiado: { threshold: 2, validators: [ - '0x06c3757a4b7a912828e523bb8a5f980ddc297356', - '0x0874967a145d70b799ebe9ed861ab7c93faef95a', - '0xd767ea1206b8295d7e1267ddd00e56d34f278db6', + { + address: '0x06c3757a4b7a912828e523bb8a5f980ddc297356', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x0874967a145d70b799ebe9ed861ab7c93faef95a', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0xd767ea1206b8295d7e1267ddd00e56d34f278db6', + alias: AW_VALIDATOR_ALIAS, + }, ], }, chilizmainnet: { threshold: 2, validators: [ - '0x7403e5d58b48b0f5f715d9c78fbc581f01a625cb', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x7403e5d58b48b0f5f715d9c78fbc581f01a625cb', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, citreatestnet: { threshold: 1, - validators: ['0x60d7380a41eb95c49be18f141efd2fde5e3dba20'], + validators: [ + { + address: '0x60d7380a41eb95c49be18f141efd2fde5e3dba20', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, connextsepolia: { threshold: 1, - validators: ['0xffbbec8c499585d80ef69eb613db624d27e089ab'], + validators: [ + { + address: '0xffbbec8c499585d80ef69eb613db624d27e089ab', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, coredao: { threshold: 2, validators: [ - '0xbd6e158a3f5830d99d7d2bce192695bc4a148de2', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xbd6e158a3f5830d99d7d2bce192695bc4a148de2', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, cyber: { threshold: 2, validators: [ - '0x94d7119ceeb802173b6924e6cc8c4cd731089a27', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x94d7119ceeb802173b6924e6cc8c4cd731089a27', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, degenchain: { threshold: 2, validators: [ - '0x433e311f19524cd64fb2123ad0aa1579a4e1fc83', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x433e311f19524cd64fb2123ad0aa1579a4e1fc83', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, dogechain: { threshold: 2, validators: [ - '0xe43f742c37858746e6d7e458bc591180d0cba440', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xe43f742c37858746e6d7e458bc591180d0cba440', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + ], + }, + + duckchain: { + threshold: 2, + validators: [ + { + address: '0x91d55fe6dac596a6735d96365e21ce4bca21d83c', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, eclipsemainnet: { threshold: 3, validators: [ - '0xebb52d7eaa3ff7a5a6260bfe5111ce52d57401d0', - '0x3571223e745dc0fcbdefa164c9b826b90c0d2dac', // luganodes - '0xea83086a62617a7228ce4206fae2ea8b0ab23513', // imperator - '0x4d4629f5bfeabe66edc7a78da26ef5273c266f97', // eclipse + { + address: '0xebb52d7eaa3ff7a5a6260bfe5111ce52d57401d0', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x3571223e745dc0fcbdefa164c9b826b90c0d2dac', + alias: 'Luganodes', + }, + { + address: '0xea83086a62617a7228ce4206fae2ea8b0ab23513', + alias: 'Imperator', + }, + { + address: '0x4d4629f5bfeabe66edc7a78da26ef5273c266f97', + alias: 'Eclipse', + }, ], }, eclipsetestnet: { threshold: 1, - validators: ['0xf344f34abca9a444545b5295066348a0ae22dda3'], + validators: [ + { + address: '0xf344f34abca9a444545b5295066348a0ae22dda3', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, ecotestnet: { threshold: 1, - validators: ['0xb3191420d463c2af8bd9b4a395e100ec5c05915a'], + validators: [ + { + address: '0xb3191420d463c2af8bd9b4a395e100ec5c05915a', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, endurance: { threshold: 2, validators: [ - '0x28c5b322da06f184ebf68693c5d19df4d4af13e5', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x7419021c0de2772b763e554480158a82a291c1f2', // fusionist + { + address: '0x28c5b322da06f184ebf68693c5d19df4d4af13e5', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + { + address: '0x7419021c0de2772b763e554480158a82a291c1f2', + alias: 'Fusionist', + }, ], }, ethereum: { threshold: 4, validators: [ - '0x03c842db86a6a3e524d4a6615390c1ea8e2b9541', - '0x94438a7de38d4548ae54df5c6010c4ebc5239eae', // dsrv - '0x5450447aee7b544c462c9352bef7cad049b0c2dc', // zeeprime - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b', // staked - '0xb683b742b378632a5f73a2a5a45801b3489bba44', // avs: luganodes - '0xbf1023eff3dba21263bf2db2add67a0d6bcda2de', // avs: pier two + { + address: '0x03c842db86a6a3e524d4a6615390c1ea8e2b9541', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0x94438a7de38d4548ae54df5c6010c4ebc5239eae', alias: 'DSRV' }, + DEFAULT_ZEE_PRIME_VALIDATOR, + DEFAULT_EVERSTAKE_VALIDATOR, + DEFAULT_STAKED_VALIDATOR, + { + address: '0xb683b742b378632a5f73a2a5a45801b3489bba44', + alias: 'AVS: Luganodes', + }, + { + address: '0xbf1023eff3dba21263bf2db2add67a0d6bcda2de', + alias: 'AVS: Pier Two', + }, ], }, everclear: { threshold: 2, validators: [ - '0xeff20ae3d5ab90abb11e882cfce4b92ea6c74837', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0xD79DFbF56ee2268f061cc613027a44A880f61Ba2', // everclear + { + address: '0xeff20ae3d5ab90abb11e882cfce4b92ea6c74837', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + { + address: '0xD79DFbF56ee2268f061cc613027a44A880f61Ba2', + alias: 'Everclear', + }, ], }, fantom: { threshold: 2, validators: [ - '0xa779572028e634e16f26af5dfd4fa685f619457d', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xa779572028e634e16f26af5dfd4fa685f619457d', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, flame: { - threshold: 2, + threshold: 3, validators: [ - '0x1fa928ce884fa16357d4b8866e096392d4d81f43', - '0xa6c998f0db2b56d7a63faf30a9b677c8b9b6faab', // p-ops - '0x0d4c1394a255568ec0ecd11795b28d1bda183ca4', // tessellated + { + address: '0x1fa928ce884fa16357d4b8866e096392d4d81f43', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0xa6c998f0db2b56d7a63faf30a9b677c8b9b6faab', + alias: 'P-OPS', + }, + { + address: '0x09f9de08f7570c4146caa708dc9f75b56958957f', + alias: 'Luganodes', + }, + { + address: '0xf1f4ae9959490380ad7863e79c3faf118c1fbf77', + alias: 'DSRV', + }, + DEFAULT_TESSELLATED_VALIDATOR, ], }, flare: { threshold: 2, validators: [ - '0xb65e52be342dba3ab2c088ceeb4290c744809134', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xb65e52be342dba3ab2c088ceeb4290c744809134', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, flowmainnet: { threshold: 3, validators: [ - '0xe132235c958ca1f3f24d772e5970dd58da4c0f6e', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis - '0x14ADB9e3598c395Fe3290f3ba706C3816Aa78F59', // flow foundation + { + address: '0xe132235c958ca1f3f24d772e5970dd58da4c0f6e', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + { + address: '0x14ADB9e3598c395Fe3290f3ba706C3816Aa78F59', + alias: 'Flow Foundation', + }, ], }, formtestnet: { threshold: 1, - validators: ['0x72ad7fddf16d17ff902d788441151982fa31a7bc'], + validators: [ + { + address: '0x72ad7fddf16d17ff902d788441151982fa31a7bc', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, fraxtal: { threshold: 4, validators: [ - '0x4bce180dac6da60d0f3a2bdf036ffe9004f944c1', - '0x0d4c1394a255568ec0ecd11795B28D1BdA183Ca4', // tessellated (superlane) - '0x1c3C3013B863Cf666499Da1A61949AE396E3Ab82', // enigma (superlane) - '0x573e960e07ad74ea2c5f1e3c31b2055994b12797', // imperator (superlane) - '0x14d0B24d3a8F3aAD17DB4b62cBcEC12821c98Cb3', // bware (superlane) - '0x25b3a88f7cfd3c9f7d7e32b295673a16a6ddbd91', // luganodes (superlane) + { + address: '0x4bce180dac6da60d0f3a2bdf036ffe9004f944c1', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_TESSELLATED_VALIDATOR, + { + address: '0x1c3C3013B863Cf666499Da1A61949AE396E3Ab82', + alias: 'Enigma', + }, + { + address: '0x573e960e07ad74ea2c5f1e3c31b2055994b12797', + alias: 'Imperator', + }, + DEFAULT_BWARE_LABS_VALIDATOR, + { + address: '0x25b3a88f7cfd3c9f7d7e32b295673a16a6ddbd91', + alias: 'Luganodes', + }, ], }, fuji: { threshold: 2, validators: [ - '0xd8154f73d04cc7f7f0c332793692e6e6f6b2402e', - '0x895ae30bc83ff1493b9cf7781b0b813d23659857', - '0x43e915573d9f1383cbf482049e4a012290759e7f', + { + address: '0xd8154f73d04cc7f7f0c332793692e6e6f6b2402e', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x895ae30bc83ff1493b9cf7781b0b813d23659857', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x43e915573d9f1383cbf482049e4a012290759e7f', + alias: AW_VALIDATOR_ALIAS, + }, ], }, fusemainnet: { threshold: 2, validators: [ - '0x770c8ec9aac8cec4b2ead583b49acfbc5a1cf8a9', - '0x6760226b34213d262D41D5291Ed57E81a68b4E0b', // fuse - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly + { + address: '0x770c8ec9aac8cec4b2ead583b49acfbc5a1cf8a9', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0x6760226b34213d262D41D5291Ed57E81a68b4E0b', alias: 'Fuse' }, + DEFAULT_MERKLY_VALIDATOR, ], }, gnosis: { threshold: 3, validators: [ - '0xd4df66a859585678f2ea8357161d896be19cc1ca', - '0x19fb7e04a1be6b39b6966a0b0c60b929a93ed672', // dsrv - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0x5450447aee7b544c462c9352bef7cad049b0c2dc', // zeeprime + { + address: '0xd4df66a859585678f2ea8357161d896be19cc1ca', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0x19fb7e04a1be6b39b6966a0b0c60b929a93ed672', alias: 'DSRV' }, + DEFAULT_EVERSTAKE_VALIDATOR, + DEFAULT_ZEE_PRIME_VALIDATOR, ], }, gravity: { threshold: 2, validators: [ - '0x23d549bf757a02a6f6068e9363196ecd958c974e', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x23d549bf757a02a6f6068e9363196ecd958c974e', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, harmony: { threshold: 2, validators: [ - '0xd677803a67651974b1c264171b5d7ca8838db8d5', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xd677803a67651974b1c264171b5d7ca8838db8d5', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, holesky: { threshold: 1, - validators: ['0x7ab28ad88bb45867137ea823af88e2cb02359c03'], // TODO + validators: [ + { + address: '0x7ab28ad88bb45867137ea823af88e2cb02359c03', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, hyperliquidevmtestnet: { threshold: 1, - validators: ['0xea673a92a23ca319b9d85cc16b248645cd5158da'], + validators: [ + { + address: '0xea673a92a23ca319b9d85cc16b248645cd5158da', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, immutablezkevmmainnet: { threshold: 2, validators: [ - '0xbdda85b19a5efbe09e52a32db1a072f043dd66da', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xbdda85b19a5efbe09e52a32db1a072f043dd66da', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, inevm: { threshold: 2, validators: [ - '0xf9e35ee88e4448a3673b4676a4e153e3584a08eb', - '0x0d4e7e64f3a032db30b75fe7acae4d2c877883bc', // decentrio - '0x9ab11f38a609940153850df611c9a2175dcffe0f', // imperator + { + address: '0xf9e35ee88e4448a3673b4676a4e153e3584a08eb', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x0d4e7e64f3a032db30b75fe7acae4d2c877883bc', + alias: 'Decentrio', + }, + { + address: '0x9ab11f38a609940153850df611c9a2175dcffe0f', + alias: 'Imperator', + }, ], }, injective: { threshold: 2, validators: [ - '0xbfb8911b72cfb138c7ce517c57d9c691535dc517', - '0x6B1d09A97b813D53e9D4b7523DA36604C0B52242', // caldera - '0x9e551b6694bbd295d7d6e6a2540c7d41ce70a3b9', // imperator + { + address: '0xbfb8911b72cfb138c7ce517c57d9c691535dc517', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x6B1d09A97b813D53e9D4b7523DA36604C0B52242', + alias: 'Caldera', + }, + { + address: '0x9e551b6694bbd295d7d6e6a2540c7d41ce70a3b9', + alias: 'Imperator', + }, ], }, inksepolia: { threshold: 1, - validators: ['0xe61c846aee275070207fcbf43674eb254f06097a'], + validators: [ + { + address: '0xe61c846aee275070207fcbf43674eb254f06097a', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, kaia: { threshold: 2, validators: [ - '0x9de0b3abb221d19719882fa4d61f769fdc2be9a4', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x9de0b3abb221d19719882fa4d61f769fdc2be9a4', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, kroma: { threshold: 2, validators: [ - '0x71b83c21342787d758199e4b8634d3a15f02dc6e', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x71b83c21342787d758199e4b8634d3a15f02dc6e', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, linea: { threshold: 2, validators: [ - '0xf2d5409a59e0f5ae7635aff73685624904a77d94', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xf2d5409a59e0f5ae7635aff73685624904a77d94', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, lisk: { threshold: 4, validators: [ - '0xc0b282aa5bac43fee83cf71dc3dd1797c1090ea5', - '0x0d4c1394a255568ec0ecd11795b28d1bda183ca4', // tessellated (superlane) - '0x3DA4ee2801Ec6CC5faD73DBb94B10A203ADb3d9e', // enigma (superlane) - '0x4df6e8878992c300e7bfe98cac6bf7d3408b9cbf', // imperator (superlane) - '0x14d0B24d3a8F3aAD17DB4b62cBcEC12821c98Cb3', // bware (superlane) - '0xf0da628f3fb71652d48260bad4691054045832ce', // luganodes (superlane) + { + address: '0xc0b282aa5bac43fee83cf71dc3dd1797c1090ea5', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_TESSELLATED_VALIDATOR, + { + address: '0x3DA4ee2801Ec6CC5faD73DBb94B10A203ADb3d9e', + alias: 'Enigma', + }, + { + address: '0x4df6e8878992c300e7bfe98cac6bf7d3408b9cbf', + alias: 'Imperator', + }, + DEFAULT_BWARE_LABS_VALIDATOR, + { + address: '0xf0da628f3fb71652d48260bad4691054045832ce', + alias: 'Luganodes', + }, ], }, lukso: { threshold: 2, validators: [ - '0xa5e953701dcddc5b958b5defb677a829d908df6d', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x101cE77261245140A0871f9407d6233C8230Ec47', // blockhunters + { + address: '0xa5e953701dcddc5b958b5defb677a829d908df6d', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + { + address: '0x101cE77261245140A0871f9407d6233C8230Ec47', + alias: 'Blockhunters', + }, ], }, lumia: { threshold: 2, validators: [ - '0x9e283254ed2cd2c80f007348c2822fc8e5c2fa5f', - '0xCF0211faFBb91FD9D06D7E306B30032DC3A1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x9e283254ed2cd2c80f007348c2822fc8e5c2fa5f', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + ], + }, + + lumiaprism: { + threshold: 1, + validators: [ + { + address: '0xb69731640ffd4338a2c9358a935b0274c6463f85', + alias: AW_VALIDATOR_ALIAS, + }, ], }, mantapacific: { threshold: 5, validators: [ - '0x8e668c97ad76d0e28375275c41ece4972ab8a5bc', //abacusworks - '0x521a3e6bf8d24809fde1c1fd3494a859a16f132c', //cosmostation - '0x14025fe092f5f8a401dd9819704d9072196d2125', //p2p - '0x25b9a0961c51e74fd83295293bc029131bf1e05a', //neutron - '0xa0eE95e280D46C14921e524B075d0C341e7ad1C8', //cosmos spaces - '0xcc9a0b6de7fe314bd99223687d784730a75bb957', //dsrv - '0x42b6de2edbaa62c2ea2309ad85d20b3e37d38acf', //sg-1 + { + address: '0x8e668c97ad76d0e28375275c41ece4972ab8a5bc', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x521a3e6bf8d24809fde1c1fd3494a859a16f132c', + alias: 'Cosmostation', + }, + { address: '0x14025fe092f5f8a401dd9819704d9072196d2125', alias: 'P2P' }, + { + address: '0x25b9a0961c51e74fd83295293bc029131bf1e05a', + alias: 'Neutron', + }, + { + address: '0xa0eE95e280D46C14921e524B075d0C341e7ad1C8', + alias: 'Cosmos Spaces', + }, + { address: '0xcc9a0b6de7fe314bd99223687d784730a75bb957', alias: 'DSRV' }, + { address: '0x42b6de2edbaa62c2ea2309ad85d20b3e37d38acf', alias: 'SG-1' }, ], }, mantle: { threshold: 2, validators: [ - '0xf930636c5a1a8bf9302405f72e3af3c96ebe4a52', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xf930636c5a1a8bf9302405f72e3af3c96ebe4a52', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, merlin: { threshold: 2, validators: [ - '0xc1d6600cb9326ed2198cc8c4ba8d6668e8671247', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xc1d6600cb9326ed2198cc8c4ba8d6668e8671247', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, metal: { - threshold: 2, + threshold: 4, validators: [ - '0xd9f7f1a05826197a93df51e86cefb41dfbfb896a', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xd9f7f1a05826197a93df51e86cefb41dfbfb896a', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x01e3909133d20c05bbc94247769235d30101f748', + alias: 'Imperator', + }, + + { + address: '0xaba06266f47e3ef554d218b879bd86114a8dabd4', + alias: 'Enigma', + }, + { + address: '0x05d91f80377ff5e9c6174025ffaf094c57a4766a', + alias: 'Luganodes', + }, + DEFAULT_BWARE_LABS_VALIDATOR, + DEFAULT_TESSELLATED_VALIDATOR, ], }, metis: { threshold: 2, validators: [ - '0xc4a3d25107060e800a43842964546db508092260', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xc4a3d25107060e800a43842964546db508092260', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, mint: { threshold: 2, validators: [ - '0xfed01ccdd7a65e8a6ad867b7fb03b9eb47777ac9', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x0230505530b80186f8cdccfaf9993eb97aebe98a', // mint + { + address: '0xfed01ccdd7a65e8a6ad867b7fb03b9eb47777ac9', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + { address: '0x0230505530b80186f8cdccfaf9993eb97aebe98a', alias: 'Mint' }, ], }, mode: { threshold: 4, validators: [ - '0x7eb2e1920a4166c19d6884c1cec3d2cf356fc9b7', - '0x0d4c1394a255568ec0ecd11795b28d1bda183ca4', // tessellated (superlane) - '0x65C140e3a05F33192384AffEF985696Fe3cDDE42', // enigma (superlane) - '0x20eade18ea2af6dfd54d72b3b5366b40fcb47f4b', // imperator (superlane) - '0x14d0B24d3a8F3aAD17DB4b62cBcEC12821c98Cb3', // bware (superlane) - '0x485a4f0009d9afbbf44521016f9b8cdd718e36ea', // luganodes (superlane) + { + address: '0x7eb2e1920a4166c19d6884c1cec3d2cf356fc9b7', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_TESSELLATED_VALIDATOR, + { + address: '0x65C140e3a05F33192384AffEF985696Fe3cDDE42', + alias: 'Enigma', + }, + { + address: '0x20eade18ea2af6dfd54d72b3b5366b40fcb47f4b', + alias: 'Imperator', + }, + DEFAULT_BWARE_LABS_VALIDATOR, + { + address: '0x485a4f0009d9afbbf44521016f9b8cdd718e36ea', + alias: 'Luganodes', + }, ], }, molten: { threshold: 2, validators: [ - '0xad5aa33f0d67f6fa258abbe75458ea4908f1dc9f', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xad5aa33f0d67f6fa258abbe75458ea4908f1dc9f', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, moonbeam: { threshold: 3, validators: [ - '0x2225e2f4e9221049456da93b71d2de41f3b6b2a8', - '0x645428d198d2e76cbd9c1647f5c80740bb750b97', // dsrv - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b', // staked + { + address: '0x2225e2f4e9221049456da93b71d2de41f3b6b2a8', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0x645428d198d2e76cbd9c1647f5c80740bb750b97', alias: 'DSRV' }, + DEFAULT_EVERSTAKE_VALIDATOR, + DEFAULT_STAKED_VALIDATOR, ], }, morph: { threshold: 2, validators: [ - '0x4884535f393151ec419add872100d352f71af380', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x4884535f393151ec419add872100d352f71af380', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, neutron: { threshold: 4, validators: [ - '0xa9b8c1f4998f781f958c63cfcd1708d02f004ff0', - '0xb65438a014fb05fbadcfe35bc6e25d372b6ba460', // cosmostation - '0x42fa752defe92459370a052b6387a87f7de9b80c', // p2p - '0xc79503a3e3011535a9c60f6d21f76f59823a38bd', // neutron - '0x47aa126e05933b95c5eb90b26e6b668d84f4b25a', // dsrv - '0x54b2cca5091b098a1a993dec03c4d1ee9af65999', // cosmos spaces - '0x42b6de2edbaa62c2ea2309ad85d20b3e37d38acf', // sg-1 + { + address: '0xa9b8c1f4998f781f958c63cfcd1708d02f004ff0', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0xb65438a014fb05fbadcfe35bc6e25d372b6ba460', + alias: 'Cosmostation', + }, + { address: '0x42fa752defe92459370a052b6387a87f7de9b80c', alias: 'P2P' }, + { + address: '0xc79503a3e3011535a9c60f6d21f76f59823a38bd', + alias: 'Neutron', + }, + { address: '0x47aa126e05933b95c5eb90b26e6b668d84f4b25a', alias: 'DSRV' }, + { + address: '0x54b2cca5091b098a1a993dec03c4d1ee9af65999', + alias: 'Cosmos Spaces', + }, + { address: '0x42b6de2edbaa62c2ea2309ad85d20b3e37d38acf', alias: 'SG-1' }, ], }, odysseytestnet: { threshold: 1, - validators: ['0xcc0a6e2d6aa8560b45b384ced7aa049870b66ea3'], + validators: [ + { + address: '0xcc0a6e2d6aa8560b45b384ced7aa049870b66ea3', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, oortmainnet: { threshold: 2, validators: [ - '0x9b7ff56cd9aa69006f73f1c5b8c63390c706a5d7', - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis - '0x032dE4f94676bF9314331e7D83E8Db4aC74c9E21', // oort + { + address: '0x9b7ff56cd9aa69006f73f1c5b8c63390c706a5d7', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MITOSIS_VALIDATOR, + { address: '0xfa94a494f01d1034b8cea025ca4c2a7e31ca39a1', alias: 'Oort' }, ], }, optimism: { threshold: 4, validators: [ - '0x20349eadc6c72e94ce38268b96692b1a5c20de4f', - '0x0d4c1394a255568ec0ecd11795b28d1bda183ca4', // tessellated (superlane) - '0xd8c1cCbfF28413CE6c6ebe11A3e29B0D8384eDbB', // enigma (superlane) - '0x1b9e5f36c4bfdb0e3f0df525ef5c888a4459ef99', // imperator (superlane) - '0x14d0B24d3a8F3aAD17DB4b62cBcEC12821c98Cb3', // bware (superlane) - '0xf9dfaa5c20ae1d84da4b2696b8dc80c919e48b12', // luganodes (superlane) + { + address: '0x20349eadc6c72e94ce38268b96692b1a5c20de4f', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_TESSELLATED_VALIDATOR, + { + address: '0xd8c1cCbfF28413CE6c6ebe11A3e29B0D8384eDbB', + alias: 'Enigma', + }, + { + address: '0x1b9e5f36c4bfdb0e3f0df525ef5c888a4459ef99', + alias: 'Imperator', + }, + DEFAULT_BWARE_LABS_VALIDATOR, + { + address: '0xf9dfaa5c20ae1d84da4b2696b8dc80c919e48b12', + alias: 'Luganodes', + }, ], }, optimismsepolia: { threshold: 1, - validators: ['0x03efe4d0632ee15685d7e8f46dea0a874304aa29'], + validators: [ + { + address: '0x03efe4d0632ee15685d7e8f46dea0a874304aa29', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, orderly: { threshold: 2, validators: [ - '0xec3dc91f9fa2ad35edf5842aa764d5573b778bb6', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xec3dc91f9fa2ad35edf5842aa764d5573b778bb6', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, osmosis: { threshold: 1, - validators: ['0xea483af11c19fa41b16c31d1534c2a486a92bcac'], + validators: [ + { + address: '0xea483af11c19fa41b16c31d1534c2a486a92bcac', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, plumetestnet: { threshold: 1, - validators: ['0xe765a214849f3ecdf00793b97d00422f2d408ea6'], + validators: [ + { + address: '0xe765a214849f3ecdf00793b97d00422f2d408ea6', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, polygon: { threshold: 3, validators: [ - '0x12ecb319c7f4e8ac5eb5226662aeb8528c5cefac', - '0x008f24cbb1cc30ad0f19f2516ca75730e37efb5f', // dsrv - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0x5450447aee7b544c462c9352bef7cad049b0c2dc', // zeeprime + { + address: '0x12ecb319c7f4e8ac5eb5226662aeb8528c5cefac', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0x008f24cbb1cc30ad0f19f2516ca75730e37efb5f', alias: 'DSRV' }, + DEFAULT_EVERSTAKE_VALIDATOR, + DEFAULT_ZEE_PRIME_VALIDATOR, ], }, polygonamoy: { threshold: 1, - validators: ['0xf0290b06e446b320bd4e9c4a519420354d7ddccd'], + validators: [ + { + address: '0xf0290b06e446b320bd4e9c4a519420354d7ddccd', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, polygonzkevm: { threshold: 2, validators: [ - '0x86f2a44592bb98da766e880cfd70d3bbb295e61a', - '0x865818fe1db986036d5fd0466dcd462562436d1a', // dsrv - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake + { + address: '0x86f2a44592bb98da766e880cfd70d3bbb295e61a', + alias: AW_VALIDATOR_ALIAS, + }, + { address: '0x865818fe1db986036d5fd0466dcd462562436d1a', alias: 'DSRV' }, + DEFAULT_EVERSTAKE_VALIDATOR, ], }, polynomialfi: { threshold: 2, validators: [ - '0x23d348c2d365040e56f3fee07e6897122915f513', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x23d348c2d365040e56f3fee07e6897122915f513', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, prom: { threshold: 2, validators: [ - '0xb0c4042b7c9a95345be8913f4cdbf4043b923d98', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xb0c4042b7c9a95345be8913f4cdbf4043b923d98', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, proofofplay: { threshold: 2, validators: [ - '0xcda40baa71970a06e5f55e306474de5ca4e21c3b', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xcda40baa71970a06e5f55e306474de5ca4e21c3b', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, rarichain: { threshold: 2, validators: [ - '0xeac012df7530720dd7d6f9b727e4fe39807d1516', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xeac012df7530720dd7d6f9b727e4fe39807d1516', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, real: { threshold: 2, validators: [ - '0xaebadd4998c70b05ce8715cf0c3cb8862fe0beec', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xaebadd4998c70b05ce8715cf0c3cb8862fe0beec', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, redstone: { threshold: 3, validators: [ - '0x1400b9737007f7978d8b4bbafb4a69c83f0641a7', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis - '0x101cE77261245140A0871f9407d6233C8230Ec47', // blockhunters + { + address: '0x1400b9737007f7978d8b4bbafb4a69c83f0641a7', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + { + address: '0x101cE77261245140A0871f9407d6233C8230Ec47', + alias: 'Blockhunters', + }, ], }, rootstockmainnet: { threshold: 2, validators: [ - '0x8675eb603d62ab64e3efe90df914e555966e04ac', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x8675eb603d62ab64e3efe90df914e555966e04ac', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, sanko: { threshold: 2, validators: [ - '0x795c37d5babbc44094b084b0c89ed9db9b5fae39', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x795c37d5babbc44094b084b0c89ed9db9b5fae39', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, scroll: { threshold: 3, validators: [ - '0xad557170a9f2f21c35e03de07cb30dcbcc3dff63', - '0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b', // staked - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0xbac4ac39f1d8b5ef15f26fdb1294a7c9aba3f948', // dsrv + { + address: '0xad557170a9f2f21c35e03de07cb30dcbcc3dff63', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_STAKED_VALIDATOR, + DEFAULT_EVERSTAKE_VALIDATOR, + { address: '0xbac4ac39f1d8b5ef15f26fdb1294a7c9aba3f948', alias: 'DSRV' }, ], }, scrollsepolia: { threshold: 2, validators: [ - '0xbe18dbd758afb367180260b524e6d4bcd1cb6d05', - '0x9a11ed23ae962974018ab45bc133caabff7b3271', - '0x7867bea3c9761fe64e6d124b171f91fd5dd79644', + { + address: '0xbe18dbd758afb367180260b524e6d4bcd1cb6d05', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x9a11ed23ae962974018ab45bc133caabff7b3271', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x7867bea3c9761fe64e6d124b171f91fd5dd79644', + alias: AW_VALIDATOR_ALIAS, + }, ], }, sei: { threshold: 3, validators: [ - '0x9920d2dbf6c85ffc228fdc2e810bf895732c6aa5', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x101cE77261245140A0871f9407d6233C8230Ec47', // blockhunters - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x9920d2dbf6c85ffc228fdc2e810bf895732c6aa5', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + { + address: '0x101cE77261245140A0871f9407d6233C8230Ec47', + alias: 'Blockhunters', + }, + DEFAULT_MITOSIS_VALIDATOR, ], }, sepolia: { threshold: 2, validators: [ - '0xb22b65f202558adf86a8bb2847b76ae1036686a5', - '0x469f0940684d147defc44f3647146cb90dd0bc8e', - '0xd3c75dcf15056012a4d74c483a0c6ea11d8c2b83', + { + address: '0xb22b65f202558adf86a8bb2847b76ae1036686a5', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x469f0940684d147defc44f3647146cb90dd0bc8e', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0xd3c75dcf15056012a4d74c483a0c6ea11d8c2b83', + alias: AW_VALIDATOR_ALIAS, + }, ], }, shibarium: { threshold: 2, validators: [ - '0xfa33391ee38597cbeef72ccde8c9e13e01e78521', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xfa33391ee38597cbeef72ccde8c9e13e01e78521', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, snaxchain: { threshold: 2, validators: [ - '0x2c25829ae32a772d2a49f6c4b34f8b01fd03ef9e', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x2c25829ae32a772d2a49f6c4b34f8b01fd03ef9e', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, solanadevnet: { threshold: 2, validators: [ - '0xec0f73dbc5b1962a20f7dcbe07c98414025b0c43', - '0x9c20a149dfa09ea9f77f5a7ca09ed44f9c025133', - '0x967c5ecdf2625ae86580bd203b630abaaf85cd62', + { + address: '0xec0f73dbc5b1962a20f7dcbe07c98414025b0c43', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x9c20a149dfa09ea9f77f5a7ca09ed44f9c025133', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x967c5ecdf2625ae86580bd203b630abaaf85cd62', + alias: AW_VALIDATOR_ALIAS, + }, ], }, solanamainnet: { threshold: 3, validators: [ - '0x28464752829b3ea59a497fca0bdff575c534c3ff', - '0x2b7514a2f77bd86bbf093fe6bb67d8611f51c659', // luganodes - '0xd90ea26ff731d967c5ea660851f7d63cb04ab820', // dsrv - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0xcb6bcbd0de155072a7ff486d9d7286b0f71dcc2d', // eclipse + { + address: '0x28464752829b3ea59a497fca0bdff575c534c3ff', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x2b7514a2f77bd86bbf093fe6bb67d8611f51c659', + alias: 'Luganodes', + }, + { address: '0xd90ea26ff731d967c5ea660851f7d63cb04ab820', alias: 'DSRV' }, + DEFAULT_EVERSTAKE_VALIDATOR, + { + address: '0xcb6bcbd0de155072a7ff486d9d7286b0f71dcc2d', + alias: 'Eclipse', + }, ], }, solanatestnet: { threshold: 1, - validators: ['0xd4ce8fa138d4e083fc0e480cca0dbfa4f5f30bd5'], + validators: [ + { + address: '0xd4ce8fa138d4e083fc0e480cca0dbfa4f5f30bd5', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, soneiumtestnet: { threshold: 1, - validators: ['0x2e2101020ccdbe76aeda1c27823b0150f43d0c63'], + validators: [ + { + address: '0x2e2101020ccdbe76aeda1c27823b0150f43d0c63', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, sonictestnet: { threshold: 1, - validators: ['0x62e6591d00daec3fb658c3d19403828b4e9ddbb3'], + validators: [ + { + address: '0x62e6591d00daec3fb658c3d19403828b4e9ddbb3', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, stride: { threshold: 6, validators: [ - '0x38c7a4ca1273ead2e867d096adbcdd0e2acb21d8', // everstake - '0x88f0E5528131b10e3463C4c68108217Dd33462ac', // cosmostation - '0xa3eaa1216827ad63dd9db43f6168258a89177990', // DSRV - '0x3f869C36110F00D10dC74cca3ac1FB133cf019ad', // polkachu - '0x502dC6135d16E74056f609FBAF76846814C197D3', // strangelove - '0xc36979780c1aD43275182600a61Ce41f1C390FbE', // imperator - '0x87460dcEd16a75AECdBffD4189111d30B099f5b0', // enigma - '0xf54982134e52Eb7253236943FBffE0886C5bde0C', // L5 - '0x5937b7cE1029C3Ec4bD8e1AaCc0C0f9422654D7d', // stakecito - '0xb3ac35d3988bca8c2ffd195b1c6bee18536b317b', // staked + DEFAULT_EVERSTAKE_VALIDATOR, + { + address: '0x88f0E5528131b10e3463C4c68108217Dd33462ac', + alias: 'Cosmostation', + }, + { address: '0xa3eaa1216827ad63dd9db43f6168258a89177990', alias: 'DSRV' }, + { + address: '0x3f869C36110F00D10dC74cca3ac1FB133cf019ad', + alias: 'Polkachu', + }, + { + address: '0x502dC6135d16E74056f609FBAF76846814C197D3', + alias: 'Strangelove', + }, + { + address: '0xc36979780c1aD43275182600a61Ce41f1C390FbE', + alias: 'Imperator', + }, + { + address: '0x87460dcEd16a75AECdBffD4189111d30B099f5b0', + alias: 'Enigma', + }, + { address: '0xf54982134e52Eb7253236943FBffE0886C5bde0C', alias: 'L5' }, + { + address: '0x5937b7cE1029C3Ec4bD8e1AaCc0C0f9422654D7d', + alias: 'Stakecito', + }, + DEFAULT_STAKED_VALIDATOR, ], }, suavetoliman: { threshold: 1, - validators: ['0xf58f6e30aabba34e8dd7f79b3168507192e2cc9b'], + validators: [ + { + address: '0xf58f6e30aabba34e8dd7f79b3168507192e2cc9b', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, superpositionmainnet: { threshold: 2, validators: [ - '0x3f489acdd341c6b4dd86293fa2cc5ecc8ccf4f84', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x3f489acdd341c6b4dd86293fa2cc5ecc8ccf4f84', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, superpositiontestnet: { threshold: 1, - validators: ['0x1d3168504b23b73cdf9c27f13bb0a595d7f1a96a'], + validators: [ + { + address: '0x1d3168504b23b73cdf9c27f13bb0a595d7f1a96a', + alias: AW_VALIDATOR_ALIAS, + }, + ], + }, + + superseed: { + threshold: 4, + validators: [ + { + address: '0xdc2b87cb555411bb138d3a4e5f7832c87fae2b88', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x68f3a3b244f6ddc135130200a6b8729e290b4240', + alias: 'Imperator', + }, + { + address: '0x6ff4554cffbc2e4e4230b78e526eab255101d05a', + alias: 'Enigma', + }, + { + address: '0x55880ac03fdf15fccff54ed6f8a83455033edd22', + alias: 'Luganodes', + }, + DEFAULT_BWARE_LABS_VALIDATOR, + DEFAULT_TESSELLATED_VALIDATOR, + ], + }, + + swell: { + threshold: 1, + validators: [ + { + address: '0x4f51e4f4c7fb45d82f91568480a1a2cfb69216ed', + alias: AW_VALIDATOR_ALIAS, + }, + ], }, taiko: { threshold: 3, validators: [ - '0xa930073c8f2d0b2f7423ea32293e0d1362e65d79', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis - '0x2F007c82672F2Bb97227D4e3F80Ac481bfB40A2a', // luganodes + { + address: '0xa930073c8f2d0b2f7423ea32293e0d1362e65d79', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + { + address: '0x2F007c82672F2Bb97227D4e3F80Ac481bfB40A2a', + alias: 'Luganodes', + }, ], }, tangle: { threshold: 2, validators: [ - '0x1ee52cbbfacd7dcb0ba4e91efaa6fbc61602b15b', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0xe271ef9a6e312540f099a378865432fa73f26689', // tangle + { + address: '0x1ee52cbbfacd7dcb0ba4e91efaa6fbc61602b15b', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + { + address: '0xe271ef9a6e312540f099a378865432fa73f26689', + alias: 'Tangle', + }, + ], + }, + + treasure: { + threshold: 1, + validators: [ + { + address: '0x6ad994819185553e8baa01533f0cd2c7cadfe6cc', + alias: AW_VALIDATOR_ALIAS, + }, ], }, treasuretopaz: { threshold: 1, - validators: ['0x9750849beda0a7870462d4685f953fe39033a5ae'], + validators: [ + { + address: '0x9750849beda0a7870462d4685f953fe39033a5ae', + alias: AW_VALIDATOR_ALIAS, + }, + ], + }, + + unichain: { + threshold: 2, + validators: [ + { + address: '0x9773a382342ebf604a2e5de0a1f462fb499e28b1', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + ], }, unichaintestnet: { threshold: 1, - validators: ['0x5e99961cf71918308c3b17ef21b5f515a4f86fe5'], + validators: [ + { + address: '0x5e99961cf71918308c3b17ef21b5f515a4f86fe5', + alias: AW_VALIDATOR_ALIAS, + }, + ], + }, + + vana: { + threshold: 2, + validators: [ + { + address: '0xfdf3b0dfd4b822d10cacb15c8ae945ea269e7534', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + ], }, viction: { threshold: 2, validators: [ - '0x4E53dA92cD5Bf0a032b6B4614b986926456756A7', // blockpi - '0xa3f93fe365bf99f431d8fde740b140615e24f99b', // rockx - '0x1f87c368f8e05a85ef9126d984a980a20930cb9c', + { + address: '0x6D113Ae51bfeA7b63a8828f97e9dcE393B25c189', + alias: 'BlockPi', + }, + { address: '0xa3f93fe365bf99f431d8fde740b140615e24f99b', alias: 'RockX' }, + { + address: '0x1f87c368f8e05a85ef9126d984a980a20930cb9c', + alias: AW_VALIDATOR_ALIAS, + }, ], }, worldchain: { threshold: 2, validators: [ - '0x31048785845325b22817448b68d08f8a8fe36854', - '0x11e2a683e83617f186614071e422b857256a9aae', // imperator - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly + { + address: '0x31048785845325b22817448b68d08f8a8fe36854', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x11e2a683e83617f186614071e422b857256a9aae', + alias: 'Imperator', + }, + DEFAULT_MERKLY_VALIDATOR, ], }, xai: { threshold: 2, validators: [ - '0xe993f01fea86eb64cda45ae5af1d5be40ac0c7e9', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xe993f01fea86eb64cda45ae5af1d5be40ac0c7e9', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, xlayer: { threshold: 2, validators: [ - '0xa2ae7c594703e988f23d97220717c513db638ea3', - '0xfed056cC0967F5BC9C6350F6C42eE97d3983394d', // imperator - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly + { + address: '0xa2ae7c594703e988f23d97220717c513db638ea3', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0xfed056cC0967F5BC9C6350F6C42eE97d3983394d', + alias: 'Imperator', + }, + DEFAULT_MERKLY_VALIDATOR, ], }, zeronetwork: { threshold: 2, validators: [ - '0x1bd9e3f8a90ea1a13b0f2838a1858046368aad87', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x1bd9e3f8a90ea1a13b0f2838a1858046368aad87', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, zetachain: { threshold: 3, validators: [ - '0xa3bca0b80317dbf9c7dce16a16ac89f4ff2b23ef', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x101cE77261245140A0871f9407d6233C8230Ec47', // blockhunters - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0xa3bca0b80317dbf9c7dce16a16ac89f4ff2b23ef', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + { + address: '0x101cE77261245140A0871f9407d6233C8230Ec47', + alias: 'Blockhunters', + }, + DEFAULT_MITOSIS_VALIDATOR, ], }, zircuit: { threshold: 3, validators: [ - '0x169ec400cc758fef3df6a0d6c51fbc6cdd1015bb', - '0x7aC6584c068eb2A72d4Db82A7B7cd5AB34044061', // luganodes - '0x0180444c9342BD672867Df1432eb3dA354413a6E', // hashkey cloud - '0x1da9176C2CE5cC7115340496fa7D1800a98911CE', // renzo + { + address: '0x169ec400cc758fef3df6a0d6c51fbc6cdd1015bb', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x7aC6584c068eb2A72d4Db82A7B7cd5AB34044061', + alias: 'Luganodes', + }, + { + address: '0x0180444c9342BD672867Df1432eb3dA354413a6E', + alias: 'Hashkey Cloud', + }, + { address: '0x1da9176C2CE5cC7115340496fa7D1800a98911CE', alias: 'Renzo' }, + ], + }, + + zklink: { + threshold: 1, + validators: [ + { + address: '0x217a8cb4789fc45abf56cb6e2ca96f251a5ac181', + alias: AW_VALIDATOR_ALIAS, + }, ], }, zksync: { threshold: 3, validators: [ - '0xadd1d39ce7a687e32255ac457cf99a6d8c5b5d1a', - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis - '0x75237d42ce8ea27349a0254ada265db94157e0c1', // imperator + { + address: '0xadd1d39ce7a687e32255ac457cf99a6d8c5b5d1a', + alias: AW_VALIDATOR_ALIAS, + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, + { + address: '0x75237d42ce8ea27349a0254ada265db94157e0c1', + alias: 'Imperator', + }, ], }, zoramainnet: { threshold: 3, validators: [ - '0x35130945b625bb69b28aee902a3b9a76fa67125f', - '0x7089b6352d37d23fb05a7fee4229c78e038fba09', // imperator - '0xcf0211fafbb91fd9d06d7e306b30032dc3a1934f', // merkly - '0x4f977a59fdc2d9e39f6d780a84d5b4add1495a36', // mitosis + { + address: '0x35130945b625bb69b28aee902a3b9a76fa67125f', + alias: AW_VALIDATOR_ALIAS, + }, + { + address: '0x7089b6352d37d23fb05a7fee4229c78e038fba09', + alias: 'Imperator', + }, + DEFAULT_MERKLY_VALIDATOR, + DEFAULT_MITOSIS_VALIDATOR, ], }, }; diff --git a/typescript/sdk/src/consts/multisigIsmVerifyCosts.ts b/typescript/sdk/src/consts/multisigIsmVerifyCosts.ts index 2891527b2c..16be1a1951 100644 --- a/typescript/sdk/src/consts/multisigIsmVerifyCosts.ts +++ b/typescript/sdk/src/consts/multisigIsmVerifyCosts.ts @@ -1,4 +1,3 @@ -/* eslint-disable sort-keys */ export const multisigIsmVerifyCosts = { '1': { '1': 151966, diff --git a/typescript/sdk/src/contracts/contracts.ts b/typescript/sdk/src/contracts/contracts.ts index 52f6606cf5..df235c7e3f 100644 --- a/typescript/sdk/src/contracts/contracts.ts +++ b/typescript/sdk/src/contracts/contracts.ts @@ -14,11 +14,10 @@ import { promiseObjAll, } from '@hyperlane-xyz/utils'; -import { OwnableConfig } from '../deploy/types.js'; import { ChainMetadataManager } from '../metadata/ChainMetadataManager.js'; import { MultiProvider } from '../providers/MultiProvider.js'; import { AnnotatedEV5Transaction } from '../providers/ProviderType.js'; -import { ChainMap, Connection } from '../types.js'; +import { ChainMap, Connection, OwnableConfig } from '../types.js'; import { HyperlaneAddresses, diff --git a/typescript/sdk/src/core/CoreDeployer.hardhat-test.ts b/typescript/sdk/src/core/CoreDeployer.hardhat-test.ts index 525ca4acd0..581568f334 100644 --- a/typescript/sdk/src/core/CoreDeployer.hardhat-test.ts +++ b/typescript/sdk/src/core/CoreDeployer.hardhat-test.ts @@ -1,9 +1,10 @@ +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers.js'; import '@nomiclabs/hardhat-waffle'; import { assert, expect } from 'chai'; import hre from 'hardhat'; import sinon from 'sinon'; -import { objMap, promiseObjAll } from '@hyperlane-xyz/utils'; +import { Address, objMap, promiseObjAll } from '@hyperlane-xyz/utils'; import { TestChainName, testChains } from '../consts/testChains.js'; import { HyperlaneContractsMap } from '../contracts/types.js'; @@ -17,6 +18,7 @@ import { testCoreConfig } from '../test/testUtils.js'; import { ChainMap } from '../types.js'; import { EvmCoreReader } from './EvmCoreReader.js'; +import { EvmIcaModule } from './EvmIcaModule.js'; import { HyperlaneCore } from './HyperlaneCore.js'; import { HyperlaneCoreChecker } from './HyperlaneCoreChecker.js'; import { HyperlaneCoreDeployer } from './HyperlaneCoreDeployer.js'; @@ -30,9 +32,10 @@ describe('core', async () => { let contracts: HyperlaneContractsMap; let coreConfig: ChainMap; let ismFactory: HyperlaneIsmFactory; + let signer: SignerWithAddress; before(async () => { - const [signer] = await hre.ethers.getSigners(); + [signer] = await hre.ethers.getSigners(); multiProvider = MultiProvider.createTestMultiProvider({ signer }); const proxyFactoryDeployer = new HyperlaneProxyFactoryDeployer( multiProvider, @@ -122,21 +125,47 @@ describe('core', async () => { }); describe('CoreConfigReader', async () => { + let icaRouterAddressMap: ChainMap
; + beforeEach(async () => { contracts = await deployer.deploy(coreConfig); + + const icaMap: ChainMap
= {}; + for (const chain of Object.keys(contracts)) { + const { interchainAccountRouter } = ( + await EvmIcaModule.create({ + chain, + multiProvider: multiProvider, + config: { + mailbox: contracts[chain].mailbox.address, + owner: signer.address, + }, + }) + ).serialize(); + icaMap[chain] = interchainAccountRouter; + } + + icaRouterAddressMap = icaMap; }); - async function deriveCoreConfig(chainName: string, mailboxAddress: string) { - return new EvmCoreReader(multiProvider, chainName).deriveCoreConfig( - mailboxAddress, - ); + async function deriveCoreConfig( + chainName: string, + mailboxAddress: string, + icaRouterAddress: string, + ) { + return new EvmCoreReader(multiProvider, chainName).deriveCoreConfig({ + mailbox: mailboxAddress, + interchainAccountRouter: icaRouterAddress, + }); } + it('should derive defaultIsm correctly', async () => { await promiseObjAll( objMap(contracts, async (chainName, contract) => { const coreConfigOnChain = await deriveCoreConfig( chainName, contract.mailbox.address, + icaRouterAddressMap[chainName], ); // Cast because we don't expect the 'string' type @@ -149,12 +178,14 @@ describe('core', async () => { }), ); }); + it('should derive defaultHook correctly', async () => { await promiseObjAll( objMap(contracts, async (chainName, contract) => { const coreConfigOnChain = await deriveCoreConfig( chainName, contract.mailbox.address, + icaRouterAddressMap[chainName], ); // Cast because we don't expect the 'string' type @@ -167,12 +198,14 @@ describe('core', async () => { }), ); }); + it('should derive requiredHook correctly', async () => { await promiseObjAll( objMap(contracts, async (chainName, contract) => { const coreConfigOnChain = await deriveCoreConfig( chainName, contract.mailbox.address, + icaRouterAddressMap[chainName], ); const { address: _, ...requiredHookOnchain } = coreConfigOnChain.requiredHook as DerivedHookConfig; @@ -195,7 +228,7 @@ describe('core', async () => { try { await deployer.deploy(coreConfig); // eslint-disable-next-line no-empty - } catch (e: any) {} + } catch {} }); afterEach(async () => { @@ -252,7 +285,7 @@ describe('core', async () => { deployer.chainTimeoutMs = 1; try { await deployer.deploy(coreConfig); - } catch (e: any) { + } catch { // TODO: figure out how to test specific error case // expect(e.message).to.include('Timed out in 1ms'); } diff --git a/typescript/sdk/src/core/EvmCoreModule.ts b/typescript/sdk/src/core/EvmCoreModule.ts index a14cdc5fe9..60dad3f523 100644 --- a/typescript/sdk/src/core/EvmCoreModule.ts +++ b/typescript/sdk/src/core/EvmCoreModule.ts @@ -1,3 +1,5 @@ +import { ethers } from 'ethers'; + import { Mailbox, Mailbox__factory, @@ -21,8 +23,12 @@ import { HyperlaneAddresses, HyperlaneContractsMap, } from '../contracts/types.js'; -import { DeployedCoreAddresses } from '../core/schemas.js'; -import { CoreConfig } from '../core/types.js'; +import { + CoreConfig, + CoreConfigSchema, + DeployedCoreAddresses, + DerivedCoreConfig, +} from '../core/types.js'; import { HyperlaneProxyFactoryDeployer } from '../deploy/HyperlaneProxyFactoryDeployer.js'; import { ProxyFactoryFactories, @@ -47,7 +53,6 @@ import { EvmCoreReader } from './EvmCoreReader.js'; import { EvmIcaModule } from './EvmIcaModule.js'; import { HyperlaneCoreDeployer } from './HyperlaneCoreDeployer.js'; import { CoreFactories } from './contracts.js'; -import { CoreConfigSchema } from './schemas.js'; export class EvmCoreModule extends HyperlaneModule< ProtocolType.Ethereum, @@ -56,6 +61,7 @@ export class EvmCoreModule extends HyperlaneModule< > { protected logger = rootLogger.child({ module: 'EvmCoreModule' }); protected coreReader: EvmCoreReader; + protected evmIcaModule?: EvmIcaModule; public readonly chainName: ChainName; public readonly chainId: EvmChainId; @@ -70,15 +76,32 @@ export class EvmCoreModule extends HyperlaneModule< this.chainName = multiProvider.getChainName(args.chain); this.chainId = multiProvider.getEvmChainId(args.chain); this.domainId = multiProvider.getDomainId(args.chain); - this.chainId = multiProvider.getEvmChainId(args.chain); + + if (args.config.interchainAccountRouter) { + this.evmIcaModule = new EvmIcaModule(multiProvider, { + chain: args.chain, + addresses: { + interchainAccountIsm: args.addresses.interchainAccountIsm, + interchainAccountRouter: args.addresses.interchainAccountRouter, + // TODO: fix this even though is not used at the moment internally + proxyAdmin: ethers.constants.AddressZero, + timelockController: + args.addresses.timelockController ?? ethers.constants.AddressZero, + }, + config: args.config.interchainAccountRouter, + }); + } } /** * Reads the core configuration from the mailbox address specified in the SDK arguments. * @returns The core config. */ - public async read(): Promise { - return this.coreReader.deriveCoreConfig(this.args.addresses.mailbox); + public async read(): Promise { + return this.coreReader.deriveCoreConfig({ + mailbox: this.args.addresses.mailbox, + interchainAccountRouter: this.args.addresses.interchainAccountRouter, + }); } /** @@ -94,7 +117,6 @@ export class EvmCoreModule extends HyperlaneModule< const actualConfig = await this.read(); const transactions: AnnotatedEV5Transaction[] = []; - transactions.push( ...(await this.createDefaultIsmUpdateTxs(actualConfig, expectedConfig)), ...this.createMailboxOwnerUpdateTxs(actualConfig, expectedConfig), @@ -106,6 +128,14 @@ export class EvmCoreModule extends HyperlaneModule< ), ); + if (expectedConfig.interchainAccountRouter && this.evmIcaModule) { + transactions.push( + ...(await this.evmIcaModule.update( + expectedConfig.interchainAccountRouter, + )), + ); + } + return transactions; } @@ -117,7 +147,7 @@ export class EvmCoreModule extends HyperlaneModule< * @returns Transaction that need to be executed to update the ISM configuration. */ async createDefaultIsmUpdateTxs( - actualConfig: CoreConfig, + actualConfig: DerivedCoreConfig, expectedConfig: CoreConfig, ): Promise { const updateTransactions: AnnotatedEV5Transaction[] = []; @@ -212,7 +242,7 @@ export class EvmCoreModule extends HyperlaneModule< * @returns Ethereum transaction that need to be executed to update the owner. */ createMailboxOwnerUpdateTxs( - actualConfig: CoreConfig, + actualConfig: DerivedCoreConfig, expectedConfig: CoreConfig, ): AnnotatedEV5Transaction[] { return transferOwnershipTransactions( diff --git a/typescript/sdk/src/core/EvmCoreReader.ts b/typescript/sdk/src/core/EvmCoreReader.ts index 0c0a7887a1..f6ff5089b4 100644 --- a/typescript/sdk/src/core/EvmCoreReader.ts +++ b/typescript/sdk/src/core/EvmCoreReader.ts @@ -10,22 +10,27 @@ import { import { DEFAULT_CONTRACT_READ_CONCURRENCY } from '../consts/concurrency.js'; import { proxyAdmin } from '../deploy/proxy.js'; -import { DeployedOwnableConfig } from '../deploy/types.js'; import { EvmHookReader } from '../hook/EvmHookReader.js'; +import { EvmIcaRouterReader } from '../ica/EvmIcaReader.js'; import { EvmIsmReader } from '../ism/EvmIsmReader.js'; import { MultiProvider } from '../providers/MultiProvider.js'; -import { ChainNameOrId } from '../types.js'; +import { ChainNameOrId, DeployedOwnableConfig } from '../types.js'; -import { CoreConfig } from './types.js'; +import { CoreConfig, DerivedCoreConfig } from './types.js'; interface CoreReader { - deriveCoreConfig(address: Address): Promise; + deriveCoreConfig(contracts: { + mailbox: Address; + interchainAccountRouter: Address; + }): Promise; } export class EvmCoreReader implements CoreReader { - provider: providers.Provider; - evmHookReader: EvmHookReader; - evmIsmReader: EvmIsmReader; + public readonly provider: providers.Provider; + public readonly evmHookReader: EvmHookReader; + public readonly evmIsmReader: EvmIsmReader; + public readonly evmIcaRouterReader: EvmIcaRouterReader; + protected readonly logger = rootLogger.child({ module: 'EvmCoreReader' }); constructor( @@ -38,6 +43,9 @@ export class EvmCoreReader implements CoreReader { this.provider = this.multiProvider.getProvider(chain); this.evmHookReader = new EvmHookReader(multiProvider, chain, concurrency); this.evmIsmReader = new EvmIsmReader(multiProvider, chain, concurrency); + this.evmIcaRouterReader = new EvmIcaRouterReader( + multiProvider.getProvider(chain), + ); } /** @@ -46,24 +54,33 @@ export class EvmCoreReader implements CoreReader { * @param address - The address of the Mailbox contract. * @returns A promise that resolves to the CoreConfig object, containing the owner, default ISM, default Hook, and required Hook configurations. */ - async deriveCoreConfig(address: Address): Promise { - const mailbox = Mailbox__factory.connect(address, this.provider); + async deriveCoreConfig({ + mailbox, + interchainAccountRouter, + }: { + mailbox: Address; + interchainAccountRouter?: Address; + }): Promise { + const mailboxInstance = Mailbox__factory.connect(mailbox, this.provider); const [defaultIsm, defaultHook, requiredHook, mailboxProxyAdmin] = await Promise.all([ - mailbox.defaultIsm(), - mailbox.defaultHook(), - mailbox.requiredHook(), - proxyAdmin(this.provider, mailbox.address), + mailboxInstance.defaultIsm(), + mailboxInstance.defaultHook(), + mailboxInstance.requiredHook(), + proxyAdmin(this.provider, mailboxInstance.address), ]); // Parallelize each configuration request const results = await promiseObjAll( objMap( { - owner: mailbox.owner(), + owner: mailboxInstance.owner(), defaultIsm: this.evmIsmReader.deriveIsmConfig(defaultIsm), defaultHook: this.evmHookReader.deriveHookConfig(defaultHook), requiredHook: this.evmHookReader.deriveHookConfig(requiredHook), + interchainAccountRouter: interchainAccountRouter + ? this.evmIcaRouterReader.deriveConfig(interchainAccountRouter) + : undefined, proxyAdmin: this.getProxyAdminConfig(mailboxProxyAdmin), }, async (_, readerCall) => { @@ -71,7 +88,7 @@ export class EvmCoreReader implements CoreReader { return readerCall; } catch (e) { this.logger.error( - `EvmCoreReader: readerCall failed for ${address}:`, + `EvmCoreReader: readerCall failed for ${mailbox}:`, e, ); return; @@ -80,7 +97,7 @@ export class EvmCoreReader implements CoreReader { ), ); - return results as CoreConfig; + return results as DerivedCoreConfig; } private async getProxyAdminConfig( diff --git a/typescript/sdk/src/core/EvmIcaModule.ts b/typescript/sdk/src/core/EvmIcaModule.ts index 475a302f4a..d31a33fd07 100644 --- a/typescript/sdk/src/core/EvmIcaModule.ts +++ b/typescript/sdk/src/core/EvmIcaModule.ts @@ -1,8 +1,22 @@ -import { ProtocolType, rootLogger } from '@hyperlane-xyz/utils'; +import { ethers } from 'ethers'; + +import { InterchainAccountRouter__factory } from '@hyperlane-xyz/core'; +import { + Domain, + EvmChainId, + ProtocolType, + addressToBytes32, + bytes32ToAddress, + difference, + rootLogger, +} from '@hyperlane-xyz/utils'; import { serializeContracts } from '../contracts/contracts.js'; import { HyperlaneAddresses } from '../contracts/types.js'; +import { proxyAdminUpdateTxs } from '../deploy/proxy.js'; import { ContractVerifier } from '../deploy/verify/ContractVerifier.js'; +import { EvmIcaRouterReader } from '../ica/EvmIcaReader.js'; +import { DerivedIcaRouterConfig } from '../ica/types.js'; import { InterchainAccountDeployer } from '../middleware/account/InterchainAccountDeployer.js'; import { InterchainAccountFactories } from '../middleware/account/contracts.js'; import { MultiProvider } from '../providers/MultiProvider.js'; @@ -15,7 +29,8 @@ import { HyperlaneModuleParams, } from './AbstractHyperlaneModule.js'; -export type InterchainAccountConfig = ProxiedRouterConfig; +export type InterchainAccountConfig = ProxiedRouterConfig & + Partial>; export class EvmIcaModule extends HyperlaneModule< ProtocolType.Ethereum, @@ -23,8 +38,11 @@ export class EvmIcaModule extends HyperlaneModule< HyperlaneAddresses > { protected logger = rootLogger.child({ module: 'EvmIcaModule' }); + protected icaRouterReader: EvmIcaRouterReader; + public readonly domainId: Domain; + public readonly chainId: EvmChainId; - protected constructor( + constructor( protected readonly multiProvider: MultiProvider, args: HyperlaneModuleParams< InterchainAccountConfig, @@ -32,16 +50,161 @@ export class EvmIcaModule extends HyperlaneModule< >, ) { super(args); + this.icaRouterReader = new EvmIcaRouterReader( + multiProvider.getProvider(this.args.chain), + ); + this.domainId = multiProvider.getDomainId(args.chain); + this.chainId = multiProvider.getEvmChainId(args.chain); } - public async read(): Promise { - throw new Error('Method not implemented.'); + public async read(): Promise { + return this.icaRouterReader.deriveConfig( + this.args.addresses.interchainAccountRouter, + ); } public async update( - _config: InterchainAccountConfig, + expectedConfig: InterchainAccountConfig, + ): Promise { + const actualConfig = await this.read(); + + const transactions: AnnotatedEV5Transaction[] = [ + ...(await this.updateRemoteRoutersEnrollment( + actualConfig.remoteIcaRouters, + expectedConfig.remoteIcaRouters, + )), + ...proxyAdminUpdateTxs( + this.chainId, + this.args.addresses.interchainAccountIsm, + actualConfig, + expectedConfig, + ), + ]; + + return transactions; + } + + private async updateRemoteRoutersEnrollment( + actualConfig: DerivedIcaRouterConfig['remoteIcaRouters'], + expectedConfig: InterchainAccountConfig['remoteIcaRouters'] = {}, + ): Promise { + const transactions: AnnotatedEV5Transaction[] = [ + ...(await this.getEnrollRemoteIcaRoutersTxs( + actualConfig, + expectedConfig, + )), + ...(await this.getUnenrollRemoteIcaRoutersTxs( + actualConfig, + expectedConfig, + )), + ]; + + return transactions; + } + + private async getEnrollRemoteIcaRoutersTxs( + actualConfig: Readonly, + expectedConfig: Readonly = {}, + ): Promise { + const transactions: AnnotatedEV5Transaction[] = []; + + const routesToEnroll = Array.from( + difference( + new Set(Object.keys(expectedConfig)), + new Set(Object.keys(actualConfig)), + ), + ); + + if (routesToEnroll.length === 0) { + return transactions; + } + + const domainsToEnroll: string[] = []; + const remoteDomainIca: string[] = []; + const remoteIsm: string[] = []; + + for (const domainId of routesToEnroll) { + domainsToEnroll.push(domainId); + remoteDomainIca.push(addressToBytes32(expectedConfig[domainId].address)); + remoteIsm.push( + expectedConfig[domainId].interchainSecurityModule + ? addressToBytes32(expectedConfig[domainId].interchainSecurityModule!) + : ethers.utils.hexZeroPad('0x', 32), + ); + } + + const remoteTransactions: AnnotatedEV5Transaction[] = domainsToEnroll.map( + (domainId) => ({ + annotation: `Enrolling InterchainAccountRouter on domain ${this.domainId} on InterchainAccountRouter at ${expectedConfig[domainId].address} on domain ${domainId}`, + chainId: this.multiProvider.getEvmChainId(domainId), + to: expectedConfig[domainId].address, + data: InterchainAccountRouter__factory.createInterface().encodeFunctionData( + 'enrollRemoteRouter(uint32,bytes32)', + [ + this.domainId, + addressToBytes32(this.args.addresses.interchainAccountRouter), + ], + ), + }), + ); + + transactions.push({ + annotation: `Enrolling remote InterchainAccountRouters on domain ${this.domainId}`, + chainId: this.chainId, + to: this.args.addresses.interchainAccountRouter, + data: InterchainAccountRouter__factory.createInterface().encodeFunctionData( + 'enrollRemoteRouterAndIsms(uint32[],bytes32[],bytes32[])', + [domainsToEnroll, remoteDomainIca, remoteIsm], + ), + }); + + transactions.push(...remoteTransactions); + + return transactions; + } + + private async getUnenrollRemoteIcaRoutersTxs( + actualConfig: Readonly, + expectedConfig: Readonly = {}, ): Promise { - throw new Error('Method not implemented.'); + const transactions: AnnotatedEV5Transaction[] = []; + + const routesToUnenroll = Array.from( + difference( + new Set(Object.keys(actualConfig)), + new Set(Object.keys(expectedConfig)), + ), + ); + + if (routesToUnenroll.length === 0) { + return transactions; + } + + transactions.push({ + annotation: `Unenrolling remote InterchainAccountRouters from chain ${this.domainId}`, + chainId: this.chainId, + to: this.args.addresses.interchainAccountRouter, + data: InterchainAccountRouter__factory.createInterface().encodeFunctionData( + 'unenrollRemoteRouters(uint32[])', + [routesToUnenroll], + ), + }); + + const remoteTransactions: AnnotatedEV5Transaction[] = routesToUnenroll.map( + (domainId) => ({ + annotation: `Removing InterchainAccountRouter on domain ${this.domainId} from InterchainAccountRouter at ${actualConfig[domainId].address} on domain ${domainId}`, + chainId: this.multiProvider.getEvmChainId(domainId), + to: bytes32ToAddress(actualConfig[domainId].address), + data: InterchainAccountRouter__factory.createInterface().encodeFunctionData( + 'unenrollRemoteRouter(uint32)', + [this.domainId], + ), + }), + ); + + transactions.push(...remoteTransactions); + + return transactions; } /** diff --git a/typescript/sdk/src/core/HyperlaneCore.ts b/typescript/sdk/src/core/HyperlaneCore.ts index a3f82e36d1..a3130ecd1a 100644 --- a/typescript/sdk/src/core/HyperlaneCore.ts +++ b/typescript/sdk/src/core/HyperlaneCore.ts @@ -30,12 +30,11 @@ import { HyperlaneAddressesMap, HyperlaneContracts, } from '../contracts/types.js'; -import { OwnableConfig } from '../deploy/types.js'; import { DerivedHookConfig, EvmHookReader } from '../hook/EvmHookReader.js'; import { DerivedIsmConfig, EvmIsmReader } from '../ism/EvmIsmReader.js'; import { MultiProvider } from '../providers/MultiProvider.js'; import { RouterConfig } from '../router/types.js'; -import { ChainMap, ChainName } from '../types.js'; +import { ChainMap, ChainName, OwnableConfig } from '../types.js'; import { findMatchingLogEvents } from '../utils/logUtils.js'; import { CoreFactories, coreFactories } from './contracts.js'; diff --git a/typescript/sdk/src/core/HyperlaneRelayer.ts b/typescript/sdk/src/core/HyperlaneRelayer.ts index 0a1a451ebf..9b82f90cbb 100644 --- a/typescript/sdk/src/core/HyperlaneRelayer.ts +++ b/typescript/sdk/src/core/HyperlaneRelayer.ts @@ -2,7 +2,6 @@ import { ethers, providers } from 'ethers'; import { Logger } from 'pino'; import { z } from 'zod'; -import { ChainMap } from '@hyperlane-xyz/sdk'; import { Address, ParsedMessage, @@ -17,12 +16,12 @@ import { } from '@hyperlane-xyz/utils'; import { DerivedHookConfig, EvmHookReader } from '../hook/EvmHookReader.js'; -import { HookConfigSchema } from '../hook/schemas.js'; +import { HookConfigSchema } from '../hook/types.js'; import { DerivedIsmConfig, EvmIsmReader } from '../ism/EvmIsmReader.js'; import { BaseMetadataBuilder } from '../ism/metadata/builder.js'; -import { IsmConfigSchema } from '../ism/schemas.js'; +import { IsmConfigSchema } from '../ism/types.js'; import { MultiProvider } from '../providers/MultiProvider.js'; -import { ChainName } from '../types.js'; +import { ChainMap, ChainName } from '../types.js'; import { HyperlaneCore } from './HyperlaneCore.js'; import { DispatchedMessage } from './types.js'; @@ -307,7 +306,7 @@ export class HyperlaneRelayer { // TODO: handle batching await this.relayMessage(dispatchReceipt, undefined, dispatchMsg); - } catch (error) { + } catch { this.logger.error( `Failed to relay message ${id} (attempt #${attempts + 1})`, ); @@ -320,7 +319,7 @@ export class HyperlaneRelayer { } } - protected whitelistChains() { + protected whitelistChains(): string[] | undefined { return this.whitelist ? Object.keys(this.whitelist) : undefined; } diff --git a/typescript/sdk/src/core/schemas.ts b/typescript/sdk/src/core/schemas.ts deleted file mode 100644 index 470df95ab0..0000000000 --- a/typescript/sdk/src/core/schemas.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { z } from 'zod'; - -import { ProxyFactoryFactoriesSchema } from '../deploy/schemas.js'; -import { HookConfigSchema } from '../hook/schemas.js'; -import { IsmConfigSchema } from '../ism/schemas.js'; -import { DeployedOwnableSchema, OwnableSchema } from '../schemas.js'; - -export const CoreConfigSchema = OwnableSchema.extend({ - defaultIsm: IsmConfigSchema, - defaultHook: HookConfigSchema, - requiredHook: HookConfigSchema, - // This field is set as optional because the old core config - // did not have it and we want to maintain backward compatibility - proxyAdmin: DeployedOwnableSchema.optional(), -}); - -export const DeployedCoreAddressesSchema = ProxyFactoryFactoriesSchema.extend({ - mailbox: z.string(), - validatorAnnounce: z.string(), - proxyAdmin: z.string(), - testRecipient: z.string(), - timelockController: z.string().optional(), - interchainAccountRouter: z.string(), - interchainAccountIsm: z.string(), - merkleTreeHook: z.string().optional(), - interchainGasPaymaster: z.string().optional(), -}); - -export type DeployedCoreAddresses = z.infer; diff --git a/typescript/sdk/src/core/types.ts b/typescript/sdk/src/core/types.ts index b212906489..d14eca1173 100644 --- a/typescript/sdk/src/core/types.ts +++ b/typescript/sdk/src/core/types.ts @@ -5,16 +5,54 @@ import type { Address, ParsedMessage } from '@hyperlane-xyz/utils'; import type { UpgradeConfig } from '../deploy/proxy.js'; import type { CheckerViolation } from '../deploy/types.js'; +import { ProxyFactoryFactoriesSchema } from '../deploy/types.js'; +import { HookConfigSchema } from '../hook/types.js'; +import { + DerivedIcaRouterConfigSchema, + IcaRouterConfigSchema, +} from '../ica/types.js'; import type { IsmConfig } from '../ism/types.js'; +import { IsmConfigSchema } from '../ism/types.js'; import type { ChainName } from '../types.js'; +import { DeployedOwnableSchema, OwnableSchema } from '../types.js'; -import { CoreConfigSchema } from './schemas.js'; +export const CoreConfigSchema = OwnableSchema.extend({ + defaultIsm: IsmConfigSchema, + defaultHook: HookConfigSchema, + requiredHook: HookConfigSchema, + // These field are set as optional because the old core config + // did not have them and we want to maintain backward compatibility + proxyAdmin: DeployedOwnableSchema.optional(), + interchainAccountRouter: IcaRouterConfigSchema.optional(), +}); + +export const DerivedCoreConfigSchema = CoreConfigSchema.merge( + z.object({ + interchainAccountRouter: DerivedIcaRouterConfigSchema.optional(), + }), +); + +export const DeployedCoreAddressesSchema = ProxyFactoryFactoriesSchema.extend({ + mailbox: z.string(), + validatorAnnounce: z.string(), + proxyAdmin: z.string(), + testRecipient: z.string(), + timelockController: z.string().optional(), + interchainAccountRouter: z.string(), + interchainAccountIsm: z.string(), + merkleTreeHook: z.string().optional(), + interchainGasPaymaster: z.string().optional(), +}); + +export type DeployedCoreAddresses = z.infer; export type CoreConfig = z.infer & { remove?: boolean; upgrade?: UpgradeConfig; }; +export type DerivedCoreConfig = z.infer; + export enum CoreViolationType { Mailbox = 'Mailbox', ConnectionManager = 'ConnectionManager', diff --git a/typescript/sdk/src/deploy/HyperlaneAppChecker.ts b/typescript/sdk/src/deploy/HyperlaneAppChecker.ts index 55f288f089..2b6eda45b8 100644 --- a/typescript/sdk/src/deploy/HyperlaneAppChecker.ts +++ b/typescript/sdk/src/deploy/HyperlaneAppChecker.ts @@ -48,11 +48,7 @@ export abstract class HyperlaneAppChecker< async check(chainsToCheck?: ChainName[]): Promise { // Get all EVM chains from config - const evmChains = Object.keys(this.configMap).filter( - (chain) => - this.multiProvider.getChainMetadata(chain).protocol === - ProtocolType.Ethereum, - ); + const evmChains = this.getEvmChains(); // Mark any EVM chains that are not deployed const appChains = this.app.chains(); @@ -82,6 +78,14 @@ export abstract class HyperlaneAppChecker< ); } + getEvmChains(): ChainName[] { + return Object.keys(this.configMap).filter( + (chain) => + this.multiProvider.getChainMetadata(chain).protocol === + ProtocolType.Ethereum, + ); + } + addViolation(violation: CheckerViolation): void { if (violation.type === ViolationType.BytecodeMismatch) { rootLogger.warn({ violation }, `Found bytecode mismatch. Ignoring...`); @@ -133,7 +137,7 @@ export abstract class HyperlaneAppChecker< const actualProxyAdminOwner = await actualProxyAdminContract.owner(); const expectedOwner = this.getOwner( - actualProxyAdminOwner, + owner, 'proxyAdmin', ownableOverrides, ); diff --git a/typescript/sdk/src/deploy/HyperlaneDeployer.ts b/typescript/sdk/src/deploy/HyperlaneDeployer.ts index c6cd2048c6..fb3262902b 100644 --- a/typescript/sdk/src/deploy/HyperlaneDeployer.ts +++ b/typescript/sdk/src/deploy/HyperlaneDeployer.ts @@ -29,13 +29,13 @@ import { HyperlaneFactories, } from '../contracts/types.js'; import { HookConfig } from '../hook/types.js'; -import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory.js'; +import type { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory.js'; import { IsmConfig } from '../ism/types.js'; import { moduleMatchesConfig } from '../ism/utils.js'; import { InterchainAccount } from '../middleware/account/InterchainAccount.js'; import { MultiProvider } from '../providers/MultiProvider.js'; import { MailboxClientConfig } from '../router/types.js'; -import { ChainMap, ChainName } from '../types.js'; +import { ChainMap, ChainName, OwnableConfig } from '../types.js'; import { UpgradeConfig, @@ -45,7 +45,6 @@ import { proxyConstructorArgs, proxyImplementation, } from './proxy.js'; -import { OwnableConfig } from './types.js'; import { ContractVerifier } from './verify/ContractVerifier.js'; import { ContractVerificationInput, diff --git a/typescript/sdk/src/deploy/proxy.ts b/typescript/sdk/src/deploy/proxy.ts index ed9767225e..8749e433a9 100644 --- a/typescript/sdk/src/deploy/proxy.ts +++ b/typescript/sdk/src/deploy/proxy.ts @@ -5,8 +5,7 @@ import { Address, ChainId, eqAddress } from '@hyperlane-xyz/utils'; import { transferOwnershipTransactions } from '../contracts/contracts.js'; import { AnnotatedEV5Transaction } from '../providers/ProviderType.js'; - -import { DeployedOwnableConfig } from './types.js'; +import { DeployedOwnableConfig } from '../types.js'; export type UpgradeConfig = { timelock: { diff --git a/typescript/sdk/src/deploy/schemas.ts b/typescript/sdk/src/deploy/schemas.ts deleted file mode 100644 index 72d70947f9..0000000000 --- a/typescript/sdk/src/deploy/schemas.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { z } from 'zod'; - -export const OwnerSchema = z.string(); - -export const OwnableConfigSchema = z.object({ - owner: OwnerSchema, -}); - -export const ProxyFactoryFactoriesSchema = z.object({ - staticMerkleRootMultisigIsmFactory: z.string(), - staticMessageIdMultisigIsmFactory: z.string(), - staticAggregationIsmFactory: z.string(), - staticAggregationHookFactory: z.string(), - domainRoutingIsmFactory: z.string(), - staticMerkleRootWeightedMultisigIsmFactory: z.string(), - staticMessageIdWeightedMultisigIsmFactory: z.string(), -}); - -export type ProxyFactoryFactoriesAddresses = z.infer< - typeof ProxyFactoryFactoriesSchema ->; diff --git a/typescript/sdk/src/deploy/types.ts b/typescript/sdk/src/deploy/types.ts index c1612d10d2..62ba684d09 100644 --- a/typescript/sdk/src/deploy/types.ts +++ b/typescript/sdk/src/deploy/types.ts @@ -8,12 +8,21 @@ import type { } from '@hyperlane-xyz/core'; import { Address } from '@hyperlane-xyz/utils'; -import { DeployedOwnableSchema, OwnableSchema } from '../schemas.js'; import type { ChainName } from '../types.js'; -export type OwnableConfig = z.infer; +export const ProxyFactoryFactoriesSchema = z.object({ + staticMerkleRootMultisigIsmFactory: z.string(), + staticMessageIdMultisigIsmFactory: z.string(), + staticAggregationIsmFactory: z.string(), + staticAggregationHookFactory: z.string(), + domainRoutingIsmFactory: z.string(), + staticMerkleRootWeightedMultisigIsmFactory: z.string(), + staticMessageIdWeightedMultisigIsmFactory: z.string(), +}); -export type DeployedOwnableConfig = z.infer; +export type ProxyFactoryFactoriesAddresses = z.infer< + typeof ProxyFactoryFactoriesSchema +>; export interface CheckerViolation { chain: ChainName; diff --git a/typescript/sdk/src/deploy/verify/.eslintrc b/typescript/sdk/src/deploy/verify/.eslintrc deleted file mode 100644 index e3f712414b..0000000000 --- a/typescript/sdk/src/deploy/verify/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "no-console": ["off"] - } -} diff --git a/typescript/sdk/src/deploy/verify/ContractVerifier.ts b/typescript/sdk/src/deploy/verify/ContractVerifier.ts index 992d2de3b9..49ecd30980 100644 --- a/typescript/sdk/src/deploy/verify/ContractVerifier.ts +++ b/typescript/sdk/src/deploy/verify/ContractVerifier.ts @@ -183,7 +183,7 @@ export class ContractVerifier { 'Parsing response from explorer...', ); responseJson = JSON.parse(responseTextString); - } catch (error) { + } catch { verificationLogger.trace( { failure: response.statusText, diff --git a/typescript/sdk/src/gas/adapters/SealevelIgpAdapter.ts b/typescript/sdk/src/gas/adapters/SealevelIgpAdapter.ts index f3bbb1b4bc..1f0f1491fd 100644 --- a/typescript/sdk/src/gas/adapters/SealevelIgpAdapter.ts +++ b/typescript/sdk/src/gas/adapters/SealevelIgpAdapter.ts @@ -1,40 +1,122 @@ -import { PublicKey } from '@solana/web3.js'; -import { deserializeUnchecked } from 'borsh'; +import { + Message, + PublicKey, + SystemProgram, + TransactionInstruction, + VersionedTransaction, +} from '@solana/web3.js'; +import { deserializeUnchecked, serialize } from 'borsh'; -import { Address } from '@hyperlane-xyz/utils'; +import { Address, Domain, assert } from '@hyperlane-xyz/utils'; import { BaseSealevelAdapter } from '../../app/MultiProtocolApp.js'; import { MultiProtocolProvider } from '../../providers/MultiProtocolProvider.js'; import { ChainName } from '../../types.js'; -import { SealevelAccountDataWrapper } from '../../utils/sealevelSerialization.js'; +import { + SealevelAccountDataWrapper, + SealevelInstructionWrapper, +} from '../../utils/sealevelSerialization.js'; import { + SealeveIgpInstruction, + SealevelIgpQuoteGasPaymentInstruction, + SealevelIgpQuoteGasPaymentResponse, + SealevelIgpQuoteGasPaymentResponseSchema, + SealevelIgpQuoteGasPaymentSchema, SealevelOverheadIgpData, SealevelOverheadIgpDataSchema, } from './serialization.js'; -export class SealevelOverheadIgpAdapter extends BaseSealevelAdapter { +export interface IgpPaymentKeys { + programId: PublicKey; + igpAccount: PublicKey; + overheadIgpAccount?: PublicKey; +} + +export abstract class SealevelIgpProgramAdapter extends BaseSealevelAdapter { + protected readonly programId: PublicKey; + constructor( public readonly chainName: ChainName, public readonly multiProvider: MultiProtocolProvider, - public readonly addresses: { igp: Address }, + public readonly addresses: { programId: Address }, ) { super(chainName, multiProvider, addresses); + + this.programId = new PublicKey(addresses.programId); } - async getAccountInfo(): Promise { - const address = this.addresses.igp; + abstract getPaymentKeys(): Promise; + + // Simulating a transaction requires a payer to have sufficient balance to pay for tx fees. + async quoteGasPayment( + destination: Domain, + gasAmount: bigint, + payerKey: PublicKey, + ): Promise { + const paymentKeys = await this.getPaymentKeys(); + const keys = [ + // 0. `[executable]` The system program. + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + // 1. `[]` The IGP account. + { + pubkey: paymentKeys.igpAccount, + isSigner: false, + isWritable: false, + }, + ]; + if (paymentKeys.overheadIgpAccount) { + // 2. `[]` The overhead IGP account (optional). + keys.push({ + pubkey: paymentKeys.overheadIgpAccount, + isSigner: false, + isWritable: false, + }); + } + const value = new SealevelInstructionWrapper({ + instruction: SealeveIgpInstruction.QuoteGasPayment, + data: new SealevelIgpQuoteGasPaymentInstruction({ + destination_domain: destination, + gas_amount: BigInt(gasAmount), + }), + }); + const quoteGasPaymentInstruction = new TransactionInstruction({ + keys, + programId: this.programId, + data: Buffer.from(serialize(SealevelIgpQuoteGasPaymentSchema, value)), + }); + + const message = Message.compile({ + // This is ignored + recentBlockhash: PublicKey.default.toBase58(), + instructions: [quoteGasPaymentInstruction], + payerKey, + }); + + const tx = new VersionedTransaction(message); + const connection = this.getProvider(); + const simulationResponse = await connection.simulateTransaction(tx, { + // ignore the recent blockhash we pass in, and have the node use its latest one + replaceRecentBlockhash: true, + // ignore signature verification + sigVerify: false, + }); - const accountInfo = await connection.getAccountInfo(new PublicKey(address)); - if (!accountInfo) throw new Error(`No account info found for ${address}}`); + const base64Data = simulationResponse.value.returnData?.data?.[0]; + assert( + base64Data, + 'No return data when quoting gas payment, may happen if the payer has insufficient funds', + ); - const accountData = deserializeUnchecked( - SealevelOverheadIgpDataSchema, - SealevelAccountDataWrapper, - accountInfo.data, + const data = Buffer.from(base64Data, 'base64'); + const quote = deserializeUnchecked( + SealevelIgpQuoteGasPaymentResponseSchema, + SealevelIgpQuoteGasPaymentResponse, + data, ); - return accountData.data as SealevelOverheadIgpData; + + return quote.payment_quote; } // https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/rust/sealevel/programs/hyperlane-sealevel-igp/src/pda_seeds.rs#L7 @@ -56,3 +138,62 @@ export class SealevelOverheadIgpAdapter extends BaseSealevelAdapter { ); } } + +export class SealevelIgpAdapter extends SealevelIgpProgramAdapter { + protected readonly igp: PublicKey; + + constructor( + public readonly chainName: ChainName, + public readonly multiProvider: MultiProtocolProvider, + public readonly addresses: { igp: Address; programId: Address }, + ) { + super(chainName, multiProvider, addresses); + + this.igp = new PublicKey(addresses.igp); + } + + override async getPaymentKeys(): Promise { + return { + programId: this.programId, + igpAccount: this.igp, + }; + } +} + +export class SealevelOverheadIgpAdapter extends SealevelIgpProgramAdapter { + protected readonly overheadIgp: PublicKey; + + constructor( + public readonly chainName: ChainName, + public readonly multiProvider: MultiProtocolProvider, + public readonly addresses: { overheadIgp: Address; programId: Address }, + ) { + super(chainName, multiProvider, addresses); + + this.overheadIgp = new PublicKey(addresses.overheadIgp); + } + + async getAccountInfo(): Promise { + const address = this.addresses.overheadIgp; + const connection = this.getProvider(); + + const accountInfo = await connection.getAccountInfo(new PublicKey(address)); + assert(accountInfo, `No account info found for ${address}}`); + + const accountData = deserializeUnchecked( + SealevelOverheadIgpDataSchema, + SealevelAccountDataWrapper, + accountInfo.data, + ); + return accountData.data as SealevelOverheadIgpData; + } + + override async getPaymentKeys(): Promise { + const igpData = await this.getAccountInfo(); + return { + programId: this.programId, + igpAccount: igpData.inner_pub_key, + overheadIgpAccount: this.overheadIgp, + }; + } +} diff --git a/typescript/sdk/src/gas/adapters/serialization.ts b/typescript/sdk/src/gas/adapters/serialization.ts index 70cd808259..5e084bec03 100644 --- a/typescript/sdk/src/gas/adapters/serialization.ts +++ b/typescript/sdk/src/gas/adapters/serialization.ts @@ -1,11 +1,12 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { PublicKey } from '@solana/web3.js'; import { Domain } from '@hyperlane-xyz/utils'; import { SealevelAccountDataWrapper, + SealevelInstructionWrapper, getSealevelAccountDataSchema, + getSealevelSimulationReturnDataSchema, } from '../../utils/sealevelSerialization.js'; // Should match https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/rust/sealevel/programs/hyperlane-sealevel-igp/src/accounts.rs#L24 @@ -90,3 +91,74 @@ export const SealevelOverheadIgpDataSchema = new Map([ }, ], ]); + +/** + * IGP instruction Borsh Schema + */ + +// Should match Instruction in https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/8f8853bcd7105a6dd7af3a45c413b137ded6e888/rust/sealevel/programs/hyperlane-sealevel-igp/src/instruction.rs#L19-L42 +export enum SealeveIgpInstruction { + Init, + InitIgp, + InitOverheadIgp, + PayForGas, + QuoteGasPayment, + TransferIgpOwnership, + TransferOverheadIgpOwnership, + SetIgpBeneficiary, + SetDestinationGasOverheads, + SetGasOracleConfigs, + Claim, +} + +export class SealevelIgpQuoteGasPaymentInstruction { + destination_domain!: number; + gas_amount!: bigint; + constructor(public readonly fields: any) { + Object.assign(this, fields); + } +} + +export const SealevelIgpQuoteGasPaymentSchema = new Map([ + [ + SealevelInstructionWrapper, + { + kind: 'struct', + fields: [ + ['instruction', 'u8'], + ['data', SealevelIgpQuoteGasPaymentInstruction], + ], + }, + ], + [ + SealevelIgpQuoteGasPaymentInstruction, + { + kind: 'struct', + fields: [ + ['destination_domain', 'u32'], + ['gas_amount', 'u64'], + ], + }, + ], +]); + +export class SealevelIgpQuoteGasPaymentResponse { + payment_quote!: bigint; + constructor(public readonly fields: any) { + Object.assign(this, fields); + } +} + +export const SealevelIgpQuoteGasPaymentResponseSchema = new Map([ + [ + SealevelAccountDataWrapper, + getSealevelSimulationReturnDataSchema(SealevelIgpQuoteGasPaymentResponse), + ], + [ + SealevelIgpQuoteGasPaymentResponse, + { + kind: 'struct', + fields: [['payment_quote', 'u64']], + }, + ], +]); diff --git a/typescript/sdk/src/gas/types.ts b/typescript/sdk/src/gas/types.ts index 55114478d2..6cb46630eb 100644 --- a/typescript/sdk/src/gas/types.ts +++ b/typescript/sdk/src/gas/types.ts @@ -5,7 +5,7 @@ import { InterchainGasPaymaster } from '@hyperlane-xyz/core'; import type { Address } from '@hyperlane-xyz/utils'; import type { CheckerViolation } from '../deploy/types.js'; -import { IgpSchema } from '../hook/schemas.js'; +import { IgpSchema } from '../hook/types.js'; import { ChainMap } from '../types.js'; export type IgpConfig = z.infer; diff --git a/typescript/sdk/src/gcp/storage.ts b/typescript/sdk/src/gcp/storage.ts new file mode 100644 index 0000000000..96c2a3fd71 --- /dev/null +++ b/typescript/sdk/src/gcp/storage.ts @@ -0,0 +1,91 @@ +import { Storage } from '@google-cloud/storage'; + +export const GCS_BUCKET_REGEX = + /^(?:(?:https?:\/\/)?([^/]+)\.storage\.googleapis\.com\/?|gs:\/\/([^/]+))$/; + +export interface StorageReceipt { + data: T; + modified: Date; +} + +export interface StorageConfig { + bucket: string; + folder?: string; + caching?: boolean; + // Optional credentials config + projectId?: string; + keyFilename?: string; +} + +export class GcpStorageWrapper { + private readonly client: Storage; + private readonly bucket: string; + private cache: Record> | undefined; + + static fromBucketUrl(bucketUrl: string): GcpStorageWrapper { + const match = bucketUrl.match(GCS_BUCKET_REGEX); + if (!match) throw new Error('Could not parse bucket url'); + return new GcpStorageWrapper({ + bucket: match[1], + caching: true, + }); + } + + constructor(readonly config: StorageConfig) { + this.client = new Storage({ + projectId: config.projectId, + keyFilename: config.keyFilename, + }); + this.bucket = config.bucket; + if (config.caching) { + this.cache = {}; + } + } + + formatKey(key: string): string { + return this.config.folder ? `${this.config.folder}/${key}` : key; + } + + async getObject(key: string): Promise | undefined> { + const Key = this.formatKey(key); + if (this.cache?.[Key]) { + return this.cache![Key]; + } + + try { + const bucket = this.client.bucket(this.bucket); + const file = bucket.file(Key); + const [exists] = await file.exists(); + + if (!exists) { + return undefined; + } + + const [metadata] = await file.getMetadata(); + const [contents] = await file.download(); + const body = contents.toString('utf-8'); + + const result = { + data: JSON.parse(body), + // If no updated date is provided, use the Unix epoch start + // 0 = Unix epoch start (1970-01-01T00:00:00.000Z) + modified: new Date(metadata.updated ?? 0), + }; + + if (this.cache) { + this.cache[Key] = result; + } + return result; + } catch (e: any) { + if (e.code === 404) { + return undefined; + } + throw e; + } + } + + url(key: string): string { + const formattedKey = this.formatKey(key); + return `https://storage.googleapis.com/${this.bucket}/${formattedKey}`; + } +} diff --git a/typescript/sdk/src/gcp/validator.ts b/typescript/sdk/src/gcp/validator.ts new file mode 100644 index 0000000000..e335ca2706 --- /dev/null +++ b/typescript/sdk/src/gcp/validator.ts @@ -0,0 +1,132 @@ +import { + Announcement, + BaseValidator, + S3Announcement, + S3CheckpointWithId, + ValidatorConfig, + ValidatorMetadata, + isS3CheckpointWithId, +} from '@hyperlane-xyz/utils'; + +import { GcpStorageWrapper, StorageConfig } from './storage.js'; + +const checkpointWithMessageIdKey = (checkpointIndex: number) => + `checkpoint_${checkpointIndex}_with_id.json`; +const LATEST_KEY = 'gcsLatestIndexKey'; +const ANNOUNCEMENT_KEY = 'gcsAnnouncementKey'; +const METADATA_KEY = 'gcsMetadataKey'; +export const GCP_LOCATION_PREFIX = 'gs://'; + +/** + * Extension of BaseValidator that includes GCP Cloud Storage utilities. + */ +export class GcpValidator extends BaseValidator { + public storage: GcpStorageWrapper; + + constructor( + public validatorConfig: ValidatorConfig, + public storageConfig: StorageConfig, + ) { + super(validatorConfig); + this.storage = new GcpStorageWrapper(storageConfig); + } + + static async fromStorageLocation( + storageLocation: string, + ): Promise { + // Remove trailing key if present + if (storageLocation.endsWith(ANNOUNCEMENT_KEY)) { + storageLocation = storageLocation.slice(0, -ANNOUNCEMENT_KEY.length); + // Remove trailing slash if present after removing key + if (storageLocation.endsWith('/')) { + storageLocation = storageLocation.slice(0, -1); + } + } + if (storageLocation.startsWith(GCP_LOCATION_PREFIX)) { + const bucketName = storageLocation.slice(GCP_LOCATION_PREFIX.length); + const pieces = bucketName.split('/'); + if (pieces.length >= 1) { + const storageFolder = + pieces.length > 1 ? pieces.slice(1).join('/') : undefined; + const storageConfig = { + bucket: pieces[0], + folder: storageFolder, + caching: true, + }; + const storage = new GcpStorageWrapper(storageConfig); + const announcement = await storage.getObject( + ANNOUNCEMENT_KEY, + ); + if (!announcement) { + throw new Error('No announcement found'); + } + + const validatorConfig = { + address: announcement.data.value.validator, + localDomain: announcement.data.value.mailbox_domain, + mailbox: announcement.data.value.mailbox_address, + }; + + return new GcpValidator(validatorConfig, storageConfig); + } + } + throw new Error(`Unable to parse location ${storageLocation}`); + } + + async getAnnouncement(): Promise { + const { value } = await this.getSignedAnnouncement(); + return value; + } + + async getSignedAnnouncement(): Promise { + const resp = await this.storage.getObject(ANNOUNCEMENT_KEY); + if (!resp) { + throw new Error(`No announcement found for ${this.config.localDomain}`); + } + + return resp.data; + } + + async getMetadata(): Promise { + const resp = await this.storage.getObject(METADATA_KEY); + if (!resp) { + throw new Error(`No metadata found for ${this.config.localDomain}`); + } + + return resp.data; + } + + async getCheckpoint(index: number): Promise { + const key = checkpointWithMessageIdKey(index); + const checkpoint = await this.storage.getObject(key); + if (!checkpoint) { + return; + } + + if (isS3CheckpointWithId(checkpoint.data)) { + return checkpoint.data; + } else { + throw new Error('Failed to parse checkpoint'); + } + } + + async getLatestCheckpointIndex(): Promise { + const latestCheckpointIndex = await this.storage.getObject( + LATEST_KEY, + ); + + if (!latestCheckpointIndex) return -1; + + return latestCheckpointIndex.data; + } + + storageLocation(): string { + return `${GCP_LOCATION_PREFIX}${this.storage.config.bucket}${ + this.storage.config.folder ? '/' + this.storage.config.folder : '' + }`; + } + + getLatestCheckpointUrl(): string { + return this.storage.url(LATEST_KEY); + } +} diff --git a/typescript/sdk/src/hook/EvmHookModule.hardhat-test.ts b/typescript/sdk/src/hook/EvmHookModule.hardhat-test.ts index aa4c9d559d..ae66d7adbf 100644 --- a/typescript/sdk/src/hook/EvmHookModule.hardhat-test.ts +++ b/typescript/sdk/src/hook/EvmHookModule.hardhat-test.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ import { expect } from 'chai'; import { Signer } from 'ethers'; import hre from 'hardhat'; diff --git a/typescript/sdk/src/hook/EvmHookModule.ts b/typescript/sdk/src/hook/EvmHookModule.ts index 5f6a64e344..eddbb1c788 100644 --- a/typescript/sdk/src/hook/EvmHookModule.ts +++ b/typescript/sdk/src/hook/EvmHookModule.ts @@ -56,13 +56,13 @@ import { normalizeConfig } from '../utils/ism.js'; import { EvmHookReader } from './EvmHookReader.js'; import { DeployedHook, HookFactories, hookFactories } from './contracts.js'; -import { HookConfigSchema } from './schemas.js'; import { AggregationHookConfig, ArbL2ToL1HookConfig, DomainRoutingHookConfig, FallbackRoutingHookConfig, HookConfig, + HookConfigSchema, HookType, IgpHookConfig, MUTABLE_HOOK_TYPE, @@ -104,7 +104,7 @@ export class EvmHookModule extends HyperlaneModule< // Transaction overrides for the chain protected readonly txOverrides: Partial; - protected constructor( + constructor( protected readonly multiProvider: MultiProvider, params: HyperlaneModuleParams< HookConfig, @@ -243,7 +243,7 @@ export class EvmHookModule extends HyperlaneModule< chain: ChainNameOrId; config: HookConfig; proxyFactoryFactories: HyperlaneAddresses; - coreAddresses: CoreAddresses; + coreAddresses: Omit; multiProvider: MultiProvider; contractVerifier?: ContractVerifier; }): Promise { diff --git a/typescript/sdk/src/hook/EvmHookReader.test.ts b/typescript/sdk/src/hook/EvmHookReader.test.ts index befd73a431..3a8bb45763 100644 --- a/typescript/sdk/src/hook/EvmHookReader.test.ts +++ b/typescript/sdk/src/hook/EvmHookReader.test.ts @@ -148,7 +148,6 @@ describe('EvmHookReader', () => { expect(config).to.deep.equal(hookConfig); }); - // eslint-disable-next-line @typescript-eslint/no-empty-function it('should derive op stack config correctly', async () => { const mockAddress = randomAddress(); const mockOwner = randomAddress(); diff --git a/typescript/sdk/src/hook/EvmHookReader.ts b/typescript/sdk/src/hook/EvmHookReader.ts index 9ebcd8ae03..dae0f9d589 100644 --- a/typescript/sdk/src/hook/EvmHookReader.ts +++ b/typescript/sdk/src/hook/EvmHookReader.ts @@ -269,7 +269,7 @@ export class EvmHookReader extends HyperlaneReader implements HookReader { this.provider, ); return oracle.owner(); - } catch (error) { + } catch { this.logger.debug( 'Domain not configured on IGP Hook', domainId, @@ -451,7 +451,7 @@ export class EvmHookReader extends HyperlaneReader implements HookReader { if (domainHook !== ethers.constants.AddressZero) { domainHooks[chainName] = await this.deriveHookConfig(domainHook); } - } catch (error) { + } catch { this.logger.debug( `Domain not configured on ${hook.constructor.name}`, domainId, diff --git a/typescript/sdk/src/hook/schemas.ts b/typescript/sdk/src/hook/schemas.ts deleted file mode 100644 index 16bd01b27f..0000000000 --- a/typescript/sdk/src/hook/schemas.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { z } from 'zod'; - -import { StorageGasOracleConfigSchema } from '../gas/oracle/types.js'; -import { ZHash } from '../metadata/customZodTypes.js'; -import { OwnableSchema, PausableSchema } from '../schemas.js'; - -import { - AggregationHookConfig, - DomainRoutingHookConfig, - FallbackRoutingHookConfig, - HookType, -} from './types.js'; - -export const ProtocolFeeSchema = OwnableSchema.extend({ - type: z.literal(HookType.PROTOCOL_FEE), - beneficiary: z.string(), - maxProtocolFee: z.string(), - protocolFee: z.string(), -}); - -export const MerkleTreeSchema = z.object({ - type: z.literal(HookType.MERKLE_TREE), -}); - -export const PausableHookSchema = PausableSchema.extend({ - type: z.literal(HookType.PAUSABLE), -}); - -export const OpStackHookSchema = OwnableSchema.extend({ - type: z.literal(HookType.OP_STACK), - nativeBridge: z.string(), - destinationChain: z.string(), -}); - -export const ArbL2ToL1HookSchema = z.object({ - type: z.literal(HookType.ARB_L2_TO_L1), - arbSys: z - .string() - .describe( - 'precompile for sending messages to L1, interface here: https://github.com/OffchainLabs/nitro-contracts/blob/90037b996509312ef1addb3f9352457b8a99d6a6/src/precompiles/ArbSys.sol#L12', - ), - bridge: z - .string() - .optional() - .describe( - 'address of the bridge contract on L1, optional only needed for non @arbitrum/sdk chains', - ), - destinationChain: z.string(), - childHook: z.lazy((): z.ZodSchema => HookConfigSchema), -}); - -export const IgpSchema = OwnableSchema.extend({ - type: z.literal(HookType.INTERCHAIN_GAS_PAYMASTER), - beneficiary: z.string(), - oracleKey: z.string(), - overhead: z.record(z.number()), - oracleConfig: z.record(StorageGasOracleConfigSchema), -}); - -export const DomainRoutingHookConfigSchema: z.ZodSchema = - z.lazy(() => - OwnableSchema.extend({ - type: z.literal(HookType.ROUTING), - domains: z.record(HookConfigSchema), - }), - ); - -export const FallbackRoutingHookConfigSchema: z.ZodSchema = - z.lazy(() => - OwnableSchema.extend({ - type: z.literal(HookType.FALLBACK_ROUTING), - domains: z.record(HookConfigSchema), - fallback: HookConfigSchema, - }), - ); - -export const AggregationHookConfigSchema: z.ZodSchema = - z.lazy(() => - z.object({ - type: z.literal(HookType.AGGREGATION), - hooks: z.array(HookConfigSchema), - }), - ); - -export const HookConfigSchema = z.union([ - ZHash, - ProtocolFeeSchema, - PausableHookSchema, - OpStackHookSchema, - MerkleTreeSchema, - IgpSchema, - DomainRoutingHookConfigSchema, - FallbackRoutingHookConfigSchema, - AggregationHookConfigSchema, - ArbL2ToL1HookSchema, -]); diff --git a/typescript/sdk/src/hook/types.ts b/typescript/sdk/src/hook/types.ts index 01d5b0df74..768e93134b 100644 --- a/typescript/sdk/src/hook/types.ts +++ b/typescript/sdk/src/hook/types.ts @@ -1,17 +1,13 @@ import { z } from 'zod'; -import { OwnableConfig } from '../deploy/types.js'; -import { ChainMap } from '../types.js'; - +import { StorageGasOracleConfigSchema } from '../gas/oracle/types.js'; +import { ZHash } from '../metadata/customZodTypes.js'; import { - ArbL2ToL1HookSchema, - HookConfigSchema, - IgpSchema, - MerkleTreeSchema, - OpStackHookSchema, - PausableHookSchema, - ProtocolFeeSchema, -} from './schemas.js'; + ChainMap, + OwnableConfig, + OwnableSchema, + PausableSchema, +} from '../types.js'; // As found in IPostDispatchHook.sol export enum OnchainHookType { @@ -75,3 +71,87 @@ export const MUTABLE_HOOK_TYPE = [ HookType.FALLBACK_ROUTING, HookType.PAUSABLE, ]; + +export const ProtocolFeeSchema = OwnableSchema.extend({ + type: z.literal(HookType.PROTOCOL_FEE), + beneficiary: z.string(), + maxProtocolFee: z.string(), + protocolFee: z.string(), +}); + +export const MerkleTreeSchema = z.object({ + type: z.literal(HookType.MERKLE_TREE), +}); + +export const PausableHookSchema = PausableSchema.extend({ + type: z.literal(HookType.PAUSABLE), +}); + +export const OpStackHookSchema = OwnableSchema.extend({ + type: z.literal(HookType.OP_STACK), + nativeBridge: z.string(), + destinationChain: z.string(), +}); + +export const ArbL2ToL1HookSchema = z.object({ + type: z.literal(HookType.ARB_L2_TO_L1), + arbSys: z + .string() + .describe( + 'precompile for sending messages to L1, interface here: https://github.com/OffchainLabs/nitro-contracts/blob/90037b996509312ef1addb3f9352457b8a99d6a6/src/precompiles/ArbSys.sol#L12', + ), + bridge: z + .string() + .optional() + .describe( + 'address of the bridge contract on L1, optional only needed for non @arbitrum/sdk chains', + ), + destinationChain: z.string(), + childHook: z.lazy((): z.ZodSchema => HookConfigSchema), +}); + +export const IgpSchema = OwnableSchema.extend({ + type: z.literal(HookType.INTERCHAIN_GAS_PAYMASTER), + beneficiary: z.string(), + oracleKey: z.string(), + overhead: z.record(z.number()), + oracleConfig: z.record(StorageGasOracleConfigSchema), +}); + +export const DomainRoutingHookConfigSchema: z.ZodSchema = + z.lazy(() => + OwnableSchema.extend({ + type: z.literal(HookType.ROUTING), + domains: z.record(HookConfigSchema), + }), + ); + +export const FallbackRoutingHookConfigSchema: z.ZodSchema = + z.lazy(() => + OwnableSchema.extend({ + type: z.literal(HookType.FALLBACK_ROUTING), + domains: z.record(HookConfigSchema), + fallback: HookConfigSchema, + }), + ); + +export const AggregationHookConfigSchema: z.ZodSchema = + z.lazy(() => + z.object({ + type: z.literal(HookType.AGGREGATION), + hooks: z.array(HookConfigSchema), + }), + ); + +export const HookConfigSchema = z.union([ + ZHash, + ProtocolFeeSchema, + PausableHookSchema, + OpStackHookSchema, + MerkleTreeSchema, + IgpSchema, + DomainRoutingHookConfigSchema, + FallbackRoutingHookConfigSchema, + AggregationHookConfigSchema, + ArbL2ToL1HookSchema, +]); diff --git a/typescript/sdk/src/ica/EvmIcaReader.hardhat-test.ts b/typescript/sdk/src/ica/EvmIcaReader.hardhat-test.ts new file mode 100644 index 0000000000..59d3a56f41 --- /dev/null +++ b/typescript/sdk/src/ica/EvmIcaReader.hardhat-test.ts @@ -0,0 +1,57 @@ +import { expect } from 'chai'; +import hre from 'hardhat'; + +import { Address, isAddressEvm } from '@hyperlane-xyz/utils'; + +import { TestChainName } from '../consts/testChains.js'; +import { EvmCoreModule } from '../core/EvmCoreModule.js'; +import { CoreConfig } from '../core/types.js'; +import { MultiProvider } from '../providers/MultiProvider.js'; +import { testCoreConfig } from '../test/testUtils.js'; + +import { EvmIcaRouterReader } from './EvmIcaReader.js'; + +describe(EvmIcaRouterReader.name, async () => { + const CHAIN = TestChainName.test4; + let interchainAccountRouterAddress: Address; + let interchainAccountRouterReader: EvmIcaRouterReader; + let signerAddress: Address; + + before(async () => { + const [signer] = await hre.ethers.getSigners(); + const multiProvider = MultiProvider.createTestMultiProvider({ signer }); + const config: CoreConfig = { + ...testCoreConfig([CHAIN])[CHAIN], + owner: signer.address, + }; + + const addresses = await EvmCoreModule.deploy({ + chain: CHAIN, + config, + multiProvider, + }); + + signerAddress = signer.address; + interchainAccountRouterAddress = addresses.interchainAccountRouter; + interchainAccountRouterReader = new EvmIcaRouterReader( + multiProvider.getProvider(CHAIN), + ); + }); + + describe(EvmIcaRouterReader.prototype.deriveConfig.name, async () => { + it('should read the ICA router config', async () => { + const res = await interchainAccountRouterReader.deriveConfig( + interchainAccountRouterAddress, + ); + + expect(res.address).to.equal(interchainAccountRouterAddress); + expect(res.owner).to.equal(signerAddress); + // Proxy admin checks + expect(res.proxyAdmin.address).to.exist; + expect(isAddressEvm(res.proxyAdmin.address)).to.be.true; + expect(res.proxyAdmin.owner).to.equal(signerAddress); + // Remote ICA Routers + expect(res.remoteIcaRouters).to.exist; + }); + }); +}); diff --git a/typescript/sdk/src/ica/EvmIcaReader.ts b/typescript/sdk/src/ica/EvmIcaReader.ts new file mode 100644 index 0000000000..1ee29896b1 --- /dev/null +++ b/typescript/sdk/src/ica/EvmIcaReader.ts @@ -0,0 +1,83 @@ +import { providers } from 'ethers'; + +import { + InterchainAccountRouter, + InterchainAccountRouter__factory, + Ownable__factory, +} from '@hyperlane-xyz/core'; +import { Address, Domain, isZeroishAddress } from '@hyperlane-xyz/utils'; + +import { proxyAdmin } from '../deploy/proxy.js'; + +import { + DerivedIcaRouterConfig, + DerivedIcaRouterConfigSchema, +} from './types.js'; + +export class EvmIcaRouterReader { + constructor(private readonly provider: providers.Provider) {} + + public async deriveConfig(address: Address): Promise { + const icaRouterInstance = InterchainAccountRouter__factory.connect( + address, + this.provider, + ); + const owner = await icaRouterInstance.owner(); + const proxyAddress = await proxyAdmin(this.provider, address); + + const proxyAdminInstance = Ownable__factory.connect( + proxyAddress, + this.provider, + ); + const [proxyAdminOwner, knownDomains, mailboxAddress] = await Promise.all([ + proxyAdminInstance.owner(), + icaRouterInstance.domains(), + icaRouterInstance.mailbox(), + ]); + + const remoteRouters = await this.deriveRemoteRoutersConfig( + icaRouterInstance, + knownDomains, + ); + + const rawConfig: DerivedIcaRouterConfig = { + owner, + address, + mailbox: mailboxAddress, + proxyAdmin: { + address: proxyAddress, + owner: proxyAdminOwner, + }, + remoteIcaRouters: remoteRouters, + }; + + return DerivedIcaRouterConfigSchema.parse(rawConfig); + } + + private async deriveRemoteRoutersConfig( + icaRouterInstance: InterchainAccountRouter, + knownDomains: ReadonlyArray, + ): Promise { + const remoteIcaRoutersConfig = await Promise.all( + knownDomains.map((domainId: Domain) => { + return Promise.all([ + icaRouterInstance.routers(domainId), + icaRouterInstance.isms(domainId), + ]); + }), + ); + + const res: DerivedIcaRouterConfig['remoteIcaRouters'] = {}; + return knownDomains.reduce((acc, curr, idx) => { + const remoteRouter = remoteIcaRoutersConfig[idx][0]; + const ism = remoteIcaRoutersConfig[idx][1]; + + acc[curr.toString()] = { + address: remoteRouter, + interchainSecurityModule: isZeroishAddress(ism) ? undefined : ism, + }; + + return acc; + }, res); + } +} diff --git a/typescript/sdk/src/ica/types.ts b/typescript/sdk/src/ica/types.ts new file mode 100644 index 0000000000..4c44c9f446 --- /dev/null +++ b/typescript/sdk/src/ica/types.ts @@ -0,0 +1,43 @@ +import { z } from 'zod'; + +import { ZHash } from '../metadata/customZodTypes.js'; +import { RemoteRouterDomain, RemoteRouterRouter } from '../router/types.js'; +import { DerivedOwnableSchema } from '../types.js'; + +export const RemoteIcaRouterConfigSchema = z.record( + RemoteRouterDomain, + RemoteRouterRouter.merge( + z.object({ + interchainSecurityModule: ZHash.optional().describe( + 'Optional ISM override to be used on the chain', + ), + }), + ), +); + +export const IcaRouterConfigSchema = z.object({ + owner: ZHash, + mailbox: ZHash, + proxyAdmin: z.object({ + address: ZHash.optional(), + owner: ZHash, + }), + remoteIcaRouters: RemoteIcaRouterConfigSchema.optional(), +}); + +export type IcaRouterConfig = z.infer; + +export const DerivedIcaRouterConfigSchema = DerivedOwnableSchema.merge( + z + .object({ + owner: ZHash, + mailbox: ZHash, + proxyAdmin: DerivedOwnableSchema, + remoteIcaRouters: RemoteIcaRouterConfigSchema, + }) + .strict(), +); + +export type DerivedIcaRouterConfig = z.infer< + typeof DerivedIcaRouterConfigSchema +>; diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index 1c2146b793..ad8c6c4870 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -13,7 +13,10 @@ export { TOKEN_EXCHANGE_RATE_SCALE, } from './consts/igp.js'; export { MAILBOX_VERSION } from './consts/mailbox.js'; -export { defaultMultisigConfigs } from './consts/multisigIsm.js'; +export { + AW_VALIDATOR_ALIAS, + defaultMultisigConfigs, +} from './consts/multisigIsm.js'; export { SEALEVEL_SPL_NOOP_ADDRESS } from './consts/sealevel.js'; export { TestChainName, @@ -67,11 +70,6 @@ export { RelayerCacheSchema, } from './core/HyperlaneRelayer.js'; export { MultiProtocolCore } from './core/MultiProtocolCore.js'; -export { - CoreConfigSchema, - DeployedCoreAddresses, - DeployedCoreAddressesSchema, -} from './core/schemas.js'; export { TestCoreApp } from './core/TestCoreApp.js'; export { TestCoreDeployer } from './core/TestCoreDeployer.js'; export { @@ -80,7 +78,12 @@ export { } from './core/TestRecipientDeployer.js'; export { CoreConfig, + CoreConfigSchema, CoreViolationType, + DeployedCoreAddresses, + DeployedCoreAddressesSchema, + DerivedCoreConfig, + DerivedCoreConfigSchema, DispatchedMessage, MailboxMultisigIsmViolation, MailboxViolation, @@ -95,10 +98,10 @@ export { export { HyperlaneProxyFactoryDeployer } from './deploy/HyperlaneProxyFactoryDeployer.js'; export { CheckerViolation, - DeployedOwnableConfig, - OwnableConfig, OwnerViolation, ProxyAdminViolation, + ProxyFactoryFactoriesAddresses, + ProxyFactoryFactoriesSchema, ViolationType, } from './deploy/types.js'; export { ContractVerifier } from './deploy/verify/ContractVerifier.js'; @@ -123,7 +126,10 @@ export { IgpFactories, igpFactories } from './gas/contracts.js'; export { HyperlaneIgp } from './gas/HyperlaneIgp.js'; export { HyperlaneIgpChecker } from './gas/HyperlaneIgpChecker.js'; export { HyperlaneIgpDeployer } from './gas/HyperlaneIgpDeployer.js'; -export { StorageGasOracleConfig } from './gas/oracle/types.js'; +export { + StorageGasOracleConfig, + StorageGasOracleConfigSchema, +} from './gas/oracle/types.js'; export { CoinGeckoTokenPriceGetter } from './gas/token-prices.js'; export { IgpBeneficiaryViolation, @@ -135,38 +141,64 @@ export { } from './gas/types.js'; export { EvmHookReader } from './hook/EvmHookReader.js'; export { HyperlaneHookDeployer } from './hook/HyperlaneHookDeployer.js'; -export { HookConfigSchema } from './hook/schemas.js'; export { AggregationHookConfig, + AggregationHookConfigSchema, + ArbL2ToL1HookConfig, + ArbL2ToL1HookSchema, DomainRoutingHookConfig, + DomainRoutingHookConfigSchema, FallbackRoutingHookConfig, + FallbackRoutingHookConfigSchema, HookConfig, + HookConfigSchema, HookType, IgpHookConfig, + IgpSchema, MerkleTreeHookConfig, + MerkleTreeSchema, OpStackHookConfig, + OpStackHookSchema, PausableHookConfig, + PausableHookSchema, ProtocolFeeHookConfig, + ProtocolFeeSchema, } from './hook/types.js'; -export { EvmIsmReader } from './ism/EvmIsmReader.js'; +export { DerivedIsmConfig, EvmIsmReader } from './ism/EvmIsmReader.js'; export { HyperlaneIsmFactory } from './ism/HyperlaneIsmFactory.js'; +export { decodeIsmMetadata } from './ism/metadata/decode.js'; export { buildAggregationIsmConfigs, buildMultisigIsmConfigs, + multisigConfigToIsmConfig, } from './ism/multisig.js'; export { AggregationIsmConfig, + AggregationIsmConfigSchema, + ArbL2ToL1IsmConfig, + ArbL2ToL1IsmConfigSchema, DeployedIsm, + DeployedIsmType, + DomainRoutingIsmConfig, + IcaRoutingIsmConfig, IsmConfig, + IsmConfigSchema, IsmType, ModuleType, MultisigConfig, + MultisigConfigSchema, MultisigIsmConfig, + MultisigIsmConfigSchema, OpStackIsmConfig, + OpStackIsmConfigSchema, PausableIsmConfig, + PausableIsmConfigSchema, RoutingIsmConfig, + RoutingIsmConfigSchema, TrustedRelayerIsmConfig, + TrustedRelayerIsmConfigSchema, WeightedMultisigIsmConfig, + WeightedMultisigIsmConfigSchema, } from './ism/types.js'; export { collectValidators, moduleCanCertainlyVerify } from './ism/utils.js'; export { @@ -234,13 +266,11 @@ export { InterchainAccountConfig, InterchainAccountDeployer, } from './middleware/account/InterchainAccountDeployer.js'; -export { - AccountConfigSchema, - GetCallRemoteSettingsSchema, -} from './middleware/account/schemas.js'; export { AccountConfig, + AccountConfigSchema, GetCallRemoteSettings, + GetCallRemoteSettingsSchema, } from './middleware/account/types.js'; export { liquidityLayerFactories } from './middleware/liquidity-layer/contracts.js'; export { LiquidityLayerApp } from './middleware/liquidity-layer/LiquidityLayerApp.js'; @@ -327,31 +357,29 @@ export { ProviderRetryOptions, SmartProviderOptions, } from './providers/SmartProvider/types.js'; -export { CallData } from './providers/transactions/types.js'; +export { CallData, CallDataSchema } from './providers/transactions/types.js'; export { randomAddress } from './test/testUtils.js'; -export { SubmitterMetadataSchema } from './providers/transactions/submitter/schemas.js'; export { TxSubmitterInterface } from './providers/transactions/submitter/TxSubmitterInterface.js'; export { TxSubmitterType } from './providers/transactions/submitter/TxSubmitterTypes.js'; -export { SubmitterMetadata } from './providers/transactions/submitter/types.js'; - export { - EV5GnosisSafeTxSubmitterPropsSchema, - EV5ImpersonatedAccountTxSubmitterPropsSchema, -} from './providers/transactions/submitter/ethersV5/schemas.js'; + SubmitterMetadata, + SubmitterMetadataSchema, +} from './providers/transactions/submitter/types.js'; + export { EV5GnosisSafeTxSubmitterProps, + EV5GnosisSafeTxSubmitterPropsSchema, EV5ImpersonatedAccountTxSubmitterProps, + EV5ImpersonatedAccountTxSubmitterPropsSchema, } from './providers/transactions/submitter/ethersV5/types.js'; -export { - ChainSubmissionStrategySchema, - SubmissionStrategySchema, -} from './providers/transactions/submitter/builder/schemas.js'; export { TxSubmitterBuilder } from './providers/transactions/submitter/builder/TxSubmitterBuilder.js'; export { ChainSubmissionStrategy, + ChainSubmissionStrategySchema, SubmissionStrategy, + SubmissionStrategySchema, } from './providers/transactions/submitter/builder/types.js'; export { EV5GnosisSafeTxBuilder } from './providers/transactions/submitter/ethersV5/EV5GnosisSafeTxBuilder.js'; @@ -360,20 +388,50 @@ export { EV5ImpersonatedAccountTxSubmitter } from './providers/transactions/subm export { EV5JsonRpcTxSubmitter } from './providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.js'; export { EV5TxSubmitterInterface } from './providers/transactions/submitter/ethersV5/EV5TxSubmitterInterface.js'; -export { TransformerMetadataSchema } from './providers/transactions/transformer/schemas.js'; export { TxTransformerInterface } from './providers/transactions/transformer/TxTransformerInterface.js'; export { TxTransformerType } from './providers/transactions/transformer/TxTransformerTypes.js'; -export { TransformerMetadata } from './providers/transactions/transformer/types.js'; +export { + TransformerMetadata, + TransformerMetadataSchema, +} from './providers/transactions/transformer/types.js'; export { EV5InterchainAccountTxTransformer } from './providers/transactions/transformer/ethersV5/EV5InterchainAccountTxTransformer.js'; export { EV5TxTransformerInterface } from './providers/transactions/transformer/ethersV5/EV5TxTransformerInterface.js'; -export { EV5InterchainAccountTxTransformerPropsSchema } from './providers/transactions/transformer/ethersV5/schemas.js'; -export { EV5InterchainAccountTxTransformerProps } from './providers/transactions/transformer/ethersV5/types.js'; +export { + EV5InterchainAccountTxTransformerProps, + EV5InterchainAccountTxTransformerPropsSchema, +} from './providers/transactions/transformer/ethersV5/types.js'; +export { EvmCoreModule } from './core/EvmCoreModule.js'; +export { + isProxy, + proxyAdmin, + proxyConstructorArgs, + proxyImplementation, +} from './deploy/proxy.js'; +export { + ChainGasOracleParams, + GasPriceConfig, + NativeTokenPriceConfig, + getCosmosChainGasPrice, + getGasPrice, + getLocalStorageGasOracleConfig, + getTokenExchangeRateFromValues, +} from './gas/utils.js'; +export { GcpValidator } from './gcp/validator.js'; +export { + DerivedIcaRouterConfig, + DerivedIcaRouterConfigSchema, + IcaRouterConfig, + IcaRouterConfigSchema, + RemoteIcaRouterConfigSchema, +} from './ica/types.js'; +export { EvmIsmModule } from './ism/EvmIsmModule.js'; export { chainMetadataToCosmosChain, chainMetadataToViemChain, } from './metadata/chainMetadataConversion.js'; +export { AnnotatedEV5Transaction } from './providers/ProviderType.js'; export { EvmGasRouterAdapter, EvmRouterAdapter, @@ -398,6 +456,7 @@ export { DestinationGas, GasRouterConfig, MailboxClientConfig, + MailboxClientConfigSchema, ProxiedFactories, ProxiedRouterConfig, RemoteRouters, @@ -441,6 +500,7 @@ export { SealevelHypCollateralAdapter, SealevelHypNativeAdapter, SealevelHypSyntheticAdapter, + SealevelHypTokenAdapter, SealevelNativeTokenAdapter, SealevelTokenAdapter, } from './token/adapters/SealevelTokenAdapter.js'; @@ -462,6 +522,7 @@ export { hypERC20factories, } from './token/contracts.js'; export { HypERC20Deployer, HypERC721Deployer } from './token/deploy.js'; +export { EvmERC20WarpModule } from './token/EvmERC20WarpModule.js'; export { EvmERC20WarpRouteReader } from './token/EvmERC20WarpRouteReader.js'; export { IToken, TokenArgs, TokenConfigSchema } from './token/IToken.js'; export { Token } from './token/Token.js'; @@ -487,8 +548,46 @@ export { TOKEN_TYPE_TO_STANDARD, TokenStandard, } from './token/TokenStandard.js'; -export { TokenRouterConfig, WarpRouteDeployConfig } from './token/types.js'; -export { ChainMap, ChainName, ChainNameOrId, Connection } from './types.js'; +export { + CollateralRebaseTokenConfigSchema, + CollateralTokenConfig, + CollateralTokenConfigSchema, + HypTokenConfig, + HypTokenConfigSchema, + HypTokenRouterConfig, + HypTokenRouterConfigSchema, + NativeTokenConfig, + NativeTokenConfigSchema, + SyntheticRebaseTokenConfig, + SyntheticRebaseTokenConfigSchema, + SyntheticTokenConfig, + SyntheticTokenConfigSchema, + TokenMetadata, + TokenMetadataSchema, + WarpRouteDeployConfig, + WarpRouteDeployConfigSchema, + WarpRouteDeployConfigSchemaErrors, + isCollateralRebaseTokenConfig, + isCollateralTokenConfig, + isNativeTokenConfig, + isSyntheticRebaseTokenConfig, + isSyntheticTokenConfig, + isTokenMetadata, +} from './token/types.js'; +export { + ChainMap, + ChainName, + ChainNameOrId, + Connection, + DeployedOwnableConfig, + DeployedOwnableSchema, + DerivedOwnableConfig, + DerivedOwnableSchema, + OwnableConfig, + OwnableSchema, + PausableConfig, + PausableSchema, +} from './types.js'; export { getCosmosRegistryChain } from './utils/cosmos.js'; export { filterByChains } from './utils/filter.js'; export { @@ -499,14 +598,24 @@ export { setFork, stopImpersonatingAccount, } from './utils/fork.js'; +export { + canProposeSafeTransactions, + getSafe, + getSafeDelegates, + getSafeService, + // @ts-ignore +} from './utils/gnosisSafe.js'; +export { HyperlaneReader } from './utils/HyperlaneReader.js'; export { multisigIsmVerificationCost, normalizeConfig } from './utils/ism.js'; export { MultiGeneric } from './utils/MultiGeneric.js'; +export { isCompliant, validateZodResult } from './utils/schemas.js'; export { SealevelAccountDataWrapper, SealevelInstructionWrapper, getSealevelAccountDataSchema, } from './utils/sealevelSerialization.js'; export { getChainIdFromTxs } from './utils/transactions.js'; +export { getValidatorFromStorageLocation } from './utils/validator.js'; export { FeeConstantConfig, RouteBlacklist, @@ -516,56 +625,4 @@ export { WarpTypedTransaction, } from './warp/types.js'; export { WarpCore, WarpCoreOptions } from './warp/WarpCore.js'; - -export { - AggregationIsmConfigSchema, - IsmConfigSchema, - MultisigIsmConfigSchema, -} from './ism/schemas.js'; -export { MailboxClientConfigSchema as mailboxClientConfigSchema } from './router/schemas.js'; -export { - CollateralConfig, - NativeConfig, - TokenConfig, - TokenRouterConfigSchema, - WarpRouteDeployConfigSchema, - WarpRouteDeployConfigSchemaErrors, - isCollateralConfig, - isNativeConfig, - isSyntheticConfig, - isSyntheticRebaseConfig, - isTokenMetadata, -} from './token/schemas.js'; -export { isCompliant, validateZodResult } from './utils/schemas.js'; - -export { - canProposeSafeTransactions, - getSafe, - getSafeDelegates, - getSafeService, - // @ts-ignore -} from './utils/gnosisSafe.js'; - -export { EvmCoreModule } from './core/EvmCoreModule.js'; -export { - isProxy, - proxyAdmin, - proxyConstructorArgs, - proxyImplementation, -} from './deploy/proxy.js'; -export { - ProxyFactoryFactoriesAddresses, - ProxyFactoryFactoriesSchema, -} from './deploy/schemas.js'; -export { - ChainGasOracleParams, - GasPriceConfig, - NativeTokenPriceConfig, - getCosmosChainGasPrice, - getGasPrice, - getLocalStorageGasOracleConfig, - getTokenExchangeRateFromValues, -} from './gas/utils.js'; -export { EvmIsmModule } from './ism/EvmIsmModule.js'; -export { AnnotatedEV5Transaction } from './providers/ProviderType.js'; -export { EvmERC20WarpModule } from './token/EvmERC20WarpModule.js'; +export { EvmHookModule } from './hook/EvmHookModule.js'; diff --git a/typescript/sdk/src/ism/EvmIsmModule.hardhat-test.ts b/typescript/sdk/src/ism/EvmIsmModule.hardhat-test.ts index 00c31fc715..79c808eac0 100644 --- a/typescript/sdk/src/ism/EvmIsmModule.hardhat-test.ts +++ b/typescript/sdk/src/ism/EvmIsmModule.hardhat-test.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ import assert from 'assert'; import { expect } from 'chai'; import { Signer } from 'ethers'; @@ -19,6 +18,7 @@ import { EvmIsmModule } from './EvmIsmModule.js'; import { HyperlaneIsmFactory } from './HyperlaneIsmFactory.js'; import { AggregationIsmConfig, + DomainRoutingIsmConfig, IsmConfig, IsmType, ModuleType, @@ -54,7 +54,10 @@ function randomNonNestedModuleType(): ModuleType { return NonNestedModuleTypes[randomInt(NonNestedModuleTypes.length)]; } -const randomIsmConfig = (depth = 0, maxDepth = 2) => { +const randomIsmConfig = ( + depth = 0, + maxDepth = 2, +): Exclude => { const moduleType = depth === maxDepth ? randomNonNestedModuleType() : randomModuleType(); @@ -77,8 +80,8 @@ const randomIsmConfig = (depth = 0, maxDepth = 2) => { const n = randomInt(2, 1); const moduleTypes = new Set(); const modules = new Array(n).fill(0).map(() => { - let moduleConfig; - let moduleType; + let moduleConfig: Exclude; + let moduleType: IsmType; // Ensure that we do not add the same module type more than once per level do { @@ -110,7 +113,7 @@ const randomIsmConfig = (depth = 0, maxDepth = 2) => { describe('EvmIsmModule', async () => { let multiProvider: MultiProvider; - let exampleRoutingConfig: RoutingIsmConfig; + let exampleRoutingConfig: DomainRoutingIsmConfig; let mailboxAddress: Address; let fundingAccount: Signer; @@ -197,6 +200,7 @@ describe('EvmIsmModule', async () => { // expect that the ISM matches the config after all tests afterEach(async () => { const derivedConfiig = await testIsm.read(); + const normalizedDerivedConfig = normalizeConfig(derivedConfiig); const normalizedConfig = normalizeConfig(testConfig); @@ -243,6 +247,12 @@ describe('EvmIsmModule', async () => { }); } + it(`deploys ${IsmType.ICA_ROUTING}`, async () => { + await createIsm({ + type: IsmType.ICA_ROUTING, + }); + }); + for (let i = 0; i < 16; i++) { it(`deploys a random ism config #${i}`, async () => { const config = randomIsmConfig(); @@ -318,7 +328,7 @@ describe('EvmIsmModule', async () => { // keep track of the domains before deleting const numDomainsBefore = Object.keys( - ((await ism.read()) as RoutingIsmConfig).domains, + ((await ism.read()) as DomainRoutingIsmConfig).domains, ).length; // deleting the domain and removing from multiprovider should unenroll the domain @@ -333,7 +343,7 @@ describe('EvmIsmModule', async () => { // domains should have decreased by 1 const numDomainsAfter = Object.keys( - ((await ism.read()) as RoutingIsmConfig).domains, + ((await ism.read()) as DomainRoutingIsmConfig).domains, ).length; expect(numDomainsBefore - 1).to.equal(numDomainsAfter); }); diff --git a/typescript/sdk/src/ism/EvmIsmModule.ts b/typescript/sdk/src/ism/EvmIsmModule.ts index 2f4e1ee1d8..310b6e1ee9 100644 --- a/typescript/sdk/src/ism/EvmIsmModule.ts +++ b/typescript/sdk/src/ism/EvmIsmModule.ts @@ -28,13 +28,13 @@ import { normalizeConfig } from '../utils/ism.js'; import { EvmIsmReader } from './EvmIsmReader.js'; import { HyperlaneIsmFactory } from './HyperlaneIsmFactory.js'; -import { IsmConfigSchema } from './schemas.js'; import { DeployedIsm, + DomainRoutingIsmConfig, IsmConfig, + IsmConfigSchema, IsmType, MUTABLE_ISM_TYPE, - RoutingIsmConfig, } from './types.js'; import { calculateDomainRoutingDelta } from './utils.js'; @@ -161,7 +161,7 @@ export class EvmIsmModule extends HyperlaneModule< targetConfig.type === IsmType.FALLBACK_ROUTING ) { updateTxs = await this.updateRoutingIsm({ - current: currentConfig as RoutingIsmConfig, + current: currentConfig, target: targetConfig, logger, }); @@ -221,8 +221,8 @@ export class EvmIsmModule extends HyperlaneModule< target, logger, }: { - current: RoutingIsmConfig; - target: RoutingIsmConfig; + current: DomainRoutingIsmConfig; + target: DomainRoutingIsmConfig; logger: Logger; }): Promise { const contract = DomainRoutingIsm__factory.connect( diff --git a/typescript/sdk/src/ism/EvmIsmReader.ts b/typescript/sdk/src/ism/EvmIsmReader.ts index 06493cb450..a6d0751188 100644 --- a/typescript/sdk/src/ism/EvmIsmReader.ts +++ b/typescript/sdk/src/ism/EvmIsmReader.ts @@ -1,6 +1,7 @@ import { BigNumber, ethers } from 'ethers'; import { + AbstractRoutingIsm__factory, ArbL2ToL1Ism__factory, DefaultFallbackRoutingIsm__factory, IInterchainSecurityModule__factory, @@ -29,6 +30,7 @@ import { HyperlaneReader } from '../utils/HyperlaneReader.js'; import { AggregationIsmConfig, ArbL2ToL1IsmConfig, + DomainRoutingIsmConfig, IsmConfig, IsmType, ModuleType, @@ -127,18 +129,34 @@ export class EvmIsmReader extends HyperlaneReader implements IsmReader { async deriveRoutingConfig( address: Address, ): Promise> { - const ism = DefaultFallbackRoutingIsm__factory.connect( - address, - this.provider, - ); + const ism = AbstractRoutingIsm__factory.connect(address, this.provider); - const owner = await ism.owner(); this.assertModuleType(await ism.moduleType(), ModuleType.ROUTING); + let owner: Address | undefined; + const defaultFallbackIsmInstance = + DefaultFallbackRoutingIsm__factory.connect(address, this.provider); + try { + owner = await defaultFallbackIsmInstance.owner(); + } catch { + this.logger.debug( + 'Error accessing owner property, implying this is an ICA routing ISM.', + address, + ); + } + + // If the current ISM does not have an owner then it is an ICA Router + if (!owner) { + return { + type: IsmType.ICA_ROUTING, + address, + }; + } + const domainIds = this.messageContext ? [BigNumber.from(this.messageContext.parsed.origin)] - : await ism.domains(); - const domains: RoutingIsmConfig['domains'] = {}; + : await defaultFallbackIsmInstance.domains(); + const domains: DomainRoutingIsmConfig['domains'] = {}; await concurrentMap(this.concurrency, domainIds, async (domainId) => { const chainName = this.multiProvider.tryGetChainName(domainId.toNumber()); @@ -149,16 +167,16 @@ export class EvmIsmReader extends HyperlaneReader implements IsmReader { return; } const module = this.messageContext - ? await ism.route(this.messageContext.message) - : await ism.module(domainId); + ? await defaultFallbackIsmInstance.route(this.messageContext.message) + : await defaultFallbackIsmInstance.module(domainId); domains[chainName] = await this.deriveIsmConfig(module); }); // Fallback routing ISM extends from MailboxClient, default routing let ismType = IsmType.FALLBACK_ROUTING; try { - await ism.mailbox(); - } catch (error) { + await defaultFallbackIsmInstance.mailbox(); + } catch { ismType = IsmType.ROUTING; this.logger.debug( 'Error accessing mailbox property, implying this is not a fallback routing ISM.', @@ -248,7 +266,7 @@ export class EvmIsmReader extends HyperlaneReader implements IsmReader { relayer, type: IsmType.TRUSTED_RELAYER, }; - } catch (error) { + } catch { this.logger.debug( 'Error accessing "trustedRelayer" property, implying this is not a Trusted Relayer ISM.', address, @@ -266,7 +284,7 @@ export class EvmIsmReader extends HyperlaneReader implements IsmReader { type: IsmType.PAUSABLE, paused, }; - } catch (error) { + } catch { this.logger.debug( 'Error accessing "paused" property, implying this is not a Pausable ISM.', address, @@ -283,7 +301,7 @@ export class EvmIsmReader extends HyperlaneReader implements IsmReader { origin: address, nativeBridge: '', // no way to extract native bridge from the ism }; - } catch (error) { + } catch { this.logger.debug( 'Error accessing "VERIFIED_MASK_INDEX" property, implying this is not an OP Stack ISM.', address, diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.hardhat-test.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.hardhat-test.ts index 894eaa2781..737266e73f 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.hardhat-test.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.hardhat-test.ts @@ -16,6 +16,7 @@ import { randomAddress } from '../test/testUtils.js'; import { HyperlaneIsmFactory } from './HyperlaneIsmFactory.js'; import { AggregationIsmConfig, + DomainRoutingIsmConfig, IsmConfig, IsmType, ModuleType, @@ -136,7 +137,7 @@ describe('HyperlaneIsmFactory', async () => { let ismFactoryDeployer: HyperlaneProxyFactoryDeployer; let ismFactory: HyperlaneIsmFactory; let multiProvider: MultiProvider; - let exampleRoutingConfig: RoutingIsmConfig; + let exampleRoutingConfig: DomainRoutingIsmConfig; let mailboxAddress: Address; let newMailboxAddress: Address; let contractsMap: HyperlaneContractsMap = {}; diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts index 2835e4a351..c8c987a5d9 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts @@ -14,6 +14,7 @@ import { IMultisigIsm__factory, IRoutingIsm, IStaticWeightedMultisigIsm, + InterchainAccountIsm__factory, OPStackIsm__factory, PausableIsm__factory, StaticAddressSetFactory, @@ -53,6 +54,7 @@ import { AggregationIsmConfig, DeployedIsm, DeployedIsmType, + DomainRoutingIsmConfig, IsmConfig, IsmType, MultisigIsmConfig, @@ -152,6 +154,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp { break; case IsmType.ROUTING: case IsmType.FALLBACK_ROUTING: + case IsmType.ICA_ROUTING: contract = await this.deployRoutingIsm({ destination, config, @@ -317,6 +320,43 @@ export class HyperlaneIsmFactory extends HyperlaneApp { mailbox?: Address; existingIsmAddress?: Address; logger: Logger; + }): Promise { + const { config } = params; + + if (config.type === IsmType.ICA_ROUTING) { + return this.deployIcaIsm(params); + } + + return this.deployOwnableRoutingIsm({ + ...params, + // Can't pass params directly because ts will complain that the types do not match + config, + }); + } + + private async deployIcaIsm(params: { + destination: ChainName; + config: RoutingIsmConfig; + mailbox?: Address; + }): Promise { + if (!params.mailbox) { + throw new Error('Mailbox address is required for deploying ICA ISM'); + } + + return this.multiProvider.handleDeploy( + params.destination, + new InterchainAccountIsm__factory(), + [params.mailbox], + ); + } + + private async deployOwnableRoutingIsm(params: { + destination: ChainName; + config: DomainRoutingIsmConfig; + origin?: ChainName; + mailbox?: Address; + existingIsmAddress?: Address; + logger: Logger; }): Promise { const { destination, config, mailbox, existingIsmAddress, logger } = params; const overrides = this.multiProvider.getTransactionOverrides(destination); @@ -360,6 +400,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp { ).owner(); isOwner = eqAddress(await signer.getAddress(), owner); } + // reconfiguring existing routing ISM if (existingIsmAddress && isOwner && !delta.mailbox) { const isms: Record = {}; @@ -466,7 +507,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp { .map((log) => { try { return domainRoutingIsmFactory.interface.parseLog(log); - } catch (e) { + } catch { return undefined; } }) diff --git a/typescript/sdk/src/ism/adapters/CosmWasmMultisigAdapter.ts b/typescript/sdk/src/ism/adapters/CosmWasmMultisigAdapter.ts index aaeb899853..b4cb823749 100644 --- a/typescript/sdk/src/ism/adapters/CosmWasmMultisigAdapter.ts +++ b/typescript/sdk/src/ism/adapters/CosmWasmMultisigAdapter.ts @@ -13,7 +13,7 @@ import { ExecuteMsg as MultisigExecute, QueryMsg as MultisigQuery, } from '../../cw-types/IsmMultisig.types.js'; -import { MultisigConfig } from '../../ism/types.js'; +import { MultisigConfig, MultisigIsmConfig } from '../../ism/types.js'; import { MultiProtocolProvider } from '../../providers/MultiProtocolProvider.js'; import { ChainMap, ChainName } from '../../types.js'; @@ -39,7 +39,7 @@ export class CosmWasmMultisigAdapter extends BaseCosmWasmAdapter { return response; } - async getConfig(chain: ChainName): Promise { + async getConfig(chain: ChainName): Promise> { return this.queryMultisig({ multisig_ism: { enrolled_validators: { @@ -67,7 +67,7 @@ export class CosmWasmMultisigAdapter extends BaseCosmWasmAdapter { ([origin, config]) => { const domain = this.multiProvider.getDomainId(origin); const configuredSet = new Set(configuredMap[origin].validators); - const configSet = new Set(config.validators); + const configSet = new Set(config.validators.map((v) => v.address)); const unenrollList = Array.from( difference(configuredSet, configSet).values(), ); diff --git a/typescript/sdk/src/ism/metadata/aggregation.ts b/typescript/sdk/src/ism/metadata/aggregation.ts index 5c347a6007..0f35e7e2cf 100644 --- a/typescript/sdk/src/ism/metadata/aggregation.ts +++ b/typescript/sdk/src/ism/metadata/aggregation.ts @@ -10,12 +10,13 @@ import { import { DerivedIsmConfig } from '../EvmIsmReader.js'; import { AggregationIsmConfig, IsmType } from '../types.js'; +import type { BaseMetadataBuilder } from './builder.js'; +import { decodeIsmMetadata } from './decode.js'; import { - BaseMetadataBuilder, MetadataBuilder, MetadataContext, StructuredMetadata, -} from './builder.js'; +} from './types.js'; // null indicates that metadata is NOT INCLUDED for this submodule // empty or 0x string indicates that metadata is INCLUDED but NULL @@ -137,7 +138,7 @@ export class AggregationMetadataBuilder implements MetadataBuilder { const range = this.metadataRange(metadata, index); if (range.start == 0) return null; if (typeof ism === 'string') return range.encoded; - return BaseMetadataBuilder.decode(range.encoded, { + return decodeIsmMetadata(range.encoded, { ...context, ism: ism as DerivedIsmConfig, }); diff --git a/typescript/sdk/src/ism/metadata/arbL2ToL1.hardhat-test.ts b/typescript/sdk/src/ism/metadata/arbL2ToL1.hardhat-test.ts index f2b66d9cb9..e186da5c9a 100644 --- a/typescript/sdk/src/ism/metadata/arbL2ToL1.hardhat-test.ts +++ b/typescript/sdk/src/ism/metadata/arbL2ToL1.hardhat-test.ts @@ -16,8 +16,12 @@ import { MockArbSys__factory, TestRecipient, } from '@hyperlane-xyz/core'; -import { Address, WithAddress, objMap } from '@hyperlane-xyz/utils'; -import { bytes32ToAddress } from '@hyperlane-xyz/utils'; +import { + Address, + WithAddress, + bytes32ToAddress, + objMap, +} from '@hyperlane-xyz/utils'; import { testChains } from '../../consts/testChains.js'; import { @@ -38,7 +42,7 @@ import { HyperlaneIsmFactory } from '../HyperlaneIsmFactory.js'; import { ArbL2ToL1IsmConfig } from '../types.js'; import { ArbL2ToL1MetadataBuilder } from './arbL2ToL1.js'; -import { MetadataContext } from './builder.js'; +import { MetadataContext } from './types.js'; describe('ArbL2ToL1MetadataBuilder', () => { const origin: ChainName = 'test4'; diff --git a/typescript/sdk/src/ism/metadata/arbL2ToL1.ts b/typescript/sdk/src/ism/metadata/arbL2ToL1.ts index 9b12010eb7..5279f1dafe 100644 --- a/typescript/sdk/src/ism/metadata/arbL2ToL1.ts +++ b/typescript/sdk/src/ism/metadata/arbL2ToL1.ts @@ -20,7 +20,7 @@ import { ArbL2ToL1HookConfig } from '../../hook/types.js'; import { findMatchingLogEvents } from '../../utils/logUtils.js'; import { ArbL2ToL1IsmConfig, IsmType } from '../types.js'; -import { MetadataBuilder, MetadataContext } from './builder.js'; +import type { MetadataBuilder, MetadataContext } from './types.js'; export type NitroChildToParentTransactionEvent = EventArgs; export type ArbL2ToL1Metadata = Omit< diff --git a/typescript/sdk/src/ism/metadata/builder.hardhat-test.ts b/typescript/sdk/src/ism/metadata/builder.hardhat-test.ts index fbda40a5b5..53fc89d3d9 100644 --- a/typescript/sdk/src/ism/metadata/builder.hardhat-test.ts +++ b/typescript/sdk/src/ism/metadata/builder.hardhat-test.ts @@ -39,7 +39,9 @@ import { EvmIsmReader } from '../EvmIsmReader.js'; import { randomIsmConfig } from '../HyperlaneIsmFactory.hardhat-test.js'; import { HyperlaneIsmFactory } from '../HyperlaneIsmFactory.js'; -import { BaseMetadataBuilder, MetadataContext } from './builder.js'; +import { BaseMetadataBuilder } from './builder.js'; +import { decodeIsmMetadata } from './decode.js'; +import { MetadataContext } from './types.js'; const MAX_ISM_DEPTH = 5; const MAX_NUM_VALIDATORS = 10; @@ -198,7 +200,7 @@ describe('BaseMetadataBuilder', () => { }); it(`should decode metadata for random ism config (${i})`, async () => { - BaseMetadataBuilder.decode(metadata, context); + decodeIsmMetadata(metadata, context); }); } }); diff --git a/typescript/sdk/src/ism/metadata/builder.ts b/typescript/sdk/src/ism/metadata/builder.ts index e290f390f7..61c7d0c861 100644 --- a/typescript/sdk/src/ism/metadata/builder.ts +++ b/typescript/sdk/src/ism/metadata/builder.ts @@ -1,53 +1,30 @@ -/* eslint-disable no-case-declarations */ -import { TransactionReceipt } from '@ethersproject/providers'; - -import { WithAddress, assert, rootLogger } from '@hyperlane-xyz/utils'; +import { + WithAddress, + assert, + deepFind, + rootLogger, +} from '@hyperlane-xyz/utils'; -import { deepFind } from '../../../../utils/dist/objects.js'; import { HyperlaneCore } from '../../core/HyperlaneCore.js'; -import { DispatchedMessage } from '../../core/types.js'; -import { DerivedHookConfig } from '../../hook/EvmHookReader.js'; import { ArbL2ToL1HookConfig, HookType, MerkleTreeHookConfig, } from '../../hook/types.js'; import { MultiProvider } from '../../providers/MultiProvider.js'; -import { DerivedIsmConfig } from '../EvmIsmReader.js'; import { IsmType } from '../types.js'; -import { - AggregationMetadata, - AggregationMetadataBuilder, -} from './aggregation.js'; -import { ArbL2ToL1Metadata, ArbL2ToL1MetadataBuilder } from './arbL2ToL1.js'; -import { MultisigMetadata, MultisigMetadataBuilder } from './multisig.js'; -import { NullMetadata, NullMetadataBuilder } from './null.js'; -import { - DefaultFallbackRoutingMetadataBuilder, - RoutingMetadata, -} from './routing.js'; - -export type StructuredMetadata = - | NullMetadata - | MultisigMetadata - | ArbL2ToL1Metadata - | AggregationMetadata - | RoutingMetadata; - -export interface MetadataContext< - IsmContext = DerivedIsmConfig, - HookContext = DerivedHookConfig, -> { - message: DispatchedMessage; - dispatchTx: TransactionReceipt; - ism: IsmContext; - hook: HookContext; -} - -export interface MetadataBuilder { - build(context: MetadataContext): Promise; -} +import { AggregationMetadataBuilder } from './aggregation.js'; +import { ArbL2ToL1MetadataBuilder } from './arbL2ToL1.js'; +import { decodeIsmMetadata } from './decode.js'; +import { MultisigMetadataBuilder } from './multisig.js'; +import { NullMetadataBuilder } from './null.js'; +import { DefaultFallbackRoutingMetadataBuilder } from './routing.js'; +import type { + MetadataBuilder, + MetadataContext, + StructuredMetadata, +} from './types.js'; export class BaseMetadataBuilder implements MetadataBuilder { public nullMetadataBuilder: NullMetadataBuilder; @@ -91,6 +68,7 @@ export class BaseMetadataBuilder implements MetadataBuilder { if (typeof hook === 'string') { throw new Error('Hook context must be an object (for multisig ISM)'); } + // eslint-disable-next-line no-case-declarations const merkleTreeHook = deepFind( hook, (v): v is WithAddress => @@ -105,6 +83,7 @@ export class BaseMetadataBuilder implements MetadataBuilder { case IsmType.ROUTING: case IsmType.FALLBACK_ROUTING: + case IsmType.ICA_ROUTING: return this.routingMetadataBuilder.build( { ...context, @@ -137,32 +116,6 @@ export class BaseMetadataBuilder implements MetadataBuilder { metadata: string, context: MetadataContext, ): StructuredMetadata { - const { ism } = context; - switch (ism.type) { - case IsmType.TRUSTED_RELAYER: - return NullMetadataBuilder.decode(ism); - - case IsmType.MERKLE_ROOT_MULTISIG: - case IsmType.MESSAGE_ID_MULTISIG: - return MultisigMetadataBuilder.decode(metadata, ism.type); - - case IsmType.AGGREGATION: - return AggregationMetadataBuilder.decode(metadata, { ...context, ism }); - - case IsmType.ROUTING: - return DefaultFallbackRoutingMetadataBuilder.decode(metadata, { - ...context, - ism, - }); - - case IsmType.ARB_L2_TO_L1: - return ArbL2ToL1MetadataBuilder.decode(metadata, { - ...context, - ism, - }); - - default: - throw new Error(`Unsupported ISM type: ${ism.type}`); - } + return decodeIsmMetadata(metadata, context); } } diff --git a/typescript/sdk/src/ism/metadata/decode.ts b/typescript/sdk/src/ism/metadata/decode.ts new file mode 100644 index 0000000000..cdd4c6194d --- /dev/null +++ b/typescript/sdk/src/ism/metadata/decode.ts @@ -0,0 +1,41 @@ +import { IsmType } from '../types.js'; + +import { AggregationMetadataBuilder } from './aggregation.js'; +import { ArbL2ToL1MetadataBuilder } from './arbL2ToL1.js'; +import { MultisigMetadataBuilder } from './multisig.js'; +import { NullMetadataBuilder } from './null.js'; +import { DefaultFallbackRoutingMetadataBuilder } from './routing.js'; +import { MetadataContext, StructuredMetadata } from './types.js'; + +export function decodeIsmMetadata( + metadata: string, + context: MetadataContext, +): StructuredMetadata { + const { ism } = context; + switch (ism.type) { + case IsmType.TRUSTED_RELAYER: + return NullMetadataBuilder.decode(ism); + + case IsmType.MERKLE_ROOT_MULTISIG: + case IsmType.MESSAGE_ID_MULTISIG: + return MultisigMetadataBuilder.decode(metadata, ism.type); + + case IsmType.AGGREGATION: + return AggregationMetadataBuilder.decode(metadata, { ...context, ism }); + + case IsmType.ROUTING: + return DefaultFallbackRoutingMetadataBuilder.decode(metadata, { + ...context, + ism, + }); + + case IsmType.ARB_L2_TO_L1: + return ArbL2ToL1MetadataBuilder.decode(metadata, { + ...context, + ism, + }); + + default: + throw new Error(`Unsupported ISM type: ${ism.type}`); + } +} diff --git a/typescript/sdk/src/ism/metadata/multisig.ts b/typescript/sdk/src/ism/metadata/multisig.ts index 1de554fa5d..74e50e355b 100644 --- a/typescript/sdk/src/ism/metadata/multisig.ts +++ b/typescript/sdk/src/ism/metadata/multisig.ts @@ -26,7 +26,7 @@ import { MerkleTreeHookConfig } from '../../hook/types.js'; import { ChainName } from '../../types.js'; import { IsmType, MultisigIsmConfig } from '../types.js'; -import { MetadataBuilder, MetadataContext } from './builder.js'; +import type { MetadataBuilder, MetadataContext } from './types.js'; interface MessageIdMultisigMetadata { type: IsmType.MESSAGE_ID_MULTISIG; diff --git a/typescript/sdk/src/ism/metadata/null.ts b/typescript/sdk/src/ism/metadata/null.ts index ed66277ce4..e4be778b73 100644 --- a/typescript/sdk/src/ism/metadata/null.ts +++ b/typescript/sdk/src/ism/metadata/null.ts @@ -3,7 +3,7 @@ import { WithAddress, assert, eqAddress } from '@hyperlane-xyz/utils'; import { MultiProvider } from '../../providers/MultiProvider.js'; import { IsmType, NullIsmConfig } from '../types.js'; -import { MetadataBuilder, MetadataContext } from './builder.js'; +import type { MetadataBuilder, MetadataContext } from './types.js'; export const NULL_METADATA = '0x'; diff --git a/typescript/sdk/src/ism/metadata/routing.ts b/typescript/sdk/src/ism/metadata/routing.ts index 36fd69e605..26af0a7b5c 100644 --- a/typescript/sdk/src/ism/metadata/routing.ts +++ b/typescript/sdk/src/ism/metadata/routing.ts @@ -1,16 +1,20 @@ -import { DefaultFallbackRoutingIsm__factory } from '@hyperlane-xyz/core'; -import { WithAddress, assert } from '@hyperlane-xyz/utils'; +import { + DefaultFallbackRoutingIsm__factory, + InterchainAccountIsm__factory, +} from '@hyperlane-xyz/core'; +import { Address, WithAddress, assert } from '@hyperlane-xyz/utils'; import { ChainName } from '../../types.js'; import { DerivedIsmConfig, EvmIsmReader } from '../EvmIsmReader.js'; -import { IsmType, RoutingIsmConfig } from '../types.js'; +import { DomainRoutingIsmConfig, IsmType, RoutingIsmConfig } from '../types.js'; -import { - BaseMetadataBuilder, +import type { BaseMetadataBuilder } from './builder.js'; +import { decodeIsmMetadata } from './decode.js'; +import type { MetadataBuilder, MetadataContext, StructuredMetadata, -} from './builder.js'; +} from './types.js'; export type RoutingMetadata = { type: IsmType.ROUTING; @@ -22,7 +26,7 @@ export class RoutingMetadataBuilder implements MetadataBuilder { constructor(protected baseMetadataBuilder: BaseMetadataBuilder) {} public async build( - context: MetadataContext>, + context: MetadataContext>, maxDepth = 10, ): Promise { const originChain = this.baseMetadataBuilder.multiProvider.getChainName( @@ -32,20 +36,22 @@ export class RoutingMetadataBuilder implements MetadataBuilder { ...context, ism: context.ism.domains[originChain] as DerivedIsmConfig, }; + return this.baseMetadataBuilder.build(originContext, maxDepth - 1); } static decode( metadata: string, - context: MetadataContext>, + context: MetadataContext>, ): RoutingMetadata { // TODO: this is a naive implementation, we should support domain ID keys assert(context.message.parsed.originChain, 'originChain is required'); const ism = context.ism.domains[context.message.parsed.originChain]; + const originMetadata = typeof ism === 'string' ? metadata - : BaseMetadataBuilder.decode(metadata, { + : decodeIsmMetadata(metadata, { ...context, ism: ism as DerivedIsmConfig, }); @@ -67,12 +73,24 @@ export class DefaultFallbackRoutingMetadataBuilder extends RoutingMetadataBuilde context.message.parsed.origin, ); - const isRouted = !!context.ism.domains[originChain]; - if (isRouted) { - return super.build(context, maxDepth); + const isRouted = + context.ism.type === IsmType.ICA_ROUTING + ? false + : !!context.ism.domains[originChain]; + // If the chain is routed then we are 100% sure that the ism is not an ICA ISM + if (isRouted && context.ism.type !== IsmType.ICA_ROUTING) { + return super.build( + // Typescript is not clever enough to understand that after the conditional check + // the ism type will be of the same expected type + context as MetadataContext>, + maxDepth, + ); } - if (context.ism.type !== IsmType.FALLBACK_ROUTING) { + if ( + context.ism.type !== IsmType.FALLBACK_ROUTING && + context.ism.type !== IsmType.ICA_ROUTING + ) { throw new Error( `Origin domain ${originChain} is not enrolled in DomainRoutingIsm`, ); @@ -82,19 +100,28 @@ export class DefaultFallbackRoutingMetadataBuilder extends RoutingMetadataBuilde this.baseMetadataBuilder.multiProvider.getProvider( context.message.parsed.destination, ); - const fallbackIsm = DefaultFallbackRoutingIsm__factory.connect( - context.ism.address, - destinationProvider, - ); - const defaultIsmAddress = await fallbackIsm.module( - context.message.parsed.origin, - ); + + let ismAddress: Address; + if (context.ism.type === IsmType.ICA_ROUTING) { + const icaFallbackRoutingIsm = InterchainAccountIsm__factory.connect( + context.ism.address, + destinationProvider, + ); + + ismAddress = await icaFallbackRoutingIsm.route(context.message.message); + } else { + const fallbackIsm = DefaultFallbackRoutingIsm__factory.connect( + context.ism.address, + destinationProvider, + ); + ismAddress = await fallbackIsm.module(context.message.parsed.origin); + } const ismReader = new EvmIsmReader( this.baseMetadataBuilder.multiProvider, context.message.parsed.destination, ); - const defaultIsmConfig = await ismReader.deriveIsmConfig(defaultIsmAddress); + const defaultIsmConfig = await ismReader.deriveIsmConfig(ismAddress); const originContext = { ...context, diff --git a/typescript/sdk/src/ism/metadata/types.ts b/typescript/sdk/src/ism/metadata/types.ts new file mode 100644 index 0000000000..104ef5757d --- /dev/null +++ b/typescript/sdk/src/ism/metadata/types.ts @@ -0,0 +1,32 @@ +import type { providers } from 'ethers'; + +import type { DispatchedMessage } from '../../core/types.js'; +import type { DerivedHookConfig } from '../../hook/EvmHookReader.js'; +import type { DerivedIsmConfig } from '../EvmIsmReader.js'; + +import type { AggregationMetadata } from './aggregation.js'; +import type { ArbL2ToL1Metadata } from './arbL2ToL1.js'; +import type { MultisigMetadata } from './multisig.js'; +import type { NullMetadata } from './null.js'; +import type { RoutingMetadata } from './routing.js'; + +export type StructuredMetadata = + | NullMetadata + | MultisigMetadata + | ArbL2ToL1Metadata + | AggregationMetadata + | RoutingMetadata; + +export interface MetadataContext< + IsmContext = DerivedIsmConfig, + HookContext = DerivedHookConfig, +> { + message: DispatchedMessage; + dispatchTx: providers.TransactionReceipt; + ism: IsmContext; + hook: HookContext; +} + +export interface MetadataBuilder { + build(context: MetadataContext): Promise; +} diff --git a/typescript/sdk/src/ism/multisig.ts b/typescript/sdk/src/ism/multisig.ts index 83025f1983..6d03945620 100644 --- a/typescript/sdk/src/ism/multisig.ts +++ b/typescript/sdk/src/ism/multisig.ts @@ -9,6 +9,16 @@ import { MultisigIsmConfig, } from './types.js'; +// Convert a MultisigConfig to a MultisigIsmConfig with the specified ISM type +export const multisigConfigToIsmConfig = ( + type: MultisigIsmConfig['type'], + config: MultisigConfig, +): MultisigIsmConfig => ({ + type, + threshold: config.threshold, + validators: config.validators.map((v) => v.address), +}); + // build multisigIsmConfig from multisigConfig // eg. for { sepolia (local), arbitrumsepolia, scrollsepolia } // arbitrumsepolia => Ism, scrollsepolia => Ism @@ -21,13 +31,10 @@ export const buildMultisigIsmConfigs = ( return objMap( objFilter( multisigConfigs, - (chain, config): config is MultisigConfig => + (chain, _): _ is MultisigConfig => chain !== local && chains.includes(chain), ), - (_, config) => ({ - ...config, - type, - }), + (_, config) => multisigConfigToIsmConfig(type, config), ); }; @@ -45,14 +52,8 @@ export const buildAggregationIsmConfigs = ( (_, config): AggregationIsmConfig => ({ type: IsmType.AGGREGATION, modules: [ - { - ...config, - type: IsmType.MESSAGE_ID_MULTISIG, - }, - { - ...config, - type: IsmType.MERKLE_ROOT_MULTISIG, - }, + multisigConfigToIsmConfig(IsmType.MESSAGE_ID_MULTISIG, config), + multisigConfigToIsmConfig(IsmType.MERKLE_ROOT_MULTISIG, config), ], threshold: 1, }), diff --git a/typescript/sdk/src/ism/schemas.ts b/typescript/sdk/src/ism/schemas.ts deleted file mode 100644 index e9d2e1cda8..0000000000 --- a/typescript/sdk/src/ism/schemas.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { z } from 'zod'; - -import { ZHash } from '../metadata/customZodTypes.js'; -import { OwnableSchema, PausableSchema } from '../schemas.js'; - -import { AggregationIsmConfig, IsmType, RoutingIsmConfig } from './types.js'; - -const ValidatorInfoSchema = z.object({ - signingAddress: ZHash, - weight: z.number(), -}); - -export const TestIsmConfigSchema = z.object({ - type: z.literal(IsmType.TEST_ISM), -}); - -export const MultisigConfigSchema = z.object({ - validators: z.array(ZHash), - threshold: z.number(), -}); - -export const WeightedMultisigConfigSchema = z.object({ - validators: z.array(ValidatorInfoSchema), - thresholdWeight: z.number(), -}); - -export const TrustedRelayerIsmConfigSchema = z.object({ - type: z.literal(IsmType.TRUSTED_RELAYER), - relayer: z.string(), -}); - -export const OpStackIsmConfigSchema = z.object({ - type: z.literal(IsmType.OP_STACK), - origin: z.string(), - nativeBridge: z.string(), -}); - -export const ArbL2ToL1IsmConfigSchema = z.object({ - type: z.literal(IsmType.ARB_L2_TO_L1), - bridge: z.string(), -}); - -export const PausableIsmConfigSchema = PausableSchema.and( - z.object({ - type: z.literal(IsmType.PAUSABLE), - }), -); - -export const MultisigIsmConfigSchema = MultisigConfigSchema.and( - z.object({ - type: z.union([ - z.literal(IsmType.MERKLE_ROOT_MULTISIG), - z.literal(IsmType.MESSAGE_ID_MULTISIG), - z.literal(IsmType.STORAGE_MERKLE_ROOT_MULTISIG), - z.literal(IsmType.STORAGE_MESSAGE_ID_MULTISIG), - ]), - }), -); - -export const WeightedMultisigIsmConfigSchema = WeightedMultisigConfigSchema.and( - z.object({ - type: z.union([ - z.literal(IsmType.WEIGHTED_MERKLE_ROOT_MULTISIG), - z.literal(IsmType.WEIGHTED_MESSAGE_ID_MULTISIG), - ]), - }), -); - -export const RoutingIsmConfigSchema: z.ZodSchema = z.lazy( - () => - OwnableSchema.extend({ - type: z.union([ - z.literal(IsmType.ROUTING), - z.literal(IsmType.FALLBACK_ROUTING), - ]), - domains: z.record(IsmConfigSchema), - }), -); - -export const AggregationIsmConfigSchema: z.ZodSchema = z - .lazy(() => - z.object({ - type: z.literal(IsmType.AGGREGATION), - modules: z.array(IsmConfigSchema), - threshold: z.number(), - }), - ) - .refine((data) => data.threshold <= data.modules.length, { - message: 'Threshold must be less than or equal to the number of modules', - }); - -export const IsmConfigSchema = z.union([ - ZHash, - TestIsmConfigSchema, - OpStackIsmConfigSchema, - PausableIsmConfigSchema, - TrustedRelayerIsmConfigSchema, - MultisigIsmConfigSchema, - WeightedMultisigIsmConfigSchema, - RoutingIsmConfigSchema, - AggregationIsmConfigSchema, - ArbL2ToL1IsmConfigSchema, -]); diff --git a/typescript/sdk/src/ism/schemas.test.ts b/typescript/sdk/src/ism/types.test.ts similarity index 85% rename from typescript/sdk/src/ism/schemas.test.ts rename to typescript/sdk/src/ism/types.test.ts index 7605382c24..9c57ebf042 100644 --- a/typescript/sdk/src/ism/schemas.test.ts +++ b/typescript/sdk/src/ism/types.test.ts @@ -1,8 +1,7 @@ import { expect } from 'chai'; import { ethers } from 'ethers'; -import { AggregationIsmConfigSchema } from './schemas.js'; -import { IsmType } from './types.js'; +import { AggregationIsmConfigSchema, IsmType } from './types.js'; const SOME_ADDRESS = ethers.Wallet.createRandom().address; describe('AggregationIsmConfigSchema refine', () => { diff --git a/typescript/sdk/src/ism/types.ts b/typescript/sdk/src/ism/types.ts index 82e025a049..87adb2cff2 100644 --- a/typescript/sdk/src/ism/types.ts +++ b/typescript/sdk/src/ism/types.ts @@ -14,19 +14,13 @@ import { } from '@hyperlane-xyz/core'; import type { Address, Domain, ValueOf } from '@hyperlane-xyz/utils'; -import { OwnableConfig } from '../deploy/types.js'; -import { ChainMap } from '../types.js'; - +import { ZHash } from '../metadata/customZodTypes.js'; import { - ArbL2ToL1IsmConfigSchema, - IsmConfigSchema, - MultisigIsmConfigSchema, - OpStackIsmConfigSchema, - PausableIsmConfigSchema, - TestIsmConfigSchema, - TrustedRelayerIsmConfigSchema, - WeightedMultisigIsmConfigSchema, -} from './schemas.js'; + ChainMap, + OwnableConfig, + OwnableSchema, + PausableSchema, +} from '../types.js'; // this enum should match the IInterchainSecurityModule.sol enum // meant for the relayer @@ -51,6 +45,7 @@ export enum IsmType { OP_STACK = 'opStackIsm', ROUTING = 'domainRoutingIsm', FALLBACK_ROUTING = 'defaultFallbackRoutingIsm', + ICA_ROUTING = 'icaRoutingIsm', AGGREGATION = 'staticAggregationIsm', STORAGE_AGGREGATION = 'storageAggregationIsm', MERKLE_ROOT_MULTISIG = 'merkleRootMultisigIsm', @@ -76,8 +71,8 @@ export const MUTABLE_ISM_TYPE = [ export function ismTypeToModuleType(ismType: IsmType): ModuleType { switch (ismType) { case IsmType.ROUTING: - return ModuleType.ROUTING; case IsmType.FALLBACK_ROUTING: + case IsmType.ICA_ROUTING: return ModuleType.ROUTING; case IsmType.AGGREGATION: case IsmType.STORAGE_AGGREGATION: @@ -103,8 +98,13 @@ export function ismTypeToModuleType(ismType: IsmType): ModuleType { } } +export type ValidatorConfig = { + address: Address; + alias: string; +}; + export type MultisigConfig = { - validators: Array
; + validators: Array; threshold: number; }; @@ -126,11 +126,21 @@ export type NullIsmConfig = | OpStackIsmConfig | TrustedRelayerIsmConfig; -export type RoutingIsmConfig = OwnableConfig & { - type: IsmType.ROUTING | IsmType.FALLBACK_ROUTING; - domains: ChainMap; +type BaseRoutingIsmConfig< + T extends IsmType.ROUTING | IsmType.FALLBACK_ROUTING | IsmType.ICA_ROUTING, +> = { + type: T; }; +export type DomainRoutingIsmConfig = BaseRoutingIsmConfig< + IsmType.ROUTING | IsmType.FALLBACK_ROUTING +> & + OwnableConfig & { domains: ChainMap }; + +export type IcaRoutingIsmConfig = BaseRoutingIsmConfig; + +export type RoutingIsmConfig = IcaRoutingIsmConfig | DomainRoutingIsmConfig; + export type AggregationIsmConfig = { type: IsmType.AGGREGATION | IsmType.STORAGE_AGGREGATION; modules: Array; @@ -143,6 +153,7 @@ export type DeployedIsmType = { [IsmType.CUSTOM]: IInterchainSecurityModule; [IsmType.ROUTING]: IRoutingIsm; [IsmType.FALLBACK_ROUTING]: IRoutingIsm; + [IsmType.ICA_ROUTING]: IRoutingIsm; [IsmType.AGGREGATION]: IAggregationIsm; [IsmType.STORAGE_AGGREGATION]: IAggregationIsm; [IsmType.MERKLE_ROOT_MULTISIG]: IMultisigIsm; @@ -167,3 +178,106 @@ export type RoutingIsmDelta = { owner?: Address; // is the owner different mailbox?: Address; // is the mailbox different (only for fallback routing) }; + +const ValidatorInfoSchema = z.object({ + signingAddress: ZHash, + weight: z.number(), +}); + +export const TestIsmConfigSchema = z.object({ + type: z.literal(IsmType.TEST_ISM), +}); + +export const MultisigConfigSchema = z.object({ + validators: z.array(ZHash), + threshold: z.number(), +}); + +export const WeightedMultisigConfigSchema = z.object({ + validators: z.array(ValidatorInfoSchema), + thresholdWeight: z.number(), +}); + +export const TrustedRelayerIsmConfigSchema = z.object({ + type: z.literal(IsmType.TRUSTED_RELAYER), + relayer: z.string(), +}); + +export const OpStackIsmConfigSchema = z.object({ + type: z.literal(IsmType.OP_STACK), + origin: z.string(), + nativeBridge: z.string(), +}); + +export const ArbL2ToL1IsmConfigSchema = z.object({ + type: z.literal(IsmType.ARB_L2_TO_L1), + bridge: z.string(), +}); + +export const PausableIsmConfigSchema = PausableSchema.and( + z.object({ + type: z.literal(IsmType.PAUSABLE), + }), +); + +export const MultisigIsmConfigSchema = MultisigConfigSchema.and( + z.object({ + type: z.union([ + z.literal(IsmType.MERKLE_ROOT_MULTISIG), + z.literal(IsmType.MESSAGE_ID_MULTISIG), + z.literal(IsmType.STORAGE_MERKLE_ROOT_MULTISIG), + z.literal(IsmType.STORAGE_MESSAGE_ID_MULTISIG), + ]), + }), +); + +export const WeightedMultisigIsmConfigSchema = WeightedMultisigConfigSchema.and( + z.object({ + type: z.union([ + z.literal(IsmType.WEIGHTED_MERKLE_ROOT_MULTISIG), + z.literal(IsmType.WEIGHTED_MESSAGE_ID_MULTISIG), + ]), + }), +); + +export const RoutingIsmConfigSchema: z.ZodSchema = z.lazy( + () => + z.discriminatedUnion('type', [ + z.object({ + type: z.literal(IsmType.ICA_ROUTING), + }), + OwnableSchema.extend({ + type: z.literal(IsmType.ROUTING), + domains: z.record(IsmConfigSchema), + }), + OwnableSchema.extend({ + type: z.literal(IsmType.FALLBACK_ROUTING), + domains: z.record(IsmConfigSchema), + }), + ]), +); + +export const AggregationIsmConfigSchema: z.ZodSchema = z + .lazy(() => + z.object({ + type: z.literal(IsmType.AGGREGATION), + modules: z.array(IsmConfigSchema), + threshold: z.number(), + }), + ) + .refine((data) => data.threshold <= data.modules.length, { + message: 'Threshold must be less than or equal to the number of modules', + }); + +export const IsmConfigSchema = z.union([ + ZHash, + TestIsmConfigSchema, + OpStackIsmConfigSchema, + PausableIsmConfigSchema, + TrustedRelayerIsmConfigSchema, + MultisigIsmConfigSchema, + WeightedMultisigIsmConfigSchema, + RoutingIsmConfigSchema, + AggregationIsmConfigSchema, + ArbL2ToL1IsmConfigSchema, +]); diff --git a/typescript/sdk/src/ism/utils.ts b/typescript/sdk/src/ism/utils.ts index 7c28d757a1..5989854ab7 100644 --- a/typescript/sdk/src/ism/utils.ts +++ b/typescript/sdk/src/ism/utils.ts @@ -28,6 +28,7 @@ import { MultiProvider } from '../providers/MultiProvider.js'; import { ChainName } from '../types.js'; import { + DomainRoutingIsmConfig, IsmConfig, IsmType, ModuleType, @@ -41,8 +42,8 @@ const logger = rootLogger.child({ module: 'IsmUtils' }); // Determines the domains to enroll and unenroll to update the current ISM config // to match the target ISM config. export function calculateDomainRoutingDelta( - current: RoutingIsmConfig, - target: RoutingIsmConfig, + current: DomainRoutingIsmConfig, + target: DomainRoutingIsmConfig, ): { domainsToEnroll: ChainName[]; domainsToUnenroll: ChainName[] } { const domainsToEnroll = []; for (const origin of Object.keys(target.domains)) { @@ -270,7 +271,7 @@ export async function moduleMatchesConfig( let mailboxAddress; try { mailboxAddress = await client.mailbox(); - } catch (error) { + } catch { matches = false; break; } @@ -405,6 +406,31 @@ export async function routingModuleDelta( multiProvider: MultiProvider, contracts: HyperlaneContracts, mailbox?: Address, +): Promise { + if (config.type === IsmType.ICA_ROUTING) { + return { + domainsToEnroll: [], + domainsToUnenroll: [], + }; + } + + return domainRoutingModuleDelta( + destination, + moduleAddress, + config, + multiProvider, + contracts, + mailbox, + ); +} + +async function domainRoutingModuleDelta( + destination: ChainName, + moduleAddress: Address, + config: DomainRoutingIsmConfig, + multiProvider: MultiProvider, + contracts: HyperlaneContracts, + mailbox?: Address, ): Promise { const provider = multiProvider.getProvider(destination); const routingIsm = DomainRoutingIsm__factory.connect(moduleAddress, provider); @@ -412,10 +438,6 @@ export async function routingModuleDelta( const deployedDomains = (await routingIsm.domains()).map((domain) => domain.toNumber(), ); - // config.domains is already filtered to only include domains in the multiprovider - const safeConfigDomains = objMap(config.domains, (chainName) => - multiProvider.getDomainId(chainName), - ); const delta: RoutingIsmDelta = { domainsToUnenroll: [], @@ -423,14 +445,21 @@ export async function routingModuleDelta( }; // if owners don't match, we need to transfer ownership - const expectedOwner = config.owner; - if (!eqAddress(owner, normalizeAddress(expectedOwner))) - delta.owner = expectedOwner; + if (!eqAddress(owner, normalizeAddress(config.owner))) { + delta.owner = config.owner; + } + if (config.type === IsmType.FALLBACK_ROUTING) { const client = MailboxClient__factory.connect(moduleAddress, provider); const mailboxAddress = await client.mailbox(); if (mailbox && !eqAddress(mailboxAddress, mailbox)) delta.mailbox = mailbox; } + + // config.domains is already filtered to only include domains in the multiprovider + const safeConfigDomains = objMap(config.domains, (chainName) => + multiProvider.getDomainId(chainName), + ); + // check for exclusion of domains in the config delta.domainsToUnenroll = deployedDomains.filter( (domain) => !Object.values(safeConfigDomains).includes(domain), @@ -457,6 +486,7 @@ export async function routingModuleDelta( } } } + return delta; } diff --git a/typescript/sdk/src/middleware/account/schemas.ts b/typescript/sdk/src/middleware/account/schemas.ts deleted file mode 100644 index 6e90b1a193..0000000000 --- a/typescript/sdk/src/middleware/account/schemas.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { z } from 'zod'; - -import { ZChainName, ZHash } from '../../metadata/customZodTypes.js'; -import { - BigNumberSchema, - CallDataSchema, -} from '../../providers/transactions/schemas.js'; - -export const AccountConfigSchema = z.object({ - origin: ZChainName, - owner: ZHash, - localRouter: ZHash.optional(), - routerOverride: ZHash.optional(), - ismOverride: ZHash.optional(), -}); - -/* For InterchainAccount::getCallRemote() */ -export const GetCallRemoteSettingsSchema = z.object({ - chain: ZChainName, - destination: ZChainName, - innerCalls: z.array(CallDataSchema), - config: AccountConfigSchema, - hookMetadata: BigNumberSchema.optional(), -}); diff --git a/typescript/sdk/src/middleware/account/types.ts b/typescript/sdk/src/middleware/account/types.ts index 58dd28d14b..519d96fab1 100644 --- a/typescript/sdk/src/middleware/account/types.ts +++ b/typescript/sdk/src/middleware/account/types.ts @@ -1,7 +1,29 @@ import { z } from 'zod'; -import { AccountConfigSchema, GetCallRemoteSettingsSchema } from './schemas.js'; +import { ZChainName, ZHash } from '../../metadata/customZodTypes.js'; +import { + BigNumberSchema, + CallDataSchema, +} from '../../providers/transactions/types.js'; + +export const AccountConfigSchema = z.object({ + origin: ZChainName, + owner: ZHash, + localRouter: ZHash.optional(), + routerOverride: ZHash.optional(), + ismOverride: ZHash.optional(), +}); export type AccountConfig = z.infer; + /* For InterchainAccount::getCallRemote() */ +export const GetCallRemoteSettingsSchema = z.object({ + chain: ZChainName, + destination: ZChainName, + innerCalls: z.array(CallDataSchema), + config: AccountConfigSchema, + hookMetadata: BigNumberSchema.optional(), +}); +/* For InterchainAccount::getCallRemote() */ + export type GetCallRemoteSettings = z.infer; diff --git a/typescript/sdk/src/middleware/liquidity-layer/.eslintrc b/typescript/sdk/src/middleware/liquidity-layer/.eslintrc deleted file mode 100644 index e3f712414b..0000000000 --- a/typescript/sdk/src/middleware/liquidity-layer/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "no-console": ["off"] - } -} diff --git a/typescript/sdk/src/middleware/liquidity-layer/LiquidityLayerApp.ts b/typescript/sdk/src/middleware/liquidity-layer/LiquidityLayerApp.ts index 93e324a24d..6e26989348 100644 --- a/typescript/sdk/src/middleware/liquidity-layer/LiquidityLayerApp.ts +++ b/typescript/sdk/src/middleware/liquidity-layer/LiquidityLayerApp.ts @@ -11,6 +11,7 @@ import { addressToBytes32, ensure0x, eqAddress, + rootLogger, strip0x, } from '@hyperlane-xyz/utils'; @@ -23,6 +24,8 @@ import { fetchWithTimeout } from '../../utils/fetch.js'; import { BridgeAdapterConfig } from './LiquidityLayerRouterDeployer.js'; import { liquidityLayerFactories } from './contracts.js'; +const logger = rootLogger.child({ module: 'LiquidityLayerApp' }); + const PORTAL_VAA_SERVICE_TESTNET_BASE_URL = 'https://wormhole-v2-testnet-api.certus.one/v1/signed_vaa/'; const CIRCLE_ATTESTATIONS_TESTNET_BASE_URL = @@ -77,7 +80,7 @@ export class LiquidityLayerApp extends HyperlaneApp< } async fetchCircleMessageTransactions(chain: ChainName): Promise { - console.log(`Fetch circle messages for ${chain}`); + logger.info(`Fetch circle messages for ${chain}`); const url = new URL(this.multiProvider.getExplorerApiUrl(chain)); url.searchParams.set('module', 'logs'); url.searchParams.set('action', 'getLogs'); @@ -140,7 +143,7 @@ export class LiquidityLayerApp extends HyperlaneApp< chain: ChainName, txHash: string, ): Promise { - console.debug(`Parse Circle messages for chain ${chain} ${txHash}`); + logger.debug(`Parse Circle messages for chain ${chain} ${txHash}`); const provider = this.multiProvider.getProvider(chain); const receipt = await provider.getTransactionReceipt(txHash); const matchingLogs = receipt.logs @@ -207,7 +210,7 @@ export class LiquidityLayerApp extends HyperlaneApp< await destinationPortalAdapter.portalTransfersProcessed(transferId); if (!eqAddress(transferTokenAddress, ethers.constants.AddressZero)) { - console.log( + logger.info( `Transfer with nonce ${message.nonce} from ${message.origin} to ${message.destination} already processed`, ); return; @@ -229,11 +232,11 @@ export class LiquidityLayerApp extends HyperlaneApp< ).then((response) => response.json()); if (vaa.code && vaa.code === PORTAL_VAA_SERVICE_SUCCESS_CODE) { - console.log(`VAA not yet found for nonce ${message.nonce}`); + logger.info(`VAA not yet found for nonce ${message.nonce}`); return; } - console.debug( + logger.debug( `Complete portal transfer for nonce ${message.nonce} on ${message.destination}`, ); @@ -246,10 +249,10 @@ export class LiquidityLayerApp extends HyperlaneApp< ); } catch (error: any) { if (error?.error?.reason?.includes('no wrapper for this token')) { - console.log( + logger.info( 'No wrapper for this token, you should register the token at https://wormhole-foundation.github.io/example-token-bridge-ui/#/register', ); - console.log(message); + logger.info(message); return; } throw error; @@ -268,11 +271,11 @@ export class LiquidityLayerApp extends HyperlaneApp< const alreadyProcessed = await transmitter.usedNonces(message.nonceHash); if (alreadyProcessed) { - console.log(`Message sent on ${message.txHash} was already processed`); + logger.info(`Message sent on ${message.txHash} was already processed`); return; } - console.log(`Attempt Circle message delivery`, JSON.stringify(message)); + logger.info(`Attempt Circle message delivery`, JSON.stringify(message)); const messageHash = ethers.utils.keccak256(message.message); const baseurl = this.multiProvider.getChainMetadata(message.chain).isTestnet @@ -282,19 +285,19 @@ export class LiquidityLayerApp extends HyperlaneApp< const attestations = await attestationsB.json(); if (attestations.status !== 'complete') { - console.log( + logger.info( `Attestations not available for message nonce ${message.nonce} on ${message.txHash}`, ); return; } - console.log(`Ready to submit attestations for message ${message.nonce}`); + logger.info(`Ready to submit attestations for message ${message.nonce}`); const tx = await transmitter.receiveMessage( message.message, attestations.attestation, ); - console.log( + logger.info( `Submitted attestations in ${this.multiProvider.tryGetExplorerTxUrl( message.remoteChain, tx, diff --git a/typescript/sdk/src/providers/SmartProvider/SmartProvider.ts b/typescript/sdk/src/providers/SmartProvider/SmartProvider.ts index 58ee3e7ef1..d30f9ddd11 100644 --- a/typescript/sdk/src/providers/SmartProvider/SmartProvider.ts +++ b/typescript/sdk/src/providers/SmartProvider/SmartProvider.ts @@ -1,5 +1,5 @@ import { BigNumber, errors as EthersError, providers, utils } from 'ethers'; -import pino, { Logger } from 'pino'; +import { Logger, pino } from 'pino'; import { raceWithContext, @@ -126,7 +126,7 @@ export class HyperlaneSmartProvider async getPriorityFee(): Promise { try { return BigNumber.from(await this.perform('maxPriorityFeePerGas', {})); - } catch (error) { + } catch { return BigNumber.from('1500000000'); } } diff --git a/typescript/sdk/src/providers/explorerHealthTest.ts b/typescript/sdk/src/providers/explorerHealthTest.ts index 4e6d8be3ff..904044fbdf 100644 --- a/typescript/sdk/src/providers/explorerHealthTest.ts +++ b/typescript/sdk/src/providers/explorerHealthTest.ts @@ -1,4 +1,3 @@ -import { ChainMetadata } from '@hyperlane-xyz/sdk'; import { Address, ProtocolType, rootLogger } from '@hyperlane-xyz/utils'; import { @@ -6,6 +5,7 @@ import { getExplorerBaseUrl, getExplorerTxUrl, } from '../metadata/blockExplorer.js'; +import { ChainMetadata } from '../metadata/chainMetadataTypes.js'; const PROTOCOL_TO_ADDRESS: Record = { [ProtocolType.Ethereum]: '0x0000000000000000000000000000000000000000', diff --git a/typescript/sdk/src/providers/transactions/schemas.ts b/typescript/sdk/src/providers/transactions/schemas.ts deleted file mode 100644 index 7547f47e4e..0000000000 --- a/typescript/sdk/src/providers/transactions/schemas.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { z } from 'zod'; - -import { ZHash } from '../../metadata/customZodTypes.js'; - -export const BigNumberSchema = z.string(); - -export const CallDataSchema = z.object({ - to: ZHash, - data: z.string(), - value: BigNumberSchema.optional(), -}); diff --git a/typescript/sdk/src/providers/transactions/submitter/builder/TxSubmitterBuilder.ts b/typescript/sdk/src/providers/transactions/submitter/builder/TxSubmitterBuilder.ts index 53d1b44524..61616ff3c0 100644 --- a/typescript/sdk/src/providers/transactions/submitter/builder/TxSubmitterBuilder.ts +++ b/typescript/sdk/src/providers/transactions/submitter/builder/TxSubmitterBuilder.ts @@ -1,7 +1,6 @@ import { Logger } from 'pino'; -import { Annotated, rootLogger } from '@hyperlane-xyz/utils'; -import { ProtocolType } from '@hyperlane-xyz/utils'; +import { Annotated, ProtocolType, rootLogger } from '@hyperlane-xyz/utils'; import { ProtocolTypedReceipt, diff --git a/typescript/sdk/src/providers/transactions/submitter/builder/schemas.ts b/typescript/sdk/src/providers/transactions/submitter/builder/schemas.ts deleted file mode 100644 index cec2d81935..0000000000 --- a/typescript/sdk/src/providers/transactions/submitter/builder/schemas.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { z } from 'zod'; - -import { ZChainName } from '../../../../metadata/customZodTypes.js'; -import { TransformerMetadataSchema } from '../../transformer/schemas.js'; -import { SubmitterMetadataSchema } from '../schemas.js'; - -export const SubmissionStrategySchema = z.object({ - submitter: SubmitterMetadataSchema, - transforms: z.array(TransformerMetadataSchema).optional(), -}); - -export const ChainSubmissionStrategySchema = z.record( - ZChainName, - SubmissionStrategySchema, -); diff --git a/typescript/sdk/src/providers/transactions/submitter/builder/types.ts b/typescript/sdk/src/providers/transactions/submitter/builder/types.ts index ea4460cd4e..6a4987dbf6 100644 --- a/typescript/sdk/src/providers/transactions/submitter/builder/types.ts +++ b/typescript/sdk/src/providers/transactions/submitter/builder/types.ts @@ -1,11 +1,21 @@ import { z } from 'zod'; -import { - ChainSubmissionStrategySchema, - SubmissionStrategySchema, -} from './schemas.js'; +import { ZChainName } from '../../../../metadata/customZodTypes.js'; +import { TransformerMetadataSchema } from '../../transformer/types.js'; +import { SubmitterMetadataSchema } from '../types.js'; + +export const SubmissionStrategySchema = z.object({ + submitter: SubmitterMetadataSchema, + transforms: z.array(TransformerMetadataSchema).optional(), +}); export type SubmissionStrategy = z.infer; + +export const ChainSubmissionStrategySchema = z.record( + ZChainName, + SubmissionStrategySchema, +); + export type ChainSubmissionStrategy = z.infer< typeof ChainSubmissionStrategySchema >; diff --git a/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.ts deleted file mode 100644 index 1586ec6b28..0000000000 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { z } from 'zod'; - -import { ZChainName, ZHash } from '../../../../metadata/customZodTypes.js'; - -export const EV5GnosisSafeTxSubmitterPropsSchema = z.object({ - chain: ZChainName, - safeAddress: ZHash, -}); - -export const EV5GnosisSafeTxBuilderPropsSchema = z.object({ - version: z.string().default('1.0'), - chain: ZChainName, - safeAddress: ZHash, -}); - -export const EV5JsonRpcTxSubmitterPropsSchema = z.object({ - chain: ZChainName, -}); - -export const EV5ImpersonatedAccountTxSubmitterPropsSchema = - EV5JsonRpcTxSubmitterPropsSchema.extend({ - userAddress: ZHash, - }); diff --git a/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.test.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/types.test.ts similarity index 98% rename from typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.test.ts rename to typescript/sdk/src/providers/transactions/submitter/ethersV5/types.test.ts index 7cce08cadf..6718410a32 100644 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.test.ts +++ b/typescript/sdk/src/providers/transactions/submitter/ethersV5/types.test.ts @@ -4,13 +4,11 @@ import { Address } from '@hyperlane-xyz/utils'; import { ChainName } from '../../../../types.js'; -import { - EV5GnosisSafeTxSubmitterPropsSchema, - EV5ImpersonatedAccountTxSubmitterPropsSchema, -} from './schemas.js'; import { EV5GnosisSafeTxSubmitterProps, + EV5GnosisSafeTxSubmitterPropsSchema, EV5ImpersonatedAccountTxSubmitterProps, + EV5ImpersonatedAccountTxSubmitterPropsSchema, } from './types.js'; describe('ethersV5 submitter props schemas', () => { diff --git a/typescript/sdk/src/providers/transactions/submitter/ethersV5/types.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/types.ts index 71a8458419..d1e1c7a90c 100644 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/types.ts +++ b/typescript/sdk/src/providers/transactions/submitter/ethersV5/types.ts @@ -1,21 +1,39 @@ import { z } from 'zod'; -import { - EV5GnosisSafeTxBuilderPropsSchema, - EV5GnosisSafeTxSubmitterPropsSchema, - EV5ImpersonatedAccountTxSubmitterPropsSchema, - EV5JsonRpcTxSubmitterPropsSchema, -} from './schemas.js'; +import { ZChainName, ZHash } from '../../../../metadata/customZodTypes.js'; + +export const EV5GnosisSafeTxSubmitterPropsSchema = z.object({ + chain: ZChainName, + safeAddress: ZHash, +}); export type EV5GnosisSafeTxSubmitterProps = z.infer< typeof EV5GnosisSafeTxSubmitterPropsSchema >; + +export const EV5GnosisSafeTxBuilderPropsSchema = z.object({ + version: z.string().default('1.0'), + chain: ZChainName, + safeAddress: ZHash, +}); + export type EV5GnosisSafeTxBuilderProps = z.infer< typeof EV5GnosisSafeTxBuilderPropsSchema >; + +export const EV5JsonRpcTxSubmitterPropsSchema = z.object({ + chain: ZChainName, +}); + export type EV5JsonRpcTxSubmitterProps = z.infer< typeof EV5JsonRpcTxSubmitterPropsSchema >; + +export const EV5ImpersonatedAccountTxSubmitterPropsSchema = + EV5JsonRpcTxSubmitterPropsSchema.extend({ + userAddress: ZHash, + }); + export type EV5ImpersonatedAccountTxSubmitterProps = z.infer< typeof EV5ImpersonatedAccountTxSubmitterPropsSchema >; diff --git a/typescript/sdk/src/providers/transactions/submitter/schemas.ts b/typescript/sdk/src/providers/transactions/submitter/schemas.ts deleted file mode 100644 index 998d4404bd..0000000000 --- a/typescript/sdk/src/providers/transactions/submitter/schemas.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { z } from 'zod'; - -import { TxSubmitterType } from './TxSubmitterTypes.js'; -import { - EV5GnosisSafeTxBuilderPropsSchema, - EV5GnosisSafeTxSubmitterPropsSchema, - EV5ImpersonatedAccountTxSubmitterPropsSchema, - EV5JsonRpcTxSubmitterPropsSchema, -} from './ethersV5/schemas.js'; - -export const SubmitterMetadataSchema = z.discriminatedUnion('type', [ - z.object({ - type: z.literal(TxSubmitterType.JSON_RPC), - ...EV5JsonRpcTxSubmitterPropsSchema.shape, - }), - z.object({ - type: z.literal(TxSubmitterType.IMPERSONATED_ACCOUNT), - ...EV5ImpersonatedAccountTxSubmitterPropsSchema.shape, - }), - z.object({ - type: z.literal(TxSubmitterType.GNOSIS_SAFE), - ...EV5GnosisSafeTxSubmitterPropsSchema.shape, - }), - z.object({ - type: z.literal(TxSubmitterType.GNOSIS_TX_BUILDER), - ...EV5GnosisSafeTxBuilderPropsSchema.shape, - }), -]); diff --git a/typescript/sdk/src/providers/transactions/submitter/types.ts b/typescript/sdk/src/providers/transactions/submitter/types.ts index 92e79f9b4b..6f0b66c84a 100644 --- a/typescript/sdk/src/providers/transactions/submitter/types.ts +++ b/typescript/sdk/src/providers/transactions/submitter/types.ts @@ -1,5 +1,30 @@ import { z } from 'zod'; -import { SubmitterMetadataSchema } from './schemas.js'; +import { TxSubmitterType } from './TxSubmitterTypes.js'; +import { + EV5GnosisSafeTxBuilderPropsSchema, + EV5GnosisSafeTxSubmitterPropsSchema, + EV5ImpersonatedAccountTxSubmitterPropsSchema, + EV5JsonRpcTxSubmitterPropsSchema, +} from './ethersV5/types.js'; + +export const SubmitterMetadataSchema = z.discriminatedUnion('type', [ + z.object({ + type: z.literal(TxSubmitterType.JSON_RPC), + ...EV5JsonRpcTxSubmitterPropsSchema.shape, + }), + z.object({ + type: z.literal(TxSubmitterType.IMPERSONATED_ACCOUNT), + ...EV5ImpersonatedAccountTxSubmitterPropsSchema.shape, + }), + z.object({ + type: z.literal(TxSubmitterType.GNOSIS_SAFE), + ...EV5GnosisSafeTxSubmitterPropsSchema.shape, + }), + z.object({ + type: z.literal(TxSubmitterType.GNOSIS_TX_BUILDER), + ...EV5GnosisSafeTxBuilderPropsSchema.shape, + }), +]); export type SubmitterMetadata = z.infer; diff --git a/typescript/sdk/src/providers/transactions/transformer/ethersV5/schemas.ts b/typescript/sdk/src/providers/transactions/transformer/ethersV5/schemas.ts deleted file mode 100644 index 7d49b0e919..0000000000 --- a/typescript/sdk/src/providers/transactions/transformer/ethersV5/schemas.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { GetCallRemoteSettingsSchema } from '../../../../middleware/account/schemas.js'; - -export const EV5InterchainAccountTxTransformerPropsSchema = - GetCallRemoteSettingsSchema.pick({ - chain: true, - config: true, - hookMetadata: true, - }); diff --git a/typescript/sdk/src/providers/transactions/transformer/ethersV5/schemas.test.ts b/typescript/sdk/src/providers/transactions/transformer/ethersV5/types.test.ts similarity index 91% rename from typescript/sdk/src/providers/transactions/transformer/ethersV5/schemas.test.ts rename to typescript/sdk/src/providers/transactions/transformer/ethersV5/types.test.ts index 5418f31fe7..72bb52ed23 100644 --- a/typescript/sdk/src/providers/transactions/transformer/ethersV5/schemas.test.ts +++ b/typescript/sdk/src/providers/transactions/transformer/ethersV5/types.test.ts @@ -4,8 +4,10 @@ import { Address } from '@hyperlane-xyz/utils'; import { ChainName } from '../../../../types.js'; -import { EV5InterchainAccountTxTransformerPropsSchema } from './schemas.js'; -import { EV5InterchainAccountTxTransformerProps } from './types.js'; +import { + EV5InterchainAccountTxTransformerProps, + EV5InterchainAccountTxTransformerPropsSchema, +} from './types.js'; describe('ethersV5 transformer props schemas', () => { const CHAIN_MOCK: ChainName = 'ethereum'; diff --git a/typescript/sdk/src/providers/transactions/transformer/ethersV5/types.ts b/typescript/sdk/src/providers/transactions/transformer/ethersV5/types.ts index f4b848f429..4e4457fd18 100644 --- a/typescript/sdk/src/providers/transactions/transformer/ethersV5/types.ts +++ b/typescript/sdk/src/providers/transactions/transformer/ethersV5/types.ts @@ -1,6 +1,13 @@ import { z } from 'zod'; -import { EV5InterchainAccountTxTransformerPropsSchema } from './schemas.js'; +import { GetCallRemoteSettingsSchema } from '../../../../middleware/account/types.js'; + +export const EV5InterchainAccountTxTransformerPropsSchema = + GetCallRemoteSettingsSchema.pick({ + chain: true, + config: true, + hookMetadata: true, + }); export type EV5InterchainAccountTxTransformerProps = z.infer< typeof EV5InterchainAccountTxTransformerPropsSchema diff --git a/typescript/sdk/src/providers/transactions/transformer/schemas.ts b/typescript/sdk/src/providers/transactions/transformer/schemas.ts deleted file mode 100644 index 621e5d0c6e..0000000000 --- a/typescript/sdk/src/providers/transactions/transformer/schemas.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { z } from 'zod'; - -import { TxTransformerType } from './TxTransformerTypes.js'; -import { EV5InterchainAccountTxTransformerPropsSchema } from './ethersV5/schemas.js'; - -export const TransformerMetadataSchema = z.discriminatedUnion('type', [ - z.object({ - type: z.literal(TxTransformerType.INTERCHAIN_ACCOUNT), - ...EV5InterchainAccountTxTransformerPropsSchema.shape, - }), -]); diff --git a/typescript/sdk/src/providers/transactions/transformer/types.ts b/typescript/sdk/src/providers/transactions/transformer/types.ts index 7f5e479124..4eedeb9cc4 100644 --- a/typescript/sdk/src/providers/transactions/transformer/types.ts +++ b/typescript/sdk/src/providers/transactions/transformer/types.ts @@ -1,5 +1,13 @@ import { z } from 'zod'; -import { TransformerMetadataSchema } from './schemas.js'; +import { TxTransformerType } from './TxTransformerTypes.js'; +import { EV5InterchainAccountTxTransformerPropsSchema } from './ethersV5/types.js'; + +export const TransformerMetadataSchema = z.discriminatedUnion('type', [ + z.object({ + type: z.literal(TxTransformerType.INTERCHAIN_ACCOUNT), + ...EV5InterchainAccountTxTransformerPropsSchema.shape, + }), +]); export type TransformerMetadata = z.infer; diff --git a/typescript/sdk/src/providers/transactions/schemas.test.ts b/typescript/sdk/src/providers/transactions/types.test.ts similarity index 93% rename from typescript/sdk/src/providers/transactions/schemas.test.ts rename to typescript/sdk/src/providers/transactions/types.test.ts index 8631a3f556..e6c50ba5ff 100644 --- a/typescript/sdk/src/providers/transactions/schemas.test.ts +++ b/typescript/sdk/src/providers/transactions/types.test.ts @@ -2,8 +2,7 @@ import { expect } from 'chai'; import { Address } from '@hyperlane-xyz/utils'; -import { CallDataSchema } from './schemas.js'; -import { CallData } from './types.js'; +import { CallData, CallDataSchema } from './types.js'; describe('transactions schemas', () => { const ADDRESS_MOCK: Address = '0x1234567890123456789012345678901234567890'; diff --git a/typescript/sdk/src/providers/transactions/types.ts b/typescript/sdk/src/providers/transactions/types.ts index 49585f2154..e3d6d28abf 100644 --- a/typescript/sdk/src/providers/transactions/types.ts +++ b/typescript/sdk/src/providers/transactions/types.ts @@ -1,5 +1,13 @@ import { z } from 'zod'; -import { CallDataSchema } from './schemas.js'; +import { ZHash } from '../../metadata/customZodTypes.js'; + +export const BigNumberSchema = z.string(); + +export const CallDataSchema = z.object({ + to: ZHash, + data: z.string(), + value: BigNumberSchema.optional(), +}); export type CallData = z.infer; diff --git a/typescript/sdk/src/router/HyperlaneRouterDeployer.ts b/typescript/sdk/src/router/HyperlaneRouterDeployer.ts index bc68d047c1..8cc4562461 100644 --- a/typescript/sdk/src/router/HyperlaneRouterDeployer.ts +++ b/typescript/sdk/src/router/HyperlaneRouterDeployer.ts @@ -55,48 +55,56 @@ export abstract class HyperlaneRouterDeployer< const allRouters = objMerge(deployedRouters, foreignRouters); const allChains = Object.keys(allRouters); - for (const [chain, contracts] of Object.entries(deployedContractsMap)) { - const allRemoteChains = this.multiProvider - .getRemoteChains(chain) - .filter((c) => allChains.includes(c)); - - const enrollEntries = await Promise.all( - allRemoteChains.map(async (remote) => { - const remoteDomain = this.multiProvider.getDomainId(remote); - const current = await this.router(contracts).routers(remoteDomain); - const expected = addressToBytes32(allRouters[remote]); - return current !== expected ? [remoteDomain, expected] : undefined; - }), - ); - const entries = enrollEntries.filter( - (entry): entry is [number, string] => entry !== undefined, - ); - const domains = entries.map(([id]) => id); - const addresses = entries.map(([, address]) => address); - - // skip if no enrollments are needed - if (domains.length === 0) { - continue; - } - - await super.runIfOwner(chain, this.router(contracts), async () => { - const chains = domains.map((id) => this.multiProvider.getChainName(id)); - this.logger.debug( - `Enrolling remote routers (${chains.join(', ')}) on ${chain}`, + await Promise.all( + Object.entries(deployedContractsMap).map(async ([chain, contracts]) => { + const allRemoteChains = this.multiProvider + .getRemoteChains(chain) + .filter((c) => allChains.includes(c)); + + const enrollEntries = await Promise.all( + allRemoteChains.map(async (remote) => { + const remoteDomain = this.multiProvider.getDomainId(remote); + const current = await this.router(contracts).routers(remoteDomain); + const expected = addressToBytes32(allRouters[remote]); + return current !== expected ? [remoteDomain, expected] : undefined; + }), ); - const router = this.router(contracts); - const estimatedGas = await router.estimateGas.enrollRemoteRouters( - domains, - addresses, + const entries = enrollEntries.filter( + (entry): entry is [number, string] => entry !== undefined, ); - // deploy with 10% buffer on gas limit - const enrollTx = await router.enrollRemoteRouters(domains, addresses, { - gasLimit: addBufferToGasLimit(estimatedGas), - ...this.multiProvider.getTransactionOverrides(chain), + const domains = entries.map(([id]) => id); + const addresses = entries.map(([, address]) => address); + + // skip if no enrollments are needed + if (domains.length === 0) { + return; + } + + await super.runIfOwner(chain, this.router(contracts), async () => { + const chains = domains.map((id) => + this.multiProvider.getChainName(id), + ); + this.logger.debug( + `Enrolling remote routers (${chains.join(', ')}) on ${chain}`, + ); + const router = this.router(contracts); + const estimatedGas = await router.estimateGas.enrollRemoteRouters( + domains, + addresses, + ); + // deploy with 10% buffer on gas limit + const enrollTx = await router.enrollRemoteRouters( + domains, + addresses, + { + gasLimit: addBufferToGasLimit(estimatedGas), + ...this.multiProvider.getTransactionOverrides(chain), + }, + ); + await this.multiProvider.handleTx(chain, enrollTx); }); - await this.multiProvider.handleTx(chain, enrollTx); - }); - } + }), + ); } async transferOwnership( diff --git a/typescript/sdk/src/router/schemas.ts b/typescript/sdk/src/router/schemas.ts deleted file mode 100644 index 571cb0d1f5..0000000000 --- a/typescript/sdk/src/router/schemas.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { z } from 'zod'; - -import { ProxyFactoryFactoriesSchema } from '../deploy/schemas.js'; -import { HookConfigSchema } from '../hook/schemas.js'; -import { IsmConfigSchema } from '../ism/schemas.js'; -import { ZHash } from '../metadata/customZodTypes.js'; -import { DeployedOwnableSchema, OwnableSchema } from '../schemas.js'; - -export const MailboxClientConfigSchema = OwnableSchema.extend({ - mailbox: ZHash, - hook: HookConfigSchema.optional(), - interchainSecurityModule: IsmConfigSchema.optional(), - ismFactoryAddresses: ProxyFactoryFactoriesSchema.optional(), -}); - -export const ForeignDeploymentConfigSchema = z.object({ - foreignDeployment: z.string().optional(), -}); - -const RemoteRouterDomain = z.string(); -const RemoteRouterRouter = z.string().startsWith('0x'); -export const RemoteRoutersSchema = z.record( - RemoteRouterDomain, - RemoteRouterRouter, -); - -export const RouterConfigSchema = MailboxClientConfigSchema.merge( - ForeignDeploymentConfigSchema, -).merge( - z.object({ - remoteRouters: RemoteRoutersSchema.optional(), - proxyAdmin: DeployedOwnableSchema.optional(), - }), -); - -const DestinationGasDomain = z.string(); -const DestinationGasAmount = z.string(); // This must be a string type to match Ether's type -export const DestinationGasSchema = z.record( - DestinationGasDomain, - DestinationGasAmount, -); -export const GasRouterConfigSchema = RouterConfigSchema.extend({ - gas: z.number().optional(), - destinationGas: DestinationGasSchema.optional(), -}); diff --git a/typescript/sdk/src/router/types.ts b/typescript/sdk/src/router/types.ts index 17e36ead66..a4dd355f2f 100644 --- a/typescript/sdk/src/router/types.ts +++ b/typescript/sdk/src/router/types.ts @@ -11,15 +11,10 @@ import { Address, AddressBytes32 } from '@hyperlane-xyz/utils'; import { HyperlaneFactories } from '../contracts/types.js'; import { UpgradeConfig } from '../deploy/proxy.js'; import { CheckerViolation } from '../deploy/types.js'; -import { ChainMap } from '../types.js'; - -import { - DestinationGasSchema, - GasRouterConfigSchema, - MailboxClientConfigSchema, - RemoteRoutersSchema, - RouterConfigSchema, -} from './schemas.js'; +import { HookConfigSchema } from '../hook/types.js'; +import { IsmConfigSchema } from '../ism/types.js'; +import { ZHash } from '../metadata/customZodTypes.js'; +import { ChainMap, DeployedOwnableSchema, OwnableSchema } from '../types.js'; export type RouterAddress = { router: Address; @@ -68,3 +63,42 @@ export interface RouterViolation extends CheckerViolation { export type RemoteRouters = z.infer; export type DestinationGas = z.infer; + +export const MailboxClientConfigSchema = OwnableSchema.extend({ + mailbox: ZHash, + hook: HookConfigSchema.optional(), + interchainSecurityModule: IsmConfigSchema.optional(), +}); + +export const ForeignDeploymentConfigSchema = z.object({ + foreignDeployment: z.string().optional(), +}); + +export const RemoteRouterDomain = z.string(); +export const RemoteRouterRouter = z.object({ + address: z.string().startsWith('0x'), +}); +export const RemoteRoutersSchema = z.record( + RemoteRouterDomain, + RemoteRouterRouter, +); + +export const RouterConfigSchema = MailboxClientConfigSchema.merge( + ForeignDeploymentConfigSchema, +).merge( + z.object({ + remoteRouters: RemoteRoutersSchema.optional(), + proxyAdmin: DeployedOwnableSchema.optional(), + }), +); + +const DestinationGasDomain = z.string(); +const DestinationGasAmount = z.string(); // This must be a string type to match Ether's type +export const DestinationGasSchema = z.record( + DestinationGasDomain, + DestinationGasAmount, +); +export const GasRouterConfigSchema = RouterConfigSchema.extend({ + gas: z.number().optional(), + destinationGas: DestinationGasSchema.optional(), +}); diff --git a/typescript/sdk/src/schemas.ts b/typescript/sdk/src/schemas.ts deleted file mode 100644 index ef37e92fb9..0000000000 --- a/typescript/sdk/src/schemas.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { z } from 'zod'; - -import { ZHash } from './metadata/customZodTypes.js'; - -export const OwnableSchema = z.object({ - owner: ZHash, - ownerOverrides: z.record(ZHash).optional(), -}); - -export const DeployedOwnableSchema = OwnableSchema.extend({ - address: ZHash.optional(), -}); - -export const PausableSchema = OwnableSchema.extend({ - paused: z.boolean(), -}); diff --git a/typescript/sdk/src/token/EvmERC20WarpModule.hardhat-test.ts b/typescript/sdk/src/token/EvmERC20WarpModule.hardhat-test.ts index d204aa1709..d4f16db8ad 100644 --- a/typescript/sdk/src/token/EvmERC20WarpModule.hardhat-test.ts +++ b/typescript/sdk/src/token/EvmERC20WarpModule.hardhat-test.ts @@ -1,6 +1,5 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers.js'; import { expect } from 'chai'; -import { constants } from 'ethers'; import hre from 'hardhat'; import { @@ -12,23 +11,29 @@ import { HypERC4626Collateral__factory, HypNativeCollateral__factory, Mailbox, + MailboxClient__factory, Mailbox__factory, } from '@hyperlane-xyz/core'; import { EvmIsmModule, + HookConfig, + HookType, HyperlaneAddresses, HyperlaneContractsMap, IsmConfig, IsmType, RouterConfig, TestChainName, + proxyAdmin, serializeContracts, } from '@hyperlane-xyz/sdk'; +import { randomInt } from '@hyperlane-xyz/utils'; import { TestCoreApp } from '../core/TestCoreApp.js'; import { TestCoreDeployer } from '../core/TestCoreDeployer.js'; import { HyperlaneProxyFactoryDeployer } from '../deploy/HyperlaneProxyFactoryDeployer.js'; import { ProxyFactoryFactories } from '../deploy/contracts.js'; +import { DerivedHookConfig } from '../hook/EvmHookReader.js'; import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory.js'; import { MultiProvider } from '../providers/MultiProvider.js'; import { AnnotatedEV5Transaction } from '../providers/ProviderType.js'; @@ -39,12 +44,14 @@ import { normalizeConfig } from '../utils/ism.js'; import { EvmERC20WarpModule } from './EvmERC20WarpModule.js'; import { TokenType } from './config.js'; -import { TokenRouterConfig } from './schemas.js'; +import { HypTokenRouterConfig } from './types.js'; const randomRemoteRouters = (n: number) => { const routers: RemoteRouters = {}; for (let domain = 0; domain < n; domain++) { - routers[domain] = randomAddress(); + routers[domain] = { + address: randomAddress(), + }; } return routers; }; @@ -55,7 +62,6 @@ describe('EvmERC20WarpHyperlaneModule', async () => { const TOKEN_DECIMALS = 18; const chain = TestChainName.test4; let mailbox: Mailbox; - let hookAddress: string; let ismAddress: string; let ismFactory: HyperlaneIsmFactory; let factories: HyperlaneContractsMap; @@ -70,10 +76,6 @@ describe('EvmERC20WarpHyperlaneModule', async () => { async function validateCoreValues(deployedToken: GasRouter) { expect(await deployedToken.mailbox()).to.equal(mailbox.address); - expect(await deployedToken.hook()).to.equal(hookAddress); - expect(await deployedToken.interchainSecurityModule()).to.equal( - constants.AddressZero, - ); expect(await deployedToken.owner()).to.equal(signer.address); } @@ -106,16 +108,14 @@ describe('EvmERC20WarpHyperlaneModule', async () => { baseConfig = routerConfigMap[chain]; mailbox = Mailbox__factory.connect(baseConfig.mailbox, signer); - hookAddress = await mailbox.defaultHook(); ismAddress = await mailbox.defaultIsm(); }); it('should create with a collateral config', async () => { - const config: TokenRouterConfig = { + const config: HypTokenRouterConfig = { ...baseConfig, type: TokenType.collateral, token: token.address, - hook: hookAddress, }; // Deploy using WarpModule @@ -123,6 +123,7 @@ describe('EvmERC20WarpHyperlaneModule', async () => { chain, config, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); // Let's derive it's onchain token type @@ -139,10 +140,9 @@ describe('EvmERC20WarpHyperlaneModule', async () => { TOKEN_NAME, TOKEN_NAME, ); - const config: TokenRouterConfig = { + const config: HypTokenRouterConfig = { type: TokenType.collateralVault, token: vault.address, - hook: hookAddress, ...baseConfig, }; @@ -151,6 +151,7 @@ describe('EvmERC20WarpHyperlaneModule', async () => { chain, config, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); // Let's derive it's onchain token type @@ -172,14 +173,13 @@ describe('EvmERC20WarpHyperlaneModule', async () => { }); it('should create with a synthetic config', async () => { - const config: TokenRouterConfig = { + const config: HypTokenRouterConfig = { + ...baseConfig, type: TokenType.synthetic, - hook: hookAddress, name: TOKEN_NAME, symbol: TOKEN_NAME, decimals: TOKEN_DECIMALS, totalSupply: TOKEN_SUPPLY, - ...baseConfig, }; // Deploy using WarpModule @@ -187,6 +187,7 @@ describe('EvmERC20WarpHyperlaneModule', async () => { chain, config, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); // Let's derive it's onchain token type @@ -210,15 +211,15 @@ describe('EvmERC20WarpHyperlaneModule', async () => { it('should create with a native config', async () => { const config = { type: TokenType.native, - hook: hookAddress, ...baseConfig, - } as TokenRouterConfig; + } as HypTokenRouterConfig; // Deploy using WarpModule const evmERC20WarpModule = await EvmERC20WarpModule.create({ chain, config, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); // Let's derive it's onchain token type @@ -240,58 +241,78 @@ describe('EvmERC20WarpHyperlaneModule', async () => { const config = { ...baseConfig, type: TokenType.native, - hook: hookAddress, remoteRouters: randomRemoteRouters(numOfRouters), - } as TokenRouterConfig; + } as HypTokenRouterConfig; // Deploy using WarpModule const evmERC20WarpModule = await EvmERC20WarpModule.create({ chain, config, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); const { remoteRouters } = await evmERC20WarpModule.read(); expect(Object.keys(remoteRouters!).length).to.equal(numOfRouters); }); describe('Update', async () => { + const owner = randomAddress(); const ismConfigToUpdate: IsmConfig[] = [ { type: IsmType.TRUSTED_RELAYER, - relayer: randomAddress(), + relayer: owner, }, { type: IsmType.FALLBACK_ROUTING, - owner: randomAddress(), + owner: owner, domains: {}, }, { type: IsmType.PAUSABLE, - owner: randomAddress(), + owner: owner, paused: false, }, ]; + const hookConfigToUpdate: HookConfig[] = [ + { + type: HookType.PROTOCOL_FEE, + beneficiary: owner, + owner: owner, + maxProtocolFee: '1337', + protocolFee: '1337', + }, + { + type: HookType.INTERCHAIN_GAS_PAYMASTER, + owner: owner, + beneficiary: owner, + oracleKey: owner, + overhead: {}, + oracleConfig: {}, + }, + { + type: HookType.MERKLE_TREE, + }, + ]; it('should deploy and set a new Ism', async () => { const config = { ...baseConfig, type: TokenType.native, - hook: hookAddress, interchainSecurityModule: ismAddress, - } as TokenRouterConfig; + } as HypTokenRouterConfig; // Deploy using WarpModule const evmERC20WarpModule = await EvmERC20WarpModule.create({ chain, config, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); const actualConfig = await evmERC20WarpModule.read(); for (const interchainSecurityModule of ismConfigToUpdate) { - const expectedConfig: TokenRouterConfig = { + const expectedConfig: HypTokenRouterConfig = { ...actualConfig, - ismFactoryAddresses, interchainSecurityModule, }; await sendTxs(await evmERC20WarpModule.update(expectedConfig)); @@ -307,15 +328,15 @@ describe('EvmERC20WarpHyperlaneModule', async () => { const config = { ...baseConfig, type: TokenType.native, - hook: hookAddress, interchainSecurityModule: ismAddress, - } as TokenRouterConfig; + } as HypTokenRouterConfig; // Deploy using WarpModule const evmERC20WarpModule = await EvmERC20WarpModule.create({ chain, config, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); const actualConfig = await evmERC20WarpModule.read(); @@ -325,9 +346,8 @@ describe('EvmERC20WarpHyperlaneModule', async () => { owner, paused: false, }; - const expectedConfig: TokenRouterConfig = { + const expectedConfig: HypTokenRouterConfig = { ...actualConfig, - ismFactoryAddresses, interchainSecurityModule, }; @@ -345,6 +365,99 @@ describe('EvmERC20WarpHyperlaneModule', async () => { expect(txs.length).to.equal(0); }); + it('should update and set a new Hook based on config', async () => { + const config = { + ...baseConfig, + type: TokenType.native, + } as HypTokenRouterConfig; + + // Deploy using WarpModule + const evmERC20WarpModule = await EvmERC20WarpModule.create({ + chain, + config, + multiProvider, + proxyFactoryFactories: ismFactoryAddresses, + }); + const actualConfig = await evmERC20WarpModule.read(); + + for (const hook of hookConfigToUpdate) { + const expectedConfig: HypTokenRouterConfig = { + ...actualConfig, + hook, + }; + await sendTxs(await evmERC20WarpModule.update(expectedConfig)); + + const updatedConfig = (await evmERC20WarpModule.read()) + .hook as DerivedHookConfig; + expect(normalizeConfig(updatedConfig)).to.deep.equal(hook); + } + }); + + it('should set new deployed hook mailbox to WarpConfig.owner', async () => { + const config = { + ...baseConfig, + type: TokenType.native, + } as HypTokenRouterConfig; + + // Deploy using WarpModule + const evmERC20WarpModule = await EvmERC20WarpModule.create({ + chain, + config, + multiProvider, + proxyFactoryFactories: ismFactoryAddresses, + }); + const actualConfig = await evmERC20WarpModule.read(); + const expectedConfig: HypTokenRouterConfig = { + ...actualConfig, + hook: hookConfigToUpdate.find( + (c: any) => c.type === HookType.MERKLE_TREE, + ), + }; + await sendTxs(await evmERC20WarpModule.update(expectedConfig)); + + const updatedConfig = (await evmERC20WarpModule.read()) + .hook as DerivedHookConfig; + + const hook = MailboxClient__factory.connect( + updatedConfig.address, + multiProvider.getProvider(chain), + ); + expect(await hook.mailbox()).to.equal(expectedConfig.mailbox); + }); + + it("should set Proxied Hook's proxyAdmins to WarpConfig.proxyAdmin", async () => { + const config = { + ...baseConfig, + type: TokenType.native, + } as HypTokenRouterConfig; + + // Deploy using WarpModule + const evmERC20WarpModule = await EvmERC20WarpModule.create({ + chain, + config, + multiProvider, + proxyFactoryFactories: ismFactoryAddresses, + }); + const actualConfig = await evmERC20WarpModule.read(); + const expectedConfig: HypTokenRouterConfig = { + ...actualConfig, + hook: hookConfigToUpdate.find( + (c: any) => c.type === HookType.INTERCHAIN_GAS_PAYMASTER, + ), + }; + await sendTxs(await evmERC20WarpModule.update(expectedConfig)); + + const updatedConfig = (await evmERC20WarpModule.read()) + .hook as DerivedHookConfig; + + expect( + await proxyAdmin( + multiProvider.getProvider(chain), + updatedConfig.address, + ), + ).to.equal(expectedConfig.proxyAdmin?.address); + }); + it('should update a mutable Ism', async () => { const ismConfig: IsmConfig = { type: IsmType.ROUTING, @@ -366,19 +479,18 @@ describe('EvmERC20WarpHyperlaneModule', async () => { const config = { ...baseConfig, type: TokenType.native, - hook: hookAddress, interchainSecurityModule: deployedIsm, - } as TokenRouterConfig; + } as HypTokenRouterConfig; const evmERC20WarpModule = await EvmERC20WarpModule.create({ chain, config, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); const actualConfig = await evmERC20WarpModule.read(); - const expectedConfig: TokenRouterConfig = { + const expectedConfig: HypTokenRouterConfig = { ...actualConfig, - ismFactoryAddresses, interchainSecurityModule: { type: IsmType.ROUTING, owner: randomAddress(), @@ -399,13 +511,12 @@ describe('EvmERC20WarpHyperlaneModule', async () => { ); }); - it('should update connected routers', async () => { + it('should enroll connected routers', async () => { const config = { ...baseConfig, type: TokenType.native, - hook: hookAddress, ismFactoryAddresses, - } as TokenRouterConfig; + } as HypTokenRouterConfig; // Deploy using WarpModule const evmERC20WarpModule = await EvmERC20WarpModule.create({ @@ -415,8 +526,9 @@ describe('EvmERC20WarpHyperlaneModule', async () => { interchainSecurityModule: ismAddress, }, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); - const numOfRouters = Math.floor(Math.random() * 10); + const numOfRouters = randomInt(10, 0); await sendTxs( await evmERC20WarpModule.update({ ...config, @@ -430,13 +542,12 @@ describe('EvmERC20WarpHyperlaneModule', async () => { ); }); - it('should only extend routers if they are new ones are different', async () => { + it('should unenroll connected routers', async () => { const config = { ...baseConfig, type: TokenType.native, - hook: hookAddress, ismFactoryAddresses, - } as TokenRouterConfig; + } as HypTokenRouterConfig; // Deploy using WarpModule const evmERC20WarpModule = await EvmERC20WarpModule.create({ @@ -446,6 +557,44 @@ describe('EvmERC20WarpHyperlaneModule', async () => { interchainSecurityModule: ismAddress, }, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, + }); + const numOfRouters = randomInt(10, 0); + await sendTxs( + await evmERC20WarpModule.update({ + ...config, + remoteRouters: randomRemoteRouters(numOfRouters), + }), + ); + // Read config & delete remoteRouters + const existingConfig = await evmERC20WarpModule.read(); + for (let i = 0; i < numOfRouters; i++) { + delete existingConfig.remoteRouters?.[i.toString()]; + await sendTxs(await evmERC20WarpModule.update(existingConfig)); + + const updatedConfig = await evmERC20WarpModule.read(); + expect(Object.keys(updatedConfig.remoteRouters!).length).to.be.equal( + numOfRouters - (i + 1), + ); + } + }); + + it('should replace an enrollment if they are new one different, if the config lengths are the same', async () => { + const config = { + ...baseConfig, + type: TokenType.native, + ismFactoryAddresses, + } as HypTokenRouterConfig; + + // Deploy using WarpModule + const evmERC20WarpModule = await EvmERC20WarpModule.create({ + chain, + config: { + ...config, + interchainSecurityModule: ismAddress, + }, + multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); const remoteRouters = randomRemoteRouters(1); await sendTxs( @@ -468,27 +617,32 @@ describe('EvmERC20WarpHyperlaneModule', async () => { await sendTxs(txs); // Try to extend with the different remoteRouters, but same length + const extendedRemoteRouter = { + 3: { + address: randomAddress(), + }, + }; txs = await evmERC20WarpModule.update({ ...config, - remoteRouters: { - 3: randomAddress(), - }, + remoteRouters: extendedRemoteRouter, }); - expect(txs.length).to.equal(1); + expect(txs.length).to.equal(2); await sendTxs(txs); updatedConfig = await evmERC20WarpModule.read(); - expect(Object.keys(updatedConfig.remoteRouters!).length).to.be.equal(2); + expect(Object.keys(updatedConfig.remoteRouters!).length).to.be.equal(1); + expect(updatedConfig.remoteRouters?.['3'].address.toLowerCase()).to.be.eq( + extendedRemoteRouter['3'].address.toLowerCase(), + ); }); it('should update the owner only if they are different', async () => { const config = { ...baseConfig, type: TokenType.native, - hook: hookAddress, ismFactoryAddresses, - } as TokenRouterConfig; + } as HypTokenRouterConfig; const owner = signer.address.toLowerCase(); const evmERC20WarpModule = await EvmERC20WarpModule.create({ @@ -498,6 +652,7 @@ describe('EvmERC20WarpHyperlaneModule', async () => { interchainSecurityModule: ismAddress, }, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); const currentConfig = await evmERC20WarpModule.read(); @@ -523,11 +678,9 @@ describe('EvmERC20WarpHyperlaneModule', async () => { }); it('should update the ProxyAdmin owner only if they are different', async () => { - const config: TokenRouterConfig = { + const config: HypTokenRouterConfig = { ...baseConfig, type: TokenType.native, - hook: hookAddress, - ismFactoryAddresses, }; const owner = signer.address.toLowerCase(); @@ -538,13 +691,14 @@ describe('EvmERC20WarpHyperlaneModule', async () => { interchainSecurityModule: ismAddress, }, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); const currentConfig = await evmERC20WarpModule.read(); expect(currentConfig.proxyAdmin?.owner.toLowerCase()).to.equal(owner); const newOwner = randomAddress(); - const updatedWarpCoreConfig: TokenRouterConfig = { + const updatedWarpCoreConfig: HypTokenRouterConfig = { ...config, proxyAdmin: { address: currentConfig.proxyAdmin!.address, @@ -553,7 +707,7 @@ describe('EvmERC20WarpHyperlaneModule', async () => { }; await sendTxs(await evmERC20WarpModule.update(updatedWarpCoreConfig)); - const latestConfig: TokenRouterConfig = normalizeConfig( + const latestConfig: HypTokenRouterConfig = normalizeConfig( await evmERC20WarpModule.read(), ); expect(latestConfig.proxyAdmin?.owner).to.equal(newOwner); @@ -567,13 +721,13 @@ describe('EvmERC20WarpHyperlaneModule', async () => { it('should update the destination gas', async () => { const domain = 3; - const config: TokenRouterConfig = { + const config: HypTokenRouterConfig = { ...baseConfig, type: TokenType.native, - hook: hookAddress, - ismFactoryAddresses, remoteRouters: { - [domain]: randomAddress(), + [domain]: { + address: randomAddress(), + }, }, }; @@ -584,6 +738,7 @@ describe('EvmERC20WarpHyperlaneModule', async () => { ...config, }, multiProvider, + proxyFactoryFactories: ismFactoryAddresses, }); await sendTxs( await evmERC20WarpModule.update({ diff --git a/typescript/sdk/src/token/EvmERC20WarpModule.ts b/typescript/sdk/src/token/EvmERC20WarpModule.ts index 2652c78269..eaea93dac9 100644 --- a/typescript/sdk/src/token/EvmERC20WarpModule.ts +++ b/typescript/sdk/src/token/EvmERC20WarpModule.ts @@ -6,7 +6,6 @@ import { TokenRouter__factory, } from '@hyperlane-xyz/core'; import { buildArtifact as coreBuildArtifact } from '@hyperlane-xyz/core/buildArtifact.js'; -import { ContractVerifier, ExplorerLicenseType } from '@hyperlane-xyz/sdk'; import { Address, Domain, @@ -15,34 +14,42 @@ import { addressToBytes32, assert, deepEquals, + difference, + eqAddress, isObjEmpty, objMap, rootLogger, } from '@hyperlane-xyz/utils'; import { transferOwnershipTransactions } from '../contracts/contracts.js'; +import { HyperlaneAddresses } from '../contracts/types.js'; import { HyperlaneModule, HyperlaneModuleParams, } from '../core/AbstractHyperlaneModule.js'; +import { ProxyFactoryFactories } from '../deploy/contracts.js'; import { proxyAdminUpdateTxs } from '../deploy/proxy.js'; +import { ContractVerifier } from '../deploy/verify/ContractVerifier.js'; +import { ExplorerLicenseType } from '../deploy/verify/types.js'; +import { EvmHookModule } from '../hook/EvmHookModule.js'; +import { DerivedHookConfig } from '../hook/EvmHookReader.js'; import { EvmIsmModule } from '../ism/EvmIsmModule.js'; import { DerivedIsmConfig } from '../ism/EvmIsmReader.js'; import { MultiProvider } from '../providers/MultiProvider.js'; import { AnnotatedEV5Transaction } from '../providers/ProviderType.js'; import { ChainName, ChainNameOrId } from '../types.js'; -import { normalizeConfig } from '../utils/ism.js'; import { EvmERC20WarpRouteReader } from './EvmERC20WarpRouteReader.js'; import { HypERC20Deployer } from './deploy.js'; -import { TokenRouterConfig, TokenRouterConfigSchema } from './schemas.js'; +import { HypTokenRouterConfig, HypTokenRouterConfigSchema } from './types.js'; +type WarpRouteAddresses = HyperlaneAddresses & { + deployedTokenRoute: Address; +}; export class EvmERC20WarpModule extends HyperlaneModule< ProtocolType.Ethereum, - TokenRouterConfig, - { - deployedTokenRoute: Address; - } + HypTokenRouterConfig, + WarpRouteAddresses > { protected logger = rootLogger.child({ module: 'EvmERC20WarpModule', @@ -54,12 +61,7 @@ export class EvmERC20WarpModule extends HyperlaneModule< constructor( protected readonly multiProvider: MultiProvider, - args: HyperlaneModuleParams< - TokenRouterConfig, - { - deployedTokenRoute: Address; - } - >, + args: HyperlaneModuleParams, protected readonly contractVerifier?: ContractVerifier, ) { super(args); @@ -82,7 +84,7 @@ export class EvmERC20WarpModule extends HyperlaneModule< * @param address - The address to derive the token router configuration from. * @returns A promise that resolves to the token router configuration. */ - public async read(): Promise { + async read(): Promise { return this.reader.deriveWarpRouteConfig( this.args.addresses.deployedTokenRoute, ); @@ -94,10 +96,10 @@ export class EvmERC20WarpModule extends HyperlaneModule< * @param expectedConfig - The configuration for the token router to be updated. * @returns An array of Ethereum transactions that were executed to update the contract, or an error if the update failed. */ - public async update( - expectedConfig: TokenRouterConfig, + async update( + expectedConfig: HypTokenRouterConfig, ): Promise { - TokenRouterConfigSchema.parse(expectedConfig); + HypTokenRouterConfigSchema.parse(expectedConfig); const actualConfig = await this.read(); const transactions = []; @@ -110,7 +112,12 @@ export class EvmERC20WarpModule extends HyperlaneModule< */ transactions.push( ...(await this.createIsmUpdateTxs(actualConfig, expectedConfig)), - ...this.createRemoteRoutersUpdateTxs(actualConfig, expectedConfig), + ...(await this.createHookUpdateTxs(actualConfig, expectedConfig)), + ...this.createEnrollRemoteRoutersUpdateTxs(actualConfig, expectedConfig), + ...this.createUnenrollRemoteRoutersUpdateTxs( + actualConfig, + expectedConfig, + ), ...this.createSetDestinationGasUpdateTxs(actualConfig, expectedConfig), ...this.createOwnershipUpdateTxs(actualConfig, expectedConfig), ...proxyAdminUpdateTxs( @@ -131,47 +138,96 @@ export class EvmERC20WarpModule extends HyperlaneModule< * @param expectedConfig - The expected token router configuration. * @returns A array with a single Ethereum transaction that need to be executed to enroll the routers */ - createRemoteRoutersUpdateTxs( - actualConfig: TokenRouterConfig, - expectedConfig: TokenRouterConfig, + createEnrollRemoteRoutersUpdateTxs( + actualConfig: HypTokenRouterConfig, + expectedConfig: HypTokenRouterConfig, ): AnnotatedEV5Transaction[] { const updateTransactions: AnnotatedEV5Transaction[] = []; if (!expectedConfig.remoteRouters) { return []; } - // We normalize the addresses for comparison - actualConfig.remoteRouters = normalizeConfig(actualConfig.remoteRouters); - expectedConfig.remoteRouters = normalizeConfig( - expectedConfig.remoteRouters, + assert(actualConfig.remoteRouters, 'actualRemoteRouters is undefined'); + assert(expectedConfig.remoteRouters, 'actualRemoteRouters is undefined'); + + const { remoteRouters: actualRemoteRouters } = actualConfig; + const { remoteRouters: expectedRemoteRouters } = expectedConfig; + + const routesToEnroll = Array.from( + difference( + new Set(Object.keys(expectedRemoteRouters)), + new Set(Object.keys(actualRemoteRouters)), + ), + ); + + if (routesToEnroll.length === 0) { + return updateTransactions; + } + + const contractToUpdate = TokenRouter__factory.connect( + this.args.addresses.deployedTokenRoute, + this.multiProvider.getProvider(this.domainId), ); + + updateTransactions.push({ + chainId: this.chainId, + annotation: `Enrolling Router ${this.args.addresses.deployedTokenRoute} on ${this.args.chain}`, + to: contractToUpdate.address, + data: contractToUpdate.interface.encodeFunctionData( + 'enrollRemoteRouters', + [ + routesToEnroll.map((k) => Number(k)), + routesToEnroll.map((a) => + addressToBytes32(expectedRemoteRouters[a].address), + ), + ], + ), + }); + + return updateTransactions; + } + + createUnenrollRemoteRoutersUpdateTxs( + actualConfig: HypTokenRouterConfig, + expectedConfig: HypTokenRouterConfig, + ): AnnotatedEV5Transaction[] { + const updateTransactions: AnnotatedEV5Transaction[] = []; + if (!expectedConfig.remoteRouters) { + return []; + } + assert(actualConfig.remoteRouters, 'actualRemoteRouters is undefined'); assert(expectedConfig.remoteRouters, 'actualRemoteRouters is undefined'); const { remoteRouters: actualRemoteRouters } = actualConfig; const { remoteRouters: expectedRemoteRouters } = expectedConfig; - if (!deepEquals(actualRemoteRouters, expectedRemoteRouters)) { - const contractToUpdate = TokenRouter__factory.connect( - this.args.addresses.deployedTokenRoute, - this.multiProvider.getProvider(this.domainId), - ); + const routesToUnenroll = Array.from( + difference( + new Set(Object.keys(actualRemoteRouters)), + new Set(Object.keys(expectedRemoteRouters)), + ), + ); - updateTransactions.push({ - chainId: this.chainId, - annotation: `Enrolling Router ${this.args.addresses.deployedTokenRoute} on ${this.args.chain}`, - to: contractToUpdate.address, - data: contractToUpdate.interface.encodeFunctionData( - 'enrollRemoteRouters', - [ - Object.keys(expectedRemoteRouters).map((k) => Number(k)), - Object.values(expectedRemoteRouters).map((a) => - addressToBytes32(a), - ), - ], - ), - }); + if (routesToUnenroll.length === 0) { + return updateTransactions; } + + const contractToUpdate = TokenRouter__factory.connect( + this.args.addresses.deployedTokenRoute, + this.multiProvider.getProvider(this.domainId), + ); + + updateTransactions.push({ + annotation: `Unenrolling Router ${this.args.addresses.deployedTokenRoute} on ${this.args.chain}`, + chainId: this.chainId, + to: contractToUpdate.address, + data: contractToUpdate.interface.encodeFunctionData( + 'unenrollRemoteRouters(uint32[])', + [routesToUnenroll.map((k) => Number(k))], + ), + }); + return updateTransactions; } @@ -183,8 +239,8 @@ export class EvmERC20WarpModule extends HyperlaneModule< * @returns A array with a single Ethereum transaction that need to be executed to enroll the routers */ createSetDestinationGasUpdateTxs( - actualConfig: TokenRouterConfig, - expectedConfig: TokenRouterConfig, + actualConfig: HypTokenRouterConfig, + expectedConfig: HypTokenRouterConfig, ): AnnotatedEV5Transaction[] { const updateTransactions: AnnotatedEV5Transaction[] = []; if (!expectedConfig.destinationGas) { @@ -234,44 +290,83 @@ export class EvmERC20WarpModule extends HyperlaneModule< * @returns Ethereum transaction that need to be executed to update the ISM configuration. */ async createIsmUpdateTxs( - actualConfig: TokenRouterConfig, - expectedConfig: TokenRouterConfig, + actualConfig: HypTokenRouterConfig, + expectedConfig: HypTokenRouterConfig, ): Promise { const updateTransactions: AnnotatedEV5Transaction[] = []; if (!expectedConfig.interchainSecurityModule) { return []; } - if (expectedConfig.ismFactoryAddresses) { - const actualDeployedIsm = ( - actualConfig.interchainSecurityModule as DerivedIsmConfig - ).address; - - // Try to update (may also deploy) Ism with the expected config - const { - deployedIsm: expectedDeployedIsm, - updateTransactions: ismUpdateTransactions, - } = await this.deployOrUpdateIsm(actualConfig, expectedConfig); - - // If an ISM is updated in-place, push the update txs - updateTransactions.push(...ismUpdateTransactions); - - // If a new ISM is deployed, push the setInterchainSecurityModule tx - if (actualDeployedIsm !== expectedDeployedIsm) { - const contractToUpdate = MailboxClient__factory.connect( - this.args.addresses.deployedTokenRoute, - this.multiProvider.getProvider(this.domainId), - ); - updateTransactions.push({ - chainId: this.chainId, - annotation: `Setting ISM for Warp Route to ${expectedDeployedIsm}`, - to: contractToUpdate.address, - data: contractToUpdate.interface.encodeFunctionData( - 'setInterchainSecurityModule', - [expectedDeployedIsm], - ), - }); - } + const actualDeployedIsm = ( + actualConfig.interchainSecurityModule as DerivedIsmConfig + ).address; + + // Try to update (may also deploy) Ism with the expected config + const { + deployedIsm: expectedDeployedIsm, + updateTransactions: ismUpdateTransactions, + } = await this.deployOrUpdateIsm(actualConfig, expectedConfig); + + // If an ISM is updated in-place, push the update txs + updateTransactions.push(...ismUpdateTransactions); + + // If a new ISM is deployed, push the setInterchainSecurityModule tx + if (actualDeployedIsm !== expectedDeployedIsm) { + const contractToUpdate = MailboxClient__factory.connect( + this.args.addresses.deployedTokenRoute, + this.multiProvider.getProvider(this.domainId), + ); + updateTransactions.push({ + chainId: this.chainId, + annotation: `Setting ISM for Warp Route to ${expectedDeployedIsm}`, + to: contractToUpdate.address, + data: contractToUpdate.interface.encodeFunctionData( + 'setInterchainSecurityModule', + [expectedDeployedIsm], + ), + }); + } + + return updateTransactions; + } + + async createHookUpdateTxs( + actualConfig: HypTokenRouterConfig, + expectedConfig: HypTokenRouterConfig, + ): Promise { + const updateTransactions: AnnotatedEV5Transaction[] = []; + + if (!expectedConfig.hook) { + return []; + } + + const actualDeployedHook = (actualConfig.hook as DerivedHookConfig) + ?.address; + + // Try to deploy or update Hook with the expected config + const { + deployedHook: expectedDeployedHook, + updateTransactions: hookUpdateTransactions, + } = await this.deployOrUpdateHook(actualConfig, expectedConfig); + + // If a Hook is updated in-place, push the update txs + updateTransactions.push(...hookUpdateTransactions); + + // If a new Hook is deployed, push the setHook tx + if (!eqAddress(actualDeployedHook, expectedDeployedHook)) { + const contractToUpdate = MailboxClient__factory.connect( + this.args.addresses.deployedTokenRoute, + this.multiProvider.getProvider(this.domainId), + ); + updateTransactions.push({ + chainId: this.chainId, + annotation: `Setting Hook for Warp Route to ${expectedDeployedHook}`, + to: contractToUpdate.address, + data: contractToUpdate.interface.encodeFunctionData('setHook', [ + expectedDeployedHook, + ]), + }); } return updateTransactions; @@ -285,8 +380,8 @@ export class EvmERC20WarpModule extends HyperlaneModule< * @returns Ethereum transaction that need to be executed to update the owner. */ createOwnershipUpdateTxs( - actualConfig: TokenRouterConfig, - expectedConfig: TokenRouterConfig, + actualConfig: HypTokenRouterConfig, + expectedConfig: HypTokenRouterConfig, ): AnnotatedEV5Transaction[] { return transferOwnershipTransactions( this.multiProvider.getEvmChainId(this.args.chain), @@ -302,21 +397,14 @@ export class EvmERC20WarpModule extends HyperlaneModule< * * @returns Object with deployedIsm address, and update Transactions */ - public async deployOrUpdateIsm( - actualConfig: TokenRouterConfig, - expectedConfig: TokenRouterConfig, + async deployOrUpdateIsm( + actualConfig: HypTokenRouterConfig, + expectedConfig: HypTokenRouterConfig, ): Promise<{ deployedIsm: Address; updateTransactions: AnnotatedEV5Transaction[]; }> { - assert( - expectedConfig.interchainSecurityModule, - 'Ism not derived correctly', - ); - assert( - expectedConfig.ismFactoryAddresses, - 'Ism Factories addresses not provided', - ); + assert(expectedConfig.interchainSecurityModule, 'Ism derived incorrectly'); const ismModule = new EvmIsmModule( this.multiProvider, @@ -324,7 +412,7 @@ export class EvmERC20WarpModule extends HyperlaneModule< chain: this.args.chain, config: expectedConfig.interchainSecurityModule, addresses: { - ...expectedConfig.ismFactoryAddresses, + ...this.args.addresses, mailbox: expectedConfig.mailbox, deployedIsm: ( actualConfig.interchainSecurityModule as DerivedIsmConfig @@ -344,6 +432,124 @@ export class EvmERC20WarpModule extends HyperlaneModule< return { deployedIsm, updateTransactions }; } + /** + * Updates or deploys the hook using the provided configuration. + * + * @returns Object with deployedHook address, and update Transactions + */ + async deployOrUpdateHook( + actualConfig: HypTokenRouterConfig, + expectedConfig: HypTokenRouterConfig, + ): Promise<{ + deployedHook: Address; + updateTransactions: AnnotatedEV5Transaction[]; + }> { + assert(expectedConfig.hook, 'No hook config'); + + if (!actualConfig.hook) { + return this.deployNewHook(expectedConfig); + } + + return this.updateExistingHook(expectedConfig, actualConfig); + } + + async deployNewHook(expectedConfig: HypTokenRouterConfig): Promise<{ + deployedHook: Address; + updateTransactions: AnnotatedEV5Transaction[]; + }> { + this.logger.info( + `No hook deployed for warp route, deploying new hook on ${this.args.chain} chain`, + ); + + const { + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticAggregationIsmFactory, + staticAggregationHookFactory, + domainRoutingIsmFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, + } = this.args.addresses; + + assert(expectedConfig.hook, 'Hook is undefined'); + assert( + expectedConfig.proxyAdmin?.address, + 'ProxyAdmin address is undefined', + ); + + const hookModule = await EvmHookModule.create({ + chain: this.args.chain, + config: expectedConfig.hook, + proxyFactoryFactories: { + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticAggregationIsmFactory, + staticAggregationHookFactory, + domainRoutingIsmFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, + }, + coreAddresses: { + mailbox: expectedConfig.mailbox, + proxyAdmin: expectedConfig.proxyAdmin?.address, // Assume that a proxyAdmin is always deployed with a WarpRoute + }, + contractVerifier: this.contractVerifier, + multiProvider: this.multiProvider, + }); + const { deployedHook } = hookModule.serialize(); + return { deployedHook, updateTransactions: [] }; + } + + async updateExistingHook( + expectedConfig: HypTokenRouterConfig, + actualConfig: HypTokenRouterConfig, + ): Promise<{ + deployedHook: Address; + updateTransactions: AnnotatedEV5Transaction[]; + }> { + const { + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticAggregationIsmFactory, + staticAggregationHookFactory, + domainRoutingIsmFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, + } = this.args.addresses; + + assert(actualConfig.proxyAdmin?.address, 'ProxyAdmin address is undefined'); + assert(actualConfig.hook, 'Hook is undefined'); + + const hookModule = new EvmHookModule( + this.multiProvider, + { + chain: this.args.chain, + config: actualConfig.hook, + addresses: { + staticMerkleRootMultisigIsmFactory, + staticMessageIdMultisigIsmFactory, + staticAggregationIsmFactory, + staticAggregationHookFactory, + domainRoutingIsmFactory, + staticMerkleRootWeightedMultisigIsmFactory, + staticMessageIdWeightedMultisigIsmFactory, + mailbox: actualConfig.mailbox, + proxyAdmin: actualConfig.proxyAdmin?.address, + deployedHook: (actualConfig.hook as DerivedHookConfig).address, + }, + }, + this.contractVerifier, + ); + + this.logger.info( + `Comparing target Hook config with ${this.args.chain} chain`, + ); + const updateTransactions = await hookModule.update(expectedConfig.hook!); + const { deployedHook } = hookModule.serialize(); + + return { deployedHook, updateTransactions }; + } + /** * Deploys the Warp Route. * @@ -352,13 +558,20 @@ export class EvmERC20WarpModule extends HyperlaneModule< * @param multiProvider - The multi-provider instance to use. * @returns A new instance of the EvmERC20WarpHyperlaneModule. */ - public static async create(params: { + static async create(params: { chain: ChainNameOrId; - config: TokenRouterConfig; + config: HypTokenRouterConfig; multiProvider: MultiProvider; contractVerifier?: ContractVerifier; + proxyFactoryFactories: HyperlaneAddresses; }): Promise { - const { chain, config, multiProvider, contractVerifier } = params; + const { + chain, + config, + multiProvider, + contractVerifier, + proxyFactoryFactories, + } = params; const chainName = multiProvider.getChainName(chain); const deployer = new HypERC20Deployer(multiProvider); const deployedContracts = await deployer.deployContracts(chainName, config); @@ -367,6 +580,7 @@ export class EvmERC20WarpModule extends HyperlaneModule< multiProvider, { addresses: { + ...proxyFactoryFactories, deployedTokenRoute: deployedContracts[config.type].address, }, chain, diff --git a/typescript/sdk/src/token/EvmERC20WarpRouteReader.hardhat-test.ts b/typescript/sdk/src/token/EvmERC20WarpRouteReader.hardhat-test.ts index 782acc3d28..28f9163797 100644 --- a/typescript/sdk/src/token/EvmERC20WarpRouteReader.hardhat-test.ts +++ b/typescript/sdk/src/token/EvmERC20WarpRouteReader.hardhat-test.ts @@ -356,7 +356,7 @@ describe('ERC20WarpRouterReader', async () => { ); expect(Object.keys(derivedConfig.remoteRouters!).length).to.equal(1); expect( - derivedConfig.remoteRouters![otherChainMetadata.domainId!], + derivedConfig.remoteRouters![otherChainMetadata.domainId!].address, ).to.be.equal(warpRoute[otherChain].collateral.address); }); }); diff --git a/typescript/sdk/src/token/EvmERC20WarpRouteReader.ts b/typescript/sdk/src/token/EvmERC20WarpRouteReader.ts index df2ab1affe..0908378462 100644 --- a/typescript/sdk/src/token/EvmERC20WarpRouteReader.ts +++ b/typescript/sdk/src/token/EvmERC20WarpRouteReader.ts @@ -9,12 +9,6 @@ import { ProxyAdmin__factory, TokenRouter__factory, } from '@hyperlane-xyz/core'; -import { - MailboxClientConfig, - TokenConfig, - TokenRouterConfig, - TokenType, -} from '@hyperlane-xyz/sdk'; import { Address, bytes32ToAddress, @@ -24,16 +18,25 @@ import { } from '@hyperlane-xyz/utils'; import { DEFAULT_CONTRACT_READ_CONCURRENCY } from '../consts/concurrency.js'; -import { DeployedOwnableConfig } from '../deploy/types.js'; import { EvmHookReader } from '../hook/EvmHookReader.js'; import { EvmIsmReader } from '../ism/EvmIsmReader.js'; import { MultiProvider } from '../providers/MultiProvider.js'; -import { DestinationGas, RemoteRouters } from '../router/types.js'; -import { ChainNameOrId } from '../types.js'; +import { + DestinationGas, + MailboxClientConfig, + RemoteRouters, + RemoteRoutersSchema, +} from '../router/types.js'; +import { ChainNameOrId, DeployedOwnableConfig } from '../types.js'; import { HyperlaneReader } from '../utils/HyperlaneReader.js'; import { proxyAdmin } from './../deploy/proxy.js'; -import { TokenMetadata } from './types.js'; +import { TokenType } from './config.js'; +import { + HypTokenConfig, + HypTokenRouterConfig, + TokenMetadata, +} from './types.js'; export class EvmERC20WarpRouteReader extends HyperlaneReader { protected readonly logger = rootLogger.child({ @@ -61,7 +64,7 @@ export class EvmERC20WarpRouteReader extends HyperlaneReader { */ async deriveWarpRouteConfig( warpRouteAddress: Address, - ): Promise { + ): Promise { // Derive the config type const type = await this.deriveTokenType(warpRouteAddress); const baseMetadata = await this.fetchMailboxClientConfig(warpRouteAddress); @@ -77,7 +80,7 @@ export class EvmERC20WarpRouteReader extends HyperlaneReader { proxyAdmin, destinationGas, type, - } as TokenRouterConfig; + } as HypTokenRouterConfig; } /** @@ -124,7 +127,7 @@ export class EvmERC20WarpRouteReader extends HyperlaneReader { const warpRoute = factory.connect(warpRouteAddress, this.provider); await warpRoute[method](); return tokenType as TokenType; - } catch (e) { + } catch { continue; } finally { this.setSmartProviderLogLevel(getLogLevel()); // returns to original level defined by rootLogger @@ -192,7 +195,7 @@ export class EvmERC20WarpRouteReader extends HyperlaneReader { async fetchTokenConfig( type: TokenType, tokenAddress: Address, - ): Promise { + ): Promise { if ( type === TokenType.collateral || type === TokenType.collateralVault || @@ -267,13 +270,18 @@ export class EvmERC20WarpRouteReader extends HyperlaneReader { ); const domains = await warpRoute.domains(); - return Object.fromEntries( + const routers = Object.fromEntries( await Promise.all( domains.map(async (domain) => { - return [domain, bytes32ToAddress(await warpRoute.routers(domain))]; + return [ + domain, + { address: bytes32ToAddress(await warpRoute.routers(domain)) }, + ]; }), ), ); + + return RemoteRoutersSchema.parse(routers); } async fetchProxyAdminConfig( diff --git a/typescript/sdk/src/token/adapters/CosmWasmTokenAdapter.test.ts b/typescript/sdk/src/token/adapters/CosmWasmTokenAdapter.test.ts index 1205d123bb..fbdd42e9d1 100644 --- a/typescript/sdk/src/token/adapters/CosmWasmTokenAdapter.test.ts +++ b/typescript/sdk/src/token/adapters/CosmWasmTokenAdapter.test.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ - /* eslint-disable no-console */ import { CosmWasmClient, @@ -372,13 +370,25 @@ export async function rotateValidators() { [TestChainName.test1]: { threshold: 5, validators: [ - '8e668c97ad76d0e28375275c41ece4972ab8a5bc', // hyperlane - '521a3e6bf8d24809fde1c1fd3494a859a16f132c', // cosmosstation - '25b9a0961c51e74fd83295293bc029131bf1e05a', // neutron (pablo) - '14025fe092f5f8a401dd9819704d9072196d2125', // p2p - 'a0ee95e280d46c14921e524b075d0c341e7ad1c8', // cosmos spaces - 'cc9a0b6de7fe314bd99223687d784730a75bb957', // dsrv - '42b6de2edbaa62c2ea2309ad85d20b3e37d38acf', // sg-1 + { + address: '8e668c97ad76d0e28375275c41ece4972ab8a5bc', + alias: 'hyperlane', + }, + { + address: '521a3e6bf8d24809fde1c1fd3494a859a16f132c', + alias: 'cosmosstation', + }, + { + address: '25b9a0961c51e74fd83295293bc029131bf1e05a', + alias: 'neutron (pablo)', + }, + { address: '14025fe092f5f8a401dd9819704d9072196d2125', alias: 'p2p' }, + { + address: 'a0ee95e280d46c14921e524b075d0c341e7ad1c8', + alias: 'cosmos spaces', + }, + { address: 'cc9a0b6de7fe314bd99223687d784730a75bb957', alias: 'dsrv' }, + { address: '42b6de2edbaa62c2ea2309ad85d20b3e37d38acf', alias: 'sg-1' }, ], }, }); diff --git a/typescript/sdk/src/token/adapters/CosmWasmTokenAdapter.ts b/typescript/sdk/src/token/adapters/CosmWasmTokenAdapter.ts index e472133bd8..61e999deed 100644 --- a/typescript/sdk/src/token/adapters/CosmWasmTokenAdapter.ts +++ b/typescript/sdk/src/token/adapters/CosmWasmTokenAdapter.ts @@ -64,6 +64,10 @@ export class CwNativeTokenAdapter throw new Error('Metadata not available to native tokens'); } + async getMinimumTransferAmount(_recipient: Address): Promise { + return 0n; + } + async isApproveRequired(): Promise { return false; } @@ -146,6 +150,10 @@ export class CwTokenAdapter }; } + async getMinimumTransferAmount(_recipient: Address): Promise { + return 0n; + } + async isApproveRequired(): Promise { return false; } diff --git a/typescript/sdk/src/token/adapters/CosmosTokenAdapter.ts b/typescript/sdk/src/token/adapters/CosmosTokenAdapter.ts index 06ea3dde10..0983e2b45d 100644 --- a/typescript/sdk/src/token/adapters/CosmosTokenAdapter.ts +++ b/typescript/sdk/src/token/adapters/CosmosTokenAdapter.ts @@ -46,6 +46,10 @@ export class CosmNativeTokenAdapter throw new Error('Metadata not available to native tokens'); } + async getMinimumTransferAmount(_recipient: Address): Promise { + return 0n; + } + async isApproveRequired(): Promise { return false; } diff --git a/typescript/sdk/src/token/adapters/EvmTokenAdapter.ts b/typescript/sdk/src/token/adapters/EvmTokenAdapter.ts index cd9910a5a2..72026be69d 100644 --- a/typescript/sdk/src/token/adapters/EvmTokenAdapter.ts +++ b/typescript/sdk/src/token/adapters/EvmTokenAdapter.ts @@ -57,6 +57,10 @@ export class EvmNativeTokenAdapter throw new Error('Metadata not available to native tokens'); } + async getMinimumTransferAmount(_recipient: Address): Promise { + return 0n; + } + async isApproveRequired( _owner: Address, _spender: Address, diff --git a/typescript/sdk/src/token/adapters/ITokenAdapter.ts b/typescript/sdk/src/token/adapters/ITokenAdapter.ts index d989fb7091..64c03490e5 100644 --- a/typescript/sdk/src/token/adapters/ITokenAdapter.ts +++ b/typescript/sdk/src/token/adapters/ITokenAdapter.ts @@ -25,6 +25,7 @@ export interface ITokenAdapter { getBalance(address: Address): Promise; getTotalSupply(): Promise; getMetadata(isNft?: boolean): Promise; + getMinimumTransferAmount(recipient: Address): Promise; isApproveRequired( owner: Address, spender: Address, @@ -39,7 +40,11 @@ export interface IHypTokenAdapter extends ITokenAdapter { getRouterAddress(domain: Domain): Promise; getAllRouters(): Promise>; getBridgedSupply(): Promise; - quoteTransferRemoteGas(destination: Domain): Promise; + // Sender is only required for Sealevel origins. + quoteTransferRemoteGas( + destination: Domain, + sender?: Address, + ): Promise; populateTransferRemoteTx(p: TransferRemoteParams): Promise; } diff --git a/typescript/sdk/src/token/adapters/SealevelTokenAdapter.ts b/typescript/sdk/src/token/adapters/SealevelTokenAdapter.ts index 788fa5f91e..65fee68f2a 100644 --- a/typescript/sdk/src/token/adapters/SealevelTokenAdapter.ts +++ b/typescript/sdk/src/token/adapters/SealevelTokenAdapter.ts @@ -19,14 +19,21 @@ import { Address, Domain, addressToBytes, + assert, eqAddress, + isNullish, median, padBytesToLength, } from '@hyperlane-xyz/utils'; import { BaseSealevelAdapter } from '../../app/MultiProtocolApp.js'; import { SEALEVEL_SPL_NOOP_ADDRESS } from '../../consts/sealevel.js'; -import { SealevelOverheadIgpAdapter } from '../../gas/adapters/SealevelIgpAdapter.js'; +import { + IgpPaymentKeys, + SealevelIgpAdapter, + SealevelIgpProgramAdapter, + SealevelOverheadIgpAdapter, +} from '../../gas/adapters/SealevelIgpAdapter.js'; import { SealevelInterchainGasPaymasterType } from '../../gas/adapters/serialization.js'; import { MultiProtocolProvider } from '../../providers/MultiProtocolProvider.js'; import { ChainName } from '../../types.js'; @@ -90,6 +97,24 @@ export class SealevelNativeTokenAdapter throw new Error('Metadata not available to native tokens'); } + // Require a minimum transfer amount to cover rent for the recipient. + async getMinimumTransferAmount(recipient: Address): Promise { + const recipientPubkey = new PublicKey(recipient); + const provider = this.getProvider(); + const recipientAccount = await provider.getAccountInfo(recipientPubkey); + const recipientDataLength = recipientAccount?.data.length ?? 0; + const recipientLamports = recipientAccount?.lamports ?? 0; + + const minRequiredLamports = + await provider.getMinimumBalanceForRentExemption(recipientDataLength); + + if (recipientLamports < minRequiredLamports) { + return BigInt(minRequiredLamports - recipientLamports); + } + + return 0n; + } + async isApproveRequired(): Promise { return false; } @@ -155,6 +180,10 @@ export class SealevelTokenAdapter return { decimals: 9, symbol: 'SPL', name: 'SPL Token', totalSupply: '' }; } + async getMinimumTransferAmount(_recipient: Address): Promise { + return 0n; + } + async isApproveRequired(): Promise { return false; } @@ -283,11 +312,32 @@ export abstract class SealevelHypTokenAdapter return undefined; } + // The sender is required, as simulating a transaction on Sealevel requires + // a payer to be specified that has sufficient funds to cover the transaction fee. async quoteTransferRemoteGas( - _destination: Domain, + destination: Domain, + sender?: Address, ): Promise { - // TODO Solana support - return { amount: 0n }; + const tokenData = await this.getTokenAccountData(); + const destinationGas = tokenData.destination_gas?.get(destination); + if (isNullish(destinationGas)) { + return { amount: 0n }; + } + + const igp = this.getIgpAdapter(tokenData); + if (!igp) { + return { amount: 0n }; + } + + assert(sender, 'Sender required for Sealevel transfer remote gas quote'); + + return { + amount: await igp.quoteGasPayment( + destination, + destinationGas, + new PublicKey(sender), + ), + }; } async populateTransferRemoteTx({ @@ -359,34 +409,10 @@ export abstract class SealevelHypTokenAdapter return tx; } - async getIgpKeys(): Promise { + async getIgpKeys(): Promise { const tokenData = await this.getTokenAccountData(); - if (!tokenData.interchain_gas_paymaster) return undefined; - const igpConfig = tokenData.interchain_gas_paymaster; - if (igpConfig.type === SealevelInterchainGasPaymasterType.Igp) { - return { - programId: igpConfig.program_id_pubkey, - }; - } else if ( - igpConfig.type === SealevelInterchainGasPaymasterType.OverheadIgp - ) { - if (!igpConfig.igp_account_pub_key) { - throw new Error('igpAccount field expected for Sealevel Overhead IGP'); - } - const overheadAdapter = new SealevelOverheadIgpAdapter( - this.chainName, - this.multiProvider, - { igp: igpConfig.igp_account_pub_key.toBase58() }, - ); - const overheadAccountInfo = await overheadAdapter.getAccountInfo(); - return { - programId: igpConfig.program_id_pubkey, - igpAccount: igpConfig.igp_account_pub_key, - innerIgpAccount: overheadAccountInfo.inner_pub_key, - }; - } else { - throw new Error(`Unsupported IGP type ${igpConfig.type}`); - } + const igpAdapter = this.getIgpAdapter(tokenData); + return igpAdapter?.getPaymentKeys(); } // Should match https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/rust/sealevel/libraries/hyperlane-sealevel-token/src/processor.rs#L257-L274 @@ -457,33 +483,26 @@ export abstract class SealevelHypTokenAdapter isWritable: true, }, ]; - if (igp.igpAccount && igp.innerIgpAccount) { + if (igp.overheadIgpAccount) { keys = [ ...keys, // 12. [] OPTIONAL - The Overhead IGP account, if the configured IGP is an Overhead IGP { - pubkey: igp.igpAccount, + pubkey: igp.overheadIgpAccount, isSigner: false, isWritable: false, }, - // 13. [writeable] The Overhead's inner IGP account - { - pubkey: igp.innerIgpAccount, - isSigner: false, - isWritable: true, - }, - ]; - } else { - keys = [ - ...keys, - // 12. [writeable] The IGP account. - { - pubkey: igp.programId, - isSigner: false, - isWritable: true, - }, ]; } + keys = [ + ...keys, + // 13. [writeable] The Overhead's inner IGP account (or the normal IGP account if there's no Overhead IGP). + { + pubkey: igp.igpAccount, + isSigner: false, + isWritable: true, + }, + ]; } return keys; } @@ -526,6 +545,14 @@ export abstract class SealevelHypTokenAdapter ); } + // Should match https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/4b3537470eff0139163a2a7aa1d19fc708a992c6/rust/sealevel/programs/hyperlane-sealevel-token/src/plugin.rs#L43-L51 + deriveAtaPayerAccount(): PublicKey { + return super.derivePda( + ['hyperlane_token', '-', 'ata_payer'], + this.warpProgramPubKey, + ); + } + /** * Fetches the median prioritization fee for transfers of the collateralAddress token. * @returns The median prioritization fee in micro-lamports @@ -557,6 +584,36 @@ export abstract class SealevelHypTokenAdapter this.logger.debug(`Median priority fee: ${medianFee}`); return medianFee; } + + protected getIgpAdapter( + tokenData: SealevelHyperlaneTokenData, + ): SealevelIgpProgramAdapter | undefined { + const igpConfig = tokenData.interchain_gas_paymaster; + + if (!igpConfig || igpConfig.igp_account_pub_key === undefined) { + return undefined; + } + + if (igpConfig.type === SealevelInterchainGasPaymasterType.Igp) { + return new SealevelIgpAdapter(this.chainName, this.multiProvider, { + igp: igpConfig.igp_account_pub_key.toBase58(), + programId: igpConfig.program_id_pubkey.toBase58(), + }); + } else if ( + igpConfig.type === SealevelInterchainGasPaymasterType.OverheadIgp + ) { + return new SealevelOverheadIgpAdapter( + this.chainName, + this.multiProvider, + { + overheadIgp: igpConfig.igp_account_pub_key.toBase58(), + programId: igpConfig.program_id_pubkey.toBase58(), + }, + ); + } else { + throw new Error(`Unsupported IGP type ${igpConfig.type}`); + } + } } // Interacts with Hyp Native token programs @@ -606,6 +663,10 @@ export class SealevelHypNativeAdapter extends SealevelHypTokenAdapter { return this.wrappedNative.getMetadata(); } + override async getMinimumTransferAmount(recipient: Address): Promise { + return this.wrappedNative.getMinimumTransferAmount(recipient); + } + override async getMedianPriorityFee(): Promise { // Native tokens don't have a collateral address, so we don't fetch // prioritization fee history @@ -633,6 +694,10 @@ export class SealevelHypNativeAdapter extends SealevelHypTokenAdapter { this.warpProgramPubKey, ); } + + deriveAtaPayerAccount(): PublicKey { + throw new Error('No ATA payer is used for native warp routes'); + } } // Interacts with Hyp Collateral token programs @@ -754,9 +819,5 @@ interface KeyListParams { sender: PublicKey; mailbox: PublicKey; randomWallet: PublicKey; - igp?: { - programId: PublicKey; - igpAccount?: PublicKey; - innerIgpAccount?: PublicKey; - }; + igp?: IgpPaymentKeys; } diff --git a/typescript/sdk/src/token/app.ts b/typescript/sdk/src/token/app.ts index ae3cf95ccb..746c184f12 100644 --- a/typescript/sdk/src/token/app.ts +++ b/typescript/sdk/src/token/app.ts @@ -1,11 +1,6 @@ import { Logger } from 'pino'; import { TokenRouter } from '@hyperlane-xyz/core'; -import { - ChainMap, - ProxiedFactories, - proxiedFactories, -} from '@hyperlane-xyz/sdk'; import { Address, objKeys } from '@hyperlane-xyz/utils'; import { appFromAddressesMapHelper } from '../contracts/contracts.js'; @@ -16,6 +11,8 @@ import { } from '../contracts/types.js'; import { MultiProvider } from '../providers/MultiProvider.js'; import { GasRouterApp } from '../router/RouterApps.js'; +import { ProxiedFactories, proxiedFactories } from '../router/types.js'; +import { ChainMap } from '../types.js'; import { HypERC20Factories, hypERC20factories } from './contracts.js'; diff --git a/typescript/sdk/src/token/checker.ts b/typescript/sdk/src/token/checker.ts index 9dcc0569ba..cf29d28c81 100644 --- a/typescript/sdk/src/token/checker.ts +++ b/typescript/sdk/src/token/checker.ts @@ -5,8 +5,9 @@ import { ERC20__factory, HypERC20Collateral, IXERC20Lockbox__factory, + TokenRouter, } from '@hyperlane-xyz/core'; -import { eqAddress } from '@hyperlane-xyz/utils'; +import { eqAddress, objMap } from '@hyperlane-xyz/utils'; import { TokenMismatchViolation } from '../deploy/types.js'; import { ProxiedRouterChecker } from '../router/ProxiedRouterChecker.js'; @@ -17,17 +18,17 @@ import { HypERC20App } from './app.js'; import { TokenType } from './config.js'; import { HypERC20Factories } from './contracts.js'; import { - TokenRouterConfig, - isCollateralConfig, - isNativeConfig, - isSyntheticConfig, -} from './schemas.js'; -import { TokenMetadata } from './types.js'; + HypTokenRouterConfig, + TokenMetadata, + isCollateralTokenConfig, + isNativeTokenConfig, + isSyntheticTokenConfig, +} from './types.js'; export class HypERC20Checker extends ProxiedRouterChecker< HypERC20Factories & ProxiedFactories, HypERC20App, - TokenRouterConfig + HypTokenRouterConfig > { async checkChain(chain: ChainName): Promise { await super.checkChain(chain); @@ -37,7 +38,7 @@ export class HypERC20Checker extends ProxiedRouterChecker< async checkToken(chain: ChainName): Promise { const checkERC20 = async ( token: ERC20, - config: TokenRouterConfig, + config: HypTokenRouterConfig, ): Promise => { const checks: { method: keyof ERC20 & keyof TokenMetadata; @@ -66,14 +67,38 @@ export class HypERC20Checker extends ProxiedRouterChecker< const expectedConfig = this.configMap[chain]; const hypToken = this.app.router(this.app.getContracts(chain)); - if (isNativeConfig(expectedConfig)) { + + // Check all actual decimals are consistent + const actualChainDecimals = await this.getEvmActualDecimals(); + this.checkDecimalConsistency( + chain, + hypToken, + actualChainDecimals, + 'actual', + true, + ); + + // Check all config decimals are consistent as well + const configDecimals = objMap( + this.configMap, + (_chain, config) => config.decimals, + ); + this.checkDecimalConsistency( + chain, + hypToken, + configDecimals, + 'config', + false, + ); + + if (isNativeTokenConfig(expectedConfig)) { try { await this.multiProvider.estimateGas(chain, { to: hypToken.address, from: await this.multiProvider.getSignerAddress(chain), value: BigNumber.from(1), }); - } catch (e) { + } catch { const violation: TokenMismatchViolation = { type: 'deployed token not payable', chain, @@ -83,40 +108,122 @@ export class HypERC20Checker extends ProxiedRouterChecker< }; this.addViolation(violation); } - } else if (isSyntheticConfig(expectedConfig)) { + } else if (isSyntheticTokenConfig(expectedConfig)) { await checkERC20(hypToken as unknown as ERC20, expectedConfig); - } else if (isCollateralConfig(expectedConfig)) { + } else if (isCollateralTokenConfig(expectedConfig)) { + const collateralToken = await this.getCollateralToken(chain); + const actualToken = await ( + hypToken as unknown as HypERC20Collateral + ).wrappedToken(); + if (!eqAddress(collateralToken.address, actualToken)) { + const violation: TokenMismatchViolation = { + type: 'CollateralTokenMismatch', + chain, + expected: collateralToken.address, + actual: actualToken, + tokenAddress: hypToken.address, + }; + this.addViolation(violation); + } + } + } + + private cachedAllActualDecimals: Record | undefined = + undefined; + + async getEvmActualDecimals(): Promise> { + if (this.cachedAllActualDecimals) { + return this.cachedAllActualDecimals; + } + const entries = await Promise.all( + this.getEvmChains().map(async (chain) => { + const token = this.app.router(this.app.getContracts(chain)); + return [chain, await this.getActualDecimals(chain, token)]; + }), + ); + + this.cachedAllActualDecimals = Object.fromEntries(entries); + + return this.cachedAllActualDecimals!; + } + + async getActualDecimals( + chain: ChainName, + hypToken: TokenRouter, + ): Promise { + const expectedConfig = this.configMap[chain]; + let decimals: number | undefined = undefined; + + if (isNativeTokenConfig(expectedConfig)) { + decimals = + this.multiProvider.getChainMetadata(chain).nativeToken?.decimals; + } else if (isSyntheticTokenConfig(expectedConfig)) { + decimals = await (hypToken as unknown as ERC20).decimals(); + } else if (isCollateralTokenConfig(expectedConfig)) { + const collateralToken = await this.getCollateralToken(chain); + decimals = await collateralToken.decimals(); + } + + if (decimals === undefined) { + throw new Error('Actual decimals not found'); + } + + return decimals; + } + + async getCollateralToken(chain: ChainName): Promise { + const expectedConfig = this.configMap[chain]; + let collateralToken: ERC20 | undefined = undefined; + + if (isCollateralTokenConfig(expectedConfig)) { const provider = this.multiProvider.getProvider(chain); - let collateralToken: ERC20; if (expectedConfig.type === TokenType.XERC20Lockbox) { const collateralTokenAddress = await IXERC20Lockbox__factory.connect( expectedConfig.token, provider, ).callStatic.ERC20(); - collateralToken = await ERC20__factory.connect( + collateralToken = ERC20__factory.connect( collateralTokenAddress, provider, ); } else { - collateralToken = await ERC20__factory.connect( + collateralToken = ERC20__factory.connect( expectedConfig.token, provider, ); } - const actualToken = await ( - hypToken as unknown as HypERC20Collateral - ).wrappedToken(); - if (!eqAddress(collateralToken.address, actualToken)) { - const violation: TokenMismatchViolation = { - type: 'CollateralTokenMismatch', - chain, - expected: collateralToken.address, - actual: actualToken, - tokenAddress: hypToken.address, - }; - this.addViolation(violation); - } + } + if (!collateralToken) { + throw new Error('Collateral token not found'); + } + return collateralToken; + } + + checkDecimalConsistency( + chain: ChainName, + hypToken: TokenRouter, + chainDecimals: Record, + decimalType: string, + nonEmpty: boolean, + ) { + const uniqueChainDecimals = new Set( + Object.values(chainDecimals).filter((decimals) => !!decimals), + ); + if ( + uniqueChainDecimals.size > 1 || + (nonEmpty && uniqueChainDecimals.size === 0) + ) { + const violation: TokenMismatchViolation = { + type: 'TokenDecimalsMismatch', + chain, + expected: `${ + nonEmpty ? 'non-empty and ' : '' + }consistent ${decimalType} decimals`, + actual: JSON.stringify(chainDecimals), + tokenAddress: hypToken.address, + }; + this.addViolation(violation); } } } diff --git a/typescript/sdk/src/token/deploy.hardhat-test.ts b/typescript/sdk/src/token/deploy.hardhat-test.ts index 772813943c..3c7d74b22a 100644 --- a/typescript/sdk/src/token/deploy.hardhat-test.ts +++ b/typescript/sdk/src/token/deploy.hardhat-test.ts @@ -15,8 +15,7 @@ import { MultiProvider } from '../providers/MultiProvider.js'; import { EvmERC20WarpRouteReader } from './EvmERC20WarpRouteReader.js'; import { TokenType } from './config.js'; import { HypERC20Deployer } from './deploy.js'; -import { TokenRouterConfig } from './schemas.js'; -import { WarpRouteDeployConfig } from './types.js'; +import { HypTokenRouterConfig, WarpRouteDeployConfig } from './types.js'; const chain = TestChainName.test1; @@ -40,7 +39,7 @@ describe('TokenDeployer', async () => { const routerConfigMap = coreApp.getRouterConfig(signer.address); config = objMap( routerConfigMap, - (chain, c): TokenRouterConfig => ({ + (chain, c): HypTokenRouterConfig => ({ type: TokenType.synthetic, name: chain, symbol: `u${chain}`, @@ -91,7 +90,7 @@ describe('TokenDeployer', async () => { routerAddress = warpRoute[chain][type].address; }); - it(`should derive TokenRouterConfig correctly`, async () => { + it(`should derive HypTokenRouterConfig correctly`, async () => { const derivedConfig = await reader.deriveWarpRouteConfig(routerAddress); expect(derivedConfig.type).to.equal(config[chain].type); }); diff --git a/typescript/sdk/src/token/deploy.ts b/typescript/sdk/src/token/deploy.ts index aa7376c883..29aeac28ef 100644 --- a/typescript/sdk/src/token/deploy.ts +++ b/typescript/sdk/src/token/deploy.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { constants } from 'ethers'; import { @@ -8,7 +7,6 @@ import { IERC4626__factory, IXERC20Lockbox__factory, } from '@hyperlane-xyz/core'; -import { TokenType } from '@hyperlane-xyz/sdk'; import { assert, objKeys, objMap, rootLogger } from '@hyperlane-xyz/utils'; import { HyperlaneContracts } from '../contracts/types.js'; @@ -18,7 +16,7 @@ import { MultiProvider } from '../providers/MultiProvider.js'; import { GasRouterDeployer } from '../router/GasRouterDeployer.js'; import { ChainName } from '../types.js'; -import { gasOverhead } from './config.js'; +import { TokenType, gasOverhead } from './config.js'; import { HypERC20Factories, HypERC721Factories, @@ -29,19 +27,20 @@ import { hypERC721factories, } from './contracts.js'; import { + HypTokenRouterConfig, + TokenMetadata, TokenMetadataSchema, - TokenRouterConfig, - isCollateralConfig, - isNativeConfig, - isSyntheticConfig, - isSyntheticRebaseConfig, + WarpRouteDeployConfig, + isCollateralTokenConfig, + isNativeTokenConfig, + isSyntheticRebaseTokenConfig, + isSyntheticTokenConfig, isTokenMetadata, -} from './schemas.js'; -import { TokenMetadata, WarpRouteDeployConfig } from './types.js'; +} from './types.js'; abstract class TokenDeployer< Factories extends TokenFactories, -> extends GasRouterDeployer { +> extends GasRouterDeployer { constructor( multiProvider: MultiProvider, factories: Factories, @@ -58,15 +57,18 @@ abstract class TokenDeployer< }); // factories not used in deploy } - async constructorArgs(_: ChainName, config: TokenRouterConfig): Promise { - if (isCollateralConfig(config)) { + async constructorArgs( + _: ChainName, + config: HypTokenRouterConfig, + ): Promise { + if (isCollateralTokenConfig(config)) { return [config.token, config.mailbox]; - } else if (isNativeConfig(config)) { + } else if (isNativeTokenConfig(config)) { return config.scale ? [config.scale, config.mailbox] : [config.mailbox]; - } else if (isSyntheticConfig(config)) { + } else if (isSyntheticTokenConfig(config)) { assert(config.decimals, 'decimals is undefined for config'); // decimals must be defined by this point return [config.decimals, config.mailbox]; - } else if (isSyntheticRebaseConfig(config)) { + } else if (isSyntheticRebaseTokenConfig(config)) { const collateralDomain = this.multiProvider.getDomainId( config.collateralChainName, ); @@ -78,7 +80,7 @@ abstract class TokenDeployer< async initializeArgs( chain: ChainName, - config: TokenRouterConfig, + config: HypTokenRouterConfig, ): Promise { const signer = await this.multiProvider.getSigner(chain).getAddress(); const defaultArgs = [ @@ -87,11 +89,11 @@ abstract class TokenDeployer< // TransferOwnership will happen later in RouterDeployer signer, ]; - if (isCollateralConfig(config) || isNativeConfig(config)) { + if (isCollateralTokenConfig(config) || isNativeTokenConfig(config)) { return defaultArgs; - } else if (isSyntheticConfig(config)) { + } else if (isSyntheticTokenConfig(config)) { return [config.totalSupply, config.name, config.symbol, ...defaultArgs]; - } else if (isSyntheticRebaseConfig(config)) { + } else if (isSyntheticRebaseTokenConfig(config)) { return [0, config.name, config.symbol, ...defaultArgs]; } else { throw new Error('Unknown collateral type when initializing arguments'); @@ -110,7 +112,7 @@ abstract class TokenDeployer< return TokenMetadataSchema.parse(config); } - if (isNativeConfig(config)) { + if (isNativeTokenConfig(config)) { const nativeToken = multiProvider.getChainMetadata(chain).nativeToken; if (nativeToken) { return TokenMetadataSchema.parse({ @@ -120,7 +122,7 @@ abstract class TokenDeployer< } } - if (isCollateralConfig(config)) { + if (isCollateralTokenConfig(config)) { const provider = multiProvider.getProvider(chain); if (config.isNft) { @@ -224,12 +226,12 @@ export class HypERC20Deployer extends TokenDeployer { throw new Error('No matching contract found'); } - routerContractKey(config: TokenRouterConfig): keyof HypERC20Factories { + routerContractKey(config: HypTokenRouterConfig): keyof HypERC20Factories { assert(config.type in hypERC20factories, 'Invalid ERC20 token type'); return config.type as keyof HypERC20Factories; } - routerContractName(config: TokenRouterConfig): string { + routerContractName(config: HypTokenRouterConfig): string { return hypERC20contracts[this.routerContractKey(config)]; } } @@ -258,12 +260,12 @@ export class HypERC721Deployer extends TokenDeployer { throw new Error('No matching contract found'); } - routerContractKey(config: TokenRouterConfig): keyof HypERC721Factories { + routerContractKey(config: HypTokenRouterConfig): keyof HypERC721Factories { assert(config.type in hypERC721factories, 'Invalid ERC721 token type'); return config.type as keyof HypERC721Factories; } - routerContractName(config: TokenRouterConfig): string { + routerContractName(config: HypTokenRouterConfig): string { return hypERC721contracts[this.routerContractKey(config)]; } } diff --git a/typescript/sdk/src/token/schemas.ts b/typescript/sdk/src/token/schemas.ts deleted file mode 100644 index ae9ee15a41..0000000000 --- a/typescript/sdk/src/token/schemas.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { z } from 'zod'; - -import { objMap } from '@hyperlane-xyz/utils'; - -import { GasRouterConfigSchema } from '../router/schemas.js'; -import { isCompliant } from '../utils/schemas.js'; - -import { TokenType } from './config.js'; - -export const WarpRouteDeployConfigSchemaErrors = { - ONLY_SYNTHETIC_REBASE: `Config with ${TokenType.collateralVaultRebase} must be deployed with ${TokenType.syntheticRebase}`, - NO_SYNTHETIC_ONLY: `Config must include Native or Collateral OR all synthetics must define token metadata`, -}; -export const TokenMetadataSchema = z.object({ - name: z.string(), - symbol: z.string(), - totalSupply: z.string().or(z.number()), - decimals: z.number().optional(), - scale: z.number().optional(), - isNft: z.boolean().optional(), -}); - -export const CollateralConfigSchema = TokenMetadataSchema.partial().extend({ - type: z.enum([ - TokenType.collateral, - TokenType.collateralVault, - TokenType.collateralVaultRebase, - TokenType.XERC20, - TokenType.XERC20Lockbox, - TokenType.collateralFiat, - TokenType.fastCollateral, - TokenType.collateralUri, - ]), - token: z - .string() - .describe('Existing token address to extend with Warp Route functionality'), -}); - -export const NativeConfigSchema = TokenMetadataSchema.partial().extend({ - type: z.enum([TokenType.native, TokenType.nativeScaled]), -}); - -export const CollateralRebaseConfigSchema = TokenMetadataSchema.omit({ - totalSupply: true, -}) - .partial() - .extend({ - type: z.literal(TokenType.collateralVaultRebase), - }); - -export const SyntheticRebaseConfigSchema = TokenMetadataSchema.partial().extend( - { - type: z.literal(TokenType.syntheticRebase), - collateralChainName: z.string(), - }, -); - -export const SyntheticConfigSchema = TokenMetadataSchema.partial().extend({ - type: z.enum([ - TokenType.synthetic, - TokenType.syntheticUri, - TokenType.fastSynthetic, - ]), -}); - -/** - * @remarks - * The discriminatedUnion is basically a switch statement for zod schemas - * It uses the 'type' key to pick from the array of schemas to validate - */ -export const TokenConfigSchema = z.discriminatedUnion('type', [ - NativeConfigSchema, - CollateralConfigSchema, - SyntheticConfigSchema, - SyntheticRebaseConfigSchema, -]); -export type TokenConfig = z.infer; - -export const TokenRouterConfigSchema = TokenConfigSchema.and( - GasRouterConfigSchema, -); - -export type TokenRouterConfig = z.infer; -export type NativeConfig = z.infer; -export type CollateralConfig = z.infer; - -export const isSyntheticConfig = isCompliant(SyntheticConfigSchema); -export const isSyntheticRebaseConfig = isCompliant(SyntheticRebaseConfigSchema); -export const isCollateralRebaseConfig = isCompliant( - CollateralRebaseConfigSchema, -); -export const isCollateralConfig = isCompliant(CollateralConfigSchema); -export const isNativeConfig = isCompliant(NativeConfigSchema); -export const isTokenMetadata = isCompliant(TokenMetadataSchema); - -export const WarpRouteDeployConfigSchema = z - .record(TokenRouterConfigSchema) - .refine((configMap) => { - const entries = Object.entries(configMap); - return ( - entries.some( - ([_, config]) => - isCollateralConfig(config) || - isCollateralRebaseConfig(config) || - isNativeConfig(config), - ) || entries.every(([_, config]) => isTokenMetadata(config)) - ); - }, WarpRouteDeployConfigSchemaErrors.NO_SYNTHETIC_ONLY) - .transform((warpRouteDeployConfig, ctx) => { - const collateralRebaseEntry = Object.entries(warpRouteDeployConfig).find( - ([_, config]) => isCollateralRebaseConfig(config), - ); - if (!collateralRebaseEntry) return warpRouteDeployConfig; // Pass through for other token types - - if (isCollateralRebasePairedCorrectly(warpRouteDeployConfig)) { - const collateralChainName = collateralRebaseEntry[0]; - return objMap(warpRouteDeployConfig, (_, config) => { - if (config.type === TokenType.syntheticRebase) - config.collateralChainName = collateralChainName; - return config; - }) as Record; - } - - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: WarpRouteDeployConfigSchemaErrors.ONLY_SYNTHETIC_REBASE, - }); - - return z.NEVER; // Causes schema validation to throw with above issue - }); - -function isCollateralRebasePairedCorrectly( - warpRouteDeployConfig: Record, -): boolean { - // Filter out all the non-collateral rebase configs to check if they are only synthetic rebase tokens - const otherConfigs = Object.entries(warpRouteDeployConfig).filter( - ([_, config]) => !isCollateralRebaseConfig(config), - ); - - if (otherConfigs.length === 0) return false; - - // The other configs MUST be synthetic rebase - const allOthersSynthetic: boolean = otherConfigs.every( - ([_, config], _index) => isSyntheticRebaseConfig(config), - ); - return allOthersSynthetic; -} diff --git a/typescript/sdk/src/token/schemas.test.ts b/typescript/sdk/src/token/types.test.ts similarity index 97% rename from typescript/sdk/src/token/schemas.test.ts rename to typescript/sdk/src/token/types.test.ts index 1a8d606ea1..eba79c928d 100644 --- a/typescript/sdk/src/token/schemas.test.ts +++ b/typescript/sdk/src/token/types.test.ts @@ -5,11 +5,11 @@ import { assert } from '@hyperlane-xyz/utils'; import { TokenType } from './config.js'; import { + WarpRouteDeployConfig, WarpRouteDeployConfigSchema, WarpRouteDeployConfigSchemaErrors, - isCollateralConfig, -} from './schemas.js'; -import { WarpRouteDeployConfig } from './types.js'; + isCollateralTokenConfig, +} from './types.js'; const SOME_ADDRESS = ethers.Wallet.createRandom().address; const COLLATERAL_TYPES = [ @@ -65,7 +65,7 @@ describe('WarpRouteDeployConfigSchema refine', () => { it('should throw if collateral type and token is empty', async () => { for (const type of COLLATERAL_TYPES) { config.arbitrum.type = type; - assert(isCollateralConfig(config.arbitrum), 'must be collateral'); + assert(isCollateralTokenConfig(config.arbitrum), 'must be collateral'); //@ts-ignore config.arbitrum.token = undefined; diff --git a/typescript/sdk/src/token/types.ts b/typescript/sdk/src/token/types.ts index 8cbead3317..400a40d263 100644 --- a/typescript/sdk/src/token/types.ts +++ b/typescript/sdk/src/token/types.ts @@ -1,11 +1,156 @@ import { z } from 'zod'; -import { - TokenMetadataSchema, - TokenRouterConfigSchema, - WarpRouteDeployConfigSchema, -} from './schemas.js'; +import { objMap } from '@hyperlane-xyz/utils'; +import { GasRouterConfigSchema } from '../router/types.js'; +import { isCompliant } from '../utils/schemas.js'; + +import { TokenType } from './config.js'; + +export const WarpRouteDeployConfigSchemaErrors = { + ONLY_SYNTHETIC_REBASE: `Config with ${TokenType.collateralVaultRebase} must be deployed with ${TokenType.syntheticRebase}`, + NO_SYNTHETIC_ONLY: `Config must include Native or Collateral OR all synthetics must define token metadata`, +}; +export const TokenMetadataSchema = z.object({ + name: z.string(), + symbol: z.string(), + totalSupply: z.string().or(z.number()), + decimals: z.number().optional(), + scale: z.number().optional(), + isNft: z.boolean().optional(), +}); export type TokenMetadata = z.infer; -export type TokenRouterConfig = z.infer; +export const isTokenMetadata = isCompliant(TokenMetadataSchema); + +export const NativeTokenConfigSchema = TokenMetadataSchema.partial().extend({ + type: z.enum([TokenType.native, TokenType.nativeScaled]), +}); +export type NativeTokenConfig = z.infer; +export const isNativeTokenConfig = isCompliant(NativeTokenConfigSchema); + +export const CollateralTokenConfigSchema = TokenMetadataSchema.partial().extend( + { + type: z.enum([ + TokenType.collateral, + TokenType.collateralVault, + TokenType.collateralVaultRebase, + TokenType.XERC20, + TokenType.XERC20Lockbox, + TokenType.collateralFiat, + TokenType.fastCollateral, + TokenType.collateralUri, + ]), + token: z + .string() + .describe( + 'Existing token address to extend with Warp Route functionality', + ), + }, +); +export type CollateralTokenConfig = z.infer; +export const isCollateralTokenConfig = isCompliant(CollateralTokenConfigSchema); + +export const CollateralRebaseTokenConfigSchema = TokenMetadataSchema.omit({ + totalSupply: true, +}) + .partial() + .extend({ + type: z.literal(TokenType.collateralVaultRebase), + }); +export const isCollateralRebaseTokenConfig = isCompliant( + CollateralRebaseTokenConfigSchema, +); + +export const SyntheticTokenConfigSchema = TokenMetadataSchema.partial().extend({ + type: z.enum([ + TokenType.synthetic, + TokenType.syntheticUri, + TokenType.fastSynthetic, + ]), +}); +export type SyntheticTokenConfig = z.infer; +export const isSyntheticTokenConfig = isCompliant(SyntheticTokenConfigSchema); + +export const SyntheticRebaseTokenConfigSchema = + TokenMetadataSchema.partial().extend({ + type: z.literal(TokenType.syntheticRebase), + collateralChainName: z.string(), + }); +export type SyntheticRebaseTokenConfig = z.infer< + typeof CollateralTokenConfigSchema +>; +export const isSyntheticRebaseTokenConfig = isCompliant( + SyntheticRebaseTokenConfigSchema, +); + +/** + * @remarks + * The discriminatedUnion is basically a switch statement for zod schemas + * It uses the 'type' key to pick from the array of schemas to validate + */ +export const HypTokenConfigSchema = z.discriminatedUnion('type', [ + NativeTokenConfigSchema, + CollateralTokenConfigSchema, + SyntheticTokenConfigSchema, + SyntheticRebaseTokenConfigSchema, +]); +export type HypTokenConfig = z.infer; + +export const HypTokenRouterConfigSchema = HypTokenConfigSchema.and( + GasRouterConfigSchema, +); +export type HypTokenRouterConfig = z.infer; + +export const WarpRouteDeployConfigSchema = z + .record(HypTokenRouterConfigSchema) + .refine((configMap) => { + const entries = Object.entries(configMap); + return ( + entries.some( + ([_, config]) => + isCollateralTokenConfig(config) || + isCollateralRebaseTokenConfig(config) || + isNativeTokenConfig(config), + ) || entries.every(([_, config]) => isTokenMetadata(config)) + ); + }, WarpRouteDeployConfigSchemaErrors.NO_SYNTHETIC_ONLY) + .transform((warpRouteDeployConfig, ctx) => { + const collateralRebaseEntry = Object.entries(warpRouteDeployConfig).find( + ([_, config]) => isCollateralRebaseTokenConfig(config), + ); + if (!collateralRebaseEntry) return warpRouteDeployConfig; // Pass through for other token types + + if (isCollateralRebasePairedCorrectly(warpRouteDeployConfig)) { + const collateralChainName = collateralRebaseEntry[0]; + return objMap(warpRouteDeployConfig, (_, config) => { + if (config.type === TokenType.syntheticRebase) + config.collateralChainName = collateralChainName; + return config; + }) as Record; + } + + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: WarpRouteDeployConfigSchemaErrors.ONLY_SYNTHETIC_REBASE, + }); + + return z.NEVER; // Causes schema validation to throw with above issue + }); export type WarpRouteDeployConfig = z.infer; + +function isCollateralRebasePairedCorrectly( + warpRouteDeployConfig: Record, +): boolean { + // Filter out all the non-collateral rebase configs to check if they are only synthetic rebase tokens + const otherConfigs = Object.entries(warpRouteDeployConfig).filter( + ([_, config]) => !isCollateralRebaseTokenConfig(config), + ); + + if (otherConfigs.length === 0) return false; + + // The other configs MUST be synthetic rebase + const allOthersSynthetic: boolean = otherConfigs.every( + ([_, config], _index) => isSyntheticRebaseTokenConfig(config), + ); + return allOthersSynthetic; +} diff --git a/typescript/sdk/src/types.ts b/typescript/sdk/src/types.ts index aad0b5d9c8..3641592812 100644 --- a/typescript/sdk/src/types.ts +++ b/typescript/sdk/src/types.ts @@ -1,7 +1,10 @@ import type { ethers } from 'ethers'; +import { z } from 'zod'; import type { Domain } from '@hyperlane-xyz/utils'; +import { ZHash } from './metadata/customZodTypes.js'; + // An alias for string to clarify type is a chain name export type ChainName = string; // A map of chain names to a value type @@ -10,3 +13,24 @@ export type ChainMap = Record; export type ChainNameOrId = ChainName | Domain; export type Connection = ethers.providers.Provider | ethers.Signer; + +export const OwnableSchema = z.object({ + owner: ZHash, + ownerOverrides: z.record(ZHash).optional(), +}); +export type OwnableConfig = z.infer; + +export const DeployedOwnableSchema = OwnableSchema.extend({ + address: ZHash.optional(), +}); +export type DeployedOwnableConfig = z.infer; + +export const DerivedOwnableSchema = DeployedOwnableSchema.omit({ + ownerOverrides: true, +}).required(); +export type DerivedOwnableConfig = z.infer; + +export const PausableSchema = OwnableSchema.extend({ + paused: z.boolean(), +}); +export type PausableConfig = z.infer; diff --git a/typescript/sdk/src/utils/.eslintrc b/typescript/sdk/src/utils/.eslintrc deleted file mode 100644 index ba8754a123..0000000000 --- a/typescript/sdk/src/utils/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "@typescript-eslint/explicit-module-boundary-types": ["off"] - } -} diff --git a/typescript/sdk/src/utils/gnosisSafe.js b/typescript/sdk/src/utils/gnosisSafe.js index c5c14fca8d..51235e2121 100644 --- a/typescript/sdk/src/utils/gnosisSafe.js +++ b/typescript/sdk/src/utils/gnosisSafe.js @@ -103,7 +103,7 @@ export async function canProposeSafeTransactions( let safeService; try { safeService = getSafeService(chain, multiProvider); - } catch (e) { + } catch { return false; } const safe = await getSafe(chain, multiProvider, safeAddress); diff --git a/typescript/sdk/src/utils/ism.ts b/typescript/sdk/src/utils/ism.ts index 92c267e662..669cf7e9d5 100644 --- a/typescript/sdk/src/utils/ism.ts +++ b/typescript/sdk/src/utils/ism.ts @@ -25,7 +25,7 @@ function lowerCaseConfig(obj: any): any { } else if (obj !== null && typeof obj === 'object') { const newObj: any = {}; for (const key in obj) { - if (key !== 'address') { + if (key !== 'address' && key !== 'ownerOverrides') { newObj[key] = key === 'type' ? obj[key] : normalizeConfig(obj[key]); } } diff --git a/typescript/sdk/src/utils/logUtils.ts b/typescript/sdk/src/utils/logUtils.ts index 5e2eeb3665..b35a8e51ac 100644 --- a/typescript/sdk/src/utils/logUtils.ts +++ b/typescript/sdk/src/utils/logUtils.ts @@ -10,7 +10,7 @@ export function findMatchingLogEvents( .map((log) => { try { return iface.parseLog(log); - } catch (e) { + } catch { return undefined; } }) diff --git a/typescript/sdk/src/utils/sealevelSerialization.ts b/typescript/sdk/src/utils/sealevelSerialization.ts index 13b3dcacd3..cd6d2d1c67 100644 --- a/typescript/sdk/src/utils/sealevelSerialization.ts +++ b/typescript/sdk/src/utils/sealevelSerialization.ts @@ -10,7 +10,6 @@ export class SealevelAccountDataWrapper { initialized!: boolean; discriminator?: unknown; data!: T; - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types constructor(public readonly fields: any) { Object.assign(this, fields); } @@ -29,3 +28,24 @@ export function getSealevelAccountDataSchema( ], }; } + +// The format of simulation return data from the Sealevel programs. +// A trailing non-zero byte was added due to a bug in Sealevel RPCs that would +// truncate responses with trailing zero bytes. +export class SealevelSimulationReturnData { + return_data!: T; + trailing_byte!: number; + constructor(public readonly fields: any) { + Object.assign(this, fields); + } +} + +export function getSealevelSimulationReturnDataSchema(DataClass: T) { + return { + kind: 'struct', + fields: [ + ['data', DataClass], + ['trailing_byte', 'u8'], + ], + }; +} diff --git a/typescript/sdk/src/utils/validator.ts b/typescript/sdk/src/utils/validator.ts new file mode 100644 index 0000000000..c49612f8a7 --- /dev/null +++ b/typescript/sdk/src/utils/validator.ts @@ -0,0 +1,12 @@ +import { S3Validator, S3_LOCATION_PREFIX } from '../aws/validator.js'; +import { GCP_LOCATION_PREFIX, GcpValidator } from '../gcp/validator.js'; + +export async function getValidatorFromStorageLocation(location: string) { + if (location.startsWith(GCP_LOCATION_PREFIX)) { + return GcpValidator.fromStorageLocation(location); + } else if (location.startsWith(S3_LOCATION_PREFIX)) { + return S3Validator.fromStorageLocation(location); + } else { + throw new Error('Invalid storage location'); + } +} diff --git a/typescript/sdk/src/warp/WarpCore.test.ts b/typescript/sdk/src/warp/WarpCore.test.ts index 1f0681ee74..f3325a4340 100644 --- a/typescript/sdk/src/warp/WarpCore.test.ts +++ b/typescript/sdk/src/warp/WarpCore.test.ts @@ -189,11 +189,13 @@ describe('WarpCore', () => { const balanceStubs = warpCore.tokens.map((t) => sinon.stub(t, 'getBalance').resolves({ amount: MOCK_BALANCE } as any), ); + const minimumTransferAmount = 10n; const quoteStubs = warpCore.tokens.map((t) => sinon.stub(t, 'getHypAdapter').returns({ quoteTransferRemoteGas: () => Promise.resolve(MOCK_INTERCHAIN_QUOTE), isApproveRequired: () => Promise.resolve(false), populateTransferRemoteTx: () => Promise.resolve({}), + getMinimumTransferAmount: () => Promise.resolve(minimumTransferAmount), } as any), ); @@ -229,6 +231,14 @@ describe('WarpCore', () => { }); expect(Object.keys(invalidAmount || {})[0]).to.equal('amount'); + const insufficientAmount = await warpCore.validateTransfer({ + originTokenAmount: evmHypNative.amount(minimumTransferAmount - 1n), + destination: test2.name, + recipient: MOCK_ADDRESS, + sender: MOCK_ADDRESS, + }); + expect(Object.keys(insufficientAmount || {})[0]).to.equal('amount'); + const insufficientBalance = await warpCore.validateTransfer({ originTokenAmount: evmHypNative.amount(BIG_TRANSFER_AMOUNT), destination: test2.name, diff --git a/typescript/sdk/src/warp/WarpCore.ts b/typescript/sdk/src/warp/WarpCore.ts index 16903b5fa2..1dfa2eac56 100644 --- a/typescript/sdk/src/warp/WarpCore.ts +++ b/typescript/sdk/src/warp/WarpCore.ts @@ -118,14 +118,17 @@ export class WarpCore { } /** - * Queries the token router for an interchain gas quote (i.e. IGP fee) + * Queries the token router for an interchain gas quote (i.e. IGP fee). + * Sender is only required for Sealevel origins. */ async getInterchainTransferFee({ originToken, destination, + sender, }: { originToken: IToken; destination: ChainNameOrId; + sender?: Address; }): Promise { this.logger.debug(`Fetching interchain transfer quote to ${destination}`); const { chainName: originName } = originToken; @@ -149,6 +152,7 @@ export class WarpCore { const destinationDomainId = this.multiProvider.getDomainId(destination); const quote = await hypAdapter.quoteTransferRemoteGas( destinationDomainId, + sender, ); gasAmount = BigInt(quote.amount); gasAddressOrDenom = quote.addressOrDenom; @@ -345,6 +349,7 @@ export class WarpCore { interchainFee = await this.getInterchainTransferFee({ originToken: token, destination, + sender, }); } @@ -391,6 +396,7 @@ export class WarpCore { const interchainQuote = await this.getInterchainTransferFee({ originToken, destination, + sender, }); // Next, get the local gas quote @@ -561,7 +567,11 @@ export class WarpCore { const recipientError = this.validateRecipient(recipient, destination); if (recipientError) return recipientError; - const amountError = this.validateAmount(originTokenAmount); + const amountError = await this.validateAmount( + originTokenAmount, + destination, + recipient, + ); if (amountError) return amountError; const destinationCollateralError = await this.validateDestinationCollateral( @@ -643,13 +653,47 @@ export class WarpCore { /** * Ensure token amount is valid */ - protected validateAmount( + protected async validateAmount( originTokenAmount: TokenAmount, - ): Record | null { + destination: ChainNameOrId, + recipient: Address, + ): Promise | null> { if (!originTokenAmount.amount || originTokenAmount.amount < 0n) { const isNft = originTokenAmount.token.isNft(); return { amount: isNft ? 'Invalid Token Id' : 'Invalid amount' }; } + + // Check the transfer amount is sufficient on the destination side + + const originToken = originTokenAmount.token; + + const destinationName = this.multiProvider.getChainName(destination); + const destinationToken = + originToken.getConnectionForChain(destinationName)?.token; + assert(destinationToken, `No connection found for ${destinationName}`); + const destinationAdapter = destinationToken.getAdapter(this.multiProvider); + + // Get the min required destination amount + const minDestinationTransferAmount = + await destinationAdapter.getMinimumTransferAmount(recipient); + + // Convert the minDestinationTransferAmount to an origin amount + const minOriginTransferAmount = destinationToken.amount( + convertDecimals( + originToken.decimals, + destinationToken.decimals, + minDestinationTransferAmount.toString(), + ), + ); + + if (minOriginTransferAmount.amount > originTokenAmount.amount) { + return { + amount: `Minimum transfer amount is ${minOriginTransferAmount.getDecimalFormattedAmount()} ${ + originToken.symbol + }`, + }; + } + return null; } @@ -678,6 +722,7 @@ export class WarpCore { const interchainQuote = await this.getInterchainTransferFee({ originToken, destination, + sender, }); // Get balance of the IGP fee token, which may be different from the transfer token const interchainQuoteTokenBalance = originToken.isFungibleWith( diff --git a/typescript/utils/CHANGELOG.md b/typescript/utils/CHANGELOG.md index 9d852ab866..3cf2756603 100644 --- a/typescript/utils/CHANGELOG.md +++ b/typescript/utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @hyperlane-xyz/utils +## 7.3.0 + +## 7.2.0 + +### Minor Changes + +- fa6d5f5c6: Add toUpperCamelCase and deepFind functions + ## 7.1.0 ### Minor Changes diff --git a/typescript/utils/eslint.config.mjs b/typescript/utils/eslint.config.mjs new file mode 100644 index 0000000000..b82e3eedb1 --- /dev/null +++ b/typescript/utils/eslint.config.mjs @@ -0,0 +1,3 @@ +import MonorepoDefaults from '../../eslint.config.mjs'; + +export default [...MonorepoDefaults, { files: ['./src/**/*.ts'] }]; diff --git a/typescript/utils/package.json b/typescript/utils/package.json index bbc326da3f..8b24cb7106 100644 --- a/typescript/utils/package.json +++ b/typescript/utils/package.json @@ -1,7 +1,7 @@ { "name": "@hyperlane-xyz/utils", "description": "General utilities and types for the Hyperlane network", - "version": "7.1.0", + "version": "7.3.0", "dependencies": { "@cosmjs/encoding": "^0.32.4", "@solana/web3.js": "^1.95.4", @@ -12,11 +12,18 @@ "yaml": "2.4.5" }, "devDependencies": { + "@eslint/js": "^9.15.0", "@types/lodash-es": "^4.17.12", "@types/mocha": "^10.0.1", "@types/sinon": "^17.0.1", "@types/sinon-chai": "^3.2.12", - "chai": "4.5.0", + "@typescript-eslint/eslint-plugin": "^8.1.6", + "@typescript-eslint/parser": "^8.1.6", + "chai": "^4.5.0", + "eslint": "^9.15.0", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import": "^2.31.0", "mocha": "^10.2.0", "prettier": "^2.8.8", "sinon": "^13.0.2", @@ -36,6 +43,7 @@ "build": "tsc", "clean": "rm -rf ./dist", "check": "tsc --noEmit", + "lint": "eslint -c ./eslint.config.mjs", "prettier": "prettier --write ./src", "test": "mocha --config .mocharc.json './src/**/*.test.ts'", "test:ci": "yarn test" diff --git a/typescript/utils/src/addresses.ts b/typescript/utils/src/addresses.ts index 01f9fdb107..29a35b6b88 100644 --- a/typescript/utils/src/addresses.ts +++ b/typescript/utils/src/addresses.ts @@ -80,7 +80,7 @@ export function isValidAddressEvm(address: Address) { try { const isValid = address && ethersUtils.isAddress(address); return !!isValid; - } catch (error) { + } catch { return false; } } @@ -90,7 +90,7 @@ export function isValidAddressSealevel(address: Address) { try { const isValid = address && new PublicKey(address).toBase58(); return !!isValid; - } catch (error) { + } catch { return false; } } @@ -104,7 +104,7 @@ export function isValidAddressCosmos(address: Address) { COSMOS_FACTORY_TOKEN_REGEX.test(address) || fromBech32(address)); return !!isValid; - } catch (error) { + } catch { return false; } } @@ -126,7 +126,7 @@ export function normalizeAddressEvm(address: Address) { if (isZeroishAddress(address)) return address; try { return ethersUtils.getAddress(address); - } catch (error) { + } catch { return address; } } @@ -135,7 +135,7 @@ export function normalizeAddressSealevel(address: Address) { if (isZeroishAddress(address)) return address; try { return new PublicKey(address).toBase58(); - } catch (error) { + } catch { return address; } } @@ -144,7 +144,7 @@ export function normalizeAddressCosmos(address: Address) { if (isZeroishAddress(address)) return address; try { return normalizeBech32(address); - } catch (error) { + } catch { return address; } } diff --git a/typescript/utils/src/amount.ts b/typescript/utils/src/amount.ts index f415c268d3..ab8a3b3347 100644 --- a/typescript/utils/src/amount.ts +++ b/typescript/utils/src/amount.ts @@ -82,7 +82,7 @@ export function tryParseAmount( const parsed = BigNumber(value); if (!parsed || parsed.isNaN() || !parsed.isFinite()) return null; else return parsed; - } catch (error) { + } catch { return null; } } diff --git a/typescript/utils/src/base64.ts b/typescript/utils/src/base64.ts index 1d2ae02fab..d09c4502e2 100644 --- a/typescript/utils/src/base64.ts +++ b/typescript/utils/src/base64.ts @@ -4,7 +4,7 @@ export function toBase64(data: any): string | undefined { try { if (!data) throw new Error('No data to encode'); return btoa(JSON.stringify(data)); - } catch (error) { + } catch { rootLogger.error('Unable to serialize + encode data to base64', data); return undefined; } @@ -15,7 +15,7 @@ export function fromBase64(data: string | string[]): T | undefined { if (!data) throw new Error('No data to decode'); const msg = Array.isArray(data) ? data[0] : data; return JSON.parse(atob(msg)); - } catch (error) { + } catch { rootLogger.error('Unable to decode + deserialize data from base64', data); return undefined; } diff --git a/typescript/utils/src/big-numbers.ts b/typescript/utils/src/big-numbers.ts index fa20e0759d..51e7a31ba9 100644 --- a/typescript/utils/src/big-numbers.ts +++ b/typescript/utils/src/big-numbers.ts @@ -15,7 +15,7 @@ export function isBigNumberish( try { const val = BigNumber(value!); return !val.isNaN() && val.isFinite() && BigNumber.isBigNumber(val); - } catch (error) { + } catch { return false; } } @@ -28,7 +28,7 @@ export function isBigNumberish( export function isZeroish(value: BigNumber.Value): boolean { try { return BigNumber(value).isZero(); - } catch (error) { + } catch { return false; } } diff --git a/typescript/utils/src/env.ts b/typescript/utils/src/env.ts index ff24f2486a..8841f56a80 100644 --- a/typescript/utils/src/env.ts +++ b/typescript/utils/src/env.ts @@ -3,7 +3,7 @@ export function safelyAccessEnvVar(name: string, toLowerCase = false) { try { return toLowerCase ? process.env[name]?.toLowerCase() : process.env[name]; - } catch (error) { + } catch { return undefined; } } diff --git a/typescript/utils/src/index.ts b/typescript/utils/src/index.ts index ff226449fe..8314418631 100644 --- a/typescript/utils/src/index.ts +++ b/typescript/utils/src/index.ts @@ -108,6 +108,7 @@ export { arrayToObject, deepCopy, deepEquals, + deepFind, diffObjMerge, invertKeysAndValues, isObjEmpty, @@ -139,6 +140,7 @@ export { streamToString, toHexString, toTitleCase, + toUpperCamelCase, trimToLength, } from './strings.js'; export { isNullish, isNumeric } from './typeof.js'; @@ -168,6 +170,7 @@ export { S3CheckpointWithId, SignatureLike, TokenCaip19Id, + ValidatorMetadata, WithAddress, } from './types.js'; export { isHttpsUrl, isRelativeUrl, isUrl } from './url.js'; diff --git a/typescript/utils/src/strings.ts b/typescript/utils/src/strings.ts index 26d40838aa..bc50107bba 100644 --- a/typescript/utils/src/strings.ts +++ b/typescript/utils/src/strings.ts @@ -6,6 +6,10 @@ export function toTitleCase(str: string) { }); } +export function toUpperCamelCase(string: string) { + return string.charAt(0).toUpperCase() + string.slice(1); +} + // Only allows letters and numbers const alphanumericRgex = /[^a-zA-Z0-9]/gi; export function sanitizeString(str: string) { diff --git a/typescript/utils/src/types.ts b/typescript/utils/src/types.ts index c2a3a1fcfd..c0b7ddee66 100644 --- a/typescript/utils/src/types.ts +++ b/typescript/utils/src/types.ts @@ -116,3 +116,7 @@ export type ParsedLegacyMultisigIsmMetadata = { export type Annotated = T & { annotation?: string; }; + +export type ValidatorMetadata = { + git_sha: string; +}; diff --git a/typescript/utils/src/url.ts b/typescript/utils/src/url.ts index 98f9ee412d..0d1c2b0abc 100644 --- a/typescript/utils/src/url.ts +++ b/typescript/utils/src/url.ts @@ -3,7 +3,7 @@ export function isUrl(value?: string | null) { if (!value) return false; const url = new URL(value); return !!url.hostname; - } catch (error) { + } catch { return false; } } @@ -13,7 +13,7 @@ export function isHttpsUrl(value?: string | null) { if (!value) return false; const url = new URL(value); return url.protocol === 'https:'; - } catch (error) { + } catch { return false; } } diff --git a/typescript/widgets/.eslintignore b/typescript/widgets/.eslintignore deleted file mode 100644 index c047b2694b..0000000000 --- a/typescript/widgets/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -node_modules -dist -coverage -tailwind.config.js -postcss.config.js -src/stories/**/*.stories.tsx diff --git a/typescript/widgets/.eslintrc b/typescript/widgets/.eslintrc deleted file mode 100644 index 9041f842f6..0000000000 --- a/typescript/widgets/.eslintrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": [ - "plugin:react/recommended", - "plugin:react-hooks/recommended", - "prettier" - ], - "plugins": ["react", "react-hooks"], - "rules": { - "react/react-in-jsx-scope": "off", - "react/prop-types": "off", - "react-hooks/rules-of-hooks": "error", - "react-hooks/exhaustive-deps": "warn" - }, - "settings": { - "react": { - "version": "18", - "defaultVersion": "18" - } - } -} diff --git a/typescript/widgets/CHANGELOG.md b/typescript/widgets/CHANGELOG.md index bcfbecee33..be73ca35c6 100644 --- a/typescript/widgets/CHANGELOG.md +++ b/typescript/widgets/CHANGELOG.md @@ -1,5 +1,36 @@ # @hyperlane-xyz/widgets +## 7.3.0 + +### Patch Changes + +- Updated dependencies [2054f4f5b] +- Updated dependencies [a96448fa6] +- Updated dependencies [170a0fc73] +- Updated dependencies [9a09afcc7] +- Updated dependencies [24784af95] +- Updated dependencies [3e8dd70ac] +- Updated dependencies [aa1ea9a48] +- Updated dependencies [665a7b8d8] +- Updated dependencies [f0b98fdef] +- Updated dependencies [ff9e8a72b] +- Updated dependencies [97c1f80b7] +- Updated dependencies [323f0f158] +- Updated dependencies [61157097b] + - @hyperlane-xyz/sdk@7.3.0 + - @hyperlane-xyz/utils@7.3.0 + +## 7.2.0 + +### Patch Changes + +- Updated dependencies [81ab4332f] +- Updated dependencies [4b3537470] +- Updated dependencies [fa6d5f5c6] +- Updated dependencies [fa6d5f5c6] + - @hyperlane-xyz/sdk@7.2.0 + - @hyperlane-xyz/utils@7.2.0 + ## 7.1.0 ### Minor Changes diff --git a/typescript/widgets/eslint.config.mjs b/typescript/widgets/eslint.config.mjs new file mode 100644 index 0000000000..e9f4b3ff39 --- /dev/null +++ b/typescript/widgets/eslint.config.mjs @@ -0,0 +1,40 @@ +import react from 'eslint-plugin-react'; +import reactHooks from 'eslint-plugin-react-hooks'; + +import MonorepoDefaults, {compat} from '../../eslint.config.mjs'; + +export default [ + ...MonorepoDefaults, + ...compat.extends("plugin:react/recommended", "plugin:react-hooks/recommended"), + { + settings: { + react: { + version: '18', + defaultVersion: '18', + }, + }, + }, + { + files: ['./src/**/*.ts', './src/**/*.tsx'], + plugins: { + react, + 'react-hooks': reactHooks, + }, + + + rules: { + 'react/react-in-jsx-scope': 'off', + 'react/prop-types': 'off', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + }, + }, + { + ignores: [ + '**/src/stories/*', + 'tailwind.config.js', + 'postcss.config.js', + '.storybook/*', + ], + }, +]; diff --git a/typescript/widgets/mg.eslint.config.mjs b/typescript/widgets/mg.eslint.config.mjs new file mode 100644 index 0000000000..a66e159b3d --- /dev/null +++ b/typescript/widgets/mg.eslint.config.mjs @@ -0,0 +1,38 @@ +import { fixupConfigRules, fixupPluginRules } from "@eslint/compat"; +import react from "eslint-plugin-react"; +import reactHooks from "eslint-plugin-react-hooks"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import js from "@eslint/js"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all +}); + +export default [...fixupConfigRules( + compat.extends("plugin:react/recommended", "plugin:react-hooks/recommended", "prettier"), +), { + plugins: { + react: fixupPluginRules(react), + "react-hooks": fixupPluginRules(reactHooks), + }, + + settings: { + react: { + version: "18", + defaultVersion: "18", + }, + }, + + rules: { + "react/react-in-jsx-scope": "off", + "react/prop-types": "off", + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "warn", + }, +}]; \ No newline at end of file diff --git a/typescript/widgets/package.json b/typescript/widgets/package.json index 8a4331ef0c..f662fa2a29 100644 --- a/typescript/widgets/package.json +++ b/typescript/widgets/package.json @@ -1,7 +1,7 @@ { "name": "@hyperlane-xyz/widgets", "description": "Common react components for Hyperlane projects", - "version": "7.1.0", + "version": "7.3.0", "peerDependencies": { "react": "^18", "react-dom": "^18" @@ -9,8 +9,8 @@ "dependencies": { "@cosmos-kit/react": "^2.18.0", "@headlessui/react": "^2.1.8", - "@hyperlane-xyz/sdk": "7.1.0", - "@hyperlane-xyz/utils": "7.1.0", + "@hyperlane-xyz/sdk": "7.3.0", + "@hyperlane-xyz/utils": "7.3.0", "@interchain-ui/react": "^1.23.28", "@rainbow-me/rainbowkit": "^2.2.0", "@solana/wallet-adapter-react": "^0.15.32", @@ -18,7 +18,7 @@ "@solana/web3.js": "^1.95.4", "clsx": "^2.1.1", "react-tooltip": "^5.28.0", - "viem": "^2.21.41", + "viem": "^2.21.45", "wagmi": "^2.12.26" }, "devDependencies": { @@ -26,7 +26,8 @@ "@cosmjs/cosmwasm-stargate": "^0.32.4", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", - "@hyperlane-xyz/registry": "6.1.0", + "@eslint/js": "^9.15.0", + "@hyperlane-xyz/registry": "6.3.0", "@storybook/addon-essentials": "^7.6.14", "@storybook/addon-interactions": "^7.6.14", "@storybook/addon-links": "^7.6.14", @@ -36,18 +37,20 @@ "@storybook/react-vite": "^7.6.14", "@storybook/test": "^7.6.14", "@tanstack/react-query": "^5.59.20", - "@types/node": "^18.11.18", + "@types/node": "^18.14.5", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", "@types/ws": "^8.5.5", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", + "@typescript-eslint/eslint-plugin": "^8.1.6", + "@typescript-eslint/parser": "^8.1.6", "babel-loader": "^8.3.0", - "eslint": "^8.57.0", + "eslint": "^9.15.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-react": "^7.37.2", "eslint-plugin-react-hooks": "^5.0.0", - "eslint-plugin-storybook": "^0.6.15", + "eslint-plugin-storybook": "^0.11.1", "framer-motion": "^10.16.4", "postcss": "^8.4.21", "prettier": "^2.8.8", @@ -86,7 +89,7 @@ "build:ts": "tsc", "build:css": "tailwindcss -c ./tailwind.config.cjs -i ./src/styles.css -o ./dist/styles.css --minify", "clean": "rm -rf ./dist ./cache ./storybook-static", - "lint": "eslint ./src --ext '.ts,.tsx'", + "lint": "eslint -c ./eslint.config.mjs", "prettier": "prettier --write ./src", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" diff --git a/typescript/widgets/src/chains/ChainAddMenu.tsx b/typescript/widgets/src/chains/ChainAddMenu.tsx index 9b3c4065c0..032366f01e 100644 --- a/typescript/widgets/src/chains/ChainAddMenu.tsx +++ b/typescript/widgets/src/chains/ChainAddMenu.tsx @@ -1,4 +1,4 @@ -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { useState } from 'react'; import { DEFAULT_GITHUB_REGISTRY } from '@hyperlane-xyz/registry'; diff --git a/typescript/widgets/src/chains/ChainDetailsMenu.tsx b/typescript/widgets/src/chains/ChainDetailsMenu.tsx index 7c175d0d88..468b60a8e4 100644 --- a/typescript/widgets/src/chains/ChainDetailsMenu.tsx +++ b/typescript/widgets/src/chains/ChainDetailsMenu.tsx @@ -1,4 +1,4 @@ -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { PropsWithChildren, useEffect, useMemo, useState } from 'react'; import { stringify as yamlStringify } from 'yaml'; diff --git a/typescript/widgets/src/chains/ChainSearchMenu.tsx b/typescript/widgets/src/chains/ChainSearchMenu.tsx index 59532e9f6d..a945e4bd93 100644 --- a/typescript/widgets/src/chains/ChainSearchMenu.tsx +++ b/typescript/widgets/src/chains/ChainSearchMenu.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { ChainMap, @@ -77,11 +77,11 @@ export function ChainSearchMenu({ showAddChainMenu, defaultSortField, }: ChainSearchMenuProps) { - const [drilldownChain, setDrilldownChain] = React.useState< - ChainName | undefined - >(showChainDetails); + const [drilldownChain, setDrilldownChain] = useState( + showChainDetails, + ); - const [addChain, setAddChain] = React.useState(showAddChainMenu || false); + const [addChain, setAddChain] = useState(showAddChainMenu || false); const { listData, mergedMetadata } = useMemo(() => { const mergedMetadata = mergeChainMetadataMap( diff --git a/typescript/widgets/src/components/Button.tsx b/typescript/widgets/src/components/Button.tsx index 3177af05b7..e983bd5645 100644 --- a/typescript/widgets/src/components/Button.tsx +++ b/typescript/widgets/src/components/Button.tsx @@ -1,4 +1,4 @@ -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { ButtonHTMLAttributes, PropsWithChildren } from 'react'; type Props = PropsWithChildren>; diff --git a/typescript/widgets/src/components/IconButton.tsx b/typescript/widgets/src/components/IconButton.tsx index 314ba40fa4..eeeddc57d7 100644 --- a/typescript/widgets/src/components/IconButton.tsx +++ b/typescript/widgets/src/components/IconButton.tsx @@ -1,4 +1,4 @@ -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { ButtonHTMLAttributes, PropsWithChildren } from 'react'; type Props = PropsWithChildren> & { diff --git a/typescript/widgets/src/components/LinkButton.tsx b/typescript/widgets/src/components/LinkButton.tsx index 026bf6ba11..5fb6c53c9c 100644 --- a/typescript/widgets/src/components/LinkButton.tsx +++ b/typescript/widgets/src/components/LinkButton.tsx @@ -1,4 +1,4 @@ -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { ButtonHTMLAttributes, PropsWithChildren } from 'react'; type Props = PropsWithChildren>; diff --git a/typescript/widgets/src/components/SearchMenu.tsx b/typescript/widgets/src/components/SearchMenu.tsx index 44c1c2c79f..750d2bfb3d 100644 --- a/typescript/widgets/src/components/SearchMenu.tsx +++ b/typescript/widgets/src/components/SearchMenu.tsx @@ -1,6 +1,7 @@ -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { ComponentType, + forwardRef, useCallback, useEffect, useMemo, @@ -184,7 +185,7 @@ export function SearchMenu< ); } -const SearchBar = React.forwardRef(function SearchBar( +const SearchBar = forwardRef(function SearchBar( { onChange, value, ...props }: InputProps, ref: React.Ref, ) { diff --git a/typescript/widgets/src/components/TextInput.tsx b/typescript/widgets/src/components/TextInput.tsx index e2dfa8e8e7..42f74f199d 100644 --- a/typescript/widgets/src/components/TextInput.tsx +++ b/typescript/widgets/src/components/TextInput.tsx @@ -1,4 +1,4 @@ -import React, { ChangeEvent, InputHTMLAttributes } from 'react'; +import React, { ChangeEvent, InputHTMLAttributes, forwardRef } from 'react'; export type InputProps = Omit< InputHTMLAttributes, @@ -28,4 +28,4 @@ export function _TextInput( ); } -export const TextInput = React.forwardRef(_TextInput); +export const TextInput = forwardRef(_TextInput); diff --git a/typescript/widgets/src/layout/DropdownMenu.tsx b/typescript/widgets/src/layout/DropdownMenu.tsx index 837a219e76..6dbca2248a 100644 --- a/typescript/widgets/src/layout/DropdownMenu.tsx +++ b/typescript/widgets/src/layout/DropdownMenu.tsx @@ -1,5 +1,5 @@ import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react'; -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { ComponentProps, ReactNode } from 'react'; export type DropdownMenuProps = { diff --git a/typescript/widgets/src/layout/Modal.tsx b/typescript/widgets/src/layout/Modal.tsx index bc0b872f01..12a774bbe7 100644 --- a/typescript/widgets/src/layout/Modal.tsx +++ b/typescript/widgets/src/layout/Modal.tsx @@ -4,7 +4,7 @@ import { DialogPanel, DialogTitle, } from '@headlessui/react'; -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { ComponentProps, PropsWithChildren, useState } from 'react'; import { IconButton } from '../components/IconButton.js'; diff --git a/typescript/widgets/src/layout/Popover.tsx b/typescript/widgets/src/layout/Popover.tsx index 34e7793fb2..f0f1b82292 100644 --- a/typescript/widgets/src/layout/Popover.tsx +++ b/typescript/widgets/src/layout/Popover.tsx @@ -3,7 +3,7 @@ import { PopoverPanel, Popover as _Popover, } from '@headlessui/react'; -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { ComponentProps, ReactNode } from 'react'; export type PopoverProps = { diff --git a/typescript/widgets/src/walletIntegrations/AccountList.tsx b/typescript/widgets/src/walletIntegrations/AccountList.tsx index db99a33a44..63d08baada 100644 --- a/typescript/widgets/src/walletIntegrations/AccountList.tsx +++ b/typescript/widgets/src/walletIntegrations/AccountList.tsx @@ -1,4 +1,4 @@ -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { ButtonHTMLAttributes } from 'react'; import { MultiProtocolProvider } from '@hyperlane-xyz/sdk'; diff --git a/typescript/widgets/src/walletIntegrations/ConnectWalletButton.tsx b/typescript/widgets/src/walletIntegrations/ConnectWalletButton.tsx index 8ecc32f846..1d64e9cf70 100644 --- a/typescript/widgets/src/walletIntegrations/ConnectWalletButton.tsx +++ b/typescript/widgets/src/walletIntegrations/ConnectWalletButton.tsx @@ -1,4 +1,4 @@ -import clsx from 'clsx'; +import { clsx } from 'clsx'; import React, { ButtonHTMLAttributes } from 'react'; import { MultiProtocolProvider } from '@hyperlane-xyz/sdk'; diff --git a/yarn.lock b/yarn.lock index 1a658284c0..91d745e473 100644 --- a/yarn.lock +++ b/yarn.lock @@ -55,18 +55,6 @@ __metadata: languageName: node linkType: hard -"@arbitrum/sdk@npm:^3.0.0": - version: 3.0.0 - resolution: "@arbitrum/sdk@npm:3.0.0" - dependencies: - "@ethersproject/address": "npm:^5.0.8" - "@ethersproject/bignumber": "npm:^5.1.1" - "@ethersproject/bytes": "npm:^5.0.8" - ethers: "npm:^5.1.0" - checksum: 10/f4f7d05631d2014546cccff85926a638e3725e522e2c9c73c70caafec8f14cf7b22f58c8f942ced2f8bd44ea545b63c99cf5044c833edd0d52934afdddbf1d40 - languageName: node - linkType: hard - "@arbitrum/sdk@npm:^4.0.0": version: 4.0.1 resolution: "@arbitrum/sdk@npm:4.0.1" @@ -91,17 +79,6 @@ __metadata: languageName: node linkType: hard -"@aws-crypto/crc32@npm:2.0.0": - version: 2.0.0 - resolution: "@aws-crypto/crc32@npm:2.0.0" - dependencies: - "@aws-crypto/util": "npm:^2.0.0" - "@aws-sdk/types": "npm:^3.1.0" - tslib: "npm:^1.11.1" - checksum: 10/da8e32353f958775b4476150c6b457ce1a04b962cdb227842f8a3fa52cb996eb979b2858d19abd6703256c0befc08ee80e3ce48e02d39900640dc6696b151701 - languageName: node - linkType: hard - "@aws-crypto/crc32@npm:3.0.0": version: 3.0.0 resolution: "@aws-crypto/crc32@npm:3.0.0" @@ -113,17 +90,6 @@ __metadata: languageName: node linkType: hard -"@aws-crypto/crc32c@npm:2.0.0": - version: 2.0.0 - resolution: "@aws-crypto/crc32c@npm:2.0.0" - dependencies: - "@aws-crypto/util": "npm:^2.0.0" - "@aws-sdk/types": "npm:^3.1.0" - tslib: "npm:^1.11.1" - checksum: 10/04496af8f9a4822bf09793c7df20fbebbdda75484eb1c8a89e98b41ab4e0b57ce9e33b4b30d6b741d85c2f751298fc39919184b5985c66e252d180ddc6f30ab1 - languageName: node - linkType: hard - "@aws-crypto/crc32c@npm:3.0.0": version: 3.0.0 resolution: "@aws-crypto/crc32c@npm:3.0.0" @@ -153,20 +119,6 @@ __metadata: languageName: node linkType: hard -"@aws-crypto/sha1-browser@npm:2.0.0": - version: 2.0.0 - resolution: "@aws-crypto/sha1-browser@npm:2.0.0" - dependencies: - "@aws-crypto/ie11-detection": "npm:^2.0.0" - "@aws-crypto/supports-web-crypto": "npm:^2.0.0" - "@aws-sdk/types": "npm:^3.1.0" - "@aws-sdk/util-locate-window": "npm:^3.0.0" - "@aws-sdk/util-utf8-browser": "npm:^3.0.0" - tslib: "npm:^1.11.1" - checksum: 10/7a1e828741339effdb26e89b28d30010f954192c75dc197fe9856faf46d9fd998b3a8c473c3f8b86ebc259ef1162191c6bd4c9c23803ea0b66b3abcff511917a - languageName: node - linkType: hard - "@aws-crypto/sha1-browser@npm:3.0.0": version: 3.0.0 resolution: "@aws-crypto/sha1-browser@npm:3.0.0" @@ -319,16 +271,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/abort-controller@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/abort-controller@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/97a5a4dfb433be2738a4ca11b830e434df1e7af9448dbbce3bd11d9f13f1e29eb987a859163250b8d49e3f0e8b8cbc5199131138b5e16a2f99daa9c2a1454f79 - languageName: node - linkType: hard - "@aws-sdk/abort-controller@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/abort-controller@npm:3.78.0" @@ -339,25 +281,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/chunked-blob-reader-native@npm:3.58.0": - version: 3.58.0 - resolution: "@aws-sdk/chunked-blob-reader-native@npm:3.58.0" - dependencies: - "@aws-sdk/util-base64-browser": "npm:3.58.0" - tslib: "npm:^2.3.1" - checksum: 10/7826f67d2f1f4af0939ae0d764ee617e02fd4e46e14e12714b559043c9ab77dcd7287ec94636bc2849b2b179803058313a1902944d647a4afe81989730c5de08 - languageName: node - linkType: hard - -"@aws-sdk/chunked-blob-reader@npm:3.55.0": - version: 3.55.0 - resolution: "@aws-sdk/chunked-blob-reader@npm:3.55.0" - dependencies: - tslib: "npm:^2.3.1" - checksum: 10/e19fcff0162b2b28a46a3c3c4936f4e7ae7c2588aac0948ec2796ac6b0d51ae8e3d50bd855f7b07230c80e00708283352435d024e16834b61d7d353b22120d73 - languageName: node - linkType: hard - "@aws-sdk/client-iam@npm:^3.74.0": version: 3.107.0 resolution: "@aws-sdk/client-iam@npm:3.107.0" @@ -403,47 +326,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-kms@npm:3.48.0": - version: 3.48.0 - resolution: "@aws-sdk/client-kms@npm:3.48.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:2.0.0" - "@aws-crypto/sha256-js": "npm:2.0.0" - "@aws-sdk/client-sts": "npm:3.48.0" - "@aws-sdk/config-resolver": "npm:3.47.2" - "@aws-sdk/credential-provider-node": "npm:3.48.0" - "@aws-sdk/fetch-http-handler": "npm:3.47.2" - "@aws-sdk/hash-node": "npm:3.47.2" - "@aws-sdk/invalid-dependency": "npm:3.47.2" - "@aws-sdk/middleware-content-length": "npm:3.47.2" - "@aws-sdk/middleware-host-header": "npm:3.47.2" - "@aws-sdk/middleware-logger": "npm:3.47.2" - "@aws-sdk/middleware-retry": "npm:3.47.2" - "@aws-sdk/middleware-serde": "npm:3.47.2" - "@aws-sdk/middleware-signing": "npm:3.47.2" - "@aws-sdk/middleware-stack": "npm:3.47.2" - "@aws-sdk/middleware-user-agent": "npm:3.47.2" - "@aws-sdk/node-config-provider": "npm:3.47.2" - "@aws-sdk/node-http-handler": "npm:3.47.2" - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/smithy-client": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/url-parser": "npm:3.47.2" - "@aws-sdk/util-base64-browser": "npm:3.47.1" - "@aws-sdk/util-base64-node": "npm:3.47.2" - "@aws-sdk/util-body-length-browser": "npm:3.47.1" - "@aws-sdk/util-body-length-node": "npm:3.47.1" - "@aws-sdk/util-defaults-mode-browser": "npm:3.47.2" - "@aws-sdk/util-defaults-mode-node": "npm:3.47.2" - "@aws-sdk/util-user-agent-browser": "npm:3.47.2" - "@aws-sdk/util-user-agent-node": "npm:3.47.2" - "@aws-sdk/util-utf8-browser": "npm:3.47.1" - "@aws-sdk/util-utf8-node": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/eff5d95d51bddcefe533dbab1c45cc06e1cd4b6549ae9cc2e1cbfb23dec21292649e5d9335751cfb773674e73507e35fc026245878d7e61c903ed12242f76e9b - languageName: node - linkType: hard - "@aws-sdk/client-kms@npm:^3.28.0, @aws-sdk/client-kms@npm:^3.39.0": version: 3.142.0 resolution: "@aws-sdk/client-kms@npm:3.142.0" @@ -601,68 +483,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-s3@npm:^3.74.0": - version: 3.107.0 - resolution: "@aws-sdk/client-s3@npm:3.107.0" - dependencies: - "@aws-crypto/sha1-browser": "npm:2.0.0" - "@aws-crypto/sha256-browser": "npm:2.0.0" - "@aws-crypto/sha256-js": "npm:2.0.0" - "@aws-sdk/client-sts": "npm:3.105.0" - "@aws-sdk/config-resolver": "npm:3.80.0" - "@aws-sdk/credential-provider-node": "npm:3.105.0" - "@aws-sdk/eventstream-serde-browser": "npm:3.78.0" - "@aws-sdk/eventstream-serde-config-resolver": "npm:3.78.0" - "@aws-sdk/eventstream-serde-node": "npm:3.78.0" - "@aws-sdk/fetch-http-handler": "npm:3.78.0" - "@aws-sdk/hash-blob-browser": "npm:3.78.0" - "@aws-sdk/hash-node": "npm:3.78.0" - "@aws-sdk/hash-stream-node": "npm:3.78.0" - "@aws-sdk/invalid-dependency": "npm:3.78.0" - "@aws-sdk/md5-js": "npm:3.78.0" - "@aws-sdk/middleware-bucket-endpoint": "npm:3.80.0" - "@aws-sdk/middleware-content-length": "npm:3.78.0" - "@aws-sdk/middleware-expect-continue": "npm:3.78.0" - "@aws-sdk/middleware-flexible-checksums": "npm:3.78.0" - "@aws-sdk/middleware-host-header": "npm:3.78.0" - "@aws-sdk/middleware-location-constraint": "npm:3.78.0" - "@aws-sdk/middleware-logger": "npm:3.78.0" - "@aws-sdk/middleware-recursion-detection": "npm:3.105.0" - "@aws-sdk/middleware-retry": "npm:3.80.0" - "@aws-sdk/middleware-sdk-s3": "npm:3.105.0" - "@aws-sdk/middleware-serde": "npm:3.78.0" - "@aws-sdk/middleware-signing": "npm:3.78.0" - "@aws-sdk/middleware-ssec": "npm:3.78.0" - "@aws-sdk/middleware-stack": "npm:3.78.0" - "@aws-sdk/middleware-user-agent": "npm:3.78.0" - "@aws-sdk/node-config-provider": "npm:3.80.0" - "@aws-sdk/node-http-handler": "npm:3.94.0" - "@aws-sdk/protocol-http": "npm:3.78.0" - "@aws-sdk/signature-v4-multi-region": "npm:3.88.0" - "@aws-sdk/smithy-client": "npm:3.99.0" - "@aws-sdk/types": "npm:3.78.0" - "@aws-sdk/url-parser": "npm:3.78.0" - "@aws-sdk/util-base64-browser": "npm:3.58.0" - "@aws-sdk/util-base64-node": "npm:3.55.0" - "@aws-sdk/util-body-length-browser": "npm:3.55.0" - "@aws-sdk/util-body-length-node": "npm:3.55.0" - "@aws-sdk/util-defaults-mode-browser": "npm:3.99.0" - "@aws-sdk/util-defaults-mode-node": "npm:3.99.0" - "@aws-sdk/util-stream-browser": "npm:3.78.0" - "@aws-sdk/util-stream-node": "npm:3.78.0" - "@aws-sdk/util-user-agent-browser": "npm:3.78.0" - "@aws-sdk/util-user-agent-node": "npm:3.80.0" - "@aws-sdk/util-utf8-browser": "npm:3.55.0" - "@aws-sdk/util-utf8-node": "npm:3.55.0" - "@aws-sdk/util-waiter": "npm:3.78.0" - "@aws-sdk/xml-builder": "npm:3.55.0" - entities: "npm:2.2.0" - fast-xml-parser: "npm:3.19.0" - tslib: "npm:^2.3.1" - checksum: 10/827f4fae394677bba41f581c851effc438935e49480d99a26c15c3315ea7a1a696c15163b2de44ef0b40e7bb05396c372e3b200e974133e238d262c33fbe6f1d - languageName: node - linkType: hard - "@aws-sdk/client-sso-oidc@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/client-sso-oidc@npm:3.577.0" @@ -789,44 +609,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.48.0": - version: 3.48.0 - resolution: "@aws-sdk/client-sso@npm:3.48.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:2.0.0" - "@aws-crypto/sha256-js": "npm:2.0.0" - "@aws-sdk/config-resolver": "npm:3.47.2" - "@aws-sdk/fetch-http-handler": "npm:3.47.2" - "@aws-sdk/hash-node": "npm:3.47.2" - "@aws-sdk/invalid-dependency": "npm:3.47.2" - "@aws-sdk/middleware-content-length": "npm:3.47.2" - "@aws-sdk/middleware-host-header": "npm:3.47.2" - "@aws-sdk/middleware-logger": "npm:3.47.2" - "@aws-sdk/middleware-retry": "npm:3.47.2" - "@aws-sdk/middleware-serde": "npm:3.47.2" - "@aws-sdk/middleware-stack": "npm:3.47.2" - "@aws-sdk/middleware-user-agent": "npm:3.47.2" - "@aws-sdk/node-config-provider": "npm:3.47.2" - "@aws-sdk/node-http-handler": "npm:3.47.2" - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/smithy-client": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/url-parser": "npm:3.47.2" - "@aws-sdk/util-base64-browser": "npm:3.47.1" - "@aws-sdk/util-base64-node": "npm:3.47.2" - "@aws-sdk/util-body-length-browser": "npm:3.47.1" - "@aws-sdk/util-body-length-node": "npm:3.47.1" - "@aws-sdk/util-defaults-mode-browser": "npm:3.47.2" - "@aws-sdk/util-defaults-mode-node": "npm:3.47.2" - "@aws-sdk/util-user-agent-browser": "npm:3.47.2" - "@aws-sdk/util-user-agent-node": "npm:3.47.2" - "@aws-sdk/util-utf8-browser": "npm:3.47.1" - "@aws-sdk/util-utf8-node": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/917bb56fdc67a324aa7c933f0dc9405036f98306ddf4a8cccade01801d91a8becde30f5b979a7f4f8084fddc3b028292a8c3fce03d9d1f60c9ed450e602aa607 - languageName: node - linkType: hard - "@aws-sdk/client-sso@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/client-sso@npm:3.577.0" @@ -961,49 +743,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.48.0": - version: 3.48.0 - resolution: "@aws-sdk/client-sts@npm:3.48.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:2.0.0" - "@aws-crypto/sha256-js": "npm:2.0.0" - "@aws-sdk/config-resolver": "npm:3.47.2" - "@aws-sdk/credential-provider-node": "npm:3.48.0" - "@aws-sdk/fetch-http-handler": "npm:3.47.2" - "@aws-sdk/hash-node": "npm:3.47.2" - "@aws-sdk/invalid-dependency": "npm:3.47.2" - "@aws-sdk/middleware-content-length": "npm:3.47.2" - "@aws-sdk/middleware-host-header": "npm:3.47.2" - "@aws-sdk/middleware-logger": "npm:3.47.2" - "@aws-sdk/middleware-retry": "npm:3.47.2" - "@aws-sdk/middleware-sdk-sts": "npm:3.47.2" - "@aws-sdk/middleware-serde": "npm:3.47.2" - "@aws-sdk/middleware-signing": "npm:3.47.2" - "@aws-sdk/middleware-stack": "npm:3.47.2" - "@aws-sdk/middleware-user-agent": "npm:3.47.2" - "@aws-sdk/node-config-provider": "npm:3.47.2" - "@aws-sdk/node-http-handler": "npm:3.47.2" - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/smithy-client": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/url-parser": "npm:3.47.2" - "@aws-sdk/util-base64-browser": "npm:3.47.1" - "@aws-sdk/util-base64-node": "npm:3.47.2" - "@aws-sdk/util-body-length-browser": "npm:3.47.1" - "@aws-sdk/util-body-length-node": "npm:3.47.1" - "@aws-sdk/util-defaults-mode-browser": "npm:3.47.2" - "@aws-sdk/util-defaults-mode-node": "npm:3.47.2" - "@aws-sdk/util-user-agent-browser": "npm:3.47.2" - "@aws-sdk/util-user-agent-node": "npm:3.47.2" - "@aws-sdk/util-utf8-browser": "npm:3.47.1" - "@aws-sdk/util-utf8-node": "npm:3.47.2" - entities: "npm:2.2.0" - fast-xml-parser: "npm:3.19.0" - tslib: "npm:^2.3.0" - checksum: 10/2ee2017400b1fc8113a2b74325f3bbc5f333143df910c78ad9dd3ab109ec1e1066b713d54192791966dfe7497e69b675938ddd9a896a125eada237f0d2bd2152 - languageName: node - linkType: hard - "@aws-sdk/client-sts@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/client-sts@npm:3.577.0" @@ -1065,18 +804,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/config-resolver@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/config-resolver@npm:3.47.2" - dependencies: - "@aws-sdk/signature-v4": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/util-config-provider": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/7e4f342261a12bb8c041fdc8ab76f9e1b2a2370e607f50a7a099cba174a3d11a32640399d344ed312ace34d7e118b71ca7c4c83df595989718b501cecc894413 - languageName: node - linkType: hard - "@aws-sdk/config-resolver@npm:3.80.0": version: 3.80.0 resolution: "@aws-sdk/config-resolver@npm:3.80.0" @@ -1116,17 +843,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/credential-provider-env@npm:3.47.2" - dependencies: - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/11416fb43d27a60c5c3b493f4145adabb6e4277642e94e429eb770c5ee9029a49230ac63b9088a9465c8bf93acf48673c289ae1666a7e34ab6c6f9d58539e08e - languageName: node - linkType: hard - "@aws-sdk/credential-provider-env@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/credential-provider-env@npm:3.577.0" @@ -1180,19 +896,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-imds@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/credential-provider-imds@npm:3.47.2" - dependencies: - "@aws-sdk/node-config-provider": "npm:3.47.2" - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/url-parser": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/37745d9957be76f2edcb73c7668e1af35c7e532f0dec477927222a692ebf84dcaa4393d8c27b8460eb2fdf7d8a4bbf1f959ac9dd3a8f05f0884d5bb20b2f2663 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-imds@npm:3.81.0": version: 3.81.0 resolution: "@aws-sdk/credential-provider-imds@npm:3.81.0" @@ -1238,23 +941,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.48.0": - version: 3.48.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.48.0" - dependencies: - "@aws-sdk/credential-provider-env": "npm:3.47.2" - "@aws-sdk/credential-provider-imds": "npm:3.47.2" - "@aws-sdk/credential-provider-sso": "npm:3.48.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.47.2" - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/shared-ini-file-loader": "npm:3.47.1" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/util-credentials": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/9c2d58944e5d6dd9076b82d6858562e7a5b4766b32d8a4a23040b6d0933b8cb8481a97939d1c53a29a26dd6b2486601e466146b0f2e99b37afd21cc58ae19537 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-ini@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/credential-provider-ini@npm:3.577.0" @@ -1311,25 +997,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.48.0": - version: 3.48.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.48.0" - dependencies: - "@aws-sdk/credential-provider-env": "npm:3.47.2" - "@aws-sdk/credential-provider-imds": "npm:3.47.2" - "@aws-sdk/credential-provider-ini": "npm:3.48.0" - "@aws-sdk/credential-provider-process": "npm:3.47.2" - "@aws-sdk/credential-provider-sso": "npm:3.48.0" - "@aws-sdk/credential-provider-web-identity": "npm:3.47.2" - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/shared-ini-file-loader": "npm:3.47.1" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/util-credentials": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/6b038691cffad9a8cd54a1e7cb4da927205fea7e5ba2add4788216f2af4280635d1e6b0c63927866fc0ba6f156b76485643670a462dacfb841e9abba91fb4584 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-node@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/credential-provider-node@npm:3.577.0" @@ -1362,19 +1029,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/credential-provider-process@npm:3.47.2" - dependencies: - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/shared-ini-file-loader": "npm:3.47.1" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/util-credentials": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/d59d900f443b8fd2f8b74902bc0c0d6bdf0156a8d44981165e051e6856793d80b84ba43b87f77c24fe1569426365bfb226e3599d60e589abbe2349de00e32666 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-process@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/credential-provider-process@npm:3.577.0" @@ -1426,20 +1080,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.48.0": - version: 3.48.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.48.0" - dependencies: - "@aws-sdk/client-sso": "npm:3.48.0" - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/shared-ini-file-loader": "npm:3.47.1" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/util-credentials": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/0c012e75023687c72fcf8945b0b83242d8d2e2f526b2c241f77ab9b1ab462292f836b5e1866966b6bf5db3ff2c1fba2a554304651e8257ccbe2e47d3bc1f8db1 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-sso@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/credential-provider-sso@npm:3.577.0" @@ -1466,17 +1106,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.47.2" - dependencies: - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/eb85ea63ad1875dccb1efec76cb8c297a256fa9988a45141d242812e0ea059fa9b41ab4a912aea96c66a25321cc7c003ab834c707df96949c6380c6ca1111929 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-web-identity@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.577.0" @@ -1502,63 +1131,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/eventstream-marshaller@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/eventstream-marshaller@npm:3.78.0" - dependencies: - "@aws-crypto/crc32": "npm:2.0.0" - "@aws-sdk/types": "npm:3.78.0" - "@aws-sdk/util-hex-encoding": "npm:3.58.0" - tslib: "npm:^2.3.1" - checksum: 10/e62d0792d28d2bc9b7ce04c95442d698f2d7043872bfc0c91422ed4e3a5b38fa1284148dc4be06545aaa0d52107650bb53da9a37733f23e30ff83ca83a93652d - languageName: node - linkType: hard - -"@aws-sdk/eventstream-serde-browser@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/eventstream-serde-browser@npm:3.78.0" - dependencies: - "@aws-sdk/eventstream-marshaller": "npm:3.78.0" - "@aws-sdk/eventstream-serde-universal": "npm:3.78.0" - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/f2be29f11c2c02c41fd161495edab2b2a90a0087840626aa8d5209e005e6be510d48cf543871a77e508db472c47922823101fda35dd9f1f2e65401ce652edfb5 - languageName: node - linkType: hard - -"@aws-sdk/eventstream-serde-config-resolver@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/eventstream-serde-config-resolver@npm:3.78.0" - dependencies: - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/38bf3a5a496bedf5f5bb1a32da4934dbfe720594fb0d3028da861428f1d0fba2091d1d634eada9e132019486682a5d318648120bf5ca87ddfe38b8a3be7c0c62 - languageName: node - linkType: hard - -"@aws-sdk/eventstream-serde-node@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/eventstream-serde-node@npm:3.78.0" - dependencies: - "@aws-sdk/eventstream-marshaller": "npm:3.78.0" - "@aws-sdk/eventstream-serde-universal": "npm:3.78.0" - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/d0eb279d27d4757c33e7ccb69ff31036ab1d5573570daebeabac773a708e89fa85c0bf8569c6d6faf976734ef4e09d5375f589723819e095d076090ff68361c7 - languageName: node - linkType: hard - -"@aws-sdk/eventstream-serde-universal@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/eventstream-serde-universal@npm:3.78.0" - dependencies: - "@aws-sdk/eventstream-marshaller": "npm:3.78.0" - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/fe8f7f219ce43d8920ff8a1434507f1504b652e03b18a53f01f7d9d60a1f0ccf6d5d0abff8c3317be20e93c317491ae140af404f5175f6b8056cf315ceb9cb86 - languageName: node - linkType: hard - "@aws-sdk/fetch-http-handler@npm:3.131.0": version: 3.131.0 resolution: "@aws-sdk/fetch-http-handler@npm:3.131.0" @@ -1572,19 +1144,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/fetch-http-handler@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/fetch-http-handler@npm:3.47.2" - dependencies: - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/querystring-builder": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/util-base64-browser": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/a37cc6cce12ab8d1a280d7f9c60e97972ed4bc9d7677418af65cd0ea18e8db4d01561a6d8d4ce8da643256b5e9087369d881532001c7076d85810a60143de69b - languageName: node - linkType: hard - "@aws-sdk/fetch-http-handler@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/fetch-http-handler@npm:3.78.0" @@ -1598,18 +1157,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/hash-blob-browser@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/hash-blob-browser@npm:3.78.0" - dependencies: - "@aws-sdk/chunked-blob-reader": "npm:3.55.0" - "@aws-sdk/chunked-blob-reader-native": "npm:3.58.0" - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/5e257b36f93bfa3af233c061f8cb2f8be28d1a21a176654acffc90b0040174fff6d181012d33729a59d7e991f0e960dfbd455a34181c1298ede52418ad606a58 - languageName: node - linkType: hard - "@aws-sdk/hash-node@npm:3.127.0": version: 3.127.0 resolution: "@aws-sdk/hash-node@npm:3.127.0" @@ -1621,17 +1168,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/hash-node@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/hash-node@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/util-buffer-from": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/b240e43e4bd4744e32e7f578118435cc9e0d069e50ec9c9669beb8813582fb1f0ddb5d58948593d7227d7cce4d2fe416255b91c8c5c8ee7385e7f7520b0a9e10 - languageName: node - linkType: hard - "@aws-sdk/hash-node@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/hash-node@npm:3.78.0" @@ -1643,16 +1179,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/hash-stream-node@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/hash-stream-node@npm:3.78.0" - dependencies: - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/dba65ef684458e45c03b9555d6ecb16747299bc30be3341b34f542f1b511bbda685df384dc729717254e4ae1756b775e2743b3e93e1635cf6d8dd34a90f167ac - languageName: node - linkType: hard - "@aws-sdk/invalid-dependency@npm:3.127.0": version: 3.127.0 resolution: "@aws-sdk/invalid-dependency@npm:3.127.0" @@ -1663,16 +1189,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/invalid-dependency@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/invalid-dependency@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/a5808f8e4d4d696610a3be8e6dee2ad387187eef9a05edaf008b4af12838f9f5cb900729698228fdeaed5ededdae080d91d1c2607cc30d650cb92dd09a8c7b05 - languageName: node - linkType: hard - "@aws-sdk/invalid-dependency@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/invalid-dependency@npm:3.78.0" @@ -1683,15 +1199,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/is-array-buffer@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/is-array-buffer@npm:3.47.1" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/5287771b7ca6e1d8b02e32c62fb7065cd6c827ea9ef030a5868cfacc7cf88aec9d9d6fc65ab216326e00184c423a9e574d93704b8cbc63338c2a378a00fdd02b - languageName: node - linkType: hard - "@aws-sdk/is-array-buffer@npm:3.55.0": version: 3.55.0 resolution: "@aws-sdk/is-array-buffer@npm:3.55.0" @@ -1701,18 +1208,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/md5-js@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/md5-js@npm:3.78.0" - dependencies: - "@aws-sdk/types": "npm:3.78.0" - "@aws-sdk/util-utf8-browser": "npm:3.55.0" - "@aws-sdk/util-utf8-node": "npm:3.55.0" - tslib: "npm:^2.3.1" - checksum: 10/03967189ad87b6e5b234f8125cee0da890e024517e7d58474c4714fcc134069233bae65e949cd285b1e963be07c06500b1a82481880836fe978788002f3360c3 - languageName: node - linkType: hard - "@aws-sdk/middleware-bucket-endpoint@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.577.0" @@ -1728,19 +1223,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.80.0": - version: 3.80.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.80.0" - dependencies: - "@aws-sdk/protocol-http": "npm:3.78.0" - "@aws-sdk/types": "npm:3.78.0" - "@aws-sdk/util-arn-parser": "npm:3.55.0" - "@aws-sdk/util-config-provider": "npm:3.55.0" - tslib: "npm:^2.3.1" - checksum: 10/06ba62bcb728d16bc70079af23385902880580f2f69f1a7fb3dc24012157974989a846047a9f08424f3b7e662089b34b09b4d560017785d699fa71e8da3cbb05 - languageName: node - linkType: hard - "@aws-sdk/middleware-content-length@npm:3.127.0": version: 3.127.0 resolution: "@aws-sdk/middleware-content-length@npm:3.127.0" @@ -1752,17 +1234,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-content-length@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/middleware-content-length@npm:3.47.2" - dependencies: - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/0c76fd9c82e9cc568fb6431b3ef34e97bd03a0a1827800363acab75bf1a47384b05fe1d9377becd4781f075de3f95fc089b083791595a01c4deca95f3db626df - languageName: node - linkType: hard - "@aws-sdk/middleware-content-length@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/middleware-content-length@npm:3.78.0" @@ -1786,18 +1257,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.78.0" - dependencies: - "@aws-sdk/middleware-header-default": "npm:3.78.0" - "@aws-sdk/protocol-http": "npm:3.78.0" - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/6db82f13c17a66a1e897419b707480298608caa32b5543229d29a2d1e2ef266d4dfda397164429ca1fe87e730da4d7c4f2a537a0ab0b4aa9d41b88509fd4c8f9 - languageName: node - linkType: hard - "@aws-sdk/middleware-flexible-checksums@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.577.0" @@ -1814,31 +1273,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.78.0" - dependencies: - "@aws-crypto/crc32": "npm:2.0.0" - "@aws-crypto/crc32c": "npm:2.0.0" - "@aws-sdk/is-array-buffer": "npm:3.55.0" - "@aws-sdk/protocol-http": "npm:3.78.0" - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/5062b9f8fbd3f8700aa0ee221d6be08e10715b3b473ae1251ff33df7751b995c1efaed52a20d116fa96c517066b696fce1fb29ecf0dddc2bd5fd696c45a46f56 - languageName: node - linkType: hard - -"@aws-sdk/middleware-header-default@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/middleware-header-default@npm:3.78.0" - dependencies: - "@aws-sdk/protocol-http": "npm:3.78.0" - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/fba1438bbc32e39120a7657d6d0204e616c4170f564638ed7b33c122ee229a9199f2d74b4efaa380e3da59aa2896b7f365c41d5fef7c7aa8ad0e0edb3a2e3e9d - languageName: node - linkType: hard - "@aws-sdk/middleware-host-header@npm:3.127.0": version: 3.127.0 resolution: "@aws-sdk/middleware-host-header@npm:3.127.0" @@ -1850,17 +1284,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/middleware-host-header@npm:3.47.2" - dependencies: - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/8f17bf82fa35a175a2443188860e21c52dbdd1cdf7be2dff685f12e32f6b7b7cbda749a45900a5b78cb7392d8b15f6893f22bbb16dfd5737a1e56a59741021fb - languageName: node - linkType: hard - "@aws-sdk/middleware-host-header@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/middleware-host-header@npm:3.577.0" @@ -1895,16 +1318,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.78.0" - dependencies: - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/88e2aa48c49af4cacbe44022b4729c52dc173ec1c7672f44326641b7169e298e6cff435d1e1502455982521b407d1df5ab7cf33e7770bcf5c947427ec5e160f5 - languageName: node - linkType: hard - "@aws-sdk/middleware-logger@npm:3.127.0": version: 3.127.0 resolution: "@aws-sdk/middleware-logger@npm:3.127.0" @@ -1915,16 +1328,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/middleware-logger@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/515f84cbd57346d9599d12e3cb9dd7b80a353ef79dba4601e3d37a32db2d2abc0066d397658dbb5c6f93c5ca49ae6e91b9e3ca76dc9ab6feb23ddbf081383612 - languageName: node - linkType: hard - "@aws-sdk/middleware-logger@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/middleware-logger@npm:3.577.0" @@ -1994,19 +1397,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-retry@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/middleware-retry@npm:3.47.2" - dependencies: - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/service-error-classification": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - uuid: "npm:^8.3.2" - checksum: 10/e9f56166045ca3446f864ee75d7226cbf665c9a21d2237daba87c7bbeea9aa1035c05fc03dc9153a92fe780b4a3469277e8ebb33fa1b57233573c1a0f066462b - languageName: node - linkType: hard - "@aws-sdk/middleware-retry@npm:3.80.0": version: 3.80.0 resolution: "@aws-sdk/middleware-retry@npm:3.80.0" @@ -2021,18 +1411,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.105.0": - version: 3.105.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.105.0" - dependencies: - "@aws-sdk/protocol-http": "npm:3.78.0" - "@aws-sdk/types": "npm:3.78.0" - "@aws-sdk/util-arn-parser": "npm:3.55.0" - tslib: "npm:^2.3.1" - checksum: 10/bf7d38974d8ff75e01f6ade411e9b09e3e90ad57a78bf21c45762b4eea78fe9741b36395c418c9bccf6b17020a678d519575300bd6a0296769b576a5c8865d5c - languageName: node - linkType: hard - "@aws-sdk/middleware-sdk-s3@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/middleware-sdk-s3@npm:3.577.0" @@ -2064,20 +1442,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sts@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/middleware-sdk-sts@npm:3.47.2" - dependencies: - "@aws-sdk/middleware-signing": "npm:3.47.2" - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/signature-v4": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/135c88d46b6350a13485c046a1ca27a7d44dc9fea3ea9206785b418a59f9cbbb4d7ca79c75d1521ed8920a7d57acd588d77b8d1e14ab4e5fddaccf87c559dea2 - languageName: node - linkType: hard - "@aws-sdk/middleware-sdk-sts@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/middleware-sdk-sts@npm:3.78.0" @@ -2102,16 +1466,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-serde@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/middleware-serde@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/89f0b72750e1f4f25f94277381d8e4c7ee1694570f99830edd5ef4c21f714737b49eb206c6d78139ae0cfb861831dbfcbc29c66cf565ec59468189ca3003fedb - languageName: node - linkType: hard - "@aws-sdk/middleware-serde@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/middleware-serde@npm:3.78.0" @@ -2135,19 +1489,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/middleware-signing@npm:3.47.2" - dependencies: - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/signature-v4": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/1127e94e56efb3caad0b1bc5ccddb80daae0ca810a6b75a5b6b12d1da9812ec0734e15f80d33e7a94a173debf0a8135a5d31c7f308cf7fe99bb2ee56df9335d7 - languageName: node - linkType: hard - "@aws-sdk/middleware-signing@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/middleware-signing@npm:3.577.0" @@ -2187,16 +1528,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.78.0" - dependencies: - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/fa9b087bd6c718f0c5f04f7f75ad8afcba743a95231e50c9b913ab1202bc23b5a96e0c81363457889c4184ed0342818a7c2f90f977379bce22e03865a6f6ce42 - languageName: node - linkType: hard - "@aws-sdk/middleware-stack@npm:3.127.0": version: 3.127.0 resolution: "@aws-sdk/middleware-stack@npm:3.127.0" @@ -2206,15 +1537,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-stack@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/middleware-stack@npm:3.47.2" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/427ed4888602ebd342c0443eb992f0daf419ea5cbe50b715b9d89dd99529ec14603d171e29d9adda11121e2bb84bafd586c2719b631aae5e396038c99a2e669a - languageName: node - linkType: hard - "@aws-sdk/middleware-stack@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/middleware-stack@npm:3.78.0" @@ -2235,17 +1557,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/middleware-user-agent@npm:3.47.2" - dependencies: - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/fb4620b773d8927236308eacb58422cac3792558a3cef307580e67412cc8f1bf9af18509f29417238078fb8b6334205c63b7cdce81921e4b678278f7b346ae44 - languageName: node - linkType: hard - "@aws-sdk/middleware-user-agent@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/middleware-user-agent@npm:3.577.0" @@ -2282,18 +1593,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/node-config-provider@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/node-config-provider@npm:3.47.2" - dependencies: - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/shared-ini-file-loader": "npm:3.47.1" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/17a83bd6b259d627ab6869a889ea7a21197d629ba320004c3d6fe771e8ff162e275445fa7eda9007a5ae761af53a3d9586d1c8fbb45e11c5a2d41601b3bbda23 - languageName: node - linkType: hard - "@aws-sdk/node-config-provider@npm:3.80.0": version: 3.80.0 resolution: "@aws-sdk/node-config-provider@npm:3.80.0" @@ -2319,19 +1618,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/node-http-handler@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/node-http-handler@npm:3.47.2" - dependencies: - "@aws-sdk/abort-controller": "npm:3.47.2" - "@aws-sdk/protocol-http": "npm:3.47.2" - "@aws-sdk/querystring-builder": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/c864b92c35a6d7955af3c4764538324e02d7aa34f54c78dd3679515d989ca151e7ba55a65de7e5686a311aa3070c12c331fd88210aadb008925134bd31afe4ef - languageName: node - linkType: hard - "@aws-sdk/node-http-handler@npm:3.94.0": version: 3.94.0 resolution: "@aws-sdk/node-http-handler@npm:3.94.0" @@ -2355,16 +1641,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/property-provider@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/property-provider@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/e731ed31300fa0352744a5209e5f476a5ec82390ad2bbe1d58ded4a6de7ce3ec299e9580d07d4bddebe626ef3069c5806a0e060f63ce419f7a5dc48b6967cc9a - languageName: node - linkType: hard - "@aws-sdk/property-provider@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/property-provider@npm:3.78.0" @@ -2385,16 +1661,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/protocol-http@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/protocol-http@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/8d6cfcbe620256480198f0782a1f7a51f954ad076593ec09d01ffb23bf7f069c7716e629221b9793d2ab2903268d21597e4e386d9aacdd3d8ea2bdaa8a657d16 - languageName: node - linkType: hard - "@aws-sdk/protocol-http@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/protocol-http@npm:3.78.0" @@ -2416,17 +1682,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/querystring-builder@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/querystring-builder@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/util-uri-escape": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/4408739767ae6ef17c00d8df3b3936ba8a49737af34d1bd3e67e0a855b6fece11a75b539e7955ab6404688176f1ff6d6625528eae90518bf91e78bb9ce3f7ee7 - languageName: node - linkType: hard - "@aws-sdk/querystring-builder@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/querystring-builder@npm:3.78.0" @@ -2448,16 +1703,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/querystring-parser@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/querystring-parser@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/a975024dd2df3391c19ea468fa826fdb2c1dca2947993978a1e461db60f232c689da4a413d1205cbcac53c64f8cea9fbcfe1f10459bd2cc3cc86c9c95ae75d98 - languageName: node - linkType: hard - "@aws-sdk/querystring-parser@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/querystring-parser@npm:3.78.0" @@ -2489,13 +1734,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/service-error-classification@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/service-error-classification@npm:3.47.2" - checksum: 10/f7be80e30f7fc5f980a58e73c9a54e93217de05c9146eed7649bff6f28d4568da4aeeed927801512ddcc55664756d7caab2f62c9dd814185188c0b761611c7bf - languageName: node - linkType: hard - "@aws-sdk/service-error-classification@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/service-error-classification@npm:3.78.0" @@ -2512,15 +1750,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/shared-ini-file-loader@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/shared-ini-file-loader@npm:3.47.1" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/1068855025162e82bcef8eeaeea7b2f2e3ec5d488c7ea361616f8f40447c0ac34ad27ddbe89adfb9dcb20e6ef8986dc5a42632636a9e541e25247d135dc42548 - languageName: node - linkType: hard - "@aws-sdk/shared-ini-file-loader@npm:3.80.0": version: 3.80.0 resolution: "@aws-sdk/shared-ini-file-loader@npm:3.80.0" @@ -2544,24 +1773,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.88.0": - version: 3.88.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.88.0" - dependencies: - "@aws-sdk/protocol-http": "npm:3.78.0" - "@aws-sdk/signature-v4": "npm:3.78.0" - "@aws-sdk/types": "npm:3.78.0" - "@aws-sdk/util-arn-parser": "npm:3.55.0" - tslib: "npm:^2.3.1" - peerDependencies: - "@aws-sdk/signature-v4-crt": ^3.79.0 - peerDependenciesMeta: - "@aws-sdk/signature-v4-crt": - optional: true - checksum: 10/2382e05d517f18a4229ceef89e975e84eb94630afd9a11793deb70b5ea26446f50311caae586b38016ee5e1bb6d17b316774b93263be6c74994b2704ea03347b - languageName: node - linkType: hard - "@aws-sdk/signature-v4@npm:3.130.0": version: 3.130.0 resolution: "@aws-sdk/signature-v4@npm:3.130.0" @@ -2576,19 +1787,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/signature-v4@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/signature-v4@npm:3.47.2" - dependencies: - "@aws-sdk/is-array-buffer": "npm:3.47.1" - "@aws-sdk/types": "npm:3.47.1" - "@aws-sdk/util-hex-encoding": "npm:3.47.1" - "@aws-sdk/util-uri-escape": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/281e618b58c2ec5e508cabafa965d3f66ce6f310ac612f39458a4aa2622a8ab978585a24effa0c2eb70e8aaf1d5ac47658878bd6fbac363e515727c5e766909c - languageName: node - linkType: hard - "@aws-sdk/signature-v4@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/signature-v4@npm:3.78.0" @@ -2614,17 +1812,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/smithy-client@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/smithy-client@npm:3.47.2" - dependencies: - "@aws-sdk/middleware-stack": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/b3a3bf3182542d93bbd4badcce4a5656dbbfb42f675c213441bdfc8de27df13ca802aa5940fcad6158e77372cdffe205993d2aaf802d55427b71197b72330a8e - languageName: node - linkType: hard - "@aws-sdk/smithy-client@npm:3.99.0": version: 3.99.0 resolution: "@aws-sdk/smithy-client@npm:3.99.0" @@ -2658,13 +1845,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/types@npm:3.47.1" - checksum: 10/6a799ce69fe87aa52c931ba86337a1b280ddfddbd59abebf4222113e2e2757c64f18dbcbc680ec88a1a14ce7b3a84a60fda3f6a55c6d0ab0665453720e976874 - languageName: node - linkType: hard - "@aws-sdk/types@npm:3.577.0, @aws-sdk/types@npm:^3.222.0": version: 3.577.0 resolution: "@aws-sdk/types@npm:3.577.0" @@ -2693,17 +1873,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/url-parser@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/url-parser@npm:3.47.2" - dependencies: - "@aws-sdk/querystring-parser": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/c286c19a2768b529dcf8477aa4c97c64f1e756211ef402707adc393b45bfebcc44e6c660acb11e722e12975a86e6b43e6c006a65174828284fdc3f26c2c7e33c - languageName: node - linkType: hard - "@aws-sdk/url-parser@npm:3.78.0": version: 3.78.0 resolution: "@aws-sdk/url-parser@npm:3.78.0" @@ -2715,15 +1884,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:3.55.0": - version: 3.55.0 - resolution: "@aws-sdk/util-arn-parser@npm:3.55.0" - dependencies: - tslib: "npm:^2.3.1" - checksum: 10/d8e56df636218c247ba3c6d1bc5c96ad853cdd5660f74bd0c43bcde4ddc1d6d6f2ee975f78772d99371d3d7315730cf03da73d47e90f32fdfc54359ee2e54915 - languageName: node - linkType: hard - "@aws-sdk/util-arn-parser@npm:3.568.0": version: 3.568.0 resolution: "@aws-sdk/util-arn-parser@npm:3.568.0" @@ -2742,15 +1902,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-base64-browser@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/util-base64-browser@npm:3.47.1" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/f79516ee53849cd7995a3372a25c5309456c719aa2f6444fe68807ee82dc0b4aba7990f30d4a1f1a504501201f67ab5b28826115c664930f33cb6856ca423194 - languageName: node - linkType: hard - "@aws-sdk/util-base64-browser@npm:3.58.0": version: 3.58.0 resolution: "@aws-sdk/util-base64-browser@npm:3.58.0" @@ -2760,16 +1911,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-base64-node@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/util-base64-node@npm:3.47.2" - dependencies: - "@aws-sdk/util-buffer-from": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/abcea31871d4666fb59fc49432ce5c57ebe8f732b01e5fe6270df4a8926d794a7fb88282011543d96938686899bedffb9373bb2e0412460ff3dbed4b03007406 - languageName: node - linkType: hard - "@aws-sdk/util-base64-node@npm:3.55.0": version: 3.55.0 resolution: "@aws-sdk/util-base64-node@npm:3.55.0" @@ -2780,15 +1921,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-body-length-browser@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/util-body-length-browser@npm:3.47.1" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/273caa8cba716ed61235695554d59c940224035a53b5188891bb09d0bdbf13bd9e40603040a682c77b47e3e30764aed8649c49929bfcbc024a2b4404e2bb5a0d - languageName: node - linkType: hard - "@aws-sdk/util-body-length-browser@npm:3.55.0": version: 3.55.0 resolution: "@aws-sdk/util-body-length-browser@npm:3.55.0" @@ -2798,15 +1930,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-body-length-node@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/util-body-length-node@npm:3.47.1" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/1e226859ea45fbb2cc5f4ac694fc8b4b0f531ff7df64621f1b43c7412c44a85e9d5e8fdd0de48d73d10cbb35c8aece52e6ad5e0858c886e66c22315f075c2811 - languageName: node - linkType: hard - "@aws-sdk/util-body-length-node@npm:3.55.0": version: 3.55.0 resolution: "@aws-sdk/util-body-length-node@npm:3.55.0" @@ -2816,16 +1939,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-buffer-from@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/util-buffer-from@npm:3.47.2" - dependencies: - "@aws-sdk/is-array-buffer": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/bacddc53a02b1e601c34601685d2bc829856f257f531d3e969a2b9ca5523244c314b214ce680ac7f8d411e58ed4800dd1a08eb18ccd697561f153d766416692a - languageName: node - linkType: hard - "@aws-sdk/util-buffer-from@npm:3.55.0": version: 3.55.0 resolution: "@aws-sdk/util-buffer-from@npm:3.55.0" @@ -2845,15 +1958,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-config-provider@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/util-config-provider@npm:3.47.1" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/747ab73fd87dc99dadacad255d36a1766d4eb15cf2a553050d46bff48fb66e906d099bf1594049fe79ba1353fa51d5225af2a67703ec2ec98759beae981a55b7 - languageName: node - linkType: hard - "@aws-sdk/util-config-provider@npm:3.55.0": version: 3.55.0 resolution: "@aws-sdk/util-config-provider@npm:3.55.0" @@ -2863,16 +1967,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-credentials@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/util-credentials@npm:3.47.2" - dependencies: - "@aws-sdk/shared-ini-file-loader": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/801cd30e796e8b09873beab22cc02ca941b3eb93e0f8241bf473bc26ddd3bd87cdfe7f289e9846fa68a5dad0032cf2bca011cce63eecc3a635ef0aa0c2117f73 - languageName: node - linkType: hard - "@aws-sdk/util-defaults-mode-browser@npm:3.142.0": version: 3.142.0 resolution: "@aws-sdk/util-defaults-mode-browser@npm:3.142.0" @@ -2885,18 +1979,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-defaults-mode-browser@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/util-defaults-mode-browser@npm:3.47.2" - dependencies: - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - bowser: "npm:^2.11.0" - tslib: "npm:^2.3.0" - checksum: 10/d987d132b6e0efb8d5b27f72dfa7ea5f642b2f6f9a13bec6bceb4d37c5345f04ce9e5ef296e83fc4f68d4f2d5bd08f656fe28390a57a0b86a87f7e3de909d6cd - languageName: node - linkType: hard - "@aws-sdk/util-defaults-mode-browser@npm:3.99.0": version: 3.99.0 resolution: "@aws-sdk/util-defaults-mode-browser@npm:3.99.0" @@ -2923,20 +2005,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-defaults-mode-node@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/util-defaults-mode-node@npm:3.47.2" - dependencies: - "@aws-sdk/config-resolver": "npm:3.47.2" - "@aws-sdk/credential-provider-imds": "npm:3.47.2" - "@aws-sdk/node-config-provider": "npm:3.47.2" - "@aws-sdk/property-provider": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/dfb2892338a3b0f2b58ab7569fc6271eaae5b0bf2889ca87fc6f1deffe59813c70e8874a8a8ec45882cbf97d5e56536b157022249bcc951f7f29a098a1623412 - languageName: node - linkType: hard - "@aws-sdk/util-defaults-mode-node@npm:3.99.0": version: 3.99.0 resolution: "@aws-sdk/util-defaults-mode-node@npm:3.99.0" @@ -2972,15 +2040,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-hex-encoding@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/util-hex-encoding@npm:3.47.1" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/9a76516009af3f32eecbf69062de7178ba61dac9f4a9203337712cd2a31a723f74bf452d864cb8d3b1351d548acb9ae12bfd43429df53e354d4993c393d4f0ee - languageName: node - linkType: hard - "@aws-sdk/util-hex-encoding@npm:3.58.0": version: 3.58.0 resolution: "@aws-sdk/util-hex-encoding@npm:3.58.0" @@ -3017,35 +2076,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-stream-browser@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/util-stream-browser@npm:3.78.0" - dependencies: - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/b7ffa0c49561c816625a1d147b3958c9320f90469cb2bbbc475a99c7ec6bc009e4a8a05032d55e91d4d51a54743ab6eeb96ee91b867985bc688364340bbe2550 - languageName: node - linkType: hard - -"@aws-sdk/util-stream-node@npm:3.78.0": - version: 3.78.0 - resolution: "@aws-sdk/util-stream-node@npm:3.78.0" - dependencies: - "@aws-sdk/types": "npm:3.78.0" - tslib: "npm:^2.3.1" - checksum: 10/2054d281919c54a1b85ce04de3d8e4c0a6273ee88f7d3073cfaefe0fd1d815203eebefe17f550d5a7e4884f66c03faa6c60ac94ca34d1eaa274590f562d20b28 - languageName: node - linkType: hard - -"@aws-sdk/util-uri-escape@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/util-uri-escape@npm:3.47.1" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/68fc6e1909d884c2ef7d019428c003f61fc70971e020aa1656a12012a6e8e0a04df844a0b16ee20b757b3940c40ddeb27f8b35739bfef23b9629f74cf195e0e3 - languageName: node - linkType: hard - "@aws-sdk/util-uri-escape@npm:3.55.0": version: 3.55.0 resolution: "@aws-sdk/util-uri-escape@npm:3.55.0" @@ -3066,17 +2096,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.47.2" - dependencies: - "@aws-sdk/types": "npm:3.47.1" - bowser: "npm:^2.11.0" - tslib: "npm:^2.3.0" - checksum: 10/d174e3cc9f1ccc771d816ff0d509673252f2950a097ed0752a1d323834b8bcc2e4598d4bd18b1f9bc07dcc7648e9c4e023461bace2dc55469babf09700baa421 - languageName: node - linkType: hard - "@aws-sdk/util-user-agent-browser@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/util-user-agent-browser@npm:3.577.0" @@ -3116,17 +2135,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/util-user-agent-node@npm:3.47.2" - dependencies: - "@aws-sdk/node-config-provider": "npm:3.47.2" - "@aws-sdk/types": "npm:3.47.1" - tslib: "npm:^2.3.0" - checksum: 10/3fdaf3e174ead8b08029b7c30c9802a27b6a61b02581f11bb2c0fa3b66b9eafd3739c9bdeb6df554473e3a75d680553f1a98adb48d035b858c20b379341d5bfc - languageName: node - linkType: hard - "@aws-sdk/util-user-agent-node@npm:3.577.0": version: 3.577.0 resolution: "@aws-sdk/util-user-agent-node@npm:3.577.0" @@ -3164,15 +2172,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-utf8-browser@npm:3.47.1": - version: 3.47.1 - resolution: "@aws-sdk/util-utf8-browser@npm:3.47.1" - dependencies: - tslib: "npm:^2.3.0" - checksum: 10/c6a7eeef1ddf9a08621c08036b2f44fe6dd700feb4beb71e150c3060c493c907df6b745663bc18d53ce03483c54fae55532b479ba34440bbfb8dcb385013bbd1 - languageName: node - linkType: hard - "@aws-sdk/util-utf8-browser@npm:3.55.0, @aws-sdk/util-utf8-browser@npm:^3.0.0": version: 3.55.0 resolution: "@aws-sdk/util-utf8-browser@npm:3.55.0" @@ -3192,16 +2191,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-utf8-node@npm:3.47.2": - version: 3.47.2 - resolution: "@aws-sdk/util-utf8-node@npm:3.47.2" - dependencies: - "@aws-sdk/util-buffer-from": "npm:3.47.2" - tslib: "npm:^2.3.0" - checksum: 10/eaf0696d0430e7c4084a08adf305e1ff9840bb1a6c30df5687b822802d550f82d4ade355d6d62a1955f397f094ee582c3e37e0a5f0bf37a2cab95e9e02d7c970 - languageName: node - linkType: hard - "@aws-sdk/util-utf8-node@npm:3.55.0": version: 3.55.0 resolution: "@aws-sdk/util-utf8-node@npm:3.55.0" @@ -3223,15 +2212,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.55.0": - version: 3.55.0 - resolution: "@aws-sdk/xml-builder@npm:3.55.0" - dependencies: - tslib: "npm:^2.3.1" - checksum: 10/0924d5725921c1e6fa6685a9dba135747f977457dc9d957e35e7b92f4bccfc80b9a57d0d044179dcd73be4029fb0c3826571595dcaaf7da30016641e9e81f3d4 - languageName: node - linkType: hard - "@aws-sdk/xml-builder@npm:3.575.0": version: 3.575.0 resolution: "@aws-sdk/xml-builder@npm:3.575.0" @@ -6069,6 +5049,17 @@ __metadata: languageName: node linkType: hard +"@effect/schema@npm:0.71.1": + version: 0.71.1 + resolution: "@effect/schema@npm:0.71.1" + dependencies: + fast-check: "npm:^3.21.0" + peerDependencies: + effect: ^3.6.5 + checksum: 10/d8ef78980409ce6fbe3de5ccba976cdcce86014916613a12dc9826ee27ad64e8f94579718a3099c6a9fc460aaafd471f573e75f74dfeaafb89b98275b4d2ed70 + languageName: node + linkType: hard + "@emotion/babel-plugin@npm:^11.12.0": version: 11.12.0 resolution: "@emotion/babel-plugin@npm:11.12.0" @@ -6252,13 +5243,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/aix-ppc64@npm:0.19.12" - conditions: os=aix & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/aix-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/aix-ppc64@npm:0.21.5" @@ -6287,13 +5271,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm64@npm:0.19.12" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/android-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm64@npm:0.21.5" @@ -6322,13 +5299,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm@npm:0.19.12" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "@esbuild/android-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm@npm:0.21.5" @@ -6357,13 +5327,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-x64@npm:0.19.12" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - "@esbuild/android-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-x64@npm:0.21.5" @@ -6392,13 +5355,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-arm64@npm:0.19.12" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/darwin-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-arm64@npm:0.21.5" @@ -6427,13 +5383,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-x64@npm:0.19.12" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - "@esbuild/darwin-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-x64@npm:0.21.5" @@ -6462,13 +5411,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-arm64@npm:0.19.12" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/freebsd-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-arm64@npm:0.21.5" @@ -6497,13 +5439,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-x64@npm:0.19.12" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/freebsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-x64@npm:0.21.5" @@ -6532,13 +5467,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm64@npm:0.19.12" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/linux-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm64@npm:0.21.5" @@ -6567,13 +5495,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm@npm:0.19.12" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - "@esbuild/linux-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm@npm:0.21.5" @@ -6602,13 +5523,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ia32@npm:0.19.12" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/linux-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ia32@npm:0.21.5" @@ -6637,13 +5551,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-loong64@npm:0.19.12" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - "@esbuild/linux-loong64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-loong64@npm:0.21.5" @@ -6672,13 +5579,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-mips64el@npm:0.19.12" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - "@esbuild/linux-mips64el@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-mips64el@npm:0.21.5" @@ -6707,13 +5607,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ppc64@npm:0.19.12" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/linux-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ppc64@npm:0.21.5" @@ -6742,13 +5635,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-riscv64@npm:0.19.12" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - "@esbuild/linux-riscv64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-riscv64@npm:0.21.5" @@ -6777,13 +5663,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-s390x@npm:0.19.12" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - "@esbuild/linux-s390x@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-s390x@npm:0.21.5" @@ -6812,13 +5691,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-x64@npm:0.19.12" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - "@esbuild/linux-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-x64@npm:0.21.5" @@ -6847,13 +5719,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/netbsd-x64@npm:0.19.12" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/netbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/netbsd-x64@npm:0.21.5" @@ -6889,13 +5754,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/openbsd-x64@npm:0.19.12" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/openbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/openbsd-x64@npm:0.21.5" @@ -6924,13 +5782,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/sunos-x64@npm:0.19.12" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - "@esbuild/sunos-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/sunos-x64@npm:0.21.5" @@ -6959,13 +5810,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-arm64@npm:0.19.12" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/win32-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-arm64@npm:0.21.5" @@ -6994,13 +5838,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-ia32@npm:0.19.12" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/win32-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-ia32@npm:0.21.5" @@ -7029,13 +5866,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-x64@npm:0.19.12" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@esbuild/win32-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-x64@npm:0.21.5" @@ -7061,34 +5891,68 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": - version: 4.10.0 - resolution: "@eslint-community/regexpp@npm:4.10.0" - checksum: 10/8c36169c815fc5d726078e8c71a5b592957ee60d08c6470f9ce0187c8046af1a00afbda0a065cc40ff18d5d83f82aed9793c6818f7304a74a7488dc9f3ecbd42 +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1": + version: 4.12.1 + resolution: "@eslint-community/regexpp@npm:4.12.1" + checksum: 10/c08f1dd7dd18fbb60bdd0d85820656d1374dd898af9be7f82cb00451313402a22d5e30569c150315b4385907cdbca78c22389b2a72ab78883b3173be317620cc languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" +"@eslint/config-array@npm:^0.19.0": + version: 0.19.0 + resolution: "@eslint/config-array@npm:0.19.0" + dependencies: + "@eslint/object-schema": "npm:^2.1.4" + debug: "npm:^4.3.1" + minimatch: "npm:^3.1.2" + checksum: 10/16e4ec468ebcb10255ab8c61234c1b3e7ac5506016e432fb489a1c5528cace7a60ddb07515516e7fc166b1dbe6c407d8a6bfbaa2e7531d445d8feb845c989913 + languageName: node + linkType: hard + +"@eslint/core@npm:^0.9.0": + version: 0.9.0 + resolution: "@eslint/core@npm:0.9.0" + checksum: 10/2d11e9c6fac14cfa817c7a9939fd6b79f2120928e4933952d061651db93797e0fcd67c858a14980ac26e90f6e0e49051436aefa4a4b06a26f24e3028366f73d9 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^3.2.0": + version: 3.2.0 + resolution: "@eslint/eslintrc@npm:3.2.0" dependencies: ajv: "npm:^6.12.4" debug: "npm:^4.3.2" - espree: "npm:^9.6.0" - globals: "npm:^13.19.0" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" ignore: "npm:^5.2.0" import-fresh: "npm:^3.2.1" js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: 10/7a3b14f4b40fc1a22624c3f84d9f467a3d9ea1ca6e9a372116cb92507e485260359465b58e25bcb6c9981b155416b98c9973ad9b796053fd7b3f776a6946bce8 + checksum: 10/b32dd90ce7da68e89b88cd729db46b27aac79a2e6cb1fa75d25a6b766d586b443bfbf59622489efbd3c6f696f147b51111e81ec7cd23d70f215c5d474cad0261 languageName: node linkType: hard -"@eslint/js@npm:8.57.0": - version: 8.57.0 - resolution: "@eslint/js@npm:8.57.0" - checksum: 10/3c501ce8a997cf6cbbaf4ed358af5492875e3550c19b9621413b82caa9ae5382c584b0efa79835639e6e0ddaa568caf3499318e5bdab68643ef4199dce5eb0a0 +"@eslint/js@npm:9.15.0, @eslint/js@npm:^9.15.0": + version: 9.15.0 + resolution: "@eslint/js@npm:9.15.0" + checksum: 10/cdea71574a8be164147f426ffa5eca05a9c7fbfbae98387ed0cf772292fc9fb5ded69ce96eac110aaa633f6b7504ec551e1d33f2d6690ae95b11ec395553bae1 + languageName: node + linkType: hard + +"@eslint/object-schema@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/object-schema@npm:2.1.4" + checksum: 10/221e8d9f281c605948cd6e030874aacce83fe097f8f9c1964787037bccf08e82b7aa9eff1850a30fffac43f1d76555727ec22a2af479d91e268e89d1e035131e + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.2.3": + version: 0.2.3 + resolution: "@eslint/plugin-kit@npm:0.2.3" + dependencies: + levn: "npm:^0.4.1" + checksum: 10/0d0653ef840823fd5c0354ef8f1937e7763dbe830173eb6d2d55a19374bf04a06dff0e5214330c10a9425cf38655f632bb0d7d0666249b366e506ae291d82f7e languageName: node linkType: hard @@ -8341,6 +7205,30 @@ __metadata: languageName: node linkType: hard +"@google-cloud/paginator@npm:^5.0.0": + version: 5.0.2 + resolution: "@google-cloud/paginator@npm:5.0.2" + dependencies: + arrify: "npm:^2.0.0" + extend: "npm:^3.0.2" + checksum: 10/b64ba2029b77fdcf3c827aea0b6d128122fd1d2f4aa8c1ba70747cba0659d4216a283769fb3bbeb8f726176f5282624637f02c30f118a010e05838411da0cb76 + languageName: node + linkType: hard + +"@google-cloud/projectify@npm:^4.0.0": + version: 4.0.0 + resolution: "@google-cloud/projectify@npm:4.0.0" + checksum: 10/fdccdda0b50855c35541d71c46a6603f3302ff1a00108d946272cb2167435da00e2a2da5963fe489f4f5a4a9eb6320abeb97d3269974a972ae89f5df8451922d + languageName: node + linkType: hard + +"@google-cloud/promisify@npm:^4.0.0": + version: 4.0.0 + resolution: "@google-cloud/promisify@npm:4.0.0" + checksum: 10/c5de81321b3a5c567edcbe0b941fb32644611147f3ba22f20575918c225a979988a99bc2ebda05ac914fa8714b0a54c69be72c3f46c7a64c3b19db7d7fba8d04 + languageName: node + linkType: hard + "@google-cloud/secret-manager@npm:^5.5.0": version: 5.5.0 resolution: "@google-cloud/secret-manager@npm:5.5.0" @@ -8350,6 +7238,29 @@ __metadata: languageName: node linkType: hard +"@google-cloud/storage@npm:7.14.0": + version: 7.14.0 + resolution: "@google-cloud/storage@npm:7.14.0" + dependencies: + "@google-cloud/paginator": "npm:^5.0.0" + "@google-cloud/projectify": "npm:^4.0.0" + "@google-cloud/promisify": "npm:^4.0.0" + abort-controller: "npm:^3.0.0" + async-retry: "npm:^1.3.3" + duplexify: "npm:^4.1.3" + fast-xml-parser: "npm:^4.4.1" + gaxios: "npm:^6.0.2" + google-auth-library: "npm:^9.6.3" + html-entities: "npm:^2.5.2" + mime: "npm:^3.0.0" + p-limit: "npm:^3.0.1" + retry-request: "npm:^7.0.0" + teeny-request: "npm:^9.0.0" + uuid: "npm:^8.0.0" + checksum: 10/0726fde2697da696637fab91ebd756354a58c1331f6a0b9ecc5011de4aae72cd9e1fe3e9564aee15c6a2118e45ed0ae8c3ac9685c6581db6107080f906a949e9 + languageName: node + linkType: hard + "@grpc/grpc-js@npm:~1.10.3": version: 1.10.8 resolution: "@grpc/grpc-js@npm:1.10.8" @@ -8389,14 +7300,20 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.14": - version: 0.11.14 - resolution: "@humanwhocodes/config-array@npm:0.11.14" +"@humanfs/core@npm:^0.19.1": + version: 0.19.1 + resolution: "@humanfs/core@npm:0.19.1" + checksum: 10/270d936be483ab5921702623bc74ce394bf12abbf57d9145a69e8a0d1c87eb1c768bd2d93af16c5705041e257e6d9cc7529311f63a1349f3678abc776fc28523 + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.6 + resolution: "@humanfs/node@npm:0.16.6" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.2" - debug: "npm:^4.3.1" - minimatch: "npm:^3.0.5" - checksum: 10/3ffb24ecdfab64014a230e127118d50a1a04d11080cbb748bc21629393d100850496456bbcb4e8c438957fe0934430d731042f1264d6a167b62d32fc2863580a + "@humanfs/core": "npm:^0.19.1" + "@humanwhocodes/retry": "npm:^0.3.0" + checksum: 10/6d43c6727463772d05610aa05c83dab2bfbe78291022ee7a92cb50999910b8c720c76cc312822e2dea2b497aa1b3fef5fe9f68803fc45c9d4ed105874a65e339 languageName: node linkType: hard @@ -8407,10 +7324,17 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.2": - version: 2.0.2 - resolution: "@humanwhocodes/object-schema@npm:2.0.2" - checksum: 10/ef915e3e2f34652f3d383b28a9a99cfea476fa991482370889ab14aac8ecd2b38d47cc21932526c6d949da0daf4a4a6bf629d30f41b0caca25e146819cbfa70e +"@humanwhocodes/retry@npm:^0.3.0": + version: 0.3.1 + resolution: "@humanwhocodes/retry@npm:0.3.1" + checksum: 10/eb457f699529de7f07649679ec9e0353055eebe443c2efe71c6dd950258892475a038e13c6a8c5e13ed1fb538cdd0a8794faa96b24b6ffc4c87fb1fc9f70ad7f + languageName: node + linkType: hard + +"@humanwhocodes/retry@npm:^0.4.1": + version: 0.4.1 + resolution: "@humanwhocodes/retry@npm:0.4.1" + checksum: 10/39fafc7319e88f61befebd5e1b4f0136534ea6a9bd10d74366698187bd63544210ec5d79a87ed4d91297f1cc64c4c53d45fb0077a2abfdce212cf0d3862d5f04 languageName: node linkType: hard @@ -8420,15 +7344,16 @@ __metadata: dependencies: "@chainlink/ccip-read-server": "npm:^0.2.1" "@jest/globals": "npm:^29.7.0" - "@types/node": "npm:^16.9.1" + "@types/node": "npm:^18.14.5" dotenv-flow: "npm:^4.1.0" - ethers: "npm:5.7.2" + eslint: "npm:^9.15.0" + ethers: "npm:^5.7.2" jest: "npm:^29.7.0" nodemon: "npm:^3.0.3" prettier: "npm:^2.8.8" ts-jest: "npm:^29.1.2" ts-node: "npm:^10.8.0" - tsx: "npm:^4.7.1" + tsx: "npm:^4.19.1" typescript: "npm:5.3.3" languageName: unknown linkType: soft @@ -8439,34 +7364,37 @@ __metadata: dependencies: "@aws-sdk/client-kms": "npm:^3.577.0" "@aws-sdk/client-s3": "npm:^3.577.0" + "@eslint/js": "npm:^9.15.0" "@ethersproject/abi": "npm:*" "@ethersproject/providers": "npm:*" - "@hyperlane-xyz/registry": "npm:6.1.0" - "@hyperlane-xyz/sdk": "npm:7.1.0" - "@hyperlane-xyz/utils": "npm:7.1.0" + "@hyperlane-xyz/registry": "npm:6.3.0" + "@hyperlane-xyz/sdk": "npm:7.3.0" + "@hyperlane-xyz/utils": "npm:7.3.0" "@inquirer/core": "npm:9.0.10" "@inquirer/figures": "npm:1.0.5" - "@inquirer/prompts": "npm:^3.0.0" + "@inquirer/prompts": "npm:3.3.2" "@types/chai-as-promised": "npm:^8" "@types/mocha": "npm:^10.0.1" "@types/node": "npm:^18.14.5" "@types/yargs": "npm:^17.0.24" - "@typescript-eslint/eslint-plugin": "npm:^7.4.0" - "@typescript-eslint/parser": "npm:^7.4.0" + "@typescript-eslint/eslint-plugin": "npm:^8.1.6" + "@typescript-eslint/parser": "npm:^8.1.6" ansi-escapes: "npm:^7.0.0" asn1.js: "npm:^5.4.1" bignumber.js: "npm:^9.1.1" chai: "npm:^4.5.0" chai-as-promised: "npm:^8.0.0" chalk: "npm:^5.3.0" - eslint: "npm:^8.57.0" + eslint: "npm:^9.15.0" eslint-config-prettier: "npm:^9.1.0" + eslint-import-resolver-typescript: "npm:^3.6.3" + eslint-plugin-import: "npm:^2.31.0" ethers: "npm:^5.7.2" latest-version: "npm:^8.0.0" mocha: "npm:^10.2.0" prettier: "npm:^2.8.8" terminal-link: "npm:^3.0.0" - tsx: "npm:^4.7.1" + tsx: "npm:^4.19.1" typescript: "npm:5.3.3" yaml: "npm:2.4.5" yargs: "npm:^17.7.2" @@ -8478,24 +7406,24 @@ __metadata: languageName: unknown linkType: soft -"@hyperlane-xyz/core@npm:5.8.1, @hyperlane-xyz/core@workspace:solidity": +"@hyperlane-xyz/core@npm:5.8.3, @hyperlane-xyz/core@workspace:solidity": version: 0.0.0-use.local resolution: "@hyperlane-xyz/core@workspace:solidity" dependencies: "@arbitrum/nitro-contracts": "npm:^1.2.1" "@eth-optimism/contracts": "npm:^0.6.0" - "@hyperlane-xyz/utils": "npm:7.1.0" + "@hyperlane-xyz/utils": "npm:7.3.0" "@layerzerolabs/lz-evm-oapp-v2": "npm:2.0.2" "@layerzerolabs/solidity-examples": "npm:^1.1.0" "@nomiclabs/hardhat-ethers": "npm:^2.2.3" "@nomiclabs/hardhat-waffle": "npm:^2.0.6" "@openzeppelin/contracts": "npm:^4.9.3" - "@openzeppelin/contracts-upgradeable": "npm:^v4.9.3" + "@openzeppelin/contracts-upgradeable": "npm:^4.9.3" "@typechain/ethers-v5": "npm:^11.1.2" "@typechain/ethers-v6": "npm:^0.5.1" "@typechain/hardhat": "npm:^9.1.0" "@types/node": "npm:^18.14.5" - chai: "npm:4.5.0" + chai: "npm:^4.5.0" ethereum-waffle: "npm:^4.0.10" ethers: "npm:^5.7.2" fx-portal: "npm:^1.0.3" @@ -8527,7 +7455,7 @@ __metadata: "@cloudflare/vitest-pool-workers": "npm:^0.4.5" "@cloudflare/workers-types": "npm:^4.20240821.1" "@faker-js/faker": "npm:^8.4.1" - chai: "npm:4.5.0" + chai: "npm:^4.5.0" prettier: "npm:^2.8.8" typescript: "npm:5.3.3" vitest: "npm:1.4.0" @@ -8535,13 +7463,14 @@ __metadata: languageName: unknown linkType: soft -"@hyperlane-xyz/helloworld@npm:7.1.0, @hyperlane-xyz/helloworld@workspace:typescript/helloworld": +"@hyperlane-xyz/helloworld@npm:7.3.0, @hyperlane-xyz/helloworld@workspace:typescript/helloworld": version: 0.0.0-use.local resolution: "@hyperlane-xyz/helloworld@workspace:typescript/helloworld" dependencies: - "@hyperlane-xyz/core": "npm:5.8.1" - "@hyperlane-xyz/registry": "npm:6.1.0" - "@hyperlane-xyz/sdk": "npm:7.1.0" + "@eslint/js": "npm:^9.15.0" + "@hyperlane-xyz/core": "npm:5.8.3" + "@hyperlane-xyz/registry": "npm:6.3.0" + "@hyperlane-xyz/sdk": "npm:7.3.0" "@nomiclabs/hardhat-ethers": "npm:^2.2.3" "@nomiclabs/hardhat-waffle": "npm:^2.0.6" "@openzeppelin/contracts-upgradeable": "npm:^4.9.3" @@ -8549,11 +7478,13 @@ __metadata: "@typechain/ethers-v5": "npm:^11.1.2" "@typechain/ethers-v6": "npm:^0.5.1" "@typechain/hardhat": "npm:^9.1.0" - "@typescript-eslint/eslint-plugin": "npm:^7.4.0" - "@typescript-eslint/parser": "npm:^7.4.0" - chai: "npm:4.5.0" - eslint: "npm:^8.57.0" + "@typescript-eslint/eslint-plugin": "npm:^8.1.6" + "@typescript-eslint/parser": "npm:^8.1.6" + chai: "npm:^4.5.0" + eslint: "npm:^9.15.0" eslint-config-prettier: "npm:^9.1.0" + eslint-import-resolver-typescript: "npm:^3.6.3" + eslint-plugin-import: "npm:^2.31.0" ethereum-waffle: "npm:^4.0.10" ethers: "npm:^5.7.2" hardhat: "npm:^2.22.2" @@ -8578,21 +7509,21 @@ __metadata: version: 0.0.0-use.local resolution: "@hyperlane-xyz/infra@workspace:typescript/infra" dependencies: - "@arbitrum/sdk": "npm:^3.0.0" + "@arbitrum/sdk": "npm:^4.0.0" "@aws-sdk/client-iam": "npm:^3.74.0" - "@aws-sdk/client-kms": "npm:3.48.0" - "@aws-sdk/client-s3": "npm:^3.74.0" + "@aws-sdk/client-kms": "npm:^3.577.0" + "@aws-sdk/client-s3": "npm:^3.577.0" "@cosmjs/amino": "npm:^0.32.4" "@eth-optimism/sdk": "npm:^3.1.6" "@ethersproject/experimental": "npm:^5.7.0" "@ethersproject/hardware-wallets": "npm:^5.7.0" - "@ethersproject/providers": "npm:^5.7.2" + "@ethersproject/providers": "npm:*" "@google-cloud/secret-manager": "npm:^5.5.0" - "@hyperlane-xyz/helloworld": "npm:7.1.0" - "@hyperlane-xyz/registry": "npm:6.1.0" - "@hyperlane-xyz/sdk": "npm:7.1.0" - "@hyperlane-xyz/utils": "npm:7.1.0" - "@inquirer/prompts": "npm:^5.3.8" + "@hyperlane-xyz/helloworld": "npm:7.3.0" + "@hyperlane-xyz/registry": "npm:6.3.0" + "@hyperlane-xyz/sdk": "npm:7.3.0" + "@hyperlane-xyz/utils": "npm:7.3.0" + "@inquirer/prompts": "npm:3.3.2" "@nomiclabs/hardhat-ethers": "npm:^2.2.3" "@nomiclabs/hardhat-etherscan": "npm:^3.0.3" "@nomiclabs/hardhat-waffle": "npm:^2.0.6" @@ -8603,13 +7534,13 @@ __metadata: "@types/chai": "npm:^4.2.21" "@types/json-stable-stringify": "npm:^1.0.36" "@types/mocha": "npm:^10.0.1" - "@types/node": "npm:^16.9.1" + "@types/node": "npm:^18.14.5" "@types/prompts": "npm:^2.0.14" "@types/sinon-chai": "npm:^3.2.12" "@types/yargs": "npm:^17.0.24" - asn1.js: "npm:5.4.1" + asn1.js: "npm:^5.4.1" aws-kms-ethers-signer: "npm:^0.1.3" - chai: "npm:4.5.0" + chai: "npm:^4.5.0" deep-object-diff: "npm:^1.1.9" dotenv: "npm:^10.0.0" ethereum-waffle: "npm:^4.0.10" @@ -8620,7 +7551,7 @@ __metadata: prettier: "npm:^2.8.8" prom-client: "npm:^14.0.1" prompts: "npm:^2.4.2" - tsx: "npm:^4.7.1" + tsx: "npm:^4.19.1" typescript: "npm:5.3.3" yaml: "npm:2.4.5" yargs: "npm:^17.7.2" @@ -8634,40 +7565,46 @@ __metadata: resolution: "@hyperlane-xyz/monorepo@workspace:." dependencies: "@changesets/cli": "npm:^2.26.2" + "@eslint/js": "npm:^9.15.0" "@trivago/prettier-plugin-sort-imports": "npm:^4.2.1" - "@typescript-eslint/eslint-plugin": "npm:^7.4.0" - "@typescript-eslint/parser": "npm:^7.4.0" - eslint: "npm:^8.57.0" + "@typescript-eslint/eslint-plugin": "npm:^8.1.6" + "@typescript-eslint/parser": "npm:^8.1.6" + eslint: "npm:^9.15.0" eslint-config-prettier: "npm:^9.1.0" + eslint-import-resolver-typescript: "npm:^3.6.3" + eslint-plugin-import: "npm:^2.31.0" eslint-plugin-jest: "npm:^28.2.0" husky: "npm:^8.0.0" lint-staged: "npm:^12.4.3" prettier: "npm:^2.8.8" - tsx: "npm:^4.7.1" + syncpack: "npm:^13.0.0" + tsx: "npm:^4.19.1" languageName: unknown linkType: soft -"@hyperlane-xyz/registry@npm:6.1.0": - version: 6.1.0 - resolution: "@hyperlane-xyz/registry@npm:6.1.0" +"@hyperlane-xyz/registry@npm:6.3.0": + version: 6.3.0 + resolution: "@hyperlane-xyz/registry@npm:6.3.0" dependencies: yaml: "npm:2.4.5" zod: "npm:^3.21.2" - checksum: 10/a0e1ecc02d83604793ddda0a3e00a9ffcaa38b1cddf9883b47cf8f1919b4474abd6cc2ee84846e6a35e1bc7539299b9bec92bfdf06be72beecff6aa44b73d382 + checksum: 10/7a1b7226593edf8e12c7e3d425b7889679d46abae1e8c5a389a0b472e2e0a08b292ba89f60572eff9e844c7b5f7322e4420a8888fabef9967c206d5b39f391a1 languageName: node linkType: hard -"@hyperlane-xyz/sdk@npm:7.1.0, @hyperlane-xyz/sdk@workspace:typescript/sdk": +"@hyperlane-xyz/sdk@npm:7.3.0, @hyperlane-xyz/sdk@workspace:typescript/sdk": version: 0.0.0-use.local resolution: "@hyperlane-xyz/sdk@workspace:typescript/sdk" dependencies: "@arbitrum/sdk": "npm:^4.0.0" - "@aws-sdk/client-s3": "npm:^3.74.0" + "@aws-sdk/client-s3": "npm:^3.577.0" "@chain-registry/types": "npm:^0.50.14" "@cosmjs/cosmwasm-stargate": "npm:^0.32.4" "@cosmjs/stargate": "npm:^0.32.4" - "@hyperlane-xyz/core": "npm:5.8.1" - "@hyperlane-xyz/utils": "npm:7.1.0" + "@eslint/js": "npm:^9.15.0" + "@google-cloud/storage": "npm:7.14.0" + "@hyperlane-xyz/core": "npm:5.8.3" + "@hyperlane-xyz/utils": "npm:7.3.0" "@nomiclabs/hardhat-ethers": "npm:^2.2.3" "@nomiclabs/hardhat-waffle": "npm:^2.0.6" "@safe-global/api-kit": "npm:1.3.0" @@ -8676,16 +7613,21 @@ __metadata: "@solana/spl-token": "npm:^0.4.9" "@solana/web3.js": "npm:^1.95.4" "@types/mocha": "npm:^10.0.1" - "@types/node": "npm:^16.9.1" + "@types/node": "npm:^18.14.5" "@types/sinon": "npm:^17.0.1" "@types/sinon-chai": "npm:^3.2.12" "@types/ws": "npm:^8.5.5" + "@typescript-eslint/eslint-plugin": "npm:^8.1.6" + "@typescript-eslint/parser": "npm:^8.1.6" bignumber.js: "npm:^9.1.1" - chai: "npm:4.5.0" + chai: "npm:^4.5.0" cosmjs-types: "npm:^0.9.0" cross-fetch: "npm:^3.1.5" dotenv: "npm:^10.0.0" - eslint: "npm:^8.57.0" + eslint: "npm:^9.15.0" + eslint-config-prettier: "npm:^9.1.0" + eslint-import-resolver-typescript: "npm:^3.6.3" + eslint-plugin-import: "npm:^2.31.0" ethereum-waffle: "npm:^4.0.10" ethers: "npm:^5.7.2" hardhat: "npm:^2.22.2" @@ -8694,7 +7636,7 @@ __metadata: prettier: "npm:^2.8.8" sinon: "npm:^13.0.2" ts-node: "npm:^10.8.0" - tsx: "npm:^4.7.1" + tsx: "npm:^4.19.1" typescript: "npm:5.3.3" viem: "npm:^2.21.45" yaml: "npm:2.4.5" @@ -8705,18 +7647,25 @@ __metadata: languageName: unknown linkType: soft -"@hyperlane-xyz/utils@npm:7.1.0, @hyperlane-xyz/utils@workspace:typescript/utils": +"@hyperlane-xyz/utils@npm:7.3.0, @hyperlane-xyz/utils@workspace:typescript/utils": version: 0.0.0-use.local resolution: "@hyperlane-xyz/utils@workspace:typescript/utils" dependencies: "@cosmjs/encoding": "npm:^0.32.4" + "@eslint/js": "npm:^9.15.0" "@solana/web3.js": "npm:^1.95.4" "@types/lodash-es": "npm:^4.17.12" "@types/mocha": "npm:^10.0.1" "@types/sinon": "npm:^17.0.1" "@types/sinon-chai": "npm:^3.2.12" + "@typescript-eslint/eslint-plugin": "npm:^8.1.6" + "@typescript-eslint/parser": "npm:^8.1.6" bignumber.js: "npm:^9.1.1" - chai: "npm:4.5.0" + chai: "npm:^4.5.0" + eslint: "npm:^9.15.0" + eslint-config-prettier: "npm:^9.1.0" + eslint-import-resolver-typescript: "npm:^3.6.3" + eslint-plugin-import: "npm:^2.31.0" ethers: "npm:^5.7.2" lodash-es: "npm:^4.17.21" mocha: "npm:^10.2.0" @@ -8737,10 +7686,11 @@ __metadata: "@cosmos-kit/react": "npm:^2.18.0" "@emotion/react": "npm:^11.13.3" "@emotion/styled": "npm:^11.13.0" + "@eslint/js": "npm:^9.15.0" "@headlessui/react": "npm:^2.1.8" - "@hyperlane-xyz/registry": "npm:6.1.0" - "@hyperlane-xyz/sdk": "npm:7.1.0" - "@hyperlane-xyz/utils": "npm:7.1.0" + "@hyperlane-xyz/registry": "npm:6.3.0" + "@hyperlane-xyz/sdk": "npm:7.3.0" + "@hyperlane-xyz/utils": "npm:7.3.0" "@interchain-ui/react": "npm:^1.23.28" "@rainbow-me/rainbowkit": "npm:^2.2.0" "@solana/wallet-adapter-react": "npm:^0.15.32" @@ -8755,19 +7705,21 @@ __metadata: "@storybook/react-vite": "npm:^7.6.14" "@storybook/test": "npm:^7.6.14" "@tanstack/react-query": "npm:^5.59.20" - "@types/node": "npm:^18.11.18" + "@types/node": "npm:^18.14.5" "@types/react": "npm:^18.0.27" "@types/react-dom": "npm:^18.0.10" "@types/ws": "npm:^8.5.5" - "@typescript-eslint/eslint-plugin": "npm:^7.4.0" - "@typescript-eslint/parser": "npm:^7.4.0" + "@typescript-eslint/eslint-plugin": "npm:^8.1.6" + "@typescript-eslint/parser": "npm:^8.1.6" babel-loader: "npm:^8.3.0" clsx: "npm:^2.1.1" - eslint: "npm:^8.57.0" + eslint: "npm:^9.15.0" eslint-config-prettier: "npm:^9.1.0" + eslint-import-resolver-typescript: "npm:^3.6.3" + eslint-plugin-import: "npm:^2.31.0" eslint-plugin-react: "npm:^7.37.2" eslint-plugin-react-hooks: "npm:^5.0.0" - eslint-plugin-storybook: "npm:^0.6.15" + eslint-plugin-storybook: "npm:^0.11.1" framer-motion: "npm:^10.16.4" postcss: "npm:^8.4.21" prettier: "npm:^2.8.8" @@ -8778,7 +7730,7 @@ __metadata: tailwindcss: "npm:^3.4.13" ts-node: "npm:^10.8.0" typescript: "npm:5.3.3" - viem: "npm:^2.21.41" + viem: "npm:^2.21.45" vite: "npm:^5.1.1" wagmi: "npm:^2.12.26" peerDependencies: @@ -8787,54 +7739,31 @@ __metadata: languageName: unknown linkType: soft -"@inquirer/checkbox@npm:^1.3.5": - version: 1.3.5 - resolution: "@inquirer/checkbox@npm:1.3.5" +"@inquirer/checkbox@npm:^1.5.2": + version: 1.5.2 + resolution: "@inquirer/checkbox@npm:1.5.2" dependencies: - "@inquirer/core": "npm:^3.0.0" - "@inquirer/type": "npm:^1.1.1" + "@inquirer/core": "npm:^6.0.0" + "@inquirer/type": "npm:^1.1.6" ansi-escapes: "npm:^4.3.2" chalk: "npm:^4.1.2" figures: "npm:^3.2.0" - checksum: 10/e7e984ef44afe2dcdcf2bb56f24065ca15954ee0a16edbc0d614df8de383123a0e956c7c22e1786b60bc0dfb41f98fbcfb89fd33adabff26e223c5acd918aac1 + checksum: 10/00e4dd403c739ce91368915d08ad98000a8dc7a83fe6fca12a4445b47768beb1c86dd99c675d79df6658a93cebca54286e34415c51f8926e6ffb338a2feb4db5 languageName: node linkType: hard -"@inquirer/checkbox@npm:^2.4.7": - version: 2.4.7 - resolution: "@inquirer/checkbox@npm:2.4.7" - dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/figures": "npm:^1.0.5" - "@inquirer/type": "npm:^1.5.2" - ansi-escapes: "npm:^4.3.2" - yoctocolors-cjs: "npm:^2.1.2" - checksum: 10/9bc0d6e9d6db90bcda3771d6b96e885e8c4e1f03d96a4fcd04b4eab2fafbecfafbced7a5cc24eca73f677452f9e354505f9cfb79a884dcf06772550845014d6f - languageName: node - linkType: hard - -"@inquirer/confirm@npm:^2.0.6": - version: 2.0.6 - resolution: "@inquirer/confirm@npm:2.0.6" +"@inquirer/confirm@npm:^2.0.17": + version: 2.0.17 + resolution: "@inquirer/confirm@npm:2.0.17" dependencies: - "@inquirer/core": "npm:^3.0.0" - "@inquirer/type": "npm:^1.1.1" + "@inquirer/core": "npm:^6.0.0" + "@inquirer/type": "npm:^1.1.6" chalk: "npm:^4.1.2" - checksum: 10/efbfeca4c2750ec65fd603d041039356d1f3f5b321305e11fefe40ebc7aa69e8e82fde42f216967462541a9a742768b8f816e4b5c86b3e82c0c886f7227e65ac + checksum: 10/76cdf50881c21bcab4813600502fb3975cbed56a85ad6deaaf06832b92b78b9c932842ffda0e911f29d7dee79dd9dc4724735bd1d60562a509c8ef6317c28c69 languageName: node linkType: hard -"@inquirer/confirm@npm:^3.1.22": - version: 3.1.22 - resolution: "@inquirer/confirm@npm:3.1.22" - dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/type": "npm:^1.5.2" - checksum: 10/14e547ae3194c6447d41bb87135c03aa5598fd340fced19e4e8bae1be4ae54a9ad3cf335a9c3c6dc54e2ffb7928319e0f4b428531b8ce720cd23d2444292ca36 - languageName: node - linkType: hard - -"@inquirer/core@npm:9.0.10, @inquirer/core@npm:^9.0.10": +"@inquirer/core@npm:9.0.10": version: 9.0.10 resolution: "@inquirer/core@npm:9.0.10" dependencies: @@ -8855,71 +7784,49 @@ __metadata: languageName: node linkType: hard -"@inquirer/core@npm:^3.0.0": - version: 3.0.0 - resolution: "@inquirer/core@npm:3.0.0" +"@inquirer/core@npm:^6.0.0": + version: 6.0.0 + resolution: "@inquirer/core@npm:6.0.0" dependencies: - "@inquirer/type": "npm:^1.1.1" - "@types/mute-stream": "npm:^0.0.1" - "@types/node": "npm:^20.4.2" + "@inquirer/type": "npm:^1.1.6" + "@types/mute-stream": "npm:^0.0.4" + "@types/node": "npm:^20.10.7" "@types/wrap-ansi": "npm:^3.0.0" ansi-escapes: "npm:^4.3.2" chalk: "npm:^4.1.2" - cli-spinners: "npm:^2.8.0" - cli-width: "npm:^4.0.0" + cli-spinners: "npm:^2.9.2" + cli-width: "npm:^4.1.0" figures: "npm:^3.2.0" mute-stream: "npm:^1.0.0" run-async: "npm:^3.0.0" - string-width: "npm:^4.2.3" + signal-exit: "npm:^4.1.0" strip-ansi: "npm:^6.0.1" - wrap-ansi: "npm:^6.0.1" - checksum: 10/7524c15d004e1686c5b66086fe70b50ab50983dd6f887a90fa765cc4f9ae2ba7e063dbf0cb740233d55ee1c8b60f10a7b957245bee95223e755e9632c77a9ca4 + wrap-ansi: "npm:^6.2.0" + checksum: 10/a9f79fe538deab439afc845e16fa8832872b4562be6e39a5de8b50eca3e2b27be0e470fc4ee014f202a750213adc8a06068402d51d6d7b34b118b12b08200f85 languageName: node linkType: hard -"@inquirer/editor@npm:^1.2.4": - version: 1.2.4 - resolution: "@inquirer/editor@npm:1.2.4" +"@inquirer/editor@npm:^1.2.15": + version: 1.2.15 + resolution: "@inquirer/editor@npm:1.2.15" dependencies: - "@inquirer/core": "npm:^3.0.0" - "@inquirer/type": "npm:^1.1.1" + "@inquirer/core": "npm:^6.0.0" + "@inquirer/type": "npm:^1.1.6" chalk: "npm:^4.1.2" - external-editor: "npm:^3.0.3" - checksum: 10/a3dac45256d334f79061b0e79b8e9427ee5d5b244367ac582811148f0fe2c7fc3bfaec3aab5fda0ea0293ff23c3c2ef2e66fdf6f6f9b56cf628b265d9cab5afd - languageName: node - linkType: hard - -"@inquirer/editor@npm:^2.1.22": - version: 2.1.22 - resolution: "@inquirer/editor@npm:2.1.22" - dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/type": "npm:^1.5.2" external-editor: "npm:^3.1.0" - checksum: 10/d36255567c88ea48bf1071b00c502d6a32bc1402966db4f9ae1be59d41d64d11e02111317d880d0bdc42fbfb1b819240fb229c89b07dfb804a6d5fb176ab8bb0 + checksum: 10/fbb79f9972aae4cbf7a2e4c36995cf7c6e77b235c47cdd1a05e69f71626aa1ac48ddb3adc3a118568eea2bf5322bfafea71bd62a7969c883c15dbf71e9630e39 languageName: node linkType: hard -"@inquirer/expand@npm:^1.1.5": - version: 1.1.5 - resolution: "@inquirer/expand@npm:1.1.5" +"@inquirer/expand@npm:^1.1.16": + version: 1.1.16 + resolution: "@inquirer/expand@npm:1.1.16" dependencies: - "@inquirer/core": "npm:^3.0.0" - "@inquirer/type": "npm:^1.1.1" + "@inquirer/core": "npm:^6.0.0" + "@inquirer/type": "npm:^1.1.6" chalk: "npm:^4.1.2" figures: "npm:^3.2.0" - checksum: 10/04df9f1713864a965bfaff12358cbd4de97f58363dfb0b625ba4c4b4736bdb1cef38b5a726024ea41b0a55cdbdd1d271fbb6659a8e7fce8927383a8d1bf77562 - languageName: node - linkType: hard - -"@inquirer/expand@npm:^2.1.22": - version: 2.1.22 - resolution: "@inquirer/expand@npm:2.1.22" - dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/type": "npm:^1.5.2" - yoctocolors-cjs: "npm:^2.1.2" - checksum: 10/f997ba916d3ddcc6e2563158805e2ae7a7a6f98e24cf0a08e23d4101b7d78f78e7dce28e648b85ca7f41759eeefdf1c6f6abf2bce0f041fbda54aacf68522454 + checksum: 10/5158f8eb807bd1d55e7e7ca9288051f5947970b32b1a33cd9c94ea228c03cdb18508be5ecd0237061276721f5c9ca96741b3e2c288123c526cdd5049cdf566db languageName: node linkType: hard @@ -8930,158 +7837,76 @@ __metadata: languageName: node linkType: hard -"@inquirer/input@npm:^1.2.5": - version: 1.2.5 - resolution: "@inquirer/input@npm:1.2.5" - dependencies: - "@inquirer/core": "npm:^3.0.0" - "@inquirer/type": "npm:^1.1.1" - chalk: "npm:^4.1.2" - checksum: 10/6a524e231e19f9d2dc80b475722c25b94cfdbc3f4e70491f70f9bdd92409eb1a4f6c856f21d76953c4b6880ce5b657a8acfd12a5cfa7fe2b38f460df8729ce56 - languageName: node - linkType: hard - -"@inquirer/input@npm:^2.2.9": - version: 2.2.9 - resolution: "@inquirer/input@npm:2.2.9" - dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/type": "npm:^1.5.2" - checksum: 10/9d0c97da9cc6972d4fb5bcb077e00e581aae90f6891d33c1c5e2f0324023c1772c6d5b03cd30ec7d4f71d22791d38bf45c47bafbe7dd9f74446693e7b120a2b0 - languageName: node - linkType: hard - -"@inquirer/number@npm:^1.0.10": - version: 1.0.10 - resolution: "@inquirer/number@npm:1.0.10" - dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/type": "npm:^1.5.2" - checksum: 10/0f9323b581e1c35ee8fbf2acde301c3e354896aeac83f6854e9672575090e0d092d19aadadb3477659079c403e63a3206bf668dd4c87e86834f775744f57c955 - languageName: node - linkType: hard - -"@inquirer/password@npm:^1.1.5": - version: 1.1.5 - resolution: "@inquirer/password@npm:1.1.5" +"@inquirer/input@npm:^1.2.16": + version: 1.2.16 + resolution: "@inquirer/input@npm:1.2.16" dependencies: - "@inquirer/input": "npm:^1.2.5" - "@inquirer/type": "npm:^1.1.1" + "@inquirer/core": "npm:^6.0.0" + "@inquirer/type": "npm:^1.1.6" chalk: "npm:^4.1.2" - checksum: 10/81aa1a101cfffdcaab6e12487ffc672e5a5cad0c4e2c504f0c56b7bf3119077826d6df5b0a35a2a938c1ff888618d68e656f7acc5103abd5d7b2b56e97aa5ff3 + checksum: 10/b4b189832ee900b9e088f43a1ce3a959c493ffb06bb112ff166603962e79981086cdf809b63ad908e1f531b52cd467c0681a8dae98005fc0eebe7cee43e41286 languageName: node linkType: hard -"@inquirer/password@npm:^2.1.22": - version: 2.1.22 - resolution: "@inquirer/password@npm:2.1.22" +"@inquirer/password@npm:^1.1.16": + version: 1.1.16 + resolution: "@inquirer/password@npm:1.1.16" dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/type": "npm:^1.5.2" + "@inquirer/core": "npm:^6.0.0" + "@inquirer/type": "npm:^1.1.6" ansi-escapes: "npm:^4.3.2" - checksum: 10/ce4e7c268f267c7436cf3a1b2890a9c92fddc2928bbe141d48f2f5a5daedbb3a2c601e44b0fe4e255792676ed241118ba69756b0d0b7d4492e0b7ee8fc548b90 - languageName: node - linkType: hard - -"@inquirer/prompts@npm:^3.0.0": - version: 3.0.0 - resolution: "@inquirer/prompts@npm:3.0.0" - dependencies: - "@inquirer/checkbox": "npm:^1.3.5" - "@inquirer/confirm": "npm:^2.0.6" - "@inquirer/core": "npm:^3.0.0" - "@inquirer/editor": "npm:^1.2.4" - "@inquirer/expand": "npm:^1.1.5" - "@inquirer/input": "npm:^1.2.5" - "@inquirer/password": "npm:^1.1.5" - "@inquirer/rawlist": "npm:^1.2.5" - "@inquirer/select": "npm:^1.2.5" - checksum: 10/aa35f8543f78f52b8cb939ac8fefd994fa3b118414525209c0993c40ecff856797c3050b8974bfec49eecadfdd25a6ecb50bb122ffc253ae2b0e4e9b5af1043b - languageName: node - linkType: hard - -"@inquirer/prompts@npm:^5.3.8": - version: 5.3.8 - resolution: "@inquirer/prompts@npm:5.3.8" - dependencies: - "@inquirer/checkbox": "npm:^2.4.7" - "@inquirer/confirm": "npm:^3.1.22" - "@inquirer/editor": "npm:^2.1.22" - "@inquirer/expand": "npm:^2.1.22" - "@inquirer/input": "npm:^2.2.9" - "@inquirer/number": "npm:^1.0.10" - "@inquirer/password": "npm:^2.1.22" - "@inquirer/rawlist": "npm:^2.2.4" - "@inquirer/search": "npm:^1.0.7" - "@inquirer/select": "npm:^2.4.7" - checksum: 10/e60eba0d64590c96fed722107962f433fbd8ff13f5d8a3ad6ba56964db69c8bc6b91a439b4e90209184090aacf73d84b0504e8c5a6a0f778ced70deb580ac1cd - languageName: node - linkType: hard - -"@inquirer/rawlist@npm:^1.2.5": - version: 1.2.5 - resolution: "@inquirer/rawlist@npm:1.2.5" - dependencies: - "@inquirer/core": "npm:^3.0.0" - "@inquirer/type": "npm:^1.1.1" chalk: "npm:^4.1.2" - checksum: 10/e94388228305b0d1b49b4f4c6b744c89614c7f413cae2098ff5f7d685ae485b9ad3af9f93796061fad2c8bfa816e7daa9e349ee2499398011744d7c03f6718c3 + checksum: 10/f40309775c690a1d4d39fba1c1bb2a2b4b1beb8b20b1956a4541d4191d7b5eab8ac663c0d0c01caff413cecdf3b2e36e527c391f3aa9a8fc1931f329056e0a81 languageName: node linkType: hard -"@inquirer/rawlist@npm:^2.2.4": - version: 2.2.4 - resolution: "@inquirer/rawlist@npm:2.2.4" +"@inquirer/prompts@npm:3.3.2": + version: 3.3.2 + resolution: "@inquirer/prompts@npm:3.3.2" dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/type": "npm:^1.5.2" - yoctocolors-cjs: "npm:^2.1.2" - checksum: 10/dd9d34a5cca081d53a9798cdfed2fdb61455dcfa856f54bc036dc5f57aceb95a7484487632c157bdba75e50de24990ebb3bb178ee765b8c0a735ff61b29cebf4 + "@inquirer/checkbox": "npm:^1.5.2" + "@inquirer/confirm": "npm:^2.0.17" + "@inquirer/core": "npm:^6.0.0" + "@inquirer/editor": "npm:^1.2.15" + "@inquirer/expand": "npm:^1.1.16" + "@inquirer/input": "npm:^1.2.16" + "@inquirer/password": "npm:^1.1.16" + "@inquirer/rawlist": "npm:^1.2.16" + "@inquirer/select": "npm:^1.3.3" + checksum: 10/d8b18c1fc87fd6774d6934600d2d7eda493bb3cceeb7f9d079acfac507d851b66cf9e9cd2dee3146649bf72db5d1788dacd7e22708bbcebc4c5a00fd94f08b67 languageName: node linkType: hard -"@inquirer/search@npm:^1.0.7": - version: 1.0.7 - resolution: "@inquirer/search@npm:1.0.7" +"@inquirer/rawlist@npm:^1.2.16": + version: 1.2.16 + resolution: "@inquirer/rawlist@npm:1.2.16" dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/figures": "npm:^1.0.5" - "@inquirer/type": "npm:^1.5.2" - yoctocolors-cjs: "npm:^2.1.2" - checksum: 10/3cd401cc1a7b01772e0e50ee27a0560cc647900f475d28a4f9b07843d4a85e1555c6adc1d7bc38ad2ef3546c524ca82c60272490d0bb159632c03cbe01f52bb1 + "@inquirer/core": "npm:^6.0.0" + "@inquirer/type": "npm:^1.1.6" + chalk: "npm:^4.1.2" + checksum: 10/a4acefb0f54e4d4c3f7c44d35971cb0b8cbf2acd6dbe490576cd24369f3304ff4a36255cd4cc851c2de7c037cf70f71c129bc6c8c5c80dce495998e6168904fd languageName: node linkType: hard -"@inquirer/select@npm:^1.2.5": - version: 1.2.5 - resolution: "@inquirer/select@npm:1.2.5" +"@inquirer/select@npm:^1.3.3": + version: 1.3.3 + resolution: "@inquirer/select@npm:1.3.3" dependencies: - "@inquirer/core": "npm:^3.0.0" - "@inquirer/type": "npm:^1.1.1" + "@inquirer/core": "npm:^6.0.0" + "@inquirer/type": "npm:^1.1.6" ansi-escapes: "npm:^4.3.2" chalk: "npm:^4.1.2" figures: "npm:^3.2.0" - checksum: 10/42dec9663740db98d043d39aa799f1292d08ed12725520b316bbe3f7cb48d55e3587725072bdf5720220a2d29befb6f80544e914aa5e54bdfb4d4e00c9299f7d + checksum: 10/0f33c51ab69c156b96092bfb107d08dd0f4227274917b9406aa23877e3ba94fd6738800fb973c44c051aaebdba72d07dc328df4b76e6e1285f68aa01a7ed0ed8 languageName: node linkType: hard -"@inquirer/select@npm:^2.4.7": - version: 2.4.7 - resolution: "@inquirer/select@npm:2.4.7" +"@inquirer/type@npm:^1.1.6": + version: 1.5.5 + resolution: "@inquirer/type@npm:1.5.5" dependencies: - "@inquirer/core": "npm:^9.0.10" - "@inquirer/figures": "npm:^1.0.5" - "@inquirer/type": "npm:^1.5.2" - ansi-escapes: "npm:^4.3.2" - yoctocolors-cjs: "npm:^2.1.2" - checksum: 10/854a3d0393073913f9bd3bf2e4ec7b8d114dfb48308a0a6698cf5c2c627da2700db5bdb69d054eaec89bd4e52a1274e493fa78d4fa26a5893972d91825456047 - languageName: node - linkType: hard - -"@inquirer/type@npm:^1.1.1": - version: 1.1.1 - resolution: "@inquirer/type@npm:1.1.1" - checksum: 10/1fcce0bd6c92611ed67ee9252deebba0fa9a54aeb4e37fc349ec736c8e1ffaa58f3a02dbe84489ff9a90bebc6b1080a19169ef30c16a18128cf8f42d06a49f51 + mute-stream: "npm:^1.0.0" + checksum: 10/bd3f3d7510785af4ad599e042e99e4be6380f52f79f3db140fe6fed0a605acf27b1a0a20fb5cc688eaf7b8aa0c36dacb1d89c7bba4586f38cbf58ba9f159e7b5 languageName: node linkType: hard @@ -10368,7 +9193,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": +"@nodelib/fs.walk@npm:^1.2.3": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -10378,6 +9203,13 @@ __metadata: languageName: node linkType: hard +"@nolyfill/is-core-module@npm:1.0.39": + version: 1.0.39 + resolution: "@nolyfill/is-core-module@npm:1.0.39" + checksum: 10/0d6e098b871eca71d875651288e1f0fa770a63478b0b50479c99dc760c64175a56b5b04f58d5581bbcc6b552b8191ab415eada093d8df9597ab3423c8cac1815 + languageName: node + linkType: hard + "@nomicfoundation/edr-darwin-arm64@npm:0.3.3": version: 0.3.3 resolution: "@nomicfoundation/edr-darwin-arm64@npm:0.3.3" @@ -10902,7 +9734,7 @@ __metadata: languageName: node linkType: hard -"@openzeppelin/contracts-upgradeable@npm:^4.9.3, @openzeppelin/contracts-upgradeable@npm:^v4.9.3": +"@openzeppelin/contracts-upgradeable@npm:^4.9.3": version: 4.9.3 resolution: "@openzeppelin/contracts-upgradeable@npm:4.9.3" checksum: 10/d8fd6fd9d2271fbdd3958c20769b72a241687883ecd3bea05a3969568cdcabdee9d53c21ac776a651c397507d9c22d8db0a4fb970d27bdab918979fae7285a2f @@ -13839,6 +12671,13 @@ __metadata: languageName: node linkType: hard +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 10/17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 + languageName: node + linkType: hard + "@safe-global/api-kit@npm:1.3.0": version: 1.3.0 resolution: "@safe-global/api-kit@npm:1.3.0" @@ -14119,6 +12958,13 @@ __metadata: languageName: node linkType: hard +"@sindresorhus/merge-streams@npm:^2.1.0": + version: 2.3.0 + resolution: "@sindresorhus/merge-streams@npm:2.3.0" + checksum: 10/798bcb53cd1ace9df84fcdd1ba86afdc9e0cd84f5758d26ae9b1eefd8e8887e5fc30051132b9e74daf01bb41fa5a2faf1369361f83d76a3b3d7ee938058fd71c + languageName: node + linkType: hard + "@sinonjs/commons@npm:^1.6.0, @sinonjs/commons@npm:^1.7.0, @sinonjs/commons@npm:^1.8.3": version: 1.8.3 resolution: "@sinonjs/commons@npm:1.8.3" @@ -15847,16 +14693,7 @@ __metadata: languageName: node linkType: hard -"@storybook/csf@npm:^0.0.1": - version: 0.0.1 - resolution: "@storybook/csf@npm:0.0.1" - dependencies: - lodash: "npm:^4.17.15" - checksum: 10/f6bb019bccd8abc14e45a85258158b7bd8cc525887ac8dc9151ed8c4908be3b5f5523da8a7a9b96ff11b13b6c1744e1a0e070560d63d836b950f595f9a5719d4 - languageName: node - linkType: hard - -"@storybook/csf@npm:^0.1.2": +"@storybook/csf@npm:^0.1.11, @storybook/csf@npm:^0.1.2": version: 0.1.11 resolution: "@storybook/csf@npm:0.1.11" dependencies: @@ -16605,6 +15442,13 @@ __metadata: languageName: node linkType: hard +"@types/estree@npm:^1.0.6": + version: 1.0.6 + resolution: "@types/estree@npm:1.0.6" + checksum: 10/9d35d475095199c23e05b431bcdd1f6fec7380612aed068b14b2a08aa70494de8a9026765a5a91b1073f636fb0368f6d8973f518a31391d519e20c59388ed88d + languageName: node + linkType: hard + "@types/express-serve-static-core@npm:^4.17.33": version: 4.19.5 resolution: "@types/express-serve-static-core@npm:4.19.5" @@ -16729,7 +15573,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.5": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10/1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 @@ -16743,6 +15587,13 @@ __metadata: languageName: node linkType: hard +"@types/json5@npm:^0.0.29": + version: 0.0.29 + resolution: "@types/json5@npm:0.0.29" + checksum: 10/4e5aed58cabb2bbf6f725da13421aa50a49abb6bc17bfab6c31b8774b073fa7b50d557c61f961a09a85f6056151190f8ac95f13f5b48136ba5841f7d4484ec56 + languageName: node + linkType: hard + "@types/jsonfile@npm:*": version: 6.1.4 resolution: "@types/jsonfile@npm:6.1.4" @@ -16876,15 +15727,6 @@ __metadata: languageName: node linkType: hard -"@types/mute-stream@npm:^0.0.1": - version: 0.0.1 - resolution: "@types/mute-stream@npm:0.0.1" - dependencies: - "@types/node": "npm:*" - checksum: 10/01bb9f45a77b691538cba7f0c89166a5bfb112993056ae06a8218cd47d417a5f6a5cfc31f0d31293790c647d27564fe6aa39aa9cb2ef08792d42ed40f18de8d5 - languageName: node - linkType: hard - "@types/mute-stream@npm:^0.0.4": version: 0.0.4 resolution: "@types/mute-stream@npm:0.0.4" @@ -16976,14 +15818,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^16.9.1": - version: 16.18.38 - resolution: "@types/node@npm:16.18.38" - checksum: 10/233cc3c4ebbfb011ecd68a552080d4879ced7f66558ecab07d5adc504b3d52181ef31ce7be03c1a616afbc187530aac38f0016ce274d6b8fb89f79365b7c721a - languageName: node - linkType: hard - -"@types/node@npm:^18.0.0, @types/node@npm:^18.11.18": +"@types/node@npm:^18.0.0": version: 18.19.42 resolution: "@types/node@npm:18.19.42" dependencies: @@ -16999,10 +15834,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.4.2": - version: 20.4.5 - resolution: "@types/node@npm:20.4.5" - checksum: 10/aa31081f82a2d377f00cfd7ced73925753db1f542fca19e6b0442585a7322b8eacd957fdccaaff65d9976454d213af0980c12390c59a975cf8a368e3f872717a +"@types/node@npm:^20.10.7": + version: 20.17.8 + resolution: "@types/node@npm:20.17.8" + dependencies: + undici-types: "npm:~6.19.2" + checksum: 10/e3e968b327abc70fd437a223f8950dd4436047e954aa7db09abde5df1f58a5c49f33d6f14524e256d09719e1960d22bf072d62e4bda7375f7895a092c7eb2f9d languageName: node linkType: hard @@ -17183,7 +16020,7 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.12, @types/semver@npm:^7.3.4": +"@types/semver@npm:^7.3.4": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" checksum: 10/3496808818ddb36deabfe4974fd343a78101fa242c4690044ccdc3b95dcf8785b494f5d628f2f47f38a702f8db9c53c67f47d7818f2be1b79f2efb09692e1178 @@ -17363,56 +16200,44 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.4.0" +"@typescript-eslint/eslint-plugin@npm:^8.1.6": + version: 8.16.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.16.0" dependencies: - "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.4.0" - "@typescript-eslint/type-utils": "npm:7.4.0" - "@typescript-eslint/utils": "npm:7.4.0" - "@typescript-eslint/visitor-keys": "npm:7.4.0" - debug: "npm:^4.3.4" + "@eslint-community/regexpp": "npm:^4.10.0" + "@typescript-eslint/scope-manager": "npm:8.16.0" + "@typescript-eslint/type-utils": "npm:8.16.0" + "@typescript-eslint/utils": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.4" + ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" + ts-api-utils: "npm:^1.3.0" peerDependencies: - "@typescript-eslint/parser": ^7.0.0 - eslint: ^8.56.0 + "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/9bd8852c7e4e9608c3fded94f7c60506cc7d2b6d8a8c1cad6d48969a7363751b20282874e55ccdf180635cf204cb10b3e1e5c3d1cff34d4fcd07762be3fc138e + checksum: 10/aa3d551d4f09940eee0c08328cb0db3a2391a8bba6d044f6bb38c51ac864896519c647d4b8fd99f7c094cc677bcf22454b27322014a08b2f2fb25695a43820db languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/parser@npm:7.4.0" +"@typescript-eslint/parser@npm:^8.1.6": + version: 8.16.0 + resolution: "@typescript-eslint/parser@npm:8.16.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.4.0" - "@typescript-eslint/types": "npm:7.4.0" - "@typescript-eslint/typescript-estree": "npm:7.4.0" - "@typescript-eslint/visitor-keys": "npm:7.4.0" + "@typescript-eslint/scope-manager": "npm:8.16.0" + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/typescript-estree": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" debug: "npm:^4.3.4" peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/142a9e1187d305ed43b4fef659c36fa4e28359467198c986f0955c70b4067c9799f4c85d9881fbf099c55dfb265e30666e28b3ef290520e242b45ca7cb8e4ca9 - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/scope-manager@npm:5.62.0" - dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" - checksum: 10/e827770baa202223bc0387e2fd24f630690809e460435b7dc9af336c77322290a770d62bd5284260fa881c86074d6a9fd6c97b07382520b115f6786b8ed499da + checksum: 10/ac1e2bfdbfe212da470bb17915b5228f7a6b027332b05eb8bcbbad440a81b2476c649e54e232084838e1edc005e6d7dc7a44899587d73672dd3d5484d9dbf9f8 languageName: node linkType: hard @@ -17426,37 +16251,30 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/scope-manager@npm:7.4.0" +"@typescript-eslint/scope-manager@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/scope-manager@npm:8.16.0" dependencies: - "@typescript-eslint/types": "npm:7.4.0" - "@typescript-eslint/visitor-keys": "npm:7.4.0" - checksum: 10/8cf9292444f9731017a707cac34bef5ae0eb33b5cd42ed07fcd046e981d97889d9201d48e02f470f2315123f53771435e10b1dc81642af28a11df5352a8e8be2 + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" + checksum: 10/e0aea61f248b39049d4ce21c19f9c8af1a8024f4f92abc8c1d5b79ea65b013c6c4ff41efb92995050036aa95b6a705601917b56809d9ec1fbbab387054aeb269 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/type-utils@npm:7.4.0" +"@typescript-eslint/type-utils@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/type-utils@npm:8.16.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.4.0" - "@typescript-eslint/utils": "npm:7.4.0" + "@typescript-eslint/typescript-estree": "npm:8.16.0" + "@typescript-eslint/utils": "npm:8.16.0" debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.0.1" + ts-api-utils: "npm:^1.3.0" peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/a8bd0929d8237679b2b8a7817f070a4b9658ee976882fba8ff37e4a70dd33f87793e1b157771104111fe8054eaa8ad437a010b6aa465072fbdb932647125db2d - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/types@npm:5.62.0" - checksum: 10/24e8443177be84823242d6729d56af2c4b47bfc664dd411a1d730506abf2150d6c31bdefbbc6d97c8f91043e3a50e0c698239dcb145b79bb6b0c34469aaf6c45 + checksum: 10/b91f6cef6af7e4f82a1dba9622d5ec9f46d1983eecfb88a1adbd310c7f980fedf5c8a198bfe968aae59fc386e4c437f55a7533988252eb9cbb0bdac8321e3dba languageName: node linkType: hard @@ -17467,28 +16285,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/types@npm:7.4.0" - checksum: 10/2782c5bf65cd3dfa9cd32bc3023676bbca22144987c3f6c6b67fd96c73d4a60b85a57458c49fd11b9971ac6531824bb3ae0664491e7a6de25d80c523c9be92b7 - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" - dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - semver: "npm:^7.3.7" - tsutils: "npm:^3.21.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/06c975eb5f44b43bd19fadc2e1023c50cf87038fe4c0dd989d4331c67b3ff509b17fa60a3251896668ab4d7322bdc56162a9926971218d2e1a1874d2bef9a52e +"@typescript-eslint/types@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/types@npm:8.16.0" + checksum: 10/b37b26cd0e45b0cd6f7d492a07af583e4877d798495ab5fc1cfacb3c561b6d7981e3166f0475bb997e6c6d56ef903e160895174c7e63c08322dbb42d026cf7dc languageName: node linkType: hard @@ -17511,57 +16311,39 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.4.0" +"@typescript-eslint/typescript-estree@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.16.0" dependencies: - "@typescript-eslint/types": "npm:7.4.0" - "@typescript-eslint/visitor-keys": "npm:7.4.0" + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" debug: "npm:^4.3.4" - globby: "npm:^11.1.0" + fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" - minimatch: "npm:9.0.3" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" peerDependenciesMeta: typescript: optional: true - checksum: 10/162ec9d7582f45588342e1be36fdb60e41f50bbdfbc3035c91b517ff5d45244f776921c88d88e543e1c7d0f1e6ada5474a8316b78f1b0e6d2233b101bc45b166 + checksum: 10/823cf55d331cf7283547a2860a5d7bfd7dbd497be6e87b226dd7456b36db214de1504855afbbaef8d89932c11a1e589d4cb2a4093b6f1c542a4ce8319d988006 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/utils@npm:7.4.0" +"@typescript-eslint/utils@npm:8.16.0, @typescript-eslint/utils@npm:^8.8.1": + version: 8.16.0 + resolution: "@typescript-eslint/utils@npm:8.16.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@types/json-schema": "npm:^7.0.12" - "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.4.0" - "@typescript-eslint/types": "npm:7.4.0" - "@typescript-eslint/typescript-estree": "npm:7.4.0" - semver: "npm:^7.5.4" + "@typescript-eslint/scope-manager": "npm:8.16.0" + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/typescript-estree": "npm:8.16.0" peerDependencies: - eslint: ^8.56.0 - checksum: 10/ffed27e770c486cd000ff892d9049b0afe8b9d6318452a5355b78a37436cbb414bceacae413a2ac813f3e584684825d5e0baa2e6376b7ad6013a108ac91bc19d - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:^5.45.0": - version: 5.62.0 - resolution: "@typescript-eslint/utils@npm:5.62.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@types/json-schema": "npm:^7.0.9" - "@types/semver": "npm:^7.3.12" - "@typescript-eslint/scope-manager": "npm:5.62.0" - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/typescript-estree": "npm:5.62.0" - eslint-scope: "npm:^5.1.1" - semver: "npm:^7.3.7" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10/15ef13e43998a082b15f85db979f8d3ceb1f9ce4467b8016c267b1738d5e7cdb12aa90faf4b4e6dd6486c236cf9d33c463200465cf25ff997dbc0f12358550a1 + eslint: ^8.57.0 || ^9.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/80ba35b97a8e80ac2b54a56ac041b4f4583328d764e1693e7d3750de383cbcefcb7e838b75e550e8aa4df446f4b41460da6dc83543517280a4e3a61546c1a8dc languageName: node linkType: hard @@ -17582,16 +16364,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" - dependencies: - "@typescript-eslint/types": "npm:5.62.0" - eslint-visitor-keys: "npm:^3.3.0" - checksum: 10/dc613ab7569df9bbe0b2ca677635eb91839dfb2ca2c6fa47870a5da4f160db0b436f7ec0764362e756d4164e9445d49d5eb1ff0b87f4c058946ae9d8c92eb388 - languageName: node - linkType: hard - "@typescript-eslint/visitor-keys@npm:6.21.0": version: 6.21.0 resolution: "@typescript-eslint/visitor-keys@npm:6.21.0" @@ -17602,20 +16374,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.4.0": - version: 7.4.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.4.0" +"@typescript-eslint/visitor-keys@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.16.0" dependencies: - "@typescript-eslint/types": "npm:7.4.0" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/70dc99f2ad116c6e2d9e55af249e4453e06bba2ceea515adef2d2e86e97e557865bb1b1d467667462443eb0d624baba36f7442fd1082f3874339bbc381c26e93 - languageName: node - linkType: hard - -"@ungap/structured-clone@npm:^1.2.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 10/c6fe89a505e513a7592e1438280db1c075764793a2397877ff1351721fe8792a966a5359769e30242b3cd023f2efb9e63ca2ca88019d73b564488cc20e3eab12 + "@typescript-eslint/types": "npm:8.16.0" + eslint-visitor-keys: "npm:^4.2.0" + checksum: 10/e3f231a3e8ca2f7a3dc0e9ebdc3ea1f51a377b1285727413b4c89c44dbfaf342f2574b1b4e7f478f295963045a6058e27b4827816fe2a5a2d09f565eb68522c7 languageName: node linkType: hard @@ -18485,7 +17250,16 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.4.1, acorn@npm:^8.9.0": +"acorn@npm:^8.14.0": + version: 8.14.0 + resolution: "acorn@npm:8.14.0" + bin: + acorn: bin/acorn + checksum: 10/6df29c35556782ca9e632db461a7f97947772c6c1d5438a81f0c873a3da3a792487e83e404d1c6c25f70513e91aa18745f6eafb1fcc3a43ecd1920b21dd173d2 + languageName: node + linkType: hard + +"acorn@npm:^8.4.1": version: 8.11.3 resolution: "acorn@npm:8.11.3" bin: @@ -18998,7 +17772,21 @@ __metadata: languageName: node linkType: hard -"array.prototype.flat@npm:^1.2.3, array.prototype.flat@npm:^1.3.1": +"array.prototype.findlastindex@npm:^1.2.5": + version: 1.2.5 + resolution: "array.prototype.findlastindex@npm:1.2.5" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/7c5c821f357cd53ab6cc305de8086430dd8d7a2485db87b13f843e868055e9582b1fd338f02338f67fc3a1603ceaf9610dd2a470b0b506f9d18934780f95b246 + languageName: node + linkType: hard + +"array.prototype.flat@npm:^1.2.3, array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": version: 1.3.2 resolution: "array.prototype.flat@npm:1.3.2" dependencies: @@ -19086,6 +17874,13 @@ __metadata: languageName: node linkType: hard +"arrify@npm:^2.0.0": + version: 2.0.1 + resolution: "arrify@npm:2.0.1" + checksum: 10/067c4c1afd182806a82e4c1cb8acee16ab8b5284fbca1ce29408e6e91281c36bb5b612f6ddfbd40a0f7a7e0c75bf2696eb94c027f6e328d6e9c52465c98e4209 + languageName: node + linkType: hard + "as-table@npm:^1.0.36": version: 1.0.55 resolution: "as-table@npm:1.0.55" @@ -19102,7 +17897,7 @@ __metadata: languageName: node linkType: hard -"asn1.js@npm:5.4.1, asn1.js@npm:^5.4.1": +"asn1.js@npm:^5.4.1": version: 5.4.1 resolution: "asn1.js@npm:5.4.1" dependencies: @@ -20404,7 +19199,7 @@ __metadata: languageName: node linkType: hard -"chai@npm:4.5.0, chai@npm:^4.3.10, chai@npm:^4.3.7, chai@npm:^4.5.0": +"chai@npm:^4.3.10, chai@npm:^4.3.7, chai@npm:^4.5.0": version: 4.5.0 resolution: "chai@npm:4.5.0" dependencies: @@ -20449,6 +19244,22 @@ __metadata: languageName: node linkType: hard +"chalk-template@npm:1.1.0": + version: 1.1.0 + resolution: "chalk-template@npm:1.1.0" + dependencies: + chalk: "npm:^5.2.0" + checksum: 10/868aae8d4e7556ad2f35de4e04fe65dbe1ea6c5c80ad783f1c156d0a5c33f444c6814f49cbb68fe348c78e99daf2bcf566b47ad7e13603e4691ca78b2f422824 + languageName: node + linkType: hard + +"chalk@npm:5.3.0, chalk@npm:^5.2.0, chalk@npm:^5.3.0": + version: 5.3.0 + resolution: "chalk@npm:5.3.0" + checksum: 10/6373caaab21bd64c405bfc4bd9672b145647fc9482657b5ea1d549b3b2765054e9d3d928870cdf764fb4aad67555f5061538ff247b8310f110c5c888d92397ea + languageName: node + linkType: hard + "chalk@npm:^2.0.0, chalk@npm:^2.1.0, chalk@npm:^2.4.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -20480,13 +19291,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.3.0": - version: 5.3.0 - resolution: "chalk@npm:5.3.0" - checksum: 10/6373caaab21bd64c405bfc4bd9672b145647fc9482657b5ea1d549b3b2765054e9d3d928870cdf764fb4aad67555f5061538ff247b8310f110c5c888d92397ea - languageName: node - linkType: hard - "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -20713,6 +19517,15 @@ __metadata: languageName: node linkType: hard +"cli-cursor@npm:^4.0.0": + version: 4.0.0 + resolution: "cli-cursor@npm:4.0.0" + dependencies: + restore-cursor: "npm:^4.0.0" + checksum: 10/ab3f3ea2076e2176a1da29f9d64f72ec3efad51c0960898b56c8a17671365c26e67b735920530eaf7328d61f8bd41c27f46b9cf6e4e10fe2fa44b5e8c0e392cc + languageName: node + linkType: hard + "cli-spinners@npm:^2.5.0, cli-spinners@npm:^2.9.2": version: 2.9.2 resolution: "cli-spinners@npm:2.9.2" @@ -20720,13 +19533,6 @@ __metadata: languageName: node linkType: hard -"cli-spinners@npm:^2.8.0": - version: 2.9.0 - resolution: "cli-spinners@npm:2.9.0" - checksum: 10/457497ccef70eec3f1d0825e4a3396ba43f6833a4900c2047c0efe2beecb1c0df476949ea378bcb6595754f7508e28ae943eeb30bbda807f59f547b270ec334c - languageName: node - linkType: hard - "cli-table3@npm:^0.5.0": version: 0.5.1 resolution: "cli-table3@npm:0.5.1" @@ -20787,13 +19593,6 @@ __metadata: languageName: node linkType: hard -"cli-width@npm:^4.0.0": - version: 4.0.0 - resolution: "cli-width@npm:4.0.0" - checksum: 10/6de44fee34dadfc95a68ba012ea4d06d776289c251a283473e5ee240f26bbade4816766eb699c78b91804943c405097155bddf8c3e492daf1da7d9ab38a89878 - languageName: node - linkType: hard - "cli-width@npm:^4.1.0": version: 4.1.0 resolution: "cli-width@npm:4.1.0" @@ -21027,6 +19826,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:12.1.0, commander@npm:^12.1.0": + version: 12.1.0 + resolution: "commander@npm:12.1.0" + checksum: 10/cdaeb672d979816853a4eed7f1310a9319e8b976172485c2a6b437ed0db0a389a44cfb222bfbde772781efa9f215bdd1b936f80d6b249485b465c6cb906e1f93 + languageName: node + linkType: hard + "commander@npm:3.0.2": version: 3.0.2 resolution: "commander@npm:3.0.2" @@ -21041,13 +19847,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^12.1.0": - version: 12.1.0 - resolution: "commander@npm:12.1.0" - checksum: 10/cdaeb672d979816853a4eed7f1310a9319e8b976172485c2a6b437ed0db0a389a44cfb222bfbde772781efa9f215bdd1b936f80d6b249485b465c6cb906e1f93 - languageName: node - linkType: hard - "commander@npm:^2.20.3": version: 2.20.3 resolution: "commander@npm:2.20.3" @@ -21303,6 +20102,23 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:9.0.0": + version: 9.0.0 + resolution: "cosmiconfig@npm:9.0.0" + dependencies: + env-paths: "npm:^2.2.1" + import-fresh: "npm:^3.3.0" + js-yaml: "npm:^4.1.0" + parse-json: "npm:^5.2.0" + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/8bdf1dfbb6fdb3755195b6886dc0649a3c742ec75afa4cb8da7b070936aed22a4f4e5b7359faafe03180358f311dbc300d248fd6586c458203d376a40cc77826 + languageName: node + linkType: hard + "cosmiconfig@npm:^7.0.0": version: 7.1.0 resolution: "cosmiconfig@npm:7.1.0" @@ -21442,7 +20258,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -21453,6 +20269,17 @@ __metadata: languageName: node linkType: hard +"cross-spawn@npm:^7.0.5": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10/0d52657d7ae36eb130999dffff1168ec348687b48dd38e2ff59992ed916c88d328cf1d07ff4a4a10bc78de5e1c23f04b306d569e42f7a2293915c081e4dfee86 + languageName: node + linkType: hard + "crossws@npm:>=0.2.0 <0.4.0": version: 0.3.1 resolution: "crossws@npm:0.3.1" @@ -21658,7 +20485,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^3.1.0": +"debug@npm:^3.1.0, debug@npm:^3.2.7": version: 3.2.7 resolution: "debug@npm:3.2.7" dependencies: @@ -21667,7 +20494,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:~4.3.1, debug@npm:~4.3.2": +"debug@npm:^4.3.5, debug@npm:~4.3.1, debug@npm:~4.3.2": version: 4.3.7 resolution: "debug@npm:4.3.7" dependencies: @@ -22247,7 +21074,7 @@ __metadata: languageName: node linkType: hard -"duplexify@npm:^4.0.0, duplexify@npm:^4.1.2": +"duplexify@npm:^4.0.0, duplexify@npm:^4.1.2, duplexify@npm:^4.1.3": version: 4.1.3 resolution: "duplexify@npm:4.1.3" dependencies: @@ -22304,6 +21131,13 @@ __metadata: languageName: node linkType: hard +"effect@npm:3.6.5": + version: 3.6.5 + resolution: "effect@npm:3.6.5" + checksum: 10/e722cc1d262dfcff85b3e43d11edafb03d68e0acf670ed0d709d32218e6bf2ae7084ac627430094b1be6aee6ffdeec061b1d097d2216fce18ebc7264087ab2f0 + languageName: node + linkType: hard + "ejs@npm:^3.1.8": version: 3.1.10 resolution: "ejs@npm:3.1.10" @@ -22373,6 +21207,13 @@ __metadata: languageName: node linkType: hard +"emoji-regex@npm:^10.3.0": + version: 10.4.0 + resolution: "emoji-regex@npm:10.4.0" + checksum: 10/76bb92c5bcf0b6980d37e535156231e4a9d0aa6ab3b9f5eabf7690231d5aa5d5b8e516f36e6804cbdd0f1c23dfef2a60c40ab7bb8aedd890584281a565b97c50 + languageName: node + linkType: hard + "emoji-regex@npm:^7.0.1": version: 7.0.3 resolution: "emoji-regex@npm:7.0.3" @@ -22465,16 +21306,17 @@ __metadata: languageName: node linkType: hard -"enquirer@npm:^2.3.0": - version: 2.3.6 - resolution: "enquirer@npm:2.3.6" +"enhanced-resolve@npm:^5.15.0": + version: 5.17.1 + resolution: "enhanced-resolve@npm:5.17.1" dependencies: - ansi-colors: "npm:^4.1.1" - checksum: 10/751d14f037eb7683997e696fb8d5fe2675e0b0cde91182c128cf598acf3f5bd9005f35f7c2a9109e291140af496ebec237b6dac86067d59a9b44f3688107f426 + graceful-fs: "npm:^4.2.4" + tapable: "npm:^2.2.0" + checksum: 10/e8e03cb7a4bf3c0250a89afbd29e5ec20e90ba5fcd026066232a0754864d7d0a393fa6fc0e5379314a6529165a1834b36731147080714459d98924520410d8f5 languageName: node linkType: hard -"enquirer@npm:^2.3.6": +"enquirer@npm:2.4.1, enquirer@npm:^2.3.6": version: 2.4.1 resolution: "enquirer@npm:2.4.1" dependencies: @@ -22484,6 +21326,15 @@ __metadata: languageName: node linkType: hard +"enquirer@npm:^2.3.0": + version: 2.3.6 + resolution: "enquirer@npm:2.3.6" + dependencies: + ansi-colors: "npm:^4.1.1" + checksum: 10/751d14f037eb7683997e696fb8d5fe2675e0b0cde91182c128cf598acf3f5bd9005f35f7c2a9109e291140af496ebec237b6dac86067d59a9b44f3688107f426 + languageName: node + linkType: hard + "entities@npm:2.2.0": version: 2.2.0 resolution: "entities@npm:2.2.0" @@ -22491,7 +21342,7 @@ __metadata: languageName: node linkType: hard -"env-paths@npm:^2.2.0": +"env-paths@npm:^2.2.0, env-paths@npm:^2.2.1": version: 2.2.1 resolution: "env-paths@npm:2.2.1" checksum: 10/65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e @@ -23101,86 +21952,6 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:~0.19.10": - version: 0.19.12 - resolution: "esbuild@npm:0.19.12" - dependencies: - "@esbuild/aix-ppc64": "npm:0.19.12" - "@esbuild/android-arm": "npm:0.19.12" - "@esbuild/android-arm64": "npm:0.19.12" - "@esbuild/android-x64": "npm:0.19.12" - "@esbuild/darwin-arm64": "npm:0.19.12" - "@esbuild/darwin-x64": "npm:0.19.12" - "@esbuild/freebsd-arm64": "npm:0.19.12" - "@esbuild/freebsd-x64": "npm:0.19.12" - "@esbuild/linux-arm": "npm:0.19.12" - "@esbuild/linux-arm64": "npm:0.19.12" - "@esbuild/linux-ia32": "npm:0.19.12" - "@esbuild/linux-loong64": "npm:0.19.12" - "@esbuild/linux-mips64el": "npm:0.19.12" - "@esbuild/linux-ppc64": "npm:0.19.12" - "@esbuild/linux-riscv64": "npm:0.19.12" - "@esbuild/linux-s390x": "npm:0.19.12" - "@esbuild/linux-x64": "npm:0.19.12" - "@esbuild/netbsd-x64": "npm:0.19.12" - "@esbuild/openbsd-x64": "npm:0.19.12" - "@esbuild/sunos-x64": "npm:0.19.12" - "@esbuild/win32-arm64": "npm:0.19.12" - "@esbuild/win32-ia32": "npm:0.19.12" - "@esbuild/win32-x64": "npm:0.19.12" - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 10/861fa8eb2428e8d6521a4b7c7930139e3f45e8d51a86985cc29408172a41f6b18df7b3401e7e5e2d528cdf83742da601ddfdc77043ddc4f1c715a8ddb2d8a255 - languageName: node - linkType: hard - "esbuild@npm:~0.23.0": version: 0.23.1 resolution: "esbuild@npm:0.23.1" @@ -23354,6 +22125,83 @@ __metadata: languageName: node linkType: hard +"eslint-import-resolver-node@npm:^0.3.9": + version: 0.3.9 + resolution: "eslint-import-resolver-node@npm:0.3.9" + dependencies: + debug: "npm:^3.2.7" + is-core-module: "npm:^2.13.0" + resolve: "npm:^1.22.4" + checksum: 10/d52e08e1d96cf630957272e4f2644dcfb531e49dcfd1edd2e07e43369eb2ec7a7d4423d417beee613201206ff2efa4eb9a582b5825ee28802fc7c71fcd53ca83 + languageName: node + linkType: hard + +"eslint-import-resolver-typescript@npm:^3.6.3": + version: 3.6.3 + resolution: "eslint-import-resolver-typescript@npm:3.6.3" + dependencies: + "@nolyfill/is-core-module": "npm:1.0.39" + debug: "npm:^4.3.5" + enhanced-resolve: "npm:^5.15.0" + eslint-module-utils: "npm:^2.8.1" + fast-glob: "npm:^3.3.2" + get-tsconfig: "npm:^4.7.5" + is-bun-module: "npm:^1.0.2" + is-glob: "npm:^4.0.3" + peerDependencies: + eslint: "*" + eslint-plugin-import: "*" + eslint-plugin-import-x: "*" + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + checksum: 10/5f9956dbbd0becc3d6c6cb945dad0e5e6f529cfd0f488d5688f3c59840cd7f4a44ab6aee0f54b5c4188134dab9a01cb63c1201767bde7fc330b7c1a14747f8ac + languageName: node + linkType: hard + +"eslint-module-utils@npm:^2.12.0, eslint-module-utils@npm:^2.8.1": + version: 2.12.0 + resolution: "eslint-module-utils@npm:2.12.0" + dependencies: + debug: "npm:^3.2.7" + peerDependenciesMeta: + eslint: + optional: true + checksum: 10/dd27791147eca17366afcb83f47d6825b6ce164abb256681e5de4ec1d7e87d8605641eb869298a0dbc70665e2446dbcc2f40d3e1631a9475dd64dd23d4ca5dee + languageName: node + linkType: hard + +"eslint-plugin-import@npm:^2.31.0": + version: 2.31.0 + resolution: "eslint-plugin-import@npm:2.31.0" + dependencies: + "@rtsao/scc": "npm:^1.1.0" + array-includes: "npm:^3.1.8" + array.prototype.findlastindex: "npm:^1.2.5" + array.prototype.flat: "npm:^1.3.2" + array.prototype.flatmap: "npm:^1.3.2" + debug: "npm:^3.2.7" + doctrine: "npm:^2.1.0" + eslint-import-resolver-node: "npm:^0.3.9" + eslint-module-utils: "npm:^2.12.0" + hasown: "npm:^2.0.2" + is-core-module: "npm:^2.15.1" + is-glob: "npm:^4.0.3" + minimatch: "npm:^3.1.2" + object.fromentries: "npm:^2.0.8" + object.groupby: "npm:^1.0.3" + object.values: "npm:^1.2.0" + semver: "npm:^6.3.1" + string.prototype.trimend: "npm:^1.0.8" + tsconfig-paths: "npm:^3.15.0" + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + checksum: 10/6b76bd009ac2db0615d9019699d18e2a51a86cb8c1d0855a35fb1b418be23b40239e6debdc6e8c92c59f1468ed0ea8d7b85c817117a113d5cc225be8a02ad31c + languageName: node + linkType: hard + "eslint-plugin-jest@npm:^28.2.0": version: 28.2.0 resolution: "eslint-plugin-jest@npm:28.2.0" @@ -23409,37 +22257,26 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-storybook@npm:^0.6.15": - version: 0.6.15 - resolution: "eslint-plugin-storybook@npm:0.6.15" +"eslint-plugin-storybook@npm:^0.11.1": + version: 0.11.1 + resolution: "eslint-plugin-storybook@npm:0.11.1" dependencies: - "@storybook/csf": "npm:^0.0.1" - "@typescript-eslint/utils": "npm:^5.45.0" - requireindex: "npm:^1.1.0" + "@storybook/csf": "npm:^0.1.11" + "@typescript-eslint/utils": "npm:^8.8.1" ts-dedent: "npm:^2.2.0" peerDependencies: eslint: ">=6" - checksum: 10/0c278594c8474ce2f176ffc6610240ae9d6c8f9dafbff02be61e6ae05f15081ce858c5b16e64d8995a3a3777c9d1725953fcde4312efab9118aa544a75b27c46 - languageName: node - linkType: hard - -"eslint-scope@npm:^5.1.1": - version: 5.1.1 - resolution: "eslint-scope@npm:5.1.1" - dependencies: - esrecurse: "npm:^4.3.0" - estraverse: "npm:^4.1.1" - checksum: 10/c541ef384c92eb5c999b7d3443d80195fcafb3da335500946f6db76539b87d5826c8f2e1d23bf6afc3154ba8cd7c8e566f8dc00f1eea25fdf3afc8fb9c87b238 + checksum: 10/3a8757e403227665566a9ee35a735bf72529a8eb2d6ba270c99e6df140601984b43e7fcf274ebee601fe3d946c76edfeefcce4200077da53edc26212ba5bd03c languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" +"eslint-scope@npm:^8.2.0": + version: 8.2.0 + resolution: "eslint-scope@npm:8.2.0" dependencies: esrecurse: "npm:^4.3.0" estraverse: "npm:^5.2.0" - checksum: 10/5c660fb905d5883ad018a6fea2b49f3cb5b1cbf2cd4bd08e98646e9864f9bc2c74c0839bed2d292e90a4a328833accc197c8f0baed89cbe8d605d6f918465491 + checksum: 10/cd9ab60d5a68f3a0fcac04d1cff5a7383d0f331964d5f1c446259123caec5b3ccc542284d07846e4f4d1389da77750821cc9a6e1ce18558c674977351666f9a6 languageName: node linkType: hard @@ -23457,69 +22294,70 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.4.3": - version: 3.4.3 - resolution: "eslint-visitor-keys@npm:3.4.3" - checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b +"eslint-visitor-keys@npm:^4.2.0": + version: 4.2.0 + resolution: "eslint-visitor-keys@npm:4.2.0" + checksum: 10/9651b3356b01760e586b4c631c5268c0e1a85236e3292bf754f0472f465bf9a856c0ddc261fceace155334118c0151778effafbab981413dbf9288349343fa25 languageName: node linkType: hard -"eslint@npm:^8.57.0": - version: 8.57.0 - resolution: "eslint@npm:8.57.0" +"eslint@npm:^9.15.0": + version: 9.15.0 + resolution: "eslint@npm:9.15.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" - "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.57.0" - "@humanwhocodes/config-array": "npm:^0.11.14" + "@eslint-community/regexpp": "npm:^4.12.1" + "@eslint/config-array": "npm:^0.19.0" + "@eslint/core": "npm:^0.9.0" + "@eslint/eslintrc": "npm:^3.2.0" + "@eslint/js": "npm:9.15.0" + "@eslint/plugin-kit": "npm:^0.2.3" + "@humanfs/node": "npm:^0.16.6" "@humanwhocodes/module-importer": "npm:^1.0.1" - "@nodelib/fs.walk": "npm:^1.2.8" - "@ungap/structured-clone": "npm:^1.2.0" + "@humanwhocodes/retry": "npm:^0.4.1" + "@types/estree": "npm:^1.0.6" + "@types/json-schema": "npm:^7.0.15" ajv: "npm:^6.12.4" chalk: "npm:^4.0.0" - cross-spawn: "npm:^7.0.2" + cross-spawn: "npm:^7.0.5" debug: "npm:^4.3.2" - doctrine: "npm:^3.0.0" escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^7.2.2" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" - esquery: "npm:^1.4.2" + eslint-scope: "npm:^8.2.0" + eslint-visitor-keys: "npm:^4.2.0" + espree: "npm:^10.3.0" + esquery: "npm:^1.5.0" esutils: "npm:^2.0.2" fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^6.0.1" + file-entry-cache: "npm:^8.0.0" find-up: "npm:^5.0.0" glob-parent: "npm:^6.0.2" - globals: "npm:^13.19.0" - graphemer: "npm:^1.4.0" ignore: "npm:^5.2.0" imurmurhash: "npm:^0.1.4" is-glob: "npm:^4.0.0" - is-path-inside: "npm:^3.0.3" - js-yaml: "npm:^4.1.0" json-stable-stringify-without-jsonify: "npm:^1.0.1" - levn: "npm:^0.4.1" lodash.merge: "npm:^4.6.2" minimatch: "npm:^3.1.2" natural-compare: "npm:^1.4.0" optionator: "npm:^0.9.3" - strip-ansi: "npm:^6.0.1" - text-table: "npm:^0.2.0" + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true bin: eslint: bin/eslint.js - checksum: 10/00496e218b23747a7a9817bf58b522276d0dc1f2e546dceb4eea49f9871574088f72f1f069a6b560ef537efa3a75261b8ef70e51ef19033da1cc4c86a755ef15 + checksum: 10/7ac1a2e6070bae64b2b0588fabad528cd3e478a6ba5e9f8185d8d9f2dce17a36630bd019b5d32d1052ea177444ab9c83f3c08baa76121c13e1ed0584ef158956 languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" +"espree@npm:^10.0.1, espree@npm:^10.3.0": + version: 10.3.0 + resolution: "espree@npm:10.3.0" dependencies: - acorn: "npm:^8.9.0" + acorn: "npm:^8.14.0" acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/255ab260f0d711a54096bdeda93adff0eadf02a6f9b92f02b323e83a2b7fc258797919437ad331efec3930475feb0142c5ecaaf3cdab4befebd336d47d3f3134 + eslint-visitor-keys: "npm:^4.2.0" + checksum: 10/3412d44d4204c9e29d6b5dd0277400cfa0cd68495dc09eae1b9ce79d0c8985c1c5cc09cb9ba32a1cd963f48a49b0c46bdb7736afe395a300aa6bb1c0d86837e8 languageName: node linkType: hard @@ -23543,12 +22381,12 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.2": - version: 1.5.0 - resolution: "esquery@npm:1.5.0" +"esquery@npm:^1.5.0": + version: 1.6.0 + resolution: "esquery@npm:1.6.0" dependencies: estraverse: "npm:^5.1.0" - checksum: 10/e65fcdfc1e0ff5effbf50fb4f31ea20143ae5df92bb2e4953653d8d40aa4bc148e0d06117a592ce4ea53eeab1dafdfded7ea7e22a5be87e82d73757329a1b01d + checksum: 10/c587fb8ec9ed83f2b1bc97cf2f6854cc30bf784a79d62ba08c6e358bf22280d69aee12827521cf38e69ae9761d23fb7fde593ce315610f85655c139d99b05e5a languageName: node linkType: hard @@ -23568,13 +22406,6 @@ __metadata: languageName: node linkType: hard -"estraverse@npm:^4.1.1": - version: 4.3.0 - resolution: "estraverse@npm:4.3.0" - checksum: 10/3f67ad02b6dbfaddd9ea459cf2b6ef4ecff9a6082a7af9d22e445b9abc082ad9ca47e1825557b293fcdae477f4714e561123e30bb6a5b2f184fb2bad4a9497eb - languageName: node - linkType: hard - "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" @@ -23852,7 +22683,24 @@ __metadata: languageName: node linkType: hard -"ethers@npm:5.7.2, ethers@npm:^5.1.0, ethers@npm:^5.3.1, ethers@npm:^5.7.0, ethers@npm:^5.7.1, ethers@npm:^5.7.2": +"ethers@npm:^4.0.40": + version: 4.0.49 + resolution: "ethers@npm:4.0.49" + dependencies: + aes-js: "npm:3.0.0" + bn.js: "npm:^4.11.9" + elliptic: "npm:6.5.4" + hash.js: "npm:1.1.3" + js-sha3: "npm:0.5.7" + scrypt-js: "npm:2.0.4" + setimmediate: "npm:1.0.4" + uuid: "npm:2.0.1" + xmlhttprequest: "npm:1.8.0" + checksum: 10/a4cec0254f940a0fb118317d23676faa46eb5540fc0a3b9177b8aef71318f509ed19b8264f102b1a2a32d0256274ecc526fd926bd22a4a4ac25cd8e0e6560f12 + languageName: node + linkType: hard + +"ethers@npm:^5.1.0, ethers@npm:^5.3.1, ethers@npm:^5.7.0, ethers@npm:^5.7.1, ethers@npm:^5.7.2": version: 5.7.2 resolution: "ethers@npm:5.7.2" dependencies: @@ -23890,23 +22738,6 @@ __metadata: languageName: node linkType: hard -"ethers@npm:^4.0.40": - version: 4.0.49 - resolution: "ethers@npm:4.0.49" - dependencies: - aes-js: "npm:3.0.0" - bn.js: "npm:^4.11.9" - elliptic: "npm:6.5.4" - hash.js: "npm:1.1.3" - js-sha3: "npm:0.5.7" - scrypt-js: "npm:2.0.4" - setimmediate: "npm:1.0.4" - uuid: "npm:2.0.1" - xmlhttprequest: "npm:1.8.0" - checksum: 10/a4cec0254f940a0fb118317d23676faa46eb5540fc0a3b9177b8aef71318f509ed19b8264f102b1a2a32d0256274ecc526fd926bd22a4a4ac25cd8e0e6560f12 - languageName: node - linkType: hard - "ethjs-unit@npm:0.1.6": version: 0.1.6 resolution: "ethjs-unit@npm:0.1.6" @@ -24198,7 +23029,7 @@ __metadata: languageName: node linkType: hard -"external-editor@npm:^3.0.3, external-editor@npm:^3.1.0": +"external-editor@npm:^3.1.0": version: 3.1.0 resolution: "external-editor@npm:3.1.0" dependencies: @@ -24251,6 +23082,24 @@ __metadata: languageName: node linkType: hard +"fast-check@npm:3.21.0": + version: 3.21.0 + resolution: "fast-check@npm:3.21.0" + dependencies: + pure-rand: "npm:^6.1.0" + checksum: 10/64e221858d5d98c6ea10c81e6a1a66760565bca41883466891974197a5439c7f0fe1dc293b8d887eaf959d0ff85197cc9d76813ae6215b018cde313254db7d53 + languageName: node + linkType: hard + +"fast-check@npm:^3.21.0": + version: 3.23.1 + resolution: "fast-check@npm:3.23.1" + dependencies: + pure-rand: "npm:^6.1.0" + checksum: 10/03720c2d4adf02701a2e974b83d6439477851a6524c5980df0870dc0032f0200cc5e157f47641afa79dc42733b05058f2333df54291d5ac39d108d317a62e6c0 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -24285,7 +23134,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.3.0": +"fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.2": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" dependencies: @@ -24353,6 +23202,17 @@ __metadata: languageName: node linkType: hard +"fast-xml-parser@npm:^4.4.1": + version: 4.5.0 + resolution: "fast-xml-parser@npm:4.5.0" + dependencies: + strnum: "npm:^1.0.5" + bin: + fxparser: src/cli/cli.js + checksum: 10/dc9571c10e7b57b5be54bcd2d92f50c446eb42ea5df347d253e94dd14eb99b5300a6d172e840f151e0721933ca2406165a8d9b316a6d777bf0596dc4fe1df756 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.13.0 resolution: "fastq@npm:1.13.0" @@ -24396,12 +23256,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" dependencies: - flat-cache: "npm:^3.0.4" - checksum: 10/099bb9d4ab332cb93c48b14807a6918a1da87c45dce91d4b61fd40e6505d56d0697da060cb901c729c90487067d93c9243f5da3dc9c41f0358483bfdebca736b + flat-cache: "npm:^4.0.0" + checksum: 10/afe55c4de4e0d226a23c1eae62a7219aafb390859122608a89fa4df6addf55c7fd3f1a2da6f5b41e7cdff496e4cf28bbd215d53eab5c817afa96d2b40c81bfb0 languageName: node linkType: hard @@ -24557,13 +23417,13 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.0.4 - resolution: "flat-cache@npm:3.0.4" +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" dependencies: - flatted: "npm:^3.1.0" - rimraf: "npm:^3.0.2" - checksum: 10/9fe5d0cb97c988e3b25242e71346965fae22757674db3fca14206850af2efa3ca3b04a3ba0eba8d5e20fd8a3be80a2e14b1c2917e70ffe1acb98a8c3327e4c9f + flatted: "npm:^3.2.9" + keyv: "npm:^4.5.4" + checksum: 10/58ce851d9045fffc7871ce2bd718bc485ad7e777bf748c054904b87c351ff1080c2c11da00788d78738bfb51b71e4d5ea12d13b98eb36e3358851ffe495b62dc languageName: node linkType: hard @@ -24576,10 +23436,10 @@ __metadata: languageName: node linkType: hard -"flatted@npm:^3.1.0": - version: 3.2.5 - resolution: "flatted@npm:3.2.5" - checksum: 10/eed01f72ad0317561e4d6187f7408dc391f7849d9cd6700520ce06155d1859539b6899afdfefc815ce51ec48f97d1015350287c541b5302a49581cf25cec1cd2 +"flatted@npm:^3.2.9": + version: 3.3.2 + resolution: "flatted@npm:3.3.2" + checksum: 10/ac3c159742e01d0e860a861164bcfd35bb567ccbebb8a0dd041e61cf3c64a435b917dd1e7ed1c380c2ebca85735fb16644485ec33665bc6aafc3b316aa1eed44 languageName: node linkType: hard @@ -25095,6 +23955,19 @@ __metadata: languageName: node linkType: hard +"gaxios@npm:^6.0.2": + version: 6.7.1 + resolution: "gaxios@npm:6.7.1" + dependencies: + extend: "npm:^3.0.2" + https-proxy-agent: "npm:^7.0.1" + is-stream: "npm:^2.0.0" + node-fetch: "npm:^2.6.9" + uuid: "npm:^9.0.1" + checksum: 10/c85599162208884eadee91215ebbfa1faa412551df4044626cb561300e15193726e8f23d63b486533e066dadad130f58ed872a23acab455238d8d48b531a0695 + languageName: node + linkType: hard + "gcp-metadata@npm:^6.1.0": version: 6.1.0 resolution: "gcp-metadata@npm:6.1.0" @@ -25119,6 +23992,13 @@ __metadata: languageName: node linkType: hard +"get-east-asian-width@npm:^1.0.0": + version: 1.3.0 + resolution: "get-east-asian-width@npm:1.3.0" + checksum: 10/8e8e779eb28701db7fdb1c8cab879e39e6ae23f52dadd89c8aed05869671cee611a65d4f8557b83e981428623247d8bc5d0c7a4ef3ea7a41d826e73600112ad8 + languageName: node + linkType: hard + "get-func-name@npm:^2.0.0": version: 2.0.0 resolution: "get-func-name@npm:2.0.0" @@ -25272,15 +24152,6 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.7.2": - version: 4.7.3 - resolution: "get-tsconfig@npm:4.7.3" - dependencies: - resolve-pkg-maps: "npm:^1.0.0" - checksum: 10/7397bb4f8aef936df4d9016555b662dcf5279f3c46428b7c7c1ff5e94ab2b87d018b3dda0f4bc1a28b154d5affd0eac5d014511172c085fd8a9cdff9ea7fe043 - languageName: node - linkType: hard - "get-tsconfig@npm:^4.7.5": version: 4.8.1 resolution: "get-tsconfig@npm:4.8.1" @@ -25520,19 +24391,10 @@ __metadata: languageName: node linkType: hard -"globals@npm:^11.1.0": - version: 11.12.0 - resolution: "globals@npm:11.12.0" - checksum: 10/9f054fa38ff8de8fa356502eb9d2dae0c928217b8b5c8de1f09f5c9b6c8a96d8b9bd3afc49acbcd384a98a81fea713c859e1b09e214c60509517bb8fc2bc13c2 - languageName: node - linkType: hard - -"globals@npm:^13.19.0": - version: 13.20.0 - resolution: "globals@npm:13.20.0" - dependencies: - type-fest: "npm:^0.20.2" - checksum: 10/9df85cde2f0dce6ac9b3a5e08bec109d2f3b38ddd055a83867e0672c55704866d53ce6a4265859fa630624baadd46f50ca38602a13607ad86be853a8c179d3e7 +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 10/03939c8af95c6df5014b137cac83aa909090c3a3985caef06ee9a5a669790877af8698ab38007e4c0186873adc14c0b13764acc754b16a754c216cc56aa5f021 languageName: node linkType: hard @@ -25555,6 +24417,20 @@ __metadata: languageName: node linkType: hard +"globby@npm:14.0.2": + version: 14.0.2 + resolution: "globby@npm:14.0.2" + dependencies: + "@sindresorhus/merge-streams": "npm:^2.1.0" + fast-glob: "npm:^3.3.2" + ignore: "npm:^5.2.4" + path-type: "npm:^5.0.0" + slash: "npm:^5.1.0" + unicorn-magic: "npm:^0.1.0" + checksum: 10/67660da70fc1223f7170c1a62ba6c373385e9e39765d952b6518606dec15ed8c7958e9dae6ba5752a31dbc1e9126f146938b830ad680fe794141734ffc3fbb75 + languageName: node + linkType: hard + "globby@npm:^10.0.1": version: 10.0.2 resolution: "globby@npm:10.0.2" @@ -25599,6 +24475,20 @@ __metadata: languageName: node linkType: hard +"google-auth-library@npm:^9.6.3": + version: 9.15.0 + resolution: "google-auth-library@npm:9.15.0" + dependencies: + base64-js: "npm:^1.3.0" + ecdsa-sig-formatter: "npm:^1.0.11" + gaxios: "npm:^6.1.1" + gcp-metadata: "npm:^6.1.0" + gtoken: "npm:^7.0.0" + jws: "npm:^4.0.0" + checksum: 10/fba2db9732bbf1b3a3a2e2b45131ba8e8aba297377f1c104d0b2ab3386bbc1e02047f20b8a7afca1c6308492da1540104618f1c7b5cd539703552e10399c560e + languageName: node + linkType: hard + "google-gax@npm:^4.0.3": version: 4.3.3 resolution: "google-gax@npm:4.3.3" @@ -26271,6 +25161,22 @@ __metadata: languageName: node linkType: hard +"hosted-git-info@npm:^7.0.0": + version: 7.0.2 + resolution: "hosted-git-info@npm:7.0.2" + dependencies: + lru-cache: "npm:^10.0.1" + checksum: 10/8f085df8a4a637d995f357f48b1e3f6fc1f9f92e82b33fb406415b5741834ed431a510a09141071001e8deea2eee43ce72786463e2aa5e5a70db8648c0eedeab + languageName: node + linkType: hard + +"html-entities@npm:^2.5.2": + version: 2.5.2 + resolution: "html-entities@npm:2.5.2" + checksum: 10/4ec12ebdf2d5ba8192c68e1aef3c1e4a4f36b29246a0a88464fe278a54517d0196d3489af46a3145c7ecacb4fc5fd50497be19eb713b810acab3f0efcf36fdc2 + languageName: node + linkType: hard + "html-escaper@npm:^2.0.0": version: 2.0.2 resolution: "html-escaper@npm:2.0.2" @@ -26528,6 +25434,13 @@ __metadata: languageName: node linkType: hard +"ignore@npm:^5.3.1": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10/cceb6a457000f8f6a50e1196429750d782afce5680dd878aa4221bd79972d68b3a55b4b1458fc682be978f4d3c6a249046aa0880637367216444ab7b014cfc98 + languageName: node + linkType: hard + "immediate@npm:^3.2.3": version: 3.3.0 resolution: "immediate@npm:3.3.0" @@ -26810,6 +25723,15 @@ __metadata: languageName: node linkType: hard +"is-bun-module@npm:^1.0.2": + version: 1.2.1 + resolution: "is-bun-module@npm:1.2.1" + dependencies: + semver: "npm:^7.6.3" + checksum: 10/1c2cbcf1a76991add1b640d2d7fe09848e8697a76f96e1289dff44133a48c97f5dc601d4a66d3f3a86217a77178d72d33d10d0c9e14194e58e70ec8df3eae41a + languageName: node + linkType: hard + "is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.4": version: 1.2.4 resolution: "is-callable@npm:1.2.4" @@ -26855,6 +25777,15 @@ __metadata: languageName: node linkType: hard +"is-core-module@npm:^2.15.1": + version: 2.15.1 + resolution: "is-core-module@npm:2.15.1" + dependencies: + hasown: "npm:^2.0.2" + checksum: 10/77316d5891d5743854bcef2cd2f24c5458fb69fbc9705c12ca17d54a2017a67d0693bbf1ba8c77af376c0eef6bf6d1b27a4ab08e4db4e69914c3789bdf2ceec5 + languageName: node + linkType: hard + "is-core-module@npm:^2.8.1": version: 2.9.0 resolution: "is-core-module@npm:2.9.0" @@ -27017,6 +25948,13 @@ __metadata: languageName: node linkType: hard +"is-interactive@npm:^2.0.0": + version: 2.0.0 + resolution: "is-interactive@npm:2.0.0" + checksum: 10/e8d52ad490bed7ae665032c7675ec07732bbfe25808b0efbc4d5a76b1a1f01c165f332775c63e25e9a03d319ebb6b24f571a9e902669fc1e40b0a60b5be6e26c + languageName: node + linkType: hard + "is-lambda@npm:^1.0.1": version: 1.0.1 resolution: "is-lambda@npm:1.0.1" @@ -27085,7 +26023,7 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.2, is-path-inside@npm:^3.0.3": +"is-path-inside@npm:^3.0.2": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" checksum: 10/abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 @@ -27257,6 +26195,20 @@ __metadata: languageName: node linkType: hard +"is-unicode-supported@npm:^1.3.0": + version: 1.3.0 + resolution: "is-unicode-supported@npm:1.3.0" + checksum: 10/20a1fc161afafaf49243551a5ac33b6c4cf0bbcce369fcd8f2951fbdd000c30698ce320de3ee6830497310a8f41880f8066d440aa3eb0a853e2aa4836dd89abc + languageName: node + linkType: hard + +"is-unicode-supported@npm:^2.0.0": + version: 2.1.0 + resolution: "is-unicode-supported@npm:2.1.0" + checksum: 10/f254e3da6b0ab1a57a94f7273a7798dd35d1d45b227759f600d0fa9d5649f9c07fa8d3c8a6360b0e376adf916d151ec24fc9a50c5295c58bae7ca54a76a063f9 + languageName: node + linkType: hard + "is-url@npm:^1.2.4": version: 1.2.4 resolution: "is-url@npm:1.2.4" @@ -28100,7 +27052,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:4.1.0, js-yaml@npm:^4.1.0": +"js-yaml@npm:4.1.0, js-yaml@npm:^4.0.0, js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" dependencies: @@ -28267,6 +27219,17 @@ __metadata: languageName: node linkType: hard +"json5@npm:^1.0.2": + version: 1.0.2 + resolution: "json5@npm:1.0.2" + dependencies: + minimist: "npm:^1.2.0" + bin: + json5: lib/cli.js + checksum: 10/a78d812dbbd5642c4f637dd130954acfd231b074965871c3e28a5bbd571f099d623ecf9161f1960c4ddf68e0cc98dee8bebfdb94a71ad4551f85a1afc94b63f6 + languageName: node + linkType: hard + "json5@npm:^2.1.2, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" @@ -28276,6 +27239,13 @@ __metadata: languageName: node linkType: hard +"jsonc-parser@npm:3.3.1": + version: 3.3.1 + resolution: "jsonc-parser@npm:3.3.1" + checksum: 10/9b0dc391f20b47378f843ef1e877e73ec652a5bdc3c5fa1f36af0f119a55091d147a86c1ee86a232296f55c929bba174538c2bf0312610e0817a22de131cc3f4 + languageName: node + linkType: hard + "jsonfile@npm:^2.1.0": version: 2.4.0 resolution: "jsonfile@npm:2.4.0" @@ -28430,7 +27400,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.3": +"keyv@npm:^4.5.3, keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -29004,6 +27974,16 @@ __metadata: languageName: node linkType: hard +"log-symbols@npm:^6.0.0": + version: 6.0.0 + resolution: "log-symbols@npm:6.0.0" + dependencies: + chalk: "npm:^5.3.0" + is-unicode-supported: "npm:^1.3.0" + checksum: 10/510cdda36700cbcd87a2a691ea08d310a6c6b449084018f7f2ec4f732ca5e51b301ff1327aadd96f53c08318e616276c65f7fe22f2a16704fb0715d788bc3c33 + languageName: node + linkType: hard + "log-update@npm:^4.0.0": version: 4.0.0 resolution: "log-update@npm:4.0.0" @@ -29080,7 +28060,7 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.2.0, lru-cache@npm:^10.4.3": +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0, lru-cache@npm:^10.4.3": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" checksum: 10/e6e90267360476720fa8e83cc168aa2bf0311f3f2eea20a6ba78b90a885ae72071d9db132f40fda4129c803e7dcec3a6b6a6fbb44ca90b081630b810b5d6a41a @@ -29667,6 +28647,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:9.0.5, minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10/dd6a8927b063aca6d910b119e1f2df6d2ce7d36eab91de83167dd136bb85e1ebff97b0d3de1cb08bd1f7e018ca170b4962479fefab5b2a69e2ae12cb2edc8348 + languageName: node + linkType: hard + "minimatch@npm:^5.0.1": version: 5.1.0 resolution: "minimatch@npm:5.1.0" @@ -29685,15 +28674,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.4": - version: 9.0.5 - resolution: "minimatch@npm:9.0.5" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10/dd6a8927b063aca6d910b119e1f2df6d2ce7d36eab91de83167dd136bb85e1ebff97b0d3de1cb08bd1f7e018ca170b4962479fefab5b2a69e2ae12cb2edc8348 - languageName: node - linkType: hard - "minimist-options@npm:^4.0.2": version: 4.1.0 resolution: "minimist-options@npm:4.1.0" @@ -30615,6 +29595,18 @@ __metadata: languageName: node linkType: hard +"npm-package-arg@npm:11.0.3": + version: 11.0.3 + resolution: "npm-package-arg@npm:11.0.3" + dependencies: + hosted-git-info: "npm:^7.0.0" + proc-log: "npm:^4.0.0" + semver: "npm:^7.3.5" + validate-npm-package-name: "npm:^5.0.0" + checksum: 10/bacc863907edf98940286edc2fd80327901c1e8b34426d538cdc708ed66bc6567f06d742d838eaf35db6804347bb4ba56ca9cef032c4b52743b33e7a22a2678e + languageName: node + linkType: hard + "npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" @@ -30836,6 +29828,17 @@ __metadata: languageName: node linkType: hard +"object.groupby@npm:^1.0.3": + version: 1.0.3 + resolution: "object.groupby@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + checksum: 10/44cb86dd2c660434be65f7585c54b62f0425b0c96b5c948d2756be253ef06737da7e68d7106e35506ce4a44d16aa85a413d11c5034eb7ce5579ec28752eb42d0 + languageName: node + linkType: hard + "object.values@npm:^1.1.6, object.values@npm:^1.2.0": version: 1.2.0 resolution: "object.values@npm:1.2.0" @@ -30994,6 +29997,23 @@ __metadata: languageName: node linkType: hard +"ora@npm:8.0.1": + version: 8.0.1 + resolution: "ora@npm:8.0.1" + dependencies: + chalk: "npm:^5.3.0" + cli-cursor: "npm:^4.0.0" + cli-spinners: "npm:^2.9.2" + is-interactive: "npm:^2.0.0" + is-unicode-supported: "npm:^2.0.0" + log-symbols: "npm:^6.0.0" + stdin-discarder: "npm:^0.2.1" + string-width: "npm:^7.0.0" + strip-ansi: "npm:^7.1.0" + checksum: 10/3d37bb3f53e965e5176004af319f82feef7323ee0b2428db5ee6f689b9b9ba939d7b1e81691d4614333c4fb9e294790eb049db9c1e990b14b9bbe150c6f09993 + languageName: node + linkType: hard + "ora@npm:^5.4.1": version: 5.4.1 resolution: "ora@npm:5.4.1" @@ -31093,7 +30113,7 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^3.0.2, p-limit@npm:^3.1.0": +"p-limit@npm:^3.0.1, p-limit@npm:^3.0.2, p-limit@npm:^3.1.0": version: 3.1.0 resolution: "p-limit@npm:3.1.0" dependencies: @@ -31393,6 +30413,13 @@ __metadata: languageName: node linkType: hard +"path-type@npm:^5.0.0": + version: 5.0.0 + resolution: "path-type@npm:5.0.0" + checksum: 10/15ec24050e8932c2c98d085b72cfa0d6b4eeb4cbde151a0a05726d8afae85784fc5544f733d8dfc68536587d5143d29c0bd793623fad03d7e61cc00067291cd5 + languageName: node + linkType: hard + "pathe@npm:^1.1.1, pathe@npm:^1.1.2": version: 1.1.2 resolution: "pathe@npm:1.1.2" @@ -31928,6 +30955,13 @@ __metadata: languageName: node linkType: hard +"proc-log@npm:^4.0.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 10/4e1394491b717f6c1ade15c570ecd4c2b681698474d3ae2d303c1e4b6ab9455bd5a81566211e82890d5a5ae9859718cc6954d5150bb18b09b72ecb297beae90a + languageName: node + linkType: hard + "process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" @@ -31998,7 +31032,7 @@ __metadata: languageName: node linkType: hard -"prompts@npm:^2.0.1, prompts@npm:^2.4.0, prompts@npm:^2.4.2": +"prompts@npm:2.4.2, prompts@npm:^2.0.1, prompts@npm:^2.4.0, prompts@npm:^2.4.2": version: 2.4.2 resolution: "prompts@npm:2.4.2" dependencies: @@ -32246,6 +31280,13 @@ __metadata: languageName: node linkType: hard +"pure-rand@npm:^6.1.0": + version: 6.1.0 + resolution: "pure-rand@npm:6.1.0" + checksum: 10/256aa4bcaf9297256f552914e03cbdb0039c8fe1db11fa1e6d3f80790e16e563eb0a859a1e61082a95e224fc0c608661839439f8ecc6a3db4e48d46d99216ee4 + languageName: node + linkType: hard + "pvtsutils@npm:^1.3.2": version: 1.3.2 resolution: "pvtsutils@npm:1.3.2" @@ -32870,6 +31911,16 @@ __metadata: languageName: node linkType: hard +"read-yaml-file@npm:2.1.0": + version: 2.1.0 + resolution: "read-yaml-file@npm:2.1.0" + dependencies: + js-yaml: "npm:^4.0.0" + strip-bom: "npm:^4.0.0" + checksum: 10/52765eb183e79466f51eebeb19b933cc0f0e907052d062d67300b97e79910064a24b370cdb0b5dd8b05afff3d0ec57282670fd9070dc608e13b11820ac79183d + languageName: node + linkType: hard + "read-yaml-file@npm:^1.1.0": version: 1.1.0 resolution: "read-yaml-file@npm:1.1.0" @@ -33280,13 +32331,6 @@ __metadata: languageName: node linkType: hard -"requireindex@npm:^1.1.0": - version: 1.2.0 - resolution: "requireindex@npm:1.2.0" - checksum: 10/266d1cb31f6cbc4b6cf2e898f5bbc45581f7919bcf61bba5c45d0adb69b722b9ff5a13727be3350cde4520d7cd37f39df45d58a29854baaa4552cd6b05ae4a1a - languageName: node - linkType: hard - "resolve-alpn@npm:^1.2.0": version: 1.2.1 resolution: "resolve-alpn@npm:1.2.1" @@ -33367,7 +32411,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.2, resolve@npm:^1.22.8": +"resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.2, resolve@npm:^1.22.4, resolve@npm:^1.22.8": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -33422,7 +32466,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.1.7#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.2#optional!builtin, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin": +"resolve@patch:resolve@npm%3A^1.1.7#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.2#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -33476,6 +32520,16 @@ __metadata: languageName: node linkType: hard +"restore-cursor@npm:^4.0.0": + version: 4.0.0 + resolution: "restore-cursor@npm:4.0.0" + dependencies: + onetime: "npm:^5.1.0" + signal-exit: "npm:^3.0.2" + checksum: 10/5b675c5a59763bf26e604289eab35711525f11388d77f409453904e1e69c0d37ae5889295706b2c81d23bd780165084d040f9b68fffc32cc921519031c4fa4af + languageName: node + linkType: hard + "retry-request@npm:^7.0.0": version: 7.0.2 resolution: "retry-request@npm:7.0.2" @@ -34024,6 +33078,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:7.6.3, semver@npm:^7.3.8, semver@npm:^7.5.0, semver@npm:^7.5.1, semver@npm:^7.6.0, semver@npm:^7.6.3": + version: 7.6.3 + resolution: "semver@npm:7.6.3" + bin: + semver: bin/semver.js + checksum: 10/36b1fbe1a2b6f873559cd57b238f1094a053dbfd997ceeb8757d79d1d2089c56d1321b9f1069ce263dc64cfa922fa1d2ad566b39426fe1ac6c723c1487589e10 + languageName: node + linkType: hard + "semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.7.0": version: 5.7.1 resolution: "semver@npm:5.7.1" @@ -34062,15 +33125,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.8, semver@npm:^7.5.0, semver@npm:^7.5.1": - version: 7.6.3 - resolution: "semver@npm:7.6.3" - bin: - semver: bin/semver.js - checksum: 10/36b1fbe1a2b6f873559cd57b238f1094a053dbfd997ceeb8757d79d1d2089c56d1321b9f1069ce263dc64cfa922fa1d2ad566b39426fe1ac6c723c1487589e10 - languageName: node - linkType: hard - "semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" @@ -34423,6 +33477,13 @@ __metadata: languageName: node linkType: hard +"slash@npm:^5.1.0": + version: 5.1.0 + resolution: "slash@npm:5.1.0" + checksum: 10/2c41ec6fb1414cd9bba0fa6b1dd00e8be739e3fe85d079c69d4b09ca5f2f86eafd18d9ce611c0c0f686428638a36c272a6ac14799146a8295f259c10cc45cde4 + languageName: node + linkType: hard + "slice-ansi@npm:^3.0.0": version: 3.0.0 resolution: "slice-ansi@npm:3.0.0" @@ -35001,6 +34062,13 @@ __metadata: languageName: node linkType: hard +"stdin-discarder@npm:^0.2.1": + version: 0.2.2 + resolution: "stdin-discarder@npm:0.2.2" + checksum: 10/642ffd05bd5b100819d6b24a613d83c6e3857c6de74eb02fc51506fa61dc1b0034665163831873868157c4538d71e31762bcf319be86cea04c3aba5336470478 + languageName: node + linkType: hard + "stealthy-require@npm:^1.1.1": version: 1.1.1 resolution: "stealthy-require@npm:1.1.1" @@ -35167,6 +34235,17 @@ __metadata: languageName: node linkType: hard +"string-width@npm:^7.0.0": + version: 7.2.0 + resolution: "string-width@npm:7.2.0" + dependencies: + emoji-regex: "npm:^10.3.0" + get-east-asian-width: "npm:^1.0.0" + strip-ansi: "npm:^7.1.0" + checksum: 10/42f9e82f61314904a81393f6ef75b832c39f39761797250de68c041d8ba4df2ef80db49ab6cd3a292923a6f0f409b8c9980d120f7d32c820b4a8a84a2598a295 + languageName: node + linkType: hard + "string.prototype.matchall@npm:^4.0.11": version: 4.0.11 resolution: "string.prototype.matchall@npm:4.0.11" @@ -35349,6 +34428,15 @@ __metadata: languageName: node linkType: hard +"strip-ansi@npm:^7.1.0": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 10/475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 + languageName: node + linkType: hard + "strip-bom@npm:^3.0.0": version: 3.0.0 resolution: "strip-bom@npm:3.0.0" @@ -35609,6 +34697,43 @@ __metadata: languageName: node linkType: hard +"syncpack@npm:^13.0.0": + version: 13.0.0 + resolution: "syncpack@npm:13.0.0" + dependencies: + "@effect/schema": "npm:0.71.1" + chalk: "npm:5.3.0" + chalk-template: "npm:1.1.0" + commander: "npm:12.1.0" + cosmiconfig: "npm:9.0.0" + effect: "npm:3.6.5" + enquirer: "npm:2.4.1" + fast-check: "npm:3.21.0" + globby: "npm:14.0.2" + jsonc-parser: "npm:3.3.1" + minimatch: "npm:9.0.5" + npm-package-arg: "npm:11.0.3" + ora: "npm:8.0.1" + prompts: "npm:2.4.2" + read-yaml-file: "npm:2.1.0" + semver: "npm:7.6.3" + tightrope: "npm:0.2.0" + ts-toolbelt: "npm:9.6.0" + bin: + syncpack: dist/bin.js + syncpack-fix-mismatches: dist/bin-fix-mismatches/index.js + syncpack-format: dist/bin-format/index.js + syncpack-lint: dist/bin-lint/index.js + syncpack-lint-semver-ranges: dist/bin-lint-semver-ranges/index.js + syncpack-list: dist/bin-list/index.js + syncpack-list-mismatches: dist/bin-list-mismatches/index.js + syncpack-prompt: dist/bin-prompt/index.js + syncpack-set-semver-ranges: dist/bin-set-semver-ranges/index.js + syncpack-update: dist/bin-update/index.js + checksum: 10/c80f60faaad640f38de4e1fb5e7daf5dac62963def211b7b3989186c503dec8800c197d3051798553998331c0b0e05ab4b96dd765cd51c7c6cd3651f87c559ed + languageName: node + linkType: hard + "system-architecture@npm:^0.1.0": version: 0.1.0 resolution: "system-architecture@npm:0.1.0" @@ -35694,6 +34819,13 @@ __metadata: languageName: node linkType: hard +"tapable@npm:^2.2.0": + version: 2.2.1 + resolution: "tapable@npm:2.2.1" + checksum: 10/1769336dd21481ae6347611ca5fca47add0962fd8e80466515032125eca0084a4f0ede11e65341b9c0018ef4e1cf1ad820adbb0fba7cc99865c6005734000b0a + languageName: node + linkType: hard + "tar-fs@npm:^2.0.0, tar-fs@npm:^2.1.1": version: 2.1.1 resolution: "tar-fs@npm:2.1.1" @@ -35936,6 +35068,13 @@ __metadata: languageName: node linkType: hard +"tightrope@npm:0.2.0": + version: 0.2.0 + resolution: "tightrope@npm:0.2.0" + checksum: 10/b57a6dec1a83d1d9b9395bca21f0b2dc4ff84d97a2302f43af240d312573bc04327e8e40394b4c2ac7172993b76ba31b34d0295b79f4f8abe9195a051782bff6 + languageName: node + linkType: hard + "timed-out@npm:^4.0.0, timed-out@npm:^4.0.1": version: 4.0.1 resolution: "timed-out@npm:4.0.1" @@ -36089,6 +35228,15 @@ __metadata: languageName: node linkType: hard +"ts-api-utils@npm:^1.3.0": + version: 1.4.1 + resolution: "ts-api-utils@npm:1.4.1" + peerDependencies: + typescript: ">=4.2.0" + checksum: 10/2f32698ed1c06e57d934704ff2579a905895441ef0a29f732242d3d3f651abd5d09610f702c656e85b73457582a1ded43adeef82e9f6d665ae0fb66497cf39f6 + languageName: node + linkType: hard + "ts-command-line-args@npm:^2.2.0": version: 2.3.1 resolution: "ts-command-line-args@npm:2.3.1" @@ -36223,7 +35371,26 @@ __metadata: languageName: node linkType: hard -"tslib@npm:1.14.1, tslib@npm:^1.11.1, tslib@npm:^1.13.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3": +"ts-toolbelt@npm:9.6.0": + version: 9.6.0 + resolution: "ts-toolbelt@npm:9.6.0" + checksum: 10/2c2dea2631dbd7372a79cccc6d09a377a6ca2f319f767fd239d2e312cd1d9165a90f8c1777a047227bfdcda6aeba3addbadce88fdfc7f43caf4534d385a43c82 + languageName: node + linkType: hard + +"tsconfig-paths@npm:^3.15.0": + version: 3.15.0 + resolution: "tsconfig-paths@npm:3.15.0" + dependencies: + "@types/json5": "npm:^0.0.29" + json5: "npm:^1.0.2" + minimist: "npm:^1.2.6" + strip-bom: "npm:^3.0.0" + checksum: 10/2041beaedc6c271fc3bedd12e0da0cc553e65d030d4ff26044b771fac5752d0460944c0b5e680f670c2868c95c664a256cec960ae528888db6ded83524e33a14 + languageName: node + linkType: hard + +"tslib@npm:1.14.1, tslib@npm:^1.11.1, tslib@npm:^1.13.0, tslib@npm:^1.9.0, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: 10/7dbf34e6f55c6492637adb81b555af5e3b4f9cc6b998fb440dac82d3b42bdc91560a35a5fb75e20e24a076c651438234da6743d139e4feabf0783f3cdfe1dddb @@ -36237,7 +35404,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.4.0, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0": +"tslib@npm:2.4.0, tslib@npm:^2.1.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0": version: 2.4.0 resolution: "tslib@npm:2.4.0" checksum: 10/d8379e68b36caf082c1905ec25d17df8261e1d68ddc1abfd6c91158a064f6e4402039ae7c02cf4c81d12e3a2a2c7cd8ea2f57b233eb80136a2e3e7279daf2911 @@ -36272,17 +35439,6 @@ __metadata: languageName: node linkType: hard -"tsutils@npm:^3.21.0": - version: 3.21.0 - resolution: "tsutils@npm:3.21.0" - dependencies: - tslib: "npm:^1.8.1" - peerDependencies: - typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - checksum: 10/ea036bec1dd024e309939ffd49fda7a351c0e87a1b8eb049570dd119d447250e2c56e0e6c00554e8205760e7417793fdebff752a46e573fbe07d4f375502a5b2 - languageName: node - linkType: hard - "tsx@npm:^4.19.1": version: 4.19.1 resolution: "tsx@npm:4.19.1" @@ -36299,22 +35455,6 @@ __metadata: languageName: node linkType: hard -"tsx@npm:^4.7.1": - version: 4.7.1 - resolution: "tsx@npm:4.7.1" - dependencies: - esbuild: "npm:~0.19.10" - fsevents: "npm:~2.3.3" - get-tsconfig: "npm:^4.7.2" - dependenciesMeta: - fsevents: - optional: true - bin: - tsx: dist/cli.mjs - checksum: 10/3a462b595f31ae58b31f9c6e8c450577dc87660b1225012bd972b6b58d7d2f6c4034728763ebc53bb731acff68de8b0fa50586e4c1ec4c086226f1788ccf9b7d - languageName: node - linkType: hard - "tty-table@npm:^4.1.5": version: 4.2.3 resolution: "tty-table@npm:4.2.3" @@ -36857,6 +35997,13 @@ __metadata: languageName: node linkType: hard +"unicorn-magic@npm:^0.1.0": + version: 0.1.0 + resolution: "unicorn-magic@npm:0.1.0" + checksum: 10/9b4d0e9809807823dc91d0920a4a4c0cff2de3ebc54ee87ac1ee9bc75eafd609b09d1f14495e0173aef26e01118706196b6ab06a75fe0841028b3983a8af313f + languageName: node + linkType: hard + "unique-filename@npm:^1.1.1": version: 1.1.1 resolution: "unique-filename@npm:1.1.1" @@ -37264,7 +36411,7 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^8.3.2": +"uuid@npm:^8.0.0, uuid@npm:^8.3.2": version: 8.3.2 resolution: "uuid@npm:8.3.2" bin: @@ -37319,6 +36466,13 @@ __metadata: languageName: node linkType: hard +"validate-npm-package-name@npm:^5.0.0": + version: 5.0.1 + resolution: "validate-npm-package-name@npm:5.0.1" + checksum: 10/0d583a1af23aeffea7748742cf22b6802458736fb8b60323ba5949763824d46f796474b0e1b9206beb716f9d75269e19dbd7795d6b038b29d561be95dd827381 + languageName: node + linkType: hard + "valtio@npm:1.11.2": version: 1.11.2 resolution: "valtio@npm:1.11.2" @@ -37362,7 +36516,7 @@ __metadata: languageName: node linkType: hard -"viem@npm:^2.1.1, viem@npm:^2.21.41, viem@npm:^2.21.45": +"viem@npm:^2.1.1, viem@npm:^2.21.45": version: 2.21.45 resolution: "viem@npm:2.21.45" dependencies: @@ -38343,7 +37497,7 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^6.0.1, wrap-ansi@npm:^6.2.0": +"wrap-ansi@npm:^6.2.0": version: 6.2.0 resolution: "wrap-ansi@npm:6.2.0" dependencies: