@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/solana/index.ts
CHANGED
|
@@ -73,14 +73,14 @@ import SELECTORS from '../selectors.ts'
|
|
|
73
73
|
import { supportedChains } from '../supported-chains.ts'
|
|
74
74
|
import {
|
|
75
75
|
type AnyMessage,
|
|
76
|
-
type CCIPCommit,
|
|
77
76
|
type CCIPExecution,
|
|
78
77
|
type CCIPMessage,
|
|
79
78
|
type CCIPRequest,
|
|
79
|
+
type CCIPVerifications,
|
|
80
80
|
type ChainTransaction,
|
|
81
81
|
type CommitReport,
|
|
82
|
+
type ExecutionInput,
|
|
82
83
|
type ExecutionReceipt,
|
|
83
|
-
type ExecutionReport,
|
|
84
84
|
type Lane,
|
|
85
85
|
type Log_,
|
|
86
86
|
type MergeArrayElements,
|
|
@@ -96,6 +96,7 @@ import {
|
|
|
96
96
|
createRateLimitedFetch,
|
|
97
97
|
decodeAddress,
|
|
98
98
|
decodeOnRampAddress,
|
|
99
|
+
getAddressBytes,
|
|
99
100
|
getDataBytes,
|
|
100
101
|
leToBigInt,
|
|
101
102
|
networkInfo,
|
|
@@ -126,7 +127,7 @@ import {
|
|
|
126
127
|
} from './utils.ts'
|
|
127
128
|
import { buildMessageForDest, getMessagesInBatch } from '../requests.ts'
|
|
128
129
|
import { patchBorsh } from './patchBorsh.ts'
|
|
129
|
-
import { DEFAULT_GAS_LIMIT } from '../
|
|
130
|
+
import { DEFAULT_GAS_LIMIT } from '../shared/constants.ts'
|
|
130
131
|
export type { UnsignedSolanaTx }
|
|
131
132
|
|
|
132
133
|
const routerCoder = new BorshCoder(CCIP_ROUTER_IDL)
|
|
@@ -171,6 +172,29 @@ export type SolanaTransaction = MergeArrayElements<
|
|
|
171
172
|
|
|
172
173
|
/**
|
|
173
174
|
* Solana chain implementation supporting Solana networks.
|
|
175
|
+
*
|
|
176
|
+
* Provides methods for sending CCIP cross-chain messages, querying message
|
|
177
|
+
* status, fetching fee quotes, and manually executing pending messages on
|
|
178
|
+
* Solana networks.
|
|
179
|
+
*
|
|
180
|
+
* @remarks
|
|
181
|
+
* Solana uses CCIP v1.6+ protocol only.
|
|
182
|
+
*
|
|
183
|
+
* @example Create from RPC URL
|
|
184
|
+
* ```typescript
|
|
185
|
+
* import { SolanaChain } from '@chainlink/ccip-sdk'
|
|
186
|
+
*
|
|
187
|
+
* const chain = await SolanaChain.fromUrl('https://api.devnet.solana.com')
|
|
188
|
+
* console.log(`Connected to: ${chain.network.name}`)
|
|
189
|
+
* ```
|
|
190
|
+
*
|
|
191
|
+
* @example Query messages in a transaction
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const requests = await chain.getMessagesInTx('5abc123...')
|
|
194
|
+
* for (const req of requests) {
|
|
195
|
+
* console.log(`Message ID: ${req.message.messageId}`)
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
174
198
|
*/
|
|
175
199
|
export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
176
200
|
static {
|
|
@@ -284,9 +308,20 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
284
308
|
|
|
285
309
|
/**
|
|
286
310
|
* Creates a SolanaChain instance from an RPC URL.
|
|
287
|
-
*
|
|
288
|
-
* @param
|
|
289
|
-
* @
|
|
311
|
+
*
|
|
312
|
+
* @param url - RPC endpoint URL (https://, http://, wss://, or ws://).
|
|
313
|
+
* @param ctx - Optional context containing logger and API client configuration.
|
|
314
|
+
* @returns A new SolanaChain instance connected to the specified network.
|
|
315
|
+
* @throws {@link CCIPChainNotFoundError} if chain cannot be identified from genesis hash
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```typescript
|
|
319
|
+
* // Create from devnet URL
|
|
320
|
+
* const chain = await SolanaChain.fromUrl('https://api.devnet.solana.com')
|
|
321
|
+
*
|
|
322
|
+
* // With custom logger
|
|
323
|
+
* const chain = await SolanaChain.fromUrl(url, { logger: customLogger })
|
|
324
|
+
* ```
|
|
290
325
|
*/
|
|
291
326
|
static async fromUrl(url: string, ctx?: ChainContext): Promise<SolanaChain> {
|
|
292
327
|
const connection = this._getConnection(url, ctx)
|
|
@@ -442,15 +477,15 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
442
477
|
}
|
|
443
478
|
|
|
444
479
|
/** {@inheritDoc Chain.getMessagesInBatch} */
|
|
445
|
-
async getMessagesInBatch<
|
|
480
|
+
override async getMessagesInBatch<
|
|
446
481
|
R extends PickDeep<
|
|
447
482
|
CCIPRequest,
|
|
448
483
|
'lane' | `log.${'topics' | 'address' | 'blockNumber'}` | 'message.sequenceNumber'
|
|
449
484
|
>,
|
|
450
485
|
>(
|
|
451
486
|
request: R,
|
|
452
|
-
|
|
453
|
-
opts?:
|
|
487
|
+
range: Pick<CommitReport, 'minSeqNr' | 'maxSeqNr'>,
|
|
488
|
+
opts?: Pick<LogFilter, 'page'>,
|
|
454
489
|
): Promise<R['message'][]> {
|
|
455
490
|
const [destChainStatePda] = PublicKey.findProgramAddressSync(
|
|
456
491
|
[Buffer.from('dest_chain_state'), toLeArray(request.lane.destChainSelector, 8)],
|
|
@@ -463,7 +498,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
463
498
|
programs: [request.log.address],
|
|
464
499
|
address: destChainStatePda.toBase58(),
|
|
465
500
|
}
|
|
466
|
-
return getMessagesInBatch(this, request,
|
|
501
|
+
return getMessagesInBatch(this, request, range, opts_)
|
|
467
502
|
}
|
|
468
503
|
|
|
469
504
|
/** {@inheritDoc Chain.typeAndVersion} */
|
|
@@ -548,8 +583,8 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
548
583
|
return Promise.resolve(router) // solana's Router is also the OnRamp
|
|
549
584
|
}
|
|
550
585
|
|
|
551
|
-
/** {@inheritDoc Chain.
|
|
552
|
-
async
|
|
586
|
+
/** {@inheritDoc Chain.getOnRampsForOffRamp} */
|
|
587
|
+
async getOnRampsForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise<string[]> {
|
|
553
588
|
const program = new Program(CCIP_OFFRAMP_IDL, new PublicKey(offRamp), {
|
|
554
589
|
connection: this.connection,
|
|
555
590
|
})
|
|
@@ -563,15 +598,12 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
563
598
|
const {
|
|
564
599
|
config: { onRamp },
|
|
565
600
|
} = await program.account.sourceChain.fetch(statePda)
|
|
566
|
-
return
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
/** {@inheritDoc Chain.getCommitStoreForOffRamp} */
|
|
573
|
-
getCommitStoreForOffRamp(offRamp: string): Promise<string> {
|
|
574
|
-
return Promise.resolve(offRamp) // Solana supports only CCIP>=1.6, for which OffRamp and CommitStore are the same
|
|
601
|
+
return [
|
|
602
|
+
decodeAddress(
|
|
603
|
+
getAddressBytes(onRamp.bytes).subarray(0, onRamp.len),
|
|
604
|
+
networkInfo(sourceChainSelector).family,
|
|
605
|
+
),
|
|
606
|
+
]
|
|
575
607
|
}
|
|
576
608
|
|
|
577
609
|
/**
|
|
@@ -1081,7 +1113,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1081
1113
|
}
|
|
1082
1114
|
|
|
1083
1115
|
/**
|
|
1084
|
-
* {@inheritDoc Chain.
|
|
1116
|
+
* {@inheritDoc Chain.generateUnsignedExecute}
|
|
1085
1117
|
* @returns instructions - array of instructions to execute the report
|
|
1086
1118
|
* lookupTables - array of lookup tables for `manuallyExecute` call
|
|
1087
1119
|
* mainIndex - index of the `manuallyExecute` instruction in the array; last unless
|
|
@@ -1089,15 +1121,14 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1089
1121
|
* second to last
|
|
1090
1122
|
* @throws {@link CCIPExecutionReportChainMismatchError} if message is not a Solana message
|
|
1091
1123
|
*/
|
|
1092
|
-
async
|
|
1124
|
+
async generateUnsignedExecute({
|
|
1093
1125
|
payer,
|
|
1094
|
-
offRamp,
|
|
1095
|
-
execReport,
|
|
1096
1126
|
...opts
|
|
1097
|
-
}: Parameters<Chain['
|
|
1098
|
-
if (!('computeUnits' in
|
|
1127
|
+
}: Parameters<Chain['generateUnsignedExecute']>[0]): Promise<UnsignedSolanaTx> {
|
|
1128
|
+
if (!('input' in opts) || !('message' in opts.input) || !('computeUnits' in opts.input.message))
|
|
1099
1129
|
throw new CCIPExecutionReportChainMismatchError('Solana')
|
|
1100
|
-
const
|
|
1130
|
+
const { offRamp, input } = opts
|
|
1131
|
+
const execReport_ = input as ExecutionInput<CCIPMessage_V1_6_Solana>
|
|
1101
1132
|
return generateUnsignedExecuteReport(
|
|
1102
1133
|
this,
|
|
1103
1134
|
new PublicKey(payer),
|
|
@@ -1108,11 +1139,11 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1108
1139
|
}
|
|
1109
1140
|
|
|
1110
1141
|
/**
|
|
1111
|
-
* {@inheritDoc Chain.
|
|
1142
|
+
* {@inheritDoc Chain.execute}
|
|
1112
1143
|
* @throws {@link CCIPWalletInvalidError} if wallet is not a valid Solana wallet
|
|
1113
1144
|
*/
|
|
1114
|
-
async
|
|
1115
|
-
opts: Parameters<Chain['
|
|
1145
|
+
async execute(
|
|
1146
|
+
opts: Parameters<Chain['execute']>[0] & {
|
|
1116
1147
|
// when cleaning leftover LookUp Tables, wait deactivation grace period (~513 slots) then close ALT
|
|
1117
1148
|
waitDeactivation?: boolean
|
|
1118
1149
|
},
|
|
@@ -1123,7 +1154,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1123
1154
|
let hash
|
|
1124
1155
|
do {
|
|
1125
1156
|
try {
|
|
1126
|
-
const unsigned = await this.
|
|
1157
|
+
const unsigned = await this.generateUnsignedExecute({
|
|
1127
1158
|
...opts,
|
|
1128
1159
|
payer: wallet.publicKey.toBase58(),
|
|
1129
1160
|
})
|
|
@@ -1199,39 +1230,36 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1199
1230
|
/**
|
|
1200
1231
|
* Solana specialization: use getProgramAccounts to fetch commit reports from PDAs
|
|
1201
1232
|
*/
|
|
1202
|
-
override async
|
|
1203
|
-
opts: Parameters<Chain['
|
|
1204
|
-
): Promise<
|
|
1205
|
-
const {
|
|
1206
|
-
const commitsAroundSeqNum = await this.connection.getProgramAccounts(
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
{
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
offset: 0,
|
|
1214
|
-
bytes: encodeBase58(BorshAccountsCoder.accountDiscriminator('CommitReport')),
|
|
1215
|
-
},
|
|
1233
|
+
override async getVerifications(
|
|
1234
|
+
opts: Parameters<Chain['getVerifications']>[0],
|
|
1235
|
+
): Promise<CCIPVerifications> {
|
|
1236
|
+
const { offRamp, request } = opts
|
|
1237
|
+
const commitsAroundSeqNum = await this.connection.getProgramAccounts(new PublicKey(offRamp), {
|
|
1238
|
+
filters: [
|
|
1239
|
+
{
|
|
1240
|
+
// commit report account discriminator filter
|
|
1241
|
+
memcmp: {
|
|
1242
|
+
offset: 0,
|
|
1243
|
+
bytes: encodeBase58(BorshAccountsCoder.accountDiscriminator('CommitReport')),
|
|
1216
1244
|
},
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1245
|
+
},
|
|
1246
|
+
{
|
|
1247
|
+
// sourceChainSelector filter
|
|
1248
|
+
memcmp: {
|
|
1249
|
+
offset: 8 + 1,
|
|
1250
|
+
bytes: encodeBase58(toLeArray(request.lane.sourceChainSelector, 8)),
|
|
1223
1251
|
},
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1252
|
+
},
|
|
1253
|
+
// memcmp report.min with msg.sequenceNumber's without least-significant byte;
|
|
1254
|
+
// this should be ~256 around seqNum, i.e. big chance of a match; requires PDAs not to have been closed
|
|
1255
|
+
{
|
|
1256
|
+
memcmp: {
|
|
1257
|
+
offset: 8 + 1 + 8 + 32 + 8 + /*skip byte*/ 1,
|
|
1258
|
+
bytes: encodeBase58(toLeArray(request.message.sequenceNumber, 8).slice(1)),
|
|
1231
1259
|
},
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
)
|
|
1260
|
+
},
|
|
1261
|
+
],
|
|
1262
|
+
})
|
|
1235
1263
|
for (const acc of commitsAroundSeqNum) {
|
|
1236
1264
|
// const merkleRoot = acc.account.data.subarray(8 + 1 + 8, 8 + 1 + 8 + 32)
|
|
1237
1265
|
const minSeqNr = acc.account.data.readBigUInt64LE(8 + 1 + 8 + 32 + 8)
|
|
@@ -1241,7 +1269,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1241
1269
|
// we have all the commit report info, but we also need log details (txHash, etc)
|
|
1242
1270
|
for await (const log of this.getLogs({
|
|
1243
1271
|
startTime: 1, // just to force getting the oldest log first
|
|
1244
|
-
programs: [
|
|
1272
|
+
programs: [offRamp],
|
|
1245
1273
|
address: acc.pubkey.toBase58(),
|
|
1246
1274
|
topics: ['CommitReportAccepted'],
|
|
1247
1275
|
})) {
|
|
@@ -1254,23 +1282,23 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1254
1282
|
}
|
|
1255
1283
|
}
|
|
1256
1284
|
// in case we can't find it, fallback to generic iterating txs
|
|
1257
|
-
return super.
|
|
1285
|
+
return super.getVerifications(opts)
|
|
1258
1286
|
}
|
|
1259
1287
|
|
|
1260
1288
|
/** {@inheritDoc Chain.getExecutionReceipts} */
|
|
1261
1289
|
override async *getExecutionReceipts(
|
|
1262
1290
|
opts: Parameters<Chain['getExecutionReceipts']>[0],
|
|
1263
1291
|
): AsyncIterableIterator<CCIPExecution> {
|
|
1264
|
-
const { offRamp, sourceChainSelector,
|
|
1292
|
+
const { offRamp, sourceChainSelector, verifications } = opts
|
|
1265
1293
|
let opts_: Parameters<Chain['getExecutionReceipts']>[0] &
|
|
1266
1294
|
Parameters<SolanaChain['getLogs']>[0] = opts
|
|
1267
|
-
if (
|
|
1295
|
+
if (sourceChainSelector && verifications && 'report' in verifications) {
|
|
1268
1296
|
// if we know of commit, use `commit_report` PDA as more specialized address
|
|
1269
1297
|
const [commitReportPda] = PublicKey.findProgramAddressSync(
|
|
1270
1298
|
[
|
|
1271
1299
|
Buffer.from('commit_report'),
|
|
1272
1300
|
toLeArray(sourceChainSelector, 8),
|
|
1273
|
-
bytesToBuffer(
|
|
1301
|
+
bytesToBuffer(verifications.report.merkleRoot),
|
|
1274
1302
|
],
|
|
1275
1303
|
new PublicKey(offRamp),
|
|
1276
1304
|
)
|
|
@@ -1559,7 +1587,11 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1559
1587
|
}
|
|
1560
1588
|
|
|
1561
1589
|
/**
|
|
1562
|
-
*
|
|
1590
|
+
* Returns a copy of a message, populating missing fields like `extraArgs` with defaults.
|
|
1591
|
+
* It's expected to return a message suitable at least for basic token transfers.
|
|
1592
|
+
*
|
|
1593
|
+
* @param message - AnyMessage (from source), containing at least `receiver`
|
|
1594
|
+
* @returns A message suitable for `sendMessage` to this destination chain family
|
|
1563
1595
|
* @throws {@link CCIPArgumentInvalidError} if tokenReceiver missing when sending tokens with data
|
|
1564
1596
|
*/
|
|
1565
1597
|
static override buildMessageForDest(
|
package/src/sui/hasher.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { concat, id, keccak256, zeroPadValue } from 'ethers'
|
|
2
2
|
|
|
3
|
-
import { encodeNumber, encodeRawBytes } from '../aptos/utils.ts'
|
|
4
3
|
import { CCIPExtraArgsInvalidError, CCIPSuiHasherVersionUnsupportedError } from '../errors/index.ts'
|
|
5
4
|
import { decodeExtraArgs } from '../extra-args.ts'
|
|
6
5
|
import { type LeafHasher, LEAF_DOMAIN_SEPARATOR } from '../hasher/common.ts'
|
|
7
6
|
import { type CCIPMessage, type CCIPMessage_V1_6, CCIPVersion } from '../types.ts'
|
|
8
7
|
import type { CCIPMessage_V1_6_Sui } from './types.ts'
|
|
8
|
+
import { encodeNumber, encodeRawBytes } from '../shared/bcs-codecs.ts'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Creates a leaf hasher for Sui CCIP messages.
|
package/src/sui/index.ts
CHANGED
|
@@ -7,7 +7,6 @@ import { isValidSuiAddress, isValidTransactionDigest, normalizeSuiAddress } from
|
|
|
7
7
|
import { type BytesLike, dataLength, hexlify, isBytesLike, isHexString } from 'ethers'
|
|
8
8
|
import type { PickDeep, SetOptional } from 'type-fest'
|
|
9
9
|
|
|
10
|
-
import { AptosChain } from '../aptos/index.ts'
|
|
11
10
|
import {
|
|
12
11
|
type ChainContext,
|
|
13
12
|
type ChainStatic,
|
|
@@ -15,24 +14,33 @@ import {
|
|
|
15
14
|
type LogFilter,
|
|
16
15
|
Chain,
|
|
17
16
|
} from '../chain.ts'
|
|
17
|
+
import { getCcipStateAddress, getOffRampForCcip } from './discovery.ts'
|
|
18
|
+
import { type CommitEvent, streamSuiLogs } from './events.ts'
|
|
19
|
+
import { getSuiLeafHasher } from './hasher.ts'
|
|
20
|
+
import {
|
|
21
|
+
deriveObjectID,
|
|
22
|
+
fetchTokenConfigs,
|
|
23
|
+
getLatestPackageId,
|
|
24
|
+
getObjectRef,
|
|
25
|
+
getReceiverModule,
|
|
26
|
+
} from './objects.ts'
|
|
18
27
|
import {
|
|
19
28
|
CCIPContractNotRouterError,
|
|
20
29
|
CCIPDataFormatUnsupportedError,
|
|
21
30
|
CCIPError,
|
|
22
31
|
CCIPErrorCode,
|
|
23
32
|
CCIPExecTxRevertedError,
|
|
24
|
-
|
|
25
|
-
} from '../errors/index.ts'
|
|
26
|
-
import {
|
|
33
|
+
CCIPExecutionReportChainMismatchError,
|
|
27
34
|
CCIPLogsAddressRequiredError,
|
|
35
|
+
CCIPNotImplementedError,
|
|
28
36
|
CCIPSuiLogInvalidError,
|
|
29
37
|
CCIPTopicsInvalidError,
|
|
30
|
-
} from '../errors/
|
|
38
|
+
} from '../errors/index.ts'
|
|
31
39
|
import type { EVMExtraArgsV2, ExtraArgs, SVMExtraArgsV1, SuiExtraArgsV1 } from '../extra-args.ts'
|
|
32
40
|
import type { LeafHasher } from '../hasher/common.ts'
|
|
33
41
|
import { decodeMessage, getMessagesInBatch } from '../requests.ts'
|
|
42
|
+
import { decodeMoveExtraArgs, getMoveAddress } from '../shared/bcs-codecs.ts'
|
|
34
43
|
import { supportedChains } from '../supported-chains.ts'
|
|
35
|
-
import { getSuiLeafHasher } from './hasher.ts'
|
|
36
44
|
import {
|
|
37
45
|
type AnyMessage,
|
|
38
46
|
type CCIPExecution,
|
|
@@ -41,8 +49,8 @@ import {
|
|
|
41
49
|
type CCIPVersion,
|
|
42
50
|
type ChainTransaction,
|
|
43
51
|
type CommitReport,
|
|
52
|
+
type ExecutionInput,
|
|
44
53
|
type ExecutionReceipt,
|
|
45
|
-
type ExecutionReport,
|
|
46
54
|
type ExecutionState,
|
|
47
55
|
type Lane,
|
|
48
56
|
type Log_,
|
|
@@ -59,20 +67,11 @@ import {
|
|
|
59
67
|
parseTypeAndVersion,
|
|
60
68
|
util,
|
|
61
69
|
} from '../utils.ts'
|
|
62
|
-
import { getCcipStateAddress, getOffRampForCcip } from './discovery.ts'
|
|
63
|
-
import { type CommitEvent, streamSuiLogs } from './events.ts'
|
|
64
70
|
import {
|
|
65
71
|
type SuiManuallyExecuteInput,
|
|
66
72
|
type TokenConfig,
|
|
67
73
|
buildManualExecutionPTB,
|
|
68
74
|
} from './manuallyExec/index.ts'
|
|
69
|
-
import {
|
|
70
|
-
deriveObjectID,
|
|
71
|
-
fetchTokenConfigs,
|
|
72
|
-
getLatestPackageId,
|
|
73
|
-
getObjectRef,
|
|
74
|
-
getReceiverModule,
|
|
75
|
-
} from './objects.ts'
|
|
76
75
|
import type { CCIPMessage_V1_6_Sui } from './types.ts'
|
|
77
76
|
|
|
78
77
|
const DEFAULT_GAS_LIMIT = 1000000n
|
|
@@ -246,10 +245,10 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
246
245
|
>,
|
|
247
246
|
>(
|
|
248
247
|
request: R,
|
|
249
|
-
|
|
250
|
-
opts?:
|
|
248
|
+
range: Pick<CommitReport, 'minSeqNr' | 'maxSeqNr'>,
|
|
249
|
+
opts?: Pick<LogFilter, 'page'>,
|
|
251
250
|
): Promise<R['message'][]> {
|
|
252
|
-
return getMessagesInBatch(this, request,
|
|
251
|
+
return getMessagesInBatch(this, request, range, opts)
|
|
253
252
|
}
|
|
254
253
|
|
|
255
254
|
/**
|
|
@@ -318,10 +317,10 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
318
317
|
}
|
|
319
318
|
|
|
320
319
|
/**
|
|
321
|
-
* {@inheritDoc Chain.
|
|
320
|
+
* {@inheritDoc Chain.getOnRampsForOffRamp}
|
|
322
321
|
* @throws {@link CCIPDataFormatUnsupportedError} if view call fails
|
|
323
322
|
*/
|
|
324
|
-
async
|
|
323
|
+
async getOnRampsForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise<string[]> {
|
|
325
324
|
offRamp = await getLatestPackageId(offRamp, this.client)
|
|
326
325
|
const functionName = 'get_source_chain_config'
|
|
327
326
|
// Preserve module suffix if present, otherwise add it
|
|
@@ -390,12 +389,7 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
390
389
|
const onRampBytes = configBytes.slice(offset, offset + onRampLength)
|
|
391
390
|
|
|
392
391
|
// Decode the address from the onRamp bytes
|
|
393
|
-
return decodeAddress(onRampBytes, networkInfo(sourceChainSelector).family)
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/** {@inheritDoc Chain.getCommitStoreForOffRamp} */
|
|
397
|
-
getCommitStoreForOffRamp(offRamp: string): Promise<string> {
|
|
398
|
-
return Promise.resolve(offRamp)
|
|
392
|
+
return [decodeAddress(onRampBytes, networkInfo(sourceChainSelector).family)]
|
|
399
393
|
}
|
|
400
394
|
|
|
401
395
|
/**
|
|
@@ -608,7 +602,7 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
608
602
|
| (EVMExtraArgsV2 & { _tag: 'EVMExtraArgsV2' })
|
|
609
603
|
| (SVMExtraArgsV1 & { _tag: 'SVMExtraArgsV1' })
|
|
610
604
|
| undefined {
|
|
611
|
-
return
|
|
605
|
+
return decodeMoveExtraArgs(extraArgs)
|
|
612
606
|
}
|
|
613
607
|
|
|
614
608
|
/**
|
|
@@ -696,7 +690,7 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
696
690
|
* @returns Sui address.
|
|
697
691
|
*/
|
|
698
692
|
static getAddress(bytes: BytesLike | readonly number[]): string {
|
|
699
|
-
return
|
|
693
|
+
return getMoveAddress(bytes)
|
|
700
694
|
}
|
|
701
695
|
|
|
702
696
|
/**
|
|
@@ -740,24 +734,27 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
740
734
|
return Promise.resolve(request.message.tokenAmounts.map(() => undefined))
|
|
741
735
|
}
|
|
742
736
|
|
|
743
|
-
/** {@inheritDoc Chain.
|
|
744
|
-
override
|
|
745
|
-
_opts: Parameters<Chain['
|
|
737
|
+
/** {@inheritDoc Chain.generateUnsignedExecute} */
|
|
738
|
+
override generateUnsignedExecute(
|
|
739
|
+
_opts: Parameters<Chain['generateUnsignedExecute']>[0],
|
|
746
740
|
): Promise<never> {
|
|
747
|
-
return Promise.reject(new CCIPNotImplementedError('SuiChain.
|
|
741
|
+
return Promise.reject(new CCIPNotImplementedError('SuiChain.generateUnsignedExecute'))
|
|
748
742
|
}
|
|
749
743
|
|
|
750
744
|
/**
|
|
751
|
-
* {@inheritDoc Chain.
|
|
745
|
+
* {@inheritDoc Chain.execute}
|
|
752
746
|
* @throws {@link CCIPError} if transaction submission fails
|
|
753
747
|
* @throws {@link CCIPExecTxRevertedError} if transaction reverts
|
|
754
748
|
*/
|
|
755
|
-
async
|
|
756
|
-
opts: Parameters<Chain['
|
|
749
|
+
async execute(
|
|
750
|
+
opts: Parameters<Chain['execute']>[0] & {
|
|
757
751
|
receiverObjectIds?: string[]
|
|
758
752
|
},
|
|
759
753
|
): Promise<CCIPExecution> {
|
|
760
|
-
|
|
754
|
+
if (!('input' in opts && 'message' in opts.input)) {
|
|
755
|
+
throw new CCIPExecutionReportChainMismatchError('Sui')
|
|
756
|
+
}
|
|
757
|
+
const { input, offRamp } = opts
|
|
761
758
|
const wallet = opts.wallet as Keypair
|
|
762
759
|
|
|
763
760
|
// Discover the CCIP package from the offramp
|
|
@@ -769,20 +766,20 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
769
766
|
this.client,
|
|
770
767
|
ccip,
|
|
771
768
|
ccipObjectRef,
|
|
772
|
-
|
|
769
|
+
input.message.receiver,
|
|
773
770
|
)
|
|
774
771
|
let tokenConfigs: TokenConfig[] = []
|
|
775
|
-
if (
|
|
772
|
+
if (input.message.tokenAmounts.length !== 0) {
|
|
776
773
|
tokenConfigs = await fetchTokenConfigs(
|
|
777
774
|
this.client,
|
|
778
775
|
ccip,
|
|
779
776
|
ccipObjectRef,
|
|
780
|
-
|
|
777
|
+
input.message.tokenAmounts as CCIPMessage<typeof CCIPVersion.V1_6>['tokenAmounts'],
|
|
781
778
|
)
|
|
782
779
|
}
|
|
783
780
|
|
|
784
|
-
const
|
|
785
|
-
executionReport:
|
|
781
|
+
const suiInput: SuiManuallyExecuteInput = {
|
|
782
|
+
executionReport: input as ExecutionInput<CCIPMessage_V1_6_Sui>,
|
|
786
783
|
offrampAddress: offRamp,
|
|
787
784
|
ccipAddress: ccip,
|
|
788
785
|
ccipObjectRef,
|
|
@@ -794,16 +791,16 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
794
791
|
this.logger.info(
|
|
795
792
|
`Overriding Sui Manual Execution receiverObjectIds with: ${opts.receiverObjectIds.join(', ')}`,
|
|
796
793
|
)
|
|
797
|
-
|
|
794
|
+
suiInput.overrideReceiverObjectIds = opts.receiverObjectIds
|
|
798
795
|
}
|
|
799
|
-
const tx = buildManualExecutionPTB(
|
|
796
|
+
const tx = buildManualExecutionPTB(suiInput)
|
|
800
797
|
|
|
801
798
|
// Set gas budget if provided
|
|
802
799
|
if (opts.gasLimit) {
|
|
803
800
|
tx.setGasBudget(opts.gasLimit)
|
|
804
801
|
}
|
|
805
802
|
|
|
806
|
-
this.logger.info(`Executing Sui CCIP
|
|
803
|
+
this.logger.info(`Executing Sui CCIP execute transaction...`)
|
|
807
804
|
// Sign and execute the transaction
|
|
808
805
|
let result: SuiTransactionBlockResponse
|
|
809
806
|
try {
|
|
@@ -818,7 +815,7 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
818
815
|
} catch (e) {
|
|
819
816
|
throw new CCIPError(
|
|
820
817
|
CCIPErrorCode.TRANSACTION_NOT_FINALIZED,
|
|
821
|
-
`Failed to send Sui
|
|
818
|
+
`Failed to send Sui execute transaction: ${(e as Error).message}`,
|
|
822
819
|
)
|
|
823
820
|
}
|
|
824
821
|
|
|
@@ -881,7 +878,13 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
881
878
|
return Promise.reject(new CCIPNotImplementedError('SuiChain.getFeeTokens'))
|
|
882
879
|
}
|
|
883
880
|
|
|
884
|
-
/**
|
|
881
|
+
/**
|
|
882
|
+
* Returns a copy of a message, populating missing fields like `extraArgs` with defaults.
|
|
883
|
+
* It's expected to return a message suitable at least for basic token transfers.
|
|
884
|
+
*
|
|
885
|
+
* @param message - AnyMessage (from source), containing at least `receiver`
|
|
886
|
+
* @returns A message suitable for `sendMessage` to this destination chain family
|
|
887
|
+
*/
|
|
885
888
|
static override buildMessageForDest(
|
|
886
889
|
message: Parameters<ChainStatic['buildMessageForDest']>[0],
|
|
887
890
|
): AnyMessage & { extraArgs: SuiExtraArgsV1 } {
|
|
@@ -5,7 +5,7 @@ import type { BytesLike } from 'ethers'
|
|
|
5
5
|
|
|
6
6
|
import { CCIPMessageInvalidError } from '../../errors/specialized.ts'
|
|
7
7
|
import { decodeExtraArgs } from '../../extra-args.ts'
|
|
8
|
-
import type { CCIPMessage, CCIPVersion,
|
|
8
|
+
import type { CCIPMessage, CCIPVersion, ExecutionInput } from '../../types.ts'
|
|
9
9
|
import { bytesToBuffer, getAddressBytes, getDataBytes, networkInfo } from '../../utils.ts'
|
|
10
10
|
|
|
11
11
|
const Any2SuiTokenTransferBCS = bcs.struct('Any2SuiTokenTransfer', {
|
|
@@ -39,7 +39,7 @@ const ExecutionReportBCS = bcs.struct('ExecutionReport', {
|
|
|
39
39
|
* @returns Serialized execution report as Uint8Array.
|
|
40
40
|
*/
|
|
41
41
|
export function serializeExecutionReport(
|
|
42
|
-
executionReport:
|
|
42
|
+
executionReport: ExecutionInput<CCIPMessage<typeof CCIPVersion.V1_6>>,
|
|
43
43
|
): Uint8Array {
|
|
44
44
|
const { message, offchainTokenData, proofs } = executionReport
|
|
45
45
|
|
|
@@ -5,7 +5,7 @@ import { Transaction } from '@mysten/sui/transactions'
|
|
|
5
5
|
import { serializeExecutionReport } from './encoder.ts'
|
|
6
6
|
import { CCIPMessageInvalidError } from '../../errors/specialized.ts'
|
|
7
7
|
import { decodeExtraArgs } from '../../extra-args.ts'
|
|
8
|
-
import type {
|
|
8
|
+
import type { ExecutionInput } from '../../types.ts'
|
|
9
9
|
import { networkInfo } from '../../utils.ts'
|
|
10
10
|
import type { CCIPMessage_V1_6_Sui } from '../types.ts'
|
|
11
11
|
|
|
@@ -30,7 +30,7 @@ export type TokenConfig = {
|
|
|
30
30
|
/** Input parameters for building a Sui manual execution transaction. */
|
|
31
31
|
export type SuiManuallyExecuteInput = {
|
|
32
32
|
offrampAddress: string
|
|
33
|
-
executionReport:
|
|
33
|
+
executionReport: ExecutionInput<CCIPMessage_V1_6_Sui>
|
|
34
34
|
ccipAddress: string
|
|
35
35
|
ccipObjectRef: string
|
|
36
36
|
offrampStateObject: string
|
package/src/ton/exec.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Cell, beginCell } from '@ton/core'
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { ExecutionInput } from '../types.ts'
|
|
4
4
|
import {
|
|
5
5
|
type CCIPMessage_V1_6_TON,
|
|
6
6
|
MANUALLY_EXECUTE_OPCODE,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
*/
|
|
18
18
|
export function generateUnsignedExecuteReport(
|
|
19
19
|
offRamp: string,
|
|
20
|
-
execReport:
|
|
20
|
+
execReport: ExecutionInput<CCIPMessage_V1_6_TON>,
|
|
21
21
|
opts?: { gasLimit?: number },
|
|
22
22
|
): { to: string; body: Cell } {
|
|
23
23
|
// Serialize the execution report
|