@chainlink/ccip-sdk 1.3.1 → 1.4.1
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 -6
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +17 -6
- package/dist/api/index.js.map +1 -1
- package/dist/aptos/index.d.ts +7 -1
- package/dist/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +20 -0
- package/dist/aptos/index.js.map +1 -1
- package/dist/chain.d.ts +65 -7
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +47 -3
- package/dist/chain.js.map +1 -1
- package/dist/errors/codes.d.ts +1 -2
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/errors/codes.js +1 -2
- package/dist/errors/codes.js.map +1 -1
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +2 -2
- package/dist/errors/index.js.map +1 -1
- package/dist/errors/recovery.d.ts.map +1 -1
- package/dist/errors/recovery.js +2 -3
- package/dist/errors/recovery.js.map +1 -1
- package/dist/errors/specialized.d.ts +23 -28
- package/dist/errors/specialized.d.ts.map +1 -1
- package/dist/errors/specialized.js +33 -37
- package/dist/errors/specialized.js.map +1 -1
- package/dist/evm/const.d.ts.map +1 -1
- package/dist/evm/const.js +1 -0
- package/dist/evm/const.js.map +1 -1
- package/dist/evm/errors.d.ts.map +1 -1
- package/dist/evm/errors.js +20 -5
- package/dist/evm/errors.js.map +1 -1
- package/dist/evm/extra-args.d.ts.map +1 -1
- package/dist/evm/extra-args.js +14 -13
- package/dist/evm/extra-args.js.map +1 -1
- package/dist/evm/index.d.ts +11 -2
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +73 -22
- package/dist/evm/index.js.map +1 -1
- package/dist/gas.d.ts +2 -1
- package/dist/gas.d.ts.map +1 -1
- package/dist/gas.js +2 -1
- package/dist/gas.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/offchain.d.ts +1 -0
- package/dist/offchain.d.ts.map +1 -1
- package/dist/offchain.js +1 -0
- package/dist/offchain.js.map +1 -1
- package/dist/requests.d.ts +7 -6
- package/dist/requests.d.ts.map +1 -1
- package/dist/requests.js +7 -8
- package/dist/requests.js.map +1 -1
- package/dist/solana/idl/1.6.0/FEE_QUOTER.d.ts +1719 -0
- package/dist/solana/idl/1.6.0/FEE_QUOTER.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/FEE_QUOTER.js +1719 -0
- package/dist/solana/idl/1.6.0/FEE_QUOTER.js.map +1 -0
- package/dist/solana/index.d.ts +34 -18
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +45 -5
- package/dist/solana/index.js.map +1 -1
- package/dist/solana/utils.d.ts +5 -2
- package/dist/solana/utils.d.ts.map +1 -1
- package/dist/solana/utils.js +5 -2
- package/dist/solana/utils.js.map +1 -1
- package/dist/sui/index.d.ts +1 -1
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +14 -14
- package/dist/sui/index.js.map +1 -1
- package/dist/ton/index.d.ts +11 -9
- package/dist/ton/index.d.ts.map +1 -1
- package/dist/ton/index.js +24 -26
- package/dist/ton/index.js.map +1 -1
- package/dist/ton/send.d.ts +7 -0
- package/dist/ton/send.d.ts.map +1 -1
- package/dist/ton/send.js +7 -0
- package/dist/ton/send.js.map +1 -1
- package/dist/utils.d.ts +9 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +10 -3
- package/dist/utils.js.map +1 -1
- package/package.json +8 -8
- package/src/api/index.ts +17 -6
- package/src/aptos/index.ts +31 -0
- package/src/chain.ts +80 -8
- package/src/errors/codes.ts +1 -2
- package/src/errors/index.ts +1 -2
- package/src/errors/recovery.ts +2 -3
- package/src/errors/specialized.ts +35 -38
- package/src/evm/const.ts +1 -0
- package/src/evm/errors.ts +22 -5
- package/src/evm/extra-args.ts +15 -14
- package/src/evm/index.ts +110 -21
- package/src/gas.ts +2 -1
- package/src/index.ts +1 -0
- package/src/offchain.ts +1 -0
- package/src/requests.ts +8 -8
- package/src/solana/idl/1.6.0/FEE_QUOTER.ts +3440 -0
- package/src/solana/index.ts +60 -4
- package/src/solana/utils.ts +5 -2
- package/src/sui/index.ts +17 -15
- package/src/ton/index.ts +23 -31
- package/src/ton/send.ts +7 -0
- package/src/utils.ts +10 -3
package/src/solana/index.ts
CHANGED
|
@@ -35,10 +35,12 @@ import {
|
|
|
35
35
|
type LogFilter,
|
|
36
36
|
type TokenInfo,
|
|
37
37
|
type TokenPoolRemote,
|
|
38
|
+
type TokenPrice,
|
|
38
39
|
type TokenTransferFeeOpts,
|
|
39
40
|
Chain,
|
|
40
41
|
} from '../chain.ts'
|
|
41
42
|
import {
|
|
43
|
+
CCIPAddressInvalidError,
|
|
42
44
|
CCIPArgumentInvalidError,
|
|
43
45
|
CCIPBlockTimeNotFoundError,
|
|
44
46
|
CCIPContractNotRouterError,
|
|
@@ -112,6 +114,7 @@ import { IDL as BURN_MINT_TOKEN_POOL } from './idl/1.6.0/BURN_MINT_TOKEN_POOL.ts
|
|
|
112
114
|
import { IDL as CCIP_CCTP_TOKEN_POOL } from './idl/1.6.0/CCIP_CCTP_TOKEN_POOL.ts'
|
|
113
115
|
import { IDL as CCIP_OFFRAMP_IDL } from './idl/1.6.0/CCIP_OFFRAMP.ts'
|
|
114
116
|
import { IDL as CCIP_ROUTER_IDL } from './idl/1.6.0/CCIP_ROUTER.ts'
|
|
117
|
+
import { IDL as FEE_QUOTER_IDL } from './idl/1.6.0/FEE_QUOTER.ts'
|
|
115
118
|
import { getTransactionsForAddress } from './logs.ts'
|
|
116
119
|
import { generateUnsignedCcipSend, getFee } from './send.ts'
|
|
117
120
|
import { type CCIPMessage_V1_6_Solana, type UnsignedSolanaTx, isWallet } from './types.ts'
|
|
@@ -1021,7 +1024,13 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1021
1024
|
} catch (_) {
|
|
1022
1025
|
// pass
|
|
1023
1026
|
}
|
|
1024
|
-
|
|
1027
|
+
try {
|
|
1028
|
+
const decoded = getDataBytes(bytes)
|
|
1029
|
+
if (decoded.length === 32) return encodeBase58(decoded)
|
|
1030
|
+
} catch {
|
|
1031
|
+
// pass
|
|
1032
|
+
}
|
|
1033
|
+
throw new CCIPAddressInvalidError(bytes, this.family)
|
|
1025
1034
|
}
|
|
1026
1035
|
|
|
1027
1036
|
/**
|
|
@@ -1567,6 +1576,43 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1567
1576
|
)
|
|
1568
1577
|
}
|
|
1569
1578
|
|
|
1579
|
+
/** {@inheritDoc Chain.getTokenPrice} */
|
|
1580
|
+
override async getTokenPrice(opts: {
|
|
1581
|
+
router: string
|
|
1582
|
+
token: string
|
|
1583
|
+
timestamp?: number
|
|
1584
|
+
}): Promise<TokenPrice> {
|
|
1585
|
+
if (opts.timestamp != null) {
|
|
1586
|
+
this.logger.warn(
|
|
1587
|
+
'getTokenPrice: timestamp parameter not yet supported on Solana, returning latest price',
|
|
1588
|
+
)
|
|
1589
|
+
}
|
|
1590
|
+
const { feeQuoter } = await this._getRouterConfig(opts.router)
|
|
1591
|
+
|
|
1592
|
+
// Resolve native SOL to wrapped SOL (NATIVE_MINT)
|
|
1593
|
+
const tokenMint =
|
|
1594
|
+
!opts.token || opts.token === PublicKey.default.toBase58()
|
|
1595
|
+
? NATIVE_MINT
|
|
1596
|
+
: new PublicKey(opts.token)
|
|
1597
|
+
|
|
1598
|
+
const feeQuoterProgram = new Program(FEE_QUOTER_IDL, feeQuoter, {
|
|
1599
|
+
connection: this.connection,
|
|
1600
|
+
})
|
|
1601
|
+
|
|
1602
|
+
const [billingTokenConfigPda] = PublicKey.findProgramAddressSync(
|
|
1603
|
+
[Buffer.from('fee_billing_token_config'), tokenMint.toBuffer()],
|
|
1604
|
+
feeQuoter,
|
|
1605
|
+
)
|
|
1606
|
+
|
|
1607
|
+
const [billingTokenConfigWrapper, { decimals }] = await Promise.all([
|
|
1608
|
+
feeQuoterProgram.account.billingTokenConfigWrapper.fetch(billingTokenConfigPda),
|
|
1609
|
+
this.getTokenInfo(tokenMint.toBase58()),
|
|
1610
|
+
])
|
|
1611
|
+
|
|
1612
|
+
const usdPerToken = billingTokenConfigWrapper.config.usdPerToken
|
|
1613
|
+
return { price: Number(toBigInt(Buffer.from(usdPerToken.value))) * 10 ** (decimals - 36) }
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1570
1616
|
/**
|
|
1571
1617
|
* Gets the router configuration from the Config PDA.
|
|
1572
1618
|
* @param router - Router program address.
|
|
@@ -1588,9 +1634,19 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1588
1634
|
* Returns a copy of a message, populating missing fields like `extraArgs` with defaults.
|
|
1589
1635
|
* It's expected to return a message suitable at least for basic token transfers.
|
|
1590
1636
|
*
|
|
1637
|
+
* @remarks
|
|
1638
|
+
* Solana-specific receiver/tokenReceiver handling:
|
|
1639
|
+
* - Explicit `tokenReceiver` in extraArgs: both `receiver` and `tokenReceiver` are kept as provided.
|
|
1640
|
+
* - Tokens but no explicit `tokenReceiver`: `receiver` is set to `PublicKey.default` and
|
|
1641
|
+
* `tokenReceiver` is set to `message.receiver`.
|
|
1642
|
+
* - No tokens: `tokenReceiver` is set to `PublicKey.default` and `receiver` is `message.receiver`.
|
|
1643
|
+
*
|
|
1644
|
+
* Accepts `gasLimit` as an alias for `computeUnits` in extraArgs.
|
|
1645
|
+
*
|
|
1591
1646
|
* @param message - AnyMessage (from source), containing at least `receiver`
|
|
1592
1647
|
* @returns A message suitable for `sendMessage` to this destination chain family
|
|
1593
1648
|
* @throws {@link CCIPArgumentInvalidError} if tokenReceiver missing when sending tokens with data
|
|
1649
|
+
* @throws {@link CCIPArgumentInvalidError} if extraArgs contains unknown fields for SVMExtraArgsV1
|
|
1594
1650
|
*/
|
|
1595
1651
|
static override buildMessageForDest(
|
|
1596
1652
|
message: Parameters<ChainStatic['buildMessageForDest']>[0],
|
|
@@ -1647,13 +1703,13 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1647
1703
|
: true
|
|
1648
1704
|
const [tokenReceiver, receiver] =
|
|
1649
1705
|
message.extraArgs && 'tokenReceiver' in message.extraArgs && !!message.extraArgs.tokenReceiver
|
|
1650
|
-
? [message.extraArgs.tokenReceiver, message.receiver] // explicit tokenReceiver, keep both
|
|
1706
|
+
? [this.getAddress(message.extraArgs.tokenReceiver), this.getAddress(message.receiver)] // explicit tokenReceiver, keep both
|
|
1651
1707
|
: message.tokenAmounts?.length
|
|
1652
1708
|
? [this.getAddress(message.receiver), PublicKey.default.toBase58()] // if sending tokens without tokenReceiver, set receiver to default and tokenReceiver to message.receiver
|
|
1653
|
-
: [PublicKey.default.toBase58(), message.receiver] // otherwise, tokenReceiver is default and receiver is message.receiver
|
|
1709
|
+
: [PublicKey.default.toBase58(), this.getAddress(message.receiver)] // otherwise, tokenReceiver is default and receiver is message.receiver
|
|
1654
1710
|
const accounts =
|
|
1655
1711
|
message.extraArgs && 'accounts' in message.extraArgs && message.extraArgs.accounts != null
|
|
1656
|
-
? message.extraArgs.accounts
|
|
1712
|
+
? message.extraArgs.accounts.map(this.getAddress.bind(this))
|
|
1657
1713
|
: []
|
|
1658
1714
|
const accountIsWritableBitmap =
|
|
1659
1715
|
message.extraArgs &&
|
package/src/solana/utils.ts
CHANGED
|
@@ -211,7 +211,7 @@ export function parseSolanaLogs(logs: readonly string[]): ParsedLog[] {
|
|
|
211
211
|
|
|
212
212
|
/**
|
|
213
213
|
* Extracts error information from Solana transaction logs.
|
|
214
|
-
* @param logs_ - Raw log strings or parsed log objects.
|
|
214
|
+
* @param logs_ - Raw log strings or parsed log objects (may include `tx` field with error info).
|
|
215
215
|
* @returns Parsed error info with program and error details.
|
|
216
216
|
*/
|
|
217
217
|
export function getErrorFromLogs(
|
|
@@ -397,6 +397,7 @@ export function simulationProvider(
|
|
|
397
397
|
* - lookupTables - lookupTables to be used for main instruction
|
|
398
398
|
* @param computeUnits - max computeUnits limit to be used for main instruction
|
|
399
399
|
* @returns - signature of successful transaction including main instruction
|
|
400
|
+
* @throws {@link CCIPSolanaComputeUnitsExceededError} if simulation exceeds compute units limit
|
|
400
401
|
*/
|
|
401
402
|
export async function simulateAndSendTxs(
|
|
402
403
|
ctx: { connection: Connection } & WithLogger,
|
|
@@ -465,7 +466,9 @@ export async function simulateAndSendTxs(
|
|
|
465
466
|
}
|
|
466
467
|
|
|
467
468
|
/**
|
|
468
|
-
* Convert TokenPool's rate limit to RateLimiterState object
|
|
469
|
+
* Convert TokenPool's rate limit to RateLimiterState object.
|
|
470
|
+
* @param input - On-chain rate limiter bucket from the TokenPool IDL.
|
|
471
|
+
* @returns RateLimiterState with capacity, rate, and current tokens, or null if disabled.
|
|
469
472
|
*/
|
|
470
473
|
export function convertRateLimiter(
|
|
471
474
|
input: IdlTypes<typeof BASE_TOKEN_POOL_IDL>['BaseChain']['inboundRateLimit'],
|
package/src/sui/index.ts
CHANGED
|
@@ -68,7 +68,6 @@ const DEFAULT_GAS_LIMIT = 1000000n
|
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* Sui chain implementation supporting Sui networks.
|
|
71
|
-
* Note: This implementation is currently a placeholder.
|
|
72
71
|
*/
|
|
73
72
|
export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
74
73
|
static {
|
|
@@ -814,6 +813,7 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
814
813
|
*
|
|
815
814
|
* @param message - AnyMessage (from source), containing at least `receiver`
|
|
816
815
|
* @returns A message suitable for `sendMessage` to this destination chain family
|
|
816
|
+
* @throws {@link CCIPArgumentInvalidError} if extraArgs contains unknown fields for SuiExtraArgsV1
|
|
817
817
|
*/
|
|
818
818
|
static override buildMessageForDest(
|
|
819
819
|
message: Parameters<ChainStatic['buildMessageForDest']>[0],
|
|
@@ -848,36 +848,38 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
848
848
|
message.extraArgs.allowOutOfOrderExecution != null
|
|
849
849
|
? message.extraArgs.allowOutOfOrderExecution
|
|
850
850
|
: true
|
|
851
|
-
const tokenReceiver =
|
|
852
|
-
message.extraArgs &&
|
|
853
|
-
|
|
854
|
-
message.extraArgs.tokenReceiver != null &&
|
|
855
|
-
typeof message.extraArgs.tokenReceiver === 'string'
|
|
856
|
-
? message.extraArgs.tokenReceiver
|
|
851
|
+
const [tokenReceiver, receiver] =
|
|
852
|
+
message.extraArgs && 'tokenReceiver' in message.extraArgs && !!message.extraArgs.tokenReceiver
|
|
853
|
+
? [this.getAddress(message.extraArgs.tokenReceiver), this.getAddress(message.receiver)] // explicit tokenReceiver, keep both
|
|
857
854
|
: message.tokenAmounts?.length
|
|
858
|
-
?
|
|
859
|
-
|
|
855
|
+
? [
|
|
856
|
+
this.getAddress(message.receiver),
|
|
857
|
+
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
858
|
+
] // if sending tokens without tokenReceiver, set receiver to default and tokenReceiver to message.receiver
|
|
859
|
+
: [
|
|
860
|
+
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
861
|
+
this.getAddress(message.receiver),
|
|
862
|
+
] // otherwise, tokenReceiver is default and receiver is message.receiver
|
|
860
863
|
const receiverObjectIds =
|
|
861
864
|
message.extraArgs &&
|
|
862
865
|
'receiverObjectIds' in message.extraArgs &&
|
|
863
866
|
message.extraArgs.receiverObjectIds?.length
|
|
864
|
-
? message.extraArgs.receiverObjectIds
|
|
867
|
+
? message.extraArgs.receiverObjectIds.map(this.getAddress.bind(this))
|
|
865
868
|
: message.extraArgs && 'accounts' in message.extraArgs && message.extraArgs.accounts?.length
|
|
866
|
-
? message.extraArgs.accounts // populates receiverObjectIds from accounts
|
|
869
|
+
? message.extraArgs.accounts.map(this.getAddress.bind(this)) // populates receiverObjectIds from accounts
|
|
867
870
|
: []
|
|
871
|
+
|
|
868
872
|
const extraArgs: SuiExtraArgsV1 = {
|
|
869
873
|
gasLimit,
|
|
870
874
|
allowOutOfOrderExecution,
|
|
871
875
|
tokenReceiver,
|
|
872
876
|
receiverObjectIds,
|
|
873
877
|
}
|
|
878
|
+
|
|
874
879
|
return {
|
|
875
880
|
...message,
|
|
881
|
+
receiver,
|
|
876
882
|
extraArgs,
|
|
877
|
-
// if tokenReceiver, then message.receiver can (must?) be default
|
|
878
|
-
...(!!message.tokenAmounts?.length && {
|
|
879
|
-
receiver: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
880
|
-
}),
|
|
881
883
|
}
|
|
882
884
|
}
|
|
883
885
|
}
|
package/src/ton/index.ts
CHANGED
|
@@ -36,7 +36,6 @@ import {
|
|
|
36
36
|
import {
|
|
37
37
|
CCIPArgumentInvalidError,
|
|
38
38
|
CCIPExecutionReportChainMismatchError,
|
|
39
|
-
CCIPExtraArgsInvalidError,
|
|
40
39
|
CCIPHttpError,
|
|
41
40
|
CCIPNotImplementedError,
|
|
42
41
|
CCIPReceiptNotFoundError,
|
|
@@ -184,6 +183,9 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
|
|
|
184
183
|
|
|
185
184
|
/**
|
|
186
185
|
* Detect client network and instantiate a TONChain instance.
|
|
186
|
+
* @param client - TonClient instance connected to the TON network.
|
|
187
|
+
* @param ctx - Optional chain context with logger, API client, and fetch function.
|
|
188
|
+
* @returns TONChain instance configured for the detected network (mainnet or testnet).
|
|
187
189
|
*/
|
|
188
190
|
static async fromClient(
|
|
189
191
|
client: TonClient,
|
|
@@ -560,10 +562,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
|
|
|
560
562
|
}
|
|
561
563
|
}
|
|
562
564
|
|
|
563
|
-
/**
|
|
564
|
-
* {@inheritDoc Chain.getBalance}
|
|
565
|
-
* @throws {@link CCIPNotImplementedError} always (not implemented for TON)
|
|
566
|
-
*/
|
|
565
|
+
/** {@inheritDoc Chain.getBalance} */
|
|
567
566
|
async getBalance(opts: GetBalanceOpts): Promise<bigint> {
|
|
568
567
|
const { holder, token } = opts
|
|
569
568
|
const holderAddress = Address.parse(holder)
|
|
@@ -606,7 +605,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
|
|
|
606
605
|
/**
|
|
607
606
|
* Decodes a CCIP message from a TON log event.
|
|
608
607
|
* @param log - Log with data field.
|
|
609
|
-
* @returns Decoded CCIPMessage or undefined if not valid.
|
|
608
|
+
* @returns Decoded CCIPMessage, or undefined if the data is not a valid CCIP message (parse errors are caught and silently return undefined).
|
|
610
609
|
*/
|
|
611
610
|
static decodeMessage({
|
|
612
611
|
data,
|
|
@@ -711,6 +710,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
|
|
|
711
710
|
*
|
|
712
711
|
* @param args - Extra arguments containing gas limit and execution flags
|
|
713
712
|
* @returns Hex string of BOC-encoded extra args (0x-prefixed)
|
|
713
|
+
* @throws {@link CCIPExtraArgsInvalidError} if args contains fields other than `gasLimit` and `allowOutOfOrderExecution`
|
|
714
714
|
*/
|
|
715
715
|
static encodeExtraArgs(args: ExtraArgs): string {
|
|
716
716
|
const cell = encodeExtraArgsCell(args)
|
|
@@ -718,15 +718,16 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
|
|
|
718
718
|
}
|
|
719
719
|
|
|
720
720
|
/**
|
|
721
|
-
* Decodes
|
|
722
|
-
*
|
|
723
|
-
*
|
|
721
|
+
* Decodes extra arguments from TON messages.
|
|
722
|
+
* Handles both raw bit-packed data (starts with EVMExtraArgsV2 tag directly)
|
|
723
|
+
* and BOC-wrapped data (starts with TON BOC magic `0xb5ee9c72`, unwrapped first).
|
|
724
|
+
* Returns undefined if parsing fails or the tag doesn't match.
|
|
724
725
|
*
|
|
725
726
|
* Currently only supports EVMExtraArgsV2 (GenericExtraArgsV2) encoding since TON
|
|
726
727
|
* lanes are only connected to EVM chains. When new lanes are planned to be added,
|
|
727
728
|
* this should be extended to support them (eg. Solana and SVMExtraArgsV1)
|
|
728
729
|
*
|
|
729
|
-
* @param extraArgs -
|
|
730
|
+
* @param extraArgs - Extra args as hex string or bytes (raw bit-packed or BOC-wrapped)
|
|
730
731
|
* @returns Decoded EVMExtraArgsV2 (GenericExtraArgsV2) object or undefined if invalid
|
|
731
732
|
*/
|
|
732
733
|
static decodeExtraArgs(
|
|
@@ -1113,25 +1114,16 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
|
|
|
1113
1114
|
* {@inheritDoc Chain.generateUnsignedExecute}
|
|
1114
1115
|
* @throws {@link CCIPExtraArgsInvalidError} if extra args are not EVMExtraArgsV2 format
|
|
1115
1116
|
*/
|
|
1116
|
-
generateUnsignedExecute(
|
|
1117
|
+
async generateUnsignedExecute(
|
|
1117
1118
|
opts: Parameters<Chain['generateUnsignedExecute']>[0],
|
|
1118
1119
|
): Promise<UnsignedTONTx> {
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
'input' in opts &&
|
|
1122
|
-
'message' in opts.input &&
|
|
1123
|
-
'allowOutOfOrderExecution' in opts.input.message &&
|
|
1124
|
-
'gasLimit' in opts.input.message
|
|
1125
|
-
)
|
|
1126
|
-
) {
|
|
1127
|
-
throw new CCIPExtraArgsInvalidError('TON')
|
|
1128
|
-
}
|
|
1129
|
-
const { offRamp, input } = opts
|
|
1120
|
+
const resolved = await this.resolveExecuteOpts(opts)
|
|
1121
|
+
const { offRamp, input } = resolved
|
|
1130
1122
|
|
|
1131
1123
|
const unsigned = generateUnsignedExecuteReport(
|
|
1132
1124
|
offRamp,
|
|
1133
1125
|
input as ExecutionInput<CCIPMessage_V1_6_EVM>,
|
|
1134
|
-
|
|
1126
|
+
resolved,
|
|
1135
1127
|
)
|
|
1136
1128
|
|
|
1137
1129
|
return Promise.resolve({
|
|
@@ -1146,16 +1138,17 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
|
|
|
1146
1138
|
* @throws {@link CCIPReceiptNotFoundError} if execution receipt not found within timeout
|
|
1147
1139
|
*/
|
|
1148
1140
|
async execute(opts: Parameters<Chain['execute']>[0]): Promise<CCIPExecution> {
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
const { offRamp, wallet } = opts
|
|
1152
|
-
if (!isTONWallet(wallet)) {
|
|
1153
|
-
throw new CCIPWalletInvalidError(wallet)
|
|
1154
|
-
}
|
|
1141
|
+
const { wallet } = opts
|
|
1142
|
+
if (!isTONWallet(wallet)) throw new CCIPWalletInvalidError(wallet)
|
|
1155
1143
|
const payer = await wallet.getAddress()
|
|
1156
1144
|
|
|
1145
|
+
const resolved = await this.resolveExecuteOpts(opts)
|
|
1146
|
+
const { offRamp } = resolved
|
|
1147
|
+
if (!('message' in resolved.input)) throw new CCIPExecutionReportChainMismatchError('TON')
|
|
1148
|
+
const message = resolved.input.message as CCIPMessage_V1_6_EVM
|
|
1149
|
+
|
|
1157
1150
|
const { family: _, ...unsigned } = await this.generateUnsignedExecute({
|
|
1158
|
-
...
|
|
1151
|
+
...resolved,
|
|
1159
1152
|
payer,
|
|
1160
1153
|
})
|
|
1161
1154
|
|
|
@@ -1166,7 +1159,6 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
|
|
|
1166
1159
|
...unsigned,
|
|
1167
1160
|
})
|
|
1168
1161
|
|
|
1169
|
-
const message = opts.input.message as CCIPMessage_V1_6_EVM
|
|
1170
1162
|
for await (const exec of this.getExecutionReceipts({
|
|
1171
1163
|
offRamp,
|
|
1172
1164
|
messageId: message.messageId,
|
package/src/ton/send.ts
CHANGED
|
@@ -54,6 +54,7 @@ function encodeTokenAmounts(
|
|
|
54
54
|
* - allowOutOfOrderExecution: 1 bit
|
|
55
55
|
* @param extraArgs - Extra arguments for CCIP message
|
|
56
56
|
* @returns Cell encoding the extra arguments
|
|
57
|
+
* @throws {@link CCIPExtraArgsInvalidError} if `extraArgs` contains fields other than `gasLimit` and `allowOutOfOrderExecution`
|
|
57
58
|
*/
|
|
58
59
|
export function encodeExtraArgsCell(extraArgs: ExtraArgs): Cell {
|
|
59
60
|
if (
|
|
@@ -78,6 +79,12 @@ export function encodeExtraArgsCell(extraArgs: ExtraArgs): Cell {
|
|
|
78
79
|
* Builds the Router ccipSend message cell.
|
|
79
80
|
*
|
|
80
81
|
* Relies on TL-B structure (Router_CCIPSend) from chainlink-ton repo.
|
|
82
|
+
*
|
|
83
|
+
* @param destChainSelector - Destination chain selector
|
|
84
|
+
* @param message - CCIP message containing receiver, data, tokenAmounts, and extraArgs
|
|
85
|
+
* @param feeTokenAddress - Fee token jetton address, or null for native TON
|
|
86
|
+
* @param queryId - TON query ID for the message (default: 0)
|
|
87
|
+
* @returns Cell containing the encoded Router ccipSend message
|
|
81
88
|
*/
|
|
82
89
|
export function buildCcipSendCell(
|
|
83
90
|
destChainSelector: bigint,
|
package/src/utils.ts
CHANGED
|
@@ -476,7 +476,7 @@ export function convertKeysToCamelCase(
|
|
|
476
476
|
mapValues?: (value: unknown, key?: string) => unknown,
|
|
477
477
|
key?: string,
|
|
478
478
|
): unknown {
|
|
479
|
-
if (Array.isArray(obj) && obj.every((v) => typeof v === 'number')) {
|
|
479
|
+
if (Array.isArray(obj) && obj.length && obj.every((v) => typeof v === 'number')) {
|
|
480
480
|
return mapValues ? mapValues(obj, key) : obj
|
|
481
481
|
} else if (Array.isArray(obj)) {
|
|
482
482
|
return obj.map((v) => convertKeysToCamelCase(v, mapValues, key))
|
|
@@ -608,7 +608,10 @@ export async function withRetry<T>(
|
|
|
608
608
|
/**
|
|
609
609
|
* Parses a typeAndVersion string into its components.
|
|
610
610
|
* @param typeAndVersion - String in format "TypeName vX.Y.Z".
|
|
611
|
-
* @returns Tuple of [
|
|
611
|
+
* @returns Tuple of `[normalizedType, normalizedVersion, original, suffix?]` where
|
|
612
|
+
* `normalizedType` has kebab-to-PascalCase, `CCIP` uppercasing, and ramp casing applied
|
|
613
|
+
* (e.g., `"ccip-offramp"` becomes `"CCIPOffRamp"`), and `normalizedVersion` has the patch
|
|
614
|
+
* component forced to `.0` for core contracts (OnRamp, OffRamp, Router).
|
|
612
615
|
* @throws {@link CCIPTypeVersionInvalidError} if string format is invalid
|
|
613
616
|
*/
|
|
614
617
|
export function parseTypeAndVersion(
|
|
@@ -828,7 +831,11 @@ export function createRateLimitedFetch(
|
|
|
828
831
|
*
|
|
829
832
|
* @param url - URL to fetch
|
|
830
833
|
* @param operation - Operation name for error context
|
|
831
|
-
* @param opts - Optional
|
|
834
|
+
* @param opts - Optional configuration:
|
|
835
|
+
* - `timeoutMs` — request timeout in milliseconds (default: 30000).
|
|
836
|
+
* - `signal` — an external `AbortSignal` to cancel the request.
|
|
837
|
+
* - `fetch` — custom fetch function (defaults to `globalThis.fetch`).
|
|
838
|
+
* - `init` — additional `RequestInit` fields merged into the fetch call.
|
|
832
839
|
* @returns Promise resolving to Response
|
|
833
840
|
* @throws CCIPTimeoutError if request times out
|
|
834
841
|
* @throws CCIPAbortError if request is aborted via signal
|