@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.
- package/dist/api/index.d.ts +17 -8
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +27 -10
- package/dist/api/index.js.map +1 -1
- package/dist/api/types.d.ts +0 -2
- package/dist/api/types.d.ts.map +1 -1
- package/dist/aptos/exec.d.ts +2 -2
- package/dist/aptos/exec.d.ts.map +1 -1
- package/dist/aptos/exec.js.map +1 -1
- package/dist/aptos/hasher.d.ts.map +1 -1
- package/dist/aptos/hasher.js +1 -1
- package/dist/aptos/hasher.js.map +1 -1
- package/dist/aptos/index.d.ts +13 -10
- package/dist/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +42 -68
- package/dist/aptos/index.js.map +1 -1
- package/dist/aptos/types.d.ts +2 -19
- package/dist/aptos/types.d.ts.map +1 -1
- package/dist/aptos/types.js +0 -11
- package/dist/aptos/types.js.map +1 -1
- package/dist/chain.d.ts +532 -151
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +113 -18
- package/dist/chain.js.map +1 -1
- package/dist/commits.d.ts +4 -6
- package/dist/commits.d.ts.map +1 -1
- package/dist/commits.js +4 -4
- package/dist/commits.js.map +1 -1
- package/dist/errors/CCIPError.d.ts +33 -4
- package/dist/errors/CCIPError.d.ts.map +1 -1
- package/dist/errors/CCIPError.js +33 -4
- package/dist/errors/CCIPError.js.map +1 -1
- package/dist/errors/codes.d.ts +3 -0
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/errors/codes.js +3 -1
- package/dist/errors/codes.js.map +1 -1
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/errors/index.js.map +1 -1
- package/dist/errors/recovery.d.ts.map +1 -1
- package/dist/errors/recovery.js +4 -1
- package/dist/errors/recovery.js.map +1 -1
- package/dist/errors/specialized.d.ts +1695 -120
- package/dist/errors/specialized.d.ts.map +1 -1
- package/dist/errors/specialized.js +1715 -123
- package/dist/errors/specialized.js.map +1 -1
- package/dist/errors/utils.d.ts.map +1 -1
- package/dist/errors/utils.js +0 -1
- package/dist/errors/utils.js.map +1 -1
- package/dist/evm/abi/OffRamp_2_0.d.ts +764 -0
- package/dist/evm/abi/OffRamp_2_0.d.ts.map +1 -0
- package/dist/evm/abi/OffRamp_2_0.js +744 -0
- package/dist/evm/abi/OffRamp_2_0.js.map +1 -0
- package/dist/evm/abi/OnRamp_2_0.d.ts +925 -0
- package/dist/evm/abi/OnRamp_2_0.d.ts.map +1 -0
- package/dist/evm/abi/OnRamp_2_0.js +992 -0
- package/dist/evm/abi/OnRamp_2_0.js.map +1 -0
- package/dist/evm/const.d.ts +12 -2
- package/dist/evm/const.d.ts.map +1 -1
- package/dist/evm/const.js +8 -2
- package/dist/evm/const.js.map +1 -1
- package/dist/evm/errors.d.ts.map +1 -1
- package/dist/evm/errors.js +7 -2
- package/dist/evm/errors.js.map +1 -1
- package/dist/evm/extra-args.d.ts.map +1 -1
- package/dist/evm/extra-args.js +5 -24
- package/dist/evm/extra-args.js.map +1 -1
- package/dist/evm/hasher.d.ts.map +1 -1
- package/dist/evm/hasher.js +23 -13
- package/dist/evm/hasher.js.map +1 -1
- package/dist/evm/index.d.ts +73 -14
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +240 -141
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/messages.d.ts +59 -5
- package/dist/evm/messages.d.ts.map +1 -1
- package/dist/evm/messages.js +210 -0
- package/dist/evm/messages.js.map +1 -1
- package/dist/evm/offchain.js.map +1 -1
- package/dist/evm/types.d.ts +7 -2
- package/dist/evm/types.d.ts.map +1 -1
- package/dist/evm/types.js +22 -1
- package/dist/evm/types.js.map +1 -1
- package/dist/execution.d.ts +62 -22
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +98 -61
- package/dist/execution.js.map +1 -1
- package/dist/extra-args.d.ts +13 -3
- package/dist/extra-args.d.ts.map +1 -1
- package/dist/extra-args.js +13 -3
- package/dist/extra-args.js.map +1 -1
- package/dist/gas.d.ts +25 -2
- package/dist/gas.d.ts.map +1 -1
- package/dist/gas.js +30 -4
- package/dist/gas.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/requests.d.ts +85 -14
- package/dist/requests.d.ts.map +1 -1
- package/dist/requests.js +99 -16
- package/dist/requests.js.map +1 -1
- package/dist/selectors.d.ts.map +1 -1
- package/dist/selectors.js +12 -0
- package/dist/selectors.js.map +1 -1
- package/dist/shared/bcs-codecs.d.ts +61 -0
- package/dist/shared/bcs-codecs.d.ts.map +1 -0
- package/dist/shared/bcs-codecs.js +102 -0
- package/dist/shared/bcs-codecs.js.map +1 -0
- package/dist/shared/constants.d.ts +3 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +3 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/solana/exec.d.ts +2 -2
- package/dist/solana/exec.d.ts.map +1 -1
- package/dist/solana/exec.js.map +1 -1
- package/dist/solana/index.d.ts +80 -17
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +67 -30
- package/dist/solana/index.js.map +1 -1
- package/dist/sui/hasher.d.ts.map +1 -1
- package/dist/sui/hasher.js +1 -1
- package/dist/sui/hasher.js.map +1 -1
- package/dist/sui/index.d.ts +14 -12
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +38 -34
- package/dist/sui/index.js.map +1 -1
- package/dist/sui/manuallyExec/encoder.d.ts +2 -2
- package/dist/sui/manuallyExec/encoder.d.ts.map +1 -1
- package/dist/sui/manuallyExec/encoder.js.map +1 -1
- package/dist/sui/manuallyExec/index.d.ts +2 -2
- package/dist/sui/manuallyExec/index.d.ts.map +1 -1
- package/dist/ton/exec.d.ts +2 -2
- package/dist/ton/exec.d.ts.map +1 -1
- package/dist/ton/exec.js.map +1 -1
- package/dist/ton/index.d.ts +9 -16
- package/dist/ton/index.d.ts.map +1 -1
- package/dist/ton/index.js +26 -31
- package/dist/ton/index.js.map +1 -1
- package/dist/ton/types.d.ts +2 -2
- package/dist/ton/types.d.ts.map +1 -1
- package/dist/ton/types.js.map +1 -1
- package/dist/types.d.ts +46 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -1
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +65 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +74 -2
- package/dist/utils.js.map +1 -1
- package/package.json +9 -9
- package/src/api/index.ts +33 -10
- package/src/api/types.ts +0 -2
- package/src/aptos/exec.ts +2 -2
- package/src/aptos/hasher.ts +1 -1
- package/src/aptos/index.ts +51 -89
- package/src/aptos/types.ts +2 -15
- package/src/chain.ts +581 -163
- package/src/commits.ts +9 -9
- package/src/errors/CCIPError.ts +33 -4
- package/src/errors/codes.ts +3 -1
- package/src/errors/index.ts +1 -0
- package/src/errors/recovery.ts +7 -1
- package/src/errors/specialized.ts +1726 -130
- package/src/errors/utils.ts +0 -1
- package/src/evm/abi/OffRamp_2_0.ts +743 -0
- package/src/evm/abi/OnRamp_2_0.ts +991 -0
- package/src/evm/const.ts +10 -3
- package/src/evm/errors.ts +6 -2
- package/src/evm/extra-args.ts +4 -21
- package/src/evm/hasher.ts +30 -18
- package/src/evm/index.ts +310 -166
- package/src/evm/messages.ts +323 -11
- package/src/evm/offchain.ts +2 -2
- package/src/evm/types.ts +20 -2
- package/src/execution.ts +125 -86
- package/src/extra-args.ts +13 -3
- package/src/gas.ts +29 -3
- package/src/index.ts +2 -2
- package/src/requests.ts +112 -16
- package/src/selectors.ts +12 -0
- package/src/shared/bcs-codecs.ts +132 -0
- package/src/shared/constants.ts +2 -0
- package/src/solana/exec.ts +4 -4
- package/src/solana/index.ts +100 -68
- package/src/sui/hasher.ts +1 -1
- package/src/sui/index.ts +50 -47
- package/src/sui/manuallyExec/encoder.ts +2 -2
- package/src/sui/manuallyExec/index.ts +2 -2
- package/src/ton/exec.ts +2 -2
- package/src/ton/index.ts +37 -40
- package/src/ton/types.ts +2 -2
- package/src/types.ts +70 -29
- package/src/utils.ts +73 -2
- package/dist/aptos/utils.d.ts +0 -12
- package/dist/aptos/utils.d.ts.map +0 -1
- package/dist/aptos/utils.js +0 -15
- package/dist/aptos/utils.js.map +0 -1
- 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 {
|
|
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 =
|
|
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.
|
|
303
|
+
* Common options for {@link Chain.generateUnsignedExecute} and {@link Chain.execute} methods.
|
|
302
304
|
*/
|
|
303
|
-
export type
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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 =
|
|
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
|
-
*
|
|
372
|
-
* @
|
|
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
|
-
*
|
|
379
|
-
* @
|
|
380
|
-
* @
|
|
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
|
-
*
|
|
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
|
-
*
|
|
531
|
-
*
|
|
532
|
-
* @param
|
|
533
|
-
* @
|
|
594
|
+
* To be implemented for chains supporting CCIPVersion <= 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
|
-
|
|
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
|
-
|
|
617
|
+
range: Pick<CommitReport, 'minSeqNr' | 'maxSeqNr'>,
|
|
544
618
|
opts?: { page?: number },
|
|
545
619
|
): Promise<R['message'][]>
|
|
620
|
+
|
|
546
621
|
/**
|
|
547
|
-
* Fetch
|
|
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
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
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 -
|
|
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 -
|
|
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
|
-
*
|
|
577
|
-
* @
|
|
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 -
|
|
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 -
|
|
592
|
-
* @returns OnRamp
|
|
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
|
|
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 -
|
|
600
|
-
* @returns
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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({
|
|
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
|
-
*
|
|
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
|
-
*
|
|
649
|
-
* @
|
|
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
|
-
* @
|
|
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
|
|
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
|
-
*
|
|
706
|
-
* @
|
|
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
|
|
709
|
-
opts:
|
|
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
|
-
* @
|
|
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
|
|
722
|
-
*
|
|
723
|
-
*
|
|
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
|
|
743
|
-
opts:
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
757
|
-
|
|
993
|
+
async getVerifications({
|
|
994
|
+
offRamp,
|
|
758
995
|
request,
|
|
759
996
|
...hints
|
|
760
997
|
}: {
|
|
761
|
-
/** address of
|
|
762
|
-
|
|
998
|
+
/** address of offRamp or commitStore contract */
|
|
999
|
+
offRamp: string
|
|
763
1000
|
/** CCIPRequest subset object */
|
|
764
|
-
request: PickDeep<
|
|
765
|
-
|
|
766
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1081
|
+
verifications?: CCIPVerifications
|
|
828
1082
|
} & Pick<
|
|
829
1083
|
LogFilter,
|
|
830
1084
|
'page' | 'watch' | 'startBlock' | 'startTime'
|
|
831
1085
|
>): AsyncIterableIterator<CCIPExecution> {
|
|
832
|
-
hints.startBlock ??=
|
|
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 -
|
|
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
|
|
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
|
-
*
|
|
911
|
-
*
|
|
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
|
|
1185
|
+
* @example Type-safe access to chain-specific fields
|
|
914
1186
|
* ```typescript
|
|
915
|
-
*
|
|
916
|
-
*
|
|
917
|
-
*
|
|
918
|
-
*
|
|
919
|
-
*
|
|
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
|
-
*
|
|
1007
|
-
* @
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
1075
|
-
*
|
|
1076
|
-
* @param
|
|
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
|
|
1081
|
-
* but
|
|
1082
|
-
*
|
|
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
|
|
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
|
-
*
|
|
1091
|
-
* @
|
|
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 -
|
|
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
|
-
*
|
|
1142
|
-
* @param
|
|
1143
|
-
* @
|
|
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
|
|
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
|
/**
|