@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.
Files changed (106) hide show
  1. package/dist/api/index.d.ts +17 -6
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/index.js +17 -6
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/aptos/index.d.ts +7 -1
  6. package/dist/aptos/index.d.ts.map +1 -1
  7. package/dist/aptos/index.js +20 -0
  8. package/dist/aptos/index.js.map +1 -1
  9. package/dist/chain.d.ts +65 -7
  10. package/dist/chain.d.ts.map +1 -1
  11. package/dist/chain.js +47 -3
  12. package/dist/chain.js.map +1 -1
  13. package/dist/errors/codes.d.ts +1 -2
  14. package/dist/errors/codes.d.ts.map +1 -1
  15. package/dist/errors/codes.js +1 -2
  16. package/dist/errors/codes.js.map +1 -1
  17. package/dist/errors/index.d.ts +2 -2
  18. package/dist/errors/index.d.ts.map +1 -1
  19. package/dist/errors/index.js +2 -2
  20. package/dist/errors/index.js.map +1 -1
  21. package/dist/errors/recovery.d.ts.map +1 -1
  22. package/dist/errors/recovery.js +2 -3
  23. package/dist/errors/recovery.js.map +1 -1
  24. package/dist/errors/specialized.d.ts +23 -28
  25. package/dist/errors/specialized.d.ts.map +1 -1
  26. package/dist/errors/specialized.js +33 -37
  27. package/dist/errors/specialized.js.map +1 -1
  28. package/dist/evm/const.d.ts.map +1 -1
  29. package/dist/evm/const.js +1 -0
  30. package/dist/evm/const.js.map +1 -1
  31. package/dist/evm/errors.d.ts.map +1 -1
  32. package/dist/evm/errors.js +20 -5
  33. package/dist/evm/errors.js.map +1 -1
  34. package/dist/evm/extra-args.d.ts.map +1 -1
  35. package/dist/evm/extra-args.js +14 -13
  36. package/dist/evm/extra-args.js.map +1 -1
  37. package/dist/evm/index.d.ts +11 -2
  38. package/dist/evm/index.d.ts.map +1 -1
  39. package/dist/evm/index.js +73 -22
  40. package/dist/evm/index.js.map +1 -1
  41. package/dist/gas.d.ts +2 -1
  42. package/dist/gas.d.ts.map +1 -1
  43. package/dist/gas.js +2 -1
  44. package/dist/gas.js.map +1 -1
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/offchain.d.ts +1 -0
  49. package/dist/offchain.d.ts.map +1 -1
  50. package/dist/offchain.js +1 -0
  51. package/dist/offchain.js.map +1 -1
  52. package/dist/requests.d.ts +7 -6
  53. package/dist/requests.d.ts.map +1 -1
  54. package/dist/requests.js +7 -8
  55. package/dist/requests.js.map +1 -1
  56. package/dist/solana/idl/1.6.0/FEE_QUOTER.d.ts +1719 -0
  57. package/dist/solana/idl/1.6.0/FEE_QUOTER.d.ts.map +1 -0
  58. package/dist/solana/idl/1.6.0/FEE_QUOTER.js +1719 -0
  59. package/dist/solana/idl/1.6.0/FEE_QUOTER.js.map +1 -0
  60. package/dist/solana/index.d.ts +34 -18
  61. package/dist/solana/index.d.ts.map +1 -1
  62. package/dist/solana/index.js +45 -5
  63. package/dist/solana/index.js.map +1 -1
  64. package/dist/solana/utils.d.ts +5 -2
  65. package/dist/solana/utils.d.ts.map +1 -1
  66. package/dist/solana/utils.js +5 -2
  67. package/dist/solana/utils.js.map +1 -1
  68. package/dist/sui/index.d.ts +1 -1
  69. package/dist/sui/index.d.ts.map +1 -1
  70. package/dist/sui/index.js +14 -14
  71. package/dist/sui/index.js.map +1 -1
  72. package/dist/ton/index.d.ts +11 -9
  73. package/dist/ton/index.d.ts.map +1 -1
  74. package/dist/ton/index.js +24 -26
  75. package/dist/ton/index.js.map +1 -1
  76. package/dist/ton/send.d.ts +7 -0
  77. package/dist/ton/send.d.ts.map +1 -1
  78. package/dist/ton/send.js +7 -0
  79. package/dist/ton/send.js.map +1 -1
  80. package/dist/utils.d.ts +9 -2
  81. package/dist/utils.d.ts.map +1 -1
  82. package/dist/utils.js +10 -3
  83. package/dist/utils.js.map +1 -1
  84. package/package.json +8 -8
  85. package/src/api/index.ts +17 -6
  86. package/src/aptos/index.ts +31 -0
  87. package/src/chain.ts +80 -8
  88. package/src/errors/codes.ts +1 -2
  89. package/src/errors/index.ts +1 -2
  90. package/src/errors/recovery.ts +2 -3
  91. package/src/errors/specialized.ts +35 -38
  92. package/src/evm/const.ts +1 -0
  93. package/src/evm/errors.ts +22 -5
  94. package/src/evm/extra-args.ts +15 -14
  95. package/src/evm/index.ts +110 -21
  96. package/src/gas.ts +2 -1
  97. package/src/index.ts +1 -0
  98. package/src/offchain.ts +1 -0
  99. package/src/requests.ts +8 -8
  100. package/src/solana/idl/1.6.0/FEE_QUOTER.ts +3440 -0
  101. package/src/solana/index.ts +60 -4
  102. package/src/solana/utils.ts +5 -2
  103. package/src/sui/index.ts +17 -15
  104. package/src/ton/index.ts +23 -31
  105. package/src/ton/send.ts +7 -0
  106. package/src/utils.ts +10 -3
@@ -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
- return encodeBase58(getDataBytes(bytes))
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 &&
@@ -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
- 'tokenReceiver' in message.extraArgs &&
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
- ? this.getAddress(message.receiver)
859
- : '0x0000000000000000000000000000000000000000000000000000000000000000'
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 BOC-encoded extra arguments from TON messages.
722
- * Parses the BOC format and extracts extra args, validating the magic tag
723
- * to ensure correct type. Returns undefined if parsing fails or tag doesn't match.
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 - BOC-encoded extra args as hex string or bytes
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
- if (
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
- opts,
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
- if (!('input' in opts && 'message' in opts.input))
1150
- throw new CCIPExecutionReportChainMismatchError('TON')
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
- ...opts,
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 [type, version, original, suffix?].
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 timeout, abort signal, fetch function, and extra RequestInit fields
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