@chainlink/ccip-sdk 0.95.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.
Files changed (217) hide show
  1. package/README.md +2 -2
  2. package/dist/all-chains.d.ts +23 -0
  3. package/dist/all-chains.d.ts.map +1 -0
  4. package/dist/all-chains.js +24 -0
  5. package/dist/all-chains.js.map +1 -0
  6. package/dist/api/index.d.ts +31 -19
  7. package/dist/api/index.d.ts.map +1 -1
  8. package/dist/api/index.js +46 -25
  9. package/dist/api/index.js.map +1 -1
  10. package/dist/api/types.d.ts +24 -30
  11. package/dist/api/types.d.ts.map +1 -1
  12. package/dist/aptos/exec.d.ts +2 -2
  13. package/dist/aptos/exec.d.ts.map +1 -1
  14. package/dist/aptos/exec.js.map +1 -1
  15. package/dist/aptos/hasher.d.ts.map +1 -1
  16. package/dist/aptos/hasher.js +1 -1
  17. package/dist/aptos/hasher.js.map +1 -1
  18. package/dist/aptos/index.d.ts +43 -15
  19. package/dist/aptos/index.d.ts.map +1 -1
  20. package/dist/aptos/index.js +112 -105
  21. package/dist/aptos/index.js.map +1 -1
  22. package/dist/aptos/types.d.ts +2 -19
  23. package/dist/aptos/types.d.ts.map +1 -1
  24. package/dist/aptos/types.js +0 -11
  25. package/dist/aptos/types.js.map +1 -1
  26. package/dist/chain.d.ts +734 -174
  27. package/dist/chain.d.ts.map +1 -1
  28. package/dist/chain.js +216 -31
  29. package/dist/chain.js.map +1 -1
  30. package/dist/commits.d.ts +4 -6
  31. package/dist/commits.d.ts.map +1 -1
  32. package/dist/commits.js +4 -4
  33. package/dist/commits.js.map +1 -1
  34. package/dist/errors/CCIPError.d.ts +33 -4
  35. package/dist/errors/CCIPError.d.ts.map +1 -1
  36. package/dist/errors/CCIPError.js +33 -4
  37. package/dist/errors/CCIPError.js.map +1 -1
  38. package/dist/errors/codes.d.ts +5 -0
  39. package/dist/errors/codes.d.ts.map +1 -1
  40. package/dist/errors/codes.js +5 -1
  41. package/dist/errors/codes.js.map +1 -1
  42. package/dist/errors/index.d.ts +2 -2
  43. package/dist/errors/index.d.ts.map +1 -1
  44. package/dist/errors/index.js +2 -2
  45. package/dist/errors/index.js.map +1 -1
  46. package/dist/errors/recovery.d.ts.map +1 -1
  47. package/dist/errors/recovery.js +6 -1
  48. package/dist/errors/recovery.js.map +1 -1
  49. package/dist/errors/specialized.d.ts +1702 -121
  50. package/dist/errors/specialized.d.ts.map +1 -1
  51. package/dist/errors/specialized.js +1729 -125
  52. package/dist/errors/specialized.js.map +1 -1
  53. package/dist/errors/utils.d.ts.map +1 -1
  54. package/dist/errors/utils.js +0 -1
  55. package/dist/errors/utils.js.map +1 -1
  56. package/dist/evm/abi/OffRamp_2_0.d.ts +764 -0
  57. package/dist/evm/abi/OffRamp_2_0.d.ts.map +1 -0
  58. package/dist/evm/abi/OffRamp_2_0.js +744 -0
  59. package/dist/evm/abi/OffRamp_2_0.js.map +1 -0
  60. package/dist/evm/abi/OnRamp_2_0.d.ts +925 -0
  61. package/dist/evm/abi/OnRamp_2_0.d.ts.map +1 -0
  62. package/dist/evm/abi/OnRamp_2_0.js +992 -0
  63. package/dist/evm/abi/OnRamp_2_0.js.map +1 -0
  64. package/dist/evm/const.d.ts +12 -2
  65. package/dist/evm/const.d.ts.map +1 -1
  66. package/dist/evm/const.js +8 -2
  67. package/dist/evm/const.js.map +1 -1
  68. package/dist/evm/errors.d.ts.map +1 -1
  69. package/dist/evm/errors.js +7 -2
  70. package/dist/evm/errors.js.map +1 -1
  71. package/dist/evm/extra-args.d.ts +25 -0
  72. package/dist/evm/extra-args.d.ts.map +1 -0
  73. package/dist/evm/extra-args.js +309 -0
  74. package/dist/evm/extra-args.js.map +1 -0
  75. package/dist/evm/gas.d.ts.map +1 -1
  76. package/dist/evm/gas.js +7 -12
  77. package/dist/evm/gas.js.map +1 -1
  78. package/dist/evm/hasher.d.ts.map +1 -1
  79. package/dist/evm/hasher.js +23 -13
  80. package/dist/evm/hasher.js.map +1 -1
  81. package/dist/evm/index.d.ts +140 -35
  82. package/dist/evm/index.d.ts.map +1 -1
  83. package/dist/evm/index.js +306 -226
  84. package/dist/evm/index.js.map +1 -1
  85. package/dist/evm/messages.d.ts +59 -5
  86. package/dist/evm/messages.d.ts.map +1 -1
  87. package/dist/evm/messages.js +210 -0
  88. package/dist/evm/messages.js.map +1 -1
  89. package/dist/evm/offchain.js.map +1 -1
  90. package/dist/evm/types.d.ts +7 -2
  91. package/dist/evm/types.d.ts.map +1 -1
  92. package/dist/evm/types.js +22 -1
  93. package/dist/evm/types.js.map +1 -1
  94. package/dist/execution.d.ts +62 -22
  95. package/dist/execution.d.ts.map +1 -1
  96. package/dist/execution.js +102 -51
  97. package/dist/execution.js.map +1 -1
  98. package/dist/extra-args.d.ts +113 -4
  99. package/dist/extra-args.d.ts.map +1 -1
  100. package/dist/extra-args.js +38 -3
  101. package/dist/extra-args.js.map +1 -1
  102. package/dist/gas.d.ts +31 -5
  103. package/dist/gas.d.ts.map +1 -1
  104. package/dist/gas.js +43 -9
  105. package/dist/gas.js.map +1 -1
  106. package/dist/index.d.ts +11 -10
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +8 -8
  109. package/dist/index.js.map +1 -1
  110. package/dist/requests.d.ts +101 -22
  111. package/dist/requests.d.ts.map +1 -1
  112. package/dist/requests.js +115 -24
  113. package/dist/requests.js.map +1 -1
  114. package/dist/selectors.d.ts.map +1 -1
  115. package/dist/selectors.js +24 -0
  116. package/dist/selectors.js.map +1 -1
  117. package/dist/shared/bcs-codecs.d.ts +61 -0
  118. package/dist/shared/bcs-codecs.d.ts.map +1 -0
  119. package/dist/shared/bcs-codecs.js +102 -0
  120. package/dist/shared/bcs-codecs.js.map +1 -0
  121. package/dist/shared/constants.d.ts +3 -0
  122. package/dist/shared/constants.d.ts.map +1 -0
  123. package/dist/shared/constants.js +3 -0
  124. package/dist/shared/constants.js.map +1 -0
  125. package/dist/solana/exec.d.ts +2 -2
  126. package/dist/solana/exec.d.ts.map +1 -1
  127. package/dist/solana/exec.js.map +1 -1
  128. package/dist/solana/index.d.ts +148 -30
  129. package/dist/solana/index.d.ts.map +1 -1
  130. package/dist/solana/index.js +137 -44
  131. package/dist/solana/index.js.map +1 -1
  132. package/dist/sui/hasher.d.ts.map +1 -1
  133. package/dist/sui/hasher.js +1 -1
  134. package/dist/sui/hasher.js.map +1 -1
  135. package/dist/sui/index.d.ts +49 -19
  136. package/dist/sui/index.d.ts.map +1 -1
  137. package/dist/sui/index.js +76 -43
  138. package/dist/sui/index.js.map +1 -1
  139. package/dist/sui/manuallyExec/encoder.d.ts +2 -2
  140. package/dist/sui/manuallyExec/encoder.d.ts.map +1 -1
  141. package/dist/sui/manuallyExec/encoder.js.map +1 -1
  142. package/dist/sui/manuallyExec/index.d.ts +2 -2
  143. package/dist/sui/manuallyExec/index.d.ts.map +1 -1
  144. package/dist/ton/exec.d.ts +2 -2
  145. package/dist/ton/exec.d.ts.map +1 -1
  146. package/dist/ton/exec.js.map +1 -1
  147. package/dist/ton/index.d.ts +66 -27
  148. package/dist/ton/index.d.ts.map +1 -1
  149. package/dist/ton/index.js +172 -47
  150. package/dist/ton/index.js.map +1 -1
  151. package/dist/ton/send.d.ts +52 -0
  152. package/dist/ton/send.d.ts.map +1 -0
  153. package/dist/ton/send.js +166 -0
  154. package/dist/ton/send.js.map +1 -0
  155. package/dist/ton/types.d.ts +2 -2
  156. package/dist/ton/types.d.ts.map +1 -1
  157. package/dist/ton/types.js.map +1 -1
  158. package/dist/types.d.ts +148 -12
  159. package/dist/types.d.ts.map +1 -1
  160. package/dist/types.js +6 -1
  161. package/dist/types.js.map +1 -1
  162. package/dist/utils.d.ts +79 -4
  163. package/dist/utils.d.ts.map +1 -1
  164. package/dist/utils.js +92 -7
  165. package/dist/utils.js.map +1 -1
  166. package/package.json +16 -11
  167. package/src/all-chains.ts +26 -0
  168. package/src/api/index.ts +58 -34
  169. package/src/api/types.ts +24 -31
  170. package/src/aptos/exec.ts +2 -2
  171. package/src/aptos/hasher.ts +1 -1
  172. package/src/aptos/index.ts +127 -129
  173. package/src/aptos/types.ts +2 -15
  174. package/src/chain.ts +837 -191
  175. package/src/commits.ts +9 -9
  176. package/src/errors/CCIPError.ts +33 -4
  177. package/src/errors/codes.ts +5 -1
  178. package/src/errors/index.ts +2 -1
  179. package/src/errors/recovery.ts +9 -1
  180. package/src/errors/specialized.ts +1745 -132
  181. package/src/errors/utils.ts +0 -1
  182. package/src/evm/abi/OffRamp_2_0.ts +743 -0
  183. package/src/evm/abi/OnRamp_2_0.ts +991 -0
  184. package/src/evm/const.ts +10 -3
  185. package/src/evm/errors.ts +6 -2
  186. package/src/evm/extra-args.ts +360 -0
  187. package/src/evm/gas.ts +14 -13
  188. package/src/evm/hasher.ts +30 -18
  189. package/src/evm/index.ts +376 -281
  190. package/src/evm/messages.ts +323 -11
  191. package/src/evm/offchain.ts +2 -2
  192. package/src/evm/types.ts +20 -2
  193. package/src/execution.ts +126 -71
  194. package/src/extra-args.ts +118 -4
  195. package/src/gas.ts +44 -11
  196. package/src/index.ts +14 -11
  197. package/src/requests.ts +128 -24
  198. package/src/selectors.ts +24 -0
  199. package/src/shared/bcs-codecs.ts +132 -0
  200. package/src/shared/constants.ts +2 -0
  201. package/src/solana/exec.ts +4 -4
  202. package/src/solana/index.ts +170 -82
  203. package/src/sui/hasher.ts +1 -1
  204. package/src/sui/index.ts +88 -56
  205. package/src/sui/manuallyExec/encoder.ts +2 -2
  206. package/src/sui/manuallyExec/index.ts +2 -2
  207. package/src/ton/exec.ts +2 -2
  208. package/src/ton/index.ts +220 -58
  209. package/src/ton/send.ts +222 -0
  210. package/src/ton/types.ts +2 -2
  211. package/src/types.ts +173 -30
  212. package/src/utils.ts +91 -7
  213. package/dist/aptos/utils.d.ts +0 -12
  214. package/dist/aptos/utils.d.ts.map +0 -1
  215. package/dist/aptos/utils.js +0 -15
  216. package/dist/aptos/utils.js.map +0 -1
  217. package/src/aptos/utils.ts +0 -24
package/src/ton/index.ts CHANGED
@@ -8,9 +8,11 @@ import { type Memoized, memoize } from 'micro-memoize'
8
8
  import type { PickDeep } from 'type-fest'
9
9
 
10
10
  import { streamTransactionsForAddress } from './logs.ts'
11
+ import { generateUnsignedCcipSend, getFee as getFeeImpl } from './send.ts'
11
12
  import { type ChainContext, type GetBalanceOpts, type LogFilter, Chain } from '../chain.ts'
12
13
  import {
13
14
  CCIPArgumentInvalidError,
15
+ CCIPExecutionReportChainMismatchError,
14
16
  CCIPExtraArgsInvalidError,
15
17
  CCIPHttpError,
16
18
  CCIPNotImplementedError,
@@ -19,21 +21,24 @@ import {
19
21
  CCIPTopicsInvalidError,
20
22
  CCIPTransactionNotFoundError,
21
23
  CCIPWalletInvalidError,
22
- } from '../errors/specialized.ts'
24
+ } from '../errors/index.ts'
23
25
  import { type EVMExtraArgsV2, type ExtraArgs, EVMExtraArgsV2Tag } from '../extra-args.ts'
26
+ import type { LeafHasher } from '../hasher/common.ts'
27
+ import { buildMessageForDest, getMessagesInBatch } from '../requests.ts'
24
28
  import { supportedChains } from '../supported-chains.ts'
25
29
  import {
26
30
  type CCIPExecution,
27
31
  type CCIPRequest,
28
32
  type ChainTransaction,
29
33
  type CommitReport,
34
+ type ExecutionInput,
30
35
  type ExecutionReceipt,
31
- type ExecutionReport,
32
36
  type Lane,
33
37
  type Log_,
34
38
  type NetworkInfo,
35
39
  type OffchainTokenData,
36
40
  type WithLogger,
41
+ CCIPVersion,
37
42
  ChainFamily,
38
43
  ExecutionState,
39
44
  } from '../types.ts'
@@ -45,11 +50,10 @@ import {
45
50
  parseTypeAndVersion,
46
51
  sleep,
47
52
  } from '../utils.ts'
48
- import { generateUnsignedExecuteReport as generateUnsignedExecuteReportImpl } from './exec.ts'
53
+ import { generateUnsignedExecuteReport } from './exec.ts'
49
54
  import { getTONLeafHasher } from './hasher.ts'
50
55
  import { type CCIPMessage_V1_6_TON, type UnsignedTONTx, isTONWallet } from './types.ts'
51
56
  import { crc32, lookupTxByRawHash, parseJettonContent } from './utils.ts'
52
- import type { LeafHasher } from '../hasher/common.ts'
53
57
  export type { TONWallet, UnsignedTONTx } from './types.ts'
54
58
 
55
59
  /**
@@ -179,6 +183,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
179
183
  * @param url - RPC endpoint URL for TonClient (v2).
180
184
  * @param ctx - Context containing logger.
181
185
  * @returns A new TONChain instance.
186
+ * @throws {@link CCIPHttpError} if connection to the RPC endpoint fails
182
187
  */
183
188
  static async fromUrl(url: string, ctx?: ChainContext): Promise<TONChain> {
184
189
  const { logger = console } = ctx ?? {}
@@ -219,6 +224,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
219
224
  *
220
225
  * @param block - Logical time (lt) as number, or 'finalized' for latest block timestamp
221
226
  * @returns Unix timestamp in seconds
227
+ * @throws {@link CCIPNotImplementedError} if lt is not in cache
222
228
  */
223
229
  async getBlockTimestamp(block: number | 'finalized'): Promise<number> {
224
230
  if (typeof block != 'number') {
@@ -246,6 +252,8 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
246
252
  * @param tx - Transaction identifier in either format
247
253
  * @returns ChainTransaction with transaction details
248
254
  * Note: `blockNumber` contains logical time (lt), not block seqno
255
+ * @throws {@link CCIPArgumentInvalidError} if hash format is invalid
256
+ * @throws {@link CCIPTransactionNotFoundError} if transaction not found
249
257
  */
250
258
  async getTransaction(tx: string | Transaction): Promise<ChainTransaction> {
251
259
  let address
@@ -340,6 +348,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
340
348
  * not block sequence numbers. This is because TON transaction APIs are indexed by lt.
341
349
  *
342
350
  * @param opts - Log filter options (startBlock/endBlock are interpreted as lt values)
351
+ * @throws {@link CCIPTopicsInvalidError} if topics format is invalid
343
352
  */
344
353
  async *getLogs(opts: LogFilter): AsyncIterableIterator<Log_> {
345
354
  let topics
@@ -369,11 +378,11 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
369
378
  'lane' | `log.${'topics' | 'address' | 'blockNumber'}` | 'message.sequenceNumber'
370
379
  >,
371
380
  >(
372
- _request: R,
373
- _commit: Pick<CommitReport, 'minSeqNr' | 'maxSeqNr'>,
374
- _opts?: { page?: number },
381
+ request: R,
382
+ range: Pick<CommitReport, 'minSeqNr' | 'maxSeqNr'>,
383
+ opts?: Pick<LogFilter, 'page'>,
375
384
  ): Promise<R['message'][]> {
376
- return Promise.reject(new CCIPNotImplementedError('getMessagesInBatch'))
385
+ return getMessagesInBatch(this, request, range, opts)
377
386
  }
378
387
 
379
388
  /** {@inheritDoc Chain.typeAndVersion} */
@@ -420,9 +429,14 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
420
429
  return stack.readAddress().toRawString()
421
430
  }
422
431
 
423
- /** {@inheritDoc Chain.getNativeTokenForRouter} */
432
+ /**
433
+ * {@inheritDoc Chain.getNativeTokenForRouter}
434
+ * @throws {@link CCIPNotImplementedError} always (not implemented for TON)
435
+ */
424
436
  getNativeTokenForRouter(_router: string): Promise<string> {
425
- return Promise.reject(new CCIPNotImplementedError('getNativeTokenForRouter'))
437
+ // TON native token is represented as address 0:0...01 (workchain 0, hash = 1)
438
+ // This is a convention for representing native TON in CCIP
439
+ return Promise.resolve('0:0000000000000000000000000000000000000000000000000000000000000001')
426
440
  }
427
441
 
428
442
  /** {@inheritDoc Chain.getOffRampsForRouter} */
@@ -445,8 +459,11 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
445
459
  return stack.readAddress().toRawString()
446
460
  }
447
461
 
448
- /** {@inheritDoc Chain.getOnRampForOffRamp} */
449
- async getOnRampForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise<string> {
462
+ /**
463
+ * {@inheritDoc Chain.getOnRampsForOffRamp}
464
+ * @throws {@link CCIPSourceChainUnsupportedError} if source chain is not configured
465
+ */
466
+ async getOnRampsForOffRamp(offRamp: string, sourceChainSelector: bigint): Promise<string[]> {
450
467
  try {
451
468
  const offRampContract = this.provider.provider(Address.parse(offRamp))
452
469
 
@@ -474,7 +491,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
474
491
  const onRampLength = onRampSlice.loadUint(8)
475
492
  onRamp = onRampSlice.loadBuffer(onRampLength)
476
493
  }
477
- return decodeAddress(onRamp, networkInfo(sourceChainSelector).family)
494
+ return [decodeAddress(onRamp, networkInfo(sourceChainSelector).family)]
478
495
  } catch (error) {
479
496
  if (isTvmError(error) && error.exitCode === 266) {
480
497
  throw new CCIPSourceChainUnsupportedError(sourceChainSelector, {
@@ -485,13 +502,10 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
485
502
  }
486
503
  }
487
504
 
488
- /** {@inheritDoc Chain.getCommitStoreForOffRamp} */
489
- async getCommitStoreForOffRamp(offRamp: string): Promise<string> {
490
- // TODO: FIXME: check assumption
491
- return Promise.resolve(offRamp)
492
- }
493
-
494
- /** {@inheritDoc Chain.getTokenForTokenPool} */
505
+ /**
506
+ * {@inheritDoc Chain.getTokenForTokenPool}
507
+ * @throws {@link CCIPNotImplementedError} always (not implemented for TON)
508
+ */
495
509
  async getTokenForTokenPool(_tokenPool: string): Promise<string> {
496
510
  return Promise.reject(new CCIPNotImplementedError('getTokenForTokenPool'))
497
511
  }
@@ -519,12 +533,45 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
519
533
  }
520
534
  }
521
535
 
522
- /** {@inheritDoc Chain.getBalance} */
523
- async getBalance(_opts: GetBalanceOpts): Promise<bigint> {
524
- return Promise.reject(new CCIPNotImplementedError('TONChain.getBalance'))
536
+ /**
537
+ * {@inheritDoc Chain.getBalance}
538
+ * @throws {@link CCIPNotImplementedError} always (not implemented for TON)
539
+ */
540
+ async getBalance(opts: GetBalanceOpts): Promise<bigint> {
541
+ const { holder, token } = opts
542
+ const holderAddress = Address.parse(holder)
543
+
544
+ if (!token) {
545
+ // Get native TON balance
546
+ const state = await this.provider.getContractState(holderAddress)
547
+ return state.balance
548
+ }
549
+
550
+ // For jetton balance, we need to:
551
+ // 1. Derive the jetton wallet address for this holder
552
+ // 2. Query the balance from that wallet contract
553
+ const jettonMaster = Address.parse(token)
554
+ const { stack } = await this.provider.runMethod(jettonMaster, 'get_wallet_address', [
555
+ { type: 'slice', cell: beginCell().storeAddress(holderAddress).endCell() },
556
+ ])
557
+ const jettonWalletAddress = stack.readAddress()
558
+
559
+ try {
560
+ const { stack: balanceStack } = await this.provider.runMethod(
561
+ jettonWalletAddress,
562
+ 'get_wallet_data',
563
+ )
564
+ return balanceStack.readBigNumber() // First value is balance
565
+ } catch {
566
+ // Wallet doesn't exist yet = 0 balance
567
+ return 0n
568
+ }
525
569
  }
526
570
 
527
- /** {@inheritDoc Chain.getTokenAdminRegistryFor} */
571
+ /**
572
+ * {@inheritDoc Chain.getTokenAdminRegistryFor}
573
+ * @throws {@link CCIPNotImplementedError} always (not implemented for TON)
574
+ */
528
575
  getTokenAdminRegistryFor(_address: string): Promise<string> {
529
576
  return Promise.reject(new CCIPNotImplementedError('getTokenAdminRegistryFor'))
530
577
  }
@@ -562,7 +609,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
562
609
  }
563
610
 
564
611
  // Load sender address
565
- const sender = slice.loadAddress().toString()
612
+ const sender = slice.loadAddress().toRawString()
566
613
 
567
614
  // Load body cell ref
568
615
  const bodyCell = slice.loadRef()
@@ -609,10 +656,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
609
656
  const allowOutOfOrderExecution = extraArgsSlice.loadBit()
610
657
 
611
658
  // Build extraArgs as raw hex matching reference format
612
- const tagHex = extraArgsTag.toString(16).padStart(8, '0')
613
- const gasLimitHex = (hasGasLimit ? '8' : '0') + gasLimit.toString(16).padStart(63, '0')
614
- const oooByte = allowOutOfOrderExecution ? '40' : '00'
615
- const extraArgs = '0x' + tagHex + gasLimitHex + oooByte
659
+ const extraArgs = '0x' + extraArgsCell.toBoc().toString('hex')
616
660
 
617
661
  // Load tokenAmounts from ref 3
618
662
  const _tokenAmountsCell = bodySlice.loadRef()
@@ -777,7 +821,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
777
821
  * - sourceChainSelector: uint64 (8 bytes)
778
822
  * - sequenceNumber: uint64 (8 bytes)
779
823
  * - messageId: uint256 (32 bytes)
780
- * - state: uint8 (1 byte) - Untouched=0, InProgress=1, Success=2, Failure=3
824
+ * - state: uint8 (1 byte) - InProgress=1, Success=2, Failed=3
781
825
  *
782
826
  * @param log - Log with data field (base64-encoded BOC).
783
827
  * @returns ExecutionReceipt or undefined if not valid.
@@ -832,6 +876,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
832
876
  * and raw format strings ("workchain:hash").
833
877
  * @param bytes - Bytes or string to convert.
834
878
  * @returns TON raw address string in format "workchain:hash".
879
+ * @throws {@link CCIPArgumentInvalidError} if bytes length is invalid
835
880
  */
836
881
  static getAddress(bytes: BytesLike): string {
837
882
  // If it's already a string address, try to parse and return raw format
@@ -951,20 +996,107 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
951
996
  }
952
997
 
953
998
  /** {@inheritDoc Chain.getFee} */
954
- async getFee(_opts: Parameters<Chain['getFee']>[0]): Promise<bigint> {
955
- return Promise.reject(new CCIPNotImplementedError('getFee'))
999
+ async getFee({
1000
+ router,
1001
+ destChainSelector,
1002
+ message,
1003
+ }: Parameters<Chain['getFee']>[0]): Promise<bigint> {
1004
+ return getFeeImpl(
1005
+ this,
1006
+ router,
1007
+ destChainSelector,
1008
+ buildMessageForDest(message, networkInfo(destChainSelector).family),
1009
+ )
956
1010
  }
957
1011
 
958
1012
  /** {@inheritDoc Chain.generateUnsignedSendMessage} */
959
- generateUnsignedSendMessage(
960
- _opts: Parameters<Chain['generateUnsignedSendMessage']>[0],
961
- ): Promise<never> {
962
- return Promise.reject(new CCIPNotImplementedError('generateUnsignedSendMessage'))
1013
+ async generateUnsignedSendMessage({
1014
+ router,
1015
+ destChainSelector,
1016
+ message,
1017
+ sender,
1018
+ }: Parameters<Chain['generateUnsignedSendMessage']>[0]): Promise<UnsignedTONTx> {
1019
+ // Convert MessageInput to AnyMessage with defaults
1020
+ const populatedMessage = buildMessageForDest(message, networkInfo(destChainSelector).family)
1021
+
1022
+ // Calculate fee if not provided
1023
+ const fee =
1024
+ message.fee ??
1025
+ (await this.getFee({
1026
+ router,
1027
+ destChainSelector,
1028
+ message: populatedMessage,
1029
+ }))
1030
+
1031
+ const unsigned = generateUnsignedCcipSend(this, sender, router, destChainSelector, {
1032
+ ...populatedMessage,
1033
+ fee,
1034
+ })
1035
+
1036
+ return {
1037
+ family: ChainFamily.TON,
1038
+ ...unsigned,
1039
+ }
963
1040
  }
964
1041
 
965
1042
  /** {@inheritDoc Chain.sendMessage} */
966
- async sendMessage(_opts: Parameters<Chain['sendMessage']>[0]): Promise<CCIPRequest> {
967
- return Promise.reject(new CCIPNotImplementedError('sendMessage'))
1043
+ async sendMessage({
1044
+ router,
1045
+ destChainSelector,
1046
+ message,
1047
+ wallet,
1048
+ }: Parameters<Chain['sendMessage']>[0]): Promise<CCIPRequest> {
1049
+ if (!isTONWallet(wallet)) {
1050
+ throw new CCIPWalletInvalidError(wallet)
1051
+ }
1052
+
1053
+ const sender = await wallet.getAddress()
1054
+
1055
+ // Generate unsigned transaction with fee calculation if needed
1056
+ const { family: _, ...unsigned } = await this.generateUnsignedSendMessage({
1057
+ router,
1058
+ destChainSelector,
1059
+ message,
1060
+ sender,
1061
+ })
1062
+
1063
+ // Send transaction
1064
+ const startTime = Math.floor(Date.now() / 1000)
1065
+ const seqno = await wallet.sendTransaction(unsigned)
1066
+
1067
+ this.logger.info('CCIP send transaction submitted, seqno:', seqno)
1068
+
1069
+ // Wait for CCIPMessageSent event and extract the request
1070
+ // Query the OnRamp for the CCIPMessageSent event
1071
+ const onRamp = await this.getOnRampForRouter(router, destChainSelector)
1072
+
1073
+ // Poll for the message in recent logs
1074
+ for await (const log of this.getLogs({
1075
+ address: onRamp,
1076
+ topics: [crc32('CCIPMessageSent')],
1077
+ startTime,
1078
+ watch: sleep(5 * 60e3 /* 5m timeout */),
1079
+ })) {
1080
+ const msg = TONChain.decodeMessage(log)
1081
+ if (!msg) continue
1082
+
1083
+ // Found our message: construct and return the CCIPRequest
1084
+ const tx = log.tx ?? (await this.getTransaction(log.transactionHash))
1085
+
1086
+ return {
1087
+ lane: {
1088
+ sourceChainSelector: this.network.chainSelector,
1089
+ destChainSelector,
1090
+ onRamp,
1091
+ version: CCIPVersion.V1_6,
1092
+ },
1093
+ message: msg,
1094
+ log,
1095
+ tx,
1096
+ }
1097
+ }
1098
+
1099
+ throw new CCIPTransactionNotFoundError(seqno.toString())
968
1100
  }
969
1101
 
970
1102
  /** {@inheritDoc Chain.getOffchainTokenData} */
@@ -972,19 +1104,28 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
972
1104
  return Promise.resolve(request.message.tokenAmounts.map(() => undefined))
973
1105
  }
974
1106
 
975
- /** {@inheritDoc Chain.generateUnsignedExecuteReport} */
976
- generateUnsignedExecuteReport({
977
- offRamp,
978
- execReport,
979
- ...opts
980
- }: Parameters<Chain['generateUnsignedExecuteReport']>[0]): Promise<UnsignedTONTx> {
981
- if (!('allowOutOfOrderExecution' in execReport.message && 'gasLimit' in execReport.message)) {
1107
+ /**
1108
+ * {@inheritDoc Chain.generateUnsignedExecute}
1109
+ * @throws {@link CCIPExtraArgsInvalidError} if extra args are not EVMExtraArgsV2 format
1110
+ */
1111
+ generateUnsignedExecute(
1112
+ opts: Parameters<Chain['generateUnsignedExecute']>[0],
1113
+ ): Promise<UnsignedTONTx> {
1114
+ if (
1115
+ !(
1116
+ 'input' in opts &&
1117
+ 'message' in opts.input &&
1118
+ 'allowOutOfOrderExecution' in opts.input.message &&
1119
+ 'gasLimit' in opts.input.message
1120
+ )
1121
+ ) {
982
1122
  throw new CCIPExtraArgsInvalidError('TON')
983
1123
  }
1124
+ const { offRamp, input } = opts
984
1125
 
985
- const unsigned = generateUnsignedExecuteReportImpl(
1126
+ const unsigned = generateUnsignedExecuteReport(
986
1127
  offRamp,
987
- execReport as ExecutionReport<CCIPMessage_V1_6_TON>,
1128
+ input as ExecutionInput<CCIPMessage_V1_6_TON>,
988
1129
  opts,
989
1130
  )
990
1131
 
@@ -994,15 +1135,21 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
994
1135
  })
995
1136
  }
996
1137
 
997
- /** {@inheritDoc Chain.executeReport} */
998
- async executeReport(opts: Parameters<Chain['executeReport']>[0]): Promise<CCIPExecution> {
1138
+ /**
1139
+ * {@inheritDoc Chain.execute}
1140
+ * @throws {@link CCIPWalletInvalidError} if wallet is not a valid TON wallet
1141
+ * @throws {@link CCIPReceiptNotFoundError} if execution receipt not found within timeout
1142
+ */
1143
+ async execute(opts: Parameters<Chain['execute']>[0]): Promise<CCIPExecution> {
1144
+ if (!('input' in opts && 'message' in opts.input))
1145
+ throw new CCIPExecutionReportChainMismatchError('TON')
999
1146
  const { offRamp, wallet } = opts
1000
1147
  if (!isTONWallet(wallet)) {
1001
1148
  throw new CCIPWalletInvalidError(wallet)
1002
1149
  }
1003
1150
  const payer = await wallet.getAddress()
1004
1151
 
1005
- const { family: _, ...unsigned } = await this.generateUnsignedExecuteReport({
1152
+ const { family: _, ...unsigned } = await this.generateUnsignedExecute({
1006
1153
  ...opts,
1007
1154
  payer,
1008
1155
  })
@@ -1014,7 +1161,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
1014
1161
  ...unsigned,
1015
1162
  })
1016
1163
 
1017
- const message = opts.execReport.message as CCIPMessage_V1_6_TON
1164
+ const message = opts.input.message as CCIPMessage_V1_6_TON
1018
1165
  for await (const exec of this.getExecutionReceipts({
1019
1166
  offRamp,
1020
1167
  messageId: message.messageId,
@@ -1039,27 +1186,42 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
1039
1186
  }
1040
1187
  }
1041
1188
 
1042
- /** {@inheritDoc Chain.getSupportedTokens} */
1189
+ /**
1190
+ * {@inheritDoc Chain.getSupportedTokens}
1191
+ * @throws {@link CCIPNotImplementedError} always (not implemented for TON)
1192
+ */
1043
1193
  async getSupportedTokens(_address: string): Promise<string[]> {
1044
1194
  return Promise.reject(new CCIPNotImplementedError('getSupportedTokens'))
1045
1195
  }
1046
1196
 
1047
- /** {@inheritDoc Chain.getRegistryTokenConfig} */
1197
+ /**
1198
+ * {@inheritDoc Chain.getRegistryTokenConfig}
1199
+ * @throws {@link CCIPNotImplementedError} always (not implemented for TON)
1200
+ */
1048
1201
  async getRegistryTokenConfig(_address: string, _tokenName: string): Promise<never> {
1049
1202
  return Promise.reject(new CCIPNotImplementedError('getRegistryTokenConfig'))
1050
1203
  }
1051
1204
 
1052
- /** {@inheritDoc Chain.getTokenPoolConfigs} */
1053
- async getTokenPoolConfigs(_tokenPool: string): Promise<never> {
1054
- return Promise.reject(new CCIPNotImplementedError('getTokenPoolConfigs'))
1205
+ /**
1206
+ * {@inheritDoc Chain.getTokenPoolConfig}
1207
+ * @throws {@link CCIPNotImplementedError} always (not implemented for TON)
1208
+ */
1209
+ async getTokenPoolConfig(_tokenPool: string): Promise<never> {
1210
+ return Promise.reject(new CCIPNotImplementedError('getTokenPoolConfig'))
1055
1211
  }
1056
1212
 
1057
- /** {@inheritDoc Chain.getTokenPoolRemotes} */
1213
+ /**
1214
+ * {@inheritDoc Chain.getTokenPoolRemotes}
1215
+ * @throws {@link CCIPNotImplementedError} always (not implemented for TON)
1216
+ */
1058
1217
  async getTokenPoolRemotes(_tokenPool: string): Promise<never> {
1059
1218
  return Promise.reject(new CCIPNotImplementedError('getTokenPoolRemotes'))
1060
1219
  }
1061
1220
 
1062
- /** {@inheritDoc Chain.getFeeTokens} */
1221
+ /**
1222
+ * {@inheritDoc Chain.getFeeTokens}
1223
+ * @throws {@link CCIPNotImplementedError} always (not implemented for TON)
1224
+ */
1063
1225
  async getFeeTokens(_router: string): Promise<never> {
1064
1226
  return Promise.reject(new CCIPNotImplementedError('getFeeTokens'))
1065
1227
  }