@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/ton/send.ts
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { type Cell, beginCell, toNano } from '@ton/core'
|
|
2
|
+
import { type TonClient, Address } from '@ton/ton'
|
|
3
|
+
import { zeroPadValue } from 'ethers'
|
|
4
|
+
|
|
5
|
+
import type { UnsignedTONTx } from './types.ts'
|
|
6
|
+
import { CCIPError, CCIPErrorCode } from '../errors/index.ts'
|
|
7
|
+
import { EVMExtraArgsV2Tag } from '../extra-args.ts'
|
|
8
|
+
import type { AnyMessage, WithLogger } from '../types.ts'
|
|
9
|
+
import { bytesToBuffer, getDataBytes } from '../utils.ts'
|
|
10
|
+
|
|
11
|
+
/** Opcode for Router ccipSend operation */
|
|
12
|
+
export const CCIP_SEND_OPCODE = 0x31768d95
|
|
13
|
+
|
|
14
|
+
/** Default gas buffer to add to fee for transaction execution */
|
|
15
|
+
export const DEFAULT_GAS_BUFFER = toNano('0.5')
|
|
16
|
+
|
|
17
|
+
/** Default gas limit for destination chain execution */
|
|
18
|
+
export const DEFAULT_GAS_LIMIT = 200_000n
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* WRAPPED_NATIVE address for TON - sentinel address representing native TON.
|
|
22
|
+
* Used as feeToken for native TON payments in FeeQuoter calls.
|
|
23
|
+
*/
|
|
24
|
+
export const WRAPPED_NATIVE = Address.parse(
|
|
25
|
+
'0:0000000000000000000000000000000000000000000000000000000000000001',
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Encodes token amounts as a snaked cell.
|
|
30
|
+
* Empty cell for no tokens.
|
|
31
|
+
*/
|
|
32
|
+
function encodeTokenAmounts(
|
|
33
|
+
tokenAmounts: readonly { token: string; amount: bigint }[] | undefined,
|
|
34
|
+
): Cell {
|
|
35
|
+
if (!tokenAmounts || tokenAmounts.length === 0) {
|
|
36
|
+
return beginCell().endCell()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const builder = beginCell()
|
|
40
|
+
for (const ta of tokenAmounts) {
|
|
41
|
+
builder.storeRef(
|
|
42
|
+
beginCell().storeAddress(Address.parse(ta.token)).storeUint(ta.amount, 256).endCell(),
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
return builder.endCell()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Encodes extraArgs as a Cell using the GenericExtraArgsV2 (EVMExtraArgsV2) format.
|
|
50
|
+
*
|
|
51
|
+
* Format per chainlink-ton TL-B:
|
|
52
|
+
* - tag: 32-bit opcode (0x181dcf10)
|
|
53
|
+
* - gasLimit: Maybe<uint256> (1 bit flag + 256 bits if present)
|
|
54
|
+
* - allowOutOfOrderExecution: 1 bit (must be true)
|
|
55
|
+
*/
|
|
56
|
+
function encodeExtraArgsCell(extraArgs: AnyMessage['extraArgs']): Cell {
|
|
57
|
+
const allowOutOfOrderExecution = true
|
|
58
|
+
|
|
59
|
+
let gasLimit = 0n
|
|
60
|
+
let hasGasLimit = false
|
|
61
|
+
|
|
62
|
+
if ('gasLimit' in extraArgs && extraArgs.gasLimit > 0n) {
|
|
63
|
+
hasGasLimit = true
|
|
64
|
+
gasLimit = extraArgs.gasLimit
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const builder = beginCell()
|
|
68
|
+
.storeUint(Number(EVMExtraArgsV2Tag), 32) // 0x181dcf10
|
|
69
|
+
.storeBit(hasGasLimit)
|
|
70
|
+
|
|
71
|
+
if (hasGasLimit) {
|
|
72
|
+
builder.storeUint(gasLimit, 256)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return builder.storeBit(allowOutOfOrderExecution).endCell()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Builds the Router ccipSend message cell.
|
|
80
|
+
*
|
|
81
|
+
* Relies on TL-B structure (Router_CCIPSend) from chainlink-ton repo.
|
|
82
|
+
*/
|
|
83
|
+
export function buildCcipSendCell(
|
|
84
|
+
destChainSelector: bigint,
|
|
85
|
+
message: AnyMessage,
|
|
86
|
+
feeTokenAddress: Address | null = null,
|
|
87
|
+
queryId = 0n,
|
|
88
|
+
): Cell {
|
|
89
|
+
// Get receiver bytes and pad to 32 bytes for cross-chain encoding
|
|
90
|
+
const paddedReceiver = bytesToBuffer(zeroPadValue(getDataBytes(message.receiver), 32))
|
|
91
|
+
|
|
92
|
+
// Data cell (ref 0)
|
|
93
|
+
const dataCell = beginCell()
|
|
94
|
+
.storeBuffer(bytesToBuffer(message.data || '0x'))
|
|
95
|
+
.endCell()
|
|
96
|
+
|
|
97
|
+
// Token amounts snaked cell (ref 1)
|
|
98
|
+
const tokenAmountsCell = encodeTokenAmounts(message.tokenAmounts)
|
|
99
|
+
|
|
100
|
+
// ExtraArgs cell (ref 2)
|
|
101
|
+
const extraArgsCell = encodeExtraArgsCell(message.extraArgs)
|
|
102
|
+
|
|
103
|
+
return beginCell()
|
|
104
|
+
.storeUint(CCIP_SEND_OPCODE, 32) // opcode
|
|
105
|
+
.storeUint(Number(queryId), 64) // queryID
|
|
106
|
+
.storeUint(destChainSelector, 64) // destChainSelector
|
|
107
|
+
.storeUint(paddedReceiver.length, 8) // receiver length in bytes
|
|
108
|
+
.storeBuffer(paddedReceiver) // receiver bytes (32 bytes, left-padded)
|
|
109
|
+
.storeRef(dataCell) // ref 0: data
|
|
110
|
+
.storeRef(tokenAmountsCell) // ref 1: tokenAmounts
|
|
111
|
+
.storeAddress(feeTokenAddress) // null = addr_none for native TON
|
|
112
|
+
.storeRef(extraArgsCell) // ref 2: extraArgs
|
|
113
|
+
.endCell()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Gets the fee for sending a CCIP message by calling FeeQuoter.validatedFee.
|
|
118
|
+
*
|
|
119
|
+
* @param ctx - Context with TonClient provider and logger
|
|
120
|
+
* @param router - Router contract address
|
|
121
|
+
* @param destChainSelector - Destination chain selector
|
|
122
|
+
* @param message - CCIP message to quote
|
|
123
|
+
* @returns Fee amount in nanotons
|
|
124
|
+
*/
|
|
125
|
+
export async function getFee(
|
|
126
|
+
ctx: { provider: TonClient } & WithLogger,
|
|
127
|
+
router: string,
|
|
128
|
+
destChainSelector: bigint,
|
|
129
|
+
message: AnyMessage,
|
|
130
|
+
): Promise<bigint> {
|
|
131
|
+
const { provider, logger = console } = ctx
|
|
132
|
+
const routerAddress = Address.parse(router)
|
|
133
|
+
|
|
134
|
+
// FeeQuoter requires WRAPPED_NATIVE for native TON
|
|
135
|
+
const feeTokenAddress = message.feeToken ? Address.parse(message.feeToken) : WRAPPED_NATIVE
|
|
136
|
+
|
|
137
|
+
// Get FeeQuoter address via OnRamp
|
|
138
|
+
let feeQuoterAddress: Address
|
|
139
|
+
try {
|
|
140
|
+
const { stack: onRampStack } = await provider.runMethod(routerAddress, 'onRamp', [
|
|
141
|
+
{ type: 'int', value: destChainSelector },
|
|
142
|
+
])
|
|
143
|
+
const onRampAddress = onRampStack.readAddress()
|
|
144
|
+
logger.debug('OnRamp:', onRampAddress.toString())
|
|
145
|
+
|
|
146
|
+
const { stack: feeQuoterStack } = await provider.runMethod(onRampAddress, 'feeQuoter', [
|
|
147
|
+
{ type: 'int', value: destChainSelector },
|
|
148
|
+
])
|
|
149
|
+
feeQuoterAddress = feeQuoterStack.readAddress()
|
|
150
|
+
logger.debug('FeeQuoter:', feeQuoterAddress.toString())
|
|
151
|
+
} catch (e) {
|
|
152
|
+
throw new CCIPError(
|
|
153
|
+
CCIPErrorCode.CONTRACT_TYPE_INVALID,
|
|
154
|
+
`Could not get FeeQuoter address: ${e instanceof Error ? e.message : String(e)}`,
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Build stack parameters for validatedFee call
|
|
159
|
+
const paddedReceiver = bytesToBuffer(zeroPadValue(getDataBytes(message.receiver), 32))
|
|
160
|
+
const receiverSlice = beginCell().storeBuffer(paddedReceiver).endCell()
|
|
161
|
+
const dataCell = beginCell()
|
|
162
|
+
.storeBuffer(bytesToBuffer(message.data || '0x'))
|
|
163
|
+
.endCell()
|
|
164
|
+
const tokenAmountsCell = encodeTokenAmounts(message.tokenAmounts)
|
|
165
|
+
const extraArgsCell = encodeExtraArgsCell(message.extraArgs)
|
|
166
|
+
const feeTokenSlice = beginCell().storeAddress(feeTokenAddress).endCell()
|
|
167
|
+
|
|
168
|
+
const { stack: feeStack } = await provider.runMethod(feeQuoterAddress, 'validatedFee', [
|
|
169
|
+
{ type: 'int', value: 0n },
|
|
170
|
+
{ type: 'int', value: destChainSelector },
|
|
171
|
+
{ type: 'slice', cell: receiverSlice },
|
|
172
|
+
{ type: 'cell', cell: dataCell },
|
|
173
|
+
{ type: 'cell', cell: tokenAmountsCell },
|
|
174
|
+
{ type: 'slice', cell: feeTokenSlice },
|
|
175
|
+
{ type: 'cell', cell: extraArgsCell },
|
|
176
|
+
])
|
|
177
|
+
|
|
178
|
+
const fee = feeStack.readBigNumber()
|
|
179
|
+
if (fee < 0n) {
|
|
180
|
+
throw new CCIPError(CCIPErrorCode.MESSAGE_INVALID, `Invalid fee: ${fee}`)
|
|
181
|
+
}
|
|
182
|
+
logger.debug('CCIP fee:', fee.toString(), 'nanotons')
|
|
183
|
+
return fee
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Generates an unsigned CCIP send transaction for the Router.
|
|
188
|
+
*
|
|
189
|
+
* @param ctx - Context with TonClient provider and logger
|
|
190
|
+
* @param _sender - Sender address (unused, for interface compatibility)
|
|
191
|
+
* @param router - Router contract address
|
|
192
|
+
* @param destChainSelector - Destination chain selector
|
|
193
|
+
* @param message - CCIP message with fee included
|
|
194
|
+
* @param opts - Optional gas buffer override
|
|
195
|
+
* @returns Unsigned transaction ready for signing
|
|
196
|
+
*/
|
|
197
|
+
export function generateUnsignedCcipSend(
|
|
198
|
+
ctx: { provider: TonClient } & WithLogger,
|
|
199
|
+
_sender: string,
|
|
200
|
+
router: string,
|
|
201
|
+
destChainSelector: bigint,
|
|
202
|
+
message: AnyMessage & { fee: bigint },
|
|
203
|
+
opts?: { gasBuffer?: bigint },
|
|
204
|
+
): Omit<UnsignedTONTx, 'family'> {
|
|
205
|
+
const { logger = console } = ctx
|
|
206
|
+
const gasBuffer = opts?.gasBuffer ?? DEFAULT_GAS_BUFFER
|
|
207
|
+
|
|
208
|
+
// Router accepts addr_none for native TON (unlike FeeQuoter which needs WRAPPED_NATIVE)
|
|
209
|
+
const feeTokenAddress = message.feeToken ? Address.parse(message.feeToken) : null
|
|
210
|
+
|
|
211
|
+
const ccipSendCell = buildCcipSendCell(destChainSelector, message, feeTokenAddress)
|
|
212
|
+
const totalValue = message.fee + gasBuffer
|
|
213
|
+
|
|
214
|
+
logger.debug('Generating ccipSend tx to router:', router)
|
|
215
|
+
logger.debug('Total value:', totalValue.toString(), 'nanotons')
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
to: router,
|
|
219
|
+
body: ccipSendCell,
|
|
220
|
+
value: totalValue,
|
|
221
|
+
}
|
|
222
|
+
}
|
package/src/ton/utils.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Cell, Dictionary, beginCell } from '@ton/core'
|
|
|
2
2
|
import { hexlify, toBeHex } from 'ethers'
|
|
3
3
|
|
|
4
4
|
import { CCIPTransactionNotFoundError } from '../errors/specialized.ts'
|
|
5
|
-
import type
|
|
5
|
+
import { type WithLogger, NetworkType } from '../types.ts'
|
|
6
6
|
import { bytesToBuffer } from '../utils.ts'
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -340,14 +340,14 @@ export async function parseJettonContent(
|
|
|
340
340
|
* TonCenter V3 provides an index that allows hash-only lookups.
|
|
341
341
|
*
|
|
342
342
|
* @param hash - Raw 64-char hex transaction hash
|
|
343
|
-
* @param
|
|
343
|
+
* @param networkType - Network type (mainnet or testnet)
|
|
344
344
|
* @param fetch - Rate-limited fetch function
|
|
345
345
|
* @param logger - Logger instance
|
|
346
346
|
* @returns Transaction identifier components needed for V4 API lookup
|
|
347
347
|
*/
|
|
348
348
|
export async function lookupTxByRawHash(
|
|
349
349
|
hash: string,
|
|
350
|
-
|
|
350
|
+
networkType: NetworkType,
|
|
351
351
|
fetch = globalThis.fetch,
|
|
352
352
|
{ logger = console }: WithLogger = {},
|
|
353
353
|
): Promise<{
|
|
@@ -355,9 +355,10 @@ export async function lookupTxByRawHash(
|
|
|
355
355
|
lt: string
|
|
356
356
|
hash: string
|
|
357
357
|
}> {
|
|
358
|
-
const baseUrl =
|
|
359
|
-
|
|
360
|
-
|
|
358
|
+
const baseUrl =
|
|
359
|
+
networkType === NetworkType.Mainnet
|
|
360
|
+
? 'https://toncenter.com/api/v3/transactions'
|
|
361
|
+
: 'https://testnet.toncenter.com/api/v3/transactions'
|
|
361
362
|
|
|
362
363
|
// TonCenter V3 accepts hex directly
|
|
363
364
|
const cleanHash = bytesToBuffer(hash).toString('hex')
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AbiParametersToPrimitiveTypes, ExtractAbiEvent } from 'abitype'
|
|
2
2
|
import type { BytesLike, Log } from 'ethers'
|
|
3
3
|
|
|
4
|
+
import type { APICCIPRequestMetadata } from './api/types.ts'
|
|
4
5
|
import type OffRamp_1_6_ABI from './evm/abi/OffRamp_1_6.ts'
|
|
5
6
|
import type { CCIPMessage_EVM, CCIPMessage_V1_6_EVM } from './evm/messages.ts'
|
|
6
7
|
import type { ExtraArgs } from './extra-args.ts'
|
|
@@ -60,15 +61,26 @@ export type MergeArrayElements<T, U> = {
|
|
|
60
61
|
* Enumeration of supported blockchain families.
|
|
61
62
|
*/
|
|
62
63
|
export const ChainFamily = {
|
|
63
|
-
EVM: '
|
|
64
|
-
Solana: '
|
|
65
|
-
Aptos: '
|
|
66
|
-
Sui: '
|
|
67
|
-
TON: '
|
|
64
|
+
EVM: 'EVM',
|
|
65
|
+
Solana: 'SVM',
|
|
66
|
+
Aptos: 'APTOS',
|
|
67
|
+
Sui: 'SUI',
|
|
68
|
+
TON: 'TON',
|
|
69
|
+
Unknown: 'UNKNOWN',
|
|
68
70
|
} as const
|
|
69
71
|
/** Type representing one of the supported chain families. */
|
|
70
72
|
export type ChainFamily = (typeof ChainFamily)[keyof typeof ChainFamily]
|
|
71
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Enumeration of network types (mainnet vs testnet).
|
|
76
|
+
*/
|
|
77
|
+
export const NetworkType = {
|
|
78
|
+
Mainnet: 'MAINNET',
|
|
79
|
+
Testnet: 'TESTNET',
|
|
80
|
+
} as const
|
|
81
|
+
/** Type representing the network environment type. */
|
|
82
|
+
export type NetworkType = (typeof NetworkType)[keyof typeof NetworkType]
|
|
83
|
+
|
|
72
84
|
/**
|
|
73
85
|
* Enumeration of supported CCIP protocol versions.
|
|
74
86
|
*/
|
|
@@ -88,23 +100,44 @@ type ChainFamilyWithId<F extends ChainFamily> = F extends
|
|
|
88
100
|
: F extends typeof ChainFamily.Solana
|
|
89
101
|
? { readonly family: F; readonly chainId: string }
|
|
90
102
|
: F extends typeof ChainFamily.Aptos | typeof ChainFamily.Sui
|
|
91
|
-
? { readonly family: F; readonly chainId: `${F}:${number}` }
|
|
103
|
+
? { readonly family: F; readonly chainId: `${Lowercase<F>}:${number}` }
|
|
92
104
|
: never
|
|
93
105
|
|
|
94
106
|
/**
|
|
95
107
|
* Network information including chain selector and metadata.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const info: NetworkInfo = {
|
|
112
|
+
* chainSelector: 16015286601757825753n,
|
|
113
|
+
* name: 'ethereum-testnet-sepolia',
|
|
114
|
+
* networkType: 'TESTNET',
|
|
115
|
+
* family: 'EVM',
|
|
116
|
+
* chainId: 11155111,
|
|
117
|
+
* }
|
|
118
|
+
* ```
|
|
96
119
|
*/
|
|
97
120
|
export type NetworkInfo<F extends ChainFamily = ChainFamily> = {
|
|
98
121
|
/** Unique chain selector used by CCIP. */
|
|
99
122
|
readonly chainSelector: bigint
|
|
100
123
|
/** Human-readable network name. */
|
|
101
124
|
readonly name: string
|
|
102
|
-
/**
|
|
103
|
-
readonly
|
|
125
|
+
/** Network environment type. */
|
|
126
|
+
readonly networkType: NetworkType
|
|
104
127
|
} & ChainFamilyWithId<F>
|
|
105
128
|
|
|
106
129
|
/**
|
|
107
130
|
* CCIP lane configuration connecting source and destination chains.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* const lane: Lane = {
|
|
135
|
+
* sourceChainSelector: 16015286601757825753n, // Ethereum Sepolia
|
|
136
|
+
* destChainSelector: 12532609583862916517n, // Polygon Mumbai
|
|
137
|
+
* onRamp: '0x1234...abcd',
|
|
138
|
+
* version: '1.6.0',
|
|
139
|
+
* }
|
|
140
|
+
* ```
|
|
108
141
|
*/
|
|
109
142
|
export interface Lane<V extends CCIPVersion = CCIPVersion> {
|
|
110
143
|
/** Source chain selector. */
|
|
@@ -138,6 +171,17 @@ export type Log_ = Pick<Log, 'topics' | 'index' | 'address' | 'blockNumber' | 't
|
|
|
138
171
|
|
|
139
172
|
/**
|
|
140
173
|
* Generic transaction structure compatible across chain families.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* const tx: ChainTransaction = {
|
|
178
|
+
* hash: '0xabc123...',
|
|
179
|
+
* logs: [],
|
|
180
|
+
* blockNumber: 12345678,
|
|
181
|
+
* timestamp: 1704067200,
|
|
182
|
+
* from: '0x1234...abcd',
|
|
183
|
+
* }
|
|
184
|
+
* ```
|
|
141
185
|
*/
|
|
142
186
|
export type ChainTransaction = {
|
|
143
187
|
/** Transaction hash. */
|
|
@@ -166,6 +210,29 @@ export interface CCIPRequest<V extends CCIPVersion = CCIPVersion> {
|
|
|
166
210
|
log: Log_
|
|
167
211
|
/** Transaction that emitted the request. */
|
|
168
212
|
tx: Pick<ChainTransaction, 'hash' | 'logs' | 'blockNumber' | 'timestamp' | 'from' | 'error'>
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* API-enriched metadata. Present only when fetched via CCIP API.
|
|
216
|
+
*
|
|
217
|
+
* @remarks
|
|
218
|
+
* When a request is fetched using {@link Chain.getMessageById} or as a fallback
|
|
219
|
+
* in {@link Chain.getMessagesInTx}, this field contains additional information
|
|
220
|
+
* including message status, execution details, and network info.
|
|
221
|
+
*
|
|
222
|
+
* When constructed from on-chain data only, this field is `undefined`.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* const request = await chain.getMessageById(messageId)
|
|
227
|
+
* if (request.metadata) {
|
|
228
|
+
* console.log('Status:', request.metadata.status)
|
|
229
|
+
* console.log('Delivery time:', request.metadata.deliveryTime)
|
|
230
|
+
* }
|
|
231
|
+
* ```
|
|
232
|
+
*
|
|
233
|
+
* @see {@link APICCIPRequestMetadata}
|
|
234
|
+
*/
|
|
235
|
+
metadata?: APICCIPRequestMetadata
|
|
169
236
|
}
|
|
170
237
|
|
|
171
238
|
/**
|
|
@@ -216,6 +283,12 @@ export const MessageStatus = {
|
|
|
216
283
|
Success: 'SUCCESS',
|
|
217
284
|
/** Message execution failed on destination. */
|
|
218
285
|
Failed: 'FAILED',
|
|
286
|
+
/** Message is being verified by the CCIP network */
|
|
287
|
+
Verifying: 'VERIFYING',
|
|
288
|
+
/** Message has been verified by the CCIP network */
|
|
289
|
+
Verified: 'VERIFIED',
|
|
290
|
+
/** Unknown status returned by API */
|
|
291
|
+
Unknown: 'UNKNOWN',
|
|
219
292
|
} as const
|
|
220
293
|
/** Type representing a CCIP message lifecycle status. */
|
|
221
294
|
export type MessageStatus = (typeof MessageStatus)[keyof typeof MessageStatus]
|
|
@@ -237,6 +310,16 @@ export type IntentStatus = (typeof IntentStatus)[keyof typeof IntentStatus]
|
|
|
237
310
|
|
|
238
311
|
/**
|
|
239
312
|
* Receipt of a CCIP message execution on the destination chain.
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```typescript
|
|
316
|
+
* const receipt: ExecutionReceipt = {
|
|
317
|
+
* messageId: '0xabc123...',
|
|
318
|
+
* sequenceNumber: 42n,
|
|
319
|
+
* state: ExecutionState.Success,
|
|
320
|
+
* sourceChainSelector: 16015286601757825753n,
|
|
321
|
+
* }
|
|
322
|
+
* ```
|
|
240
323
|
*/
|
|
241
324
|
export type ExecutionReceipt = {
|
|
242
325
|
/** Unique message identifier. */
|
|
@@ -274,6 +357,17 @@ export type OffchainTokenData = { _tag: string; [k: string]: BytesLike } | undef
|
|
|
274
357
|
|
|
275
358
|
/**
|
|
276
359
|
* Execution report containing message, proofs, and offchain token data.
|
|
360
|
+
*
|
|
361
|
+
* @example
|
|
362
|
+
* ```typescript
|
|
363
|
+
* const report: ExecutionReport = {
|
|
364
|
+
* message: { messageId: '0x...', ... },
|
|
365
|
+
* proofs: ['0xproof1...', '0xproof2...'],
|
|
366
|
+
* proofFlagBits: 0n,
|
|
367
|
+
* merkleRoot: '0xroot...',
|
|
368
|
+
* offchainTokenData: [],
|
|
369
|
+
* }
|
|
370
|
+
* ```
|
|
277
371
|
*/
|
|
278
372
|
export type ExecutionReport<M extends CCIPMessage = CCIPMessage> = {
|
|
279
373
|
/** The CCIP message to execute. */
|
|
@@ -290,6 +384,16 @@ export type ExecutionReport<M extends CCIPMessage = CCIPMessage> = {
|
|
|
290
384
|
|
|
291
385
|
/**
|
|
292
386
|
* A message to be sent to another network.
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* ```typescript
|
|
390
|
+
* const message: AnyMessage = {
|
|
391
|
+
* receiver: '0x1234...abcd',
|
|
392
|
+
* extraArgs: { gasLimit: 200_000n, allowOutOfOrderExecution: true },
|
|
393
|
+
* data: '0xdeadbeef',
|
|
394
|
+
* tokenAmounts: [{ token: '0xtoken...', amount: 1000000n }],
|
|
395
|
+
* }
|
|
396
|
+
* ```
|
|
293
397
|
*/
|
|
294
398
|
export type AnyMessage = {
|
|
295
399
|
/** Receiver address on the destination chain. */
|
|
@@ -305,7 +409,22 @@ export type AnyMessage = {
|
|
|
305
409
|
}
|
|
306
410
|
|
|
307
411
|
/**
|
|
308
|
-
* Partial
|
|
412
|
+
* Partial {@link AnyMessage}, which populates default fields like `extraArgs` if needed.
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* ```typescript
|
|
416
|
+
* // Minimal input - only receiver required, defaults applied for extraArgs
|
|
417
|
+
* const input: MessageInput = {
|
|
418
|
+
* receiver: '0x1234...abcd',
|
|
419
|
+
* }
|
|
420
|
+
*
|
|
421
|
+
* // With custom gas limit
|
|
422
|
+
* const inputWithGas: MessageInput = {
|
|
423
|
+
* receiver: '0x1234...abcd',
|
|
424
|
+
* extraArgs: { gasLimit: 500_000n },
|
|
425
|
+
* data: '0xdeadbeef',
|
|
426
|
+
* }
|
|
427
|
+
* ```
|
|
309
428
|
*/
|
|
310
429
|
export type MessageInput = Partial<AnyMessage> & {
|
|
311
430
|
receiver: AnyMessage['receiver']
|