@chainlink/ccip-sdk 0.90.2 → 0.91.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 (202) hide show
  1. package/README.md +35 -26
  2. package/dist/aptos/exec.d.ts +4 -5
  3. package/dist/aptos/exec.d.ts.map +1 -1
  4. package/dist/aptos/exec.js +5 -14
  5. package/dist/aptos/exec.js.map +1 -1
  6. package/dist/aptos/hasher.d.ts +18 -0
  7. package/dist/aptos/hasher.d.ts.map +1 -1
  8. package/dist/aptos/hasher.js +18 -0
  9. package/dist/aptos/hasher.js.map +1 -1
  10. package/dist/aptos/index.d.ts +127 -28
  11. package/dist/aptos/index.d.ts.map +1 -1
  12. package/dist/aptos/index.js +199 -70
  13. package/dist/aptos/index.js.map +1 -1
  14. package/dist/aptos/logs.d.ts +18 -0
  15. package/dist/aptos/logs.d.ts.map +1 -1
  16. package/dist/aptos/logs.js +21 -3
  17. package/dist/aptos/logs.js.map +1 -1
  18. package/dist/aptos/send.d.ts +22 -5
  19. package/dist/aptos/send.d.ts.map +1 -1
  20. package/dist/aptos/send.js +23 -15
  21. package/dist/aptos/send.js.map +1 -1
  22. package/dist/aptos/token.d.ts +6 -0
  23. package/dist/aptos/token.d.ts.map +1 -1
  24. package/dist/aptos/token.js +6 -0
  25. package/dist/aptos/token.js.map +1 -1
  26. package/dist/aptos/types.d.ts +16 -1
  27. package/dist/aptos/types.d.ts.map +1 -1
  28. package/dist/aptos/types.js +13 -0
  29. package/dist/aptos/types.js.map +1 -1
  30. package/dist/aptos/utils.d.ts +1 -1
  31. package/dist/aptos/utils.js +1 -1
  32. package/dist/chain.d.ts +185 -99
  33. package/dist/chain.d.ts.map +1 -1
  34. package/dist/chain.js +38 -15
  35. package/dist/chain.js.map +1 -1
  36. package/dist/commits.d.ts +4 -10
  37. package/dist/commits.d.ts.map +1 -1
  38. package/dist/commits.js +2 -1
  39. package/dist/commits.js.map +1 -1
  40. package/dist/evm/const.d.ts +5 -0
  41. package/dist/evm/const.d.ts.map +1 -1
  42. package/dist/evm/const.js +5 -0
  43. package/dist/evm/const.js.map +1 -1
  44. package/dist/evm/errors.d.ts +5 -0
  45. package/dist/evm/errors.d.ts.map +1 -1
  46. package/dist/evm/errors.js +6 -1
  47. package/dist/evm/errors.js.map +1 -1
  48. package/dist/evm/hasher.d.ts +16 -2
  49. package/dist/evm/hasher.d.ts.map +1 -1
  50. package/dist/evm/hasher.js +17 -3
  51. package/dist/evm/hasher.js.map +1 -1
  52. package/dist/evm/index.d.ts +176 -31
  53. package/dist/evm/index.d.ts.map +1 -1
  54. package/dist/evm/index.js +312 -154
  55. package/dist/evm/index.js.map +1 -1
  56. package/dist/evm/logs.d.ts +20 -0
  57. package/dist/evm/logs.d.ts.map +1 -0
  58. package/dist/evm/logs.js +194 -0
  59. package/dist/evm/logs.js.map +1 -0
  60. package/dist/evm/messages.d.ts +11 -2
  61. package/dist/evm/messages.d.ts.map +1 -1
  62. package/dist/evm/messages.js +4 -2
  63. package/dist/evm/messages.js.map +1 -1
  64. package/dist/evm/offchain.d.ts +7 -2
  65. package/dist/evm/offchain.d.ts.map +1 -1
  66. package/dist/evm/offchain.js +12 -7
  67. package/dist/evm/offchain.js.map +1 -1
  68. package/dist/execution.d.ts +19 -62
  69. package/dist/execution.d.ts.map +1 -1
  70. package/dist/execution.js +28 -31
  71. package/dist/execution.js.map +1 -1
  72. package/dist/extra-args.d.ts +35 -5
  73. package/dist/extra-args.d.ts.map +1 -1
  74. package/dist/extra-args.js +10 -5
  75. package/dist/extra-args.js.map +1 -1
  76. package/dist/gas.d.ts +6 -8
  77. package/dist/gas.d.ts.map +1 -1
  78. package/dist/gas.js +7 -9
  79. package/dist/gas.js.map +1 -1
  80. package/dist/hasher/common.d.ts +3 -2
  81. package/dist/hasher/common.d.ts.map +1 -1
  82. package/dist/hasher/common.js +2 -2
  83. package/dist/hasher/common.js.map +1 -1
  84. package/dist/hasher/hasher.d.ts +8 -2
  85. package/dist/hasher/hasher.d.ts.map +1 -1
  86. package/dist/hasher/hasher.js +8 -3
  87. package/dist/hasher/hasher.js.map +1 -1
  88. package/dist/hasher/merklemulti.d.ts +11 -9
  89. package/dist/hasher/merklemulti.d.ts.map +1 -1
  90. package/dist/hasher/merklemulti.js +17 -16
  91. package/dist/hasher/merklemulti.js.map +1 -1
  92. package/dist/index.d.ts +16 -8
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +17 -7
  95. package/dist/index.js.map +1 -1
  96. package/dist/requests.d.ts +39 -25
  97. package/dist/requests.d.ts.map +1 -1
  98. package/dist/requests.js +42 -35
  99. package/dist/requests.js.map +1 -1
  100. package/dist/selectors.d.ts +1 -1
  101. package/dist/solana/cleanup.d.ts +14 -10
  102. package/dist/solana/cleanup.d.ts.map +1 -1
  103. package/dist/solana/cleanup.js +35 -33
  104. package/dist/solana/cleanup.js.map +1 -1
  105. package/dist/solana/exec.d.ts +19 -11
  106. package/dist/solana/exec.d.ts.map +1 -1
  107. package/dist/solana/exec.js +86 -163
  108. package/dist/solana/exec.js.map +1 -1
  109. package/dist/solana/hasher.d.ts +7 -2
  110. package/dist/solana/hasher.d.ts.map +1 -1
  111. package/dist/solana/hasher.js +7 -2
  112. package/dist/solana/hasher.js.map +1 -1
  113. package/dist/solana/index.d.ts +202 -84
  114. package/dist/solana/index.d.ts.map +1 -1
  115. package/dist/solana/index.js +367 -252
  116. package/dist/solana/index.js.map +1 -1
  117. package/dist/solana/offchain.d.ts +8 -18
  118. package/dist/solana/offchain.d.ts.map +1 -1
  119. package/dist/solana/offchain.js +29 -83
  120. package/dist/solana/offchain.js.map +1 -1
  121. package/dist/solana/patchBorsh.d.ts +5 -1
  122. package/dist/solana/patchBorsh.d.ts.map +1 -1
  123. package/dist/solana/patchBorsh.js +57 -46
  124. package/dist/solana/patchBorsh.js.map +1 -1
  125. package/dist/solana/send.d.ts +28 -10
  126. package/dist/solana/send.d.ts.map +1 -1
  127. package/dist/solana/send.js +44 -77
  128. package/dist/solana/send.js.map +1 -1
  129. package/dist/solana/types.d.ts +22 -1
  130. package/dist/solana/types.d.ts.map +1 -1
  131. package/dist/solana/types.js +12 -1
  132. package/dist/solana/types.js.map +1 -1
  133. package/dist/solana/utils.d.ts +58 -4
  134. package/dist/solana/utils.d.ts.map +1 -1
  135. package/dist/solana/utils.js +110 -7
  136. package/dist/solana/utils.js.map +1 -1
  137. package/dist/sui/hasher.d.ts +18 -0
  138. package/dist/sui/hasher.d.ts.map +1 -1
  139. package/dist/sui/hasher.js +18 -0
  140. package/dist/sui/hasher.js.map +1 -1
  141. package/dist/sui/index.d.ts +99 -12
  142. package/dist/sui/index.d.ts.map +1 -1
  143. package/dist/sui/index.js +108 -19
  144. package/dist/sui/index.js.map +1 -1
  145. package/dist/sui/types.d.ts +6 -0
  146. package/dist/sui/types.d.ts.map +1 -1
  147. package/dist/sui/types.js +5 -0
  148. package/dist/sui/types.js.map +1 -1
  149. package/dist/supported-chains.d.ts +2 -1
  150. package/dist/supported-chains.d.ts.map +1 -1
  151. package/dist/supported-chains.js.map +1 -1
  152. package/dist/types.d.ts +127 -16
  153. package/dist/types.d.ts.map +1 -1
  154. package/dist/types.js +18 -0
  155. package/dist/types.js.map +1 -1
  156. package/dist/utils.d.ts +67 -46
  157. package/dist/utils.d.ts.map +1 -1
  158. package/dist/utils.js +143 -21
  159. package/dist/utils.js.map +1 -1
  160. package/package.json +13 -9
  161. package/src/aptos/exec.ts +7 -18
  162. package/src/aptos/hasher.ts +18 -0
  163. package/src/aptos/index.ts +288 -110
  164. package/src/aptos/logs.ts +21 -3
  165. package/src/aptos/send.ts +25 -22
  166. package/src/aptos/token.ts +6 -0
  167. package/src/aptos/types.ts +26 -2
  168. package/src/aptos/utils.ts +1 -1
  169. package/src/chain.ts +243 -108
  170. package/src/commits.ts +6 -7
  171. package/src/evm/const.ts +5 -0
  172. package/src/evm/errors.ts +6 -1
  173. package/src/evm/hasher.ts +20 -4
  174. package/src/evm/index.ts +416 -214
  175. package/src/evm/logs.ts +255 -0
  176. package/src/evm/messages.ts +11 -5
  177. package/src/evm/offchain.ts +13 -4
  178. package/src/execution.ts +40 -32
  179. package/src/extra-args.ts +38 -6
  180. package/src/gas.ts +7 -9
  181. package/src/hasher/common.ts +3 -2
  182. package/src/hasher/hasher.ts +12 -4
  183. package/src/hasher/merklemulti.ts +17 -16
  184. package/src/index.ts +29 -23
  185. package/src/requests.ts +64 -46
  186. package/src/selectors.ts +1 -1
  187. package/src/solana/cleanup.ts +49 -34
  188. package/src/solana/exec.ts +128 -272
  189. package/src/solana/hasher.ts +13 -4
  190. package/src/solana/index.ts +483 -356
  191. package/src/solana/offchain.ts +32 -102
  192. package/src/solana/patchBorsh.ts +65 -50
  193. package/src/solana/send.ts +52 -111
  194. package/src/solana/types.ts +44 -3
  195. package/src/solana/utils.ts +143 -19
  196. package/src/sui/hasher.ts +18 -0
  197. package/src/sui/index.ts +143 -31
  198. package/src/sui/types.ts +6 -0
  199. package/src/supported-chains.ts +2 -1
  200. package/src/types.ts +130 -18
  201. package/src/utils.ts +168 -26
  202. package/tsconfig.json +2 -1
package/src/chain.ts CHANGED
@@ -1,9 +1,9 @@
1
- import util from 'util'
2
-
3
1
  import type { BytesLike } from 'ethers'
2
+ import type { PickDeep } from 'type-fest'
4
3
 
4
+ import type { UnsignedAptosTx } from './aptos/types.ts'
5
5
  import { fetchCommitReport } from './commits.ts'
6
- import { fetchExecutionReceipts } from './execution.ts'
6
+ import type { UnsignedEVMTx } from './evm/index.ts'
7
7
  import type {
8
8
  EVMExtraArgsV1,
9
9
  EVMExtraArgsV2,
@@ -12,76 +12,120 @@ import type {
12
12
  SuiExtraArgsV1,
13
13
  } from './extra-args.ts'
14
14
  import type { LeafHasher } from './hasher/common.ts'
15
- import type {
16
- AnyMessage,
17
- CCIPCommit,
18
- CCIPExecution,
19
- CCIPMessage,
20
- CCIPRequest,
21
- CommitReport,
22
- ExecutionReceipt,
23
- ExecutionReport,
24
- Lane,
25
- Log_,
26
- NetworkInfo,
27
- OffchainTokenData,
15
+ import type { UnsignedSolanaTx } from './solana/types.ts'
16
+ import {
17
+ type AnyMessage,
18
+ type CCIPCommit,
19
+ type CCIPExecution,
20
+ type CCIPMessage,
21
+ type CCIPRequest,
22
+ type ChainFamily,
23
+ type ChainTransaction,
24
+ type CommitReport,
25
+ type ExecutionReceipt,
26
+ type ExecutionReport,
27
+ type Lane,
28
+ type Log_,
29
+ type Logger,
30
+ type NetworkInfo,
31
+ type OffchainTokenData,
32
+ type WithLogger,
33
+ ExecutionState,
28
34
  } from './types.ts'
35
+ import { util } from './utils.ts'
29
36
 
30
- export const ChainFamily = {
31
- EVM: 'evm',
32
- Solana: 'solana',
33
- Aptos: 'aptos',
34
- Sui: 'sui',
35
- } as const
36
- export type ChainFamily = (typeof ChainFamily)[keyof typeof ChainFamily]
37
-
37
+ /**
38
+ * Filter options for getLogs queries across chains.
39
+ */
38
40
  export type LogFilter = {
41
+ /** Starting block number (inclusive). */
39
42
  startBlock?: number
43
+ /** Starting Unix timestamp (inclusive). */
40
44
  startTime?: number
45
+ /** Ending block number (inclusive). */
41
46
  endBlock?: number
47
+ /** Optional hint signature for end of iteration. */
42
48
  endBefore?: string
49
+ /** Contract address to filter logs by. */
43
50
  address?: string
44
- topics?: string[] | string[][]
51
+ /** Topics to filter logs by. */
52
+ topics?: (string | string[] | null)[]
53
+ /** Page size for pagination. */
45
54
  page?: number
46
55
  }
47
56
 
48
- export type ChainTransaction = {
49
- chain: Chain
50
- hash: string
51
- logs: readonly Log_[]
52
- blockNumber: number
53
- timestamp: number
54
- from: string
55
- error?: unknown
56
- }
57
-
57
+ /**
58
+ * Token metadata information.
59
+ */
58
60
  export type TokenInfo = {
61
+ /** Token symbol (e.g., "LINK"). */
59
62
  readonly symbol: string
63
+ /** Number of decimals for the token. */
60
64
  readonly decimals: number
65
+ /** Optional human-readable token name. */
61
66
  readonly name?: string
62
67
  }
63
68
 
69
+ /**
70
+ * Rate limiter state for token pool configurations.
71
+ * Null if rate limiting is disabled.
72
+ */
64
73
  export type RateLimiterState = {
74
+ /** Current token balance in the rate limiter bucket. */
65
75
  tokens: bigint
76
+ /** Maximum capacity of the rate limiter bucket. */
66
77
  capacity: bigint
78
+ /** Rate at which tokens are replenished. */
67
79
  rate: bigint
68
80
  } | null
69
81
 
82
+ /**
83
+ * Remote token pool configuration for a specific chain.
84
+ */
70
85
  export type TokenPoolRemote = {
86
+ /** Address of the remote token on the destination chain. */
71
87
  remoteToken: string
88
+ /** Addresses of remote token pools. */
72
89
  remotePools: string[]
90
+ /** Inbound rate limiter state for tokens coming into this chain. */
73
91
  inboundRateLimiterState: RateLimiterState
92
+ /** Outbound rate limiter state for tokens leaving this chain. */
74
93
  outboundRateLimiterState: RateLimiterState
75
94
  }
76
95
 
96
+ /**
97
+ * Maps chain family to respective unsigned transaction type.
98
+ */
99
+ export type UnsignedTx = {
100
+ [ChainFamily.EVM]: UnsignedEVMTx
101
+ [ChainFamily.Solana]: UnsignedSolanaTx
102
+ [ChainFamily.Aptos]: UnsignedAptosTx
103
+ [ChainFamily.Sui]: never // TODO
104
+ }
105
+
77
106
  /**
78
107
  * Works like an interface for a base Chain class, but provides implementation (which can be
79
108
  * specialized) for some basic methods
80
109
  */
81
110
  export abstract class Chain<F extends ChainFamily = ChainFamily> {
82
- abstract readonly network: NetworkInfo<F>
83
- abstract destroy?(): Promise<void>
111
+ readonly network: NetworkInfo<F>
112
+ logger: Logger
113
+
114
+ /**
115
+ * Base constructor for Chain class.
116
+ * @param network - NetworkInfo object for the Chain instance
117
+ */
118
+ constructor(network: NetworkInfo, { logger = console }: WithLogger = {}) {
119
+ if (network.family !== (this.constructor as ChainStatic).family)
120
+ throw new Error(`Invalid network family for ${this.constructor.name}: ${network.family}`)
121
+ this.network = network as NetworkInfo<F>
122
+ this.logger = logger
123
+ }
84
124
 
125
+ /** Cleanup method to release resources (e.g., close connections). */
126
+ destroy?(): void | Promise<void>
127
+
128
+ /** Custom inspector for Node.js util.inspect. */
85
129
  [util.inspect.custom]() {
86
130
  return `${this.constructor.name} { ${this.network.name} }`
87
131
  }
@@ -100,33 +144,69 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
100
144
  abstract getTransaction(hash: string): Promise<ChainTransaction>
101
145
  /**
102
146
  * An async generator that yields logs based on the provided options.
103
- * @param opts - options object
104
- * @param opts.startBlock - if provided, fetch and generate logs forward starting from this block;
105
- * otherwise, returns logs backwards in time from endBlock;
106
- * optionally, startTime may be provided to fetch logs forward starting from this time;
107
- * @param opts.endBlock - if omitted, use latest block
108
- * @param opts.endBefore - optional hint signature for end of iteration, instead of endBlock
109
- * @param opts.address - if provided, fetch logs for this address only (may be required in some
110
- * networks/implementations)
111
- * @param opts.topics - if provided, fetch logs for these topics only;
112
- * if string[], it's assumed to be a list of topic0s (i.e. string[] or string[][0], event_ids);
113
- * some networks/implementations may not be able to filter topics other than topic0s, so one may
114
- * want to assume those are optimization hints, instead of hard filters, and verify results
115
- * @param opts.page - if provided, try to use this page/range for batches
116
- * @returns an async iterable iterator of logs
147
+ * @param opts - Options object containing:
148
+ * - `startBlock`: if provided, fetch and generate logs forward starting from this block;
149
+ * otherwise, returns logs backwards in time from endBlock;
150
+ * optionally, startTime may be provided to fetch logs forward starting from this time
151
+ * - `endBlock`: if omitted, use latest block
152
+ * - `endBefore`: optional hint signature for end of iteration, instead of endBlock
153
+ * - `address`: if provided, fetch logs for this address only (may be required in some
154
+ * networks/implementations)
155
+ * - `topics`: if provided, fetch logs for these topics only;
156
+ * if string[], it's assumed to be a list of topic0s (i.e. string[] or string[][0], event_ids);
157
+ * some networks/implementations may not be able to filter topics other than topic0s, so one may
158
+ * want to assume those are optimization hints, instead of hard filters, and verify results
159
+ * - `page`: if provided, try to use this page/range for batches
160
+ * @returns An async iterable iterator of logs.
117
161
  */
118
162
  abstract getLogs(opts: LogFilter): AsyncIterableIterator<Log_>
163
+
119
164
  /**
120
- * Fetch the typeAndVersion tag of a given CCIP contract
165
+ * Fetch all CCIP requests in a transaction
166
+ * @param tx - ChainTransaction or txHash to fetch requests from
167
+ * @returns CCIP messages in the transaction (at least one)
168
+ **/
169
+ abstract fetchRequestsInTx(tx: string | ChainTransaction): Promise<CCIPRequest[]>
170
+
171
+ /**
172
+ * Scan for a CCIP request by message ID
173
+ * @param messageId - message ID to fetch request for
174
+ * @param onRamp - address may be required in some implementations, and throw if missing
175
+ * @returns CCIPRequest
176
+ **/
177
+ fetchRequestById?(
178
+ messageId: string,
179
+ onRamp?: string,
180
+ opts?: { page?: number },
181
+ ): Promise<CCIPRequest>
182
+
183
+ /**
184
+ * Fetches all CCIP messages contained in a given commit batch.
185
+ * @param request - CCIPRequest to fetch batch for.
186
+ * @param commit - CommitReport range (min, max).
187
+ * @param opts - Optional parameters (e.g., `page` for pagination width).
188
+ */
189
+ abstract fetchAllMessagesInBatch<
190
+ R extends PickDeep<
191
+ CCIPRequest,
192
+ 'lane' | `log.${'topics' | 'address' | 'blockNumber'}` | 'message.header.sequenceNumber'
193
+ >,
194
+ >(
195
+ request: R,
196
+ commit: Pick<CommitReport, 'minSeqNr' | 'maxSeqNr'>,
197
+ opts?: { page?: number },
198
+ ): Promise<R['message'][]>
199
+ /**
200
+ * Fetch typeAndVersion for a given CCIP contract address
121
201
  * @param address - CCIP contract address
122
- * @returns typeAndVersion tag, validated and split
202
+ * @returns type - parsed type of the contract, e.g. `OnRamp`
203
+ * @returns version - parsed version of the contract, e.g. `1.6.0`
204
+ * @returns typeAndVersion - original (unparsed) typeAndVersion() string
205
+ * @returns suffix - suffix of the version, if any (e.g. `-dev`)
123
206
  */
124
207
  abstract typeAndVersion(
125
208
  address: string,
126
- ): Promise<
127
- | [type_: string, version: string, typeAndVersion: string]
128
- | [type_: string, version: string, typeAndVersion: string, suffix: string]
129
- >
209
+ ): Promise<[type: string, version: string, typeAndVersion: string, suffix?: string]>
130
210
 
131
211
  /**
132
212
  * Fetch the Router address set in OnRamp config
@@ -173,10 +253,10 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
173
253
  */
174
254
  abstract getOnRampForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise<string>
175
255
  /**
176
- * Fetch the CommitStore set in OffRamp config (CCIP<=v1.5)
177
- * For CCIP>=v1.6, it should return the offRamp address
178
- * @param offRamp - OffRamp contract address
179
- * @returns CommitStore address
256
+ * Fetch the CommitStore set in OffRamp config (CCIP v1.5 and earlier).
257
+ * For CCIP v1.6 and later, it should return the offRamp address.
258
+ * @param offRamp - OffRamp contract address.
259
+ * @returns CommitStore address.
180
260
  */
181
261
  abstract getCommitStoreForOffRamp(offRamp: string): Promise<string>
182
262
  /**
@@ -197,12 +277,6 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
197
277
  * @param onRamp - Some contract for which we can fetch a TokenAdminRegistry
198
278
  */
199
279
  abstract getTokenAdminRegistryFor(address: string): Promise<string>
200
- /**
201
- * Build, derive, load or fetch a wallet for this instance which will be used in any tx send operation
202
- * @param opts.wallet - cli or environmental parameters to help pick a wallet
203
- * @returns address of fetched (and stored internally) account
204
- */
205
- abstract getWalletAddress(opts?: { wallet?: unknown }): Promise<string>
206
280
  /**
207
281
  * Fetch the current fee for a given intended message
208
282
  * @param router - router address on this chain
@@ -211,54 +285,96 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
211
285
  */
212
286
  abstract getFee(router: string, destChainSelector: bigint, message: AnyMessage): Promise<bigint>
213
287
  /**
214
- * Send a CCIP message through a router using loaded wallet
215
- * @param router - router address on this chain
216
- * @param destChainSelector - dest network selector
217
- * @param message - message to send
218
- * @param opts.wallet - cli or environmental parameters to help pick a wallet
219
- * @param opts.approveMax - approve the maximum amount of tokens to transfer
288
+ * Generate unsigned txs for ccipSend'ing a message
289
+ * @param sender - sender address
290
+ * @param router - address of the Router contract
291
+ * @param destChainSelector - chainSelector of destination chain
292
+ * @param message - AnyMessage to send; if `fee` is not present, it'll be calculated
293
+ * @param approveMax - if tokens approvals are needed, opt into approving maximum allowance
294
+ * @returns chain-family specific unsigned txs
295
+ */
296
+ abstract generateUnsignedSendMessage(
297
+ sender: string,
298
+ router: string,
299
+ destChainSelector: bigint,
300
+ message: AnyMessage & { fee?: bigint },
301
+ opts?: { approveMax?: boolean },
302
+ ): Promise<UnsignedTx[F]>
303
+ /**
304
+ * Send a CCIP message through a router using provided wallet.
305
+ * @param router - Router address on this chain.
306
+ * @param destChainSelector - Destination network selector.
307
+ * @param message - Message to send.
308
+ * @param opts - Optional parameters:
309
+ * - `wallet`: cli or environmental parameters to help pick a wallet
310
+ * - `approveMax`: approve the maximum amount of tokens to transfer
220
311
  */
221
312
  abstract sendMessage(
222
313
  router: string,
223
314
  destChainSelector: bigint,
224
- message: AnyMessage & { fee: bigint },
225
- opts?: { wallet?: unknown; approveMax?: boolean },
226
- ): Promise<ChainTransaction>
315
+ message: AnyMessage & { fee?: bigint },
316
+ opts: { wallet: unknown; approveMax?: boolean },
317
+ ): Promise<CCIPRequest>
227
318
  /**
228
319
  * Fetch supported offchain token data for a request from this network
229
320
  * @param request - CCIP request, with tx, logs and message
230
321
  * @returns array with one offchain token data for each token transfer in request
231
322
  */
232
323
  abstract fetchOffchainTokenData(request: CCIPRequest): Promise<OffchainTokenData[]>
324
+ /**
325
+ * Generate unsigned tx to manuallyExecute a message
326
+ * @param payer - address which will be used to transmit the report tx
327
+ * @param offRamp - address of the OffRamp contract
328
+ * @param execReport - execution report
329
+ * @param gasLimit - gasLimit or computeUnits limit override for the ccipReceive call
330
+ * @param tokensGasLimit - For EVM, overrides gasLimit on tokenpPool call
331
+ * @param forceBuffer - For Solana, send report in chunks to OffRamp, to later execute
332
+ * @param forceLookupTable - For Solana, create and extend addresses in a lookup table before executing
333
+ * @returns chain-family specific unsigned txs
334
+ */
335
+ abstract generateUnsignedExecuteReport(
336
+ payer: string,
337
+ offRamp: string,
338
+ execReport: ExecutionReport,
339
+ opts: {
340
+ gasLimit?: number
341
+ tokensGasLimit?: number
342
+ forceBuffer?: boolean
343
+ forceLookupTable?: boolean
344
+ },
345
+ ): Promise<UnsignedTx[F]>
233
346
  /**
234
347
  * Execute messages in report in an offRamp
235
348
  * @param offRamp - offRamp address on this dest chain
236
349
  * @param execReport - execution report containing messages to execute, proofs and offchainTokenData
237
- * @param opts - general options for execution
238
- * @returns transaction hash of the execution
350
+ * @param opts - general options for execution (see [[generateUnsignedExecuteReport]])
351
+ * @param wallet - chain-specific wallet or signer instance, to sign transactions
352
+ * @returns transaction of the execution
239
353
  */
240
354
  abstract executeReport(
241
355
  offRamp: string,
242
356
  execReport: ExecutionReport,
243
- opts?: Record<string, unknown>,
357
+ opts: {
358
+ wallet: unknown
359
+ gasLimit?: number
360
+ tokensGasLimit?: number
361
+ forceBuffer?: boolean
362
+ forceLookupTable?: boolean
363
+ },
244
364
  ): Promise<ChainTransaction>
245
365
 
246
366
  /**
247
367
  * Look for a CommitReport at dest for given CCIP request
248
368
  * May be specialized by some subclasses
249
369
  *
250
- * @param dest - Destination network provider
251
- * @param request - CCIP request info
370
+ * @param commitStore - Commit store address
371
+ * @param request - CCIPRequest to get commit info for
252
372
  * @param hints - Additional filtering hints
253
- * @returns CCIP commit info
373
+ * @returns CCIPCommit info, or reject if none found
254
374
  **/
255
375
  async fetchCommitReport(
256
376
  commitStore: string,
257
- request: {
258
- lane: Lane
259
- message: { header: { sequenceNumber: bigint } }
260
- timestamp?: number
261
- },
377
+ request: PickDeep<CCIPRequest, 'lane' | 'message.header.sequenceNumber' | 'tx.timestamp'>,
262
378
  hints?: { startBlock?: number; page?: number },
263
379
  ): Promise<CCIPCommit> {
264
380
  return fetchCommitReport(this, commitStore, request, hints)
@@ -267,23 +383,39 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
267
383
  /**
268
384
  * Default/generic implementation of fetchExecutionReceipts
269
385
  * @param offRamp - Off-ramp address
270
- * @param messageIds - Set of message IDs to fetch receipts for
386
+ * @param request - CCIPRequest to get execution receipts for
387
+ * @param commit - CCIPCommit info to help narrowing search for executions
271
388
  * @param hints - Additional filtering hints
272
- * @returns Async generator of CCIP execution receipts
389
+ * @returns Async generator of CCIPExecution receipts
273
390
  */
274
391
  async *fetchExecutionReceipts(
275
392
  offRamp: string,
276
- messageIds: Set<string>,
277
- hints?: { startBlock?: number; startTime?: number; page?: number; commit?: CommitReport },
278
- ): AsyncGenerator<CCIPExecution> {
279
- yield* fetchExecutionReceipts(this, offRamp, messageIds, hints)
393
+ request: PickDeep<CCIPRequest, 'lane' | 'message.header.messageId' | 'tx.timestamp'>,
394
+ commit?: CCIPCommit,
395
+ hints?: { page?: number },
396
+ ): AsyncIterableIterator<CCIPExecution> {
397
+ const onlyLast = !commit?.log.blockNumber && !request.tx.timestamp // backwards
398
+ for await (const log of this.getLogs({
399
+ startBlock: commit?.log.blockNumber,
400
+ startTime: request.tx.timestamp,
401
+ address: offRamp,
402
+ topics: ['ExecutionStateChanged'],
403
+ ...hints,
404
+ })) {
405
+ const receipt = (this.constructor as ChainStatic).decodeReceipt(log)
406
+ if (!receipt || receipt.messageId !== request.message.header.messageId) continue
407
+
408
+ const timestamp = log.tx?.timestamp ?? (await this.getBlockTimestamp(log.blockNumber))
409
+ yield { receipt, log, timestamp }
410
+ if (onlyLast || receipt.state === ExecutionState.Success) break
411
+ }
280
412
  }
281
413
 
282
414
  /**
283
- * List tokens supported by given TokenAdminRegistry contract
284
- * @param address - Usually TokenAdminRegistry, but chain may support receiving Router, OnRamp, etc
285
- * @param opts.page - Page range, if needed
286
- * @retursn array of supported token addresses
415
+ * List tokens supported by given TokenAdminRegistry contract.
416
+ * @param address - Usually TokenAdminRegistry, but chain may support receiving Router, OnRamp, etc.
417
+ * @param opts - Optional parameters (e.g., `page` for pagination range).
418
+ * @returns Array of supported token addresses.
287
419
  */
288
420
  abstract getSupportedTokens(address: string, opts?: { page?: number }): Promise<string[]>
289
421
 
@@ -312,10 +444,10 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
312
444
  }>
313
445
 
314
446
  /**
315
- * Get TokenPool remote configurations
316
- * @param tokenPool - Token pool address
317
- * @param remoteChainSelector - If provided, only return remotes for the specified chain (may error if remote not supported)
318
- * @param Record of network *names* and remote configurations (remoteToken, remotePools, rateLimitStates)
447
+ * Get TokenPool remote configurations.
448
+ * @param tokenPool - Token pool address.
449
+ * @param remoteChainSelector - If provided, only return remotes for the specified chain (may error if remote not supported).
450
+ * @returns Record of network names and remote configurations (remoteToken, remotePools, rateLimitStates).
319
451
  */
320
452
  abstract getTokenPoolRemotes(
321
453
  tokenPool: string,
@@ -323,13 +455,14 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
323
455
  ): Promise<Record<string, TokenPoolRemote>>
324
456
 
325
457
  /**
326
- * Fetch list and info of supported feeTokens
327
- * @param router address on this chain
328
- * @returns mapping of token addresses to respective TokenInfo objects
458
+ * Fetch list and info of supported feeTokens.
459
+ * @param router - Router address on this chain.
460
+ * @returns Mapping of token addresses to respective TokenInfo objects.
329
461
  */
330
- abstract listFeeTokens(router: string): Promise<Record<string, TokenInfo>>
462
+ abstract getFeeTokens(router: string): Promise<Record<string, TokenInfo>>
331
463
  }
332
464
 
465
+ /** Static methods and properties available on Chain class constructors. */
333
466
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
334
467
  export type ChainStatic<F extends ChainFamily = ChainFamily> = Function & {
335
468
  readonly family: F
@@ -338,7 +471,7 @@ export type ChainStatic<F extends ChainFamily = ChainFamily> = Function & {
338
471
  * async constructor: builds a Chain from a rpc endpoint url
339
472
  * @param url - rpc endpoint url
340
473
  */
341
- fromUrl(url: string): Promise<Chain<F>>
474
+ fromUrl(url: string, ctx?: WithLogger): Promise<Chain<F>>
342
475
  /**
343
476
  * Try to decode a CCIP message *from* a log/event *originated* from this *source* chain,
344
477
  * but which may *target* other dest chain families
@@ -384,15 +517,17 @@ export type ChainStatic<F extends ChainFamily = ChainFamily> = Function & {
384
517
  /**
385
518
  * Create a leaf hasher for this dest chain and lane
386
519
  * @param lane - source, dest and onramp lane info
520
+ * @param ctx - context object containing logger
387
521
  * @returns LeafHasher is a function that takes a message and returns a hash of it
388
522
  */
389
- getDestLeafHasher(lane: Lane): LeafHasher
523
+ getDestLeafHasher(lane: Lane, ctx?: WithLogger): LeafHasher
390
524
  /**
391
525
  * Try to parse an error or bytearray generated by this chain family
392
- * @param error - catched object, string or bytearray
526
+ * @param data - Caught object, string or bytearray
393
527
  * @returns Ordered record with messages/properties, or undefined if not a recognized error
394
528
  */
395
529
  parse?(data: unknown): Record<string, unknown> | undefined | null
396
530
  }
397
531
 
532
+ /** Function type for getting a Chain instance by ID, selector, or name. */
398
533
  export type ChainGetter = (idOrSelectorOrName: number | string | bigint) => Promise<Chain>
package/src/commits.ts CHANGED
@@ -1,5 +1,7 @@
1
+ import type { PickDeep } from 'type-fest'
2
+
1
3
  import type { Chain, ChainStatic } from './chain.ts'
2
- import { type CCIPCommit, type Lane, CCIPVersion } from './types.ts'
4
+ import { type CCIPCommit, type CCIPRequest, CCIPVersion } from './types.ts'
3
5
 
4
6
  /**
5
7
  * Look for a CommitReport at dest for given CCIPRequest
@@ -7,6 +9,7 @@ import { type CCIPCommit, type Lane, CCIPVersion } from './types.ts'
7
9
  * logic in Chain.fetchCommitReport method
8
10
  *
9
11
  * @param dest - Destination network provider
12
+ * @param commitStore - Commit store address
10
13
  * @param request - CCIP request info
11
14
  * @param hints - Additional filtering hints
12
15
  * @returns CCIP commit info
@@ -17,12 +20,8 @@ export async function fetchCommitReport(
17
20
  {
18
21
  lane,
19
22
  message: { header },
20
- timestamp: requestTimestamp,
21
- }: {
22
- lane: Lane
23
- message: { header: { sequenceNumber: bigint } }
24
- timestamp?: number
25
- },
23
+ tx: { timestamp: requestTimestamp },
24
+ }: PickDeep<CCIPRequest, 'lane' | 'message.header.sequenceNumber' | 'tx.timestamp'>,
26
25
  hints?: { startBlock?: number; page?: number },
27
26
  ): Promise<CCIPCommit> {
28
27
  for await (const log of dest.getLogs({
package/src/evm/const.ts CHANGED
@@ -46,6 +46,11 @@ export const interfaces = {
46
46
  Custom: new Interface(customErrors),
47
47
  } as const
48
48
 
49
+ /**
50
+ * Gets all event fragments matching the given event names.
51
+ * @param events - Event names to match.
52
+ * @returns Map of topic hash to event fragment.
53
+ */
49
54
  export function getAllFragmentsMatchingEvents(
50
55
  events: readonly string[],
51
56
  ): Record<`0x${string}`, EventFragment> {
package/src/evm/errors.ts CHANGED
@@ -12,8 +12,8 @@ import {
12
12
  } from 'ethers'
13
13
 
14
14
  import { defaultAbiCoder, interfaces } from './const.ts'
15
- import { ChainFamily } from '../chain.ts'
16
15
  import { decodeExtraArgs } from '../extra-args.ts'
16
+ import { ChainFamily } from '../types.ts'
17
17
 
18
18
  /**
19
19
  * Get error data from an error object, if possible
@@ -173,6 +173,11 @@ export function recursiveParseError(
173
173
  return res
174
174
  }
175
175
 
176
+ /**
177
+ * Parses error data and transaction responses to extract human-readable info.
178
+ * @param data - Raw error data or transaction response.
179
+ * @returns Parsed error information or undefined.
180
+ */
176
181
  export function parseData(data: unknown): Record<string, unknown> | undefined {
177
182
  if (!data) return
178
183
  if (isHexString(data)) {
package/src/evm/hasher.ts CHANGED
@@ -1,13 +1,21 @@
1
1
  import { concat, id, keccak256, toBeHex, zeroPadValue } from 'ethers'
2
+ import type { ReadonlyDeep } from 'type-fest'
2
3
 
3
4
  import { decodeExtraArgs } from '../extra-args.ts'
4
5
  import { type LeafHasher, LEAF_DOMAIN_SEPARATOR } from '../hasher/common.ts'
5
- import type { CCIPMessage, CCIPVersion, DeepReadonly } from '../types.ts'
6
+ import type { CCIPMessage, CCIPVersion, WithLogger } from '../types.ts'
6
7
  import { getAddressBytes, getDataBytes, networkInfo } from '../utils.ts'
7
8
  import { defaultAbiCoder } from './const.ts'
8
9
 
9
10
  const METADATA_PREFIX_1_2 = id('EVM2EVMMessageHashV2')
10
11
 
12
+ /**
13
+ * Creates a leaf hasher for v1.2/v1.5 EVM CCIP messages.
14
+ * @param sourceChainSelector - Source chain selector.
15
+ * @param destChainSelector - Destination chain selector.
16
+ * @param onRamp - OnRamp contract address.
17
+ * @returns Leaf hasher function.
18
+ */
11
19
  export function getV12LeafHasher(
12
20
  sourceChainSelector: bigint,
13
21
  destChainSelector: bigint,
@@ -80,10 +88,18 @@ export function getV12LeafHasher(
80
88
 
81
89
  const ANY_2_EVM_MESSAGE_HASH = id('Any2EVMMessageHashV1')
82
90
 
91
+ /**
92
+ * Creates a leaf hasher for v1.6 EVM CCIP messages.
93
+ * @param sourceChainSelector - Source chain selector.
94
+ * @param destChainSelector - Destination chain selector.
95
+ * @param onRamp - OnRamp contract address.
96
+ * @returns Leaf hasher function.
97
+ */
83
98
  export function getV16LeafHasher(
84
99
  sourceChainSelector: bigint,
85
100
  destChainSelector: bigint,
86
101
  onRamp: string,
102
+ { logger = console }: WithLogger = {},
87
103
  ): LeafHasher<typeof CCIPVersion.V1_6> {
88
104
  const metadataInput = concat([
89
105
  ANY_2_EVM_MESSAGE_HASH,
@@ -92,8 +108,8 @@ export function getV16LeafHasher(
92
108
  keccak256(zeroPadValue(getAddressBytes(onRamp), 32)),
93
109
  ])
94
110
 
95
- return (message: DeepReadonly<CCIPMessage<typeof CCIPVersion.V1_6>>): string => {
96
- console.debug('Message', message)
111
+ return (message: ReadonlyDeep<CCIPMessage<typeof CCIPVersion.V1_6>>): string => {
112
+ logger.debug('Message', message)
97
113
  const parsedArgs = decodeExtraArgs(
98
114
  message.extraArgs,
99
115
  networkInfo(message.header.sourceChainSelector).family,
@@ -153,7 +169,7 @@ export function getV16LeafHasher(
153
169
  ],
154
170
  )
155
171
 
156
- console.debug('v1.6 leafHasher:', {
172
+ logger.debug('v1.6 leafHasher:', {
157
173
  messageId: message.header.messageId,
158
174
  encodedTokens,
159
175
  fixedSizeValues,