@chainlink/ccip-sdk 0.94.0 → 0.96.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/README.md +2 -2
- package/dist/all-chains.d.ts +23 -0
- package/dist/all-chains.d.ts.map +1 -0
- package/dist/all-chains.js +24 -0
- package/dist/all-chains.js.map +1 -0
- package/dist/api/index.d.ts +86 -7
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +270 -10
- package/dist/api/index.js.map +1 -1
- package/dist/api/types.d.ts +134 -13
- package/dist/api/types.d.ts.map +1 -1
- package/dist/aptos/index.d.ts +38 -17
- package/dist/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +91 -61
- package/dist/aptos/index.js.map +1 -1
- package/dist/aptos/logs.js +3 -3
- package/dist/aptos/logs.js.map +1 -1
- package/dist/chain.d.ts +300 -42
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +160 -9
- package/dist/chain.js.map +1 -1
- package/dist/errors/codes.d.ts +9 -3
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/errors/codes.js +10 -3
- package/dist/errors/codes.js.map +1 -1
- package/dist/errors/index.d.ts +8 -8
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +8 -8
- package/dist/errors/index.js.map +1 -1
- package/dist/errors/recovery.d.ts.map +1 -1
- package/dist/errors/recovery.js +10 -4
- package/dist/errors/recovery.js.map +1 -1
- package/dist/errors/specialized.d.ts +62 -21
- package/dist/errors/specialized.d.ts.map +1 -1
- package/dist/errors/specialized.js +128 -41
- package/dist/errors/specialized.js.map +1 -1
- package/dist/evm/extra-args.d.ts +25 -0
- package/dist/evm/extra-args.d.ts.map +1 -0
- package/dist/evm/extra-args.js +328 -0
- package/dist/evm/extra-args.js.map +1 -0
- package/dist/evm/gas.d.ts +14 -0
- package/dist/evm/gas.d.ts.map +1 -0
- package/dist/evm/gas.js +92 -0
- package/dist/evm/gas.js.map +1 -0
- package/dist/evm/index.d.ts +76 -32
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +94 -104
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/offchain.d.ts.map +1 -1
- package/dist/evm/offchain.js +8 -8
- package/dist/evm/offchain.js.map +1 -1
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +24 -3
- package/dist/execution.js.map +1 -1
- package/dist/extra-args.d.ts +103 -4
- package/dist/extra-args.d.ts.map +1 -1
- package/dist/extra-args.js +28 -3
- package/dist/extra-args.js.map +1 -1
- package/dist/gas.d.ts +46 -19
- package/dist/gas.d.ts.map +1 -1
- package/dist/gas.js +56 -68
- package/dist/gas.js.map +1 -1
- package/dist/index.d.ts +18 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -13
- package/dist/index.js.map +1 -1
- package/dist/offchain.d.ts +5 -4
- package/dist/offchain.d.ts.map +1 -1
- package/dist/offchain.js +7 -6
- package/dist/offchain.js.map +1 -1
- package/dist/requests.d.ts +30 -20
- package/dist/requests.d.ts.map +1 -1
- package/dist/requests.js +86 -56
- package/dist/requests.js.map +1 -1
- package/dist/selectors.d.ts +2 -1
- package/dist/selectors.d.ts.map +1 -1
- package/dist/selectors.js +625 -278
- package/dist/selectors.js.map +1 -1
- package/dist/solana/exec.d.ts.map +1 -1
- package/dist/solana/exec.js +2 -1
- package/dist/solana/exec.js.map +1 -1
- package/dist/solana/index.d.ts +73 -22
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +91 -28
- package/dist/solana/index.js.map +1 -1
- package/dist/solana/offchain.js +2 -2
- package/dist/solana/offchain.js.map +1 -1
- package/dist/solana/send.d.ts.map +1 -1
- package/dist/solana/send.js +6 -9
- package/dist/solana/send.js.map +1 -1
- package/dist/solana/utils.d.ts +29 -1
- package/dist/solana/utils.d.ts.map +1 -1
- package/dist/solana/utils.js +39 -1
- package/dist/solana/utils.js.map +1 -1
- package/dist/sui/discovery.d.ts +7 -4
- package/dist/sui/discovery.d.ts.map +1 -1
- package/dist/sui/discovery.js +66 -19
- package/dist/sui/discovery.js.map +1 -1
- package/dist/sui/events.d.ts +23 -12
- package/dist/sui/events.d.ts.map +1 -1
- package/dist/sui/events.js +267 -128
- package/dist/sui/events.js.map +1 -1
- package/dist/sui/index.d.ts +57 -41
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +286 -159
- package/dist/sui/index.js.map +1 -1
- package/dist/sui/objects.d.ts +14 -4
- package/dist/sui/objects.d.ts.map +1 -1
- package/dist/sui/objects.js +61 -68
- package/dist/sui/objects.js.map +1 -1
- package/dist/sui/types.d.ts +33 -0
- package/dist/sui/types.d.ts.map +1 -1
- package/dist/sui/types.js.map +1 -1
- package/dist/ton/index.d.ts +67 -21
- package/dist/ton/index.d.ts.map +1 -1
- package/dist/ton/index.js +159 -30
- package/dist/ton/index.js.map +1 -1
- package/dist/ton/send.d.ts +52 -0
- package/dist/ton/send.d.ts.map +1 -0
- package/dist/ton/send.js +166 -0
- package/dist/ton/send.js.map +1 -0
- package/dist/ton/utils.d.ts +3 -3
- package/dist/ton/utils.d.ts.map +1 -1
- package/dist/ton/utils.js +6 -5
- package/dist/ton/utils.js.map +1 -1
- package/dist/types.d.ts +126 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +19 -5
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +67 -4
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +126 -17
- package/dist/utils.js.map +1 -1
- package/package.json +14 -9
- package/src/all-chains.ts +26 -0
- package/src/api/index.ts +348 -13
- package/src/api/types.ts +160 -13
- package/src/aptos/index.ts +98 -76
- package/src/aptos/logs.ts +3 -3
- package/src/chain.ts +408 -51
- package/src/errors/codes.ts +10 -3
- package/src/errors/index.ts +8 -5
- package/src/errors/recovery.ts +18 -5
- package/src/errors/specialized.ts +168 -49
- package/src/evm/extra-args.ts +377 -0
- package/src/evm/gas.ts +150 -0
- package/src/evm/index.ts +123 -155
- package/src/evm/offchain.ts +15 -9
- package/src/execution.ts +26 -3
- package/src/extra-args.ts +108 -4
- package/src/gas.ts +101 -115
- package/src/index.ts +27 -14
- package/src/offchain.ts +12 -6
- package/src/requests.ts +117 -67
- package/src/selectors.ts +632 -280
- package/src/solana/exec.ts +3 -1
- package/src/solana/index.ts +97 -37
- package/src/solana/offchain.ts +2 -2
- package/src/solana/send.ts +5 -23
- package/src/solana/utils.ts +66 -0
- package/src/sui/discovery.ts +92 -31
- package/src/sui/events.ts +346 -239
- package/src/sui/index.ts +365 -212
- package/src/sui/objects.ts +74 -98
- package/src/sui/types.ts +35 -0
- package/src/ton/index.ts +199 -35
- package/src/ton/send.ts +222 -0
- package/src/ton/utils.ts +7 -6
- package/src/types.ts +128 -9
- package/src/utils.ts +169 -21
package/src/extra-args.ts
CHANGED
|
@@ -8,6 +8,8 @@ import { ChainFamily } from './types.ts'
|
|
|
8
8
|
export const EVMExtraArgsV1Tag = id('CCIP EVMExtraArgsV1').substring(0, 10) as '0x97a657c9'
|
|
9
9
|
/** Tag identifier for EVMExtraArgsV2 encoding. */
|
|
10
10
|
export const EVMExtraArgsV2Tag = id('CCIP EVMExtraArgsV2').substring(0, 10) as '0x181dcf10'
|
|
11
|
+
/** Tag identifier for GenericExtraArgsV3 encoding (tightly packed binary format). */
|
|
12
|
+
export const GenericExtraArgsV3Tag = '0x302326cb' as const
|
|
11
13
|
/** Tag identifier for SVMExtraArgsV1 encoding. */
|
|
12
14
|
export const SVMExtraArgsV1Tag = id('CCIP SVMExtraArgsV1').substring(0, 10) as '0x1f3b3aba'
|
|
13
15
|
/** Tag identifier for SuiExtraArgsV1 encoding. */
|
|
@@ -15,6 +17,13 @@ export const SuiExtraArgsV1Tag = id('CCIP SuiExtraArgsV1').substring(0, 10) as '
|
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* EVM extra arguments version 1 with gas limit only.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const args: EVMExtraArgsV1 = {
|
|
24
|
+
* gasLimit: 200_000n,
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
18
27
|
*/
|
|
19
28
|
export type EVMExtraArgsV1 = {
|
|
20
29
|
/** Gas limit for execution on the destination chain. */
|
|
@@ -24,14 +33,70 @@ export type EVMExtraArgsV1 = {
|
|
|
24
33
|
/**
|
|
25
34
|
* EVM extra arguments version 2 with out-of-order execution support.
|
|
26
35
|
* Also known as GenericExtraArgsV2.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const args: EVMExtraArgsV2 = {
|
|
40
|
+
* gasLimit: 200_000n,
|
|
41
|
+
* allowOutOfOrderExecution: true,
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
27
44
|
*/
|
|
28
45
|
export type EVMExtraArgsV2 = EVMExtraArgsV1 & {
|
|
29
46
|
/** Whether to allow out-of-order message execution. */
|
|
30
47
|
allowOutOfOrderExecution: boolean
|
|
31
48
|
}
|
|
32
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Generic extra arguments version 3 with cross-chain verifiers and executor support.
|
|
52
|
+
* Uses tightly packed binary encoding (NOT ABI-encoded).
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const args: GenericExtraArgsV3 = {
|
|
57
|
+
* gasLimit: 200_000n,
|
|
58
|
+
* blockConfirmations: 5,
|
|
59
|
+
* ccvs: ['0x1234...'],
|
|
60
|
+
* ccvArgs: ['0x010203'],
|
|
61
|
+
* executor: '0x5678...',
|
|
62
|
+
* executorArgs: '0x',
|
|
63
|
+
* tokenReceiver: '0xReceiverAddress...',
|
|
64
|
+
* tokenArgs: '0x',
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export type GenericExtraArgsV3 = {
|
|
69
|
+
/** Gas limit for execution on the destination chain (uint32). */
|
|
70
|
+
gasLimit: bigint
|
|
71
|
+
/** Number of block confirmations required. */
|
|
72
|
+
blockConfirmations: number
|
|
73
|
+
/** Cross-chain verifier addresses (EVM addresses). */
|
|
74
|
+
ccvs: string[]
|
|
75
|
+
/** Per-CCV arguments (BytesLike). */
|
|
76
|
+
ccvArgs: BytesLike[]
|
|
77
|
+
/** Executor address (EVM address or empty string for none). */
|
|
78
|
+
executor: string
|
|
79
|
+
/** Executor-specific arguments (BytesLike). */
|
|
80
|
+
executorArgs: BytesLike
|
|
81
|
+
/** Token receiver address (checksummed EVM address or hex string). */
|
|
82
|
+
tokenReceiver: string
|
|
83
|
+
/** Token pool-specific arguments (BytesLike). */
|
|
84
|
+
tokenArgs: BytesLike
|
|
85
|
+
}
|
|
86
|
+
|
|
33
87
|
/**
|
|
34
88
|
* Solana (SVM) extra arguments version 1.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const args: SVMExtraArgsV1 = {
|
|
93
|
+
* computeUnits: 200_000n,
|
|
94
|
+
* accountIsWritableBitmap: 0n,
|
|
95
|
+
* allowOutOfOrderExecution: true,
|
|
96
|
+
* tokenReceiver: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
97
|
+
* accounts: [],
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
35
100
|
*/
|
|
36
101
|
export type SVMExtraArgsV1 = {
|
|
37
102
|
/** Compute units for Solana execution. */
|
|
@@ -48,6 +113,16 @@ export type SVMExtraArgsV1 = {
|
|
|
48
113
|
|
|
49
114
|
/**
|
|
50
115
|
* Sui extra arguments version 1.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const args: SuiExtraArgsV1 = {
|
|
120
|
+
* gasLimit: 200_000n,
|
|
121
|
+
* allowOutOfOrderExecution: true,
|
|
122
|
+
* tokenReceiver: '0x1234...abcd',
|
|
123
|
+
* receiverObjectIds: ['0xobject1...', '0xobject2...'],
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
51
126
|
*/
|
|
52
127
|
export type SuiExtraArgsV1 = EVMExtraArgsV2 & {
|
|
53
128
|
/** Token receiver address on Sui. */
|
|
@@ -59,13 +134,31 @@ export type SuiExtraArgsV1 = EVMExtraArgsV2 & {
|
|
|
59
134
|
/**
|
|
60
135
|
* Union type of all supported extra arguments formats.
|
|
61
136
|
*/
|
|
62
|
-
export type ExtraArgs =
|
|
137
|
+
export type ExtraArgs =
|
|
138
|
+
| EVMExtraArgsV1
|
|
139
|
+
| EVMExtraArgsV2
|
|
140
|
+
| GenericExtraArgsV3
|
|
141
|
+
| SVMExtraArgsV1
|
|
142
|
+
| SuiExtraArgsV1
|
|
63
143
|
|
|
64
144
|
/**
|
|
65
145
|
* Encodes extra arguments for CCIP messages.
|
|
66
|
-
* The args are *to* a dest network, but are encoded as a message *from* this source chain
|
|
67
|
-
*
|
|
68
|
-
|
|
146
|
+
* The args are *to* a dest network, but are encoded as a message *from* this source chain.
|
|
147
|
+
* E.g. Solana uses Borsh to encode extraArgs in its produced requests, even those targeting EVM.
|
|
148
|
+
* @param args - Extra arguments to encode
|
|
149
|
+
* @param from - Source chain family for encoding format (defaults to EVM)
|
|
150
|
+
* @returns Encoded extra arguments as hex string
|
|
151
|
+
* @throws {@link CCIPChainFamilyUnsupportedError} if chain family not supported
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const encoded = encodeExtraArgs({
|
|
156
|
+
* gasLimit: 200_000n,
|
|
157
|
+
* allowOutOfOrderExecution: true,
|
|
158
|
+
* })
|
|
159
|
+
* // Returns: '0x181dcf10...'
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
69
162
|
export function encodeExtraArgs(args: ExtraArgs, from: ChainFamily = ChainFamily.EVM): string {
|
|
70
163
|
const chain = supportedChains[from]
|
|
71
164
|
if (!chain) throw new CCIPChainFamilyUnsupportedError(from)
|
|
@@ -77,6 +170,16 @@ export function encodeExtraArgs(args: ExtraArgs, from: ChainFamily = ChainFamily
|
|
|
77
170
|
* @param data - Extra arguments bytearray data.
|
|
78
171
|
* @param from - Optional chain family to narrow decoding attempts.
|
|
79
172
|
* @returns Extra arguments object if found, undefined otherwise.
|
|
173
|
+
* @throws {@link CCIPChainFamilyUnsupportedError} if specified chain family not supported
|
|
174
|
+
* @throws {@link CCIPExtraArgsParseError} if data cannot be parsed as valid extra args
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```typescript
|
|
178
|
+
* const decoded = decodeExtraArgs('0x181dcf10...')
|
|
179
|
+
* if (decoded?._tag === 'EVMExtraArgsV2') {
|
|
180
|
+
* console.log(decoded.gasLimit, decoded.allowOutOfOrderExecution)
|
|
181
|
+
* }
|
|
182
|
+
* ```
|
|
80
183
|
*/
|
|
81
184
|
export function decodeExtraArgs(
|
|
82
185
|
data: BytesLike,
|
|
@@ -84,6 +187,7 @@ export function decodeExtraArgs(
|
|
|
84
187
|
):
|
|
85
188
|
| (EVMExtraArgsV1 & { _tag: 'EVMExtraArgsV1' })
|
|
86
189
|
| (EVMExtraArgsV2 & { _tag: 'EVMExtraArgsV2' })
|
|
190
|
+
| (GenericExtraArgsV3 & { _tag: 'GenericExtraArgsV3' })
|
|
87
191
|
| (SVMExtraArgsV1 & { _tag: 'SVMExtraArgsV1' })
|
|
88
192
|
| (SuiExtraArgsV1 & { _tag: 'SuiExtraArgsV1' })
|
|
89
193
|
| undefined {
|
package/src/gas.ts
CHANGED
|
@@ -1,140 +1,126 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type BytesLike,
|
|
3
|
-
Contract,
|
|
4
|
-
FunctionFragment,
|
|
5
|
-
concat,
|
|
6
|
-
formatUnits,
|
|
7
|
-
getNumber,
|
|
8
|
-
hexlify,
|
|
9
|
-
randomBytes,
|
|
10
|
-
solidityPackedKeccak256,
|
|
11
|
-
toBeHex,
|
|
12
|
-
zeroPadValue,
|
|
13
|
-
} from 'ethers'
|
|
14
|
-
import type { TypedContract } from 'ethers-abitype'
|
|
1
|
+
import { type BytesLike, formatUnits, hexlify, randomBytes } from 'ethers'
|
|
15
2
|
|
|
16
3
|
import type { Chain } from './chain.ts'
|
|
17
4
|
import {
|
|
18
|
-
|
|
5
|
+
CCIPContractTypeInvalidError,
|
|
6
|
+
CCIPMethodUnsupportedError,
|
|
19
7
|
CCIPTokenDecimalsInsufficientError,
|
|
20
8
|
} from './errors/index.ts'
|
|
21
|
-
import TokenABI from './evm/abi/BurnMintERC677Token.ts'
|
|
22
|
-
import RouterABI from './evm/abi/Router.ts'
|
|
23
|
-
import { defaultAbiCoder } from './evm/const.ts'
|
|
24
|
-
import type { EVMChain } from './evm/index.ts'
|
|
25
9
|
import { discoverOffRamp } from './execution.ts'
|
|
26
|
-
import
|
|
10
|
+
import { sourceToDestTokenAddresses } from './requests.ts'
|
|
27
11
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
12
|
+
/**
|
|
13
|
+
* A subset of {@link MessageInput} for estimating receive execution gas.
|
|
14
|
+
*/
|
|
15
|
+
export type EstimateMessageInput = {
|
|
16
|
+
/** receiver contract address */
|
|
17
|
+
receiver: string
|
|
18
|
+
/** optional messageId; random hash will be passed if omitted */
|
|
19
|
+
messageId?: string
|
|
20
|
+
/** optional sender: zero address will be used if omitted */
|
|
21
|
+
sender?: string
|
|
22
|
+
/** optional data: zero bytes will be used if omitted */
|
|
23
|
+
data?: BytesLike
|
|
24
|
+
/**
|
|
25
|
+
* optional tokenAmounts; `amount` with either source `token` (as in MessageInput) or
|
|
26
|
+
* `{ sourceTokenAddress?, sourcePoolAddress, destTokenAddress }` (as in v1.5..v1.7 tokenAmounts)
|
|
27
|
+
* can be provided
|
|
28
|
+
*/
|
|
29
|
+
tokenAmounts?: readonly ({
|
|
30
|
+
amount: bigint
|
|
31
|
+
} & (
|
|
32
|
+
| { token: string }
|
|
33
|
+
| { sourceTokenAddress?: string; sourcePoolAddress: string; destTokenAddress: string }
|
|
34
|
+
))[]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Options for {@link estimateReceiveExecution} function.
|
|
39
|
+
*/
|
|
40
|
+
export type EstimateReceiveExecutionOpts = {
|
|
41
|
+
/** Source chain instance (for token data retrieval) */
|
|
42
|
+
source: Chain
|
|
43
|
+
/** Dest chain instance (for token and execution simulation) */
|
|
44
|
+
dest: Chain
|
|
45
|
+
/** source router or onRamp, or dest offRamp contract address */
|
|
46
|
+
routerOrRamp: string
|
|
47
|
+
/** message to be simulated */
|
|
48
|
+
message: EstimateMessageInput
|
|
49
|
+
}
|
|
40
50
|
|
|
41
51
|
/**
|
|
42
52
|
* Estimate CCIP gasLimit needed to execute a request on a contract receiver.
|
|
43
|
-
* @param
|
|
44
|
-
* @
|
|
45
|
-
* @
|
|
46
|
-
* @
|
|
53
|
+
* @param opts - Options for estimation: source and dest chains, router or ramp address, and message
|
|
54
|
+
* @returns Estimated gasLimit.
|
|
55
|
+
* @throws {@link CCIPMethodUnsupportedError} if dest chain doesn't support estimation
|
|
56
|
+
* @throws {@link CCIPContractTypeInvalidError} if routerOrRamp is not a valid contract type
|
|
57
|
+
* @throws {@link CCIPTokenDecimalsInsufficientError} if dest token has insufficient decimals
|
|
47
58
|
*/
|
|
48
|
-
export async function
|
|
49
|
-
source
|
|
50
|
-
dest
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
export async function estimateReceiveExecution({
|
|
60
|
+
source,
|
|
61
|
+
dest,
|
|
62
|
+
routerOrRamp,
|
|
63
|
+
message,
|
|
64
|
+
}: EstimateReceiveExecutionOpts) {
|
|
65
|
+
if (!dest.estimateReceiveExecution)
|
|
66
|
+
throw new CCIPMethodUnsupportedError(dest.constructor.name, 'estimateReceiveExecution')
|
|
67
|
+
|
|
68
|
+
let onRamp, offRamp: string
|
|
69
|
+
try {
|
|
70
|
+
const tnv = await source.typeAndVersion(routerOrRamp)
|
|
71
|
+
if (!tnv[0].includes('OnRamp'))
|
|
72
|
+
onRamp = await source.getOnRampForRouter(routerOrRamp, dest.network.chainSelector)
|
|
73
|
+
else onRamp = routerOrRamp
|
|
74
|
+
offRamp = await discoverOffRamp(source, dest, onRamp, source)
|
|
75
|
+
} catch (sourceErr) {
|
|
76
|
+
try {
|
|
77
|
+
const tnv = await dest.typeAndVersion(routerOrRamp)
|
|
78
|
+
if (!tnv[0].includes('OffRamp'))
|
|
79
|
+
throw new CCIPContractTypeInvalidError(routerOrRamp, tnv[2], ['OffRamp'])
|
|
80
|
+
offRamp = routerOrRamp
|
|
81
|
+
onRamp = await dest.getOnRampForOffRamp(offRamp, source.network.chainSelector)
|
|
82
|
+
} catch {
|
|
83
|
+
throw sourceErr // re-throw original error
|
|
62
84
|
}
|
|
63
|
-
}
|
|
64
|
-
) {
|
|
65
|
-
const offRamp = await discoverOffRamp(source, dest, request.lane.onRamp, source)
|
|
66
|
-
const destRouter = await dest.getRouterForOffRamp(offRamp, request.lane.sourceChainSelector)
|
|
85
|
+
}
|
|
67
86
|
|
|
68
87
|
const destTokenAmounts = await Promise.all(
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
(message.tokenAmounts ?? []).map(async (ta) => {
|
|
89
|
+
const tokenAmount =
|
|
90
|
+
'destTokenAddress' in ta
|
|
91
|
+
? ta
|
|
92
|
+
: await sourceToDestTokenAddresses(source, dest.network.chainSelector, onRamp, ta)
|
|
93
|
+
const sourceTokenAddress =
|
|
94
|
+
'token' in ta
|
|
95
|
+
? ta.token
|
|
96
|
+
: ta.sourceTokenAddress
|
|
97
|
+
? ta.sourceTokenAddress
|
|
98
|
+
: await source.getTokenForTokenPool(tokenAmount.sourcePoolAddress)
|
|
71
99
|
const [{ decimals: sourceDecimals }, { decimals: destDecimals }] = await Promise.all([
|
|
72
|
-
source
|
|
73
|
-
|
|
74
|
-
.then((token) => source.getTokenInfo(token)),
|
|
75
|
-
dest.getTokenInfo(ta.destTokenAddress),
|
|
100
|
+
source.getTokenInfo(sourceTokenAddress),
|
|
101
|
+
dest.getTokenInfo(tokenAmount.destTokenAddress),
|
|
76
102
|
])
|
|
77
103
|
const destAmount =
|
|
78
|
-
(
|
|
104
|
+
(tokenAmount.amount * 10n ** BigInt(destDecimals)) / 10n ** BigInt(sourceDecimals)
|
|
79
105
|
if (destAmount === 0n)
|
|
80
106
|
throw new CCIPTokenDecimalsInsufficientError(
|
|
81
|
-
|
|
107
|
+
tokenAmount.destTokenAddress,
|
|
82
108
|
destDecimals,
|
|
83
109
|
dest.network.name,
|
|
84
|
-
formatUnits(
|
|
110
|
+
formatUnits(tokenAmount.amount, sourceDecimals),
|
|
85
111
|
)
|
|
86
|
-
return { token:
|
|
112
|
+
return { token: tokenAmount.destTokenAddress, amount: destAmount }
|
|
87
113
|
}),
|
|
88
114
|
)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const destAmounts: Record<string, bigint> = {}
|
|
101
|
-
const stateOverrides: Record<string, { stateDiff: Record<string, string> }> = {}
|
|
102
|
-
for (const { token, amount } of destTokenAmounts) {
|
|
103
|
-
if (!(token in destAmounts)) {
|
|
104
|
-
const tokenContract = new Contract(token, TokenABI, dest) as unknown as TypedContract<
|
|
105
|
-
typeof TokenABI
|
|
106
|
-
>
|
|
107
|
-
const currentBalance = await tokenContract.balanceOf(request.message.receiver)
|
|
108
|
-
destAmounts[token] = currentBalance
|
|
109
|
-
}
|
|
110
|
-
destAmounts[token]! += amount
|
|
111
|
-
stateOverrides[token] = {
|
|
112
|
-
stateDiff: {
|
|
113
|
-
[solidityPackedKeccak256(
|
|
114
|
-
['uint256', 'uint256'],
|
|
115
|
-
[request.message.receiver, BALANCES_SLOT],
|
|
116
|
-
)]: toBeHex(destAmounts[token]!, 32),
|
|
117
|
-
},
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const calldata = concat([
|
|
122
|
-
ccipReceive.selector,
|
|
123
|
-
defaultAbiCoder.encode(ccipReceive.inputs, [message]),
|
|
124
|
-
])
|
|
125
|
-
|
|
126
|
-
return (
|
|
127
|
-
getNumber(
|
|
128
|
-
(await dest.provider.send('eth_estimateGas', [
|
|
129
|
-
{
|
|
130
|
-
from: destRouter,
|
|
131
|
-
to: request.message.receiver,
|
|
132
|
-
data: calldata,
|
|
133
|
-
},
|
|
134
|
-
'latest',
|
|
135
|
-
...(Object.keys(stateOverrides).length ? [stateOverrides] : []),
|
|
136
|
-
])) as string,
|
|
137
|
-
) -
|
|
138
|
-
(21_000 - 700) // 21k is the base gas cost for a transaction, 700 is the gas cost of the call
|
|
139
|
-
)
|
|
115
|
+
return dest.estimateReceiveExecution({
|
|
116
|
+
receiver: message.receiver,
|
|
117
|
+
offRamp,
|
|
118
|
+
message: {
|
|
119
|
+
messageId: message.messageId ?? hexlify(randomBytes(32)),
|
|
120
|
+
sender: message.sender,
|
|
121
|
+
data: message.data,
|
|
122
|
+
sourceChainSelector: source.network.chainSelector,
|
|
123
|
+
destTokenAmounts,
|
|
124
|
+
},
|
|
125
|
+
})
|
|
140
126
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,16 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* \@chainlink/ccip-sdk - SDK for interacting with Chainlink CCIP (Cross-Chain Interoperability Protocol).
|
|
3
|
+
*
|
|
4
|
+
* This package provides tools for sending cross-chain messages, tracking message status,
|
|
5
|
+
* and executing manual message delivery across supported blockchain networks.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type {
|
|
11
|
+
APICCIPRequestMetadata,
|
|
12
|
+
APIErrorResponse,
|
|
13
|
+
CCIPAPIClientContext,
|
|
14
|
+
LaneLatencyResponse,
|
|
15
|
+
} from './api/index.ts'
|
|
2
16
|
export { CCIPAPIClient, DEFAULT_API_BASE_URL } from './api/index.ts'
|
|
3
17
|
|
|
4
18
|
export type {
|
|
19
|
+
ApiRetryConfig,
|
|
5
20
|
Chain,
|
|
6
21
|
ChainContext,
|
|
7
22
|
ChainGetter,
|
|
8
23
|
ChainStatic,
|
|
24
|
+
GetBalanceOpts,
|
|
9
25
|
LogFilter,
|
|
10
26
|
RateLimiterState,
|
|
27
|
+
RegistryTokenConfig,
|
|
11
28
|
TokenInfo,
|
|
29
|
+
TokenPoolConfig,
|
|
12
30
|
TokenPoolRemote,
|
|
13
31
|
} from './chain.ts'
|
|
32
|
+
export { DEFAULT_API_RETRY_CONFIG } from './chain.ts'
|
|
14
33
|
export { calculateManualExecProof, discoverOffRamp } from './execution.ts'
|
|
15
34
|
export {
|
|
16
35
|
type EVMExtraArgsV1,
|
|
@@ -21,8 +40,8 @@ export {
|
|
|
21
40
|
decodeExtraArgs,
|
|
22
41
|
encodeExtraArgs,
|
|
23
42
|
} from './extra-args.ts'
|
|
24
|
-
export {
|
|
25
|
-
export { decodeMessage, getMessagesForSender,
|
|
43
|
+
export { estimateReceiveExecution } from './gas.ts'
|
|
44
|
+
export { decodeMessage, getMessagesForSender, sourceToDestTokenAddresses } from './requests.ts'
|
|
26
45
|
export {
|
|
27
46
|
type CCIPCommit,
|
|
28
47
|
type CCIPExecution,
|
|
@@ -34,15 +53,16 @@ export {
|
|
|
34
53
|
type ExecutionReport,
|
|
35
54
|
type Lane,
|
|
36
55
|
type Logger,
|
|
56
|
+
type MessageInput,
|
|
37
57
|
type NetworkInfo,
|
|
38
58
|
type OffchainTokenData,
|
|
39
|
-
type MessageInput,
|
|
40
59
|
type WithLogger,
|
|
41
60
|
CCIPVersion,
|
|
42
61
|
ExecutionState,
|
|
43
62
|
IntentStatus,
|
|
44
63
|
MessageStatus,
|
|
45
64
|
} from './types.ts'
|
|
65
|
+
export type { WithRetryConfig } from './utils.ts'
|
|
46
66
|
export {
|
|
47
67
|
bigIntReplacer,
|
|
48
68
|
bigIntReviver,
|
|
@@ -51,6 +71,7 @@ export {
|
|
|
51
71
|
getDataBytes,
|
|
52
72
|
isSupportedTxHash,
|
|
53
73
|
networkInfo,
|
|
74
|
+
withRetry,
|
|
54
75
|
} from './utils.ts'
|
|
55
76
|
export {
|
|
56
77
|
type CCIPExplorerLinks,
|
|
@@ -73,15 +94,7 @@ export type { UnsignedSolanaTx } from './solana/index.ts'
|
|
|
73
94
|
import { SuiChain } from './sui/index.ts'
|
|
74
95
|
import { TONChain } from './ton/index.ts'
|
|
75
96
|
export type { UnsignedTONTx } from './ton/index.ts'
|
|
76
|
-
import { ChainFamily } from './types.ts'
|
|
77
|
-
export { AptosChain, ChainFamily, EVMChain, SolanaChain, SuiChain, TONChain }
|
|
97
|
+
import { ChainFamily, NetworkType } from './types.ts'
|
|
98
|
+
export { AptosChain, ChainFamily, EVMChain, NetworkType, SolanaChain, SuiChain, TONChain }
|
|
78
99
|
// use `supportedChains` to override/register derived classes, if needed
|
|
79
100
|
export { supportedChains } from './supported-chains.ts'
|
|
80
|
-
// import `allSupportedChains` to get them all registered, in tree-shaken environments
|
|
81
|
-
export const allSupportedChains = {
|
|
82
|
-
[ChainFamily.EVM]: EVMChain,
|
|
83
|
-
[ChainFamily.Solana]: SolanaChain,
|
|
84
|
-
[ChainFamily.Aptos]: AptosChain,
|
|
85
|
-
[ChainFamily.Sui]: SuiChain,
|
|
86
|
-
[ChainFamily.TON]: TONChain,
|
|
87
|
-
}
|
package/src/offchain.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
CCIPLbtcAttestationNotFoundError,
|
|
6
6
|
CCIPUsdcAttestationError,
|
|
7
7
|
} from './errors/index.ts'
|
|
8
|
+
import { NetworkType } from './types.ts'
|
|
8
9
|
|
|
9
10
|
const CIRCLE_API_URL = {
|
|
10
11
|
mainnet: 'https://iris-api.circle.com/v1',
|
|
@@ -31,13 +32,17 @@ type LombardAttestationsResponse = { attestations: Array<LombardAttestation> }
|
|
|
31
32
|
* https://developers.circle.com/stablecoins/reference/getattestation
|
|
32
33
|
*
|
|
33
34
|
* @param message - payload of USDC MessageSent(bytes message) event
|
|
34
|
-
* @param
|
|
35
|
+
* @param networkType - network type (mainnet or testnet)
|
|
35
36
|
* @returns USDC/CCTP attestation bytes
|
|
36
37
|
*/
|
|
37
|
-
export async function getUsdcAttestation(
|
|
38
|
+
export async function getUsdcAttestation(
|
|
39
|
+
message: string,
|
|
40
|
+
networkType: NetworkType,
|
|
41
|
+
): Promise<string> {
|
|
38
42
|
const msgHash = keccak256(message)
|
|
39
43
|
|
|
40
|
-
const circleApiBaseUrl =
|
|
44
|
+
const circleApiBaseUrl =
|
|
45
|
+
networkType === NetworkType.Mainnet ? CIRCLE_API_URL.mainnet : CIRCLE_API_URL.testnet
|
|
41
46
|
const res = await fetch(`${circleApiBaseUrl}/attestations/${msgHash}`)
|
|
42
47
|
const json = (await res.json()) as CctpAttestationResponse
|
|
43
48
|
if (!('status' in json) || json.status !== 'complete' || !json.attestation) {
|
|
@@ -50,16 +55,17 @@ export async function getUsdcAttestation(message: string, isTestnet: boolean): P
|
|
|
50
55
|
* Returns the LBTC attestation for a given payload hash
|
|
51
56
|
*
|
|
52
57
|
* @param payloadHash - hash of the payload of the LBTC transfer
|
|
53
|
-
* @param
|
|
58
|
+
* @param networkType - network type (mainnet or testnet)
|
|
54
59
|
* @returns LBTC attestation bytes
|
|
55
60
|
*/
|
|
56
61
|
export async function getLbtcAttestation(
|
|
57
62
|
payloadHash: string,
|
|
58
|
-
|
|
63
|
+
networkType: NetworkType,
|
|
59
64
|
): Promise<{
|
|
60
65
|
attestation: string
|
|
61
66
|
}> {
|
|
62
|
-
const lbtcApiBaseUrl =
|
|
67
|
+
const lbtcApiBaseUrl =
|
|
68
|
+
networkType === NetworkType.Mainnet ? LOMBARD_API_URL.mainnet : LOMBARD_API_URL.testnet
|
|
63
69
|
const res = await fetch(`${lbtcApiBaseUrl}/api/bridge/v1/deposits/getByHash`, {
|
|
64
70
|
method: 'POST',
|
|
65
71
|
body: JSON.stringify({ messageHash: [payloadHash] }),
|