@hyperlane-xyz/sdk 41.3.1 → 43.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/dist/ccip/consts.d.ts.map +1 -1
  2. package/dist/ccip/consts.js +20 -0
  3. package/dist/ccip/consts.js.map +1 -1
  4. package/dist/consts/multisigIsm.d.ts.map +1 -1
  5. package/dist/consts/multisigIsm.js +32 -0
  6. package/dist/consts/multisigIsm.js.map +1 -1
  7. package/dist/contracts/contracts.d.ts.map +1 -1
  8. package/dist/contracts/contracts.js +15 -0
  9. package/dist/contracts/contracts.js.map +1 -1
  10. package/dist/contracts/contracts.test.d.ts +2 -0
  11. package/dist/contracts/contracts.test.d.ts.map +1 -0
  12. package/dist/contracts/contracts.test.js +88 -0
  13. package/dist/contracts/contracts.test.js.map +1 -0
  14. package/dist/core/types.d.ts +48 -4158
  15. package/dist/core/types.d.ts.map +1 -1
  16. package/dist/core/types.js +21 -3
  17. package/dist/core/types.js.map +1 -1
  18. package/dist/core/types.test.js +58 -0
  19. package/dist/core/types.test.js.map +1 -1
  20. package/dist/deploy/HyperlaneDeployer.js +1 -1
  21. package/dist/deploy/proxy.d.ts +8 -40
  22. package/dist/deploy/proxy.d.ts.map +1 -1
  23. package/dist/deploy/proxy.js +4 -4
  24. package/dist/deploy/proxy.js.map +1 -1
  25. package/dist/deploy/types.d.ts +1 -19
  26. package/dist/deploy/types.d.ts.map +1 -1
  27. package/dist/deploy/warp.d.ts +119 -3
  28. package/dist/deploy/warp.d.ts.map +1 -1
  29. package/dist/deploy/warp.js +696 -33
  30. package/dist/deploy/warp.js.map +1 -1
  31. package/dist/deploy/warp.test.d.ts +2 -0
  32. package/dist/deploy/warp.test.d.ts.map +1 -0
  33. package/dist/deploy/warp.test.js +358 -0
  34. package/dist/deploy/warp.test.js.map +1 -0
  35. package/dist/deploy/warpHybridPlan.d.ts +104 -0
  36. package/dist/deploy/warpHybridPlan.d.ts.map +1 -0
  37. package/dist/deploy/warpHybridPlan.js +178 -0
  38. package/dist/deploy/warpHybridPlan.js.map +1 -0
  39. package/dist/deploy/warpHybridPlan.test.d.ts +2 -0
  40. package/dist/deploy/warpHybridPlan.test.d.ts.map +1 -0
  41. package/dist/deploy/warpHybridPlan.test.js +141 -0
  42. package/dist/deploy/warpHybridPlan.test.js.map +1 -0
  43. package/dist/fee/EvmTokenFeeDeployer.d.ts.map +1 -1
  44. package/dist/fee/EvmTokenFeeDeployer.hardhat-test.js +68 -0
  45. package/dist/fee/EvmTokenFeeDeployer.hardhat-test.js.map +1 -1
  46. package/dist/fee/EvmTokenFeeDeployer.js +18 -10
  47. package/dist/fee/EvmTokenFeeDeployer.js.map +1 -1
  48. package/dist/fee/EvmTokenFeeModule.d.ts.map +1 -1
  49. package/dist/fee/EvmTokenFeeModule.hardhat-test.js +18 -8
  50. package/dist/fee/EvmTokenFeeModule.hardhat-test.js.map +1 -1
  51. package/dist/fee/EvmTokenFeeModule.js +8 -1
  52. package/dist/fee/EvmTokenFeeModule.js.map +1 -1
  53. package/dist/fee/EvmTokenFeeReader.d.ts +2 -2
  54. package/dist/fee/EvmTokenFeeReader.d.ts.map +1 -1
  55. package/dist/fee/EvmTokenFeeReader.js.map +1 -1
  56. package/dist/fee/feeConfigMapping.d.ts.map +1 -1
  57. package/dist/fee/feeConfigMapping.js +1 -0
  58. package/dist/fee/feeConfigMapping.js.map +1 -1
  59. package/dist/fee/types.d.ts +147 -646
  60. package/dist/fee/types.d.ts.map +1 -1
  61. package/dist/fee/types.js +26 -17
  62. package/dist/fee/types.js.map +1 -1
  63. package/dist/fork/types.d.ts +125 -1924
  64. package/dist/fork/types.d.ts.map +1 -1
  65. package/dist/fork/types.js +3 -3
  66. package/dist/fork/types.js.map +1 -1
  67. package/dist/gas/oracle/types.d.ts +5 -56
  68. package/dist/gas/oracle/types.d.ts.map +1 -1
  69. package/dist/hook/EvmHookModule.d.ts +1 -1
  70. package/dist/hook/EvmHookModule.d.ts.map +1 -1
  71. package/dist/hook/EvmHookModule.hardhat-test.js +12 -1
  72. package/dist/hook/EvmHookModule.hardhat-test.js.map +1 -1
  73. package/dist/hook/EvmHookModule.js +19 -3
  74. package/dist/hook/EvmHookModule.js.map +1 -1
  75. package/dist/hook/EvmHookReader.d.ts +10 -0
  76. package/dist/hook/EvmHookReader.d.ts.map +1 -1
  77. package/dist/hook/EvmHookReader.js +92 -11
  78. package/dist/hook/EvmHookReader.js.map +1 -1
  79. package/dist/hook/EvmHookReader.test.js +155 -1
  80. package/dist/hook/EvmHookReader.test.js.map +1 -1
  81. package/dist/hook/HyperlaneHookDeployer.d.ts +12 -0
  82. package/dist/hook/HyperlaneHookDeployer.d.ts.map +1 -1
  83. package/dist/hook/HyperlaneHookDeployer.hardhat-test.d.ts +2 -0
  84. package/dist/hook/HyperlaneHookDeployer.hardhat-test.d.ts.map +1 -0
  85. package/dist/hook/HyperlaneHookDeployer.hardhat-test.js +322 -0
  86. package/dist/hook/HyperlaneHookDeployer.hardhat-test.js.map +1 -0
  87. package/dist/hook/HyperlaneHookDeployer.js +262 -5
  88. package/dist/hook/HyperlaneHookDeployer.js.map +1 -1
  89. package/dist/hook/types.d.ts +72 -2223
  90. package/dist/hook/types.d.ts.map +1 -1
  91. package/dist/hook/types.js +66 -10
  92. package/dist/hook/types.js.map +1 -1
  93. package/dist/hook/types.test.js +21 -1
  94. package/dist/hook/types.test.js.map +1 -1
  95. package/dist/hook/updates.d.ts +1 -0
  96. package/dist/hook/updates.d.ts.map +1 -1
  97. package/dist/hook/updates.js +2 -2
  98. package/dist/hook/updates.js.map +1 -1
  99. package/dist/hook/utils.d.ts +28 -1
  100. package/dist/hook/utils.d.ts.map +1 -1
  101. package/dist/hook/utils.js +89 -0
  102. package/dist/hook/utils.js.map +1 -1
  103. package/dist/ica/types.d.ts +35 -1570
  104. package/dist/ica/types.d.ts.map +1 -1
  105. package/dist/ica/types.js +1 -1
  106. package/dist/ica/types.js.map +1 -1
  107. package/dist/index.d.ts +7 -6
  108. package/dist/index.d.ts.map +1 -1
  109. package/dist/index.js +7 -6
  110. package/dist/index.js.map +1 -1
  111. package/dist/ism/EvmIsmModule.d.ts +29 -3
  112. package/dist/ism/EvmIsmModule.d.ts.map +1 -1
  113. package/dist/ism/EvmIsmModule.hardhat-test.js +512 -3
  114. package/dist/ism/EvmIsmModule.hardhat-test.js.map +1 -1
  115. package/dist/ism/EvmIsmModule.js +239 -21
  116. package/dist/ism/EvmIsmModule.js.map +1 -1
  117. package/dist/ism/EvmIsmReader.d.ts.map +1 -1
  118. package/dist/ism/EvmIsmReader.js +77 -1
  119. package/dist/ism/EvmIsmReader.js.map +1 -1
  120. package/dist/ism/EvmIsmReader.test.js +245 -4
  121. package/dist/ism/EvmIsmReader.test.js.map +1 -1
  122. package/dist/ism/HyperlaneIsmFactory.d.ts +17 -5
  123. package/dist/ism/HyperlaneIsmFactory.d.ts.map +1 -1
  124. package/dist/ism/HyperlaneIsmFactory.hardhat-test.js +431 -4
  125. package/dist/ism/HyperlaneIsmFactory.hardhat-test.js.map +1 -1
  126. package/dist/ism/HyperlaneIsmFactory.js +121 -11
  127. package/dist/ism/HyperlaneIsmFactory.js.map +1 -1
  128. package/dist/ism/delayedFlow.d.ts +31 -0
  129. package/dist/ism/delayedFlow.d.ts.map +1 -0
  130. package/dist/ism/delayedFlow.js +33 -0
  131. package/dist/ism/delayedFlow.js.map +1 -0
  132. package/dist/ism/types.d.ts +86 -237
  133. package/dist/ism/types.d.ts.map +1 -1
  134. package/dist/ism/types.js +270 -20
  135. package/dist/ism/types.js.map +1 -1
  136. package/dist/ism/types.test.js +433 -1
  137. package/dist/ism/types.test.js.map +1 -1
  138. package/dist/ism/utils.d.ts.map +1 -1
  139. package/dist/ism/utils.js +113 -3
  140. package/dist/ism/utils.js.map +1 -1
  141. package/dist/ism/utils.test.js +44 -0
  142. package/dist/ism/utils.test.js.map +1 -1
  143. package/dist/metadata/agentConfig.d.ts +537 -10384
  144. package/dist/metadata/agentConfig.d.ts.map +1 -1
  145. package/dist/metadata/agentConfig.js +14 -16
  146. package/dist/metadata/agentConfig.js.map +1 -1
  147. package/dist/metadata/chainMetadataTypes.d.ts +70 -4678
  148. package/dist/metadata/chainMetadataTypes.d.ts.map +1 -1
  149. package/dist/metadata/chainMetadataTypes.js +5 -5
  150. package/dist/metadata/chainMetadataTypes.js.map +1 -1
  151. package/dist/metadata/customZodTypes.d.ts +5 -5
  152. package/dist/metadata/customZodTypes.d.ts.map +1 -1
  153. package/dist/metadata/customZodTypes.js +4 -5
  154. package/dist/metadata/customZodTypes.js.map +1 -1
  155. package/dist/metadata/deploymentArtifacts.d.ts +1 -13
  156. package/dist/metadata/deploymentArtifacts.d.ts.map +1 -1
  157. package/dist/metadata/matchingList.d.ts +12 -40
  158. package/dist/metadata/matchingList.d.ts.map +1 -1
  159. package/dist/metadata/warpRouteConfig.d.ts +8 -114
  160. package/dist/metadata/warpRouteConfig.d.ts.map +1 -1
  161. package/dist/metadata/warpRouteConfig.js +3 -3
  162. package/dist/metadata/warpRouteConfig.js.map +1 -1
  163. package/dist/middleware/account/InterchainAccount.d.ts.map +1 -1
  164. package/dist/middleware/account/InterchainAccount.js +12 -8
  165. package/dist/middleware/account/InterchainAccount.js.map +1 -1
  166. package/dist/middleware/account/InterchainAccount.test.js +22 -3
  167. package/dist/middleware/account/InterchainAccount.test.js.map +1 -1
  168. package/dist/middleware/account/icaCalls.d.ts +13 -145
  169. package/dist/middleware/account/icaCalls.d.ts.map +1 -1
  170. package/dist/middleware/account/types.d.ts +11 -105
  171. package/dist/middleware/account/types.d.ts.map +1 -1
  172. package/dist/predicate/PredicateApiClient.d.ts +1 -11
  173. package/dist/predicate/PredicateApiClient.d.ts.map +1 -1
  174. package/dist/providers/MultiProvider.d.ts.map +1 -1
  175. package/dist/providers/MultiProvider.js +3 -2
  176. package/dist/providers/MultiProvider.js.map +1 -1
  177. package/dist/providers/MultiProviderAdapter.d.ts +3 -3
  178. package/dist/providers/MultiProviderAdapter.d.ts.map +1 -1
  179. package/dist/providers/MultiProviderAdapter.js +2 -1
  180. package/dist/providers/MultiProviderAdapter.js.map +1 -1
  181. package/dist/providers/SmartProvider/HyperlaneJsonRpcProvider.d.ts.map +1 -1
  182. package/dist/providers/SmartProvider/HyperlaneJsonRpcProvider.js +4 -0
  183. package/dist/providers/SmartProvider/HyperlaneJsonRpcProvider.js.map +1 -1
  184. package/dist/providers/transactionFeeEstimators.d.ts +16 -9
  185. package/dist/providers/transactionFeeEstimators.d.ts.map +1 -1
  186. package/dist/providers/transactionFeeEstimators.js +66 -17
  187. package/dist/providers/transactionFeeEstimators.js.map +1 -1
  188. package/dist/providers/transactionFeeEstimators.test.js +153 -1
  189. package/dist/providers/transactionFeeEstimators.test.js.map +1 -1
  190. package/dist/providers/transactions/submitter/builder/types.d.ts +13 -280
  191. package/dist/providers/transactions/submitter/builder/types.d.ts.map +1 -1
  192. package/dist/providers/transactions/submitter/builder/types.js +2 -4
  193. package/dist/providers/transactions/submitter/builder/types.js.map +1 -1
  194. package/dist/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.d.ts +2 -0
  195. package/dist/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.d.ts.map +1 -1
  196. package/dist/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.js +15 -7
  197. package/dist/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.js.map +1 -1
  198. package/dist/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.test.d.ts +2 -0
  199. package/dist/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.test.d.ts.map +1 -0
  200. package/dist/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.test.js +145 -0
  201. package/dist/providers/transactions/submitter/ethersV5/EV5GnosisSafeTxSubmitter.test.js.map +1 -0
  202. package/dist/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.d.ts +14 -1
  203. package/dist/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.d.ts.map +1 -1
  204. package/dist/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.js +46 -5
  205. package/dist/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.js.map +1 -1
  206. package/dist/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.test.d.ts +2 -0
  207. package/dist/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.test.d.ts.map +1 -0
  208. package/dist/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.test.js +125 -0
  209. package/dist/providers/transactions/submitter/ethersV5/EV5JsonRpcTxSubmitter.test.js.map +1 -0
  210. package/dist/providers/transactions/submitter/ethersV5/types.d.ts +30 -102
  211. package/dist/providers/transactions/submitter/ethersV5/types.d.ts.map +1 -1
  212. package/dist/providers/transactions/submitter/ethersV5/types.js +3 -21
  213. package/dist/providers/transactions/submitter/ethersV5/types.js.map +1 -1
  214. package/dist/providers/transactions/submitter/types.d.ts +5 -51
  215. package/dist/providers/transactions/submitter/types.d.ts.map +1 -1
  216. package/dist/providers/transactions/types.d.ts +1 -9
  217. package/dist/providers/transactions/types.d.ts.map +1 -1
  218. package/dist/router/HyperlaneRouterDeployer.d.ts +3 -1
  219. package/dist/router/HyperlaneRouterDeployer.d.ts.map +1 -1
  220. package/dist/router/HyperlaneRouterDeployer.js +4 -2
  221. package/dist/router/HyperlaneRouterDeployer.js.map +1 -1
  222. package/dist/router/types.d.ts +33 -1824
  223. package/dist/router/types.d.ts.map +1 -1
  224. package/dist/router/types.js +4 -4
  225. package/dist/router/types.js.map +1 -1
  226. package/dist/rpc/evm/EvmEventLogsReader.d.ts +19 -27
  227. package/dist/rpc/evm/EvmEventLogsReader.d.ts.map +1 -1
  228. package/dist/rpc/evm/EvmEventLogsReader.js +23 -0
  229. package/dist/rpc/evm/EvmEventLogsReader.js.map +1 -1
  230. package/dist/rpc/evm/EvmEventLogsReader.test.js +53 -1
  231. package/dist/rpc/evm/EvmEventLogsReader.test.js.map +1 -1
  232. package/dist/signers/turnkeyClient.d.ts +1 -15
  233. package/dist/signers/turnkeyClient.d.ts.map +1 -1
  234. package/dist/test/testUtils.d.ts +1 -1
  235. package/dist/test/testUtils.d.ts.map +1 -1
  236. package/dist/test/testUtils.js +17 -0
  237. package/dist/test/testUtils.js.map +1 -1
  238. package/dist/test/testUtils.test.d.ts +2 -0
  239. package/dist/test/testUtils.test.d.ts.map +1 -0
  240. package/dist/test/testUtils.test.js +28 -0
  241. package/dist/test/testUtils.test.js.map +1 -0
  242. package/dist/timelock/types.d.ts +8 -32
  243. package/dist/timelock/types.d.ts.map +1 -1
  244. package/dist/token/EvmWarpModule.d.ts +44 -8
  245. package/dist/token/EvmWarpModule.d.ts.map +1 -1
  246. package/dist/token/EvmWarpModule.hardhat-test.js +574 -4
  247. package/dist/token/EvmWarpModule.hardhat-test.js.map +1 -1
  248. package/dist/token/EvmWarpModule.js +237 -25
  249. package/dist/token/EvmWarpModule.js.map +1 -1
  250. package/dist/token/EvmWarpRouteReader.d.ts.map +1 -1
  251. package/dist/token/EvmWarpRouteReader.js +36 -19
  252. package/dist/token/EvmWarpRouteReader.js.map +1 -1
  253. package/dist/token/EvmWarpRouteReader.test.js +219 -2
  254. package/dist/token/EvmWarpRouteReader.test.js.map +1 -1
  255. package/dist/token/EvmXERC20Reader.d.ts +9 -21
  256. package/dist/token/EvmXERC20Reader.d.ts.map +1 -1
  257. package/dist/token/EvmXERC20Reader.js +24 -48
  258. package/dist/token/EvmXERC20Reader.js.map +1 -1
  259. package/dist/token/EvmXERC20Reader.test.js +97 -0
  260. package/dist/token/EvmXERC20Reader.test.js.map +1 -1
  261. package/dist/token/ITokenMetadata.d.ts +12 -130
  262. package/dist/token/ITokenMetadata.d.ts.map +1 -1
  263. package/dist/token/ITokenMetadata.js +2 -2
  264. package/dist/token/ITokenMetadata.js.map +1 -1
  265. package/dist/token/TokenConnection.d.ts +3 -35
  266. package/dist/token/TokenConnection.d.ts.map +1 -1
  267. package/dist/token/configUtils.d.ts +17 -7
  268. package/dist/token/configUtils.d.ts.map +1 -1
  269. package/dist/token/configUtils.js +124 -0
  270. package/dist/token/configUtils.js.map +1 -1
  271. package/dist/token/configUtils.test.js +212 -11
  272. package/dist/token/configUtils.test.js.map +1 -1
  273. package/dist/token/deploy.d.ts +3 -1
  274. package/dist/token/deploy.d.ts.map +1 -1
  275. package/dist/token/deploy.hardhat-test.js +617 -6
  276. package/dist/token/deploy.hardhat-test.js.map +1 -1
  277. package/dist/token/deploy.js +25 -6
  278. package/dist/token/deploy.js.map +1 -1
  279. package/dist/token/types.d.ts +4373 -25929
  280. package/dist/token/types.d.ts.map +1 -1
  281. package/dist/token/types.js +10 -12
  282. package/dist/token/types.js.map +1 -1
  283. package/dist/token/types.test.js +48 -0
  284. package/dist/token/types.test.js.map +1 -1
  285. package/dist/token/warpCheck.d.ts.map +1 -1
  286. package/dist/token/warpCheck.js +36 -1
  287. package/dist/token/warpCheck.js.map +1 -1
  288. package/dist/token/xerc20-abi.d.ts +31 -0
  289. package/dist/token/xerc20-abi.d.ts.map +1 -1
  290. package/dist/token/xerc20-abi.js +40 -0
  291. package/dist/token/xerc20-abi.js.map +1 -1
  292. package/dist/token/xerc20-limits.d.ts +63 -0
  293. package/dist/token/xerc20-limits.d.ts.map +1 -0
  294. package/dist/token/xerc20-limits.js +80 -0
  295. package/dist/token/xerc20-limits.js.map +1 -0
  296. package/dist/token/xerc20.d.ts +30 -1
  297. package/dist/token/xerc20.d.ts.map +1 -1
  298. package/dist/token/xerc20.js +137 -54
  299. package/dist/token/xerc20.js.map +1 -1
  300. package/dist/token/xerc20.test.js +461 -169
  301. package/dist/token/xerc20.test.js.map +1 -1
  302. package/dist/types.d.ts +6 -36
  303. package/dist/types.d.ts.map +1 -1
  304. package/dist/types.js +1 -1
  305. package/dist/types.js.map +1 -1
  306. package/dist/utils/cosmos.d.ts +113 -844
  307. package/dist/utils/cosmos.d.ts.map +1 -1
  308. package/dist/utils/cosmos.js +50 -91
  309. package/dist/utils/cosmos.js.map +1 -1
  310. package/dist/utils/ism.d.ts +167 -1
  311. package/dist/utils/ism.d.ts.map +1 -1
  312. package/dist/utils/ism.js +412 -2
  313. package/dist/utils/ism.js.map +1 -1
  314. package/dist/utils/ism.test.d.ts +2 -0
  315. package/dist/utils/ism.test.d.ts.map +1 -0
  316. package/dist/utils/ism.test.js +372 -0
  317. package/dist/utils/ism.test.js.map +1 -0
  318. package/dist/utils/schemas.d.ts +3 -3
  319. package/dist/utils/schemas.d.ts.map +1 -1
  320. package/dist/utils/schemas.js +2 -1
  321. package/dist/utils/schemas.js.map +1 -1
  322. package/dist/warp/types.d.ts +25 -367
  323. package/dist/warp/types.d.ts.map +1 -1
  324. package/package.json +11 -11
@@ -3,16 +3,18 @@ import chai, { expect } from 'chai';
3
3
  import chaiAsPromised from 'chai-as-promised';
4
4
  import hre from 'hardhat';
5
5
  import sinon from 'sinon';
6
- import { BlacklistIsm__factory, RateLimitedIsm__factory, StaticAggregationIsm__factory, TestLegacyBlacklistIsm__factory, } from '@hyperlane-xyz/core';
7
- import { eqAddress, rootLogger } from '@hyperlane-xyz/utils';
6
+ import { BlacklistIsm__factory, DefaultIsm__factory, DelayedFlowRouterHookIsm__factory, HypERC20__factory, NetFlowRateLimitedHookIsm__factory, PausableIsm__factory, RateLimitedIsm__factory, StaticAggregationIsm__factory, TestLegacyBlacklistIsm__factory, } from '@hyperlane-xyz/core';
7
+ import { addressToBytes32, eqAddress, rootLogger, } from '@hyperlane-xyz/utils';
8
8
  import { TestChainName, testChains } from '../consts/testChains.js';
9
9
  import { TestCoreDeployer } from '../core/TestCoreDeployer.js';
10
10
  import { HyperlaneProxyFactoryDeployer } from '../deploy/HyperlaneProxyFactoryDeployer.js';
11
+ import { buildDelayedFlowEnrollmentTxs, } from '../deploy/warp.js';
11
12
  import { MultiProvider } from '../providers/MultiProvider.js';
12
13
  import { EvmEventLogsReader } from '../rpc/evm/EvmEventLogsReader.js';
13
14
  import { randomAddress, randomIsmConfig, randomMultisigIsmConfig, } from '../test/testUtils.js';
14
- import { normalizeConfig } from '../utils/ism.js';
15
+ import { collectHybridIsmNodes, normalizeConfig } from '../utils/ism.js';
15
16
  import { EvmIsmModule } from './EvmIsmModule.js';
17
+ import { EvmIsmReader } from './EvmIsmReader.js';
16
18
  import { HyperlaneIsmFactory } from './HyperlaneIsmFactory.js';
17
19
  import { IsmType, ModuleType, } from './types.js';
18
20
  chai.use(chaiAsPromised);
@@ -31,6 +33,8 @@ describe('EvmIsmModule', async () => {
31
33
  const legacyDeploymentBlocks = new Map();
32
34
  let legacyExplorerMetadataStub;
33
35
  let legacyDeploymentBlockStub;
36
+ // paired TokenRouter required by the warp-route hybrid hook/ISM constructors
37
+ let warpRouterAddress;
34
38
  before(async () => {
35
39
  const [signer, funder] = await hre.ethers.getSigners();
36
40
  fundingAccount = funder;
@@ -47,6 +51,7 @@ describe('EvmIsmModule', async () => {
47
51
  const legacyIsmFactory = new HyperlaneIsmFactory(contractsMap, multiProvider);
48
52
  // mailbox
49
53
  mailboxAddress = (await new TestCoreDeployer(multiProvider, legacyIsmFactory).deployApp()).getContracts(chain).mailbox.address;
54
+ warpRouterAddress = (await new HypERC20__factory(signer).deploy(18, 1, 1, mailboxAddress)).address;
50
55
  });
51
56
  beforeEach(async () => {
52
57
  // Reset the MultiProvider for each test
@@ -153,6 +158,29 @@ describe('EvmIsmModule', async () => {
153
158
  },
154
159
  });
155
160
  }
161
+ /**
162
+ * Hybrid hook/ISMs are only valid inside a mandatory aggregation beside an
163
+ * authenticating ISM, which is also how a warp route always installs them.
164
+ * The wrapper holds `hybrid` by reference, so tests can keep mutating the
165
+ * node in place between create and update.
166
+ */
167
+ function hybridAgg(hybrid) {
168
+ return {
169
+ type: IsmType.AGGREGATION,
170
+ threshold: 2,
171
+ modules: [
172
+ { type: IsmType.TRUSTED_RELAYER, relayer: mailboxAddress },
173
+ hybrid,
174
+ ],
175
+ };
176
+ }
177
+ /** Address of the hybrid leaf inside the module's installed tree. */
178
+ async function hybridLeaf(ism) {
179
+ const derived = await new EvmIsmReader(multiProvider, chain).deriveIsmConfig(ism.serialize().deployedIsm);
180
+ const [leaf] = collectHybridIsmNodes(derived);
181
+ assert(leaf && 'address' in leaf && typeof leaf.address === 'string', 'expected a deployed hybrid leaf');
182
+ return leaf.address;
183
+ }
156
184
  describe('create', async () => {
157
185
  it('deploys a simple ism', async () => {
158
186
  const config = randomMultisigIsmConfig(3, 5);
@@ -241,6 +269,45 @@ describe('EvmIsmModule', async () => {
241
269
  multiProvider,
242
270
  })).to.be.rejectedWith(BLACKLIST_COMPOSITION_ERROR);
243
271
  });
272
+ it('deploys a mailbox default ism', async () => {
273
+ const config = {
274
+ type: IsmType.MAILBOX_DEFAULT,
275
+ };
276
+ await createIsm(config);
277
+ });
278
+ it('deploys a net flow rate limited hook ism and transfers ownership to non-deployer', async () => {
279
+ const owner = randomAddress();
280
+ const config = {
281
+ type: IsmType.NET_FLOW_RATE_LIMITED,
282
+ warpRouter: warpRouterAddress,
283
+ thresholdBps: 500,
284
+ duration: 86400n,
285
+ owner,
286
+ };
287
+ const { ism } = await createIsm(hybridAgg(config));
288
+ const netFlowIsm = NetFlowRateLimitedHookIsm__factory.connect(await hybridLeaf(ism), multiProvider.getProvider(chain));
289
+ expect((await netFlowIsm.owner()).toLowerCase()).to.equal(owner.toLowerCase());
290
+ expect((await netFlowIsm.warpRouter()).toLowerCase()).to.equal(warpRouterAddress.toLowerCase());
291
+ });
292
+ it('deploys a delayed flow router hook ism, enrolling routers before transferring ownership', async () => {
293
+ // owner is a non-deployer EOA: the deploy only succeeds if the
294
+ // owner-gated enrollment happens BEFORE the ownership transfer
295
+ const owner = randomAddress();
296
+ const remoteRouter = addressToBytes32(randomAddress()).toLowerCase();
297
+ const config = {
298
+ type: IsmType.DELAYED_FLOW_ROUTER,
299
+ warpRouter: warpRouterAddress,
300
+ thresholdBps: 10000,
301
+ maxDelay: 3600,
302
+ duration: 86400n,
303
+ owner,
304
+ remoteIsms: { [TestChainName.test2]: remoteRouter },
305
+ };
306
+ const { ism } = await createIsm(hybridAgg(config));
307
+ const delayedIsm = DelayedFlowRouterHookIsm__factory.connect(await hybridLeaf(ism), multiProvider.getProvider(chain));
308
+ expect(await delayedIsm.routers(multiProvider.getDomainId(TestChainName.test2))).to.equal(remoteRouter);
309
+ expect((await delayedIsm.owner()).toLowerCase()).to.equal(owner.toLowerCase());
310
+ });
244
311
  for (let i = 0; i < 16; i++) {
245
312
  it(`deploys a random ism config #${i}`, async () => {
246
313
  const config = randomIsmConfig();
@@ -253,6 +320,40 @@ describe('EvmIsmModule', async () => {
253
320
  });
254
321
  });
255
322
  describe('update', async () => {
323
+ it('applies a pausable state change when the signer is the owner', async () => {
324
+ const config = {
325
+ type: IsmType.PAUSABLE,
326
+ owner: await multiProvider.getSignerAddress(chain),
327
+ paused: false,
328
+ };
329
+ const { ism, initialIsmAddress } = await createIsm(config);
330
+ const pausable = PausableIsm__factory.connect(initialIsmAddress, multiProvider.getProvider(chain));
331
+ const target = { ...config, paused: true };
332
+ const txs = await ism.update(target);
333
+ testConfig = target;
334
+ expect(txs).to.be.empty;
335
+ expect(await pausable.paused()).to.be.true;
336
+ });
337
+ it('returns a pausable state change when the signer is not the owner', async () => {
338
+ const owner = randomAddress();
339
+ const config = {
340
+ type: IsmType.PAUSABLE,
341
+ owner,
342
+ paused: false,
343
+ };
344
+ const { ism, initialIsmAddress } = await createIsm(config);
345
+ const pausable = PausableIsm__factory.connect(initialIsmAddress, multiProvider.getProvider(chain));
346
+ const target = { ...config, paused: true };
347
+ const txs = await ism.update(target);
348
+ expect(txs).to.have.length(1);
349
+ expect(txs[0].to).to.equal(initialIsmAddress);
350
+ expect(txs[0].data).to.equal(PausableIsm__factory.createInterface().encodeFunctionData('pause'));
351
+ expect(await pausable.paused()).to.be.false;
352
+ const ownerMultiProvider = await impersonateAccount(owner);
353
+ await ownerMultiProvider.sendTransaction(chain, txs[0]);
354
+ testConfig = target;
355
+ expect(await pausable.paused()).to.be.true;
356
+ });
256
357
  for (const type of [IsmType.ROUTING, IsmType.FALLBACK_ROUTING]) {
257
358
  beforeEach(() => {
258
359
  exampleRoutingConfig.type = type;
@@ -765,6 +866,414 @@ describe('EvmIsmModule', async () => {
765
866
  expect(blacklistFound).to.be.true;
766
867
  });
767
868
  });
869
+ it('no changes to an existing mailbox default ism means no redeployment or updates', async () => {
870
+ const config = {
871
+ type: IsmType.MAILBOX_DEFAULT,
872
+ };
873
+ const { ism, initialIsmAddress } = await createIsm(config);
874
+ await expectTxsAndUpdate(ism, config, 0);
875
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
876
+ .true;
877
+ });
878
+ it('redeploys a mailbox default ism that defers to a different mailbox', async () => {
879
+ const config = {
880
+ type: IsmType.MAILBOX_DEFAULT,
881
+ };
882
+ const { initialIsmAddress } = await createIsm(config);
883
+ // A DefaultIsm's mailbox is an immutable constructor arg the reader
884
+ // omits, so this module — pointed at the same instance but at a
885
+ // different mailbox — sees an identical `{ type }` config while the
886
+ // instance routes through the wrong mailbox's default ISM.
887
+ const otherMailbox = warpRouterAddress;
888
+ const reboundModule = new EvmIsmModule(multiProvider, {
889
+ chain,
890
+ config,
891
+ addresses: {
892
+ ...factoryAddresses,
893
+ mailbox: otherMailbox,
894
+ deployedIsm: initialIsmAddress,
895
+ },
896
+ });
897
+ // redeploys internally (MAILBOX_DEFAULT is immutable), emitting no txs
898
+ expect(await reboundModule.update(config)).to.deep.equal([]);
899
+ const redeployedIsm = reboundModule.serialize().deployedIsm;
900
+ expect(eqAddress(redeployedIsm, initialIsmAddress)).to.be.false;
901
+ expect(eqAddress(await DefaultIsm__factory.connect(redeployedIsm, multiProvider.getProvider(chain)).mailbox(), otherMailbox)).to.be.true;
902
+ });
903
+ it('redeploys when changing a mailbox default ism to another type', async () => {
904
+ const { ism, initialIsmAddress } = await createIsm({
905
+ type: IsmType.MAILBOX_DEFAULT,
906
+ });
907
+ const trustedRelayerConfig = {
908
+ type: IsmType.TRUSTED_RELAYER,
909
+ relayer: randomAddress(),
910
+ };
911
+ // keep testConfig in sync for the afterEach read-back assertion
912
+ testConfig = trustedRelayerConfig;
913
+ // update() redeploys internally and emits no txs
914
+ await expectTxsAndUpdate(ism, trustedRelayerConfig, 0);
915
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
916
+ .false;
917
+ });
918
+ it('transfers netFlowRateLimitedHookIsm ownership in-place on owner change', async () => {
919
+ const signerAddress = await multiProvider.getSignerAddress(chain);
920
+ const netFlowConfig = {
921
+ type: IsmType.NET_FLOW_RATE_LIMITED,
922
+ warpRouter: warpRouterAddress,
923
+ thresholdBps: 500,
924
+ duration: 86400n,
925
+ owner: signerAddress,
926
+ };
927
+ const { ism, initialIsmAddress } = await createIsm(hybridAgg(netFlowConfig));
928
+ const newOwner = randomAddress();
929
+ // mutate in-place so testConfig (same reference) stays in sync for afterEach
930
+ netFlowConfig.owner = newOwner;
931
+ // NET_FLOW_RATE_LIMITED is mutable — update() transfers ownership in-place (1 tx)
932
+ await expectTxsAndUpdate(ism, hybridAgg(netFlowConfig), 1);
933
+ // same contract address — no redeploy
934
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
935
+ .true;
936
+ const netFlowIsm = NetFlowRateLimitedHookIsm__factory.connect(await hybridLeaf(ism), multiProvider.getProvider(chain));
937
+ expect((await netFlowIsm.owner()).toLowerCase()).to.equal(newOwner.toLowerCase());
938
+ });
939
+ it('redeploys a new netFlowRateLimitedHookIsm on thresholdBps change (immutable)', async () => {
940
+ const signerAddress = await multiProvider.getSignerAddress(chain);
941
+ const netFlowConfig = {
942
+ type: IsmType.NET_FLOW_RATE_LIMITED,
943
+ warpRouter: warpRouterAddress,
944
+ thresholdBps: 500,
945
+ duration: 86400n,
946
+ owner: signerAddress,
947
+ };
948
+ const { ism, initialIsmAddress } = await createIsm(hybridAgg(netFlowConfig));
949
+ // thresholdBps is immutable on-chain; changing it must redeploy
950
+ netFlowConfig.thresholdBps = 750;
951
+ // update() redeploys internally and emits no txs
952
+ await expectTxsAndUpdate(ism, hybridAgg(netFlowConfig), 0);
953
+ // different contract address — redeployed
954
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
955
+ .false;
956
+ const netFlowIsm = NetFlowRateLimitedHookIsm__factory.connect(await hybridLeaf(ism), multiProvider.getProvider(chain));
957
+ expect((await netFlowIsm.thresholdBps()).toString()).to.equal('750');
958
+ });
959
+ it('updates netFlowRateLimitedHookIsm owner in-place inside an aggregation ism without redeploying the container', async () => {
960
+ // the contract mandates composing NetFlowRateLimitedHookIsm under an
961
+ // authenticating ISM, so aggregation-wrapped is the primary shape
962
+ const signerAddress = await multiProvider.getSignerAddress(chain);
963
+ const netFlowConfig = {
964
+ type: IsmType.NET_FLOW_RATE_LIMITED,
965
+ warpRouter: warpRouterAddress,
966
+ thresholdBps: 500,
967
+ duration: 86400n,
968
+ owner: signerAddress,
969
+ };
970
+ const aggregationConfig = {
971
+ type: IsmType.AGGREGATION,
972
+ modules: [netFlowConfig, randomMultisigIsmConfig(3, 5)],
973
+ threshold: 2,
974
+ };
975
+ const { ism, initialIsmAddress } = await createIsm(aggregationConfig);
976
+ // mutate in-place so testConfig (same reference) stays in sync for afterEach
977
+ const newOwner = randomAddress();
978
+ netFlowConfig.owner = newOwner;
979
+ // owner is the netFlow's only mutable field: expect a single in-place
980
+ // transferOwnership tx, with the aggregation container untouched
981
+ await expectTxsAndUpdate(ism, aggregationConfig, 1);
982
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
983
+ .true;
984
+ });
985
+ it('no changes to an existing delayedFlowRouterHookIsm means no redeployment or updates', async () => {
986
+ const signerAddress = await multiProvider.getSignerAddress(chain);
987
+ const delayedConfig = {
988
+ type: IsmType.DELAYED_FLOW_ROUTER,
989
+ warpRouter: warpRouterAddress,
990
+ thresholdBps: 10000,
991
+ maxDelay: 3600,
992
+ duration: 86400n,
993
+ owner: signerAddress,
994
+ remoteIsms: {
995
+ [TestChainName.test2]: addressToBytes32(randomAddress()).toLowerCase(),
996
+ },
997
+ };
998
+ const { ism, initialIsmAddress } = await createIsm(hybridAgg(delayedConfig));
999
+ await expectTxsAndUpdate(ism, hybridAgg(delayedConfig), 0);
1000
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
1001
+ .true;
1002
+ });
1003
+ it('does not redeploy a delayedFlowRouterHookIsm when the target omits warpRouter', async () => {
1004
+ const signerAddress = await multiProvider.getSignerAddress(chain);
1005
+ const delayedConfig = {
1006
+ type: IsmType.DELAYED_FLOW_ROUTER,
1007
+ warpRouter: warpRouterAddress,
1008
+ thresholdBps: 10000,
1009
+ maxDelay: 3600,
1010
+ duration: 86400n,
1011
+ owner: signerAddress,
1012
+ remoteIsms: {},
1013
+ };
1014
+ const { ism, initialIsmAddress } = await createIsm(hybridAgg(delayedConfig));
1015
+ // warp-route-context configs omit warpRouter (implicitly the token);
1016
+ // the update must treat it as unchanged, not as an immutable-field change
1017
+ const targetWithoutWarpRouter = {
1018
+ type: IsmType.DELAYED_FLOW_ROUTER,
1019
+ thresholdBps: 10000,
1020
+ maxDelay: 3600,
1021
+ duration: 86400n,
1022
+ owner: signerAddress,
1023
+ remoteIsms: {},
1024
+ };
1025
+ await expectTxsAndUpdate(ism, hybridAgg(targetWithoutWarpRouter), 0);
1026
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
1027
+ .true;
1028
+ });
1029
+ it('enrolls and unenrolls remote routers on an existing delayedFlowRouterHookIsm', async () => {
1030
+ const signerAddress = await multiProvider.getSignerAddress(chain);
1031
+ const test2Router = addressToBytes32(randomAddress()).toLowerCase();
1032
+ const test3Router = addressToBytes32(randomAddress()).toLowerCase();
1033
+ const delayedConfig = {
1034
+ type: IsmType.DELAYED_FLOW_ROUTER,
1035
+ warpRouter: warpRouterAddress,
1036
+ thresholdBps: 10000,
1037
+ maxDelay: 3600,
1038
+ duration: 86400n,
1039
+ owner: signerAddress,
1040
+ remoteIsms: { [TestChainName.test2]: test2Router },
1041
+ };
1042
+ const { ism, initialIsmAddress } = await createIsm(hybridAgg(delayedConfig));
1043
+ // replace test2 with test3: 1 enroll tx + 1 unenroll tx
1044
+ delayedConfig.remoteIsms = { [TestChainName.test3]: test3Router };
1045
+ await expectTxsAndUpdate(ism, hybridAgg(delayedConfig), 2);
1046
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
1047
+ .true;
1048
+ const delayedIsm = DelayedFlowRouterHookIsm__factory.connect(await hybridLeaf(ism), multiProvider.getProvider(chain));
1049
+ const test3Domain = multiProvider.getDomainId(TestChainName.test3);
1050
+ expect(await delayedIsm.routers(test3Domain)).to.equal(test3Router);
1051
+ const enrolledDomains = await delayedIsm.domains();
1052
+ expect(enrolledDomains.map((domain) => Number(domain))).to.deep.equal([
1053
+ test3Domain,
1054
+ ]);
1055
+ });
1056
+ it('unenrolls a delayed flow domain missing from provider metadata', async () => {
1057
+ const signerAddress = await multiProvider.getSignerAddress(chain);
1058
+ const delayedConfig = {
1059
+ type: IsmType.DELAYED_FLOW_ROUTER,
1060
+ warpRouter: warpRouterAddress,
1061
+ thresholdBps: 10000,
1062
+ maxDelay: 3600,
1063
+ duration: 86400n,
1064
+ owner: signerAddress,
1065
+ remoteIsms: {},
1066
+ };
1067
+ const { ism } = await createIsm(hybridAgg(delayedConfig));
1068
+ const leafAddress = await hybridLeaf(ism);
1069
+ const delayedIsm = DelayedFlowRouterHookIsm__factory.connect(leafAddress, multiProvider.getSigner(chain));
1070
+ const unknownDomain = 987654;
1071
+ expect(multiProvider.tryGetChainName(unknownDomain)).to.be.null;
1072
+ await delayedIsm.enrollRemoteRouters([unknownDomain], [addressToBytes32(randomAddress())]);
1073
+ const leafModule = new EvmIsmModule(multiProvider, {
1074
+ chain,
1075
+ config: delayedConfig,
1076
+ addresses: {
1077
+ ...factoryAddresses,
1078
+ mailbox: mailboxAddress,
1079
+ deployedIsm: leafAddress,
1080
+ },
1081
+ });
1082
+ const txs = await leafModule.updateDeployedInstance(delayedConfig);
1083
+ expect(txs).to.have.length(1);
1084
+ for (const tx of txs) {
1085
+ await multiProvider.sendTransaction(chain, tx);
1086
+ }
1087
+ expect(await delayedIsm.domains()).to.deep.equal([]);
1088
+ });
1089
+ it('updateDeployedInstance reconciles the hybrid leaf but rejects a composed tree', async () => {
1090
+ const signerAddress = await multiProvider.getSignerAddress(chain);
1091
+ const delayedConfig = {
1092
+ type: IsmType.DELAYED_FLOW_ROUTER,
1093
+ warpRouter: warpRouterAddress,
1094
+ thresholdBps: 10000,
1095
+ maxDelay: 3600,
1096
+ duration: 86400n,
1097
+ owner: signerAddress,
1098
+ remoteIsms: {},
1099
+ };
1100
+ const { ism } = await createIsm(hybridAgg(delayedConfig));
1101
+ // Same module shape buildDelayedFlowEnrollmentTxs builds: pointed at the
1102
+ // deployed hybrid leaf, not at the aggregation above it.
1103
+ const leafModule = new EvmIsmModule(multiProvider, {
1104
+ chain,
1105
+ config: delayedConfig,
1106
+ addresses: {
1107
+ ...factoryAddresses,
1108
+ mailbox: mailboxAddress,
1109
+ deployedIsm: await hybridLeaf(ism),
1110
+ },
1111
+ });
1112
+ // The escape hatch skips the composition rules, so it must not accept a
1113
+ // config that composes anything.
1114
+ await expect(leafModule.updateDeployedInstance(hybridAgg(delayedConfig))).to.be.rejectedWith('composed');
1115
+ // ...while the leaf node it exists for still reconciles.
1116
+ delayedConfig.remoteIsms = {
1117
+ [TestChainName.test2]: addressToBytes32(randomAddress()).toLowerCase(),
1118
+ };
1119
+ const txs = await leafModule.updateDeployedInstance(delayedConfig);
1120
+ expect(txs.length).to.equal(1);
1121
+ for (const tx of txs) {
1122
+ await multiProvider.sendTransaction(chain, tx);
1123
+ }
1124
+ });
1125
+ it('transfers delayedFlowRouterHookIsm ownership after enrollment updates', async () => {
1126
+ const signerAddress = await multiProvider.getSignerAddress(chain);
1127
+ const delayedConfig = {
1128
+ type: IsmType.DELAYED_FLOW_ROUTER,
1129
+ warpRouter: warpRouterAddress,
1130
+ thresholdBps: 10000,
1131
+ maxDelay: 3600,
1132
+ duration: 86400n,
1133
+ owner: signerAddress,
1134
+ remoteIsms: {},
1135
+ };
1136
+ const { ism, initialIsmAddress } = await createIsm(hybridAgg(delayedConfig));
1137
+ // enroll a router AND hand over ownership in the same update: the txs
1138
+ // only execute successfully if enrollment (owner-gated) precedes the
1139
+ // ownership transfer
1140
+ const newOwner = randomAddress();
1141
+ delayedConfig.remoteIsms = {
1142
+ [TestChainName.test2]: addressToBytes32(randomAddress()).toLowerCase(),
1143
+ };
1144
+ delayedConfig.owner = newOwner;
1145
+ await expectTxsAndUpdate(ism, hybridAgg(delayedConfig), 2);
1146
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
1147
+ .true;
1148
+ const delayedIsm = DelayedFlowRouterHookIsm__factory.connect(await hybridLeaf(ism), multiProvider.getProvider(chain));
1149
+ expect((await delayedIsm.owner()).toLowerCase()).to.equal(newOwner.toLowerCase());
1150
+ });
1151
+ it('redeploys a new delayedFlowRouterHookIsm on maxDelay change (immutable)', async () => {
1152
+ const signerAddress = await multiProvider.getSignerAddress(chain);
1153
+ const delayedConfig = {
1154
+ type: IsmType.DELAYED_FLOW_ROUTER,
1155
+ warpRouter: warpRouterAddress,
1156
+ thresholdBps: 10000,
1157
+ maxDelay: 3600,
1158
+ duration: 86400n,
1159
+ owner: signerAddress,
1160
+ remoteIsms: {},
1161
+ };
1162
+ const { ism, initialIsmAddress } = await createIsm(hybridAgg(delayedConfig));
1163
+ // maxDelay is immutable on-chain; changing it must redeploy
1164
+ delayedConfig.maxDelay = 7200;
1165
+ // update() redeploys internally and emits no txs
1166
+ await expectTxsAndUpdate(ism, hybridAgg(delayedConfig), 0);
1167
+ // different contract address — redeployed
1168
+ expect(eqAddress(initialIsmAddress, ism.serialize().deployedIsm)).to.be
1169
+ .false;
1170
+ const delayedIsm = DelayedFlowRouterHookIsm__factory.connect(await hybridLeaf(ism), multiProvider.getProvider(chain));
1171
+ expect(await delayedIsm.maxDelay()).to.equal(7200);
1172
+ });
1173
+ });
1174
+ describe('delayed flow router cross-chain enrollment', async () => {
1175
+ const remoteChain = TestChainName.test2;
1176
+ const manualChain = TestChainName.test3;
1177
+ function registryAddresses() {
1178
+ return { [chain]: { ...factoryAddresses, mailbox: mailboxAddress } };
1179
+ }
1180
+ async function enrollmentTxs(allTargets) {
1181
+ return buildDelayedFlowEnrollmentTxs({
1182
+ chain,
1183
+ multiProvider,
1184
+ registryAddresses: registryAddresses(),
1185
+ warpRouter: warpRouterAddress,
1186
+ target: allTargets[chain],
1187
+ allTargets,
1188
+ });
1189
+ }
1190
+ async function applyTxs(txs) {
1191
+ for (const tx of txs) {
1192
+ await multiProvider.sendTransaction(chain, tx);
1193
+ }
1194
+ }
1195
+ it('enrolls the pairing derived from the route and converges on re-run', async () => {
1196
+ const signerAddress = await multiProvider.getSignerAddress(chain);
1197
+ const delayedConfig = {
1198
+ type: IsmType.DELAYED_FLOW_ROUTER,
1199
+ warpRouter: warpRouterAddress,
1200
+ thresholdBps: 10000,
1201
+ maxDelay: 3600,
1202
+ duration: 86400n,
1203
+ owner: signerAddress,
1204
+ };
1205
+ const { ism } = await createIsm(hybridAgg(delayedConfig));
1206
+ const remoteIsmAddress = randomAddress();
1207
+ const allTargets = {
1208
+ [chain]: {
1209
+ ismAddress: await hybridLeaf(ism),
1210
+ userNode: delayedConfig,
1211
+ },
1212
+ [remoteChain]: {
1213
+ ismAddress: remoteIsmAddress,
1214
+ userNode: delayedConfig,
1215
+ },
1216
+ };
1217
+ const txs = await enrollmentTxs(allTargets);
1218
+ expect(txs.length).to.equal(1);
1219
+ await applyTxs(txs);
1220
+ expect((await enrollmentTxs(allTargets)).length).to.equal(0);
1221
+ const delayedIsm = DelayedFlowRouterHookIsm__factory.connect(await hybridLeaf(ism), multiProvider.getProvider(chain));
1222
+ expect(await delayedIsm.domains()).to.deep.equal([
1223
+ multiProvider.getDomainId(remoteChain),
1224
+ ]);
1225
+ // keep testConfig (same reference) in sync for the afterEach read-back
1226
+ delayedConfig.remoteIsms = {
1227
+ [remoteChain]: addressToBytes32(remoteIsmAddress).toLowerCase(),
1228
+ };
1229
+ });
1230
+ it('enrolls a configured external remoteIsms alongside the derived pairing and converges on re-run', async () => {
1231
+ const signerAddress = await multiProvider.getSignerAddress(chain);
1232
+ const delayedConfig = {
1233
+ type: IsmType.DELAYED_FLOW_ROUTER,
1234
+ warpRouter: warpRouterAddress,
1235
+ thresholdBps: 10000,
1236
+ maxDelay: 3600,
1237
+ duration: 86400n,
1238
+ owner: signerAddress,
1239
+ remoteIsms: {},
1240
+ };
1241
+ const { ism } = await createIsm(hybridAgg(delayedConfig));
1242
+ // An operator-authored pairing names a chain the route never derives.
1243
+ // It is retained alongside the route-managed counterpart.
1244
+ const manualRouter = addressToBytes32(randomAddress()).toLowerCase();
1245
+ delayedConfig.remoteIsms = { [manualChain]: manualRouter };
1246
+ const derivedRouterAddress = randomAddress();
1247
+ const derivedRouter = addressToBytes32(derivedRouterAddress).toLowerCase();
1248
+ const allTargets = {
1249
+ [chain]: {
1250
+ ismAddress: await hybridLeaf(ism),
1251
+ userNode: delayedConfig,
1252
+ },
1253
+ [remoteChain]: {
1254
+ ismAddress: derivedRouterAddress,
1255
+ userNode: delayedConfig,
1256
+ },
1257
+ };
1258
+ const txs = await enrollmentTxs(allTargets);
1259
+ expect(txs.length).to.equal(1);
1260
+ await applyTxs(txs);
1261
+ expect((await enrollmentTxs(allTargets)).length).to.equal(0);
1262
+ const delayedIsm = DelayedFlowRouterHookIsm__factory.connect(await hybridLeaf(ism), multiProvider.getProvider(chain));
1263
+ const manualDomain = multiProvider.getDomainId(manualChain);
1264
+ const derivedDomain = multiProvider.getDomainId(remoteChain);
1265
+ expect(await delayedIsm.domains()).to.have.members([
1266
+ manualDomain,
1267
+ derivedDomain,
1268
+ ]);
1269
+ expect(await delayedIsm.routers(manualDomain)).to.equal(manualRouter);
1270
+ expect(await delayedIsm.routers(derivedDomain)).to.equal(derivedRouter);
1271
+ // keep testConfig (same reference) in sync for the afterEach read-back
1272
+ delayedConfig.remoteIsms = {
1273
+ [manualChain]: manualRouter,
1274
+ [remoteChain]: derivedRouter,
1275
+ };
1276
+ });
768
1277
  });
769
1278
  });
770
1279
  //# sourceMappingURL=EvmIsmModule.hardhat-test.js.map