@chainlink/ccip-sdk 0.0.0 → 0.90.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.
- package/LICENSE +21 -0
- package/README.md +109 -0
- package/dist/aptos/exec.d.ts +18 -0
- package/dist/aptos/exec.d.ts.map +1 -0
- package/dist/aptos/exec.js +55 -0
- package/dist/aptos/exec.js.map +1 -0
- package/dist/aptos/hasher.d.ts +11 -0
- package/dist/aptos/hasher.d.ts.map +1 -0
- package/dist/aptos/hasher.js +62 -0
- package/dist/aptos/hasher.js.map +1 -0
- package/dist/aptos/index.d.ts +92 -0
- package/dist/aptos/index.d.ts.map +1 -0
- package/dist/aptos/index.js +482 -0
- package/dist/aptos/index.js.map +1 -0
- package/dist/aptos/logs.d.ts +9 -0
- package/dist/aptos/logs.d.ts.map +1 -0
- package/dist/aptos/logs.js +167 -0
- package/dist/aptos/logs.js.map +1 -0
- package/dist/aptos/send.d.ts +11 -0
- package/dist/aptos/send.d.ts.map +1 -0
- package/dist/aptos/send.js +78 -0
- package/dist/aptos/send.js.map +1 -0
- package/dist/aptos/token.d.ts +4 -0
- package/dist/aptos/token.d.ts.map +1 -0
- package/dist/aptos/token.js +134 -0
- package/dist/aptos/token.js.map +1 -0
- package/dist/aptos/types.d.ts +78 -0
- package/dist/aptos/types.d.ts.map +1 -0
- package/dist/aptos/types.js +60 -0
- package/dist/aptos/types.js.map +1 -0
- package/dist/aptos/utils.d.ts +12 -0
- package/dist/aptos/utils.d.ts.map +1 -0
- package/dist/aptos/utils.js +15 -0
- package/dist/aptos/utils.js.map +1 -0
- package/dist/chain.d.ts +344 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +41 -0
- package/dist/chain.js.map +1 -0
- package/dist/commits.d.ts +25 -0
- package/dist/commits.d.ts.map +1 -0
- package/dist/commits.js +29 -0
- package/dist/commits.js.map +1 -0
- package/dist/evm/abi/BurnMintERC677Token.d.ts +602 -0
- package/dist/evm/abi/BurnMintERC677Token.d.ts.map +1 -0
- package/dist/evm/abi/BurnMintERC677Token.js +488 -0
- package/dist/evm/abi/BurnMintERC677Token.js.map +1 -0
- package/dist/evm/abi/CommitStore_1_2.d.ts +688 -0
- package/dist/evm/abi/CommitStore_1_2.d.ts.map +1 -0
- package/dist/evm/abi/CommitStore_1_2.js +638 -0
- package/dist/evm/abi/CommitStore_1_2.js.map +1 -0
- package/dist/evm/abi/CommitStore_1_5.d.ts +708 -0
- package/dist/evm/abi/CommitStore_1_5.d.ts.map +1 -0
- package/dist/evm/abi/CommitStore_1_5.js +675 -0
- package/dist/evm/abi/CommitStore_1_5.js.map +1 -0
- package/dist/evm/abi/FeeQuoter_1_6.d.ts +1770 -0
- package/dist/evm/abi/FeeQuoter_1_6.d.ts.map +1 -0
- package/dist/evm/abi/FeeQuoter_1_6.js +1904 -0
- package/dist/evm/abi/FeeQuoter_1_6.js.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5.d.ts +1116 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5.d.ts.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5.js +1096 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5.js.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5_1.d.ts +1306 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5_1.d.ts.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5_1.js +1278 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5_1.js.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_6_1.d.ts +1290 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_6_1.d.ts.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_6_1.js +1288 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_6_1.js.map +1 -0
- package/dist/evm/abi/OffRamp_1_2.d.ts +1217 -0
- package/dist/evm/abi/OffRamp_1_2.d.ts.map +1 -0
- package/dist/evm/abi/OffRamp_1_2.js +1204 -0
- package/dist/evm/abi/OffRamp_1_2.js.map +1 -0
- package/dist/evm/abi/OffRamp_1_5.d.ts +1271 -0
- package/dist/evm/abi/OffRamp_1_5.d.ts.map +1 -0
- package/dist/evm/abi/OffRamp_1_5.js +1273 -0
- package/dist/evm/abi/OffRamp_1_5.js.map +1 -0
- package/dist/evm/abi/OffRamp_1_6.d.ts +1472 -0
- package/dist/evm/abi/OffRamp_1_6.d.ts.map +1 -0
- package/dist/evm/abi/OffRamp_1_6.js +1529 -0
- package/dist/evm/abi/OffRamp_1_6.js.map +1 -0
- package/dist/evm/abi/OnRamp_1_2.d.ts +1391 -0
- package/dist/evm/abi/OnRamp_1_2.d.ts.map +1 -0
- package/dist/evm/abi/OnRamp_1_2.js +1343 -0
- package/dist/evm/abi/OnRamp_1_2.js.map +1 -0
- package/dist/evm/abi/OnRamp_1_5.d.ts +1443 -0
- package/dist/evm/abi/OnRamp_1_5.d.ts.map +1 -0
- package/dist/evm/abi/OnRamp_1_5.js +1427 -0
- package/dist/evm/abi/OnRamp_1_5.js.map +1 -0
- package/dist/evm/abi/OnRamp_1_6.d.ts +796 -0
- package/dist/evm/abi/OnRamp_1_6.d.ts.map +1 -0
- package/dist/evm/abi/OnRamp_1_6.js +880 -0
- package/dist/evm/abi/OnRamp_1_6.js.map +1 -0
- package/dist/evm/abi/Router.d.ts +541 -0
- package/dist/evm/abi/Router.d.ts.map +1 -0
- package/dist/evm/abi/Router.js +508 -0
- package/dist/evm/abi/Router.js.map +1 -0
- package/dist/evm/abi/TokenAdminRegistry_1_5.d.ts +373 -0
- package/dist/evm/abi/TokenAdminRegistry_1_5.d.ts.map +1 -0
- package/dist/evm/abi/TokenAdminRegistry_1_5.js +333 -0
- package/dist/evm/abi/TokenAdminRegistry_1_5.js.map +1 -0
- package/dist/evm/const.d.ts +27 -0
- package/dist/evm/const.d.ts.map +1 -0
- package/dist/evm/const.js +63 -0
- package/dist/evm/const.js.map +1 -0
- package/dist/evm/errors.d.ts +36 -0
- package/dist/evm/errors.d.ts.map +1 -0
- package/dist/evm/errors.js +192 -0
- package/dist/evm/errors.js.map +1 -0
- package/dist/evm/hasher.d.ts +5 -0
- package/dist/evm/hasher.d.ts.map +1 -0
- package/dist/evm/hasher.js +116 -0
- package/dist/evm/hasher.js.map +1 -0
- package/dist/evm/index.d.ts +121 -0
- package/dist/evm/index.d.ts.map +1 -0
- package/dist/evm/index.js +904 -0
- package/dist/evm/index.js.map +1 -0
- package/dist/evm/messages.d.ts +35 -0
- package/dist/evm/messages.d.ts.map +1 -0
- package/dist/evm/messages.js +11 -0
- package/dist/evm/messages.js.map +1 -0
- package/dist/evm/offchain.d.ts +16 -0
- package/dist/evm/offchain.d.ts.map +1 -0
- package/dist/evm/offchain.js +142 -0
- package/dist/evm/offchain.js.map +1 -0
- package/dist/execution.d.ts +80 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +91 -0
- package/dist/execution.js.map +1 -0
- package/dist/extra-args.d.ts +45 -0
- package/dist/extra-args.d.ts.map +1 -0
- package/dist/extra-args.js +44 -0
- package/dist/extra-args.js.map +1 -0
- package/dist/gas.d.ts +27 -0
- package/dist/gas.d.ts.map +1 -0
- package/dist/gas.js +80 -0
- package/dist/gas.js.map +1 -0
- package/dist/hasher/common.d.ts +12 -0
- package/dist/hasher/common.d.ts.map +1 -0
- package/dist/hasher/common.js +19 -0
- package/dist/hasher/common.js.map +1 -0
- package/dist/hasher/hasher.d.ts +4 -0
- package/dist/hasher/hasher.d.ts.map +1 -0
- package/dist/hasher/hasher.js +11 -0
- package/dist/hasher/hasher.js.map +1 -0
- package/dist/hasher/index.d.ts +4 -0
- package/dist/hasher/index.d.ts.map +1 -0
- package/dist/hasher/index.js +4 -0
- package/dist/hasher/index.js.map +1 -0
- package/dist/hasher/merklemulti.d.ts +58 -0
- package/dist/hasher/merklemulti.d.ts.map +1 -0
- package/dist/hasher/merklemulti.js +257 -0
- package/dist/hasher/merklemulti.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/offchain.d.ts +20 -0
- package/dist/offchain.d.ts.map +1 -0
- package/dist/offchain.js +59 -0
- package/dist/offchain.js.map +1 -0
- package/dist/requests.d.ts +48 -0
- package/dist/requests.d.ts.map +1 -0
- package/dist/requests.js +286 -0
- package/dist/requests.js.map +1 -0
- package/dist/selectors.d.ts +9 -0
- package/dist/selectors.d.ts.map +1 -0
- package/dist/selectors.js +1330 -0
- package/dist/selectors.js.map +1 -0
- package/dist/solana/cleanup.d.ts +15 -0
- package/dist/solana/cleanup.d.ts.map +1 -0
- package/dist/solana/cleanup.js +159 -0
- package/dist/solana/cleanup.js.map +1 -0
- package/dist/solana/exec.d.ts +15 -0
- package/dist/solana/exec.d.ts.map +1 -0
- package/dist/solana/exec.js +417 -0
- package/dist/solana/exec.js.map +1 -0
- package/dist/solana/hasher.d.ts +4 -0
- package/dist/solana/hasher.d.ts.map +1 -0
- package/dist/solana/hasher.js +81 -0
- package/dist/solana/hasher.js.map +1 -0
- package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.d.ts +866 -0
- package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.js +866 -0
- package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.js.map +1 -0
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.d.ts +949 -0
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.js +949 -0
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.js.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.d.ts +1374 -0
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.js +1374 -0
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.js.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts +104 -0
- package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_COMMON.js +104 -0
- package/dist/solana/idl/1.6.0/CCIP_COMMON.js.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.d.ts +2746 -0
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.js +2746 -0
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.js.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.d.ts +2332 -0
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.js +2332 -0
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.js.map +1 -0
- package/dist/solana/index.d.ts +205 -0
- package/dist/solana/index.d.ts.map +1 -0
- package/dist/solana/index.js +1085 -0
- package/dist/solana/index.js.map +1 -0
- package/dist/solana/offchain.d.ts +31 -0
- package/dist/solana/offchain.d.ts.map +1 -0
- package/dist/solana/offchain.js +152 -0
- package/dist/solana/offchain.js.map +1 -0
- package/dist/solana/patchBorsh.d.ts +2 -0
- package/dist/solana/patchBorsh.d.ts.map +1 -0
- package/dist/solana/patchBorsh.js +60 -0
- package/dist/solana/patchBorsh.js.map +1 -0
- package/dist/solana/send.d.ts +14 -0
- package/dist/solana/send.d.ts.map +1 -0
- package/dist/solana/send.js +272 -0
- package/dist/solana/send.js.map +1 -0
- package/dist/solana/types.d.ts +4 -0
- package/dist/solana/types.d.ts.map +1 -0
- package/dist/solana/types.js +2 -0
- package/dist/solana/types.js.map +1 -0
- package/dist/solana/utils.d.ts +58 -0
- package/dist/solana/utils.d.ts.map +1 -0
- package/dist/solana/utils.js +211 -0
- package/dist/solana/utils.js.map +1 -0
- package/dist/sui/hasher.d.ts +12 -0
- package/dist/sui/hasher.d.ts.map +1 -0
- package/dist/sui/hasher.js +63 -0
- package/dist/sui/hasher.js.map +1 -0
- package/dist/sui/index.d.ts +72 -0
- package/dist/sui/index.d.ts.map +1 -0
- package/dist/sui/index.js +128 -0
- package/dist/sui/index.js.map +1 -0
- package/dist/sui/types.d.ts +17 -0
- package/dist/sui/types.d.ts.map +1 -0
- package/dist/sui/types.js +17 -0
- package/dist/sui/types.js.map +1 -0
- package/dist/supported-chains.d.ts +5 -0
- package/dist/supported-chains.d.ts.map +1 -0
- package/dist/supported-chains.js +3 -0
- package/dist/supported-chains.js.map +1 -0
- package/dist/types.d.ts +118 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +117 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +336 -0
- package/dist/utils.js.map +1 -0
- package/package.json +66 -8
- package/src/aptos/exec.ts +69 -0
- package/src/aptos/hasher.ts +92 -0
- package/src/aptos/index.ts +660 -0
- package/src/aptos/logs.ts +210 -0
- package/src/aptos/send.ts +120 -0
- package/src/aptos/token.ts +150 -0
- package/src/aptos/types.ts +85 -0
- package/src/aptos/utils.ts +24 -0
- package/src/chain.ts +398 -0
- package/src/commits.ts +44 -0
- package/src/evm/abi/BurnMintERC677Token.ts +487 -0
- package/src/evm/abi/CommitStore_1_2.ts +637 -0
- package/src/evm/abi/CommitStore_1_5.ts +674 -0
- package/src/evm/abi/FeeQuoter_1_6.ts +1903 -0
- package/src/evm/abi/LockReleaseTokenPool_1_5.ts +1095 -0
- package/src/evm/abi/LockReleaseTokenPool_1_5_1.ts +1277 -0
- package/src/evm/abi/LockReleaseTokenPool_1_6_1.ts +1287 -0
- package/src/evm/abi/OffRamp_1_2.ts +1203 -0
- package/src/evm/abi/OffRamp_1_5.ts +1272 -0
- package/src/evm/abi/OffRamp_1_6.ts +1528 -0
- package/src/evm/abi/OnRamp_1_2.ts +1342 -0
- package/src/evm/abi/OnRamp_1_5.ts +1426 -0
- package/src/evm/abi/OnRamp_1_6.ts +879 -0
- package/src/evm/abi/Router.ts +507 -0
- package/src/evm/abi/TokenAdminRegistry_1_5.ts +332 -0
- package/src/evm/const.ts +69 -0
- package/src/evm/errors.ts +212 -0
- package/src/evm/hasher.ts +166 -0
- package/src/evm/index.ts +1262 -0
- package/src/evm/messages.ts +73 -0
- package/src/evm/offchain.ts +189 -0
- package/src/execution.ts +131 -0
- package/src/extra-args.ts +71 -0
- package/src/gas.ts +135 -0
- package/src/hasher/common.ts +23 -0
- package/src/hasher/hasher.ts +12 -0
- package/src/hasher/index.ts +3 -0
- package/src/hasher/merklemulti.ts +309 -0
- package/src/index.ts +51 -0
- package/src/offchain.ts +86 -0
- package/src/requests.ts +339 -0
- package/src/selectors.ts +1340 -0
- package/src/solana/cleanup.ts +216 -0
- package/src/solana/exec.ts +645 -0
- package/src/solana/hasher.ts +104 -0
- package/src/solana/idl/1.6.0/BASE_TOKEN_POOL.ts +1734 -0
- package/src/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.ts +1900 -0
- package/src/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.ts +2750 -0
- package/src/solana/idl/1.6.0/CCIP_COMMON.ts +210 -0
- package/src/solana/idl/1.6.0/CCIP_OFFRAMP.ts +5494 -0
- package/src/solana/idl/1.6.0/CCIP_ROUTER.ts +4671 -0
- package/src/solana/index.ts +1454 -0
- package/src/solana/offchain.ts +209 -0
- package/src/solana/patchBorsh.ts +67 -0
- package/src/solana/send.ts +436 -0
- package/src/solana/types.ts +6 -0
- package/src/solana/utils.ts +272 -0
- package/src/sui/hasher.ts +90 -0
- package/src/sui/index.ts +198 -0
- package/src/sui/types.ts +22 -0
- package/src/supported-chains.ts +4 -0
- package/src/types.ts +153 -0
- package/src/utils.ts +405 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,904 @@
|
|
|
1
|
+
import util from 'util';
|
|
2
|
+
import { parseAbi } from 'abitype';
|
|
3
|
+
import { AbstractSigner, BaseWallet, Contract, JsonRpcProvider, Result, SigningKey, WebSocketProvider, ZeroAddress, concat, dataSlice, encodeBase58, getAddress, getBytes, hexlify, isBytesLike, isHexString, toBigInt, zeroPadValue, } from 'ethers';
|
|
4
|
+
import moize, {} from 'moize';
|
|
5
|
+
import { Chain, ChainFamily, } from "../chain.js";
|
|
6
|
+
import { EVMExtraArgsV1Tag, EVMExtraArgsV2Tag, SVMExtraArgsV1Tag, SuiExtraArgsV1Tag, } from "../extra-args.js";
|
|
7
|
+
import { supportedChains } from "../supported-chains.js";
|
|
8
|
+
import { CCIPVersion, } from "../types.js";
|
|
9
|
+
import { blockRangeGenerator, decodeAddress, decodeOnRampAddress, getAddressBytes, getDataBytes, getSomeBlockNumberBefore, networkInfo, parseTypeAndVersion, } from "../utils.js";
|
|
10
|
+
import EVM2EVMOffRamp_1_2_ABI from "./abi/OffRamp_1_2.js";
|
|
11
|
+
import EVM2EVMOffRamp_1_5_ABI from "./abi/OffRamp_1_5.js";
|
|
12
|
+
import OffRamp_1_6_ABI from "./abi/OffRamp_1_6.js";
|
|
13
|
+
import EVM2EVMOnRamp_1_2_ABI from "./abi/OnRamp_1_2.js";
|
|
14
|
+
import EVM2EVMOnRamp_1_5_ABI from "./abi/OnRamp_1_5.js";
|
|
15
|
+
import OnRamp_1_6_ABI from "./abi/OnRamp_1_6.js";
|
|
16
|
+
import { DEFAULT_APPROVE_GAS_LIMIT, DEFAULT_GAS_LIMIT, commitsFragments, defaultAbiCoder, getAllFragmentsMatchingEvents, interfaces, receiptsFragments, requestsFragments, } from "./const.js";
|
|
17
|
+
import { parseData } from "./errors.js";
|
|
18
|
+
import { getV12LeafHasher, getV16LeafHasher } from "./hasher.js";
|
|
19
|
+
import { parseSourceTokenData, } from "./messages.js";
|
|
20
|
+
import { encodeEVMOffchainTokenData, fetchEVMOffchainTokenData } from "./offchain.js";
|
|
21
|
+
const VersionedContractABI = parseAbi(['function typeAndVersion() view returns (string)']);
|
|
22
|
+
const EVMExtraArgsV1 = 'tuple(uint256 gasLimit)';
|
|
23
|
+
const EVMExtraArgsV2 = 'tuple(uint256 gasLimit, bool allowOutOfOrderExecution)';
|
|
24
|
+
const SVMExtraArgsV1 = 'tuple(uint32 computeUnits, uint64 accountIsWritableBitmap, bool allowOutOfOrderExecution, bytes32 tokenReceiver, bytes32[] accounts)';
|
|
25
|
+
const SuiExtraArgsV1 = 'tuple(uint256 gasLimit, bool allowOutOfOrderExecution, bytes32 tokenReceiver, bytes32[] receiverObjectIds)';
|
|
26
|
+
function resultToObject(o) {
|
|
27
|
+
return o instanceof Promise
|
|
28
|
+
? o.then(resultToObject)
|
|
29
|
+
: o instanceof Result
|
|
30
|
+
? o.toObject()
|
|
31
|
+
: o;
|
|
32
|
+
}
|
|
33
|
+
function resultsToMessage(result) {
|
|
34
|
+
if (result.message)
|
|
35
|
+
result = result.message;
|
|
36
|
+
return {
|
|
37
|
+
...result.toObject(),
|
|
38
|
+
tokenAmounts: result.tokenAmounts.map((ta) => ta.toObject()),
|
|
39
|
+
...(result.sourceTokenData
|
|
40
|
+
? { sourceTokenData: result.sourceTokenData.toArray() }
|
|
41
|
+
: {}),
|
|
42
|
+
...(result.header ? { header: result.header.toObject() } : {}),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export class EVMChain extends Chain {
|
|
46
|
+
static family = ChainFamily.EVM;
|
|
47
|
+
static decimals = 18;
|
|
48
|
+
network;
|
|
49
|
+
provider;
|
|
50
|
+
constructor(provider, network) {
|
|
51
|
+
if (network.family !== ChainFamily.EVM)
|
|
52
|
+
throw new Error(`Invalid network family for EVMChain: ${network.family}`);
|
|
53
|
+
super();
|
|
54
|
+
this.network = network;
|
|
55
|
+
this.provider = provider;
|
|
56
|
+
this.typeAndVersion = moize.default(this.typeAndVersion.bind(this));
|
|
57
|
+
this.getBlockTimestamp = moize.default(this.getBlockTimestamp.bind(this), {
|
|
58
|
+
maxSize: 100,
|
|
59
|
+
updateCacheForKey: (key) => typeof key[key.length - 1] !== 'number',
|
|
60
|
+
});
|
|
61
|
+
this.getTransaction = moize.default(this.getTransaction.bind(this), {
|
|
62
|
+
maxSize: 100,
|
|
63
|
+
transformArgs: (args) => typeof args[0] !== 'string'
|
|
64
|
+
? [args[0].hash]
|
|
65
|
+
: args,
|
|
66
|
+
});
|
|
67
|
+
this.getTokenForTokenPool = moize.default(this.getTokenForTokenPool.bind(this));
|
|
68
|
+
this.getNativeTokenForRouter = moize.default(this.getNativeTokenForRouter.bind(this), {
|
|
69
|
+
maxArgs: 1,
|
|
70
|
+
isPromise: true,
|
|
71
|
+
});
|
|
72
|
+
this.getTokenInfo = moize.default(this.getTokenInfo.bind(this));
|
|
73
|
+
this.getWallet = moize.default(this.getWallet.bind(this), { maxSize: 1, maxArgs: 0 });
|
|
74
|
+
this.getTokenAdminRegistryFor = moize.default(this.getTokenAdminRegistryFor.bind(this), {
|
|
75
|
+
isPromise: true,
|
|
76
|
+
maxArgs: 1,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// overwrite EVMChain.getWallet to implement custom wallet loading
|
|
80
|
+
// some signers don't like to be `.connect`ed, so pass provider as first param
|
|
81
|
+
static getWallet(_provider, _opts) {
|
|
82
|
+
throw new Error('static EVM wallet loading not available');
|
|
83
|
+
}
|
|
84
|
+
// cached wallet/signer getter
|
|
85
|
+
async getWallet(opts = {}) {
|
|
86
|
+
if (typeof opts.wallet === 'number' ||
|
|
87
|
+
(typeof opts.wallet === 'string' && opts.wallet.match(/^(\d+|0x[a-fA-F0-9]{40})$/))) {
|
|
88
|
+
// if given a number, numeric string or address, use ethers `provider.getSigner` (e.g. geth or MM)
|
|
89
|
+
return this.provider.getSigner(typeof opts.wallet === 'string' && opts.wallet.match(/^0x[a-fA-F0-9]{40}$/)
|
|
90
|
+
? opts.wallet
|
|
91
|
+
: Number(opts.wallet));
|
|
92
|
+
}
|
|
93
|
+
else if (typeof opts.wallet === 'string') {
|
|
94
|
+
// support receiving private key directly (not recommended)
|
|
95
|
+
try {
|
|
96
|
+
return Promise.resolve(new BaseWallet(new SigningKey((opts.wallet.startsWith('0x') ? '' : '0x') + opts.wallet), this.provider));
|
|
97
|
+
}
|
|
98
|
+
catch (_) {
|
|
99
|
+
// pass
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (opts.wallet instanceof AbstractSigner) {
|
|
103
|
+
// if given a signer, return/cache it
|
|
104
|
+
return opts.wallet;
|
|
105
|
+
}
|
|
106
|
+
return this.constructor.getWallet(this.provider, opts);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Expose ethers provider's `listAccounts`, if provider supports it
|
|
110
|
+
*/
|
|
111
|
+
async listAccounts() {
|
|
112
|
+
return (await this.provider.listAccounts()).map(({ address }) => address);
|
|
113
|
+
}
|
|
114
|
+
async getWalletAddress(opts) {
|
|
115
|
+
return (await this.getWallet(opts)).getAddress();
|
|
116
|
+
}
|
|
117
|
+
static async _getProvider(url) {
|
|
118
|
+
let provider;
|
|
119
|
+
let providerReady;
|
|
120
|
+
if (url.startsWith('ws')) {
|
|
121
|
+
const provider_ = new WebSocketProvider(url);
|
|
122
|
+
providerReady = new Promise((resolve, reject) => {
|
|
123
|
+
provider_.websocket.onerror = reject;
|
|
124
|
+
provider_
|
|
125
|
+
._waitUntilReady()
|
|
126
|
+
.then(() => resolve(provider_))
|
|
127
|
+
.catch(reject);
|
|
128
|
+
});
|
|
129
|
+
provider = provider_;
|
|
130
|
+
}
|
|
131
|
+
else if (url.startsWith('http')) {
|
|
132
|
+
provider = new JsonRpcProvider(url);
|
|
133
|
+
providerReady = Promise.resolve(provider);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
throw new Error(`Unknown JSON RPC protocol in endpoint (should be wss?:// or https?://): ${url}`);
|
|
137
|
+
}
|
|
138
|
+
return providerReady;
|
|
139
|
+
}
|
|
140
|
+
static async fromProvider(provider) {
|
|
141
|
+
try {
|
|
142
|
+
return new EVMChain(provider, networkInfo(Number((await provider.getNetwork()).chainId)));
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
provider.destroy();
|
|
146
|
+
throw err;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
static async fromUrl(url) {
|
|
150
|
+
return this.fromProvider(await this._getProvider(url));
|
|
151
|
+
}
|
|
152
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
153
|
+
async destroy() {
|
|
154
|
+
this.provider.destroy();
|
|
155
|
+
}
|
|
156
|
+
async getBlockTimestamp(block) {
|
|
157
|
+
const res = await this.provider.getBlock(block);
|
|
158
|
+
if (!res)
|
|
159
|
+
throw new Error(`Block not found: ${block}`);
|
|
160
|
+
return res.timestamp;
|
|
161
|
+
}
|
|
162
|
+
async getTransaction(hash) {
|
|
163
|
+
const tx = typeof hash === 'string' ? await this.provider.getTransactionReceipt(hash) : hash;
|
|
164
|
+
if (!tx)
|
|
165
|
+
throw new Error(`Transaction not found: ${hash}`);
|
|
166
|
+
const timestamp = await this.getBlockTimestamp(tx.blockNumber);
|
|
167
|
+
const chainTx = {
|
|
168
|
+
...tx,
|
|
169
|
+
chain: this,
|
|
170
|
+
timestamp,
|
|
171
|
+
logs: [],
|
|
172
|
+
};
|
|
173
|
+
const logs = tx.logs.map((l) => Object.assign(l, { tx: chainTx }));
|
|
174
|
+
chainTx.logs = logs;
|
|
175
|
+
return chainTx;
|
|
176
|
+
}
|
|
177
|
+
async *getLogs(filter) {
|
|
178
|
+
const endBlock = filter.endBlock ?? (await this.provider.getBlockNumber());
|
|
179
|
+
if (filter.topics?.length &&
|
|
180
|
+
filter.topics.every((t) => typeof t === 'string')) {
|
|
181
|
+
const topics = new Set(filter.topics
|
|
182
|
+
.filter(isHexString)
|
|
183
|
+
.concat(Object.keys(getAllFragmentsMatchingEvents(filter.topics)))
|
|
184
|
+
.flat());
|
|
185
|
+
if (!topics.size) {
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
187
|
+
throw new Error(`Could not find matching topics: ${filter.topics}`);
|
|
188
|
+
}
|
|
189
|
+
filter.topics = [Array.from(topics)];
|
|
190
|
+
}
|
|
191
|
+
if (!filter.startBlock && filter.startTime) {
|
|
192
|
+
filter.startBlock = await getSomeBlockNumberBefore(this.getBlockTimestamp.bind(this), endBlock, filter.startTime);
|
|
193
|
+
}
|
|
194
|
+
for (const blockRange of blockRangeGenerator({ ...filter, endBlock })) {
|
|
195
|
+
console.debug('evm getLogs:', {
|
|
196
|
+
...blockRange,
|
|
197
|
+
...(filter.address ? { address: filter.address } : {}),
|
|
198
|
+
...(filter.topics?.length ? { topics: filter.topics } : {}),
|
|
199
|
+
});
|
|
200
|
+
const logs = await this.provider.getLogs({
|
|
201
|
+
...blockRange,
|
|
202
|
+
...(filter.address ? { address: filter.address } : {}),
|
|
203
|
+
...(filter.topics?.length ? { topics: filter.topics } : {}),
|
|
204
|
+
});
|
|
205
|
+
if (!filter.startBlock)
|
|
206
|
+
logs.reverse();
|
|
207
|
+
yield* logs;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
static decodeMessage(log) {
|
|
211
|
+
if (!isBytesLike(log.data))
|
|
212
|
+
throw new Error(`invalid data=${util.inspect(log.data)}`);
|
|
213
|
+
let fragments;
|
|
214
|
+
if (log.topics?.[0]) {
|
|
215
|
+
fragments = [requestsFragments[log.topics[0]]];
|
|
216
|
+
if (!fragments[0])
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
fragments = Object.values(requestsFragments);
|
|
221
|
+
}
|
|
222
|
+
let message;
|
|
223
|
+
for (const fragment of fragments) {
|
|
224
|
+
try {
|
|
225
|
+
// we don't actually use Interface instance here, `decodeEventLog` is mostly static when given a fragment
|
|
226
|
+
const result = interfaces.OnRamp_v1_6.decodeEventLog(fragment, log.data, log.topics);
|
|
227
|
+
message = resultsToMessage(result);
|
|
228
|
+
}
|
|
229
|
+
catch (_) {
|
|
230
|
+
// try next fragment
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (!message)
|
|
234
|
+
return;
|
|
235
|
+
if (!isHexString(message.sender, 20))
|
|
236
|
+
throw new Error('could not decode CCIPMessage');
|
|
237
|
+
if (!message.header) {
|
|
238
|
+
// CCIPMessage_V1_2_EVM
|
|
239
|
+
message.header = {
|
|
240
|
+
messageId: message.messageId,
|
|
241
|
+
sequenceNumber: message.sequenceNumber,
|
|
242
|
+
nonce: message.nonce,
|
|
243
|
+
sourceChainSelector: message.sourceChainSelector,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
const sourceFamily = networkInfo(message.header.sourceChainSelector).family;
|
|
247
|
+
let destFamily = ChainFamily.EVM;
|
|
248
|
+
if (message.header?.destChainSelector) {
|
|
249
|
+
destFamily = networkInfo(message.header.destChainSelector).family;
|
|
250
|
+
}
|
|
251
|
+
// conversions to make any message version be compatible with latest v1.6
|
|
252
|
+
message.tokenAmounts = message.tokenAmounts.map((tokenAmount, i) => {
|
|
253
|
+
if ('sourceTokenData' in message) {
|
|
254
|
+
// CCIPMessage_V1_2_EVM
|
|
255
|
+
try {
|
|
256
|
+
tokenAmount = {
|
|
257
|
+
...parseSourceTokenData(message.sourceTokenData[i]),
|
|
258
|
+
...tokenAmount,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
catch (_) {
|
|
262
|
+
console.debug('legacy sourceTokenData:', i, message.sourceTokenData[i]);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (typeof tokenAmount.destExecData === 'string' && tokenAmount.destGasAmount == null) {
|
|
266
|
+
// CCIPMessage_V1_6_EVM
|
|
267
|
+
tokenAmount.destGasAmount = toBigInt(getDataBytes(tokenAmount.destExecData));
|
|
268
|
+
}
|
|
269
|
+
// Can be undefined if the message is from before v1.5 and failed to parse sourceTokenData
|
|
270
|
+
if (tokenAmount.sourcePoolAddress) {
|
|
271
|
+
tokenAmount.sourcePoolAddress = decodeAddress(tokenAmount.sourcePoolAddress, sourceFamily);
|
|
272
|
+
}
|
|
273
|
+
if (tokenAmount.destTokenAddress) {
|
|
274
|
+
tokenAmount.destTokenAddress = decodeAddress(tokenAmount.destTokenAddress, destFamily);
|
|
275
|
+
}
|
|
276
|
+
return tokenAmount;
|
|
277
|
+
});
|
|
278
|
+
message.sender = decodeAddress(message.sender, sourceFamily);
|
|
279
|
+
message.feeToken = decodeAddress(message.feeToken, sourceFamily);
|
|
280
|
+
message.receiver = decodeAddress(message.receiver, destFamily);
|
|
281
|
+
if (message.extraArgs) {
|
|
282
|
+
// v1.6+
|
|
283
|
+
const parsed = this.decodeExtraArgs(message.extraArgs);
|
|
284
|
+
if (!parsed)
|
|
285
|
+
throw new Error(`Unknown extraArgs: ${message.extraArgs}`);
|
|
286
|
+
const { _tag, ...rest } = parsed;
|
|
287
|
+
// merge parsed extraArgs to any family in message root object
|
|
288
|
+
Object.assign(message, rest);
|
|
289
|
+
}
|
|
290
|
+
else if (message.nonce === 0n) {
|
|
291
|
+
// v1.2..v1.5 targets EVM only; extraArgs is not explicit, gasLimit is already in
|
|
292
|
+
// message body, allowOutOfOrderExecution (in v1.5) was present only as nonce=0
|
|
293
|
+
message.allowOutOfOrderExecution = true;
|
|
294
|
+
}
|
|
295
|
+
return message;
|
|
296
|
+
}
|
|
297
|
+
static decodeCommits(log, lane) {
|
|
298
|
+
if (!isBytesLike(log.data))
|
|
299
|
+
throw new Error(`invalid data=${util.inspect(log.data)}`);
|
|
300
|
+
let fragments;
|
|
301
|
+
if (log.topics?.[0]) {
|
|
302
|
+
const fragment = commitsFragments[log.topics[0]];
|
|
303
|
+
if (!fragment)
|
|
304
|
+
return;
|
|
305
|
+
const isCcipV15 = fragment.name === 'ReportAccepted';
|
|
306
|
+
// CCIP<=1.5 doesn't have lane info in event, so we need lane to be provided (e.g. from CommitStore's configs)
|
|
307
|
+
if (isCcipV15 && !lane)
|
|
308
|
+
throw new Error('decoding commits from CCIP<=v1.5 requires lane');
|
|
309
|
+
fragments = [fragment];
|
|
310
|
+
}
|
|
311
|
+
else
|
|
312
|
+
fragments = Object.values(commitsFragments);
|
|
313
|
+
for (const fragment of fragments) {
|
|
314
|
+
let result;
|
|
315
|
+
try {
|
|
316
|
+
result = interfaces.OffRamp_v1_6.decodeEventLog(fragment, log.data, log.topics);
|
|
317
|
+
}
|
|
318
|
+
catch (_) {
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (result.length === 1)
|
|
322
|
+
result = result[0];
|
|
323
|
+
const isCcipV15 = fragment.name === 'ReportAccepted';
|
|
324
|
+
if (isCcipV15) {
|
|
325
|
+
return [
|
|
326
|
+
{
|
|
327
|
+
merkleRoot: result.merkleRoot,
|
|
328
|
+
minSeqNr: result.interval.min,
|
|
329
|
+
maxSeqNr: result.interval.max,
|
|
330
|
+
sourceChainSelector: lane.sourceChainSelector,
|
|
331
|
+
onRampAddress: lane.onRamp,
|
|
332
|
+
},
|
|
333
|
+
];
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
const reports = [];
|
|
337
|
+
for (const c of [...result[0], ...result[1]]) {
|
|
338
|
+
// if ccip>=v1.6 and lane is provided, use it to filter reports; otherwise, include all
|
|
339
|
+
if (lane && c.sourceChainSelector !== lane.sourceChainSelector)
|
|
340
|
+
continue;
|
|
341
|
+
const onRampAddress = decodeOnRampAddress(c.onRampAddress, networkInfo(c.sourceChainSelector).family);
|
|
342
|
+
if (lane && onRampAddress !== lane.onRamp)
|
|
343
|
+
continue;
|
|
344
|
+
reports.push({ ...c.toObject(), onRampAddress });
|
|
345
|
+
}
|
|
346
|
+
if (reports.length)
|
|
347
|
+
return reports;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
static decodeReceipt(log) {
|
|
352
|
+
if (!isBytesLike(log.data))
|
|
353
|
+
throw new Error(`invalid data=${util.inspect(log.data)}`);
|
|
354
|
+
let fragments;
|
|
355
|
+
if (log.topics?.[0]) {
|
|
356
|
+
fragments = [receiptsFragments[log.topics[0]]];
|
|
357
|
+
if (!fragments[0])
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
else
|
|
361
|
+
fragments = Object.values(receiptsFragments);
|
|
362
|
+
for (const fragment of fragments) {
|
|
363
|
+
try {
|
|
364
|
+
const result = interfaces.OffRamp_v1_6.decodeEventLog(fragment, log.data, log.topics);
|
|
365
|
+
return {
|
|
366
|
+
...result.toObject(),
|
|
367
|
+
// ...(fragment.inputs.filter((p) => p.indexed).map((p, i) => [p.name, log.topics[i+1]] as const)).
|
|
368
|
+
state: Number(result.state),
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
catch (_) {
|
|
372
|
+
// continue
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
static decodeExtraArgs(extraArgs) {
|
|
377
|
+
const data = getDataBytes(extraArgs), tag = dataSlice(data, 0, 4);
|
|
378
|
+
switch (tag) {
|
|
379
|
+
case EVMExtraArgsV1Tag: {
|
|
380
|
+
const args = defaultAbiCoder.decode([EVMExtraArgsV1], dataSlice(data, 4));
|
|
381
|
+
return { ...args[0].toObject(), _tag: 'EVMExtraArgsV1' };
|
|
382
|
+
}
|
|
383
|
+
case EVMExtraArgsV2Tag: {
|
|
384
|
+
const args = defaultAbiCoder.decode([EVMExtraArgsV2], dataSlice(data, 4));
|
|
385
|
+
return { ...args[0].toObject(), _tag: 'EVMExtraArgsV2' };
|
|
386
|
+
}
|
|
387
|
+
case SVMExtraArgsV1Tag: {
|
|
388
|
+
const args = defaultAbiCoder.decode([SVMExtraArgsV1], dataSlice(data, 4));
|
|
389
|
+
const parsed = args[0].toObject();
|
|
390
|
+
parsed.tokenReceiver = encodeBase58(parsed.tokenReceiver);
|
|
391
|
+
parsed.accounts = parsed.accounts.map((a) => encodeBase58(a));
|
|
392
|
+
return { ...parsed, _tag: 'SVMExtraArgsV1' };
|
|
393
|
+
}
|
|
394
|
+
case SuiExtraArgsV1Tag: {
|
|
395
|
+
const args = defaultAbiCoder.decode([SuiExtraArgsV1], dataSlice(data, 4));
|
|
396
|
+
const parsed = args[0].toObject();
|
|
397
|
+
return {
|
|
398
|
+
...parsed,
|
|
399
|
+
receiverObjectIds: Array.from(parsed.receiverObjectIds),
|
|
400
|
+
_tag: 'SuiExtraArgsV1',
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
default:
|
|
404
|
+
return undefined;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
static encodeExtraArgs(args) {
|
|
408
|
+
if (!args)
|
|
409
|
+
return '0x';
|
|
410
|
+
if ('computeUnits' in args) {
|
|
411
|
+
return concat([
|
|
412
|
+
SVMExtraArgsV1Tag,
|
|
413
|
+
defaultAbiCoder.encode([SVMExtraArgsV1], [
|
|
414
|
+
{
|
|
415
|
+
...args,
|
|
416
|
+
tokenReceiver: getAddressBytes(args.tokenReceiver),
|
|
417
|
+
accounts: args.accounts.map((a) => getAddressBytes(a)),
|
|
418
|
+
},
|
|
419
|
+
]),
|
|
420
|
+
]);
|
|
421
|
+
}
|
|
422
|
+
else if ('receiverObjectIds' in args) {
|
|
423
|
+
return concat([
|
|
424
|
+
SuiExtraArgsV1Tag,
|
|
425
|
+
defaultAbiCoder.encode([SuiExtraArgsV1], [
|
|
426
|
+
{
|
|
427
|
+
...args,
|
|
428
|
+
tokenReceiver: zeroPadValue(getAddressBytes(args.tokenReceiver), 32),
|
|
429
|
+
receiverObjectIds: args.receiverObjectIds.map((a) => getDataBytes(a)),
|
|
430
|
+
},
|
|
431
|
+
]),
|
|
432
|
+
]);
|
|
433
|
+
}
|
|
434
|
+
else if ('allowOutOfOrderExecution' in args) {
|
|
435
|
+
if (args.gasLimit == null)
|
|
436
|
+
args.gasLimit = DEFAULT_GAS_LIMIT;
|
|
437
|
+
return concat([EVMExtraArgsV2Tag, defaultAbiCoder.encode([EVMExtraArgsV2], [args])]);
|
|
438
|
+
}
|
|
439
|
+
else if (args.gasLimit != null) {
|
|
440
|
+
return concat([EVMExtraArgsV1Tag, defaultAbiCoder.encode([EVMExtraArgsV1], [args])]);
|
|
441
|
+
}
|
|
442
|
+
return '0x';
|
|
443
|
+
}
|
|
444
|
+
static getAddress(bytes) {
|
|
445
|
+
bytes = getBytes(bytes);
|
|
446
|
+
if (bytes.length < 20)
|
|
447
|
+
throw new Error(`Invalid address: ${hexlify(bytes)}`);
|
|
448
|
+
else if (bytes.length > 20) {
|
|
449
|
+
if (bytes.slice(0, bytes.length - 20).every((b) => b === 0)) {
|
|
450
|
+
bytes = bytes.slice(-20);
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
throw new Error(`Invalid address: ${hexlify(bytes)}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return getAddress(hexlify(bytes));
|
|
457
|
+
}
|
|
458
|
+
async typeAndVersion(address) {
|
|
459
|
+
const contract = new Contract(address, VersionedContractABI, this.provider);
|
|
460
|
+
return parseTypeAndVersion(await contract.typeAndVersion());
|
|
461
|
+
}
|
|
462
|
+
async getLaneForOnRamp(onRamp) {
|
|
463
|
+
const [, version] = await this.typeAndVersion(onRamp);
|
|
464
|
+
const onRampABI = version === CCIPVersion.V1_2 ? EVM2EVMOnRamp_1_2_ABI : EVM2EVMOnRamp_1_5_ABI;
|
|
465
|
+
const contract = new Contract(onRamp, onRampABI, this.provider);
|
|
466
|
+
// TODO: memo this call
|
|
467
|
+
const staticConfig = await contract.getStaticConfig();
|
|
468
|
+
if (!staticConfig.destChainSelector)
|
|
469
|
+
throw new Error(`No destChainSelector in OnRamp.staticConfig: ${JSON.stringify(staticConfig)}`);
|
|
470
|
+
return {
|
|
471
|
+
sourceChainSelector: this.network.chainSelector,
|
|
472
|
+
destChainSelector: staticConfig.destChainSelector,
|
|
473
|
+
version: version,
|
|
474
|
+
onRamp,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
async getRouterForOnRamp(onRamp, destChainSelector) {
|
|
478
|
+
const [, version] = await this.typeAndVersion(onRamp);
|
|
479
|
+
let onRampABI;
|
|
480
|
+
switch (version) {
|
|
481
|
+
case CCIPVersion.V1_2:
|
|
482
|
+
onRampABI = EVM2EVMOnRamp_1_2_ABI;
|
|
483
|
+
// falls through
|
|
484
|
+
case CCIPVersion.V1_5: {
|
|
485
|
+
onRampABI ??= EVM2EVMOnRamp_1_5_ABI;
|
|
486
|
+
const contract = new Contract(onRamp, onRampABI, this.provider);
|
|
487
|
+
const { router } = await contract.getDynamicConfig();
|
|
488
|
+
return router;
|
|
489
|
+
}
|
|
490
|
+
case CCIPVersion.V1_6: {
|
|
491
|
+
onRampABI = OnRamp_1_6_ABI;
|
|
492
|
+
const contract = new Contract(onRamp, onRampABI, this.provider);
|
|
493
|
+
const [, , router] = await contract.getDestChainConfig(destChainSelector);
|
|
494
|
+
return router;
|
|
495
|
+
}
|
|
496
|
+
default:
|
|
497
|
+
throw new Error(`Unsupported version: ${version}`);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
async getRouterForOffRamp(offRamp, sourceChainSelector) {
|
|
501
|
+
const [, version] = await this.typeAndVersion(offRamp);
|
|
502
|
+
let offRampABI, router;
|
|
503
|
+
switch (version) {
|
|
504
|
+
case CCIPVersion.V1_2:
|
|
505
|
+
offRampABI = EVM2EVMOffRamp_1_2_ABI;
|
|
506
|
+
// falls through
|
|
507
|
+
case CCIPVersion.V1_5: {
|
|
508
|
+
offRampABI ??= EVM2EVMOffRamp_1_5_ABI;
|
|
509
|
+
const contract = new Contract(offRamp, offRampABI, this.provider);
|
|
510
|
+
({ router } = await contract.getDynamicConfig());
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
case CCIPVersion.V1_6: {
|
|
514
|
+
offRampABI = OffRamp_1_6_ABI;
|
|
515
|
+
const contract = new Contract(offRamp, offRampABI, this.provider);
|
|
516
|
+
({ router } = await contract.getSourceChainConfig(sourceChainSelector));
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
default:
|
|
520
|
+
throw new Error(`Unsupported version: ${version}`);
|
|
521
|
+
}
|
|
522
|
+
return router;
|
|
523
|
+
}
|
|
524
|
+
async getNativeTokenForRouter(router) {
|
|
525
|
+
const contract = new Contract(router, interfaces.Router, this.provider);
|
|
526
|
+
return contract.getWrappedNative();
|
|
527
|
+
}
|
|
528
|
+
async getOffRampsForRouter(router, sourceChainSelector) {
|
|
529
|
+
const contract = new Contract(router, interfaces.Router, this.provider);
|
|
530
|
+
const offRamps = await contract.getOffRamps();
|
|
531
|
+
return offRamps
|
|
532
|
+
.filter((offRamp) => offRamp.sourceChainSelector === sourceChainSelector)
|
|
533
|
+
.map(({ offRamp }) => offRamp);
|
|
534
|
+
}
|
|
535
|
+
async getOnRampForRouter(router, destChainSelector) {
|
|
536
|
+
const contract = new Contract(router, interfaces.Router, this.provider);
|
|
537
|
+
return contract.getOnRamp(destChainSelector);
|
|
538
|
+
}
|
|
539
|
+
async getOnRampForOffRamp(offRamp, sourceChainSelector) {
|
|
540
|
+
const [, version] = await this.typeAndVersion(offRamp);
|
|
541
|
+
let offRampABI;
|
|
542
|
+
switch (version) {
|
|
543
|
+
case CCIPVersion.V1_2:
|
|
544
|
+
offRampABI = EVM2EVMOffRamp_1_2_ABI;
|
|
545
|
+
// falls through
|
|
546
|
+
case CCIPVersion.V1_5: {
|
|
547
|
+
offRampABI ??= EVM2EVMOffRamp_1_5_ABI;
|
|
548
|
+
const contract = new Contract(offRamp, offRampABI, this.provider);
|
|
549
|
+
const { onRamp } = await contract.getStaticConfig();
|
|
550
|
+
return onRamp;
|
|
551
|
+
}
|
|
552
|
+
case CCIPVersion.V1_6: {
|
|
553
|
+
offRampABI = OffRamp_1_6_ABI;
|
|
554
|
+
const contract = new Contract(offRamp, offRampABI, this.provider);
|
|
555
|
+
const { onRamp } = await contract.getSourceChainConfig(sourceChainSelector);
|
|
556
|
+
return decodeOnRampAddress(onRamp, networkInfo(sourceChainSelector).family);
|
|
557
|
+
}
|
|
558
|
+
default:
|
|
559
|
+
throw new Error(`Unsupported version: ${version}`);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
async getCommitStoreForOffRamp(offRamp) {
|
|
563
|
+
const [, version] = await this.typeAndVersion(offRamp);
|
|
564
|
+
let offRampABI;
|
|
565
|
+
switch (version) {
|
|
566
|
+
case CCIPVersion.V1_2:
|
|
567
|
+
offRampABI = EVM2EVMOffRamp_1_2_ABI;
|
|
568
|
+
// falls through
|
|
569
|
+
case CCIPVersion.V1_5: {
|
|
570
|
+
offRampABI ??= EVM2EVMOffRamp_1_5_ABI;
|
|
571
|
+
const contract = new Contract(offRamp, offRampABI, this.provider);
|
|
572
|
+
const { commitStore } = await contract.getStaticConfig();
|
|
573
|
+
return commitStore;
|
|
574
|
+
}
|
|
575
|
+
case CCIPVersion.V1_6: {
|
|
576
|
+
return offRamp;
|
|
577
|
+
}
|
|
578
|
+
default:
|
|
579
|
+
throw new Error(`Unsupported version: ${version}`);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
async getTokenForTokenPool(tokenPool) {
|
|
583
|
+
const contract = new Contract(tokenPool, interfaces.TokenPool_v1_6, this.provider);
|
|
584
|
+
return contract.getToken();
|
|
585
|
+
}
|
|
586
|
+
async getTokenInfo(token) {
|
|
587
|
+
const contract = new Contract(token, interfaces.Token, this.provider);
|
|
588
|
+
const [symbol, decimals, name] = await Promise.all([
|
|
589
|
+
contract.symbol(),
|
|
590
|
+
contract.decimals(),
|
|
591
|
+
contract.name(),
|
|
592
|
+
]);
|
|
593
|
+
return { symbol, decimals: Number(decimals), name };
|
|
594
|
+
}
|
|
595
|
+
static getDestLeafHasher({ sourceChainSelector, destChainSelector, onRamp, version, }) {
|
|
596
|
+
switch (version) {
|
|
597
|
+
case CCIPVersion.V1_2:
|
|
598
|
+
case CCIPVersion.V1_5:
|
|
599
|
+
if (networkInfo(sourceChainSelector).family !== ChainFamily.EVM)
|
|
600
|
+
throw new Error(`Unsupported source chain: ${sourceChainSelector}`);
|
|
601
|
+
return getV12LeafHasher(sourceChainSelector, destChainSelector, onRamp);
|
|
602
|
+
case CCIPVersion.V1_6:
|
|
603
|
+
return getV16LeafHasher(sourceChainSelector, destChainSelector, onRamp);
|
|
604
|
+
default:
|
|
605
|
+
throw new Error(`Unsupported hasher version for EVM: ${version}`);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
async _getSomeOnRampFor(router) {
|
|
609
|
+
// when given a router, we take any onRamp we can find, as usually they all use same registry
|
|
610
|
+
const someOtherNetwork = this.network.isTestnet
|
|
611
|
+
? this.network.name === 'ethereum-testnet-sepolia'
|
|
612
|
+
? 'avalanche-testnet-fuji'
|
|
613
|
+
: 'ethereum-testnet-sepolia'
|
|
614
|
+
: this.network.name === 'ethereum-mainnet'
|
|
615
|
+
? 'avalanche-mainnet'
|
|
616
|
+
: 'ethereum-mainnet';
|
|
617
|
+
return this.getOnRampForRouter(router, networkInfo(someOtherNetwork).chainSelector);
|
|
618
|
+
}
|
|
619
|
+
async getTokenAdminRegistryFor(address) {
|
|
620
|
+
let [type, version, typeAndVersion] = await this.typeAndVersion(address);
|
|
621
|
+
if (type === 'TokenAdminRegistry') {
|
|
622
|
+
return address;
|
|
623
|
+
}
|
|
624
|
+
else if (type === 'Router') {
|
|
625
|
+
address = await this._getSomeOnRampFor(address);
|
|
626
|
+
[type, version, typeAndVersion] = await this.typeAndVersion(address);
|
|
627
|
+
}
|
|
628
|
+
else if (!type.includes('Ramp')) {
|
|
629
|
+
throw new Error(`Not a Router, Ramp or TokenAdminRegistry: ${address} is "${typeAndVersion}"`);
|
|
630
|
+
}
|
|
631
|
+
const contract = new Contract(address, version < CCIPVersion.V1_6
|
|
632
|
+
? type.includes('OnRamp')
|
|
633
|
+
? interfaces.EVM2EVMOnRamp_v1_5
|
|
634
|
+
: interfaces.EVM2EVMOffRamp_v1_5
|
|
635
|
+
: type.includes('OnRamp')
|
|
636
|
+
? interfaces.OnRamp_v1_6
|
|
637
|
+
: interfaces.OffRamp_v1_6, this.provider);
|
|
638
|
+
const { tokenAdminRegistry } = await contract.getStaticConfig();
|
|
639
|
+
return tokenAdminRegistry;
|
|
640
|
+
}
|
|
641
|
+
async getFeeQuoterFor(address) {
|
|
642
|
+
let [type, version, typeAndVersion] = await this.typeAndVersion(address);
|
|
643
|
+
if (type === 'FeeQuoter') {
|
|
644
|
+
return address;
|
|
645
|
+
}
|
|
646
|
+
else if (type === 'Router') {
|
|
647
|
+
address = await this._getSomeOnRampFor(address);
|
|
648
|
+
[type, version, typeAndVersion] = await this.typeAndVersion(address);
|
|
649
|
+
}
|
|
650
|
+
else if (!type.includes('Ramp')) {
|
|
651
|
+
throw new Error(`Not a Router, Ramp or FeeQuoter: ${address} is "${typeAndVersion}"`);
|
|
652
|
+
}
|
|
653
|
+
if (version < CCIPVersion.V1_6)
|
|
654
|
+
throw new Error(`Version < v1.6 doesn't have feeQuoter: got=${version}`);
|
|
655
|
+
const contract = new Contract(address, type.includes('OnRamp') ? interfaces.OnRamp_v1_6 : interfaces.OffRamp_v1_6, this.provider);
|
|
656
|
+
const { feeQuoter } = await contract.getDynamicConfig();
|
|
657
|
+
return feeQuoter;
|
|
658
|
+
}
|
|
659
|
+
async getFee(router_, destChainSelector, message) {
|
|
660
|
+
const router = new Contract(router_, interfaces.Router, this.provider);
|
|
661
|
+
return router.getFee(destChainSelector, {
|
|
662
|
+
receiver: zeroPadValue(getAddressBytes(message.receiver), 32),
|
|
663
|
+
data: hexlify(message.data),
|
|
664
|
+
tokenAmounts: message.tokenAmounts ?? [],
|
|
665
|
+
feeToken: message.feeToken ?? ZeroAddress,
|
|
666
|
+
extraArgs: hexlify(this.constructor.encodeExtraArgs(message.extraArgs)),
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
async sendMessage(router_, destChainSelector, message, opts) {
|
|
670
|
+
const feeToken = message.feeToken ?? ZeroAddress;
|
|
671
|
+
const receiver = zeroPadValue(getAddressBytes(message.receiver), 32);
|
|
672
|
+
const data = hexlify(message.data);
|
|
673
|
+
const extraArgs = hexlify(this.constructor.encodeExtraArgs(message.extraArgs));
|
|
674
|
+
// make sure to approve once per token, for the total amount (including fee, if needed)
|
|
675
|
+
const amountsToApprove = (message.tokenAmounts ?? []).reduce((acc, { token, amount }) => ({ ...acc, [token]: (acc[token] ?? 0n) + amount }), {});
|
|
676
|
+
if (feeToken !== ZeroAddress)
|
|
677
|
+
amountsToApprove[feeToken] = (amountsToApprove[feeToken] ?? 0n) + message.fee;
|
|
678
|
+
const wallet = await this.getWallet(opts); // moized wallet arg (if called previously)
|
|
679
|
+
// approve all tokens (including fee token) in parallel
|
|
680
|
+
let nonce = await this.provider.getTransactionCount(await this.getWalletAddress());
|
|
681
|
+
await Promise.all(Object.entries(amountsToApprove).map(async ([token, amount]) => {
|
|
682
|
+
const contract = new Contract(token, interfaces.Token, wallet);
|
|
683
|
+
const allowance = await contract.allowance(await wallet.getAddress(), router_);
|
|
684
|
+
if (allowance < amount) {
|
|
685
|
+
const amnt = opts?.approveMax ? 2n ** 256n - 1n : amount;
|
|
686
|
+
// optimization: hardcode nonce and gasLimit to send all approvals in parallel without estimating
|
|
687
|
+
console.info('Approving', amnt, 'of', token, 'tokens for router', router_);
|
|
688
|
+
const tx = await contract.approve(router_, amnt, {
|
|
689
|
+
nonce: nonce++,
|
|
690
|
+
gasLimit: DEFAULT_APPROVE_GAS_LIMIT,
|
|
691
|
+
});
|
|
692
|
+
console.info('=>', tx.hash);
|
|
693
|
+
await tx.wait(1, 60_000);
|
|
694
|
+
}
|
|
695
|
+
}));
|
|
696
|
+
const router = new Contract(router_, interfaces.Router, wallet);
|
|
697
|
+
const tx = await router.ccipSend(destChainSelector, {
|
|
698
|
+
receiver,
|
|
699
|
+
data,
|
|
700
|
+
tokenAmounts: message.tokenAmounts ?? [],
|
|
701
|
+
extraArgs,
|
|
702
|
+
feeToken,
|
|
703
|
+
}, {
|
|
704
|
+
nonce: nonce++,
|
|
705
|
+
// if native fee, include it in value; otherwise, it's transferedFrom feeToken
|
|
706
|
+
...(feeToken === ZeroAddress ? { value: message.fee } : {}),
|
|
707
|
+
});
|
|
708
|
+
const receipt = await tx.wait(1);
|
|
709
|
+
return this.getTransaction(receipt);
|
|
710
|
+
}
|
|
711
|
+
fetchOffchainTokenData(request) {
|
|
712
|
+
return fetchEVMOffchainTokenData(request);
|
|
713
|
+
}
|
|
714
|
+
async executeReport(offRamp, execReport, opts) {
|
|
715
|
+
const [_, version] = await this.typeAndVersion(offRamp);
|
|
716
|
+
const wallet = await this.getWallet(opts);
|
|
717
|
+
let manualExecTx;
|
|
718
|
+
const offchainTokenData = execReport.offchainTokenData.map(encodeEVMOffchainTokenData);
|
|
719
|
+
switch (version) {
|
|
720
|
+
case CCIPVersion.V1_2: {
|
|
721
|
+
const contract = new Contract(offRamp, EVM2EVMOffRamp_1_2_ABI, wallet);
|
|
722
|
+
const gasOverride = BigInt(opts?.gasLimit ?? 0);
|
|
723
|
+
manualExecTx = await contract.manuallyExecute({
|
|
724
|
+
...execReport,
|
|
725
|
+
proofs: execReport.proofs.map((d) => hexlify(d)),
|
|
726
|
+
messages: [execReport.message],
|
|
727
|
+
offchainTokenData: [offchainTokenData],
|
|
728
|
+
}, [gasOverride]);
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
case CCIPVersion.V1_5: {
|
|
732
|
+
const contract = new Contract(offRamp, EVM2EVMOffRamp_1_5_ABI, wallet);
|
|
733
|
+
manualExecTx = await contract.manuallyExecute({
|
|
734
|
+
...execReport,
|
|
735
|
+
proofs: execReport.proofs.map((d) => hexlify(d)),
|
|
736
|
+
messages: [execReport.message],
|
|
737
|
+
offchainTokenData: [offchainTokenData],
|
|
738
|
+
}, [
|
|
739
|
+
{
|
|
740
|
+
receiverExecutionGasLimit: BigInt(opts?.gasLimit ?? 0),
|
|
741
|
+
tokenGasOverrides: execReport.message.tokenAmounts.map(() => BigInt(opts?.tokensGasLimit ?? opts?.gasLimit ?? 0)),
|
|
742
|
+
},
|
|
743
|
+
]);
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
case CCIPVersion.V1_6: {
|
|
747
|
+
// normalize message
|
|
748
|
+
const sender = zeroPadValue(getAddressBytes(execReport.message.sender), 32);
|
|
749
|
+
const tokenAmounts = execReport.message.tokenAmounts.map((ta) => ({
|
|
750
|
+
...ta,
|
|
751
|
+
sourcePoolAddress: zeroPadValue(getAddressBytes(ta.sourcePoolAddress), 32),
|
|
752
|
+
extraData: hexlify(getDataBytes(ta.extraData)),
|
|
753
|
+
}));
|
|
754
|
+
const message = {
|
|
755
|
+
...execReport.message,
|
|
756
|
+
sender,
|
|
757
|
+
tokenAmounts,
|
|
758
|
+
};
|
|
759
|
+
const contract = new Contract(offRamp, OffRamp_1_6_ABI, wallet);
|
|
760
|
+
manualExecTx = await contract.manuallyExecute([
|
|
761
|
+
{
|
|
762
|
+
...execReport,
|
|
763
|
+
proofs: execReport.proofs.map((p) => hexlify(p)),
|
|
764
|
+
sourceChainSelector: execReport.message.header.sourceChainSelector,
|
|
765
|
+
messages: [message],
|
|
766
|
+
offchainTokenData: [offchainTokenData],
|
|
767
|
+
},
|
|
768
|
+
], [
|
|
769
|
+
[
|
|
770
|
+
{
|
|
771
|
+
receiverExecutionGasLimit: BigInt(opts?.gasLimit ?? 0),
|
|
772
|
+
tokenGasOverrides: execReport.message.tokenAmounts.map(() => BigInt(opts?.tokensGasLimit ?? opts?.gasLimit ?? 0)),
|
|
773
|
+
},
|
|
774
|
+
],
|
|
775
|
+
]);
|
|
776
|
+
break;
|
|
777
|
+
}
|
|
778
|
+
default:
|
|
779
|
+
throw new Error(`Unsupported version: ${version}`);
|
|
780
|
+
}
|
|
781
|
+
const receipt = await this.provider.waitForTransaction(manualExecTx.hash, 1, 60e3);
|
|
782
|
+
if (!receipt?.hash)
|
|
783
|
+
throw new Error(`Could not confirm exec tx: ${manualExecTx.hash}`);
|
|
784
|
+
if (!receipt.status)
|
|
785
|
+
throw new Error(`Exec transaction reverted: ${manualExecTx.hash}`);
|
|
786
|
+
return this.getTransaction(receipt);
|
|
787
|
+
}
|
|
788
|
+
static parse(data) {
|
|
789
|
+
return parseData(data);
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Get the supported tokens for a given contract address
|
|
793
|
+
*
|
|
794
|
+
* @param address Router, OnRamp, OffRamp or TokenAdminRegistry contract
|
|
795
|
+
* @returns An array of supported token addresses.
|
|
796
|
+
*/
|
|
797
|
+
async getSupportedTokens(registry, opts) {
|
|
798
|
+
const contract = new Contract(registry, interfaces.TokenAdminRegistry, this.provider);
|
|
799
|
+
const limit = (opts?.page ?? 1000) || Number.MAX_SAFE_INTEGER;
|
|
800
|
+
const res = [];
|
|
801
|
+
let page;
|
|
802
|
+
do {
|
|
803
|
+
page = await contract.getAllConfiguredTokens(BigInt(res.length), BigInt(limit));
|
|
804
|
+
res.push(...page);
|
|
805
|
+
} while (page.length === limit);
|
|
806
|
+
return res;
|
|
807
|
+
}
|
|
808
|
+
async getRegistryTokenConfig(registry, token) {
|
|
809
|
+
const contract = new Contract(registry, interfaces.TokenAdminRegistry, this.provider);
|
|
810
|
+
const config = (await resultToObject(contract.getTokenConfig(token)));
|
|
811
|
+
if (!config.administrator || config.administrator === ZeroAddress)
|
|
812
|
+
throw new Error(`Token ${token} is not configured in registry ${registry}`);
|
|
813
|
+
if (!config.pendingAdministrator || config.pendingAdministrator === ZeroAddress)
|
|
814
|
+
delete config.pendingAdministrator;
|
|
815
|
+
if (!config.tokenPool || config.tokenPool === ZeroAddress)
|
|
816
|
+
delete config.tokenPool;
|
|
817
|
+
return {
|
|
818
|
+
...config,
|
|
819
|
+
administrator: config.administrator,
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
async getTokenPoolConfigs(tokenPool) {
|
|
823
|
+
const [_, , typeAndVersion] = await this.typeAndVersion(tokenPool);
|
|
824
|
+
const contract = new Contract(tokenPool, interfaces.TokenPool_v1_6, this.provider);
|
|
825
|
+
const token = contract.getToken();
|
|
826
|
+
const router = contract.getRouter();
|
|
827
|
+
return Promise.all([token, router]).then(([token, router]) => {
|
|
828
|
+
return {
|
|
829
|
+
token: token,
|
|
830
|
+
router: router,
|
|
831
|
+
typeAndVersion,
|
|
832
|
+
};
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
async getTokenPoolRemotes(tokenPool, remoteChainSelector) {
|
|
836
|
+
const [_, version] = await this.typeAndVersion(tokenPool);
|
|
837
|
+
let supportedChains;
|
|
838
|
+
if (remoteChainSelector)
|
|
839
|
+
supportedChains = Promise.resolve([networkInfo(remoteChainSelector)]);
|
|
840
|
+
let remotePools;
|
|
841
|
+
let contract;
|
|
842
|
+
if (version < '1.5.1') {
|
|
843
|
+
const contract_ = new Contract(tokenPool, interfaces.TokenPool_v1_5, this.provider);
|
|
844
|
+
contract = contract_;
|
|
845
|
+
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo));
|
|
846
|
+
remotePools = supportedChains.then((chains) => Promise.all(chains.map((chain) => contract_
|
|
847
|
+
.getRemotePool(chain.chainSelector)
|
|
848
|
+
.then((remotePool) => [decodeAddress(remotePool, chain.family)]))));
|
|
849
|
+
}
|
|
850
|
+
else {
|
|
851
|
+
const contract_ = new Contract(tokenPool, interfaces.TokenPool_v1_6, this.provider);
|
|
852
|
+
contract = contract_;
|
|
853
|
+
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo));
|
|
854
|
+
remotePools = supportedChains.then((chains) => Promise.all(chains.map((chain) => contract_
|
|
855
|
+
.getRemotePools(chain.chainSelector)
|
|
856
|
+
.then((pools) => pools.map((remotePool) => decodeAddress(remotePool, chain.family))))));
|
|
857
|
+
}
|
|
858
|
+
const remoteInfo = supportedChains.then((chains) => Promise.all(chains.map((chain) => Promise.all([
|
|
859
|
+
contract.getRemoteToken(chain.chainSelector),
|
|
860
|
+
resultToObject(contract.getCurrentInboundRateLimiterState(chain.chainSelector)),
|
|
861
|
+
resultToObject(contract.getCurrentOutboundRateLimiterState(chain.chainSelector)),
|
|
862
|
+
]))));
|
|
863
|
+
return Promise.all([supportedChains, remotePools, remoteInfo]).then(([supportedChains, remotePools, remoteInfo]) => Object.fromEntries(supportedChains.map((chain, i) => [
|
|
864
|
+
chain.name,
|
|
865
|
+
{
|
|
866
|
+
remoteToken: decodeAddress(remoteInfo[i][0], chain.family),
|
|
867
|
+
remotePools: remotePools[i].map((pool) => decodeAddress(pool, chain.family)),
|
|
868
|
+
inboundRateLimiterState: remoteInfo[i][1].isEnabled ? remoteInfo[i][1] : null,
|
|
869
|
+
outboundRateLimiterState: remoteInfo[i][2].isEnabled ? remoteInfo[i][2] : null,
|
|
870
|
+
},
|
|
871
|
+
])));
|
|
872
|
+
}
|
|
873
|
+
async listFeeTokens(router) {
|
|
874
|
+
const onRamp = await this._getSomeOnRampFor(router);
|
|
875
|
+
const [_, version] = await this.typeAndVersion(onRamp);
|
|
876
|
+
let tokens;
|
|
877
|
+
let onRampABI;
|
|
878
|
+
switch (version) {
|
|
879
|
+
case CCIPVersion.V1_2:
|
|
880
|
+
onRampABI = EVM2EVMOnRamp_1_2_ABI;
|
|
881
|
+
// falls through
|
|
882
|
+
case CCIPVersion.V1_5: {
|
|
883
|
+
onRampABI ??= EVM2EVMOnRamp_1_5_ABI;
|
|
884
|
+
const contract = new Contract(onRamp, onRampABI, this.provider);
|
|
885
|
+
tokens = await Promise.all([
|
|
886
|
+
this.getNativeTokenForRouter(router),
|
|
887
|
+
contract.getStaticConfig().then(({ linkToken }) => linkToken),
|
|
888
|
+
]);
|
|
889
|
+
break;
|
|
890
|
+
}
|
|
891
|
+
case CCIPVersion.V1_6: {
|
|
892
|
+
const feeQuoter = await this.getFeeQuoterFor(onRamp);
|
|
893
|
+
const contract = new Contract(feeQuoter, interfaces.FeeQuoter, this.provider);
|
|
894
|
+
tokens = await contract.getFeeTokens();
|
|
895
|
+
break;
|
|
896
|
+
}
|
|
897
|
+
default:
|
|
898
|
+
throw new Error(`Unsupported version: ${version}`);
|
|
899
|
+
}
|
|
900
|
+
return Object.fromEntries(await Promise.all(tokens.map(async (token) => [token, await this.getTokenInfo(token)])));
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
supportedChains[ChainFamily.EVM] = EVMChain;
|
|
904
|
+
//# sourceMappingURL=index.js.map
|