@chainlink/ccip-sdk 0.96.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/README.md +12 -9
  2. package/dist/api/index.d.ts +21 -8
  3. package/dist/api/index.d.ts.map +1 -1
  4. package/dist/api/index.js +42 -13
  5. package/dist/api/index.js.map +1 -1
  6. package/dist/api/types.d.ts +0 -2
  7. package/dist/api/types.d.ts.map +1 -1
  8. package/dist/aptos/exec.d.ts +2 -2
  9. package/dist/aptos/exec.d.ts.map +1 -1
  10. package/dist/aptos/exec.js.map +1 -1
  11. package/dist/aptos/hasher.d.ts.map +1 -1
  12. package/dist/aptos/hasher.js +1 -1
  13. package/dist/aptos/hasher.js.map +1 -1
  14. package/dist/aptos/index.d.ts +17 -16
  15. package/dist/aptos/index.d.ts.map +1 -1
  16. package/dist/aptos/index.js +42 -73
  17. package/dist/aptos/index.js.map +1 -1
  18. package/dist/aptos/logs.d.ts +2 -2
  19. package/dist/aptos/logs.d.ts.map +1 -1
  20. package/dist/aptos/types.d.ts +2 -19
  21. package/dist/aptos/types.d.ts.map +1 -1
  22. package/dist/aptos/types.js +0 -11
  23. package/dist/aptos/types.js.map +1 -1
  24. package/dist/chain.d.ts +538 -158
  25. package/dist/chain.d.ts.map +1 -1
  26. package/dist/chain.js +132 -19
  27. package/dist/chain.js.map +1 -1
  28. package/dist/commits.d.ts +4 -6
  29. package/dist/commits.d.ts.map +1 -1
  30. package/dist/commits.js +4 -4
  31. package/dist/commits.js.map +1 -1
  32. package/dist/errors/CCIPError.d.ts +33 -4
  33. package/dist/errors/CCIPError.d.ts.map +1 -1
  34. package/dist/errors/CCIPError.js +33 -4
  35. package/dist/errors/CCIPError.js.map +1 -1
  36. package/dist/errors/codes.d.ts +3 -0
  37. package/dist/errors/codes.d.ts.map +1 -1
  38. package/dist/errors/codes.js +3 -1
  39. package/dist/errors/codes.js.map +1 -1
  40. package/dist/errors/index.d.ts +4 -4
  41. package/dist/errors/index.d.ts.map +1 -1
  42. package/dist/errors/index.js +4 -4
  43. package/dist/errors/index.js.map +1 -1
  44. package/dist/errors/recovery.d.ts.map +1 -1
  45. package/dist/errors/recovery.js +4 -1
  46. package/dist/errors/recovery.js.map +1 -1
  47. package/dist/errors/specialized.d.ts +1695 -120
  48. package/dist/errors/specialized.d.ts.map +1 -1
  49. package/dist/errors/specialized.js +1715 -123
  50. package/dist/errors/specialized.js.map +1 -1
  51. package/dist/errors/utils.d.ts.map +1 -1
  52. package/dist/errors/utils.js +0 -1
  53. package/dist/errors/utils.js.map +1 -1
  54. package/dist/evm/abi/OffRamp_2_0.d.ts +764 -0
  55. package/dist/evm/abi/OffRamp_2_0.d.ts.map +1 -0
  56. package/dist/evm/abi/OffRamp_2_0.js +744 -0
  57. package/dist/evm/abi/OffRamp_2_0.js.map +1 -0
  58. package/dist/evm/abi/OnRamp_2_0.d.ts +925 -0
  59. package/dist/evm/abi/OnRamp_2_0.d.ts.map +1 -0
  60. package/dist/evm/abi/OnRamp_2_0.js +992 -0
  61. package/dist/evm/abi/OnRamp_2_0.js.map +1 -0
  62. package/dist/evm/const.d.ts +12 -2
  63. package/dist/evm/const.d.ts.map +1 -1
  64. package/dist/evm/const.js +8 -2
  65. package/dist/evm/const.js.map +1 -1
  66. package/dist/evm/errors.d.ts.map +1 -1
  67. package/dist/evm/errors.js +7 -2
  68. package/dist/evm/errors.js.map +1 -1
  69. package/dist/evm/extra-args.d.ts.map +1 -1
  70. package/dist/evm/extra-args.js +5 -24
  71. package/dist/evm/extra-args.js.map +1 -1
  72. package/dist/evm/hasher.d.ts.map +1 -1
  73. package/dist/evm/hasher.js +23 -13
  74. package/dist/evm/hasher.js.map +1 -1
  75. package/dist/evm/index.d.ts +73 -16
  76. package/dist/evm/index.d.ts.map +1 -1
  77. package/dist/evm/index.js +241 -146
  78. package/dist/evm/index.js.map +1 -1
  79. package/dist/evm/logs.d.ts +1 -1
  80. package/dist/evm/logs.js +1 -1
  81. package/dist/evm/messages.d.ts +59 -5
  82. package/dist/evm/messages.d.ts.map +1 -1
  83. package/dist/evm/messages.js +210 -0
  84. package/dist/evm/messages.js.map +1 -1
  85. package/dist/evm/offchain.d.ts +1 -14
  86. package/dist/evm/offchain.d.ts.map +1 -1
  87. package/dist/evm/offchain.js +1 -133
  88. package/dist/evm/offchain.js.map +1 -1
  89. package/dist/evm/types.d.ts +7 -2
  90. package/dist/evm/types.d.ts.map +1 -1
  91. package/dist/evm/types.js +22 -1
  92. package/dist/evm/types.js.map +1 -1
  93. package/dist/execution.d.ts +62 -22
  94. package/dist/execution.d.ts.map +1 -1
  95. package/dist/execution.js +98 -61
  96. package/dist/execution.js.map +1 -1
  97. package/dist/extra-args.d.ts +13 -3
  98. package/dist/extra-args.d.ts.map +1 -1
  99. package/dist/extra-args.js +13 -3
  100. package/dist/extra-args.js.map +1 -1
  101. package/dist/gas.d.ts +25 -2
  102. package/dist/gas.d.ts.map +1 -1
  103. package/dist/gas.js +30 -4
  104. package/dist/gas.js.map +1 -1
  105. package/dist/index.d.ts +3 -2
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +2 -1
  108. package/dist/index.js.map +1 -1
  109. package/dist/offchain.d.ts +23 -6
  110. package/dist/offchain.d.ts.map +1 -1
  111. package/dist/offchain.js +92 -17
  112. package/dist/offchain.js.map +1 -1
  113. package/dist/requests.d.ts +85 -14
  114. package/dist/requests.d.ts.map +1 -1
  115. package/dist/requests.js +99 -17
  116. package/dist/requests.js.map +1 -1
  117. package/dist/selectors.d.ts.map +1 -1
  118. package/dist/selectors.js +12 -0
  119. package/dist/selectors.js.map +1 -1
  120. package/dist/shared/bcs-codecs.d.ts +61 -0
  121. package/dist/shared/bcs-codecs.d.ts.map +1 -0
  122. package/dist/shared/bcs-codecs.js +102 -0
  123. package/dist/shared/bcs-codecs.js.map +1 -0
  124. package/dist/shared/constants.d.ts +3 -0
  125. package/dist/shared/constants.d.ts.map +1 -0
  126. package/dist/shared/constants.js +3 -0
  127. package/dist/shared/constants.js.map +1 -0
  128. package/dist/solana/exec.d.ts +2 -2
  129. package/dist/solana/exec.d.ts.map +1 -1
  130. package/dist/solana/exec.js.map +1 -1
  131. package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.d.ts +1 -1
  132. package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.js +1 -1
  133. package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.d.ts +1 -1
  134. package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.js +1 -1
  135. package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.d.ts +1 -1
  136. package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.js +1 -1
  137. package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts +16 -1
  138. package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts.map +1 -1
  139. package/dist/solana/idl/1.6.0/CCIP_COMMON.js +16 -1
  140. package/dist/solana/idl/1.6.0/CCIP_COMMON.js.map +1 -1
  141. package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.d.ts +1 -1
  142. package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.js +1 -1
  143. package/dist/solana/idl/1.6.0/CCIP_ROUTER.d.ts +1 -1
  144. package/dist/solana/idl/1.6.0/CCIP_ROUTER.js +1 -1
  145. package/dist/solana/index.d.ts +85 -24
  146. package/dist/solana/index.d.ts.map +1 -1
  147. package/dist/solana/index.js +69 -37
  148. package/dist/solana/index.js.map +1 -1
  149. package/dist/solana/offchain.d.ts +1 -13
  150. package/dist/solana/offchain.d.ts.map +1 -1
  151. package/dist/solana/offchain.js +1 -66
  152. package/dist/solana/offchain.js.map +1 -1
  153. package/dist/solana/utils.d.ts +4 -4
  154. package/dist/solana/utils.d.ts.map +1 -1
  155. package/dist/solana/utils.js +1 -1
  156. package/dist/solana/utils.js.map +1 -1
  157. package/dist/sui/hasher.d.ts.map +1 -1
  158. package/dist/sui/hasher.js +1 -1
  159. package/dist/sui/hasher.js.map +1 -1
  160. package/dist/sui/index.d.ts +18 -18
  161. package/dist/sui/index.d.ts.map +1 -1
  162. package/dist/sui/index.js +38 -39
  163. package/dist/sui/index.js.map +1 -1
  164. package/dist/sui/manuallyExec/encoder.d.ts +2 -2
  165. package/dist/sui/manuallyExec/encoder.d.ts.map +1 -1
  166. package/dist/sui/manuallyExec/encoder.js.map +1 -1
  167. package/dist/sui/manuallyExec/index.d.ts +2 -2
  168. package/dist/sui/manuallyExec/index.d.ts.map +1 -1
  169. package/dist/ton/exec.d.ts +3 -3
  170. package/dist/ton/exec.d.ts.map +1 -1
  171. package/dist/ton/exec.js +1 -1
  172. package/dist/ton/exec.js.map +1 -1
  173. package/dist/ton/index.d.ts +14 -22
  174. package/dist/ton/index.d.ts.map +1 -1
  175. package/dist/ton/index.js +26 -35
  176. package/dist/ton/index.js.map +1 -1
  177. package/dist/ton/types.d.ts +3 -5
  178. package/dist/ton/types.d.ts.map +1 -1
  179. package/dist/ton/types.js.map +1 -1
  180. package/dist/types.d.ts +55 -20
  181. package/dist/types.d.ts.map +1 -1
  182. package/dist/types.js +6 -1
  183. package/dist/types.js.map +1 -1
  184. package/dist/utils.d.ts +65 -2
  185. package/dist/utils.d.ts.map +1 -1
  186. package/dist/utils.js +74 -2
  187. package/dist/utils.js.map +1 -1
  188. package/package.json +14 -10
  189. package/src/api/index.ts +53 -17
  190. package/src/api/types.ts +0 -2
  191. package/src/aptos/exec.ts +2 -2
  192. package/src/aptos/hasher.ts +1 -1
  193. package/src/aptos/index.ts +55 -100
  194. package/src/aptos/logs.ts +2 -2
  195. package/src/aptos/types.ts +2 -15
  196. package/src/chain.ts +594 -171
  197. package/src/commits.ts +9 -9
  198. package/src/errors/CCIPError.ts +33 -4
  199. package/src/errors/codes.ts +3 -1
  200. package/src/errors/index.ts +4 -0
  201. package/src/errors/recovery.ts +7 -1
  202. package/src/errors/specialized.ts +1726 -130
  203. package/src/errors/utils.ts +0 -1
  204. package/src/evm/abi/OffRamp_2_0.ts +743 -0
  205. package/src/evm/abi/OnRamp_2_0.ts +991 -0
  206. package/src/evm/const.ts +10 -3
  207. package/src/evm/errors.ts +6 -2
  208. package/src/evm/extra-args.ts +4 -21
  209. package/src/evm/hasher.ts +30 -18
  210. package/src/evm/index.ts +314 -176
  211. package/src/evm/logs.ts +1 -1
  212. package/src/evm/messages.ts +323 -11
  213. package/src/evm/offchain.ts +2 -191
  214. package/src/evm/types.ts +20 -2
  215. package/src/execution.ts +125 -86
  216. package/src/extra-args.ts +13 -3
  217. package/src/gas.ts +29 -3
  218. package/src/index.ts +10 -3
  219. package/src/offchain.ts +125 -28
  220. package/src/requests.ts +114 -19
  221. package/src/selectors.ts +12 -0
  222. package/src/shared/bcs-codecs.ts +132 -0
  223. package/src/shared/constants.ts +2 -0
  224. package/src/solana/exec.ts +4 -4
  225. package/src/solana/idl/1.6.0/BASE_TOKEN_POOL.ts +2 -2
  226. package/src/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.ts +2 -2
  227. package/src/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.ts +2 -2
  228. package/src/solana/idl/1.6.0/CCIP_COMMON.ts +32 -2
  229. package/src/solana/idl/1.6.0/CCIP_OFFRAMP.ts +2 -2
  230. package/src/solana/idl/1.6.0/CCIP_ROUTER.ts +2 -2
  231. package/src/solana/index.ts +110 -85
  232. package/src/solana/offchain.ts +3 -100
  233. package/src/solana/utils.ts +8 -5
  234. package/src/sui/hasher.ts +1 -1
  235. package/src/sui/index.ts +55 -59
  236. package/src/sui/manuallyExec/encoder.ts +2 -2
  237. package/src/sui/manuallyExec/index.ts +2 -2
  238. package/src/ton/exec.ts +4 -7
  239. package/src/ton/index.ts +45 -53
  240. package/src/ton/types.ts +4 -7
  241. package/src/types.ts +81 -37
  242. package/src/utils.ts +73 -2
  243. package/dist/aptos/utils.d.ts +0 -12
  244. package/dist/aptos/utils.d.ts.map +0 -1
  245. package/dist/aptos/utils.js +0 -15
  246. package/dist/aptos/utils.js.map +0 -1
  247. package/src/aptos/utils.ts +0 -24
package/src/requests.ts CHANGED
@@ -19,8 +19,8 @@ import {
19
19
  type CCIPMessage,
20
20
  type CCIPRequest,
21
21
  type CCIPVersion,
22
+ type ChainLog,
22
23
  type ChainTransaction,
23
- type Log_,
24
24
  type MessageInput,
25
25
  ChainFamily,
26
26
  } from './types.ts'
@@ -46,6 +46,14 @@ function decodeJsonMessage(data: Record<string, unknown> | undefined) {
46
46
  source_chain_selector?: string
47
47
  sourceChainSelector?: string
48
48
  extraArgs?: string | Record<string, unknown>
49
+ sequenceNumber?: bigint
50
+ messageNumber?: bigint
51
+ tokenTransfer?: {
52
+ destExecData: string
53
+ destGasAmount?: bigint
54
+ token?: string
55
+ sourceTokenAddress?: string
56
+ }[]
49
57
  tokenAmounts: {
50
58
  destExecData: string
51
59
  destGasAmount?: bigint
@@ -60,6 +68,7 @@ function decodeJsonMessage(data: Record<string, unknown> | undefined) {
60
68
  totalAmount: bigint
61
69
  }
62
70
  }
71
+ receipts?: { feeTokenAmount: bigint }[]
63
72
  sourceNetworkInfo?: { chainSelector: string }
64
73
  destNetworkInfo?: { chainSelector: string }
65
74
  }
@@ -69,7 +78,6 @@ function decodeJsonMessage(data: Record<string, unknown> | undefined) {
69
78
  data_.sourceNetworkInfo?.chainSelector
70
79
  if (!sourceChainSelector) throw new CCIPMessageInvalidError(data)
71
80
  data_.sourceChainSelector ??= sourceChainSelector
72
- data_.nonce ??= 0n
73
81
  const sourceFamily = networkInfo(sourceChainSelector).family
74
82
 
75
83
  const destChainSelector =
@@ -82,7 +90,7 @@ function decodeJsonMessage(data: Record<string, unknown> | undefined) {
82
90
  ? BigInt(v as string | number | bigint)
83
91
  : k?.match(/(^dest.*address)|(receiver|offramp|accounts)/i)
84
92
  ? decodeAddress(v as BytesLike, destFamily)
85
- : k?.match(/((source.*address)|sender|origin|onramp|(feetoken$)|(token.*address$))/i)
93
+ : k?.match(/((source.*address)|sender|issuer|origin|onramp|(feetoken$)|(token.*address$))/i)
86
94
  ? decodeAddress(v as BytesLike, sourceFamily)
87
95
  : v instanceof Uint8Array ||
88
96
  (Array.isArray(v) && v.length >= 4 && v.every((e) => typeof e === 'number'))
@@ -90,6 +98,10 @@ function decodeJsonMessage(data: Record<string, unknown> | undefined) {
90
98
  : v,
91
99
  ) as typeof data_
92
100
 
101
+ if (data_.tokenTransfer) {
102
+ data_.tokenAmounts = data_.tokenTransfer
103
+ delete data_.tokenTransfer
104
+ }
93
105
  for (const ta of data_.tokenAmounts) {
94
106
  if (ta.token && !ta.sourceTokenAddress) ta.sourceTokenAddress = ta.token
95
107
  if (!ta.token && ta.sourceTokenAddress) ta.token = ta.sourceTokenAddress
@@ -121,6 +133,15 @@ function decodeJsonMessage(data: Record<string, unknown> | undefined) {
121
133
  data_.feeToken = data_.fees.fixedFeesDetails.tokenAddress
122
134
  data_.feeTokenAmount = data_.fees.fixedFeesDetails.totalAmount
123
135
  }
136
+ if (data_.sequenceNumber == null && data_.messageNumber != null) {
137
+ data_.sequenceNumber = data_.messageNumber
138
+ }
139
+ if (!data_.feeTokenAmount && data_.receipts) {
140
+ data_.feeTokenAmount = data_.receipts.reduce(
141
+ (acc, receipt) => acc + receipt.feeTokenAmount,
142
+ BigInt(0),
143
+ )
144
+ }
124
145
 
125
146
  return data_ as unknown as CCIPMessage
126
147
  }
@@ -128,9 +149,24 @@ function decodeJsonMessage(data: Record<string, unknown> | undefined) {
128
149
  /**
129
150
  * Decodes hex strings, bytearrays, JSON strings and raw objects as CCIPMessages.
130
151
  * Does minimal validation, but converts objects in the format expected by ccip-tools-ts.
152
+ *
131
153
  * @param data - Data to decode (hex string, Uint8Array, JSON string, or object)
132
154
  * @returns Decoded CCIPMessage
133
155
  * @throws {@link CCIPMessageDecodeError} if data cannot be decoded as a valid message
156
+ * @throws {@link CCIPMessageInvalidError} if message structure is invalid or missing required fields
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * import { decodeMessage } from '@chainlink/ccip-sdk'
161
+ *
162
+ * // Decode from JSON string
163
+ * const message = decodeMessage('{"header":{"sourceChainSelector":"123",...}')
164
+ *
165
+ * // Decode from hex-encoded bytes
166
+ * const message = decodeMessage('0x...')
167
+ *
168
+ * console.log('Message ID:', message.messageId)
169
+ * ```
134
170
  */
135
171
  export function decodeMessage(data: string | Uint8Array | Record<string, unknown>): CCIPMessage {
136
172
  if (
@@ -144,7 +180,7 @@ export function decodeMessage(data: string | Uint8Array | Record<string, unknown
144
180
  // try bytearray decoding on each supported chain
145
181
  for (const chain of Object.values(supportedChains)) {
146
182
  try {
147
- const decoded = chain.decodeMessage({ data } as unknown as Log_)
183
+ const decoded = chain.decodeMessage({ data } as unknown as ChainLog)
148
184
  if (decoded) return decoded
149
185
  } catch (_) {
150
186
  // continue
@@ -171,6 +207,8 @@ export function buildMessageForDest(message: MessageInput, dest: ChainFamily): A
171
207
  * @returns CCIP requests (messages) in the transaction (at least one)
172
208
  * @throws {@link CCIPChainFamilyUnsupportedError} if chain family not supported for legacy messages
173
209
  * @throws {@link CCIPMessageNotFoundInTxError} if no CCIP messages found in transaction
210
+ *
211
+ * @see {@link getMessageById} - Search by messageId when tx hash unknown
174
212
  */
175
213
  export async function getMessagesInTx(source: Chain, tx: ChainTransaction): Promise<CCIPRequest[]> {
176
214
  // RPC fallback
@@ -194,17 +232,36 @@ export async function getMessagesInTx(source: Chain, tx: ChainTransaction): Prom
194
232
  }
195
233
  requests.push({ lane, message, log, tx })
196
234
  }
197
- if (!requests.length) throw new CCIPMessageNotFoundInTxError(tx.hash)
235
+ if (!requests.length)
236
+ throw new CCIPMessageNotFoundInTxError(tx.hash, { context: { network: source.network.name } })
198
237
  return requests
199
238
  }
200
239
 
201
240
  /**
202
- * Fetch a CCIP message by its messageId from RPC (slow).
203
- * Should be called *after* generic Chain implementation, which fetches from API if available.
204
- * @param source - Provider to fetch logs from.
205
- * @param messageId - MessageId to search for.
206
- * @param opts - Optional hints for pagination (e.g., `address` for onRamp, `page` for pagination size).
207
- * @returns CCIPRequest with given messageId.
241
+ * Fetch a CCIP message by messageId from RPC logs (slow scan).
242
+ *
243
+ * This is the fallback implementation called by {@link Chain.getMessageById}
244
+ * when the API client is unavailable or fails.
245
+ *
246
+ * @param source - Source chain to scan logs from
247
+ * @param messageId - Message ID to search for
248
+ * @param opts - Optional hints (onRamp address narrows search, page controls batch size)
249
+ * @returns CCIPRequest matching the messageId
250
+ *
251
+ * @throws {@link CCIPMessageIdNotFoundError} if message not found after scanning all logs
252
+ *
253
+ * @example
254
+ *
255
+ * ```typescript
256
+ * import { getMessageById, EVMChain } from '@chainlink/ccip-sdk'
257
+ *
258
+ * const source = await EVMChain.fromUrl('https://rpc.sepolia.org')
259
+ * const request = await getMessageById(source, '0xabc123...', {
260
+ * onRamp: '0xOnRampAddress...',
261
+ * })
262
+ * console.log(`Found: seqNr=${request.message.sequenceNumber}`)
263
+ * ```
264
+ *
208
265
  * @internal
209
266
  */
210
267
  export async function getMessageById(
@@ -249,9 +306,10 @@ const BLOCK_LOG_WINDOW_SIZE = 5000
249
306
  * Fetches all CCIP messages contained in a given commit batch.
250
307
  * @param source - The source chain.
251
308
  * @param request - The CCIP request containing lane and message info.
252
- * @param seqNrRange - Object containing minSeqNr and maxSeqNr for the batch range.
309
+ * @param range - Object containing minSeqNr and maxSeqNr for the batch range.
253
310
  * @param opts - Optional log filtering parameters.
254
311
  * @returns Array of messages in the batch.
312
+ * @see {@link getVerifications} - Get commit report to determine batch range
255
313
  */
256
314
  export async function getMessagesInBatch<
257
315
  C extends Chain,
@@ -293,6 +351,7 @@ export async function getMessagesInBatch<
293
351
  const message = (source.constructor as ChainStatic).decodeMessage(log)
294
352
  if (
295
353
  !message ||
354
+ !('sequenceNumber' in message) ||
296
355
  ('destChainSelector' in message &&
297
356
  message.destChainSelector !== request.lane.destChainSelector)
298
357
  )
@@ -314,6 +373,7 @@ export async function getMessagesInBatch<
314
373
  const message = (source.constructor as ChainStatic).decodeMessage(log)
315
374
  if (
316
375
  !message ||
376
+ !('sequenceNumber' in message) ||
317
377
  ('destChainSelector' in message &&
318
378
  message.destChainSelector !== request.lane.destChainSelector)
319
379
  )
@@ -339,6 +399,21 @@ export async function getMessagesInBatch<
339
399
  * @param filter - Log filter options.
340
400
  * @returns Async generator of CCIP requests.
341
401
  * @throws {@link CCIPChainFamilyUnsupportedError} if chain family not supported for legacy messages
402
+ *
403
+ * @example
404
+ * ```typescript
405
+ * import { getMessagesForSender, EVMChain } from '@chainlink/ccip-sdk'
406
+ *
407
+ * const chain = await EVMChain.fromUrl('https://rpc.sepolia.org')
408
+ *
409
+ * for await (const request of getMessagesForSender(chain, '0xSenderAddress', {})) {
410
+ * console.log('Message ID:', request.message.messageId)
411
+ * console.log('Destination:', request.lane.destChainSelector)
412
+ * }
413
+ * ```
414
+ *
415
+ * @see {@link getMessagesInTx} - Fetch from specific transaction
416
+ * @see {@link getMessageById} - Search by messageId
342
417
  */
343
418
  export async function* getMessagesForSender(
344
419
  source: Chain,
@@ -376,13 +451,33 @@ export async function* getMessagesForSender(
376
451
  }
377
452
 
378
453
  /**
379
- * Map source `token` to `sourcePoolAddress + destTokenAddress`.
380
- * @param source - Source chain.
381
- * @param destChainSelector - Destination network selector.
382
- * @param onRamp - Contract address.
383
- * @param sourceTokenAmount - tokenAmount object, usually containing `token` and `amount` properties.
384
- * @returns tokenAmount object with `sourcePoolAddress`, `sourceTokenAddress`, `destTokenAddress`, and remaining properties.
385
- * @throws {@link CCIPTokenNotInRegistryError} if token not found in registry
454
+ * Map source token to its pool address and destination token address.
455
+ *
456
+ * Resolves token routing by querying the TokenAdminRegistry and TokenPool
457
+ * to find the corresponding destination chain token.
458
+ *
459
+ * @param source - Source chain instance
460
+ * @param destChainSelector - Destination chain selector
461
+ * @param onRamp - OnRamp contract address
462
+ * @param sourceTokenAmount - Token amount object containing `token` and `amount`
463
+ * @returns Extended token amount with `sourcePoolAddress`, `sourceTokenAddress`, and `destTokenAddress`
464
+ *
465
+ * @throws {@link CCIPTokenNotInRegistryError} if token is not registered in TokenAdminRegistry
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * import { sourceToDestTokenAddresses, EVMChain } from '@chainlink/ccip-sdk'
470
+ *
471
+ * const source = await EVMChain.fromUrl('https://rpc.sepolia.org')
472
+ * const tokenAmount = await sourceToDestTokenAddresses(
473
+ * source,
474
+ * destChainSelector,
475
+ * '0xOnRamp...',
476
+ * { token: '0xLINK...', amount: 1000000000000000000n }
477
+ * )
478
+ * console.log(`Pool: ${tokenAmount.sourcePoolAddress}`)
479
+ * console.log(`Dest token: ${tokenAmount.destTokenAddress}`)
480
+ * ```
386
481
  */
387
482
  export async function sourceToDestTokenAddresses<S extends { token: string }>(
388
483
  source: Chain,
package/src/selectors.ts CHANGED
@@ -1099,6 +1099,12 @@ const selectors: Selectors = {
1099
1099
  network_type: 'TESTNET',
1100
1100
  family: 'EVM',
1101
1101
  },
1102
+ '46630': {
1103
+ selector: 2032988798112970440n,
1104
+ name: 'robinhood-testnet',
1105
+ network_type: 'TESTNET',
1106
+ family: 'EVM',
1107
+ },
1102
1108
  '47763': {
1103
1109
  selector: 7222032299962346917n,
1104
1110
  name: 'neox-mainnet',
@@ -1349,6 +1355,12 @@ const selectors: Selectors = {
1349
1355
  network_type: 'MAINNET',
1350
1356
  family: 'EVM',
1351
1357
  },
1358
+ '202601': {
1359
+ selector: 1091131740251125869n,
1360
+ name: 'ethereum-testnet-sepolia-ronin-1',
1361
+ network_type: 'TESTNET',
1362
+ family: 'EVM',
1363
+ },
1352
1364
  '421613': {
1353
1365
  selector: 6101244977088475029n,
1354
1366
  name: 'ethereum-testnet-goerli-arbitrum-1',
@@ -0,0 +1,132 @@
1
+ /**
2
+ * BCS (Binary Canonical Serialization) codecs for Move-based chains (Aptos, Sui).
3
+ * These chains share similar BCS encoding and 32-byte address formats.
4
+ */
5
+ import { bcs } from '@mysten/bcs'
6
+ import {
7
+ type BigNumberish,
8
+ type BytesLike,
9
+ concat,
10
+ dataLength,
11
+ dataSlice,
12
+ getBytes,
13
+ hexlify,
14
+ toBeHex,
15
+ zeroPadBytes,
16
+ zeroPadValue,
17
+ } from 'ethers'
18
+
19
+ import { CCIPDataFormatUnsupportedError } from '../errors/index.ts'
20
+ import {
21
+ type EVMExtraArgsV2,
22
+ type SVMExtraArgsV1,
23
+ EVMExtraArgsV2Tag,
24
+ SVMExtraArgsV1Tag,
25
+ } from '../extra-args.ts'
26
+ import { ChainFamily } from '../types.ts'
27
+ import { decodeAddress, getDataBytes } from '../utils.ts'
28
+
29
+ /**
30
+ * BCS codec for decoding EVM extra args on Move chains (Aptos/Sui).
31
+ * Used when receiving cross-chain messages from EVM source chains.
32
+ */
33
+ export const BcsEVMExtraArgsV2Codec = bcs.struct('EVMExtraArgsV2', {
34
+ gasLimit: bcs.u256(),
35
+ allowOutOfOrderExecution: bcs.bool(),
36
+ })
37
+
38
+ /**
39
+ * BCS codec for decoding SVM (Solana) extra args on Move chains (Aptos/Sui).
40
+ * Used when receiving cross-chain messages from Solana source chains.
41
+ */
42
+ export const BcsSVMExtraArgsV1Codec = bcs.struct('SVMExtraArgsV1', {
43
+ computeUnits: bcs.u32(),
44
+ accountIsWritableBitmap: bcs.u64(),
45
+ allowOutOfOrderExecution: bcs.bool(),
46
+ tokenReceiver: bcs.vector(bcs.u8()),
47
+ accounts: bcs.vector(bcs.vector(bcs.u8())),
48
+ })
49
+
50
+ /**
51
+ * Decodes extra arguments from Move-based chain CCIP messages.
52
+ * Works for both Aptos and Sui since they share the same BCS encoding.
53
+ * @param extraArgs - Encoded extra arguments bytes.
54
+ * @returns Decoded extra arguments or undefined if unknown format.
55
+ */
56
+ export function decodeMoveExtraArgs(
57
+ extraArgs: BytesLike,
58
+ ):
59
+ | (EVMExtraArgsV2 & { _tag: 'EVMExtraArgsV2' })
60
+ | (SVMExtraArgsV1 & { _tag: 'SVMExtraArgsV1' })
61
+ | undefined {
62
+ const data = getDataBytes(extraArgs),
63
+ tag = dataSlice(data, 0, 4)
64
+ switch (tag) {
65
+ case EVMExtraArgsV2Tag: {
66
+ const parsed = BcsEVMExtraArgsV2Codec.parse(getBytes(dataSlice(data, 4)))
67
+ // Move serialization of EVMExtraArgsV2: 37 bytes total: 4 tag + 32 LE gasLimit + 1 allowOOOE
68
+ return {
69
+ _tag: 'EVMExtraArgsV2',
70
+ ...parsed,
71
+ gasLimit: BigInt(parsed.gasLimit),
72
+ }
73
+ }
74
+ case SVMExtraArgsV1Tag: {
75
+ const parsed = BcsSVMExtraArgsV1Codec.parse(getBytes(dataSlice(data, 4)))
76
+ // Move serialization of SVMExtraArgsV1: 13 bytes total: 4 tag + 8 LE computeUnits
77
+ return {
78
+ _tag: 'SVMExtraArgsV1',
79
+ ...parsed,
80
+ computeUnits: BigInt(parsed.computeUnits),
81
+ accountIsWritableBitmap: BigInt(parsed.accountIsWritableBitmap),
82
+ tokenReceiver: decodeAddress(new Uint8Array(parsed.tokenReceiver), ChainFamily.Solana),
83
+ accounts: parsed.accounts.map((account) =>
84
+ decodeAddress(new Uint8Array(account), ChainFamily.Solana),
85
+ ),
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Converts bytes to a Move-chain address (32-byte zero-padded).
93
+ * Works for both Aptos and Sui since they share the same address format.
94
+ * @param bytes - Bytes to convert.
95
+ * @returns Address as 0x-prefixed hex string, 32 bytes padded.
96
+ * @throws {@link CCIPDataFormatUnsupportedError} if bytes length exceeds 32
97
+ */
98
+ export function getMoveAddress(bytes: BytesLike | readonly number[]): string {
99
+ let suffix = ''
100
+ if (Array.isArray(bytes)) bytes = new Uint8Array(bytes)
101
+ if (typeof bytes === 'string' && bytes.startsWith('0x')) {
102
+ const idx = bytes.indexOf('::')
103
+ if (idx > 0) {
104
+ suffix = bytes.slice(idx)
105
+ bytes = bytes.slice(0, idx)
106
+ }
107
+ }
108
+ bytes = getDataBytes(bytes)
109
+ if (bytes.length > 32)
110
+ throw new CCIPDataFormatUnsupportedError(`Move address exceeds 32 bytes: ${hexlify(bytes)}`)
111
+ return zeroPadValue(bytes, 32) + suffix
112
+ }
113
+
114
+ /**
115
+ * Encodes a numeric value as a 32-byte hex string.
116
+ * Used for BCS encoding on Move chains (Aptos/Sui).
117
+ * @param value - Numeric value to encode.
118
+ * @returns 32-byte hex string representation of the value.
119
+ */
120
+ export const encodeNumber = (value: BigNumberish): string => toBeHex(value, 32)
121
+
122
+ /**
123
+ * Encodes dynamic bytes with length prefix for BCS serialization.
124
+ * Used for BCS encoding on Move chains (Aptos/Sui).
125
+ * @param value - Bytes to encode.
126
+ * @returns Encoded bytes with 32-byte aligned padding.
127
+ */
128
+ export const encodeRawBytes = (value: BytesLike): string =>
129
+ concat([
130
+ encodeNumber(dataLength(value)),
131
+ zeroPadBytes(value, Math.ceil(dataLength(value) / 32) * 32),
132
+ ])
@@ -0,0 +1,2 @@
1
+ /** Default gas limit for cross-chain message execution (200,000 units). */
2
+ export const DEFAULT_GAS_LIMIT = 200_000n
@@ -14,7 +14,7 @@ import BN from 'bn.js'
14
14
  import { hexlify } from 'ethers'
15
15
 
16
16
  import { CCIPSolanaLookupTableNotFoundError } from '../errors/index.ts'
17
- import { type ExecutionReport, type WithLogger, ChainFamily } from '../types.ts'
17
+ import { type ExecutionInput, type WithLogger, ChainFamily } from '../types.ts'
18
18
  import { IDL as CCIP_OFFRAMP_IDL } from './idl/1.6.0/CCIP_OFFRAMP.ts'
19
19
  import { encodeSolanaOffchainTokenData } from './offchain.ts'
20
20
  import type { CCIPMessage_V1_6_Solana, UnsignedSolanaTx } from './types.ts'
@@ -43,7 +43,7 @@ export async function generateUnsignedExecuteReport(
43
43
  ctx: { connection: Connection } & WithLogger,
44
44
  payer: PublicKey,
45
45
  offramp: PublicKey,
46
- execReport: ExecutionReport<CCIPMessage_V1_6_Solana>,
46
+ execReport: ExecutionInput<CCIPMessage_V1_6_Solana>,
47
47
  opts?: { forceLookupTable?: boolean; forceBuffer?: boolean; clearLeftoverAccounts?: boolean },
48
48
  ): Promise<UnsignedSolanaTx> {
49
49
  const { connection, logger = console } = ctx
@@ -274,7 +274,7 @@ async function getManuallyExecuteInputs({
274
274
  }: {
275
275
  payer: PublicKey
276
276
  offramp: Program<typeof CCIP_OFFRAMP_IDL>
277
- execReport: ExecutionReport<CCIPMessage_V1_6_Solana>
277
+ execReport: ExecutionInput<CCIPMessage_V1_6_Solana>
278
278
  bufferId?: Buffer
279
279
  } & WithLogger) {
280
280
  const executionReport = prepareExecutionReport(execReport)
@@ -346,7 +346,7 @@ function prepareExecutionReport({
346
346
  message,
347
347
  offchainTokenData,
348
348
  proofs,
349
- }: ExecutionReport<CCIPMessage_V1_6_Solana>): IdlTypes<
349
+ }: ExecutionInput<CCIPMessage_V1_6_Solana>): IdlTypes<
350
350
  typeof CCIP_OFFRAMP_IDL
351
351
  >['ExecutionReportSingleChain'] {
352
352
  return {
@@ -3,7 +3,7 @@
3
3
  // .then((res) => res.text())
4
4
  // .then((text) => text.trim())
5
5
  export type BaseTokenPool = {
6
- version: '1.6.0'
6
+ version: '1.6.1'
7
7
  name: 'base_token_pool'
8
8
  instructions: []
9
9
  types: [
@@ -868,7 +868,7 @@ export type BaseTokenPool = {
868
868
  }
869
869
 
870
870
  export const IDL: BaseTokenPool = {
871
- version: '1.6.0',
871
+ version: '1.6.1',
872
872
  name: 'base_token_pool',
873
873
  instructions: [],
874
874
  types: [
@@ -3,7 +3,7 @@
3
3
  // .then((res) => res.text())
4
4
  // .then((text) => text.trim())
5
5
  export type BurnmintTokenPool = {
6
- version: '1.6.0'
6
+ version: '1.6.1'
7
7
  name: 'burnmint_token_pool'
8
8
  instructions: [
9
9
  {
@@ -951,7 +951,7 @@ export type BurnmintTokenPool = {
951
951
  }
952
952
 
953
953
  export const IDL: BurnmintTokenPool = {
954
- version: '1.6.0',
954
+ version: '1.6.1',
955
955
  name: 'burnmint_token_pool',
956
956
  instructions: [
957
957
  {
@@ -3,7 +3,7 @@
3
3
  // .then((res) => res.text())
4
4
  // .then((text) => text.trim())
5
5
  export type CctpTokenPool = {
6
- version: '1.6.0'
6
+ version: '1.6.1'
7
7
  name: 'cctp_token_pool'
8
8
  instructions: [
9
9
  {
@@ -1376,7 +1376,7 @@ export type CctpTokenPool = {
1376
1376
  }
1377
1377
 
1378
1378
  export const IDL: CctpTokenPool = {
1379
- version: '1.6.0',
1379
+ version: '1.6.1',
1380
1380
  name: 'cctp_token_pool',
1381
1381
  instructions: [
1382
1382
  {
@@ -3,7 +3,7 @@
3
3
  // .then((res) => res.text())
4
4
  // .then((text) => text.trim())
5
5
  export type CcipCommon = {
6
- version: '0.1.1'
6
+ version: '1.6.1'
7
7
  name: 'ccip_common'
8
8
  instructions: []
9
9
  accounts: [
@@ -102,11 +102,26 @@ export type CcipCommon = {
102
102
  name: 'InvalidSVMAddress'
103
103
  msg: 'Invalid SVM address'
104
104
  },
105
+ {
106
+ code: 10011
107
+ name: 'InvalidTVMAddress'
108
+ msg: 'Invalid TVM address'
109
+ },
110
+ {
111
+ code: 10012
112
+ name: 'InvalidAptosAddress'
113
+ msg: 'Invalid Aptos address'
114
+ },
115
+ {
116
+ code: 10013
117
+ name: 'InvalidSuiAddress'
118
+ msg: 'Invalid Sui address'
119
+ },
105
120
  ]
106
121
  }
107
122
 
108
123
  export const IDL: CcipCommon = {
109
- version: '0.1.1',
124
+ version: '1.6.1',
110
125
  name: 'ccip_common',
111
126
  instructions: [],
112
127
  accounts: [
@@ -205,6 +220,21 @@ export const IDL: CcipCommon = {
205
220
  name: 'InvalidSVMAddress',
206
221
  msg: 'Invalid SVM address',
207
222
  },
223
+ {
224
+ code: 10011,
225
+ name: 'InvalidTVMAddress',
226
+ msg: 'Invalid TVM address',
227
+ },
228
+ {
229
+ code: 10012,
230
+ name: 'InvalidAptosAddress',
231
+ msg: 'Invalid Aptos address',
232
+ },
233
+ {
234
+ code: 10013,
235
+ name: 'InvalidSuiAddress',
236
+ msg: 'Invalid Sui address',
237
+ },
208
238
  ],
209
239
  }
210
240
  // generate:end
@@ -3,7 +3,7 @@
3
3
  // .then((res) => res.text())
4
4
  // .then((text) => text.trim())
5
5
  export type CcipOfframp = {
6
- version: '0.1.1'
6
+ version: '1.6.1'
7
7
  name: 'ccip_offramp'
8
8
  constants: [
9
9
  {
@@ -2748,7 +2748,7 @@ export type CcipOfframp = {
2748
2748
  }
2749
2749
 
2750
2750
  export const IDL: CcipOfframp = {
2751
- version: '0.1.1',
2751
+ version: '1.6.1',
2752
2752
  name: 'ccip_offramp',
2753
2753
  constants: [
2754
2754
  {
@@ -8,7 +8,7 @@
8
8
  // else throw new Error('isMut is already true, no need for this workaround anymore');
9
9
  // }))
10
10
  export type CcipRouter = {
11
- version: '0.1.1'
11
+ version: '1.6.1'
12
12
  name: 'ccip_router'
13
13
  docs: [
14
14
  'The `ccip_router` module contains the implementation of the Cross-Chain Interoperability Protocol (CCIP) Router.',
@@ -2339,7 +2339,7 @@ export type CcipRouter = {
2339
2339
  }
2340
2340
 
2341
2341
  export const IDL: CcipRouter = {
2342
- version: '0.1.1',
2342
+ version: '1.6.1',
2343
2343
  name: 'ccip_router',
2344
2344
  docs: [
2345
2345
  'The `ccip_router` module contains the implementation of the Cross-Chain Interoperability Protocol (CCIP) Router.',