@chainlink/ccip-sdk 0.96.0 → 0.97.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 (199) hide show
  1. package/dist/api/index.d.ts +17 -8
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/index.js +27 -10
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/types.d.ts +0 -2
  6. package/dist/api/types.d.ts.map +1 -1
  7. package/dist/aptos/exec.d.ts +2 -2
  8. package/dist/aptos/exec.d.ts.map +1 -1
  9. package/dist/aptos/exec.js.map +1 -1
  10. package/dist/aptos/hasher.d.ts.map +1 -1
  11. package/dist/aptos/hasher.js +1 -1
  12. package/dist/aptos/hasher.js.map +1 -1
  13. package/dist/aptos/index.d.ts +13 -10
  14. package/dist/aptos/index.d.ts.map +1 -1
  15. package/dist/aptos/index.js +42 -68
  16. package/dist/aptos/index.js.map +1 -1
  17. package/dist/aptos/types.d.ts +2 -19
  18. package/dist/aptos/types.d.ts.map +1 -1
  19. package/dist/aptos/types.js +0 -11
  20. package/dist/aptos/types.js.map +1 -1
  21. package/dist/chain.d.ts +532 -151
  22. package/dist/chain.d.ts.map +1 -1
  23. package/dist/chain.js +113 -18
  24. package/dist/chain.js.map +1 -1
  25. package/dist/commits.d.ts +4 -6
  26. package/dist/commits.d.ts.map +1 -1
  27. package/dist/commits.js +4 -4
  28. package/dist/commits.js.map +1 -1
  29. package/dist/errors/CCIPError.d.ts +33 -4
  30. package/dist/errors/CCIPError.d.ts.map +1 -1
  31. package/dist/errors/CCIPError.js +33 -4
  32. package/dist/errors/CCIPError.js.map +1 -1
  33. package/dist/errors/codes.d.ts +3 -0
  34. package/dist/errors/codes.d.ts.map +1 -1
  35. package/dist/errors/codes.js +3 -1
  36. package/dist/errors/codes.js.map +1 -1
  37. package/dist/errors/index.d.ts +1 -1
  38. package/dist/errors/index.d.ts.map +1 -1
  39. package/dist/errors/index.js +1 -1
  40. package/dist/errors/index.js.map +1 -1
  41. package/dist/errors/recovery.d.ts.map +1 -1
  42. package/dist/errors/recovery.js +4 -1
  43. package/dist/errors/recovery.js.map +1 -1
  44. package/dist/errors/specialized.d.ts +1695 -120
  45. package/dist/errors/specialized.d.ts.map +1 -1
  46. package/dist/errors/specialized.js +1715 -123
  47. package/dist/errors/specialized.js.map +1 -1
  48. package/dist/errors/utils.d.ts.map +1 -1
  49. package/dist/errors/utils.js +0 -1
  50. package/dist/errors/utils.js.map +1 -1
  51. package/dist/evm/abi/OffRamp_2_0.d.ts +764 -0
  52. package/dist/evm/abi/OffRamp_2_0.d.ts.map +1 -0
  53. package/dist/evm/abi/OffRamp_2_0.js +744 -0
  54. package/dist/evm/abi/OffRamp_2_0.js.map +1 -0
  55. package/dist/evm/abi/OnRamp_2_0.d.ts +925 -0
  56. package/dist/evm/abi/OnRamp_2_0.d.ts.map +1 -0
  57. package/dist/evm/abi/OnRamp_2_0.js +992 -0
  58. package/dist/evm/abi/OnRamp_2_0.js.map +1 -0
  59. package/dist/evm/const.d.ts +12 -2
  60. package/dist/evm/const.d.ts.map +1 -1
  61. package/dist/evm/const.js +8 -2
  62. package/dist/evm/const.js.map +1 -1
  63. package/dist/evm/errors.d.ts.map +1 -1
  64. package/dist/evm/errors.js +7 -2
  65. package/dist/evm/errors.js.map +1 -1
  66. package/dist/evm/extra-args.d.ts.map +1 -1
  67. package/dist/evm/extra-args.js +5 -24
  68. package/dist/evm/extra-args.js.map +1 -1
  69. package/dist/evm/hasher.d.ts.map +1 -1
  70. package/dist/evm/hasher.js +23 -13
  71. package/dist/evm/hasher.js.map +1 -1
  72. package/dist/evm/index.d.ts +73 -14
  73. package/dist/evm/index.d.ts.map +1 -1
  74. package/dist/evm/index.js +240 -141
  75. package/dist/evm/index.js.map +1 -1
  76. package/dist/evm/messages.d.ts +59 -5
  77. package/dist/evm/messages.d.ts.map +1 -1
  78. package/dist/evm/messages.js +210 -0
  79. package/dist/evm/messages.js.map +1 -1
  80. package/dist/evm/offchain.js.map +1 -1
  81. package/dist/evm/types.d.ts +7 -2
  82. package/dist/evm/types.d.ts.map +1 -1
  83. package/dist/evm/types.js +22 -1
  84. package/dist/evm/types.js.map +1 -1
  85. package/dist/execution.d.ts +62 -22
  86. package/dist/execution.d.ts.map +1 -1
  87. package/dist/execution.js +98 -61
  88. package/dist/execution.js.map +1 -1
  89. package/dist/extra-args.d.ts +13 -3
  90. package/dist/extra-args.d.ts.map +1 -1
  91. package/dist/extra-args.js +13 -3
  92. package/dist/extra-args.js.map +1 -1
  93. package/dist/gas.d.ts +25 -2
  94. package/dist/gas.d.ts.map +1 -1
  95. package/dist/gas.js +30 -4
  96. package/dist/gas.js.map +1 -1
  97. package/dist/index.d.ts +1 -1
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/requests.d.ts +85 -14
  100. package/dist/requests.d.ts.map +1 -1
  101. package/dist/requests.js +99 -16
  102. package/dist/requests.js.map +1 -1
  103. package/dist/selectors.d.ts.map +1 -1
  104. package/dist/selectors.js +12 -0
  105. package/dist/selectors.js.map +1 -1
  106. package/dist/shared/bcs-codecs.d.ts +61 -0
  107. package/dist/shared/bcs-codecs.d.ts.map +1 -0
  108. package/dist/shared/bcs-codecs.js +102 -0
  109. package/dist/shared/bcs-codecs.js.map +1 -0
  110. package/dist/shared/constants.d.ts +3 -0
  111. package/dist/shared/constants.d.ts.map +1 -0
  112. package/dist/shared/constants.js +3 -0
  113. package/dist/shared/constants.js.map +1 -0
  114. package/dist/solana/exec.d.ts +2 -2
  115. package/dist/solana/exec.d.ts.map +1 -1
  116. package/dist/solana/exec.js.map +1 -1
  117. package/dist/solana/index.d.ts +80 -17
  118. package/dist/solana/index.d.ts.map +1 -1
  119. package/dist/solana/index.js +67 -30
  120. package/dist/solana/index.js.map +1 -1
  121. package/dist/sui/hasher.d.ts.map +1 -1
  122. package/dist/sui/hasher.js +1 -1
  123. package/dist/sui/hasher.js.map +1 -1
  124. package/dist/sui/index.d.ts +14 -12
  125. package/dist/sui/index.d.ts.map +1 -1
  126. package/dist/sui/index.js +38 -34
  127. package/dist/sui/index.js.map +1 -1
  128. package/dist/sui/manuallyExec/encoder.d.ts +2 -2
  129. package/dist/sui/manuallyExec/encoder.d.ts.map +1 -1
  130. package/dist/sui/manuallyExec/encoder.js.map +1 -1
  131. package/dist/sui/manuallyExec/index.d.ts +2 -2
  132. package/dist/sui/manuallyExec/index.d.ts.map +1 -1
  133. package/dist/ton/exec.d.ts +2 -2
  134. package/dist/ton/exec.d.ts.map +1 -1
  135. package/dist/ton/exec.js.map +1 -1
  136. package/dist/ton/index.d.ts +9 -16
  137. package/dist/ton/index.d.ts.map +1 -1
  138. package/dist/ton/index.js +26 -31
  139. package/dist/ton/index.js.map +1 -1
  140. package/dist/ton/types.d.ts +2 -2
  141. package/dist/ton/types.d.ts.map +1 -1
  142. package/dist/ton/types.js.map +1 -1
  143. package/dist/types.d.ts +46 -11
  144. package/dist/types.d.ts.map +1 -1
  145. package/dist/types.js +6 -1
  146. package/dist/types.js.map +1 -1
  147. package/dist/utils.d.ts +65 -2
  148. package/dist/utils.d.ts.map +1 -1
  149. package/dist/utils.js +74 -2
  150. package/dist/utils.js.map +1 -1
  151. package/package.json +9 -9
  152. package/src/api/index.ts +33 -10
  153. package/src/api/types.ts +0 -2
  154. package/src/aptos/exec.ts +2 -2
  155. package/src/aptos/hasher.ts +1 -1
  156. package/src/aptos/index.ts +51 -89
  157. package/src/aptos/types.ts +2 -15
  158. package/src/chain.ts +581 -163
  159. package/src/commits.ts +9 -9
  160. package/src/errors/CCIPError.ts +33 -4
  161. package/src/errors/codes.ts +3 -1
  162. package/src/errors/index.ts +1 -0
  163. package/src/errors/recovery.ts +7 -1
  164. package/src/errors/specialized.ts +1726 -130
  165. package/src/errors/utils.ts +0 -1
  166. package/src/evm/abi/OffRamp_2_0.ts +743 -0
  167. package/src/evm/abi/OnRamp_2_0.ts +991 -0
  168. package/src/evm/const.ts +10 -3
  169. package/src/evm/errors.ts +6 -2
  170. package/src/evm/extra-args.ts +4 -21
  171. package/src/evm/hasher.ts +30 -18
  172. package/src/evm/index.ts +310 -166
  173. package/src/evm/messages.ts +323 -11
  174. package/src/evm/offchain.ts +2 -2
  175. package/src/evm/types.ts +20 -2
  176. package/src/execution.ts +125 -86
  177. package/src/extra-args.ts +13 -3
  178. package/src/gas.ts +29 -3
  179. package/src/index.ts +2 -2
  180. package/src/requests.ts +112 -16
  181. package/src/selectors.ts +12 -0
  182. package/src/shared/bcs-codecs.ts +132 -0
  183. package/src/shared/constants.ts +2 -0
  184. package/src/solana/exec.ts +4 -4
  185. package/src/solana/index.ts +100 -68
  186. package/src/sui/hasher.ts +1 -1
  187. package/src/sui/index.ts +50 -47
  188. package/src/sui/manuallyExec/encoder.ts +2 -2
  189. package/src/sui/manuallyExec/index.ts +2 -2
  190. package/src/ton/exec.ts +2 -2
  191. package/src/ton/index.ts +37 -40
  192. package/src/ton/types.ts +2 -2
  193. package/src/types.ts +70 -29
  194. package/src/utils.ts +73 -2
  195. package/dist/aptos/utils.d.ts +0 -12
  196. package/dist/aptos/utils.d.ts.map +0 -1
  197. package/dist/aptos/utils.js +0 -15
  198. package/dist/aptos/utils.js.map +0 -1
  199. package/src/aptos/utils.ts +0 -24
package/src/chain.ts CHANGED
@@ -3,7 +3,7 @@ import type { PickDeep, SetOptional } from 'type-fest'
3
3
 
4
4
  import { type LaneLatencyResponse, CCIPAPIClient } from './api/index.ts'
5
5
  import type { UnsignedAptosTx } from './aptos/types.ts'
6
- import { getCommitReport } from './commits.ts'
6
+ import { getOnchainCommitReport } from './commits.ts'
7
7
  import {
8
8
  CCIPApiClientNotAvailableError,
9
9
  CCIPChainFamilyMismatchError,
@@ -11,8 +11,8 @@ import {
11
11
  CCIPTokenPoolChainConfigNotFoundError,
12
12
  CCIPTransactionNotFinalizedError,
13
13
  } from './errors/index.ts'
14
- import { DEFAULT_GAS_LIMIT } from './evm/const.ts'
15
14
  import type { UnsignedEVMTx } from './evm/types.ts'
15
+ import { calculateManualExecProof } from './execution.ts'
16
16
  import type {
17
17
  EVMExtraArgsV1,
18
18
  EVMExtraArgsV2,
@@ -23,19 +23,21 @@ import type {
23
23
  } from './extra-args.ts'
24
24
  import type { LeafHasher } from './hasher/common.ts'
25
25
  import { getMessagesInTx } from './requests.ts'
26
+ import { DEFAULT_GAS_LIMIT } from './shared/constants.ts'
26
27
  import type { UnsignedSolanaTx } from './solana/types.ts'
27
28
  import type { UnsignedTONTx } from './ton/types.ts'
28
29
  import {
29
30
  type AnyMessage,
30
- type CCIPCommit,
31
31
  type CCIPExecution,
32
32
  type CCIPMessage,
33
33
  type CCIPRequest,
34
+ type CCIPVerifications,
35
+ type CCIPVersion,
34
36
  type ChainFamily,
35
37
  type ChainTransaction,
36
38
  type CommitReport,
39
+ type ExecutionInput,
37
40
  type ExecutionReceipt,
38
- type ExecutionReport,
39
41
  type Lane,
40
42
  type Log_,
41
43
  type Logger,
@@ -76,7 +78,7 @@ function hasV3ExtraArgs(extraArgs: Partial<ExtraArgs> | undefined): boolean {
76
78
  *
77
79
  * @example Custom API endpoint
78
80
  * ```typescript
79
- * const api = new CCIPAPIClient('https://staging-api.example.com', { logger })
81
+ * const api = CCIPAPIClient.fromUrl('https://staging-api.example.com', { logger })
80
82
  * const chain = await EVMChain.fromUrl(rpcUrl, { apiClient: api, logger })
81
83
  * ```
82
84
  *
@@ -298,13 +300,23 @@ export type SendMessageOpts = {
298
300
  }
299
301
 
300
302
  /**
301
- * Common options for {@link Chain.generateUnsignedExecuteReport} and {@link Chain.executeReport} methods.
303
+ * Common options for {@link Chain.generateUnsignedExecute} and {@link Chain.execute} methods.
302
304
  */
303
- export type ExecuteReportOpts = {
304
- /** address of the OffRamp contract */
305
- offRamp: string
306
- /** execution report */
307
- execReport: ExecutionReport
305
+ export type ExecuteOpts = (
306
+ | {
307
+ /** address of the OffRamp contract */
308
+ offRamp: string
309
+ /** input payload to execute message; contains proofs for v1 and verifications for v2 */
310
+ input: ExecutionInput
311
+ }
312
+ | {
313
+ /**
314
+ * messageId of message to execute; requires `apiClient`.
315
+ * @remarks Currently throws CCIPNotImplementedError - API endpoint pending.
316
+ */
317
+ messageId: string
318
+ }
319
+ ) & {
308
320
  /** gasLimit or computeUnits limit override for the ccipReceive call */
309
321
  gasLimit?: number
310
322
  /** For EVM, overrides gasLimit on tokenPool call */
@@ -353,7 +365,7 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
353
365
  this.apiClient = apiClient // Use provided instance
354
366
  this.apiRetryConfig = { ...DEFAULT_API_RETRY_CONFIG, ...apiRetryConfig }
355
367
  } else {
356
- this.apiClient = new CCIPAPIClient(undefined, { logger }) // Default
368
+ this.apiClient = CCIPAPIClient.fromUrl(undefined, { logger }) // Default
357
369
  this.apiRetryConfig = { ...DEFAULT_API_RETRY_CONFIG, ...apiRetryConfig }
358
370
  }
359
371
  }
@@ -367,24 +379,63 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
367
379
  }
368
380
 
369
381
  /**
370
- * Fetch the timestamp of a given block
371
- * @param block - positive block number, negative finality depth or 'finalized' tag
372
- * @returns timestamp of the block, in seconds
382
+ * Fetch the timestamp of a given block.
383
+ *
384
+ * @param block - Positive block number, negative finality depth, or 'finalized' tag
385
+ * @returns Promise resolving to timestamp of the block, in seconds
386
+ *
373
387
  * @throws {@link CCIPBlockNotFoundError} if block does not exist
388
+ *
389
+ * @example Get finalized block timestamp
390
+ * ```typescript
391
+ * const chain = await EVMChain.fromUrl('https://eth-mainnet.example.com')
392
+ * const timestamp = await chain.getBlockTimestamp('finalized')
393
+ * console.log(`Finalized at: ${new Date(timestamp * 1000).toISOString()}`)
394
+ * ```
374
395
  */
375
396
  abstract getBlockTimestamp(block: number | 'finalized'): Promise<number>
376
397
  /**
377
- * Fetch a transaction by its hash
378
- * @param hash - transaction hash
379
- * @returns generic transaction details
380
- * @throws {@link CCIPTransactionNotFoundError} if transaction not found
398
+ * Fetch a transaction by its hash.
399
+ *
400
+ * @param hash - Transaction hash
401
+ * @returns Promise resolving to generic transaction details
402
+ *
403
+ * @throws {@link CCIPTransactionNotFoundError} if transaction does not exist (transient)
404
+ *
405
+ * @example Fetch transaction details
406
+ * ```typescript
407
+ * const chain = await EVMChain.fromUrl('https://eth-mainnet.example.com')
408
+ * try {
409
+ * const tx = await chain.getTransaction('0xabc123...')
410
+ * console.log(`Block: ${tx.blockNumber}, Timestamp: ${tx.timestamp}`)
411
+ * } catch (err) {
412
+ * if (err instanceof CCIPTransactionNotFoundError && err.isTransient) {
413
+ * // Transaction may be pending
414
+ * }
415
+ * }
416
+ * ```
381
417
  */
382
418
  abstract getTransaction(hash: string): Promise<ChainTransaction>
383
419
  /**
384
420
  * Confirm a log tx is finalized or wait for it to be finalized.
421
+ *
385
422
  * @param opts - Options containing the request, finality level, and optional cancel promise
386
423
  * @returns true when the transaction is finalized
424
+ *
387
425
  * @throws {@link CCIPTransactionNotFinalizedError} if the transaction is not included (e.g., due to a reorg)
426
+ *
427
+ * @example Wait for message finality
428
+ * ```typescript
429
+ * const request = await source.getMessagesInTx(txHash)
430
+ * try {
431
+ * await source.waitFinalized({ request: request[0] })
432
+ * console.log('Transaction finalized')
433
+ * } catch (err) {
434
+ * if (err instanceof CCIPTransactionNotFinalizedError) {
435
+ * console.log('Transaction not yet finalized')
436
+ * }
437
+ * }
438
+ * ```
388
439
  */
389
440
  async waitFinalized({
390
441
  request: { log, tx },
@@ -453,10 +504,22 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
453
504
  abstract getLogs(opts: LogFilter): AsyncIterableIterator<Log_>
454
505
 
455
506
  /**
456
- * Fetch all CCIP requests in a transaction
507
+ * Fetch all CCIP requests in a transaction.
508
+ *
457
509
  * @param tx - ChainTransaction or txHash to fetch requests from
458
- * @returns CCIP messages in the transaction (at least one)
459
- * @throws {@link CCIPMessageNotFoundInTxError} if no CCIP messages found in transaction
510
+ * @returns Promise resolving to CCIP messages in the transaction (at least one)
511
+ *
512
+ * @throws {@link CCIPTransactionNotFoundError} if transaction does not exist
513
+ * @throws {@link CCIPMessageNotFoundInTxError} if no CCIPSendRequested events in tx
514
+ *
515
+ * @example Get messages from transaction
516
+ * ```typescript
517
+ * const chain = await EVMChain.fromUrl('https://eth-mainnet.example.com')
518
+ * const requests = await chain.getMessagesInTx('0xabc123...')
519
+ * for (const req of requests) {
520
+ * console.log(`Message ID: ${req.message.messageId}`)
521
+ * }
522
+ * ```
460
523
  */
461
524
  async getMessagesInTx(tx: string | ChainTransaction): Promise<CCIPRequest[]> {
462
525
  const txHash = typeof tx === 'string' ? tx : tx.hash
@@ -511,8 +574,9 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
511
574
  * @returns CCIPRequest with `metadata` populated from API
512
575
  * @throws {@link CCIPApiClientNotAvailableError} if API disabled
513
576
  * @throws {@link CCIPMessageIdNotFoundError} if message not found
577
+ * @throws {@link CCIPOnRampRequiredError} if onRamp is required but not provided
514
578
  * @throws {@link CCIPHttpError} if API request fails
515
- **/
579
+ */
516
580
  async getMessageById(
517
581
  messageId: string,
518
582
  _opts?: { page?: number; onRamp?: string },
@@ -527,96 +591,213 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
527
591
 
528
592
  /**
529
593
  * Fetches all CCIP messages contained in a given commit batch.
530
- * @param request - CCIPRequest to fetch batch for.
531
- * @param commit - CommitReport range (min, max).
532
- * @param opts - Optional parameters (e.g., `page` for pagination width).
533
- * @returns Array of messages in the batch.
594
+ * To be implemented for chains supporting CCIPVersion &lt;= v1.6.0
595
+ *
596
+ * @param request - CCIPRequest to fetch batch for
597
+ * @param range - batch range \{ minSeqnr, maxSeqNr \}, e.g. from [[CommitReport]]
598
+ * @param opts - Optional parameters (e.g., `page` for pagination width)
599
+ * @returns Array of messages in the batch
600
+ *
534
601
  * @throws {@link CCIPMessageBatchIncompleteError} if not all messages in range could be fetched
602
+ *
603
+ * @example Get all messages in a batch
604
+ * ```typescript
605
+ * const verifications = await dest.getVerifications({ offRamp, request })
606
+ * const messages = await source.getMessagesInBatch(request, verifications.report)
607
+ * console.log(`Found ${messages.length} messages in batch`)
608
+ * ```
535
609
  */
536
- abstract getMessagesInBatch<
610
+ getMessagesInBatch?<
537
611
  R extends PickDeep<
538
612
  CCIPRequest,
539
613
  'lane' | `log.${'topics' | 'address' | 'blockNumber'}` | 'message.sequenceNumber'
540
614
  >,
541
615
  >(
542
616
  request: R,
543
- commit: Pick<CommitReport, 'minSeqNr' | 'maxSeqNr'>,
617
+ range: Pick<CommitReport, 'minSeqNr' | 'maxSeqNr'>,
544
618
  opts?: { page?: number },
545
619
  ): Promise<R['message'][]>
620
+
546
621
  /**
547
- * Fetch typeAndVersion for a given CCIP contract address
622
+ * Fetch input data needed for executing messages
623
+ * Should be called on the *source* instance
624
+ * @param opts - getExecutionInput options containing request and verifications
625
+ * @returns `input` payload to be passed to [[execute]]
626
+ * @see {@link execute} - method to execute a message
627
+ */
628
+ async getExecutionInput({
629
+ request,
630
+ verifications,
631
+ ...opts
632
+ }: {
633
+ request: CCIPRequest
634
+ verifications: CCIPVerifications
635
+ } & Pick<LogFilter, 'page'>): Promise<ExecutionInput> {
636
+ if ('verifications' in verifications) {
637
+ // >=v2 verifications is enough for execution
638
+ return {
639
+ encodedMessage: (request.message as CCIPMessage<typeof CCIPVersion.V2_0>).encodedMessage,
640
+ ...verifications,
641
+ }
642
+ }
643
+ // other messages in same batch are available from `source` side;
644
+ // not needed for chain families supporting only >=v2
645
+ const messagesInBatch = await this.getMessagesInBatch!(request, verifications.report, opts)
646
+ const execReportProof = calculateManualExecProof(
647
+ messagesInBatch,
648
+ request.lane,
649
+ request.message.messageId,
650
+ verifications.report.merkleRoot,
651
+ this,
652
+ )
653
+ const offchainTokenData = await this.getOffchainTokenData(request)
654
+ return {
655
+ ...execReportProof,
656
+ message: request.message,
657
+ offchainTokenData,
658
+ } as ExecutionInput
659
+ }
660
+ /**
661
+ * Fetch typeAndVersion for a given CCIP contract address.
662
+ *
548
663
  * @param address - CCIP contract address
549
- * @returns type - parsed type of the contract, e.g. `OnRamp`
550
- * @returns version - parsed version of the contract, e.g. `1.6.0`
551
- * @returns typeAndVersion - original (unparsed) typeAndVersion() string
552
- * @returns suffix - suffix of the version, if any (e.g. `-dev`)
553
- * @throws {@link CCIPTypeVersionInvalidError} if contract doesn't have valid typeAndVersion
664
+ * @returns Promise resolving to tuple:
665
+ * - `type` - Parsed type of the contract, e.g. `OnRamp`
666
+ * - `version` - Parsed version of the contract, e.g. `1.6.0`
667
+ * - `typeAndVersion` - Original (unparsed) typeAndVersion() string
668
+ * - `suffix` - Suffix of the version, if any (e.g. `-dev`)
669
+ *
670
+ * @throws {@link CCIPTypeVersionInvalidError} if typeAndVersion string cannot be parsed
671
+ *
672
+ * @example Check contract version
673
+ * ```typescript
674
+ * const [type, version] = await chain.typeAndVersion(contractAddress)
675
+ * console.log(`Contract: ${type} v${version}`)
676
+ * if (version < '1.6.0') {
677
+ * console.log('Legacy contract detected')
678
+ * }
679
+ * ```
554
680
  */
555
681
  abstract typeAndVersion(
556
682
  address: string,
557
683
  ): Promise<[type: string, version: string, typeAndVersion: string, suffix?: string]>
558
684
 
559
685
  /**
560
- * Fetch the Router address set in OnRamp config
561
- * Used to discover OffRamp connected to OnRamp
686
+ * Fetch the Router address set in OnRamp config.
687
+ * Used to discover OffRamp connected to OnRamp.
688
+ *
562
689
  * @param onRamp - OnRamp contract address
563
- * @param destChainSelector - destination chain selector
564
- * @returns Router address
690
+ * @param destChainSelector - Destination chain selector
691
+ * @returns Promise resolving to Router address
692
+ *
693
+ * @throws {@link CCIPContractTypeInvalidError} if address is not an OnRamp
694
+ *
695
+ * @example Get router from onRamp
696
+ * ```typescript
697
+ * const router = await chain.getRouterForOnRamp(onRampAddress, destSelector)
698
+ * console.log(`Router: ${router}`)
699
+ * ```
565
700
  */
566
701
  abstract getRouterForOnRamp(onRamp: string, destChainSelector: bigint): Promise<string>
567
702
  /**
568
- * Fetch the Router address set in OffRamp config
703
+ * Fetch the Router address set in OffRamp config.
704
+ *
569
705
  * @param offRamp - OffRamp contract address
570
- * @param sourceChainSelector - source chain selector
571
- * @returns Router address
706
+ * @param sourceChainSelector - Source chain selector
707
+ * @returns Promise resolving to Router address
708
+ *
709
+ * @throws {@link CCIPContractTypeInvalidError} if address is not an OffRamp
710
+ *
711
+ * @example Get router from offRamp
712
+ * ```typescript
713
+ * const router = await chain.getRouterForOffRamp(offRampAddress, sourceSelector)
714
+ * console.log(`Router: ${router}`)
715
+ * ```
572
716
  */
573
717
  abstract getRouterForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise<string>
574
718
  /**
575
- * Get the native token address for a Router
576
- * @param router - router contract address
577
- * @returns native token address (usually wrapped)
719
+ * Get the native token address for a Router.
720
+ *
721
+ * @param router - Router contract address
722
+ * @returns Promise resolving to native token address (usually wrapped)
723
+ *
724
+ * @example Get wrapped native token
725
+ * ```typescript
726
+ * const weth = await chain.getNativeTokenForRouter(routerAddress)
727
+ * console.log(`Wrapped native: ${weth}`)
728
+ * ```
578
729
  */
579
730
  abstract getNativeTokenForRouter(router: string): Promise<string>
580
731
  /**
581
- * Fetch the OffRamps allowlisted in a Router
582
- * Used to discover OffRamp connected to an OnRamp
732
+ * Fetch the OffRamps allowlisted in a Router.
733
+ * Used to discover OffRamp connected to an OnRamp.
734
+ *
583
735
  * @param router - Router contract address
584
- * @param sourceChainSelector - source chain selector
585
- * @returns array of OffRamp addresses
736
+ * @param sourceChainSelector - Source chain selector
737
+ * @returns Promise resolving to array of OffRamp addresses
738
+ *
739
+ * @example Get offRamps for a source chain
740
+ * ```typescript
741
+ * const offRamps = await dest.getOffRampsForRouter(routerAddress, sourceSelector)
742
+ * console.log(`Found ${offRamps.length} offRamp(s)`)
743
+ * ```
586
744
  */
587
745
  abstract getOffRampsForRouter(router: string, sourceChainSelector: bigint): Promise<string[]>
588
746
  /**
589
- * Fetch the OnRamp registered in a Router for a destination chain
747
+ * Fetch the OnRamp registered in a Router for a destination chain.
748
+ *
590
749
  * @param router - Router contract address
591
- * @param destChainSelector - destination chain selector
592
- * @returns OnRamp addresses
750
+ * @param destChainSelector - Destination chain selector
751
+ * @returns Promise resolving to OnRamp address
752
+ *
753
+ * @throws {@link CCIPLaneNotFoundError} if no lane exists to destination
754
+ *
755
+ * @example Get onRamp for destination
756
+ * ```typescript
757
+ * const onRamp = await source.getOnRampForRouter(routerAddress, destSelector)
758
+ * console.log(`OnRamp: ${onRamp}`)
759
+ * ```
593
760
  */
594
761
  abstract getOnRampForRouter(router: string, destChainSelector: bigint): Promise<string>
595
762
  /**
596
- * Fetch the OnRamp address set in OffRamp config
597
- * Used to discover OffRamp connected to an OnRamp
763
+ * Fetch the OnRamps addresses set in OffRamp config.
764
+ * Used to discover OffRamp connected to an OnRamp.
765
+ *
598
766
  * @param offRamp - OffRamp contract address
599
- * @param sourceChainSelector - source chain selector
600
- * @returns OnRamp address
601
- */
602
- abstract getOnRampForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise<string>
603
- /**
604
- * Fetch the CommitStore set in OffRamp config (CCIP v1.5 and earlier).
605
- * For CCIP v1.6 and later, it should return the offRamp address.
606
- * @param offRamp - OffRamp contract address.
607
- * @returns CommitStore address.
767
+ * @param sourceChainSelector - Source chain selector
768
+ * @returns Promise resolving to OnRamps addresses
769
+ *
770
+ * @example Get onRamp from offRamp config
771
+ * ```typescript
772
+ * const [onRamp] = await dest.getOnRampsForOffRamp(offRampAddress, sourceSelector)
773
+ * console.log(`OnRamp: ${onRamp}`)
774
+ * ```
608
775
  */
609
- abstract getCommitStoreForOffRamp(offRamp: string): Promise<string>
776
+ abstract getOnRampsForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise<string[]>
610
777
  /**
611
- * Fetch the TokenPool's token/mint
778
+ * Fetch the TokenPool's token/mint.
779
+ *
612
780
  * @param tokenPool - TokenPool address
613
- * @returns Token or mint address
781
+ * @returns Promise resolving to token or mint address
782
+ *
783
+ * @example Get token for pool
784
+ * ```typescript
785
+ * const token = await chain.getTokenForTokenPool(tokenPoolAddress)
786
+ * console.log(`Token: ${token}`)
787
+ * ```
614
788
  */
615
789
  abstract getTokenForTokenPool(tokenPool: string): Promise<string>
616
790
  /**
617
- * Fetch token metadata
791
+ * Fetch token metadata.
792
+ *
618
793
  * @param token - Token address
619
- * @returns Token symbol and decimals, and optionally name
794
+ * @returns Promise resolving to token symbol, decimals, and optionally name
795
+ *
796
+ * @example Get token info
797
+ * ```typescript
798
+ * const info = await chain.getTokenInfo(tokenAddress)
799
+ * console.log(`${info.symbol}: ${info.decimals} decimals`)
800
+ * ```
620
801
  */
621
802
  abstract getTokenInfo(token: string): Promise<TokenInfo>
622
803
  /**
@@ -628,14 +809,14 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
628
809
  *
629
810
  * @example Query native token balance
630
811
  * ```typescript
631
- * const balance = await chain.getBalance({ address: '0x123...' })
812
+ * const balance = await chain.getBalance({ holder: '0x123...' })
632
813
  * console.log(`Native balance: ${balance}`) // balance in wei
633
814
  * ```
634
815
  *
635
816
  * @example Query ERC20 token balance
636
817
  * ```typescript
637
818
  * const balance = await chain.getBalance({
638
- * address: '0x123...',
819
+ * holder: '0x123...',
639
820
  * token: '0xLINK...'
640
821
  * })
641
822
  * console.log(`LINK balance: ${balance}`) // balance in smallest units
@@ -643,22 +824,52 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
643
824
  */
644
825
  abstract getBalance(opts: GetBalanceOpts): Promise<bigint>
645
826
  /**
646
- * Fetch TokenAdminRegistry configured in a given OnRamp, Router, etc
647
- * Needed to map a source token to its dest counterparts
648
- * @param address - Some contract for which we can fetch a TokenAdminRegistry (OnRamp, Router, etc.)
649
- * @returns TokenAdminRegistry address
827
+ * Fetch TokenAdminRegistry configured in a given OnRamp, Router, etc.
828
+ * Needed to map a source token to its dest counterparts.
829
+ *
830
+ * @param address - Contract address (OnRamp, Router, etc.)
831
+ * @returns Promise resolving to TokenAdminRegistry address
832
+ *
833
+ * @example Get token registry
834
+ * ```typescript
835
+ * const registry = await chain.getTokenAdminRegistryFor(onRampAddress)
836
+ * console.log(`Registry: ${registry}`)
837
+ * ```
650
838
  */
651
839
  abstract getTokenAdminRegistryFor(address: string): Promise<string>
652
840
  /**
653
- * Fetch the current fee for a given intended message
841
+ * Fetch the current fee for a given intended message.
842
+ *
654
843
  * @param opts - {@link SendMessageOpts} without approveMax
655
844
  * @returns Fee amount in the feeToken's smallest units
845
+ *
846
+ * @example Calculate message fee
847
+ * ```typescript
848
+ * const fee = await chain.getFee({
849
+ * router: routerAddress,
850
+ * destChainSelector: destSelector,
851
+ * message: { receiver: '0x...', data: '0x' },
852
+ * })
853
+ * console.log(`Fee: ${fee} wei`)
854
+ * ```
656
855
  */
657
856
  abstract getFee(opts: Omit<SendMessageOpts, 'approveMax'>): Promise<bigint>
658
857
  /**
659
- * Generate unsigned txs for ccipSend'ing a message
858
+ * Generate unsigned txs for ccipSend'ing a message.
859
+ *
660
860
  * @param opts - {@link SendMessageOpts} with sender address
661
- * @returns chain-family specific unsigned txs
861
+ * @returns Promise resolving to chain-family specific unsigned txs
862
+ *
863
+ * @example Generate unsigned transaction
864
+ * ```typescript
865
+ * const unsignedTx = await chain.generateUnsignedSendMessage({
866
+ * router: routerAddress,
867
+ * destChainSelector: destSelector,
868
+ * message: { receiver: '0x...', data: '0x1337' },
869
+ * sender: walletAddress,
870
+ * })
871
+ * // Sign and send with external wallet
872
+ * ```
662
873
  */
663
874
  abstract generateUnsignedSendMessage(
664
875
  opts: SendMessageOpts & {
@@ -668,11 +879,14 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
668
879
  ): Promise<UnsignedTx[F]>
669
880
  /**
670
881
  * Send a CCIP message through a router using provided wallet.
882
+ *
671
883
  * @param opts - {@link SendMessageOpts} with chain-specific wallet for signing
672
- * @returns CCIP request
673
- * @throws {@link CCIPWalletNotSignerError} if wallet cannot sign transactions
884
+ * @returns Promise resolving to CCIP request with message details
674
885
  *
675
- * @example
886
+ * @throws {@link CCIPWalletNotSignerError} if wallet is not a valid signer
887
+ * @throws {@link CCIPLaneNotFoundError} if no lane exists to destination
888
+ *
889
+ * @example Send cross-chain message
676
890
  * ```typescript
677
891
  * const request = await chain.sendMessage({
678
892
  * router: '0x...',
@@ -695,75 +909,101 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
695
909
  },
696
910
  ): Promise<CCIPRequest>
697
911
  /**
698
- * Fetch supported offchain token data for a request from this network
912
+ * Fetch supported offchain token data for a request from this network.
913
+ *
699
914
  * @param request - CCIP request, with tx, logs and message
700
- * @returns array with one offchain token data for each token transfer in request
915
+ * @returns Promise resolving to array with one offchain token data for each token transfer
916
+ *
917
+ * @throws {@link CCIPUsdcAttestationError} if USDC attestation fetch fails (transient)
918
+ * @throws {@link CCIPLbtcAttestationError} if LBTC attestation fetch fails (transient)
919
+ *
920
+ * @example Get offchain token data for USDC transfer
921
+ * ```typescript
922
+ * const offchainData = await source.getOffchainTokenData(request)
923
+ * // Use in execution report
924
+ * ```
701
925
  */
702
926
  abstract getOffchainTokenData(request: CCIPRequest): Promise<OffchainTokenData[]>
703
927
  /**
704
- * Generate unsigned tx to manuallyExecute a message
705
- * @param opts - {@link ExecuteReportOpts} with payer address which will send the exec tx
706
- * @returns chain-family specific unsigned txs
928
+ * Generate unsigned tx to manuallyExecute a message.
929
+ *
930
+ * @param opts - {@link ExecuteOpts} with payer address which will send the exec tx
931
+ * @returns Promise resolving to chain-family specific unsigned txs
932
+ *
933
+ * @example Generate unsigned execution tx
934
+ * ```typescript
935
+ * const unsignedTx = await dest.generateUnsignedExecute({
936
+ * offRamp: offRampAddress,
937
+ * execReport,
938
+ * payer: walletAddress,
939
+ * })
940
+ * // Sign and send with external wallet
941
+ * ```
707
942
  */
708
- abstract generateUnsignedExecuteReport(
709
- opts: ExecuteReportOpts & {
943
+ abstract generateUnsignedExecute(
944
+ opts: ExecuteOpts & {
710
945
  /** address which will be used to send the report tx */
711
946
  payer: string
712
947
  },
713
948
  ): Promise<UnsignedTx[F]>
714
949
  /**
715
- * Execute messages in report in an offRamp
716
- * @param opts - {@link ExecuteReportOpts} with chain-specific wallet to sign and send tx
717
- * @returns transaction of the execution
950
+ * Execute messages in report in an offRamp.
718
951
  *
719
- * @example
952
+ * @param opts - {@link ExecuteOpts} with chain-specific wallet to sign and send tx
953
+ * @returns Promise resolving to transaction of the execution
954
+ *
955
+ * @throws {@link CCIPWalletNotSignerError} if wallet is not a valid signer
956
+ * @throws {@link CCIPExecTxRevertedError} if execution transaction reverts
957
+ * @throws {@link CCIPMerkleRootMismatchError} if merkle proof is invalid
958
+ *
959
+ * @example Manual execution of pending message
720
960
  * ```typescript
721
- * const execReportProof = calculateManualExecProof(
722
- * messagesInBatch: await source.getMessagesInBatch(request, commit.report),
723
- * request.lane,
724
- * request.message.messageId,
725
- * commit.report.merkleRoot,
726
- * dest,
727
- * )
728
- * const receipt = await dest.executeReport({
729
- * offRamp,
730
- * execReport: {
731
- * ...execReportProof,
732
- * message: request.message,
733
- * offchainTokenData: await source.getOffchainTokenData(request),
734
- * },
735
- * wallet,
736
- * })
737
- * console.log(`Message ID: ${request.message.messageId}`)
961
+ * const input = await source.getExecutionInput({ request, verifications })
962
+ * const receipt = await dest.execute({ offRamp, input, wallet })
963
+ * console.log(`Executed: ${receipt.log.transactionHash}`)
738
964
  * ```
739
965
  * @throws {@link CCIPWalletNotSignerError} if wallet cannot sign transactions
740
966
  * @throws {@link CCIPExecTxNotConfirmedError} if execution transaction fails to confirm
741
967
  */
742
- abstract executeReport(
743
- opts: ExecuteReportOpts & {
968
+ abstract execute(
969
+ opts: ExecuteOpts & {
744
970
  // Signer instance (chain-dependent)
745
971
  wallet: unknown
746
972
  },
747
973
  ): Promise<CCIPExecution>
748
974
 
749
975
  /**
750
- * Look for a CommitReport at dest for given CCIP request
751
- * May be specialized by some subclasses
752
- * @param opts - getCommitReport options
976
+ * Look for a CommitReport at dest for given CCIP request.
977
+ * May be specialized by some subclasses.
978
+ *
979
+ * @param opts - getVerifications options
753
980
  * @returns CCIPCommit info
754
- * @throws {@link CCIPCommitNotFoundError} if no commit found for the request
981
+ *
982
+ * @throws {@link CCIPCommitNotFoundError} if no commit found for the request (transient)
983
+ *
984
+ * @example Get commit for a request
985
+ * ```typescript
986
+ * const verifications = await dest.getVerifications({
987
+ * offRamp: offRampAddress,
988
+ * request,
989
+ * })
990
+ * console.log(`Committed at block: ${verifications.log.blockNumber}`)
991
+ * ```
755
992
  */
756
- async getCommitReport({
757
- commitStore,
993
+ async getVerifications({
994
+ offRamp,
758
995
  request,
759
996
  ...hints
760
997
  }: {
761
- /** address of commitStore (OffRamp in \>=v1.6) */
762
- commitStore: string
998
+ /** address of offRamp or commitStore contract */
999
+ offRamp: string
763
1000
  /** CCIPRequest subset object */
764
- request: PickDeep<CCIPRequest, 'lane' | 'message.sequenceNumber' | 'tx.timestamp'>
765
- } & Pick<LogFilter, 'page' | 'watch' | 'startBlock'>): Promise<CCIPCommit> {
766
- return getCommitReport(this, commitStore, request, hints)
1001
+ request: PickDeep<
1002
+ CCIPRequest,
1003
+ 'lane' | `message.${'sequenceNumber' | 'messageId'}` | 'tx.timestamp'
1004
+ >
1005
+ } & Pick<LogFilter, 'page' | 'watch' | 'startBlock'>): Promise<CCIPVerifications> {
1006
+ return getOnchainCommitReport(this, offRamp, request, hints)
767
1007
  }
768
1008
 
769
1009
  /**
@@ -806,15 +1046,29 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
806
1046
  }
807
1047
 
808
1048
  /**
809
- * Default/generic implementation of getExecutionReceipts
1049
+ * Default/generic implementation of getExecutionReceipts.
1050
+ * Yields execution receipts for a given offRamp.
1051
+ *
810
1052
  * @param opts - getExecutionReceipts options
811
1053
  * @returns Async generator of CCIPExecution receipts
1054
+ *
1055
+ * @example Watch for execution receipts
1056
+ * ```typescript
1057
+ * for await (const exec of dest.getExecutionReceipts({
1058
+ * offRamp: offRampAddress,
1059
+ * messageId: request.message.messageId,
1060
+ * startBlock: commit.log.blockNumber,
1061
+ * })) {
1062
+ * console.log(`State: ${exec.receipt.state}`)
1063
+ * if (exec.receipt.state === ExecutionState.Success) break
1064
+ * }
1065
+ * ```
812
1066
  */
813
1067
  async *getExecutionReceipts({
814
1068
  offRamp,
815
1069
  messageId,
816
1070
  sourceChainSelector,
817
- commit,
1071
+ verifications,
818
1072
  ...hints
819
1073
  }: {
820
1074
  /** address of OffRamp contract */
@@ -824,12 +1078,12 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
824
1078
  /** filter: yield only executions for this source chain */
825
1079
  sourceChainSelector?: bigint
826
1080
  /** optional commit associated with the request, can be used for optimizations in some families */
827
- commit?: CCIPCommit
1081
+ verifications?: CCIPVerifications
828
1082
  } & Pick<
829
1083
  LogFilter,
830
1084
  'page' | 'watch' | 'startBlock' | 'startTime'
831
1085
  >): AsyncIterableIterator<CCIPExecution> {
832
- hints.startBlock ??= commit?.log.blockNumber
1086
+ if (verifications && 'log' in verifications) hints.startBlock ??= verifications.log.blockNumber
833
1087
  const onlyLast = !hints.startTime && !hints.startBlock // backwards
834
1088
  for await (const log of this.getLogs({
835
1089
  address: offRamp,
@@ -855,10 +1109,18 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
855
1109
 
856
1110
  /**
857
1111
  * Fetch first execution receipt inside a transaction.
1112
+ *
858
1113
  * @internal
859
- * @param tx - transaction hash or transaction object
1114
+ * @param tx - Transaction hash or transaction object
860
1115
  * @returns CCIP execution object
1116
+ *
861
1117
  * @throws {@link CCIPExecTxRevertedError} if no execution receipt found in transaction
1118
+ *
1119
+ * @example Get receipt from execution tx
1120
+ * ```typescript
1121
+ * const exec = await dest.getExecutionReceiptInTx(execTxHash)
1122
+ * console.log(`State: ${exec.receipt.state}`)
1123
+ * ```
862
1124
  */
863
1125
  async getExecutionReceiptInTx(tx: string | ChainTransaction): Promise<CCIPExecution> {
864
1126
  if (typeof tx === 'string') tx = await this.getTransaction(tx)
@@ -874,9 +1136,16 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
874
1136
 
875
1137
  /**
876
1138
  * List tokens supported by given TokenAdminRegistry contract.
1139
+ *
877
1140
  * @param address - Usually TokenAdminRegistry, but chain may support receiving Router, OnRamp, etc.
878
- * @param opts - Optional parameters (e.g., `page` for pagination range).
879
- * @returns Array of supported token addresses.
1141
+ * @param opts - Optional parameters (e.g., `page` for pagination range)
1142
+ * @returns Promise resolving to array of supported token addresses
1143
+ *
1144
+ * @example Get all supported tokens
1145
+ * ```typescript
1146
+ * const tokens = await chain.getSupportedTokens(registryAddress)
1147
+ * console.log(`${tokens.length} tokens supported`)
1148
+ * ```
880
1149
  */
881
1150
  abstract getSupportedTokens(address: string, opts?: { page?: number }): Promise<string[]>
882
1151
 
@@ -907,21 +1176,27 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
907
1176
  * Fetch configuration of a token pool.
908
1177
  *
909
1178
  * @remarks
910
- * Returns the core configuration of a token pool including which token it manages
911
- * and which router it's registered with.
1179
+ * Return type varies by chain:
1180
+ * - **EVM**: `typeAndVersion` is always present (required)
1181
+ * - **Solana**: Includes extra `tokenPoolProgram` field
1182
+ * - **Aptos**: Standard fields only
1183
+ * - **Sui/TON**: Throws {@link CCIPNotImplementedError}
912
1184
  *
913
- * @example Query pool configuration
1185
+ * @example Type-safe access to chain-specific fields
914
1186
  * ```typescript
915
- * const config = await chain.getTokenPoolConfig(poolAddress)
916
- * console.log(`Manages token: ${config.token}`)
917
- * console.log(`Router: ${config.router}`)
918
- * if (config.typeAndVersion) {
919
- * console.log(`Version: ${config.typeAndVersion}`)
1187
+ * // Use instanceof to narrow the chain type
1188
+ * if (chain instanceof SolanaChain) {
1189
+ * const config = await chain.getTokenPoolConfig(poolAddress)
1190
+ * console.log(config.tokenPoolProgram) // TypeScript knows this exists!
1191
+ * } else if (chain instanceof EVMChain) {
1192
+ * const config = await chain.getTokenPoolConfig(poolAddress)
1193
+ * console.log(config.typeAndVersion) // TypeScript knows this is required!
920
1194
  * }
921
1195
  * ```
922
1196
  *
923
1197
  * @param tokenPool - Token pool contract address.
924
1198
  * @returns {@link TokenPoolConfig} containing token, router, and version info.
1199
+ * @throws {@link CCIPNotImplementedError} on Sui or TON chains
925
1200
  */
926
1201
  abstract getTokenPoolConfig(tokenPool: string): Promise<TokenPoolConfig>
927
1202
 
@@ -1003,12 +1278,27 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
1003
1278
 
1004
1279
  /**
1005
1280
  * Fetch list and info of supported feeTokens.
1006
- * @param router - Router address on this chain.
1007
- * @returns Mapping of token addresses to respective TokenInfo objects.
1281
+ *
1282
+ * @param router - Router address on this chain
1283
+ * @returns Promise resolving to mapping of token addresses to TokenInfo objects
1284
+ *
1285
+ * @example Get available fee tokens
1286
+ * ```typescript
1287
+ * const feeTokens = await chain.getFeeTokens(routerAddress)
1288
+ * for (const [addr, info] of Object.entries(feeTokens)) {
1289
+ * console.log(`${info.symbol}: ${addr}`)
1290
+ * }
1291
+ * ```
1008
1292
  */
1009
1293
  abstract getFeeTokens(router: string): Promise<Record<string, TokenInfo>>
1010
1294
 
1011
- /** {@inheritDoc ChainStatic.buildMessageForDest} */
1295
+ /**
1296
+ * Returns a copy of a message, populating missing fields like `extraArgs` with defaults.
1297
+ * It's expected to return a message suitable at least for basic token transfers.
1298
+ *
1299
+ * @param message - AnyMessage (from source), containing at least `receiver`
1300
+ * @returns A message suitable for `sendMessage` to this destination chain family
1301
+ */
1012
1302
  static buildMessageForDest(
1013
1303
  message: Parameters<ChainStatic['buildMessageForDest']>[0],
1014
1304
  ): AnyMessage {
@@ -1065,30 +1355,72 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
1065
1355
  }): Promise<number>
1066
1356
  }
1067
1357
 
1068
- /** Static methods and properties available on Chain class constructors. */
1358
+ /**
1359
+ * Static methods and properties available on Chain class constructors.
1360
+ *
1361
+ * @example Using static methods
1362
+ * ```typescript
1363
+ * // Create chain from URL
1364
+ * const chain = await EVMChain.fromUrl('https://eth-mainnet.example.com')
1365
+ *
1366
+ * // Decode message from log
1367
+ * const message = EVMChain.decodeMessage(log)
1368
+ *
1369
+ * // Validate address format
1370
+ * const normalized = EVMChain.getAddress('0xABC...')
1371
+ * ```
1372
+ */
1069
1373
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
1070
1374
  export type ChainStatic<F extends ChainFamily = ChainFamily> = Function & {
1071
1375
  readonly family: F
1072
1376
  readonly decimals: number
1073
1377
  /**
1074
- * async constructor: builds a Chain from a rpc endpoint url
1075
- * @param url - rpc endpoint url
1076
- * @param ctx - optional context with logger and API client configuration
1378
+ * Async constructor: builds a Chain from an RPC endpoint URL.
1379
+ *
1380
+ * @param url - RPC endpoint URL
1381
+ * @param ctx - Optional context with logger and API client configuration
1382
+ * @returns Promise resolving to Chain instance
1383
+ *
1384
+ * @throws {@link CCIPChainNotFoundError} if chain cannot be identified
1385
+ *
1386
+ * @example Create chain from RPC
1387
+ * ```typescript
1388
+ * const chain = await EVMChain.fromUrl('https://eth-mainnet.example.com')
1389
+ * console.log(`Connected to: ${chain.network.name}`)
1390
+ * ```
1077
1391
  */
1078
1392
  fromUrl(url: string, ctx?: ChainContext): Promise<Chain<F>>
1079
1393
  /**
1080
- * Try to decode a CCIP message *from* a log/event *originated* from this *source* chain,
1081
- * but which may *target* other dest chain families
1082
- * iow: the parsing is specific to this chain family, but content may be intended to alien chains
1083
- * e.g: EVM-born (abi.encoded) bytearray may output message.computeUnits for Solana
1394
+ * Try to decode a CCIP message from a log/event originated from this source chain.
1395
+ * The parsing is specific to this chain family, but content may target other chains.
1396
+ *
1084
1397
  * @param log - Chain generic log
1085
- * @returns decoded CCIP message with merged extraArgs
1398
+ * @returns Decoded CCIP message with merged extraArgs, or undefined if not a CCIP message
1399
+ *
1400
+ * @example Decode message from log
1401
+ * ```typescript
1402
+ * const message = EVMChain.decodeMessage(log)
1403
+ * if (message) {
1404
+ * console.log(`Message ID: ${message.messageId}`)
1405
+ * }
1406
+ * ```
1086
1407
  */
1087
1408
  decodeMessage(log: Pick<Log_, 'data'>): CCIPMessage | undefined
1088
1409
  /**
1089
- * Try to decode an extraArgs array serialized for this chain family
1090
- * @param extraArgs - extra args bytes (Uint8Array, HexString or base64)
1091
- * @returns object containing decoded extraArgs and their tags
1410
+ * Try to decode an extraArgs array serialized for this chain family.
1411
+ *
1412
+ * @param extraArgs - Extra args bytes (Uint8Array, HexString or base64)
1413
+ * @returns Object containing decoded extraArgs and their tag, or undefined
1414
+ *
1415
+ * @throws {@link CCIPExtraArgsParseError} if bytes cannot be decoded
1416
+ *
1417
+ * @example Decode extra args
1418
+ * ```typescript
1419
+ * const decoded = EVMChain.decodeExtraArgs(message.extraArgs)
1420
+ * if (decoded?._tag === 'EVMExtraArgsV2') {
1421
+ * console.log(`Gas limit: ${decoded.gasLimit}`)
1422
+ * }
1423
+ * ```
1092
1424
  */
1093
1425
  decodeExtraArgs(
1094
1426
  extraArgs: BytesLike,
@@ -1099,54 +1431,140 @@ export type ChainStatic<F extends ChainFamily = ChainFamily> = Function & {
1099
1431
  | (SVMExtraArgsV1 & { _tag: 'SVMExtraArgsV1' })
1100
1432
  | (SuiExtraArgsV1 & { _tag: 'SuiExtraArgsV1' })
1101
1433
  | undefined
1434
+ /**
1435
+ * Encode extraArgs for this chain family.
1436
+ *
1437
+ * @param extraArgs - Extra args object to encode
1438
+ * @returns Encoded hex string
1439
+ *
1440
+ * @example Encode extra args
1441
+ * ```typescript
1442
+ * const encoded = EVMChain.encodeExtraArgs({
1443
+ * gasLimit: 200000n,
1444
+ * strict: false,
1445
+ * })
1446
+ * ```
1447
+ */
1102
1448
  encodeExtraArgs(extraArgs: ExtraArgs): string
1103
1449
  /**
1104
- * Decode a commit (CommitReportAccepted) event
1450
+ * Decode a commit (CommitReportAccepted) event.
1451
+ *
1105
1452
  * @param log - Chain generic log
1106
- * @param lane - if passed, filter or validate reports by lane
1107
- * @returns Array of commit reports contained in the log
1453
+ * @param lane - If passed, filter or validate reports by lane
1454
+ * @returns Array of commit reports contained in the log, or undefined
1455
+ *
1456
+ * @example Decode commit from log
1457
+ * ```typescript
1458
+ * const commits = EVMChain.decodeCommits(log, lane)
1459
+ * if (commits) {
1460
+ * console.log(`Found ${commits.length} commit(s)`)
1461
+ * }
1462
+ * ```
1108
1463
  */
1109
1464
  decodeCommits(log: Pick<Log_, 'data'>, lane?: Lane): CommitReport[] | undefined
1110
1465
  /**
1111
- * Decode a receipt (ExecutionStateChanged) event
1466
+ * Decode a receipt (ExecutionStateChanged) event.
1467
+ *
1112
1468
  * @param log - Chain generic log
1113
1469
  * @returns ExecutionReceipt or undefined if not a recognized receipt
1470
+ *
1471
+ * @example Decode execution receipt
1472
+ * ```typescript
1473
+ * const receipt = EVMChain.decodeReceipt(log)
1474
+ * if (receipt) {
1475
+ * console.log(`State: ${receipt.state}, Message: ${receipt.messageId}`)
1476
+ * }
1477
+ * ```
1114
1478
  */
1115
1479
  decodeReceipt(log: Pick<Log_, 'data'>): ExecutionReceipt | undefined
1116
1480
  /**
1117
- * Receive a bytes array and try to decode and normalize it as an address of this chain family
1481
+ * Receive a bytes array and try to decode and normalize it as an address of this chain family.
1482
+ *
1118
1483
  * @param bytes - Bytes array (Uint8Array, HexString or Base64)
1119
1484
  * @returns Address in this chain family's format
1485
+ *
1486
+ * @throws {@link CCIPAddressInvalidEvmError} if invalid EVM address
1487
+ * @throws {@link CCIPDataFormatUnsupportedError} if invalid Aptos/Sui address
1488
+ *
1489
+ * @example Normalize address
1490
+ * ```typescript
1491
+ * const normalized = EVMChain.getAddress('0xABC123...')
1492
+ * console.log(normalized) // checksummed address
1493
+ * ```
1120
1494
  */
1121
1495
  getAddress(bytes: BytesLike): string
1122
1496
  /**
1123
- * Validates a transaction hash format for this chain family
1497
+ * Validates a transaction hash format for this chain family.
1498
+ *
1499
+ * @param v - Value to validate
1500
+ * @returns True if value is a valid transaction hash format
1501
+ *
1502
+ * @example Validate transaction hash
1503
+ * ```typescript
1504
+ * if (EVMChain.isTxHash(userInput)) {
1505
+ * const tx = await chain.getTransaction(userInput)
1506
+ * }
1507
+ * ```
1124
1508
  */
1125
1509
  isTxHash(v: unknown): v is string
1126
1510
  /**
1127
1511
  * Format an address for human-friendly display.
1128
1512
  * Defaults to getAddress if not overridden.
1513
+ *
1129
1514
  * @param address - Address string in any recognized format
1130
1515
  * @returns Human-friendly address string for display
1516
+ *
1517
+ * @example Format address for display
1518
+ * ```typescript
1519
+ * const display = EVMChain.formatAddress?.(rawAddress) ?? rawAddress
1520
+ * console.log(display)
1521
+ * ```
1131
1522
  */
1132
1523
  formatAddress?(address: string): string
1133
1524
  /**
1134
1525
  * Format a transaction hash for human-friendly display.
1526
+ *
1135
1527
  * @param hash - Transaction hash string
1136
1528
  * @returns Human-friendly hash string for display
1529
+ *
1530
+ * @example Format tx hash for display
1531
+ * ```typescript
1532
+ * const display = EVMChain.formatTxHash?.(rawHash) ?? rawHash
1533
+ * console.log(display)
1534
+ * ```
1137
1535
  */
1138
1536
  formatTxHash?(hash: string): string
1139
1537
  /**
1140
- * Create a leaf hasher for this dest chain and lane
1141
- * @param lane - source, dest and onramp lane info
1142
- * @param ctx - context object containing logger
1143
- * @returns LeafHasher is a function that takes a message and returns a hash of it
1538
+ * Create a leaf hasher for this dest chain and lane.
1539
+ *
1540
+ * @param lane - Source, dest and onramp lane info
1541
+ * @param ctx - Context object containing logger
1542
+ * @returns LeafHasher function that takes a message and returns its hash
1543
+ *
1544
+ * @throws {@link CCIPHasherVersionUnsupportedError} if hasher version unsupported
1545
+ *
1546
+ * @example Create leaf hasher
1547
+ * ```typescript
1548
+ * const hasher = EVMChain.getDestLeafHasher(lane, { logger })
1549
+ * const leafHash = hasher(message)
1550
+ * ```
1144
1551
  */
1145
1552
  getDestLeafHasher(lane: Lane, ctx?: WithLogger): LeafHasher
1146
1553
  /**
1147
- * Try to parse an error or bytearray generated by this chain family
1554
+ * Try to parse an error or bytearray generated by this chain family.
1555
+ *
1148
1556
  * @param data - Caught object, string or bytearray
1149
- * @returns Ordered record with messages/properties, or undefined if not a recognized error
1557
+ * @returns Ordered record with messages/properties, or undefined/null if not recognized
1558
+ *
1559
+ * @example Parse contract error
1560
+ * ```typescript
1561
+ * try {
1562
+ * await chain.sendMessage(opts)
1563
+ * } catch (err) {
1564
+ * const parsed = EVMChain.parse?.(err)
1565
+ * if (parsed) console.log('Contract error:', parsed)
1566
+ * }
1567
+ * ```
1150
1568
  */
1151
1569
  parse?(data: unknown): Record<string, unknown> | undefined | null
1152
1570
  /**