From e3b97c4555cf90f48881d5476e2ca706e88cb6fe Mon Sep 17 00:00:00 2001 From: Paul Balaji <10051819+paulbalaji@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:25:36 +0000 Subject: [PATCH] feat: detangle chainId / domainId EVM assumptions (#4798) ### Description Detangle assumption that chainId == domainId for EVM chains. - required to support new domain IDs for sept26 chain deploy batch https://github.com/hyperlane-xyz/hyperlane-registry/pull/352 Domain IDs and Chain Names are still unique, but chainId is no longer guaranteed to be a unique identifier. - required to support shadow lumia (current deployment) + prod lumia (new deployment with different domain id) Touches: - evm core/ism/hook/warp modules - multiprovider + chain metadata manager - safe service - renaming `ChainNameOrId` to `ChainNameOrDomain` (where bulk of the diff comes from) ### Drive-by changes - ~~add name of a `chain` to `Annotated` types, since chain ID on a populated transaction is a looser tie to a chain than `domainId` or `chain`~~ - ~~simplify multiprovider.sendtransaction, since `chain` is provided with the annotated transaction~~ - ensure domainId is not optional in the chain metadata schema - requires registry fix https://github.com/hyperlane-xyz/hyperlane-registry/pull/357 - update ethers v5 json rpc submitter to require a `chain` as well ### Related issues - mostly redoes work from https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/4599 - will have to be rechecked after zksync changes are also in ### Backward compatibility no ### Testing ci, manual --------- Signed-off-by: pbio <10051819+paulbalaji@users.noreply.github.com> --- .changeset/thirty-adults-camp.md | 8 ++ .registryrc | 2 +- rust/main/config/mainnet_config.json | 134 +++++++++--------- .../impersonated-account-strategy.yaml | 1 + .../strategy/json-rpc-chain-strategy.yaml | 2 + .../submit/strategy/json-rpc-strategy.yaml | 1 + typescript/cli/src/config/submit.ts | 28 +--- typescript/cli/src/deploy/warp.ts | 13 +- typescript/cli/src/submit/submit.ts | 4 +- typescript/cli/src/tests/commands/helpers.ts | 8 +- .../cli/src/tests/warp-apply.e2e-test.ts | 18 +-- .../funding/fund-keys-from-deployer.ts | 7 +- .../generate-scraper-add-domain-sql.sh | 5 +- typescript/infra/scripts/helloworld/kathy.ts | 16 ++- typescript/infra/src/utils/safe.ts | 4 +- typescript/sdk/src/contracts/contracts.ts | 3 +- .../sdk/src/core/AbstractHyperlaneModule.ts | 2 +- .../src/core/EvmCoreModule.hardhat-test.ts | 2 +- typescript/sdk/src/core/EvmCoreModule.ts | 17 +-- typescript/sdk/src/hook/EvmHookModule.ts | 40 +++--- typescript/sdk/src/index.ts | 1 + typescript/sdk/src/ism/EvmIsmModule.ts | 15 +- typescript/sdk/src/ism/HyperlaneIsmFactory.ts | 21 ++- .../sdk/src/metadata/ChainMetadataManager.ts | 100 +++++++------ .../sdk/src/metadata/chainMetadataTypes.ts | 4 +- typescript/sdk/src/providers/MultiProvider.ts | 16 +-- typescript/sdk/src/providers/ProviderType.ts | 6 +- .../submitter/TxSubmitterInterface.ts | 4 +- .../submitter/builder/TxSubmitterBuilder.ts | 4 +- .../ethersV5/EV5GnosisSafeTxBuilder.ts | 3 +- .../ethersV5/EV5GnosisSafeTxSubmitter.ts | 8 +- .../EV5ImpersonatedAccountTxSubmitter.ts | 2 +- .../ethersV5/EV5JsonRpcTxSubmitter.ts | 16 ++- .../submitter/ethersV5/schemas.test.ts | 4 +- .../submitter/ethersV5/schemas.ts | 9 +- .../transactions/submitter/ethersV5/types.ts | 4 + .../transactions/submitter/schemas.ts | 2 + .../transformer/TxTransformerInterface.ts | 6 +- .../EV5InterchainAccountTxTransformer.ts | 21 +-- .../sdk/src/token/EvmERC20WarpModule.ts | 19 +-- typescript/sdk/src/types.ts | 6 +- typescript/sdk/src/utils/gnosisSafe.js | 15 +- typescript/sdk/src/utils/transactions.ts | 26 ++++ typescript/utils/src/index.ts | 1 + typescript/utils/src/types.ts | 1 + .../widgets/src/chains/ChainAddMenu.tsx | 9 +- .../widgets/src/chains/ChainSearchMenu.tsx | 2 +- 47 files changed, 358 insertions(+), 282 deletions(-) create mode 100644 .changeset/thirty-adults-camp.md create mode 100644 typescript/sdk/src/utils/transactions.ts diff --git a/.changeset/thirty-adults-camp.md b/.changeset/thirty-adults-camp.md new file mode 100644 index 000000000..695b67939 --- /dev/null +++ b/.changeset/thirty-adults-camp.md @@ -0,0 +1,8 @@ +--- +'@hyperlane-xyz/utils': major +'@hyperlane-xyz/cli': major +'@hyperlane-xyz/sdk': major +'@hyperlane-xyz/widgets': major +--- + +Detangle assumption that chainId == domainId for EVM chains. Domain IDs and Chain Names are still unique, but chainId is no longer guaranteed to be a unique identifier. Domain ID is no longer an optional field and is now required for all chain metadata. diff --git a/.registryrc b/.registryrc index 612062b3f..cacb68b67 100644 --- a/.registryrc +++ b/.registryrc @@ -1 +1 @@ -14836804e543a64cd3747cd6bbea6e245b6353b1 +1ea2849e2fc1e750bac67e35827c9d682c7fd4bf diff --git a/rust/main/config/mainnet_config.json b/rust/main/config/mainnet_config.json index b0404fee4..2217fda56 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": "0x4e1d2cdB48A2C2912b11801Eb1F1d5007474cA43", + "interchainSecurityModule": "0x259Da872714f84B74B4473fab45e9839f3453a40", "isTestnet": false, "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x811808Dd29ba8B0FC6C0ec0b5537035E59745162", @@ -100,7 +100,7 @@ "interchainAccountIsm": "0x2A7574358Ec53522CE2452887661AB4c86F7d400", "interchainAccountRouter": "0x91874Dbed74925dFe6059B90385EEb90DdE0B2E6", "interchainGasPaymaster": "0x3b6044acd6767f017e99318AA6Ef93b7B06A5a22", - "interchainSecurityModule": "0x50d0b0E27B8B93119618f053A623886116dd3b6d", + "interchainSecurityModule": "0xDeeE785e0b3De36A7F1aF5d0A0a1F86e7c356a58", "mailbox": "0x979Ca5202784112f4738403dBec5D0F3B9daabB9", "merkleTreeHook": "0x748040afB89B8FdBb992799808215419d36A0930", "name": "arbitrum", @@ -172,7 +172,7 @@ "interchainAccountIsm": "0x27a3233c05C1Df7c163123301D14bE9349E3Cb48", "interchainAccountRouter": "0xa82a0227e6d6db53AF4B264A852bfF91C6504a51", "interchainGasPaymaster": "0x95519ba800BBd0d34eeAE026fEc620AD978176C0", - "interchainSecurityModule": "0xbc803Da34A88E5f6B50dfc0CC9D924d9865c91C5", + "interchainSecurityModule": "0x8Ea008E1E39D9770312b9b516D1f0C41DD3feCb3", "mailbox": "0xFf06aFcaABaDDd1fb08371f9ccA15D73D51FeBD6", "merkleTreeHook": "0x84eea61D679F42D92145fA052C89900CBAccE95A", "name": "avalanche", @@ -245,7 +245,7 @@ "interchainAccountIsm": "0x223F7D3f27E6272266AE4B5B91Fd5C7A2d798cD8", "interchainAccountRouter": "0x4767D22117bBeeb295413000B620B93FD8522d53", "interchainGasPaymaster": "0xc3F23848Ed2e04C0c6d41bd7804fa8f89F940B94", - "interchainSecurityModule": "0xB7fcb4665ace2B0d36fd92D26b4a8B516c0bFe5F", + "interchainSecurityModule": "0x875a788e4A887848ac0B5d4431125Ecd5cdB3dAe", "mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", "merkleTreeHook": "0x19dc38aeae620380430C200a6E990D5Af5480117", "name": "base", @@ -316,7 +316,7 @@ "interchainAccountIsm": "0xe93f2f409ad8B5000431D234472973fe848dcBEC", "interchainAccountRouter": "0x2f4Eb04189e11Af642237Da62d163Ab714614498", "interchainGasPaymaster": "0xB3fCcD379ad66CED0c91028520C64226611A48c9", - "interchainSecurityModule": "0xECa4a584E91867a72cd036DB7Db22Ad894a197B7", + "interchainSecurityModule": "0x518C62D6771b7a6b393E429ba5f9025a6F485301", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0xC9B8ea6230d6687a4b13fD3C0b8f0Ec607B26465", "name": "blast", @@ -384,7 +384,7 @@ "interchainAccountIsm": "0x451dF8AB0936D85526D816f0b4dCaDD934A034A4", "interchainAccountRouter": "0x5C02157068a52cEcfc98EDb6115DE6134EcB4764", "interchainGasPaymaster": "0x62B7592C1B6D1E43f4630B8e37f4377097840C05", - "interchainSecurityModule": "0x93E3e6CA295803417212421785606B1F7dDeaD8f", + "interchainSecurityModule": "0x28Df661E61e2f4e7a35F3a554094191e64cd6E5A", "mailbox": "0x8358D8291e3bEDb04804975eEa0fe9fe0fAfB147", "merkleTreeHook": "0x781bE492F1232E66990d83a9D3AC3Ec26f56DAfB", "name": "bob", @@ -450,7 +450,7 @@ "interchainAccountIsm": "0x9e22945bE593946618383B108CC5bce09eBA4C26", "interchainAccountRouter": "0x32A07c1B7a7fe8D4A0e44B0181873aB9d64C16c1", "interchainGasPaymaster": "0x78E25e7f84416e69b9339B0A6336EB6EFfF6b451", - "interchainSecurityModule": "0xA0506B5b12770494740A4a7cc86C9A36Dc1Fc6Dc", + "interchainSecurityModule": "0x5BC506C2C04dfDe5b45cbF47f05b4373D65832e4", "mailbox": "0x2971b9Aec44bE4eb673DF1B88cDB57b96eefe8a4", "merkleTreeHook": "0xFDb9Cd5f9daAA2E4474019405A328a88E7484f26", "name": "bsc", @@ -531,7 +531,7 @@ "interchainAccountIsm": "0xB732c83aeE29596E3163Da2260710eAB67Bc0B29", "interchainAccountRouter": "0x27a6cAe33378bB6A6663b382070427A01fc9cB37", "interchainGasPaymaster": "0x571f1435613381208477ac5d6974310d88AC7cB7", - "interchainSecurityModule": "0xa6f4835940dbA46E295076D0CD0411349C33789f", + "interchainSecurityModule": "0xB9aD1ccE862444B5C3bad009ef500AD3680940Da", "mailbox": "0x50da3B3907A08a24fe4999F4Dcf337E8dC7954bb", "merkleTreeHook": "0x04dB778f05854f26E67e0a66b740BBbE9070D366", "name": "celo", @@ -596,7 +596,7 @@ "interchainAccountIsm": "0x4Eb82Ee35b0a1c1d776E3a3B547f9A9bA6FCC9f2", "interchainAccountRouter": "0xEF9A332Ec1fD233Bf9344A58be56ff9E104B4f60", "interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503", - "interchainSecurityModule": "0x05f6BAa16F1aCf7b19c4A09E019D856c10ab8355", + "interchainSecurityModule": "0x77e9F81405DBC1eBeDA93f23aB4a339452d2AD9D", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD", "name": "cheesechain", @@ -659,7 +659,7 @@ "from": 4842212 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0x9A746C4BC2bE7E657A3469f0a0DAA1dE517b8514", + "interchainSecurityModule": "0xcC5534C4665D9BD93B377F56eC4c09Fdee87AD30", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "cyber", @@ -726,7 +726,7 @@ "from": 23783929 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0x168E9C1481F50E66Cc5F5E24b04eBf7071629c4E", + "interchainSecurityModule": "0xF6C78dDeeb0Ef1682bC020787ecA835C5F353701", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "degenchain", @@ -839,7 +839,7 @@ "interchainAccountIsm": "0xCeafc098e5c3c7768b9229Be2FEC275862A81Abd", "interchainAccountRouter": "0xed9a722c543883FB7e07E78F3879762DE09eA7D5", "interchainGasPaymaster": "0xB30EAB08aa87138D57168D0e236850A530f49921", - "interchainSecurityModule": "0x094120BaC576aD7D88ec6893C9B220a0e64923E9", + "interchainSecurityModule": "0x702A7e81b3625AA02b365Aa95A7123a9EB31012f", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xC831271c1fB212012811a91Dd43e5926C1020563", "name": "endurance", @@ -910,7 +910,7 @@ "interchainAccountIsm": "0x292C614ED53DaaDBf971521bc2C652d1ca51cB47", "interchainAccountRouter": "0x5E532F7B610618eE73C2B462978e94CB1F7995Ce", "interchainGasPaymaster": "0x9e6B1022bE9BBF5aFd152483DAD9b88911bC8611", - "interchainSecurityModule": "0x23d160e4474Ce011829c71Bf1bCaA40F0b5612D5", + "interchainSecurityModule": "0xc7b5BA9EcedcFd7D250Cf7df19558D7dd0d06ECc", "mailbox": "0xc005dc82818d67AF737725bD4bf75435d065D239", "merkleTreeHook": "0x48e6c30B97748d1e2e03bf3e9FbE3890ca5f8CCA", "name": "ethereum", @@ -979,7 +979,7 @@ "interchainAccountIsm": "0x7C012DCA02C42cfA3Fd7Da3B0ED7234B52AE68eF", "interchainAccountRouter": "0xbed53B5C5BCE9433f25A2A702e6df13E22d84Ae9", "interchainGasPaymaster": "0x2Fca7f6eC3d4A0408900f2BB30004d4616eE985E", - "interchainSecurityModule": "0x8B497dff421844Bb0882E0C495d0851D4461675C", + "interchainSecurityModule": "0xC8e75e117E1dBC43880ac6c85e820844Dd5f527a", "mailbox": "0x2f9DB5616fa3fAd1aB06cB2C906830BA63d135e3", "merkleTreeHook": "0x8358D8291e3bEDb04804975eEa0fe9fe0fAfB147", "name": "fraxtal", @@ -1047,7 +1047,7 @@ "interchainAccountIsm": "0x9629c28990F11c31735765A6FD59E1E1bC197DbD", "interchainAccountRouter": "0x2351FBe24C1212F253b7a300ff0cBCFd97952a19", "interchainGasPaymaster": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", - "interchainSecurityModule": "0x69b33D67B9C51D45E23d22E727FF186DD6298ECA", + "interchainSecurityModule": "0xf0b1EC4228c0F26B7225851f940c625e4Be12226", "mailbox": "0x3071D4DA6020C956Fe15Bfd0a9Ca8D4574f16696", "merkleTreeHook": "0xfBc08389224d23b79cb21cDc16c5d42F0ad0F57f", "name": "fusemainnet", @@ -1121,7 +1121,7 @@ "interchainAccountIsm": "0x07E2062A1bC66a2C1d05cb5C3870a4AF86e0056E", "interchainAccountRouter": "0xBE70Ab882D1F7E37e04a70CDd9Ec23b37a234064", "interchainGasPaymaster": "0xDd260B99d302f0A3fF885728c086f729c06f227f", - "interchainSecurityModule": "0x00533a5F14B3a0632C86f99E4e20a10b73C4AE0D", + "interchainSecurityModule": "0xcfA4D90A43AAB0dE6a07c33A0614606b5Fbf71eC", "mailbox": "0xaD09d78f4c6b9dA2Ae82b1D34107802d380Bb74f", "merkleTreeHook": "0x2684C6F89E901987E1FdB7649dC5Be0c57C61645", "name": "gnosis", @@ -1192,7 +1192,7 @@ "interchainAccountIsm": "0x708E002637792FDC031E6B62f23DD60014AC976a", "interchainAccountRouter": "0xfB8cea1c7F45608Da30655b50bbF355D123A4358", "interchainGasPaymaster": "0x19dc38aeae620380430C200a6E990D5Af5480117", - "interchainSecurityModule": "0xB8F85B879775adF156Dd4AFa43e97DeB880d99D4", + "interchainSecurityModule": "0x5f39C3f0d9c74a667C177795b769CC22aE0A200d", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x0972954923a1e2b2aAb04Fa0c4a0797e5989Cd65", "name": "inevm", @@ -1320,7 +1320,7 @@ "from": 14616307 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xE2968dAb74541184Ad95651b1e5Cf34Ab1bBEc97", + "interchainSecurityModule": "0xa078A84FCB5d53BCe9529DcF96635794951116Ba", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "kroma", @@ -1393,7 +1393,7 @@ "interchainAccountIsm": "0xdcA646C56E7768DD11654956adE24bfFf9Ba4893", "interchainAccountRouter": "0xD59dA396F162Ed93a41252Cebb8d5DD4F093238C", "interchainGasPaymaster": "0x8105a095368f1a184CceA86cCe21318B5Ee5BE28", - "interchainSecurityModule": "0x0EEF1e64646EE01DeED4850074Cd4B97C0A630a9", + "interchainSecurityModule": "0x3902B990C5DC30D6CeeFf8b8B6Ad0cb6466b7d45", "mailbox": "0x02d16BC51af6BfD153d67CA61754cF912E82C4d9", "merkleTreeHook": "0xC077A0Cc408173349b1c9870C667B40FE3C01dd7", "name": "linea", @@ -1464,7 +1464,7 @@ "from": 4195553 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0x63Bb509b9CA644609B15Ea55E56f0Acbbb9dB02E", + "interchainSecurityModule": "0xcee06f87aC789615B0BF989B54fb36De334af5bC", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "lisk", @@ -1528,7 +1528,7 @@ "from": 3088760 }, "interchainGasPaymaster": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", - "interchainSecurityModule": "0x609ad94304896607A6D81DB00d882245045B79da", + "interchainSecurityModule": "0x351621b2fbfe92193304A8e4DD97E04108883Ac8", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x062200d92dF6bB7bA89Ce4D6800110450f94784e", "name": "lukso", @@ -1602,7 +1602,7 @@ "interchainAccountIsm": "0x8Ea50255C282F89d1A14ad3F159437EE5EF0507f", "interchainAccountRouter": "0x693A4cE39d99e46B04cb562329e3F0141cA17331", "interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4", - "interchainSecurityModule": "0xC012e8E3cBeB6295E1E4837FBA5DB8E077EBc549", + "interchainSecurityModule": "0x4110577c0970e591b3DC6D8FfCbE8FA499b4cD14", "isTestnet": false, "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112", @@ -1672,7 +1672,7 @@ "interchainAccountIsm": "0xe039DA3A0071BEd087A12660D7b03cf669c7776E", "interchainAccountRouter": "0x45285463352c53a481e882cD5E2AF2E25BBdAd0D", "interchainGasPaymaster": "0x8105a095368f1a184CceA86cCe21318B5Ee5BE28", - "interchainSecurityModule": "0x8722328A5Ed815965F9B5eBAA21d04f0F9BFDd35", + "interchainSecurityModule": "0xAb7DdE83cf33e0B305624462A6B9D7D06A32A699", "mailbox": "0x398633D19f4371e1DB5a8EFE90468eB70B1176AA", "merkleTreeHook": "0x5332D1AC0A626D265298c14ff681c0A8D28dB86d", "name": "mantle", @@ -1734,7 +1734,7 @@ "from": 13523607 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xE8176Fc70f129255aA83d3db242C2246Ad77Af7D", + "interchainSecurityModule": "0xc0dc69896334eD2f3Af2666d5EEF70e062a4636e", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "merlin", @@ -1801,7 +1801,7 @@ "from": 17966274 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xA9309228762699D5c81A4b0BAfd06Da21589746b", + "interchainSecurityModule": "0xA04202E77957f7451c0a2F2CA9eF54FFC334BcF3", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "metis", @@ -1866,7 +1866,7 @@ "from": 3752032 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0xA9309228762699D5c81A4b0BAfd06Da21589746b", + "interchainSecurityModule": "0x120bbFe296f11Dd653Cd6aC4F93106d9e6ADe5Bc", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "mint", @@ -1933,7 +1933,7 @@ "interchainAccountIsm": "0xa377b8269e0A47cdd2fD5AAeAe860b45623c6d82", "interchainAccountRouter": "0x6e1B9f776bd415d7cC3C7458A5f0d801016918f8", "interchainGasPaymaster": "0x931dFCc8c1141D6F532FD023bd87DAe0080c835d", - "interchainSecurityModule": "0x0777dFffcEd18EE416e35401E0e5e0413b7D43be", + "interchainSecurityModule": "0x0ab4853f2104C8f8e0b4Da4028601D999c7dFCF5", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xE2ee936bEa8e42671c400aC96dE198E06F2bA2A6", "name": "mode", @@ -2001,7 +2001,7 @@ "interchainAccountIsm": "0x79b3730CE3685f65802aF1771319992bA960EB9D", "interchainAccountRouter": "0xc4482f66191754a8629D35289043C4EB0285F10E", "interchainGasPaymaster": "0x14760E32C0746094cF14D97124865BC7F0F7368F", - "interchainSecurityModule": "0xad1Ad827035eDe500aFd0ff122c53f6eA607Eb5C", + "interchainSecurityModule": "0x11cC5Ac8F65e337Db6E95a542e87Af630cd0b1CD", "mailbox": "0x094d03E751f49908080EFf000Dd6FD177fd44CC3", "merkleTreeHook": "0x87403b85f6f316e7ba91ba1fa6C3Fb7dD4095547", "name": "moonbeam", @@ -2143,7 +2143,7 @@ "interchainAccountIsm": "0x2c46BF14641d00549ECa4779BF5CBf91602C1DEd", "interchainAccountRouter": "0x03D6cC17d45E9EA27ED757A8214d1F07F7D901aD", "interchainGasPaymaster": "0xD8A76C4D91fCbB7Cc8eA795DFDF870E48368995C", - "interchainSecurityModule": "0x3878aB31B2426A92E8a1E0AE758d848879F7F5E8", + "interchainSecurityModule": "0x5E04bA55C08456562f7e1BF9E2b46628b81593c8", "mailbox": "0xd4C1905BB1D26BC93DAC913e13CaCC278CdCC80D", "merkleTreeHook": "0x68eE9bec9B4dbB61f69D9D293Ae26a5AACb2e28f", "name": "optimism", @@ -2278,7 +2278,7 @@ "interchainAccountIsm": "0xBAC4529cdfE7CCe9E858BF706e41F8Ed096C1BAd", "interchainAccountRouter": "0xF163949AD9F88977ebF649D0461398Ca752E64B9", "interchainGasPaymaster": "0x0071740Bf129b05C4684abfbBeD248D80971cce2", - "interchainSecurityModule": "0x9fFC02BfB5C7260C985b005C0cF40d7EC601aac2", + "interchainSecurityModule": "0x0c3fE398595235A3163b39E5C6443aa1f7e145c4", "mailbox": "0x5d934f4e2f797775e53561bB72aca21ba36B96BB", "merkleTreeHook": "0x73FbD25c3e817DC4B4Cd9d00eff6D83dcde2DfF6", "name": "polygon", @@ -2355,7 +2355,7 @@ "interchainAccountIsm": "0xc1198e241DAe48BF5AEDE5DCE49Fe4A6064cF7a7", "interchainAccountRouter": "0x20a0A32a110362920597F72974E1E0d7e25cA20a", "interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4", - "interchainSecurityModule": "0xc6c475184F197FA65f233dFc22FA6bD4cE48B4fE", + "interchainSecurityModule": "0x3351FC009ccb309C367787ff9f3040FDee0Dcf66", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112", "name": "polygonzkevm", @@ -2423,7 +2423,7 @@ "from": 32018468 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0x70e8beCE806914959c1B5D8F75d2217058D31437", + "interchainSecurityModule": "0x37282B7505DA332Fc57FAb1623C73A4AeDb49165", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "proofofplay", @@ -2487,7 +2487,7 @@ "from": 363159 }, "interchainGasPaymaster": "0x3071D4DA6020C956Fe15Bfd0a9Ca8D4574f16696", - "interchainSecurityModule": "0x43346a54445BBdf8241062904E8A13AA62842a02", + "interchainSecurityModule": "0x14551EfDB6c29c8fC61D469627255E5f2c8Bf981", "mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", "merkleTreeHook": "0x55E4F0bc6b7Bb493D50839A8592e7ad8d5e93cf7", "name": "real", @@ -2554,7 +2554,7 @@ "interchainAccountIsm": "0x5DA60220C5dDe35b7aE91c042ff5979047FA0785", "interchainAccountRouter": "0x7a4d31a686A36285d68e14EDD53631417eB19603", "interchainGasPaymaster": "0x2Fa570E83009eaEef3a1cbd496a9a30F05266634", - "interchainSecurityModule": "0xd8b6B632526834D8192860e6B6CE47165Fd02a42", + "interchainSecurityModule": "0x5fe5b8f20437336a74fA53e553472f6fF048e73A", "mailbox": "0xeA87ae93Fa0019a82A727bfd3eBd1cFCa8f64f1D", "merkleTreeHook": "0x8F1E22d309baa69D398a03cc88E9b46037e988AA", "name": "redstone", @@ -2616,7 +2616,7 @@ "from": 937117 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0x6A2748201F66647ad6D164CB3340A893881A4bb2", + "interchainSecurityModule": "0xcC5534C4665D9BD93B377F56eC4c09Fdee87AD30", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "sanko", @@ -2684,7 +2684,7 @@ "interchainAccountIsm": "0x32af5Df81fEd5E26119F6640FBB13f3d63a94CDe", "interchainAccountRouter": "0x0B48a744698ba8dFa514742dFEB6728f52fD66f7", "interchainGasPaymaster": "0xBF12ef4B9f307463D3FB59c3604F294dDCe287E2", - "interchainSecurityModule": "0xAd1a987BfE0D6fbD92089628daC7C7e4bA9a6AAF", + "interchainSecurityModule": "0x41D5dbBe3a6B5d3937f03e82C23d1EDF9D4d0B6C", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x6119E37Bd66406A1Db74920aC79C15fB8411Ba76", "name": "scroll", @@ -2752,7 +2752,7 @@ "interchainAccountIsm": "0xf35dc7B9eE4Ebf0cd3546Bd6EE3b403dE2b9F5D6", "interchainAccountRouter": "0xBcaedE97a98573A88242B3b0CB0A255F3f90d4d5", "interchainGasPaymaster": "0xFC62DeF1f08793aBf0E67f69257c6be258194F72", - "interchainSecurityModule": "0x494028EA206642e4c60Ec3d12e96B4549E5e1800", + "interchainSecurityModule": "0x42Aa14207b41A7c2b1692DFC4927a32Caaa52b24", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xca1b69fA4c4a7c7fD839bC50867c589592bcfe49", "name": "sei", @@ -2867,7 +2867,7 @@ "interchainAccountIsm": "0xAE557e108b3336130370aC74836f1356B4b30Cf2", "interchainAccountRouter": "0x1F8CF09F060A2AE962c0Bb1F92e209a1E7b0E10B", "interchainGasPaymaster": "0x273Bc6b01D9E88c064b6E5e409BdF998246AEF42", - "interchainSecurityModule": "0xC93F2796A17Ee4580c039aeB7b0c923b10ce79C2", + "interchainSecurityModule": "0x2faB8c35cd093904F3d9a9f022996103d4bb7A85", "mailbox": "0x28EFBCadA00A7ed6772b3666F3898d276e88CAe3", "merkleTreeHook": "0x6A55822cf11f9fcBc4c75BC2638AfE8Eb942cAdd", "name": "taiko", @@ -2929,7 +2929,7 @@ "from": 1678063 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0x70e8beCE806914959c1B5D8F75d2217058D31437", + "interchainSecurityModule": "0xcC5534C4665D9BD93B377F56eC4c09Fdee87AD30", "isTestnet": false, "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", @@ -2997,7 +2997,7 @@ "interchainAccountIsm": "0x551BbEc45FD665a8C95ca8731CbC32b7653Bc59B", "interchainAccountRouter": "0xc11f8Cf2343d3788405582F65B8af6A4F7a6FfC8", "interchainGasPaymaster": "0x0D63128D887159d63De29497dfa45AFc7C699AE4", - "interchainSecurityModule": "0x3465AccC39AE5e6C344184013a57cDCe546834d6", + "interchainSecurityModule": "0x87Fb0665D25aC674D4d1494a13cA60E378f7536F", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x149db7afD694722747035d5AEC7007ccb6F8f112", "name": "viction", @@ -3065,7 +3065,7 @@ "interchainAccountIsm": "0xCB9f90EE5d83Ea52ABd922BD70898f0155D54798", "interchainAccountRouter": "0x473884010F0C1742DA8Ad01E7E295624B931076b", "interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503", - "interchainSecurityModule": "0x05f6BAa16F1aCf7b19c4A09E019D856c10ab8355", + "interchainSecurityModule": "0xb936B97837C4158DEA65CBaBCcC55bAE24134108", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD", "name": "worldchain", @@ -3127,7 +3127,7 @@ "from": 24395308 }, "interchainGasPaymaster": "0x9844aFFaBE17c37F791ff99ABa58B0FbB75e22AF", - "interchainSecurityModule": "0x4886ed96bcdba2ad85Bf518C3171C39e256ac840", + "interchainSecurityModule": "0xf61ee4520B7b316a34cdB31F4B95d8ad1808F919", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "name": "xai", @@ -3195,7 +3195,7 @@ "interchainAccountIsm": "0x29B37088724B745C0ABcE591449Cf042772160C2", "interchainAccountRouter": "0x03cF708E42C89623bd83B281A56935cB562b9258", "interchainGasPaymaster": "0x7E27456a839BFF31CA642c060a2b68414Cb6e503", - "interchainSecurityModule": "0x59B0ec92522F164b72c9BE473382197c564B92dc", + "interchainSecurityModule": "0x59Dcbb486F91561acC3500cdc378104AaE27e94a", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0x0054D19613f20dD72721A146ED408971a2CCA9BD", "name": "xlayer", @@ -3263,7 +3263,7 @@ "interchainAccountIsm": "0x2b6d3F7d28B5EC8C3C028fBCAdcf774D9709Dd29", "interchainAccountRouter": "0x3AdCBc94ab8C48EC52D06dc65Bb787fD1981E3d5", "interchainGasPaymaster": "0x931dFCc8c1141D6F532FD023bd87DAe0080c835d", - "interchainSecurityModule": "0xd32353Ae5719ac4f8f24AeD81A2A6898d2632D26", + "interchainSecurityModule": "0x3DFD05cc42F1B5370e688520e65C8fb909418471", "mailbox": "0x2f2aFaE1139Ce54feFC03593FeE8AB2aDF4a85A7", "merkleTreeHook": "0xE2ee936bEa8e42671c400aC96dE198E06F2bA2A6", "name": "zetachain", @@ -3329,7 +3329,7 @@ "from": 1511458 }, "interchainGasPaymaster": "0x03cF708E42C89623bd83B281A56935cB562b9258", - "interchainSecurityModule": "0xFFec270FE3D0e3B9348B3664BE73A5d4906BA620", + "interchainSecurityModule": "0x6C5288BBdFBfED98aE3e2C4201a53A9bBcC24fCE", "mailbox": "0xc2FbB9411186AB3b1a6AFCCA702D1a80B48b197c", "merkleTreeHook": "0x4C97D35c668EE5194a13c8DE8Afc18cce40C9F28", "name": "zircuit", @@ -3402,7 +3402,7 @@ "interchainAccountIsm": "0xb2674E213019972f937CCFc5e23BF963D915809e", "interchainAccountRouter": "0x11b76D93a9D39Eb51F54eBf5566308640cDe882b", "interchainGasPaymaster": "0x18B0688990720103dB63559a3563f7E8d0f63EDb", - "interchainSecurityModule": "0xED5fD1715A0885a3C7B908BAd5c8C64Ba5166265", + "interchainSecurityModule": "0x10455742E8D25b3FC2b19D41A006E91594D05Cd5", "mailbox": "0xF5da68b2577EF5C0A0D98aA2a58483a68C2f232a", "merkleTreeHook": "0x886BB0f329781b98f98FDeb1ce7a8957F2d43B9F", "name": "zoramainnet", @@ -3473,7 +3473,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674", + "interchainSecurityModule": "0xed2b47397954E0a56ca7C2a862dba4027da0f595", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3540,7 +3540,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0xa18979d2e5b8A64f62E0f9e9523d28E934F1104c", + "interchainSecurityModule": "0x73b3A13eA8084C9BeAd07eD867cEe1E8F5cceF9e", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3610,7 +3610,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674", + "interchainSecurityModule": "0x0fFD49C8ae6f5DdC20124B92c4b4048EbeF71830", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3686,7 +3686,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674", + "interchainSecurityModule": "0x6dCfEB77d5801DCC76C0EDd1F44E32D6dEcAD2A2", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3750,7 +3750,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674", + "interchainSecurityModule": "0x119b3dFBef304b07BBCb08D5182459f35808bfF2", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3823,7 +3823,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674", + "interchainSecurityModule": "0x7954Da9003180D64B9Eb7dE5E23fC83Fd7673047", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3891,7 +3891,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0x8Ad4d573D7EafC4Ca58f1dB704B8Db804814D674", + "interchainSecurityModule": "0xE96E34b0e66A5FAe90Be8f5FE41B6adB86D84A8b", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -3954,7 +3954,7 @@ "domainRoutingIsmFactory": "0x1052eF3419f26Bec74Ed7CEf4a4FA6812Bc09908", "fallbackRoutingHook": "0xc401e251CCa7A364114504A994D6fC7cb1c243AB", "interchainGasPaymaster": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", - "interchainSecurityModule": "0xf08b7F859966ed27286Fe7d924A42b40e2DB80Bd", + "interchainSecurityModule": "0x6CECA24Ebc20183B17fbA17f2856d5B3f97659Db", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x441a01Fca2eD731C0Fc4633998332f9FEDB17575", "pausableHook": "0x5Ed813B8b41f25c8002B01A72bbDBe6A0232Fe27", @@ -4024,7 +4024,7 @@ "interchainAccountIsm": "0xcd9D3744512F07AE844c40E27912092d7c503565", "interchainAccountRouter": "0x92cdbF0Ccdf8E93467FA858fb986fa650A02f2A8", "interchainGasPaymaster": "0xb58257cc81E47EC72fD38aE16297048de23163b4", - "interchainSecurityModule": "0xcC5C35a6214982d9018B95e9684D5b4dA626237e", + "interchainSecurityModule": "0x6B38f93e9145BF8b09B127e20F0275E92E29E4F5", "mailbox": "0x7f50C5776722630a0024fAE05fDe8b47571D7B39", "merkleTreeHook": "0xCC3D1659D50461d27a2F025dDb2c9B06B584B7e1", "pausableHook": "0x4E55aDA3ef1942049EA43E904EB01F4A0a9c39bd", @@ -4084,7 +4084,7 @@ "interchainAccountIsm": "0xc23BaF5Eb5848D19701BbE7f139645e6bd58a319", "interchainAccountRouter": "0x7c58Cadcc2b60ACF794eE1843488d6f5703f76BE", "interchainGasPaymaster": "0xb4fc9B5fD57499Ef6FfF3995728a55F7A618ef86", - "interchainSecurityModule": "0x50B5Edd94A1C7ad18Fa2CA667A30Dc051a695aEe", + "interchainSecurityModule": "0x0d242364057129d99Fca35BA8Ed2d9Ae90956F63", "mailbox": "0xb129828B9EDa48192D0B2db35D0E40dCF51B3594", "merkleTreeHook": "0x3E969bA938E6A993eeCD6F65b0dd8712B07dFe59", "pausableHook": "0x6Fb36672365C7c797028C400A61c58c0ECc53cD2", @@ -4889,7 +4889,7 @@ "interchainAccountIsm": "0x6119B76720CcfeB3D256EC1b91218EEfFD6756E1", "interchainAccountRouter": "0x9eaaC366BFD70430cFee6E70265fefFf1CfC9E47", "interchainGasPaymaster": "0x18B0688990720103dB63559a3563f7E8d0f63EDb", - "interchainSecurityModule": "0x9FF3f38DED52D74EF4b666A7A09BcB5F38d6D272", + "interchainSecurityModule": "0x70196Ec5e193dC07CFDC7AeC583DF9aeC20f4939", "mailbox": "0x7f50C5776722630a0024fAE05fDe8b47571D7B39", "merkleTreeHook": "0x886BB0f329781b98f98FDeb1ce7a8957F2d43B9F", "pausableHook": "0x2F619Ac5122689180AeBB930ADccdae215d538a9", @@ -4953,7 +4953,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x92772a801db50044a9D5078CC35CD63CEcD7B424", + "interchainSecurityModule": "0x8FBFF0cF2920c4deFfd8EAE6a51BB55E1d40eFFc", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -5014,7 +5014,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x92772a801db50044a9D5078CC35CD63CEcD7B424", + "interchainSecurityModule": "0xCC95B2978F65B2f358dD4A8B428Dd442AB37f478", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -5093,7 +5093,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x92772a801db50044a9D5078CC35CD63CEcD7B424", + "interchainSecurityModule": "0xeD0fc456143f761614478D170bf12403638DDa1e", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -5160,7 +5160,7 @@ "interchainAccountIsm": "0x783EC5e105234a570eB90f314284E5dBe53bdd90", "interchainAccountRouter": "0xc5D6aCaafBCcEC6D7fD7d92F4509befce641c563", "interchainGasPaymaster": "0xf3dFf6747E7FC74B431C943961054B7BF6309d8a", - "interchainSecurityModule": "0xfa19BfEcB4fed2e0268ee5008a11cD946DcC13c3", + "interchainSecurityModule": "0xFbDfEE404a9DFA413fF8B587aDad4B7979Db28a0", "mailbox": "0x3a464f746D23Ab22155710f44dB16dcA53e0775E", "merkleTreeHook": "0x5090dF2FBDa7127c7aDa41f60B79F5c55D380Dd8", "pausableHook": "0x886BB0f329781b98f98FDeb1ce7a8957F2d43B9F", @@ -5231,7 +5231,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x92772a801db50044a9D5078CC35CD63CEcD7B424", + "interchainSecurityModule": "0x2D92EeB56FbEB258d918485200aC1C2e010547b8", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -5296,7 +5296,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x92772a801db50044a9D5078CC35CD63CEcD7B424", + "interchainSecurityModule": "0xCC95B2978F65B2f358dD4A8B428Dd442AB37f478", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -5360,7 +5360,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x92772a801db50044a9D5078CC35CD63CEcD7B424", + "interchainSecurityModule": "0x8FBFF0cF2920c4deFfd8EAE6a51BB55E1d40eFFc", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -5427,7 +5427,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x92772a801db50044a9D5078CC35CD63CEcD7B424", + "interchainSecurityModule": "0x8FBFF0cF2920c4deFfd8EAE6a51BB55E1d40eFFc", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -5491,7 +5491,7 @@ "interchainAccountIsm": "0xFB9e40D811Cea562cc8a322b029eF2BDcC3ef6ed", "interchainAccountRouter": "0xeE8C0E1EeBfFCC451a013336386eA53E42a44451", "interchainGasPaymaster": "0x145566181A18E23bB6a8A3eC6D87765542A7F754", - "interchainSecurityModule": "0x92772a801db50044a9D5078CC35CD63CEcD7B424", + "interchainSecurityModule": "0xC7a2a8103dF4bdE8c78C2C5C03389ee9337A9942", "mailbox": "0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7", "merkleTreeHook": "0x6963480b05EB58f4d624B014ab92e9aD4d21df6D", "pausableHook": "0xD0dca420feFda68537695A8D887080eeF4030AF7", @@ -5580,7 +5580,7 @@ } ], "blocks": { - "confirmations": 1, + "confirmations": 2, "estimateBlockTime": 1, "reorgPeriod": 0 }, diff --git a/typescript/cli/examples/submit/strategy/impersonated-account-strategy.yaml b/typescript/cli/examples/submit/strategy/impersonated-account-strategy.yaml index 567c4bbb1..61ecbc51f 100644 --- a/typescript/cli/examples/submit/strategy/impersonated-account-strategy.yaml +++ b/typescript/cli/examples/submit/strategy/impersonated-account-strategy.yaml @@ -1,3 +1,4 @@ submitter: + chain: anvil2 type: impersonatedAccount userAddress: '0x16F4898F47c085C41d7Cc6b1dc72B91EA617dcBb' diff --git a/typescript/cli/examples/submit/strategy/json-rpc-chain-strategy.yaml b/typescript/cli/examples/submit/strategy/json-rpc-chain-strategy.yaml index 20197ffd6..771153a67 100644 --- a/typescript/cli/examples/submit/strategy/json-rpc-chain-strategy.yaml +++ b/typescript/cli/examples/submit/strategy/json-rpc-chain-strategy.yaml @@ -1,6 +1,8 @@ anvil2: submitter: + chain: anvil2 type: jsonRpc anvil3: submitter: + chain: anvil3 type: jsonRpc diff --git a/typescript/cli/examples/submit/strategy/json-rpc-strategy.yaml b/typescript/cli/examples/submit/strategy/json-rpc-strategy.yaml index 5be823ae0..baafe170a 100644 --- a/typescript/cli/examples/submit/strategy/json-rpc-strategy.yaml +++ b/typescript/cli/examples/submit/strategy/json-rpc-strategy.yaml @@ -1,2 +1,3 @@ submitter: + chain: anvil2 type: jsonRpc diff --git a/typescript/cli/src/config/submit.ts b/typescript/cli/src/config/submit.ts index 45f3367b0..3b7e3c59e 100644 --- a/typescript/cli/src/config/submit.ts +++ b/typescript/cli/src/config/submit.ts @@ -3,8 +3,8 @@ import { stringify as yamlStringify } from 'yaml'; import { AnnotatedEV5Transaction, SubmissionStrategy, + getChainIdFromTxs, } from '@hyperlane-xyz/sdk'; -import { MultiProvider } from '@hyperlane-xyz/sdk'; import { assert, errorToString } from '@hyperlane-xyz/utils'; import { WriteCommandContext } from '../context/types.js'; @@ -34,9 +34,9 @@ export async function runSubmit({ 'Submission strategy required to submit transactions.\nPlease create a submission strategy. See examples in cli/examples/submit/strategy/*.', ); const transactions = getTransactions(transactionsFilepath); - const chain = getChainFromTxs(multiProvider, transactions); + const chainId = getChainIdFromTxs(transactions); - const protocol = chainMetadata[chain].protocol; + const protocol = chainMetadata[chainId].protocol; const submitterBuilder = await getSubmitterBuilder({ submissionStrategy, multiProvider, @@ -60,28 +60,6 @@ export async function runSubmit({ } } -/** - * Retrieves the chain name from transactions[0]. - * - * @param multiProvider - The MultiProvider instance to use for chain name lookup. - * @param transactions - The list of populated transactions. - * @returns The name of the chain that the transactions are submitted on. - * @throws If the transactions are not all on the same chain or chain is not found - */ -function getChainFromTxs( - multiProvider: MultiProvider, - transactions: AnnotatedEV5Transaction[], -) { - const firstTransaction = transactions[0]; - assert(firstTransaction.chainId, 'Invalid transaction: chainId is required'); - const sameChainIds = transactions.every( - (t: AnnotatedEV5Transaction) => t.chainId === firstTransaction.chainId, - ); - assert(sameChainIds, 'Transactions must be submitted on the same chains'); - - return multiProvider.getChainName(firstTransaction.chainId); -} - function getTransactions( transactionsFilepath: string, ): AnnotatedEV5Transaction[] { diff --git a/typescript/cli/src/deploy/warp.ts b/typescript/cli/src/deploy/warp.ts index 984d46235..508e18f69 100644 --- a/typescript/cli/src/deploy/warp.ts +++ b/typescript/cli/src/deploy/warp.ts @@ -885,12 +885,20 @@ async function submitWarpApplyTransactions( params: WarpApplyParams, chainTransactions: Record, ): Promise { - const { multiProvider } = params.context; + // Create mapping of chain ID to chain name for all chains in warpDeployConfig + const chains = Object.keys(params.warpDeployConfig); + const chainIdToName = Object.fromEntries( + chains.map((chain) => [ + params.context.multiProvider.getChainId(chain), + chain, + ]), + ); + await promiseObjAll( objMap(chainTransactions, async (chainId, transactions) => { await retryAsync( async () => { - const chain = multiProvider.getChainName(chainId); + const chain = chainIdToName[chainId]; const submitter: TxSubmitterBuilder = await getWarpApplySubmitter({ chain, @@ -935,6 +943,7 @@ async function getWarpApplySubmitter({ ? readChainSubmissionStrategy(strategyUrl)[chain] : { submitter: { + chain, type: TxSubmitterType.JSON_RPC, }, }; diff --git a/typescript/cli/src/submit/submit.ts b/typescript/cli/src/submit/submit.ts index 29d1f8a05..8aa87f4a2 100644 --- a/typescript/cli/src/submit/submit.ts +++ b/typescript/cli/src/submit/submit.ts @@ -39,7 +39,9 @@ async function getSubmitter( ): Promise> { switch (submitterMetadata.type) { case TxSubmitterType.JSON_RPC: - return new EV5JsonRpcTxSubmitter(multiProvider); + return new EV5JsonRpcTxSubmitter(multiProvider, { + ...submitterMetadata, + }); case TxSubmitterType.IMPERSONATED_ACCOUNT: return new EV5ImpersonatedAccountTxSubmitter(multiProvider, { ...submitterMetadata, diff --git a/typescript/cli/src/tests/commands/helpers.ts b/typescript/cli/src/tests/commands/helpers.ts index c4ad03651..6dd76969f 100644 --- a/typescript/cli/src/tests/commands/helpers.ts +++ b/typescript/cli/src/tests/commands/helpers.ts @@ -119,14 +119,18 @@ export async function deployOrUseExistingCore( return addresses; } -export async function getChainId(chainName: string, key: string) { + +export async function getDomainId( + chainName: string, + key: string, +): Promise { const { registry } = await getContext({ registryUri: REGISTRY_PATH, registryOverrideUri: '', key, }); const chainMetadata = await registry.getChainMetadata(chainName); - return String(chainMetadata?.chainId); + return String(chainMetadata?.domainId); } export async function deployToken(privateKey: string, chain: string) { diff --git a/typescript/cli/src/tests/warp-apply.e2e-test.ts b/typescript/cli/src/tests/warp-apply.e2e-test.ts index ff891448d..a97729c82 100644 --- a/typescript/cli/src/tests/warp-apply.e2e-test.ts +++ b/typescript/cli/src/tests/warp-apply.e2e-test.ts @@ -15,7 +15,7 @@ import { REGISTRY_PATH, deployOrUseExistingCore, extendWarpConfig, - getChainId, + getDomainId, updateOwner, } from './commands/helpers.js'; import { @@ -128,7 +128,7 @@ describe('WarpApply e2e tests', async function () { warpConfigPath, ); - const chain2Id = await getChainId(CHAIN_NAME_3, ANVIL_KEY); + const chain2Id = await getDomainId(CHAIN_NAME_3, ANVIL_KEY); const remoteRouterKeys1 = Object.keys( updatedWarpDeployConfig1[CHAIN_NAME_2].remoteRouters!, ); @@ -141,7 +141,7 @@ describe('WarpApply e2e tests', async function () { warpConfigPath, ); - const chain1Id = await getChainId(CHAIN_NAME_2, ANVIL_KEY); + const chain1Id = await getDomainId(CHAIN_NAME_2, ANVIL_KEY); const remoteRouterKeys2 = Object.keys( updatedWarpDeployConfig2[CHAIN_NAME_3].remoteRouters!, ); @@ -182,7 +182,7 @@ describe('WarpApply e2e tests', async function () { warpConfigPath, ); - const chain2Id = await getChainId(CHAIN_NAME_3, ANVIL_KEY); + const chain2Id = await getDomainId(CHAIN_NAME_3, ANVIL_KEY); const remoteRouterKeys1 = Object.keys( updatedWarpDeployConfig1[CHAIN_NAME_2].remoteRouters!, ); @@ -195,7 +195,7 @@ describe('WarpApply e2e tests', async function () { warpConfigPath, ); - const chain1Id = await getChainId(CHAIN_NAME_2, ANVIL_KEY); + const chain1Id = await getDomainId(CHAIN_NAME_2, ANVIL_KEY); const remoteRouterKeys2 = Object.keys( updatedWarpDeployConfig2[CHAIN_NAME_3].remoteRouters!, ); @@ -247,8 +247,8 @@ describe('WarpApply e2e tests', async function () { expect(updatedWarpDeployConfig_3.anvil3.owner).to.equal(randomOwner); // Check that both chains enrolled - const chain2Id = await getChainId(CHAIN_NAME_2, ANVIL_KEY); - const chain3Id = await getChainId(CHAIN_NAME_3, ANVIL_KEY); + const chain2Id = await getDomainId(CHAIN_NAME_2, ANVIL_KEY); + const chain3Id = await getDomainId(CHAIN_NAME_3, ANVIL_KEY); const remoteRouterKeys2 = Object.keys( updatedWarpDeployConfig_2[CHAIN_NAME_2].remoteRouters!, @@ -295,8 +295,8 @@ describe('WarpApply e2e tests', async function () { warpConfigPath, ); - const chain2Id = await getChainId(CHAIN_NAME_2, ANVIL_KEY); - const chain3Id = await getChainId(CHAIN_NAME_3, ANVIL_KEY); + const chain2Id = await getDomainId(CHAIN_NAME_2, ANVIL_KEY); + const chain3Id = await getDomainId(CHAIN_NAME_3, ANVIL_KEY); // Destination gas should be set in the existing chain (chain2) to include the extended chain (chain3) const destinationGas_2 = diff --git a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts index c1c660922..508aa28e6 100644 --- a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts +++ b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts @@ -5,7 +5,6 @@ import { BigNumber, ethers } from 'ethers'; import { Gauge, Registry } from 'prom-client'; import { format } from 'util'; -import { eclipsemainnet } from '@hyperlane-xyz/registry'; import { ChainMap, ChainName, @@ -818,8 +817,8 @@ class ContextFunder { ) { const l1Chain = L2ToL1[l2Chain]; const crossChainMessenger = new CrossChainMessenger({ - l1ChainId: this.multiProvider.getDomainId(l1Chain), - l2ChainId: this.multiProvider.getDomainId(l2Chain), + l1ChainId: this.multiProvider.getEvmChainId(l1Chain), + l2ChainId: this.multiProvider.getEvmChainId(l2Chain), l1SignerOrProvider: this.multiProvider.getSignerOrProvider(l1Chain), l2SignerOrProvider: this.multiProvider.getSignerOrProvider(l2Chain), }); @@ -832,7 +831,7 @@ class ContextFunder { private async bridgeToArbitrum(l2Chain: ChainName, amount: BigNumber) { const l1Chain = L2ToL1[l2Chain]; const l2Network = await getL2Network( - this.multiProvider.getDomainId(l2Chain), + this.multiProvider.getEvmChainId(l2Chain), ); const ethBridger = new EthBridger(l2Network); return ethBridger.deposit({ diff --git a/typescript/infra/scripts/generate-scraper-add-domain-sql.sh b/typescript/infra/scripts/generate-scraper-add-domain-sql.sh index ca9eb3fe8..ea06fafb3 100755 --- a/typescript/infra/scripts/generate-scraper-add-domain-sql.sh +++ b/typescript/infra/scripts/generate-scraper-add-domain-sql.sh @@ -10,6 +10,7 @@ cd "$(dirname "$0")/../../../" # Generate the SQL command for inserting domains into the scraper database echo "insert into domain (id, time_created, time_updated, name, native_token, chain_id, is_test_net, is_deprecated) values" for name in "$@"; do + chain_id=$(yq e ".$name.chainId" ../hyperlane-registry/chains/metadata.yaml) domain_id=$(yq e ".$name.domainId" ../hyperlane-registry/chains/metadata.yaml) if [ -z "$domain_id" ]; then echo "Error: domain_id for $name not found" >&2 @@ -22,8 +23,8 @@ for name in "$@"; do fi is_testnet=$(yq e ".$name.isTestnet" ../hyperlane-registry/chains/metadata.yaml) if [ "$is_testnet" = "true" ]; then - echo "($domain_id, current_timestamp, current_timestamp, '$name', '$native_token_symbol', $domain_id, true, false)" + echo "($domain_id, current_timestamp, current_timestamp, '$name', '$native_token_symbol', $chain_id, true, false)" else - echo "($domain_id, current_timestamp, current_timestamp, '$name', '$native_token_symbol', $domain_id, false, false)" + echo "($domain_id, current_timestamp, current_timestamp, '$name', '$native_token_symbol', $chain_id, false, false)" fi done | paste -sd, - diff --git a/typescript/infra/scripts/helloworld/kathy.ts b/typescript/infra/scripts/helloworld/kathy.ts index cea226d4f..dfed8fe6b 100644 --- a/typescript/infra/scripts/helloworld/kathy.ts +++ b/typescript/infra/scripts/helloworld/kathy.ts @@ -232,13 +232,15 @@ async function main(): Promise { messageReceiptSeconds.labels({ origin, remote }).inc(0); } - chains.map(async (chain) => { - return updateWalletBalanceMetricFor( - app, - chain, - coreConfig.owners[chain].owner, - ); - }); + await Promise.all( + chains.map(async (chain) => { + return updateWalletBalanceMetricFor( + app, + chain, + coreConfig.owners[chain].owner, + ); + }), + ); // Incremented each time an entire cycle has occurred let currentCycle = 0; diff --git a/typescript/infra/src/utils/safe.ts b/typescript/infra/src/utils/safe.ts index fc03e9366..397e746c0 100644 --- a/typescript/infra/src/utils/safe.ts +++ b/typescript/infra/src/utils/safe.ts @@ -122,7 +122,7 @@ export async function deleteSafeTx( safeTxHash: string, ): Promise { const signer = multiProvider.getSigner(chain); - const domainId = multiProvider.getDomainId(chain); + const chainId = multiProvider.getEvmChainId(chain); const txServiceUrl = multiProvider.getChainMetadata(chain).gnosisSafeTransactionServiceUrl; @@ -179,7 +179,7 @@ export async function deleteSafeTx( domain: { name: 'Safe Transaction Service', version: '1.0', - chainId: domainId, + chainId: chainId, verifyingContract: safeAddress, }, primaryType: 'DeleteRequest', diff --git a/typescript/sdk/src/contracts/contracts.ts b/typescript/sdk/src/contracts/contracts.ts index aadeba085..52f6606cf 100644 --- a/typescript/sdk/src/contracts/contracts.ts +++ b/typescript/sdk/src/contracts/contracts.ts @@ -3,6 +3,7 @@ import { Contract } from 'ethers'; import { Ownable, Ownable__factory } from '@hyperlane-xyz/core'; import { Address, + EvmChainId, ProtocolType, ValueOf, eqAddress, @@ -262,7 +263,7 @@ export function appFromAddressesMapHelper( } export function transferOwnershipTransactions( - chainId: number, + chainId: EvmChainId, contract: Address, actual: OwnableConfig, expected: OwnableConfig, diff --git a/typescript/sdk/src/core/AbstractHyperlaneModule.ts b/typescript/sdk/src/core/AbstractHyperlaneModule.ts index b4a42ec30..5ef6d6ff4 100644 --- a/typescript/sdk/src/core/AbstractHyperlaneModule.ts +++ b/typescript/sdk/src/core/AbstractHyperlaneModule.ts @@ -32,7 +32,7 @@ export abstract class HyperlaneModule< public abstract read(): Promise; public abstract update( config: TConfig, - ): Promise['transaction'][]>>; + ): Promise['transaction']>[]>; // /* // Types and static methods can be challenging. Ensure each implementation includes a static create function. diff --git a/typescript/sdk/src/core/EvmCoreModule.hardhat-test.ts b/typescript/sdk/src/core/EvmCoreModule.hardhat-test.ts index 13f81f92e..9d74fb146 100644 --- a/typescript/sdk/src/core/EvmCoreModule.hardhat-test.ts +++ b/typescript/sdk/src/core/EvmCoreModule.hardhat-test.ts @@ -130,7 +130,7 @@ describe('EvmCoreModule', async () => { // Check that it's actually a mailbox by calling one of it's methods expect(await mailboxContract.localDomain()).to.equal( - multiProvider.getChainId(CHAIN), + multiProvider.getDomainId(CHAIN), ); }); diff --git a/typescript/sdk/src/core/EvmCoreModule.ts b/typescript/sdk/src/core/EvmCoreModule.ts index 1be81d98f..84a931dca 100644 --- a/typescript/sdk/src/core/EvmCoreModule.ts +++ b/typescript/sdk/src/core/EvmCoreModule.ts @@ -2,6 +2,7 @@ import { Mailbox, Mailbox__factory } from '@hyperlane-xyz/core'; import { Address, Domain, + EvmChainId, ProtocolType, eqAddress, rootLogger, @@ -31,7 +32,7 @@ import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory.js'; import { IsmConfig } from '../ism/types.js'; import { MultiProvider } from '../providers/MultiProvider.js'; import { AnnotatedEV5Transaction } from '../providers/ProviderType.js'; -import { ChainNameOrId } from '../types.js'; +import { ChainName, ChainNameOrId } from '../types.js'; import { HyperlaneModule, @@ -50,10 +51,9 @@ export class EvmCoreModule extends HyperlaneModule< > { protected logger = rootLogger.child({ module: 'EvmCoreModule' }); protected coreReader: EvmCoreReader; - public readonly chainName: string; + public readonly chainName: ChainName; - // We use domainId here because MultiProvider.getDomainId() will always - // return a number, and EVM the domainId and chainId are the same. + public readonly chainId: EvmChainId; public readonly domainId: Domain; constructor( @@ -61,8 +61,9 @@ export class EvmCoreModule extends HyperlaneModule< args: HyperlaneModuleParams, ) { super(args); - this.coreReader = new EvmCoreReader(multiProvider, this.args.chain); - this.chainName = this.multiProvider.getChainName(this.args.chain); + this.coreReader = new EvmCoreReader(multiProvider, args.chain); + this.chainName = multiProvider.getChainName(args.chain); + this.chainId = multiProvider.getEvmChainId(args.chain); this.domainId = multiProvider.getDomainId(args.chain); } @@ -133,7 +134,7 @@ export class EvmCoreModule extends HyperlaneModule< ); updateTransactions.push({ annotation: `Setting default ISM for Mailbox ${mailbox} to ${deployedIsm}`, - chainId: this.domainId, + chainId: this.chainId, to: contractToUpdate.address, data: contractToUpdate.interface.encodeFunctionData('setDefaultIsm', [ deployedIsm, @@ -203,7 +204,7 @@ export class EvmCoreModule extends HyperlaneModule< expectedConfig: CoreConfig, ): AnnotatedEV5Transaction[] { return transferOwnershipTransactions( - this.domainId, + this.chainId, this.args.addresses.mailbox, actualConfig, expectedConfig, diff --git a/typescript/sdk/src/hook/EvmHookModule.ts b/typescript/sdk/src/hook/EvmHookModule.ts index b09099464..5f6a64e34 100644 --- a/typescript/sdk/src/hook/EvmHookModule.ts +++ b/typescript/sdk/src/hook/EvmHookModule.ts @@ -26,6 +26,8 @@ import { } from '@hyperlane-xyz/core'; import { Address, + Domain, + EvmChainId, ProtocolType, addressToBytes32, deepEquals, @@ -95,10 +97,9 @@ export class EvmHookModule extends HyperlaneModule< protected readonly deployer: HookDeployer; // Adding these to reduce how often we need to grab from MultiProvider. - public readonly chain: string; - // We use domainId here because MultiProvider.getDomainId() will always - // return a number, and EVM the domainId and chainId are the same. - public readonly domainId: number; + public readonly chain: ChainName; + public readonly chainId: EvmChainId; + public readonly domainId: Domain; // Transaction overrides for the chain protected readonly txOverrides: Partial; @@ -121,10 +122,11 @@ export class EvmHookModule extends HyperlaneModule< ); this.deployer = new HookDeployer(multiProvider, hookFactories); - this.chain = this.multiProvider.getChainName(this.args.chain); - this.domainId = this.multiProvider.getDomainId(this.chain); + this.chain = multiProvider.getChainName(this.args.chain); + this.chainId = multiProvider.getEvmChainId(this.chain); + this.domainId = multiProvider.getDomainId(this.chain); - this.txOverrides = this.multiProvider.getTransactionOverrides(this.chain); + this.txOverrides = multiProvider.getTransactionOverrides(this.chain); } public async read(): Promise { @@ -217,7 +219,7 @@ export class EvmHookModule extends HyperlaneModule< if (!eqAddress(targetConfig.owner, owner)) { updateTxs.push({ annotation: 'Transferring ownership of ownable Hook...', - chainId: this.domainId, + chainId: this.chainId, to: this.args.addresses.deployedHook, data: Ownable__factory.createInterface().encodeFunctionData( 'transferOwnership(address)', @@ -319,7 +321,7 @@ export class EvmHookModule extends HyperlaneModule< updateTxs.push({ annotation: `Updating paused state to ${targetConfig.paused}`, - chainId: this.domainId, + chainId: this.chainId, to: this.args.addresses.deployedHook, data, }); @@ -342,7 +344,7 @@ export class EvmHookModule extends HyperlaneModule< if (!eqAddress(currentConfig.beneficiary, targetConfig.beneficiary)) { updateTxs.push({ annotation: `Updating beneficiary from ${currentConfig.beneficiary} to ${targetConfig.beneficiary}`, - chainId: this.domainId, + chainId: this.chainId, to: this.args.addresses.deployedHook, data: igpInterface.encodeFunctionData('setBeneficiary(address)', [ targetConfig.beneficiary, @@ -443,7 +445,7 @@ export class EvmHookModule extends HyperlaneModule< annotation: `Updating overhead for domains ${Object.keys( targetOverheads, ).join(', ')}...`, - chainId: this.domainId, + chainId: this.chainId, to: interchainGasPaymaster, data: InterchainGasPaymaster__factory.createInterface().encodeFunctionData( 'setDestinationGasConfigs((uint32,(address,uint96))[])', @@ -509,7 +511,7 @@ export class EvmHookModule extends HyperlaneModule< annotation: `Updating gas oracle config for domains ${Object.keys( targetOracleConfig, ).join(', ')}...`, - chainId: this.domainId, + chainId: this.chainId, to: gasOracle, data: StorageGasOracle__factory.createInterface().encodeFunctionData( 'setRemoteGasDataConfigs((uint32,uint128,uint128)[])', @@ -540,7 +542,7 @@ export class EvmHookModule extends HyperlaneModule< if (currentConfig.protocolFee !== targetConfig.protocolFee) { updateTxs.push({ annotation: `Updating protocol fee from ${currentConfig.protocolFee} to ${targetConfig.protocolFee}`, - chainId: this.domainId, + chainId: this.chainId, to: this.args.addresses.deployedHook, data: protocolFeeInterface.encodeFunctionData( 'setProtocolFee(uint256)', @@ -553,7 +555,7 @@ export class EvmHookModule extends HyperlaneModule< if (currentConfig.beneficiary !== targetConfig.beneficiary) { updateTxs.push({ annotation: `Updating beneficiary from ${currentConfig.beneficiary} to ${targetConfig.beneficiary}`, - chainId: this.domainId, + chainId: this.chainId, to: this.args.addresses.deployedHook, data: protocolFeeInterface.encodeFunctionData( 'setBeneficiary(address)', @@ -601,7 +603,7 @@ export class EvmHookModule extends HyperlaneModule< return [ { annotation: 'Updating routing hooks...', - chainId: this.domainId, + chainId: this.chainId, to: this.args.addresses.deployedHook, data: DomainRoutingHook__factory.createInterface().encodeFunctionData( 'setHooks((uint32,address)[])', @@ -828,17 +830,17 @@ export class EvmHookModule extends HyperlaneModule< const chain = this.chain; const mailbox = this.args.addresses.mailbox; - const destinationChain = this.multiProvider.getChainId( + const destinationChainId = this.multiProvider.tryGetEvmChainId( config.destinationChain, ); - if (typeof destinationChain !== 'number') { + if (!destinationChainId) { throw new Error( - `Only ethereum chains supported for deploying Arbitrum L2 hook, given: ${config.destinationChain}`, + `Only ethereum chains supported for deploying Arbitrum L2 hook, given: ${config.destinationChain}`, ); } const bridge = - config.bridge ?? getArbitrumNetwork(destinationChain).ethBridge.bridge; + config.bridge ?? getArbitrumNetwork(destinationChainId).ethBridge.bridge; const ismConfig: ArbL2ToL1IsmConfig = { type: IsmType.ARB_L2_TO_L1, diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index e57d4895b..b2358f080 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -498,6 +498,7 @@ export { SealevelInstructionWrapper, getSealevelAccountDataSchema, } from './utils/sealevelSerialization.js'; +export { getChainIdFromTxs } from './utils/transactions.js'; export { chainMetadataToWagmiChain } from './utils/wagmi.js'; export { FeeConstantConfig, diff --git a/typescript/sdk/src/ism/EvmIsmModule.ts b/typescript/sdk/src/ism/EvmIsmModule.ts index bba38aa57..2f4e1ee1d 100644 --- a/typescript/sdk/src/ism/EvmIsmModule.ts +++ b/typescript/sdk/src/ism/EvmIsmModule.ts @@ -5,6 +5,7 @@ import { DomainRoutingIsm__factory } from '@hyperlane-xyz/core'; import { Address, Domain, + EvmChainId, ProtocolType, assert, deepEquals, @@ -54,8 +55,7 @@ export class EvmIsmModule extends HyperlaneModule< // Adding these to reduce how often we need to grab from MultiProvider. public readonly chain: ChainName; - // We use domainId here because MultiProvider.getDomainId() will always - // return a number, and EVM the domainId and chainId are the same. + public readonly chainId: EvmChainId; public readonly domainId: Domain; constructor( @@ -78,8 +78,9 @@ export class EvmIsmModule extends HyperlaneModule< this.mailbox = params.addresses.mailbox; - this.chain = this.multiProvider.getChainName(this.args.chain); - this.domainId = this.multiProvider.getDomainId(this.chain); + this.chain = multiProvider.getChainName(this.args.chain); + this.chainId = multiProvider.getEvmChainId(this.chain); + this.domainId = multiProvider.getDomainId(this.chain); } public async read(): Promise { @@ -169,7 +170,7 @@ export class EvmIsmModule extends HyperlaneModule< // Lastly, check if the resolved owner is different from the current owner updateTxs.push( ...transferOwnershipTransactions( - this.domainId, + this.chainId, this.args.addresses.deployedIsm, currentConfig, targetConfig, @@ -252,9 +253,9 @@ export class EvmIsmModule extends HyperlaneModule< const domainId = this.multiProvider.getDomainId(origin); const tx = await contract.populateTransaction.set(domainId, ism.address); updateTxs.push({ + chainId: this.chainId, annotation: `Setting new ISM for origin ${origin}...`, ...tx, - chainId: this.domainId, }); } @@ -268,9 +269,9 @@ export class EvmIsmModule extends HyperlaneModule< const domainId = this.multiProvider.getDomainId(origin); const tx = await contract.populateTransaction.remove(domainId); updateTxs.push({ + chainId: this.chainId, annotation: `Unenrolling originDomain ${domainId} from preexisting routing ISM at ${this.args.addresses.deployedIsm}...`, ...tx, - chainId: this.domainId, }); } diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts index 645fee8aa..f9a0b42d4 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts @@ -281,18 +281,15 @@ export class HyperlaneIsmFactory extends HyperlaneApp { this.getContracts(destination).domainRoutingIsmFactory; let routingIsm: DomainRoutingIsm | DefaultFallbackRoutingIsm; // filtering out domains which are not part of the multiprovider - config.domains = objFilter( - config.domains, - (domain, config): config is IsmConfig => { - const domainId = this.multiProvider.tryGetDomainId(domain); - if (domainId === null) { - logger.warn( - `Domain ${domain} doesn't have chain metadata provided, skipping ...`, - ); - } - return domainId !== null; - }, - ); + config.domains = objFilter(config.domains, (domain, _): _ is IsmConfig => { + const domainId = this.multiProvider.tryGetDomainId(domain); + if (domainId === null) { + logger.warn( + `Domain ${domain} doesn't have chain metadata provided, skipping ...`, + ); + } + return domainId !== null; + }); const safeConfigDomains = Object.keys(config.domains).map((domain) => this.multiProvider.getDomainId(domain), ); diff --git a/typescript/sdk/src/metadata/ChainMetadataManager.ts b/typescript/sdk/src/metadata/ChainMetadataManager.ts index 3a3d02745..09a43e086 100644 --- a/typescript/sdk/src/metadata/ChainMetadataManager.ts +++ b/typescript/sdk/src/metadata/ChainMetadataManager.ts @@ -1,6 +1,12 @@ import { Logger } from 'pino'; -import { ProtocolType, exclude, pick, rootLogger } from '@hyperlane-xyz/utils'; +import { + EvmChainId, + ProtocolType, + exclude, + pick, + rootLogger, +} from '@hyperlane-xyz/utils'; import { ChainMap, ChainName, ChainNameOrId } from '../types.js'; @@ -56,31 +62,25 @@ export class ChainMetadataManager { /** * Add a chain to the MultiProvider - * @throws if chain's name or domain/chain ID collide + * @throws if chain's name or domain ID collide */ addChain(metadata: ChainMetadata): void { ChainMetadataSchema.parse(metadata); - // Ensure no two chains have overlapping names/domainIds/chainIds + // Ensure no two chains have overlapping names/domainIds for (const chainMetadata of Object.values(this.metadata)) { - const { name, chainId, domainId } = chainMetadata; + const { name, domainId } = chainMetadata; if (name == metadata.name) throw new Error(`Duplicate chain name: ${name}`); - // Chain and Domain Ids should be globally unique - const idCollision = - chainId == metadata.chainId || - domainId == metadata.chainId || - (metadata.domainId && - (chainId == metadata.domainId || domainId == metadata.domainId)); + // Domain Ids should be globally unique + const idCollision = metadata.domainId && domainId == metadata.domainId; if (idCollision) - throw new Error( - `Chain/Domain id collision: ${name} and ${metadata.name}`, - ); + throw new Error(`Domain id collision: ${name} and ${metadata.name}`); } this.metadata[metadata.name] = metadata; } /** - * Get the metadata for a given chain name, chain id, or domain id + * Get the metadata for a given chain name or domain id * @throws if chain's metadata has not been set */ tryGetChainMetadata( @@ -88,15 +88,15 @@ export class ChainMetadataManager { ): ChainMetadata | null { // First check if it's a chain name if (this.metadata[chainNameOrId]) return this.metadata[chainNameOrId]; - // Otherwise search by chain id and domain id + // Otherwise search by domain id const chainMetadata = Object.values(this.metadata).find( - (m) => m.chainId == chainNameOrId || m.domainId == chainNameOrId, + (m) => m.domainId == chainNameOrId, ); return chainMetadata || null; } /** - * Get the metadata for a given chain name, chain id, or domain id + * Get the metadata for a given chain name or domain id * @throws if chain's metadata has not been set */ getChainMetadata(chainNameOrId: ChainNameOrId): ChainMetadata { @@ -119,22 +119,22 @@ export class ChainMetadataManager { } /** - * Returns true if the given chain name, chain id, or domain id is - * include in this manager's metadata, false otherwise + * Returns true if the given chain name or domain id is + * included in this manager's metadata, false otherwise */ hasChain(chainNameOrId: ChainNameOrId): boolean { return !!this.tryGetChainMetadata(chainNameOrId); } /** - * Get the name for a given chain name, chain id, or domain id + * Get the name for a given chain name or domain id */ tryGetChainName(chainNameOrId: ChainNameOrId): string | null { return this.tryGetChainMetadata(chainNameOrId)?.name ?? null; } /** - * Get the name for a given chain name, chain id, or domain id + * Get the name for a given chain name or domain id * @throws if chain's metadata has not been set */ getChainName(chainNameOrId: ChainNameOrId): string { @@ -149,14 +149,14 @@ export class ChainMetadataManager { } /** - * Get the id for a given chain name, chain id, or domain id + * Get the id for a given chain name or domain id */ tryGetChainId(chainNameOrId: ChainNameOrId): number | string | null { return this.tryGetChainMetadata(chainNameOrId)?.chainId ?? null; } /** - * Get the id for a given chain name, chain id, or domain id + * Get the id for a given chain name or domain id * @throws if chain's metadata has not been set */ getChainId(chainNameOrId: ChainNameOrId): number | string { @@ -164,14 +164,34 @@ export class ChainMetadataManager { } /** - * Get the ids for all chains known to this MultiProvider + * Get the id for a given EVM chain name or domain id + * Returns null if chain's metadata has not been set or is not an EVM chain */ - getKnownChainIds(): Array { - return Object.values(this.metadata).map((c) => c.chainId); + tryGetEvmChainId(chainNameOrId: ChainNameOrId): number | null { + const metadata = this.tryGetChainMetadata(chainNameOrId); + if (!metadata) return null; + if (metadata.protocol !== ProtocolType.Ethereum) return null; + if (typeof metadata.chainId !== 'number') return null; + return metadata.chainId; + } + + /** + * Get the id for a given EVM chain name or domain id + * @throws if chain's metadata has not been set + */ + getEvmChainId(chainNameOrId: ChainNameOrId): EvmChainId { + const { protocol, chainId } = this.getChainMetadata(chainNameOrId); + if (protocol !== ProtocolType.Ethereum) { + throw new Error(`Chain is not an EVM chain: ${chainNameOrId}`); + } + if (typeof chainId !== 'number') { + throw new Error(`Chain ID is not a number: ${chainId}`); + } + return chainId; } /** - * Get the domain id for a given chain name, chain id, or domain id + * Get the domain id for a given chain name or domain id */ tryGetDomainId(chainNameOrId: ChainNameOrId): number | null { const metadata = this.tryGetChainMetadata(chainNameOrId); @@ -180,7 +200,7 @@ export class ChainMetadataManager { } /** - * Get the domain id for a given chain name, chain id, or domain id + * Get the domain id for a given chain name or domain id * @throws if chain's metadata has not been set */ getDomainId(chainNameOrId: ChainNameOrId): number { @@ -190,14 +210,14 @@ export class ChainMetadataManager { } /** - * Get the protocol type for a given chain name, chain id, or domain id + * Get the protocol type for a given chain name or domain id */ tryGetProtocol(chainNameOrId: ChainNameOrId): ProtocolType | null { return this.tryGetChainMetadata(chainNameOrId)?.protocol ?? null; } /** - * Get the protocol type for a given chain name, chain id, or domain id + * Get the protocol type for a given chain name or domain id * @throws if chain's metadata or protocol has not been set */ getProtocol(chainNameOrId: ChainNameOrId): ProtocolType { @@ -205,7 +225,7 @@ export class ChainMetadataManager { } /** - * Get the domain ids for a list of chain names, chain ids, or domain ids + * Get the domain ids for a list of chain names or domain ids * @throws if any chain's metadata has not been set */ getDomainIds(chainNamesOrIds: Array): number[] { @@ -240,7 +260,7 @@ export class ChainMetadataManager { } /** - * Get the RPC details for a given chain name, chain id, or domain id. + * Get the RPC details for a given chain name or domain id. * Optional index for metadata containing more than one RPC. * @throws if chain's metadata has not been set */ @@ -257,7 +277,7 @@ export class ChainMetadataManager { } /** - * Get an RPC URL for a given chain name, chain id, or domain id + * Get an RPC URL for a given chain name or domain id * @throws if chain's metadata has not been set */ getRpcUrl(chainNameOrId: ChainNameOrId, index = 0): string { @@ -267,7 +287,7 @@ export class ChainMetadataManager { } /** - * Get an RPC concurrency level for a given chain name, chain id, or domain id + * Get an RPC concurrency level for a given chain name or domain id */ tryGetRpcConcurrency(chainNameOrId: ChainNameOrId, index = 0): number | null { const { concurrency } = this.getRpc(chainNameOrId, index); @@ -275,7 +295,7 @@ export class ChainMetadataManager { } /** - * Get a block explorer URL for a given chain name, chain id, or domain id + * Get a block explorer URL for a given chain name or domain id */ tryGetExplorerUrl(chainNameOrId: ChainNameOrId): string | null { const metadata = this.tryGetChainMetadata(chainNameOrId); @@ -284,7 +304,7 @@ export class ChainMetadataManager { } /** - * Get a block explorer URL for a given chain name, chain id, or domain id + * Get a block explorer URL for a given chain name or domain id * @throws if chain's metadata or block explorer data has no been set */ getExplorerUrl(chainNameOrId: ChainNameOrId): string { @@ -294,7 +314,7 @@ export class ChainMetadataManager { } /** - * Get a block explorer's API for a given chain name, chain id, or domain id + * Get a block explorer's API for a given chain name or domain id */ tryGetExplorerApi(chainNameOrId: ChainName | number): { apiUrl: string; @@ -307,7 +327,7 @@ export class ChainMetadataManager { } /** - * Get a block explorer API for a given chain name, chain id, or domain id + * Get a block explorer API for a given chain name or domain id * @throws if chain's metadata or block explorer data has no been set */ getExplorerApi(chainNameOrId: ChainName | number): { @@ -322,7 +342,7 @@ export class ChainMetadataManager { } /** - * Get a block explorer's API URL for a given chain name, chain id, or domain id + * Get a block explorer's API URL for a given chain name or domain id */ tryGetExplorerApiUrl(chainNameOrId: ChainNameOrId): string | null { const metadata = this.tryGetChainMetadata(chainNameOrId); @@ -331,7 +351,7 @@ export class ChainMetadataManager { } /** - * Get a block explorer API URL for a given chain name, chain id, or domain id + * Get a block explorer API URL for a given chain name or domain id * @throws if chain's metadata or block explorer data has no been set */ getExplorerApiUrl(chainNameOrId: ChainNameOrId): string { diff --git a/typescript/sdk/src/metadata/chainMetadataTypes.ts b/typescript/sdk/src/metadata/chainMetadataTypes.ts index bf41cd4ac..f8972f9bd 100644 --- a/typescript/sdk/src/metadata/chainMetadataTypes.ts +++ b/typescript/sdk/src/metadata/chainMetadataTypes.ts @@ -187,8 +187,8 @@ export const ChainMetadataSchemaObject = z.object({ 'A shorter human-readable name of the chain for use in user interfaces.', ), - domainId: ZNzUint.optional().describe( - 'The domainId of the chain, should generally default to `chainId`. Consumer of `ChainMetadata` should use this value if present, but otherwise fallback to `chainId`.', + domainId: ZNzUint.describe( + 'The domainId of the chain, should generally default to `chainId`. Consumer of `ChainMetadata` should use this value or `name` as a unique identifier.', ), gasCurrencyCoinGeckoId: z diff --git a/typescript/sdk/src/providers/MultiProvider.ts b/typescript/sdk/src/providers/MultiProvider.ts index b37aba1c5..7b5f92306 100644 --- a/typescript/sdk/src/providers/MultiProvider.ts +++ b/typescript/sdk/src/providers/MultiProvider.ts @@ -84,7 +84,7 @@ export class MultiProvider extends ChainMetadataManager { } /** - * Get an Ethers provider for a given chain name, chain id, or domain id + * Get an Ethers provider for a given chain name or domain id */ tryGetProvider(chainNameOrId: ChainNameOrId): Provider | null { const metadata = this.tryGetChainMetadata(chainNameOrId); @@ -108,7 +108,7 @@ export class MultiProvider extends ChainMetadataManager { } /** - * Get an Ethers provider for a given chain name, chain id, or domain id + * Get an Ethers provider for a given chain name or domain id * @throws if chain's metadata has not been set */ getProvider(chainNameOrId: ChainNameOrId): Provider { @@ -119,7 +119,7 @@ export class MultiProvider extends ChainMetadataManager { } /** - * Sets an Ethers provider for a given chain name, chain id, or domain id + * Sets an Ethers provider for a given chain name or domain id * @throws if chain's metadata has not been set */ setProvider(chainNameOrId: ChainNameOrId, provider: Provider): Provider { @@ -144,7 +144,7 @@ export class MultiProvider extends ChainMetadataManager { } /** - * Get an Ethers signer for a given chain name, chain id, or domain id + * Get an Ethers signer for a given chain name or domain id * If signer is not yet connected, it will be connected */ tryGetSigner(chainNameOrId: ChainNameOrId): Signer | null { @@ -159,7 +159,7 @@ export class MultiProvider extends ChainMetadataManager { } /** - * Get an Ethers signer for a given chain name, chain id, or domain id + * Get an Ethers signer for a given chain name or domain id * If signer is not yet connected, it will be connected * @throws if chain's metadata or signer has not been set */ @@ -170,7 +170,7 @@ export class MultiProvider extends ChainMetadataManager { } /** - * Get an Ethers signer for a given chain name, chain id, or domain id + * Get an Ethers signer for a given chain name or domain id * @throws if chain's metadata or signer has not been set */ async getSignerAddress(chainNameOrId: ChainNameOrId): Promise
{ @@ -180,7 +180,7 @@ export class MultiProvider extends ChainMetadataManager { } /** - * Sets an Ethers Signer for a given chain name, chain id, or domain id + * Sets an Ethers Signer for a given chain name or domain id * @throws if chain's metadata has not been set or shared signer has already been set */ setSigner(chainNameOrId: ChainNameOrId, signer: Signer): Signer { @@ -295,7 +295,7 @@ export class MultiProvider extends ChainMetadataManager { } /** - * Get the transaction overrides for a given chain name, chain id, or domain id + * Get the transaction overrides for a given chain name or domain id * @throws if chain's metadata has not been set */ getTransactionOverrides( diff --git a/typescript/sdk/src/providers/ProviderType.ts b/typescript/sdk/src/providers/ProviderType.ts index c74a9995d..ce1740873 100644 --- a/typescript/sdk/src/providers/ProviderType.ts +++ b/typescript/sdk/src/providers/ProviderType.ts @@ -22,7 +22,7 @@ import type { TransactionReceipt as VTransactionReceipt, } from 'viem'; -import { ProtocolType } from '@hyperlane-xyz/utils'; +import { Annotated, ProtocolType } from '@hyperlane-xyz/utils'; export enum ProviderType { EthersV5 = 'ethers-v5', @@ -192,9 +192,7 @@ export interface EthersV5Transaction transaction: EV5Transaction; } -export interface AnnotatedEV5Transaction extends EV5Transaction { - annotation?: string; -} +export type AnnotatedEV5Transaction = Annotated; export interface ViemTransaction extends TypedTransactionBase { type: ProviderType.Viem; diff --git a/typescript/sdk/src/providers/transactions/submitter/TxSubmitterInterface.ts b/typescript/sdk/src/providers/transactions/submitter/TxSubmitterInterface.ts index eab6fa575..e3f676bef 100644 --- a/typescript/sdk/src/providers/transactions/submitter/TxSubmitterInterface.ts +++ b/typescript/sdk/src/providers/transactions/submitter/TxSubmitterInterface.ts @@ -1,4 +1,4 @@ -import { ProtocolType } from '@hyperlane-xyz/utils'; +import { Annotated, ProtocolType } from '@hyperlane-xyz/utils'; import { ProtocolTypedProvider, @@ -22,7 +22,7 @@ export interface TxSubmitterInterface { * @param txs The array of transactions to execute */ submit( - ...txs: ProtocolTypedTransaction['transaction'][] + ...txs: Annotated['transaction']>[] ): Promise< | ProtocolTypedReceipt['receipt'] | ProtocolTypedReceipt['receipt'][] diff --git a/typescript/sdk/src/providers/transactions/submitter/builder/TxSubmitterBuilder.ts b/typescript/sdk/src/providers/transactions/submitter/builder/TxSubmitterBuilder.ts index a113e681d..53d1b4452 100644 --- a/typescript/sdk/src/providers/transactions/submitter/builder/TxSubmitterBuilder.ts +++ b/typescript/sdk/src/providers/transactions/submitter/builder/TxSubmitterBuilder.ts @@ -1,6 +1,6 @@ import { Logger } from 'pino'; -import { rootLogger } from '@hyperlane-xyz/utils'; +import { Annotated, rootLogger } from '@hyperlane-xyz/utils'; import { ProtocolType } from '@hyperlane-xyz/utils'; import { @@ -73,7 +73,7 @@ export class TxSubmitterBuilder * @param txs The transactions to submit */ public async submit( - ...txs: ProtocolTypedTransaction['transaction'][] + ...txs: Annotated['transaction']>[] ): Promise< | ProtocolTypedReceipt['receipt'] | ProtocolTypedReceipt['receipt'][] diff --git a/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxBuilder.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxBuilder.ts index 7e8b61408..bae3ed269 100644 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxBuilder.ts +++ b/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxBuilder.ts @@ -59,6 +59,7 @@ export class EV5GnosisSafeTxBuilder extends EV5GnosisSafeTxSubmitter { * @param txs - An array of populated transactions */ public async submit(...txs: AnnotatedEV5Transaction[]): Promise { + const chainId = this.multiProvider.getChainId(this.props.chain); const transactions: SafeTransactionData[] = await Promise.all( txs.map( async (tx: AnnotatedEV5Transaction) => @@ -69,7 +70,7 @@ export class EV5GnosisSafeTxBuilder extends EV5GnosisSafeTxSubmitter { ); return { version: this.props.version, - chainId: this.multiProvider.getChainId(this.props.chain).toString(), + chainId: chainId.toString(), meta: {}, transactions, }; diff --git a/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.ts index 9ed8ef98b..d3555f5a2 100644 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.ts +++ b/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.ts @@ -72,11 +72,11 @@ export class EV5GnosisSafeTxSubmitter implements EV5TxSubmitterInterface { const nextNonce: number = await this.safeService.getNextNonce( this.props.safeAddress, ); - assert(chainId, 'Invalid PopulatedTransaction: chainId is required'); - const txChain = this.multiProvider.getChainName(chainId); + const submitterChainId = this.multiProvider.getChainId(this.props.chain); + assert(chainId, 'Invalid AnnotatedEV5Transaction: chainId is required'); assert( - txChain === this.props.chain, - `Invalid PopulatedTransaction: Cannot submit ${txChain} tx to ${this.props.chain} submitter.`, + chainId === submitterChainId, + `Invalid AnnotatedEV5Transaction: Cannot submit tx for chain ID ${chainId} to submitter for chain ID ${submitterChainId}.`, ); return this.safe.createTransaction({ safeTransactionData: [{ to, data, value: value?.toString() ?? '0' }], diff --git a/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5ImpersonatedAccountTxSubmitter.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5ImpersonatedAccountTxSubmitter.ts index f0fea448a..b36082a4b 100644 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5ImpersonatedAccountTxSubmitter.ts +++ b/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5ImpersonatedAccountTxSubmitter.ts @@ -26,7 +26,7 @@ export class EV5ImpersonatedAccountTxSubmitter extends EV5JsonRpcTxSubmitter { multiProvider: MultiProvider, public readonly props: EV5ImpersonatedAccountTxSubmitterProps, ) { - super(multiProvider); + super(multiProvider, props); } public async submit( diff --git a/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.ts index 4a3d11d47..1c58ef19f 100644 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.ts +++ b/typescript/sdk/src/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.ts @@ -9,6 +9,7 @@ import { AnnotatedEV5Transaction } from '../../../ProviderType.js'; import { TxSubmitterType } from '../TxSubmitterTypes.js'; import { EV5TxSubmitterInterface } from './EV5TxSubmitterInterface.js'; +import { EV5JsonRpcTxSubmitterProps } from './types.js'; export class EV5JsonRpcTxSubmitter implements EV5TxSubmitterInterface { public readonly txSubmitterType: TxSubmitterType = TxSubmitterType.JSON_RPC; @@ -17,21 +18,28 @@ export class EV5JsonRpcTxSubmitter implements EV5TxSubmitterInterface { module: 'json-rpc-submitter', }); - constructor(public readonly multiProvider: MultiProvider) {} + constructor( + public readonly multiProvider: MultiProvider, + public readonly props: EV5JsonRpcTxSubmitterProps, + ) {} public async submit( ...txs: AnnotatedEV5Transaction[] ): Promise { const receipts: TransactionReceipt[] = []; + const submitterChainId = this.multiProvider.getChainId(this.props.chain); for (const tx of txs) { assert(tx.chainId, 'Invalid PopulatedTransaction: Missing chainId field'); - const txChain = this.multiProvider.getChainName(tx.chainId); + assert( + tx.chainId === submitterChainId, + `Transaction chainId ${tx.chainId} does not match submitter chainId ${submitterChainId}`, + ); const receipt: ContractReceipt = await this.multiProvider.sendTransaction( - txChain, + this.props.chain, tx, ); this.logger.debug( - `Submitted PopulatedTransaction on ${txChain}: ${receipt.transactionHash}`, + `Submitted PopulatedTransaction on ${this.props.chain}: ${receipt.transactionHash}`, ); receipts.push(receipt); } diff --git a/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.test.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.test.ts index fdffb778a..7cce08cad 100644 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.test.ts +++ b/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.test.ts @@ -42,7 +42,8 @@ describe('ethersV5 submitter props schemas', () => { describe('EV5ImpersonatedAccountTxSubmitterPropsSchema', () => { it('should parse valid props', () => { const validProps: EV5ImpersonatedAccountTxSubmitterProps = { - userAddress: '0x1234567890123456789012345678901234567890', + chain: CHAIN_MOCK, + userAddress: ADDRESS_MOCK, }; const result = EV5ImpersonatedAccountTxSubmitterPropsSchema.safeParse(validProps); @@ -51,6 +52,7 @@ describe('ethersV5 submitter props schemas', () => { it('should fail parsing invalid props', () => { const invalidProps: EV5ImpersonatedAccountTxSubmitterProps = { + chain: CHAIN_MOCK, userAddress: INVALID_ADDRESS, }; const result = diff --git a/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.ts index 931eb11bf..1586ec6b2 100644 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.ts +++ b/typescript/sdk/src/providers/transactions/submitter/ethersV5/schemas.ts @@ -13,6 +13,11 @@ export const EV5GnosisSafeTxBuilderPropsSchema = z.object({ safeAddress: ZHash, }); -export const EV5ImpersonatedAccountTxSubmitterPropsSchema = z.object({ - userAddress: 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/types.ts b/typescript/sdk/src/providers/transactions/submitter/ethersV5/types.ts index ee41edfa4..71a845841 100644 --- a/typescript/sdk/src/providers/transactions/submitter/ethersV5/types.ts +++ b/typescript/sdk/src/providers/transactions/submitter/ethersV5/types.ts @@ -4,6 +4,7 @@ import { EV5GnosisSafeTxBuilderPropsSchema, EV5GnosisSafeTxSubmitterPropsSchema, EV5ImpersonatedAccountTxSubmitterPropsSchema, + EV5JsonRpcTxSubmitterPropsSchema, } from './schemas.js'; export type EV5GnosisSafeTxSubmitterProps = z.infer< @@ -12,6 +13,9 @@ export type EV5GnosisSafeTxSubmitterProps = z.infer< export type EV5GnosisSafeTxBuilderProps = z.infer< typeof EV5GnosisSafeTxBuilderPropsSchema >; +export type EV5JsonRpcTxSubmitterProps = z.infer< + typeof EV5JsonRpcTxSubmitterPropsSchema +>; 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 index 89c891c09..998d4404b 100644 --- a/typescript/sdk/src/providers/transactions/submitter/schemas.ts +++ b/typescript/sdk/src/providers/transactions/submitter/schemas.ts @@ -5,11 +5,13 @@ 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), diff --git a/typescript/sdk/src/providers/transactions/transformer/TxTransformerInterface.ts b/typescript/sdk/src/providers/transactions/transformer/TxTransformerInterface.ts index 5f2476d9f..25c0dbfb6 100644 --- a/typescript/sdk/src/providers/transactions/transformer/TxTransformerInterface.ts +++ b/typescript/sdk/src/providers/transactions/transformer/TxTransformerInterface.ts @@ -1,4 +1,4 @@ -import { ProtocolType } from '@hyperlane-xyz/utils'; +import { Annotated, ProtocolType } from '@hyperlane-xyz/utils'; import { ProtocolTypedTransaction } from '../../ProviderType.js'; @@ -14,6 +14,6 @@ export interface TxTransformerInterface { * @param txs The array of transactions to transform */ transform( - ...txs: ProtocolTypedTransaction['transaction'][] - ): Promise['transaction'][]>; + ...txs: Annotated['transaction']>[] + ): Promise['transaction']>[]>; } diff --git a/typescript/sdk/src/providers/transactions/transformer/ethersV5/EV5InterchainAccountTxTransformer.ts b/typescript/sdk/src/providers/transactions/transformer/ethersV5/EV5InterchainAccountTxTransformer.ts index b2cce124f..11d77ba6b 100644 --- a/typescript/sdk/src/providers/transactions/transformer/ethersV5/EV5InterchainAccountTxTransformer.ts +++ b/typescript/sdk/src/providers/transactions/transformer/ethersV5/EV5InterchainAccountTxTransformer.ts @@ -1,4 +1,3 @@ -import { ethers } from 'ethers'; import { Logger } from 'pino'; import { assert, objMap, rootLogger } from '@hyperlane-xyz/utils'; @@ -37,18 +36,22 @@ export class EV5InterchainAccountTxTransformer public async transform( ...txs: AnnotatedEV5Transaction[] - ): Promise { + ): Promise { + const transformerChainId = this.multiProvider.getChainId(this.props.chain); const txChainsToInnerCalls: Record = txs.reduce( ( txChainToInnerCalls: Record, { to, data, chainId }: AnnotatedEV5Transaction, ) => { - assert(chainId, 'Invalid PopulatedTransaction: chainId is required'); - assert(to, 'Invalid PopulatedTransaction: to is required'); - assert(data, 'Invalid PopulatedTransaction: data is required'); - const txChain = this.multiProvider.getChainName(chainId); - txChainToInnerCalls[txChain] ||= []; - txChainToInnerCalls[txChain].push({ to, data }); + assert(chainId, 'Invalid PopulatedTransaction: "chainId" is required'); + assert(to, 'Invalid PopulatedTransaction: "to" is required'); + assert(data, 'Invalid PopulatedTransaction: "data" is required'); + assert( + chainId === transformerChainId, + `Transaction chainId ${chainId} does not match transformer chainId ${transformerChainId}`, + ); + txChainToInnerCalls[chainId] ||= []; + txChainToInnerCalls[chainId].push({ to, data }); return txChainToInnerCalls; }, {}, @@ -60,7 +63,7 @@ export class EV5InterchainAccountTxTransformer this.props.config, ); - const transformedTxs: ethers.PopulatedTransaction[] = []; + const transformedTxs: AnnotatedEV5Transaction[] = []; objMap(txChainsToInnerCalls, async (destination, innerCalls) => { transformedTxs.push( await interchainAccountApp.getCallRemote({ diff --git a/typescript/sdk/src/token/EvmERC20WarpModule.ts b/typescript/sdk/src/token/EvmERC20WarpModule.ts index a62e7a05b..85ef112f0 100644 --- a/typescript/sdk/src/token/EvmERC20WarpModule.ts +++ b/typescript/sdk/src/token/EvmERC20WarpModule.ts @@ -10,6 +10,7 @@ import { ContractVerifier, ExplorerLicenseType } from '@hyperlane-xyz/sdk'; import { Address, Domain, + EvmChainId, ProtocolType, addressToBytes32, assert, @@ -29,7 +30,7 @@ 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 { ChainNameOrId } from '../types.js'; +import { ChainName, ChainNameOrId } from '../types.js'; import { normalizeConfig } from '../utils/ism.js'; import { EvmERC20WarpRouteReader } from './EvmERC20WarpRouteReader.js'; @@ -47,8 +48,8 @@ export class EvmERC20WarpModule extends HyperlaneModule< module: 'EvmERC20WarpModule', }); reader: EvmERC20WarpRouteReader; - // We use domainId here because MultiProvider.getDomainId() will always - // return a number, and EVM the domainId and chainId are the same. + public readonly chainName: ChainName; + public readonly chainId: EvmChainId; public readonly domainId: Domain; constructor( @@ -63,6 +64,8 @@ export class EvmERC20WarpModule extends HyperlaneModule< ) { super(args); this.reader = new EvmERC20WarpRouteReader(multiProvider, args.chain); + this.chainName = this.multiProvider.getChainName(args.chain); + this.chainId = multiProvider.getEvmChainId(args.chain); this.domainId = multiProvider.getDomainId(args.chain); this.contractVerifier ??= new ContractVerifier( multiProvider, @@ -149,8 +152,8 @@ export class EvmERC20WarpModule extends HyperlaneModule< ); updateTransactions.push({ + chainId: this.chainId, annotation: `Enrolling Router ${this.args.addresses.deployedTokenRoute} on ${this.args.chain}`, - chainId: this.domainId, to: contractToUpdate.address, data: contractToUpdate.interface.encodeFunctionData( 'enrollRemoteRouters', @@ -205,8 +208,8 @@ export class EvmERC20WarpModule extends HyperlaneModule< }); updateTransactions.push({ + chainId: this.chainId, annotation: `Setting destination gas for ${this.args.addresses.deployedTokenRoute} on ${this.args.chain}`, - chainId: this.domainId, to: contractToUpdate.address, data: contractToUpdate.interface.encodeFunctionData( 'setDestinationGas((uint32,uint256)[])', @@ -254,8 +257,8 @@ export class EvmERC20WarpModule extends HyperlaneModule< this.multiProvider.getProvider(this.domainId), ); updateTransactions.push({ + chainId: this.chainId, annotation: `Setting ISM for Warp Route to ${expectedDeployedIsm}`, - chainId: this.domainId, to: contractToUpdate.address, data: contractToUpdate.interface.encodeFunctionData( 'setInterchainSecurityModule', @@ -280,7 +283,7 @@ export class EvmERC20WarpModule extends HyperlaneModule< expectedConfig: TokenRouterConfig, ): AnnotatedEV5Transaction[] { return transferOwnershipTransactions( - this.multiProvider.getDomainId(this.args.chain), + this.multiProvider.getEvmChainId(this.args.chain), this.args.addresses.deployedTokenRoute, actualConfig, expectedConfig, @@ -310,7 +313,7 @@ export class EvmERC20WarpModule extends HyperlaneModule< // Internally the createTransferOwnershipTx method already checks if the // two owner values are the same and produces an empty tx batch if they are ...transferOwnershipTransactions( - this.domainId, + this.chainId, actualProxyAdmin.address!, actualProxyAdmin, expectedConfig.proxyAdmin, diff --git a/typescript/sdk/src/types.ts b/typescript/sdk/src/types.ts index ca4d4acdf..aad0b5d9c 100644 --- a/typescript/sdk/src/types.ts +++ b/typescript/sdk/src/types.ts @@ -1,12 +1,12 @@ import type { ethers } from 'ethers'; -import type { ChainId, Domain } from '@hyperlane-xyz/utils'; +import type { Domain } from '@hyperlane-xyz/utils'; // An alias for string to clarify type is a chain name export type ChainName = string; // A map of chain names to a value type -export type ChainMap = Record; +export type ChainMap = Record; -export type ChainNameOrId = ChainName | ChainId | Domain; +export type ChainNameOrId = ChainName | Domain; export type Connection = ethers.providers.Provider | ethers.Signer; diff --git a/typescript/sdk/src/utils/gnosisSafe.js b/typescript/sdk/src/utils/gnosisSafe.js index 400931043..c5c14fca8 100644 --- a/typescript/sdk/src/utils/gnosisSafe.js +++ b/typescript/sdk/src/utils/gnosisSafe.js @@ -48,8 +48,8 @@ export async function getSafe(chain, multiProvider, safeAddress) { const signer = multiProvider.getSigner(chain); const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: signer }); - // Get the domain id for the given chain - const domainId = multiProvider.getDomainId(chain); + // Get the chain id for the given chain + const chainId = multiProvider.getChainId(chain); // Get the safe version const safeService = getSafeService(chain, multiProvider); @@ -66,11 +66,11 @@ export async function getSafe(chain, multiProvider, safeAddress) { safeDeploymentsVersions[safeVersion]; multiSend = getMultiSendDeployment({ version: multiSendVersion, - network: domainId, + network: chainId, }); multiSendCallOnly = getMultiSendCallOnlyDeployment({ version: multiSendCallOnlyVersion, - network: domainId, + network: chainId, }); } @@ -78,13 +78,12 @@ export async function getSafe(chain, multiProvider, safeAddress) { ethAdapter, safeAddress, contractNetworks: { - // DomainId == ChainId for EVM Chains - [domainId]: { + [chainId]: { // Use the safe address for multiSendAddress and multiSendCallOnlyAddress // if the contract is not deployed or if the version is not found. - multiSendAddress: multiSend?.networkAddresses[domainId] || safeAddress, + multiSendAddress: multiSend?.networkAddresses[chainId] || safeAddress, multiSendCallOnlyAddress: - multiSendCallOnly?.networkAddresses[domainId] || safeAddress, + multiSendCallOnly?.networkAddresses[chainId] || safeAddress, }, }, }); diff --git a/typescript/sdk/src/utils/transactions.ts b/typescript/sdk/src/utils/transactions.ts new file mode 100644 index 000000000..256df4f60 --- /dev/null +++ b/typescript/sdk/src/utils/transactions.ts @@ -0,0 +1,26 @@ +import { EvmChainId, assert } from '@hyperlane-xyz/utils'; + +import { AnnotatedEV5Transaction } from '../providers/ProviderType.js'; + +/** + * Retrieves the chain ID from the first transaction and verifies all transactions + * are for the same chain. + * + * @param transactions - The list of populated transactions. + * @returns The EVM chain ID that the transactions are for. + * @throws If the transactions are not all for the same chain ID or if chain ID is missing + */ +export function getChainIdFromTxs( + transactions: AnnotatedEV5Transaction[], +): EvmChainId { + const firstTransaction = transactions[0]; + const sameChainIds = transactions.every( + (t: AnnotatedEV5Transaction) => t.chainId === firstTransaction.chainId, + ); + assert(sameChainIds, 'Transactions must be submitted on the same chains'); + assert( + firstTransaction.chainId, + 'Invalid PopulatedTransaction: "chainId" is required', + ); + return firstTransaction.chainId; +} diff --git a/typescript/utils/src/index.ts b/typescript/utils/src/index.ts index 26921fa1c..97e931a83 100644 --- a/typescript/utils/src/index.ts +++ b/typescript/utils/src/index.ts @@ -151,6 +151,7 @@ export { Checkpoint, CheckpointWithId, Domain, + EvmChainId, HexString, MerkleProof, MessageStatus, diff --git a/typescript/utils/src/types.ts b/typescript/utils/src/types.ts index 3d79f0058..c2a3a1fcf 100644 --- a/typescript/utils/src/types.ts +++ b/typescript/utils/src/types.ts @@ -17,6 +17,7 @@ export const ProtocolSmallestUnit = { /********* BASIC TYPES *********/ export type Domain = number; +export type EvmChainId = number; export type ChainId = string | number; export type Address = string; export type AddressBytes32 = string; diff --git a/typescript/widgets/src/chains/ChainAddMenu.tsx b/typescript/widgets/src/chains/ChainAddMenu.tsx index 1b8beb617..102b1bf5e 100644 --- a/typescript/widgets/src/chains/ChainAddMenu.tsx +++ b/typescript/widgets/src/chains/ChainAddMenu.tsx @@ -155,14 +155,7 @@ function tryParseMetadataInput( return failure('name is already in use by another chain'); } - if (multiProvider.tryGetChainMetadata(newMetadata.chainId)) { - return failure('chainId is already in use by another chain'); - } - - if ( - newMetadata.domainId && - multiProvider.tryGetChainMetadata(newMetadata.domainId) - ) { + if (multiProvider.tryGetChainMetadata(newMetadata.domainId)) { return failure('domainId is already in use by another chain'); } diff --git a/typescript/widgets/src/chains/ChainSearchMenu.tsx b/typescript/widgets/src/chains/ChainSearchMenu.tsx index c3fe19066..3d88152f5 100644 --- a/typescript/widgets/src/chains/ChainSearchMenu.tsx +++ b/typescript/widgets/src/chains/ChainSearchMenu.tsx @@ -241,7 +241,7 @@ function chainSearch({ chain.name.includes(queryFormatted) || chain.displayName?.toLowerCase().includes(queryFormatted) || chain.chainId.toString().includes(queryFormatted) || - chain.domainId?.toString().includes(queryFormatted), + chain.domainId.toString().includes(queryFormatted), ) // Filter options .filter((chain) => {