@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
package/src/requests.ts
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import util from 'util'
|
|
2
|
+
|
|
3
|
+
import { isBytesLike, toBigInt } from 'ethers'
|
|
4
|
+
import yaml from 'yaml'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
type Chain,
|
|
8
|
+
type ChainStatic,
|
|
9
|
+
type ChainTransaction,
|
|
10
|
+
type LogFilter,
|
|
11
|
+
ChainFamily,
|
|
12
|
+
} from './chain.ts'
|
|
13
|
+
import type { EVMChain } from './evm/index.ts'
|
|
14
|
+
import { decodeExtraArgs } from './extra-args.ts'
|
|
15
|
+
import { supportedChains } from './supported-chains.ts'
|
|
16
|
+
import type { CCIPMessage, CCIPRequest, CCIPVersion, Log_ } from './types.ts'
|
|
17
|
+
import { convertKeysToCamelCase, decodeAddress, leToBigInt, networkInfo } from './utils.ts'
|
|
18
|
+
|
|
19
|
+
function decodeJsonMessage(data: Record<string, unknown>) {
|
|
20
|
+
if (!data || typeof data != 'object') throw new Error(`invalid msg: ${util.inspect(data)}`)
|
|
21
|
+
if (data.message) data = data.message as Record<string, unknown>
|
|
22
|
+
let data_ = data as Record<string, unknown> & {
|
|
23
|
+
header: {
|
|
24
|
+
dest_chain_selector?: string
|
|
25
|
+
destChainSelector?: string
|
|
26
|
+
sourceChainSelector?: string
|
|
27
|
+
source_chain_selector?: string
|
|
28
|
+
}
|
|
29
|
+
sourceChainSelector?: string
|
|
30
|
+
extraArgs?: string
|
|
31
|
+
tokenAmounts: {
|
|
32
|
+
destExecData: string
|
|
33
|
+
destGasAmount?: bigint
|
|
34
|
+
}[]
|
|
35
|
+
}
|
|
36
|
+
const sourceChainSelector =
|
|
37
|
+
data_.header?.sourceChainSelector ??
|
|
38
|
+
data_.header?.source_chain_selector ??
|
|
39
|
+
data_.sourceChainSelector
|
|
40
|
+
if (!sourceChainSelector) throw new Error(`invalid msg: ${util.inspect(data)}`)
|
|
41
|
+
const sourceNetwork = networkInfo(sourceChainSelector)
|
|
42
|
+
if (!data_.header) {
|
|
43
|
+
const header = {
|
|
44
|
+
sourceChainSelector: data_.sourceChainSelector,
|
|
45
|
+
messageId: data_.messageId,
|
|
46
|
+
nonce: data_.nonce,
|
|
47
|
+
sequenceNumber: data_.sequenceNumber,
|
|
48
|
+
}
|
|
49
|
+
data_.header = header
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const destChainSelector = data_.header.dest_chain_selector ?? data_.header.destChainSelector
|
|
53
|
+
if (destChainSelector) {
|
|
54
|
+
const destFamily = networkInfo(destChainSelector).family
|
|
55
|
+
data_ = convertKeysToCamelCase(data_, (v, k) =>
|
|
56
|
+
typeof v === 'string' && v.match(/^\d+$/)
|
|
57
|
+
? BigInt(v)
|
|
58
|
+
: k === 'receiver' || k === 'destTokenAddress'
|
|
59
|
+
? decodeAddress(v as string, destFamily)
|
|
60
|
+
: v,
|
|
61
|
+
) as typeof data_
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for (const ta of data_.tokenAmounts) {
|
|
65
|
+
if (ta.destGasAmount != null || ta.destExecData == null) continue
|
|
66
|
+
switch (sourceNetwork.family) {
|
|
67
|
+
// EVM & Solana encode destExecData as big-endian
|
|
68
|
+
case ChainFamily.EVM:
|
|
69
|
+
case ChainFamily.Solana:
|
|
70
|
+
ta.destGasAmount = toBigInt(ta.destExecData)
|
|
71
|
+
break
|
|
72
|
+
// Aptos & Sui, as little-endian
|
|
73
|
+
default:
|
|
74
|
+
ta.destGasAmount = leToBigInt(ta.destExecData)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (data_.extraArgs) {
|
|
79
|
+
const extraArgs = decodeExtraArgs(data_.extraArgs ?? '', sourceNetwork.family)
|
|
80
|
+
if (extraArgs) {
|
|
81
|
+
const { _tag, ...rest } = extraArgs
|
|
82
|
+
Object.assign(data_, rest)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return data_ as unknown as CCIPMessage
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Decodes hex strings, bytearrays, JSON strings and raw objects as CCIPMessages
|
|
90
|
+
* Does minimal validation, but converts objects in the format expected by ccip-tools-ts
|
|
91
|
+
**/
|
|
92
|
+
export function decodeMessage(data: string | Uint8Array | Record<string, unknown>): CCIPMessage {
|
|
93
|
+
if (
|
|
94
|
+
(typeof data === 'string' && data.startsWith('{')) ||
|
|
95
|
+
(typeof data === 'object' && data !== null && !isBytesLike(data))
|
|
96
|
+
) {
|
|
97
|
+
if (typeof data === 'string')
|
|
98
|
+
data = yaml.parse(data, { intAsBigInt: true }) as Record<string, unknown>
|
|
99
|
+
return decodeJsonMessage(data)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// try bytearray decoding on each supported chain
|
|
103
|
+
for (const chain of Object.values(supportedChains)) {
|
|
104
|
+
try {
|
|
105
|
+
const decoded = chain.decodeMessage({ data } as unknown as Log_)
|
|
106
|
+
if (decoded) return decoded
|
|
107
|
+
} catch (_) {
|
|
108
|
+
// continue
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
throw new Error('Failed to decode message')
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Fetch all CCIP messages in a transaction
|
|
116
|
+
* @param tx - TransactionReceipt to search in
|
|
117
|
+
* @returns CCIP messages in the transaction (at least one)
|
|
118
|
+
**/
|
|
119
|
+
export async function fetchCCIPRequestsInTx(tx: ChainTransaction): Promise<CCIPRequest[]> {
|
|
120
|
+
const source = tx.chain
|
|
121
|
+
const txHash = tx.hash
|
|
122
|
+
const timestamp = tx.timestamp
|
|
123
|
+
|
|
124
|
+
const requests: CCIPRequest[] = []
|
|
125
|
+
for (const log of tx.logs) {
|
|
126
|
+
let lane
|
|
127
|
+
const message = (source.constructor as ChainStatic).decodeMessage(log)
|
|
128
|
+
if (!message) continue
|
|
129
|
+
if ('destChainSelector' in message.header) {
|
|
130
|
+
const [_, version] = await source.typeAndVersion(log.address)
|
|
131
|
+
lane = {
|
|
132
|
+
sourceChainSelector: message.header.sourceChainSelector,
|
|
133
|
+
destChainSelector: message.header.destChainSelector,
|
|
134
|
+
onRamp: log.address,
|
|
135
|
+
version: version as CCIPVersion,
|
|
136
|
+
}
|
|
137
|
+
} else if (source.network.family !== ChainFamily.EVM) {
|
|
138
|
+
throw new Error(`Unsupported network family: ${source.network.family}`)
|
|
139
|
+
} else {
|
|
140
|
+
lane = await (source as EVMChain).getLaneForOnRamp(log.address)
|
|
141
|
+
}
|
|
142
|
+
requests.push({ lane, message, log, tx, timestamp })
|
|
143
|
+
}
|
|
144
|
+
if (!requests.length) {
|
|
145
|
+
throw new Error(`Could not find any CCIPSendRequested message in tx: ${txHash}`)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return requests
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Fetch a CCIP message by its messageId
|
|
153
|
+
* Can be slow due to having to paginate backwards through logs
|
|
154
|
+
*
|
|
155
|
+
* @param source - Provider to fetch logs from
|
|
156
|
+
* @param messageId - messageId to search for
|
|
157
|
+
* @param hints - Optional hints for pagination
|
|
158
|
+
* @returns CCIPRequest with given messageId
|
|
159
|
+
**/
|
|
160
|
+
export async function fetchCCIPMessageById(
|
|
161
|
+
source: Chain,
|
|
162
|
+
messageId: string,
|
|
163
|
+
hints?: { page?: number; onRamp?: string },
|
|
164
|
+
): Promise<CCIPRequest> {
|
|
165
|
+
for await (const log of source.getLogs({
|
|
166
|
+
...hints,
|
|
167
|
+
...(hints?.onRamp ? { address: hints.onRamp } : {}),
|
|
168
|
+
topics: ['CCIPSendRequested', 'CCIPMessageSent'],
|
|
169
|
+
})) {
|
|
170
|
+
const message = (source.constructor as ChainStatic).decodeMessage(log)
|
|
171
|
+
if (message?.header.messageId !== messageId) continue
|
|
172
|
+
let destChainSelector, version
|
|
173
|
+
if ('destChainSelector' in message.header) {
|
|
174
|
+
destChainSelector = message.header.destChainSelector
|
|
175
|
+
;[, version] = await source.typeAndVersion(log.address)
|
|
176
|
+
} else if (source.network.family !== ChainFamily.EVM) {
|
|
177
|
+
throw new Error(`Unsupported network family: ${source.network.family}`)
|
|
178
|
+
} else {
|
|
179
|
+
;({ destChainSelector, version } = await (source as EVMChain).getLaneForOnRamp(log.address))
|
|
180
|
+
}
|
|
181
|
+
const tx = await source.getTransaction(log.transactionHash)
|
|
182
|
+
return {
|
|
183
|
+
lane: {
|
|
184
|
+
sourceChainSelector: source.network.chainSelector,
|
|
185
|
+
destChainSelector,
|
|
186
|
+
onRamp: log.address,
|
|
187
|
+
version: version as CCIPVersion,
|
|
188
|
+
},
|
|
189
|
+
message,
|
|
190
|
+
log,
|
|
191
|
+
tx,
|
|
192
|
+
timestamp: tx.timestamp,
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
throw new Error('Could not find a CCIPSendRequested message with messageId: ' + messageId)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Number of blocks to expand the search window for logs
|
|
199
|
+
const BLOCK_LOG_WINDOW_SIZE = 5000
|
|
200
|
+
|
|
201
|
+
// Helper function to find the sequence number from CCIPSendRequested event logs
|
|
202
|
+
export async function fetchAllMessagesInBatch<R extends Omit<CCIPRequest, 'tx' | 'timestamp'>>(
|
|
203
|
+
source: Chain,
|
|
204
|
+
request: R,
|
|
205
|
+
{ minSeqNr, maxSeqNr }: { minSeqNr: bigint; maxSeqNr: bigint },
|
|
206
|
+
{ page: eventsBatchSize = BLOCK_LOG_WINDOW_SIZE }: { page?: number } = {},
|
|
207
|
+
): Promise<R['message'][]> {
|
|
208
|
+
if (minSeqNr === maxSeqNr) return [request.message]
|
|
209
|
+
|
|
210
|
+
const filter: LogFilter = {
|
|
211
|
+
page: eventsBatchSize,
|
|
212
|
+
topics: [request.log.topics[0]],
|
|
213
|
+
address: request.log.address,
|
|
214
|
+
}
|
|
215
|
+
if (request.message.header.sequenceNumber === maxSeqNr) filter.endBlock = request.log.blockNumber
|
|
216
|
+
else
|
|
217
|
+
// start proportionally before send request block, including case when seqNum==min => startBlock
|
|
218
|
+
filter.startBlock =
|
|
219
|
+
request.log.blockNumber -
|
|
220
|
+
Math.ceil(
|
|
221
|
+
(Number(request.message.header.sequenceNumber - minSeqNr) / Number(maxSeqNr - minSeqNr)) *
|
|
222
|
+
eventsBatchSize,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
const messages: R['message'][] = []
|
|
226
|
+
if (filter.startBlock) {
|
|
227
|
+
// forward
|
|
228
|
+
let backwardsBefore, backwardsEndBlock
|
|
229
|
+
for await (const log of source.getLogs(filter)) {
|
|
230
|
+
backwardsBefore ??= log.transactionHash
|
|
231
|
+
backwardsEndBlock ??= log.blockNumber - 1
|
|
232
|
+
const message = (source.constructor as ChainStatic).decodeMessage(log)
|
|
233
|
+
if (
|
|
234
|
+
!message ||
|
|
235
|
+
('destChainSelector' in message.header &&
|
|
236
|
+
message.header.destChainSelector !== request.lane.destChainSelector)
|
|
237
|
+
)
|
|
238
|
+
continue
|
|
239
|
+
if (message.header.sequenceNumber < minSeqNr) continue
|
|
240
|
+
messages.push(message)
|
|
241
|
+
if (message.header.sequenceNumber >= maxSeqNr) break
|
|
242
|
+
}
|
|
243
|
+
if (messages.length && messages[0].header.sequenceNumber > minSeqNr) {
|
|
244
|
+
// still work to be done backwards
|
|
245
|
+
delete filter['startBlock']
|
|
246
|
+
filter['endBlock'] = backwardsEndBlock
|
|
247
|
+
filter['endBefore'] = backwardsBefore
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (filter.endBlock) {
|
|
251
|
+
// backwards
|
|
252
|
+
for await (const log of source.getLogs(filter)) {
|
|
253
|
+
const message = (source.constructor as ChainStatic).decodeMessage(log)
|
|
254
|
+
if (
|
|
255
|
+
!message ||
|
|
256
|
+
('destChainSelector' in message.header &&
|
|
257
|
+
message.header.destChainSelector !== request.lane.destChainSelector)
|
|
258
|
+
)
|
|
259
|
+
continue
|
|
260
|
+
messages.unshift(message)
|
|
261
|
+
if (message.header.sequenceNumber <= minSeqNr) break
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (messages.length != Number(maxSeqNr - minSeqNr) + 1) {
|
|
266
|
+
throw new Error(
|
|
267
|
+
`Could not find all expected request events: from=${request.log.blockNumber}, wanted=[${Number(minSeqNr)}..${Number(maxSeqNr)}:${Number(maxSeqNr - minSeqNr) + 1}], got=[${messages.map((e) => Number(e.header.sequenceNumber)).join(',')}]`,
|
|
268
|
+
)
|
|
269
|
+
}
|
|
270
|
+
return messages
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export async function* fetchRequestsForSender(
|
|
274
|
+
source: Chain,
|
|
275
|
+
sender: string,
|
|
276
|
+
filter: Pick<LogFilter, 'address' | 'startBlock' | 'startTime' | 'endBlock'>,
|
|
277
|
+
): AsyncGenerator<Omit<CCIPRequest, 'tx' | 'timestamp'>, void, unknown> {
|
|
278
|
+
const filterWithSender = {
|
|
279
|
+
...filter,
|
|
280
|
+
sender, // some chain families may use this to look for account lookup/narrow down the search
|
|
281
|
+
topics: ['CCIPSendRequested', 'CCIPMessageSent'],
|
|
282
|
+
}
|
|
283
|
+
for await (const log of source.getLogs(filterWithSender)) {
|
|
284
|
+
const message = (source.constructor as ChainStatic).decodeMessage(log)
|
|
285
|
+
if (message?.sender !== sender) continue
|
|
286
|
+
let destChainSelector, version
|
|
287
|
+
if ('destChainSelector' in message.header) {
|
|
288
|
+
destChainSelector = message.header.destChainSelector
|
|
289
|
+
;[, version] = await source.typeAndVersion(log.address)
|
|
290
|
+
} else if (source.network.family === ChainFamily.EVM) {
|
|
291
|
+
;({ destChainSelector, version } = await (source as EVMChain).getLaneForOnRamp(log.address))
|
|
292
|
+
} else {
|
|
293
|
+
throw new Error(`Unsupported network family: ${source.network.family}`)
|
|
294
|
+
}
|
|
295
|
+
yield {
|
|
296
|
+
lane: {
|
|
297
|
+
sourceChainSelector: source.network.chainSelector,
|
|
298
|
+
destChainSelector,
|
|
299
|
+
onRamp: log.address,
|
|
300
|
+
version: version as CCIPVersion,
|
|
301
|
+
},
|
|
302
|
+
message,
|
|
303
|
+
log,
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Map source `token` to `sourcePoolAddress + destTokenAddress`
|
|
310
|
+
* @param source - source chain
|
|
311
|
+
* @param destChainSelector - dest network
|
|
312
|
+
* @param onRamp - contract address
|
|
313
|
+
* @param sourceTokenAmounts - usually `{ token, amount }`
|
|
314
|
+
* @returns - { sourcePoolAddress, destTokenAddress, ...rest } objects
|
|
315
|
+
*/
|
|
316
|
+
export async function sourceToDestTokenAmounts<S extends { token: string }>(
|
|
317
|
+
source: Chain,
|
|
318
|
+
destChainSelector: bigint,
|
|
319
|
+
onRamp: string,
|
|
320
|
+
sourceTokenAmounts: readonly S[],
|
|
321
|
+
): Promise<(Omit<S, 'token'> & { sourcePoolAddress: string; destTokenAddress: string })[]> {
|
|
322
|
+
const tokenAdminRegistry = await source.getTokenAdminRegistryFor(onRamp)
|
|
323
|
+
return Promise.all(
|
|
324
|
+
sourceTokenAmounts.map(async ({ token, ...rest }) => {
|
|
325
|
+
const { tokenPool: sourcePoolAddress } = await source.getRegistryTokenConfig(
|
|
326
|
+
tokenAdminRegistry,
|
|
327
|
+
token,
|
|
328
|
+
)
|
|
329
|
+
if (!sourcePoolAddress)
|
|
330
|
+
throw new Error(`Token=${token} not found in registry=${tokenAdminRegistry}`)
|
|
331
|
+
const remotes = await source.getTokenPoolRemotes(sourcePoolAddress, destChainSelector)
|
|
332
|
+
return {
|
|
333
|
+
...rest,
|
|
334
|
+
sourcePoolAddress,
|
|
335
|
+
destTokenAddress: remotes[networkInfo(destChainSelector).name].remoteToken,
|
|
336
|
+
}
|
|
337
|
+
}),
|
|
338
|
+
)
|
|
339
|
+
}
|