@chainlink/ccip-sdk 0.92.1 → 0.93.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 (223) hide show
  1. package/README.md +20 -18
  2. package/dist/api/index.d.ts +103 -0
  3. package/dist/api/index.d.ts.map +1 -0
  4. package/dist/api/index.js +141 -0
  5. package/dist/api/index.js.map +1 -0
  6. package/dist/api/types.d.ts +38 -0
  7. package/dist/api/types.d.ts.map +1 -0
  8. package/dist/api/types.js +2 -0
  9. package/dist/api/types.js.map +1 -0
  10. package/dist/aptos/index.d.ts +20 -33
  11. package/dist/aptos/index.d.ts.map +1 -1
  12. package/dist/aptos/index.js +34 -26
  13. package/dist/aptos/index.js.map +1 -1
  14. package/dist/aptos/logs.js +1 -1
  15. package/dist/aptos/logs.js.map +1 -1
  16. package/dist/aptos/token.js.map +1 -1
  17. package/dist/chain.d.ts +206 -71
  18. package/dist/chain.d.ts.map +1 -1
  19. package/dist/chain.js +89 -20
  20. package/dist/chain.js.map +1 -1
  21. package/dist/commits.d.ts +2 -2
  22. package/dist/commits.d.ts.map +1 -1
  23. package/dist/commits.js +4 -4
  24. package/dist/commits.js.map +1 -1
  25. package/dist/errors/CCIPError.d.ts.map +1 -1
  26. package/dist/errors/CCIPError.js +3 -2
  27. package/dist/errors/CCIPError.js.map +1 -1
  28. package/dist/errors/codes.d.ts +4 -1
  29. package/dist/errors/codes.d.ts.map +1 -1
  30. package/dist/errors/codes.js +6 -1
  31. package/dist/errors/codes.js.map +1 -1
  32. package/dist/errors/index.d.ts +5 -2
  33. package/dist/errors/index.d.ts.map +1 -1
  34. package/dist/errors/index.js +8 -2
  35. package/dist/errors/index.js.map +1 -1
  36. package/dist/errors/recovery.d.ts.map +1 -1
  37. package/dist/errors/recovery.js +4 -1
  38. package/dist/errors/recovery.js.map +1 -1
  39. package/dist/errors/specialized.d.ts +29 -4
  40. package/dist/errors/specialized.d.ts.map +1 -1
  41. package/dist/errors/specialized.js +48 -6
  42. package/dist/errors/specialized.js.map +1 -1
  43. package/dist/evm/errors.js.map +1 -1
  44. package/dist/evm/index.d.ts +24 -48
  45. package/dist/evm/index.d.ts.map +1 -1
  46. package/dist/evm/index.js +71 -59
  47. package/dist/evm/index.js.map +1 -1
  48. package/dist/evm/logs.js.map +1 -1
  49. package/dist/evm/offchain.js +3 -2
  50. package/dist/evm/offchain.js.map +1 -1
  51. package/dist/evm/viem/client-adapter.d.ts +68 -0
  52. package/dist/evm/viem/client-adapter.d.ts.map +1 -0
  53. package/dist/evm/viem/client-adapter.js +104 -0
  54. package/dist/evm/viem/client-adapter.js.map +1 -0
  55. package/dist/evm/viem/index.d.ts +29 -0
  56. package/dist/evm/viem/index.d.ts.map +1 -0
  57. package/dist/evm/viem/index.js +28 -0
  58. package/dist/evm/viem/index.js.map +1 -0
  59. package/dist/evm/viem/types.d.ts +13 -0
  60. package/dist/evm/viem/types.d.ts.map +1 -0
  61. package/dist/evm/viem/types.js +2 -0
  62. package/dist/evm/viem/types.js.map +1 -0
  63. package/dist/evm/viem/wallet-adapter.d.ts +58 -0
  64. package/dist/evm/viem/wallet-adapter.d.ts.map +1 -0
  65. package/dist/evm/viem/wallet-adapter.js +197 -0
  66. package/dist/evm/viem/wallet-adapter.js.map +1 -0
  67. package/dist/execution.d.ts +1 -1
  68. package/dist/execution.d.ts.map +1 -1
  69. package/dist/execution.js +2 -2
  70. package/dist/execution.js.map +1 -1
  71. package/dist/explorer.d.ts +74 -0
  72. package/dist/explorer.d.ts.map +1 -0
  73. package/dist/explorer.js +67 -0
  74. package/dist/explorer.js.map +1 -0
  75. package/dist/gas.js.map +1 -1
  76. package/dist/hasher/merklemulti.js.map +1 -1
  77. package/dist/http-status.d.ts +20 -0
  78. package/dist/http-status.d.ts.map +1 -0
  79. package/dist/http-status.js +25 -0
  80. package/dist/http-status.js.map +1 -0
  81. package/dist/index.d.ts +10 -3
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +4 -2
  84. package/dist/index.js.map +1 -1
  85. package/dist/offchain.js.map +1 -1
  86. package/dist/requests.d.ts +4 -4
  87. package/dist/requests.d.ts.map +1 -1
  88. package/dist/requests.js +6 -6
  89. package/dist/requests.js.map +1 -1
  90. package/dist/solana/cleanup.js +2 -2
  91. package/dist/solana/cleanup.js.map +1 -1
  92. package/dist/solana/exec.js +1 -5
  93. package/dist/solana/exec.js.map +1 -1
  94. package/dist/solana/index.d.ts +28 -57
  95. package/dist/solana/index.d.ts.map +1 -1
  96. package/dist/solana/index.js +66 -70
  97. package/dist/solana/index.js.map +1 -1
  98. package/dist/solana/logs.js +2 -2
  99. package/dist/solana/logs.js.map +1 -1
  100. package/dist/solana/offchain.js +3 -3
  101. package/dist/solana/offchain.js.map +1 -1
  102. package/dist/solana/send.js +1 -1
  103. package/dist/solana/send.js.map +1 -1
  104. package/dist/solana/utils.js +1 -1
  105. package/dist/solana/utils.js.map +1 -1
  106. package/dist/sui/discovery.d.ts.map +1 -1
  107. package/dist/sui/discovery.js +2 -5
  108. package/dist/sui/discovery.js.map +1 -1
  109. package/dist/sui/events.d.ts.map +1 -1
  110. package/dist/sui/events.js +1 -4
  111. package/dist/sui/events.js.map +1 -1
  112. package/dist/sui/index.d.ts +18 -29
  113. package/dist/sui/index.d.ts.map +1 -1
  114. package/dist/sui/index.js +24 -26
  115. package/dist/sui/index.js.map +1 -1
  116. package/dist/sui/manuallyExec/encoder.d.ts.map +1 -1
  117. package/dist/sui/manuallyExec/encoder.js +0 -3
  118. package/dist/sui/manuallyExec/encoder.js.map +1 -1
  119. package/dist/sui/manuallyExec/index.d.ts.map +1 -1
  120. package/dist/sui/manuallyExec/index.js +1 -2
  121. package/dist/sui/manuallyExec/index.js.map +1 -1
  122. package/dist/sui/objects.js +4 -4
  123. package/dist/sui/objects.js.map +1 -1
  124. package/dist/ton/exec.d.ts +2 -2
  125. package/dist/ton/exec.d.ts.map +1 -1
  126. package/dist/ton/exec.js.map +1 -1
  127. package/dist/ton/hasher.js +5 -5
  128. package/dist/ton/hasher.js.map +1 -1
  129. package/dist/ton/index.d.ts +54 -49
  130. package/dist/ton/index.d.ts.map +1 -1
  131. package/dist/ton/index.js +331 -236
  132. package/dist/ton/index.js.map +1 -1
  133. package/dist/ton/logs.d.ts +11 -22
  134. package/dist/ton/logs.d.ts.map +1 -1
  135. package/dist/ton/logs.js +95 -118
  136. package/dist/ton/logs.js.map +1 -1
  137. package/dist/ton/types.d.ts +9 -9
  138. package/dist/ton/types.d.ts.map +1 -1
  139. package/dist/ton/types.js +5 -9
  140. package/dist/ton/types.js.map +1 -1
  141. package/dist/ton/utils.d.ts +8 -27
  142. package/dist/ton/utils.d.ts.map +1 -1
  143. package/dist/ton/utils.js +31 -111
  144. package/dist/ton/utils.js.map +1 -1
  145. package/dist/types.d.ts +34 -0
  146. package/dist/types.d.ts.map +1 -1
  147. package/dist/types.js +30 -0
  148. package/dist/types.js.map +1 -1
  149. package/dist/utils.d.ts +6 -5
  150. package/dist/utils.d.ts.map +1 -1
  151. package/dist/utils.js +76 -52
  152. package/dist/utils.js.map +1 -1
  153. package/dist/viem.d.ts +6 -0
  154. package/dist/viem.d.ts.map +1 -0
  155. package/dist/viem.js +6 -0
  156. package/dist/viem.js.map +1 -0
  157. package/package.json +17 -2
  158. package/src/api/index.ts +167 -0
  159. package/src/api/types.ts +39 -0
  160. package/src/aptos/index.ts +57 -64
  161. package/src/aptos/logs.ts +10 -10
  162. package/src/aptos/token.ts +1 -1
  163. package/src/chain.ts +274 -97
  164. package/src/commits.ts +5 -5
  165. package/src/errors/CCIPError.ts +5 -2
  166. package/src/errors/codes.ts +8 -1
  167. package/src/errors/index.ts +15 -2
  168. package/src/errors/recovery.ts +9 -1
  169. package/src/errors/specialized.ts +61 -6
  170. package/src/evm/errors.ts +2 -2
  171. package/src/evm/index.ts +107 -120
  172. package/src/evm/logs.ts +4 -4
  173. package/src/evm/offchain.ts +5 -4
  174. package/src/evm/viem/client-adapter.ts +124 -0
  175. package/src/evm/viem/index.ts +29 -0
  176. package/src/evm/viem/types.ts +14 -0
  177. package/src/evm/viem/wallet-adapter.ts +233 -0
  178. package/src/execution.ts +9 -9
  179. package/src/explorer.ts +90 -0
  180. package/src/gas.ts +2 -2
  181. package/src/hasher/merklemulti.ts +7 -7
  182. package/src/http-status.ts +31 -0
  183. package/src/index.ts +18 -1
  184. package/src/offchain.ts +1 -1
  185. package/src/requests.ts +9 -12
  186. package/src/solana/cleanup.ts +4 -4
  187. package/src/solana/exec.ts +13 -18
  188. package/src/solana/index.ts +92 -117
  189. package/src/solana/logs.ts +8 -8
  190. package/src/solana/offchain.ts +3 -3
  191. package/src/solana/send.ts +20 -20
  192. package/src/solana/utils.ts +4 -4
  193. package/src/sui/discovery.ts +4 -10
  194. package/src/sui/events.ts +4 -8
  195. package/src/sui/index.ts +36 -48
  196. package/src/sui/manuallyExec/encoder.ts +0 -4
  197. package/src/sui/manuallyExec/index.ts +1 -3
  198. package/src/sui/objects.ts +14 -14
  199. package/src/ton/exec.ts +2 -5
  200. package/src/ton/hasher.ts +5 -5
  201. package/src/ton/index.ts +392 -316
  202. package/src/ton/logs.ts +122 -143
  203. package/src/ton/types.ts +17 -21
  204. package/src/ton/utils.ts +39 -145
  205. package/src/types.ts +36 -0
  206. package/src/utils.ts +96 -66
  207. package/src/viem.ts +5 -0
  208. package/tsconfig.json +3 -2
  209. package/dist/ton/bindings/offramp.d.ts +0 -48
  210. package/dist/ton/bindings/offramp.d.ts.map +0 -1
  211. package/dist/ton/bindings/offramp.js +0 -63
  212. package/dist/ton/bindings/offramp.js.map +0 -1
  213. package/dist/ton/bindings/onramp.d.ts +0 -40
  214. package/dist/ton/bindings/onramp.d.ts.map +0 -1
  215. package/dist/ton/bindings/onramp.js +0 -51
  216. package/dist/ton/bindings/onramp.js.map +0 -1
  217. package/dist/ton/bindings/router.d.ts +0 -47
  218. package/dist/ton/bindings/router.d.ts.map +0 -1
  219. package/dist/ton/bindings/router.js +0 -51
  220. package/dist/ton/bindings/router.js.map +0 -1
  221. package/src/ton/bindings/offramp.ts +0 -96
  222. package/src/ton/bindings/onramp.ts +0 -72
  223. package/src/ton/bindings/router.ts +0 -65
package/src/evm/index.ts CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  type Signer,
8
8
  type TransactionReceipt,
9
9
  type TransactionRequest,
10
+ type TransactionResponse,
10
11
  Contract,
11
12
  JsonRpcProvider,
12
13
  Result,
@@ -28,7 +29,7 @@ import type { TypedContract } from 'ethers-abitype'
28
29
  import { memoize } from 'micro-memoize'
29
30
  import type { PickDeep, SetRequired } from 'type-fest'
30
31
 
31
- import { type LogFilter, type TokenPoolRemote, Chain } from '../chain.ts'
32
+ import { type ChainContext, type LogFilter, type TokenPoolRemote, Chain } from '../chain.ts'
32
33
  import {
33
34
  CCIPAddressInvalidEvmError,
34
35
  CCIPBlockNotFoundError,
@@ -63,15 +64,12 @@ import {
63
64
  import type { LeafHasher } from '../hasher/common.ts'
64
65
  import { supportedChains } from '../supported-chains.ts'
65
66
  import {
66
- type AnyMessage,
67
- type CCIPCommit,
68
67
  type CCIPExecution,
69
68
  type CCIPMessage,
70
69
  type CCIPRequest,
71
70
  type ChainTransaction,
72
71
  type CommitReport,
73
72
  type ExecutionReceipt,
74
- type ExecutionReport,
75
73
  type ExecutionState,
76
74
  type Lane,
77
75
  type Log_,
@@ -118,11 +116,7 @@ import {
118
116
  parseSourceTokenData,
119
117
  } from './messages.ts'
120
118
  import { encodeEVMOffchainTokenData, fetchEVMOffchainTokenData } from './offchain.ts'
121
- import {
122
- fetchAllMessagesInBatch,
123
- fetchCCIPRequestById,
124
- fetchCCIPRequestsInTx,
125
- } from '../requests.ts'
119
+ import { getMessageById, getMessagesInBatch, getMessagesInTx } from '../requests.ts'
126
120
  import type { UnsignedEVMTx } from './types.ts'
127
121
  export type { UnsignedEVMTx }
128
122
 
@@ -159,6 +153,24 @@ function isSigner(wallet: unknown): wallet is Signer {
159
153
  )
160
154
  }
161
155
 
156
+ /**
157
+ * Submit transaction using best available method.
158
+ * Try sendTransaction() first (works with browser wallets),
159
+ * fallback to signTransaction() + broadcastTransaction() if unsupported.
160
+ */
161
+ async function submitTransaction(
162
+ wallet: Signer,
163
+ tx: TransactionRequest,
164
+ provider: JsonRpcApiProvider,
165
+ ): Promise<TransactionResponse> {
166
+ try {
167
+ return await wallet.sendTransaction(tx)
168
+ } catch {
169
+ const signed = await wallet.signTransaction(tx)
170
+ return provider.broadcastTransaction(signed)
171
+ }
172
+ }
173
+
162
174
  /**
163
175
  * EVM chain implementation supporting Ethereum-compatible networks.
164
176
  */
@@ -177,7 +189,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
177
189
  * @param provider - JSON-RPC provider for the EVM network.
178
190
  * @param network - Network information for this chain.
179
191
  */
180
- constructor(provider: JsonRpcApiProvider, network: NetworkInfo, ctx?: WithLogger) {
192
+ constructor(provider: JsonRpcApiProvider, network: NetworkInfo, ctx?: ChainContext) {
181
193
  super(network, ctx)
182
194
 
183
195
  this.provider = provider
@@ -252,7 +264,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
252
264
  * @param ctx - context containing logger.
253
265
  * @returns A new EVMChain instance.
254
266
  */
255
- static async fromProvider(provider: JsonRpcApiProvider, ctx?: WithLogger): Promise<EVMChain> {
267
+ static async fromProvider(provider: JsonRpcApiProvider, ctx?: ChainContext): Promise<EVMChain> {
256
268
  try {
257
269
  return new EVMChain(provider, networkInfo(Number((await provider.getNetwork()).chainId)), ctx)
258
270
  } catch (err) {
@@ -267,7 +279,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
267
279
  * @param ctx - context containing logger.
268
280
  * @returns A new EVMChain instance.
269
281
  */
270
- static async fromUrl(url: string, ctx?: WithLogger): Promise<EVMChain> {
282
+ static async fromUrl(url: string, ctx?: ChainContext): Promise<EVMChain> {
271
283
  return this.fromProvider(await this._getProvider(url), ctx)
272
284
  }
273
285
 
@@ -300,22 +312,22 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
300
312
  yield* getEvmLogs(filter, this)
301
313
  }
302
314
 
303
- /** {@inheritDoc Chain.fetchRequestsInTx} */
304
- async fetchRequestsInTx(tx: string | ChainTransaction): Promise<CCIPRequest[]> {
305
- return fetchCCIPRequestsInTx(this, typeof tx === 'string' ? await this.getTransaction(tx) : tx)
315
+ /** {@inheritDoc Chain.getMessagesInTx} */
316
+ async getMessagesInTx(tx: string | ChainTransaction): Promise<CCIPRequest[]> {
317
+ return getMessagesInTx(this, typeof tx === 'string' ? await this.getTransaction(tx) : tx)
306
318
  }
307
319
 
308
- /** {@inheritDoc Chain.fetchRequestById} */
309
- override fetchRequestById(
320
+ /** {@inheritDoc Chain.getMessageById} */
321
+ override getMessageById(
310
322
  messageId: string,
311
323
  onRamp?: string,
312
324
  opts?: { page?: number },
313
325
  ): Promise<CCIPRequest> {
314
- return fetchCCIPRequestById(this, messageId, { address: onRamp, ...opts })
326
+ return getMessageById(this, messageId, { address: onRamp, ...opts })
315
327
  }
316
328
 
317
- /** {@inheritDoc Chain.fetchAllMessagesInBatch} */
318
- async fetchAllMessagesInBatch<
329
+ /** {@inheritDoc Chain.getMessagesInBatch} */
330
+ getMessagesInBatch<
319
331
  R extends PickDeep<
320
332
  CCIPRequest,
321
333
  'lane' | `log.${'topics' | 'address' | 'blockNumber'}` | 'message.sequenceNumber'
@@ -330,10 +342,10 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
330
342
  // specialized getLogs filter for v1.6 CCIPMessageSent events, to filter by dest
331
343
  opts_ = {
332
344
  ...opts,
333
- topics: [[request.log.topics[0]], [toBeHex(request.lane.destChainSelector, 32)]],
345
+ topics: [[request.log.topics[0]!], [toBeHex(request.lane.destChainSelector, 32)]],
334
346
  }
335
347
  }
336
- return fetchAllMessagesInBatch(this, request, commit, opts_)
348
+ return getMessagesInBatch(this, request, commit, opts_)
337
349
  }
338
350
 
339
351
  /** {@inheritDoc Chain.typeAndVersion} */
@@ -358,8 +370,9 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
358
370
  if (!isBytesLike(log.data)) throw new CCIPLogDataInvalidError(log.data)
359
371
  let fragments
360
372
  if (log.topics?.[0]) {
361
- fragments = [requestsFragments[log.topics[0] as `0x${string}`]]
362
- if (!fragments[0]) return
373
+ const f = requestsFragments[log.topics[0] as `0x${string}`]
374
+ if (!f) return
375
+ fragments = [f]
363
376
  } else {
364
377
  fragments = Object.values(requestsFragments)
365
378
  }
@@ -369,7 +382,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
369
382
  // we don't actually use Interface instance here, `decodeEventLog` is mostly static when given a fragment
370
383
  const result = interfaces.OnRamp_v1_6.decodeEventLog(fragment, log.data, log.topics)
371
384
  message = resultToObject(result) as Record<string, unknown>
372
- if (message.message) message = message.message as Record<string, unknown>
385
+ if (message.message) message = message.message as Record<string, unknown> | undefined
373
386
  if (message) break
374
387
  } catch (_) {
375
388
  // try next fragment
@@ -399,7 +412,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
399
412
  try {
400
413
  tokenAmount = {
401
414
  ...parseSourceTokenData(
402
- (message as { sourceTokenData: string[] }).sourceTokenData[i],
415
+ (message as { sourceTokenData: string[] }).sourceTokenData[i]!,
403
416
  ),
404
417
  ...tokenAmount,
405
418
  }
@@ -513,8 +526,9 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
513
526
  if (!isBytesLike(log.data)) throw new CCIPLogDataInvalidError(log.data)
514
527
  let fragments
515
528
  if (log.topics?.[0]) {
516
- fragments = [receiptsFragments[log.topics[0] as `0x${string}`]]
517
- if (!fragments[0]) return
529
+ const f = receiptsFragments[log.topics[0] as `0x${string}`]
530
+ if (!f) return
531
+ fragments = [f]
518
532
  } else fragments = Object.values(receiptsFragments)
519
533
  for (const fragment of fragments) {
520
534
  try {
@@ -579,7 +593,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
579
593
  * @param args - Extra arguments to encode.
580
594
  * @returns Encoded extra arguments as hex string.
581
595
  */
582
- static encodeExtraArgs(args: ExtraArgs): string {
596
+ static encodeExtraArgs(args: ExtraArgs | undefined): string {
583
597
  if (!args) return '0x'
584
598
  if ('computeUnits' in args) {
585
599
  return concat([
@@ -610,9 +624,9 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
610
624
  ),
611
625
  ])
612
626
  } else if ('allowOutOfOrderExecution' in args) {
613
- if (args.gasLimit == null) args.gasLimit = DEFAULT_GAS_LIMIT
627
+ if ((args as Partial<typeof args>).gasLimit == null) args.gasLimit = DEFAULT_GAS_LIMIT
614
628
  return concat([EVMExtraArgsV2Tag, defaultAbiCoder.encode([EVMExtraArgsV2], [args])])
615
- } else if (args.gasLimit != null) {
629
+ } else if ((args as Partial<typeof args>).gasLimit != null) {
616
630
  return concat([EVMExtraArgsV1Tag, defaultAbiCoder.encode([EVMExtraArgsV1], [args])])
617
631
  }
618
632
  return '0x'
@@ -914,6 +928,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
914
928
 
915
929
  /**
916
930
  * Gets the FeeQuoter contract address for a given Router or Ramp.
931
+ * @internal
917
932
  * @param address - Router or Ramp contract address.
918
933
  * @returns FeeQuoter contract address.
919
934
  */
@@ -940,13 +955,17 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
940
955
  }
941
956
 
942
957
  /** {@inheritDoc Chain.getFee} */
943
- async getFee(router_: string, destChainSelector: bigint, message: AnyMessage): Promise<bigint> {
944
- const router = new Contract(
945
- router_,
958
+ async getFee({
959
+ router,
960
+ destChainSelector,
961
+ message,
962
+ }: Parameters<Chain['getFee']>[0]): Promise<bigint> {
963
+ const contract = new Contract(
964
+ router,
946
965
  interfaces.Router,
947
966
  this.provider,
948
967
  ) as unknown as TypedContract<typeof Router_ABI>
949
- return router.getFee(destChainSelector, {
968
+ return contract.getFee(destChainSelector, {
950
969
  receiver: zeroPadValue(getAddressBytes(message.receiver), 32),
951
970
  data: hexlify(message.data),
952
971
  tokenAmounts: message.tokenAmounts ?? [],
@@ -956,23 +975,15 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
956
975
  }
957
976
 
958
977
  /**
959
- * Generate unsigned txs for ccipSend'ing a message
960
- * @param sender - sender address
961
- * @param router - address of the Router contract
962
- * @param destChainSelector - chainSelector of destination chain
963
- * @param message - AnyMessage to send; if `fee` is not present, it'll be calculated
964
- * @param approveMax - if tokens approvals are needed, opt into approving maximum allowance
978
+ * {@inheritDoc Chain.generateUnsignedSendMessage}
965
979
  * @returns Array containing 0 or more unsigned token approvals txs (if needed at the time of
966
980
  * generation), followed by a ccipSend TransactionRequest
967
981
  */
968
982
  async generateUnsignedSendMessage(
969
- sender: string,
970
- router: string,
971
- destChainSelector: bigint,
972
- message: AnyMessage & { fee?: bigint },
973
- opts?: { approveMax?: boolean },
983
+ opts: Parameters<Chain['generateUnsignedSendMessage']>[0],
974
984
  ): Promise<UnsignedEVMTx> {
975
- if (!message.fee) message.fee = await this.getFee(router, destChainSelector, message)
985
+ const { sender, router, destChainSelector, message } = opts
986
+ if (!message.fee) message.fee = await this.getFee(opts)
976
987
  const feeToken = message.feeToken ?? ZeroAddress
977
988
  const receiver = zeroPadValue(getAddressBytes(message.receiver), 32)
978
989
  const data = hexlify(message.data)
@@ -998,7 +1009,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
998
1009
  ) as unknown as TypedContract<typeof Token_ABI>
999
1010
  const allowance = await contract.allowance(sender, router)
1000
1011
  if (allowance >= amount) return
1001
- const amnt = opts?.approveMax ? 2n ** 256n - 1n : amount
1012
+ const amnt = opts.approveMax ? 2n ** 256n - 1n : amount
1002
1013
  return contract.approve.populateTransaction(router, amnt, { from: sender })
1003
1014
  }),
1004
1015
  )
@@ -1032,25 +1043,14 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1032
1043
  }
1033
1044
 
1034
1045
  /** {@inheritDoc Chain.sendMessage} */
1035
- async sendMessage(
1036
- router_: string,
1037
- destChainSelector: bigint,
1038
- message: AnyMessage & { fee?: bigint },
1039
- opts: { wallet: unknown; approveMax?: boolean },
1040
- ): Promise<CCIPRequest> {
1046
+ async sendMessage(opts: Parameters<Chain['sendMessage']>[0]): Promise<CCIPRequest> {
1041
1047
  const wallet = opts.wallet
1042
1048
  if (!isSigner(wallet)) throw new CCIPWalletInvalidError(wallet)
1043
1049
 
1044
1050
  const sender = await wallet.getAddress()
1045
- const txs = await this.generateUnsignedSendMessage(
1046
- sender,
1047
- router_,
1048
- destChainSelector,
1049
- message,
1050
- opts,
1051
- )
1051
+ const txs = await this.generateUnsignedSendMessage({ ...opts, sender })
1052
1052
  const approveTxs = txs.transactions.slice(0, txs.transactions.length - 1)
1053
- let sendTx: TransactionRequest = txs.transactions[txs.transactions.length - 1]
1053
+ let sendTx: TransactionRequest = txs.transactions[txs.transactions.length - 1]!
1054
1054
 
1055
1055
  // approve all tokens (including feeToken, if needed) in parallel
1056
1056
  let nonce = await this.provider.getTransactionCount(sender)
@@ -1059,44 +1059,37 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1059
1059
  tx.nonce = nonce++
1060
1060
  tx = await wallet.populateTransaction(tx)
1061
1061
  tx.from = undefined
1062
- const signed = await wallet.signTransaction(tx)
1063
- const response = await this.provider.broadcastTransaction(signed)
1062
+ const response = await submitTransaction(wallet, tx, this.provider)
1064
1063
  this.logger.debug('approve =>', response.hash)
1065
1064
  return response
1066
1065
  }),
1067
1066
  )
1068
- if (responses.length) await responses[responses.length - 1].wait(1, 60_000) // wait last tx nonce to be mined
1067
+ if (responses.length) await responses[responses.length - 1]!.wait(1, 60_000) // wait last tx nonce to be mined
1069
1068
 
1070
1069
  sendTx.nonce = nonce++
1071
1070
  // sendTx.gasLimit = await this.provider.estimateGas(sendTx)
1072
1071
  sendTx = await wallet.populateTransaction(sendTx)
1073
1072
  sendTx.from = undefined // some signers don't like receiving pre-populated `from`
1074
- const signed = await wallet.signTransaction(sendTx)
1075
- const response = await this.provider.broadcastTransaction(signed)
1073
+ const response = await submitTransaction(wallet, sendTx, this.provider)
1076
1074
  this.logger.debug('ccipSend =>', response.hash)
1077
1075
  await response.wait(1, 60_000)
1078
- return (await this.fetchRequestsInTx(await this.getTransaction(response.hash)))[0]
1076
+ return (await this.getMessagesInTx(await this.getTransaction(response.hash)))[0]!
1079
1077
  }
1080
1078
 
1081
- /** {@inheritDoc Chain.fetchOffchainTokenData} */
1082
- fetchOffchainTokenData(request: CCIPRequest): Promise<OffchainTokenData[]> {
1079
+ /** {@inheritDoc Chain.getOffchainTokenData} */
1080
+ getOffchainTokenData(request: CCIPRequest): Promise<OffchainTokenData[]> {
1083
1081
  return fetchEVMOffchainTokenData(request, this)
1084
1082
  }
1085
1083
 
1086
1084
  /**
1087
- * Generate unsigned tx to manuallyExecute a message
1088
- * @param _payer - not used in EVM
1089
- * @param offRamp - address of the OffRamp contract
1090
- * @param execReport - execution report
1091
- * @param opts - gas limit overrides for ccipReceive and tokenPool calls options
1085
+ * {@inheritDoc Chain.generateUnsignedExecuteReport}
1092
1086
  * @returns array containing one unsigned `manuallyExecute` TransactionRequest object
1093
1087
  */
1094
- async generateUnsignedExecuteReport(
1095
- _payer: string,
1096
- offRamp: string,
1097
- execReport: ExecutionReport,
1098
- opts: { gasLimit?: number; tokensGasLimit?: number },
1099
- ): Promise<UnsignedEVMTx> {
1088
+ async generateUnsignedExecuteReport({
1089
+ offRamp,
1090
+ execReport,
1091
+ ...opts
1092
+ }: Parameters<Chain['generateUnsignedExecuteReport']>[0]): Promise<UnsignedEVMTx> {
1100
1093
  const [_, version] = await this.typeAndVersion(offRamp)
1101
1094
 
1102
1095
  let manualExecTx
@@ -1109,7 +1102,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1109
1102
  EVM2EVMOffRamp_1_2_ABI,
1110
1103
  this.provider,
1111
1104
  ) as unknown as TypedContract<typeof EVM2EVMOffRamp_1_2_ABI>
1112
- const gasOverride = BigInt(opts?.gasLimit ?? 0)
1105
+ const gasOverride = BigInt(opts.gasLimit ?? 0)
1113
1106
  manualExecTx = await contract.manuallyExecute.populateTransaction(
1114
1107
  {
1115
1108
  ...execReport,
@@ -1136,9 +1129,9 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1136
1129
  },
1137
1130
  [
1138
1131
  {
1139
- receiverExecutionGasLimit: BigInt(opts?.gasLimit ?? 0),
1132
+ receiverExecutionGasLimit: BigInt(opts.gasLimit ?? 0),
1140
1133
  tokenGasOverrides: execReport.message.tokenAmounts.map(() =>
1141
- BigInt(opts?.tokensGasLimit ?? opts?.gasLimit ?? 0),
1134
+ BigInt(opts.tokensGasLimit ?? opts.gasLimit ?? 0),
1142
1135
  ),
1143
1136
  },
1144
1137
  ],
@@ -1189,9 +1182,9 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1189
1182
  [
1190
1183
  [
1191
1184
  {
1192
- receiverExecutionGasLimit: BigInt(opts?.gasLimit ?? 0),
1185
+ receiverExecutionGasLimit: BigInt(opts.gasLimit ?? 0),
1193
1186
  tokenGasOverrides: execReport.message.tokenAmounts.map(() =>
1194
- BigInt(opts?.tokensGasLimit ?? opts?.gasLimit ?? 0),
1187
+ BigInt(opts.tokensGasLimit ?? opts.gasLimit ?? 0),
1195
1188
  ),
1196
1189
  },
1197
1190
  ],
@@ -1206,29 +1199,23 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1206
1199
  }
1207
1200
 
1208
1201
  /** {@inheritDoc Chain.executeReport} */
1209
- async executeReport(
1210
- offRamp: string,
1211
- execReport: ExecutionReport,
1212
- opts: { wallet: unknown; gasLimit?: number; tokensGasLimit?: number },
1213
- ) {
1202
+ async executeReport(opts: Parameters<Chain['executeReport']>[0]) {
1214
1203
  const wallet = opts.wallet
1215
1204
  if (!isSigner(wallet)) throw new CCIPWalletInvalidError(wallet)
1216
1205
 
1217
- const unsignedTxs = await this.generateUnsignedExecuteReport(
1218
- await wallet.getAddress(),
1219
- offRamp,
1220
- execReport,
1221
- opts,
1222
- )
1223
- const unsignedTx = await wallet.populateTransaction(unsignedTxs.transactions[0])
1206
+ const unsignedTxs = await this.generateUnsignedExecuteReport({
1207
+ ...opts,
1208
+ payer: await wallet.getAddress(),
1209
+ })
1210
+ const unsignedTx = await wallet.populateTransaction(unsignedTxs.transactions[0]!)
1224
1211
  unsignedTx.from = undefined // some signers don't like receiving pre-populated `from`
1225
- const signed = await wallet.signTransaction(unsignedTx)
1226
- const response = await this.provider.broadcastTransaction(signed)
1227
- this.logger.debug('ccipSend =>', response.hash)
1212
+ const response = await submitTransaction(wallet, unsignedTx, this.provider)
1213
+ this.logger.debug('manuallyExecute =>', response.hash)
1228
1214
  const receipt = await response.wait(1, 60_000)
1229
1215
  if (!receipt?.hash) throw new CCIPExecTxNotConfirmedError(response.hash)
1230
1216
  if (!receipt.status) throw new CCIPExecTxRevertedError(response.hash)
1231
- return this.getTransaction(receipt)
1217
+ const tx = await this.getTransaction(receipt)
1218
+ return this.getExecutionReceiptInTx(tx)
1232
1219
  }
1233
1220
 
1234
1221
  /**
@@ -1324,7 +1311,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1324
1311
  ): Promise<Record<string, TokenPoolRemote>> {
1325
1312
  const [_, version] = await this.typeAndVersion(tokenPool)
1326
1313
 
1327
- let supportedChains: Promise<NetworkInfo[]>
1314
+ let supportedChains: Promise<NetworkInfo[]> | undefined
1328
1315
  if (remoteChainSelector) supportedChains = Promise.resolve([networkInfo(remoteChainSelector)])
1329
1316
 
1330
1317
  let remotePools: Promise<string[][]>
@@ -1383,10 +1370,10 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1383
1370
  [
1384
1371
  chain.name,
1385
1372
  {
1386
- remoteToken: decodeAddress(remoteInfo[i][0], chain.family),
1387
- remotePools: remotePools[i].map((pool) => decodeAddress(pool, chain.family)),
1388
- inboundRateLimiterState: remoteInfo[i][1].isEnabled ? remoteInfo[i][1] : null,
1389
- outboundRateLimiterState: remoteInfo[i][2].isEnabled ? remoteInfo[i][2] : null,
1373
+ remoteToken: decodeAddress(remoteInfo[i]![0], chain.family),
1374
+ remotePools: remotePools[i]!.map((pool) => decodeAddress(pool, chain.family)),
1375
+ inboundRateLimiterState: remoteInfo[i]![1].isEnabled ? remoteInfo[i]![1] : null,
1376
+ outboundRateLimiterState: remoteInfo[i]![2].isEnabled ? remoteInfo[i]![2] : null,
1390
1377
  },
1391
1378
  ] as const,
1392
1379
  ),
@@ -1399,7 +1386,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1399
1386
  const onRamp = await this._getSomeOnRampFor(router)
1400
1387
  const [_, version] = await this.typeAndVersion(onRamp)
1401
1388
  let tokens
1402
- let onRampIface: Interface
1389
+ let onRampIface: Interface | undefined
1403
1390
  switch (version) {
1404
1391
  case CCIPVersion.V1_2:
1405
1392
  onRampIface = interfaces.EVM2EVMOnRamp_v1_2
@@ -1447,21 +1434,21 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1447
1434
  )
1448
1435
  }
1449
1436
 
1450
- /** {@inheritDoc Chain.fetchExecutionReceipts} */
1451
- override async *fetchExecutionReceipts(
1452
- offRamp: string,
1453
- request: PickDeep<CCIPRequest, 'lane' | 'message.messageId' | 'tx.timestamp'>,
1454
- commit?: CCIPCommit,
1455
- opts?: Pick<LogFilter, 'page' | 'watch'>,
1437
+ /** {@inheritDoc Chain.getExecutionReceipts} */
1438
+ override async *getExecutionReceipts(
1439
+ opts: Parameters<Chain['getExecutionReceipts']>[0],
1456
1440
  ): AsyncIterableIterator<CCIPExecution> {
1457
- let opts_: Parameters<EVMChain['getLogs']>[0] | undefined = opts
1458
- if (request.lane.version < CCIPVersion.V1_6) {
1441
+ const { messageId, sourceChainSelector } = opts
1442
+ let opts_: Parameters<Chain['getExecutionReceipts']>[0] & Parameters<EVMChain['getLogs']>[0] =
1443
+ opts
1444
+ const [, version] = await this.typeAndVersion(opts.offRamp)
1445
+ if (version < CCIPVersion.V1_6) {
1459
1446
  opts_ = {
1460
1447
  ...opts,
1461
1448
  topics: [
1462
1449
  interfaces.EVM2EVMOffRamp_v1_5.getEvent('ExecutionStateChanged')!.topicHash,
1463
1450
  null,
1464
- request.message.messageId,
1451
+ messageId ?? null,
1465
1452
  ],
1466
1453
  // onlyFallback: false,
1467
1454
  }
@@ -1470,13 +1457,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
1470
1457
  ...opts,
1471
1458
  topics: [
1472
1459
  interfaces.OffRamp_v1_6.getEvent('ExecutionStateChanged')!.topicHash,
1473
- toBeHex(request.lane.sourceChainSelector, 32),
1460
+ sourceChainSelector ? toBeHex(sourceChainSelector, 32) : null,
1474
1461
  null,
1475
- request.message.messageId,
1462
+ messageId ?? null,
1476
1463
  ],
1477
1464
  // onlyFallback: false,
1478
1465
  }
1479
1466
  }
1480
- yield* super.fetchExecutionReceipts(offRamp, request, commit, opts_)
1467
+ yield* super.getExecutionReceipts(opts_)
1481
1468
  }
1482
1469
  }
package/src/evm/logs.ts CHANGED
@@ -62,7 +62,7 @@ function anyPromiseMax<T>(
62
62
  const currentIndex = index++
63
63
  inFlight++
64
64
 
65
- void promises[currentIndex]()
65
+ void promises[currentIndex]!()
66
66
  .then(resolve)
67
67
  .catch((error) => {
68
68
  errors[currentIndex] = error
@@ -114,7 +114,7 @@ async function getFallbackArchiveLogs(
114
114
  let cancel$ = new Promise<unknown>((resolve) => (cancel = resolve))
115
115
  if (destroy$) cancel$ = Promise.race([destroy$, cancel$])
116
116
 
117
- let winner: string
117
+ let winner: string | undefined
118
118
  const providerLogs$ = getFallbackRpcsList()
119
119
  .then((rpcs) => {
120
120
  const rpc = rpcs.find(({ chainId: id }) => id === chainId)
@@ -268,7 +268,7 @@ export async function* getEvmLogs(
268
268
  logger.debug('evm getLogs:', filter_)
269
269
  const logs = await provider.getLogs(filter_)
270
270
  if (logs.length)
271
- latestLogBlockNumber = Math.max(latestLogBlockNumber, logs[logs.length - 1].blockNumber)
271
+ latestLogBlockNumber = Math.max(latestLogBlockNumber, logs[logs.length - 1]!.blockNumber)
272
272
  if (filter.startBlock == null) logs.reverse()
273
273
  yield* logs
274
274
  }
@@ -297,7 +297,7 @@ export async function* getEvmLogs(
297
297
  logger.debug('evm watch getLogs:', filter_)
298
298
  const logs = await provider.getLogs(filter_)
299
299
  if (logs.length)
300
- latestLogBlockNumber = Math.max(latestLogBlockNumber, logs[logs.length - 1].blockNumber)
300
+ latestLogBlockNumber = Math.max(latestLogBlockNumber, logs[logs.length - 1]!.blockNumber)
301
301
  yield* logs
302
302
  }
303
303
  }
@@ -40,7 +40,7 @@ export async function fetchEVMOffchainTokenData(
40
40
  // any USDC logs after that and before our CCIPSendRequested
41
41
  const prevCcipRequestIdx =
42
42
  request.tx.logs.find(
43
- ({ topics, index }) => topics[0] in requestsFragments && index < request.log.index,
43
+ ({ topics, index }) => topics[0]! in requestsFragments && index < request.log.index,
44
44
  )?.index ?? -1
45
45
  const usdcRequestLogs = request.tx.logs.filter(
46
46
  ({ index }) => prevCcipRequestIdx < index && index < request.log.index,
@@ -118,8 +118,9 @@ async function getUsdcTokenData(
118
118
  const poolLog = arr[i + 2]
119
119
  if (
120
120
  log.topics[0] !== USDC_EVENT.topicHash ||
121
- transferLog?.topics?.[0] !== TRANSFER_EVENT.topicHash ||
122
- !BURNED_EVENT_TOPIC_HASHES.has(poolLog?.topics?.[0])
121
+ transferLog?.topics[0] !== TRANSFER_EVENT.topicHash ||
122
+ !poolLog?.topics.length ||
123
+ !BURNED_EVENT_TOPIC_HASHES.has(poolLog.topics[0]!)
123
124
  ) {
124
125
  return acc
125
126
  }
@@ -179,7 +180,7 @@ async function getLbtcTokenData(
179
180
  ): Promise<OffchainTokenData[]> {
180
181
  const lbtcDepositHashes = new Set(
181
182
  allLogsInRequest
182
- .filter(({ topics }) => LBTC_EVENTS_HASHES.has(topics[0]))
183
+ .filter(({ topics }) => LBTC_EVENTS_HASHES.has(topics[0]!))
183
184
  .map(({ topics }) => topics[3]),
184
185
  )
185
186
  return Promise.all(