@chainlink/ccip-sdk 0.93.0 → 0.95.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 (164) hide show
  1. package/dist/api/index.d.ts +80 -4
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/index.js +262 -6
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/types.d.ts +138 -13
  6. package/dist/api/types.d.ts.map +1 -1
  7. package/dist/aptos/index.d.ts +5 -9
  8. package/dist/aptos/index.d.ts.map +1 -1
  9. package/dist/aptos/index.js +26 -25
  10. package/dist/aptos/index.js.map +1 -1
  11. package/dist/aptos/logs.js +3 -3
  12. package/dist/aptos/logs.js.map +1 -1
  13. package/dist/aptos/send.js +1 -1
  14. package/dist/aptos/send.js.map +1 -1
  15. package/dist/chain.d.ts +96 -10
  16. package/dist/chain.d.ts.map +1 -1
  17. package/dist/chain.js +77 -2
  18. package/dist/chain.js.map +1 -1
  19. package/dist/errors/codes.d.ts +7 -3
  20. package/dist/errors/codes.d.ts.map +1 -1
  21. package/dist/errors/codes.js +8 -3
  22. package/dist/errors/codes.js.map +1 -1
  23. package/dist/errors/index.d.ts +7 -7
  24. package/dist/errors/index.d.ts.map +1 -1
  25. package/dist/errors/index.js +7 -7
  26. package/dist/errors/index.js.map +1 -1
  27. package/dist/errors/recovery.d.ts.map +1 -1
  28. package/dist/errors/recovery.js +8 -4
  29. package/dist/errors/recovery.js.map +1 -1
  30. package/dist/errors/specialized.d.ts +53 -18
  31. package/dist/errors/specialized.d.ts.map +1 -1
  32. package/dist/errors/specialized.js +112 -37
  33. package/dist/errors/specialized.js.map +1 -1
  34. package/dist/evm/gas.d.ts +14 -0
  35. package/dist/evm/gas.d.ts.map +1 -0
  36. package/dist/evm/gas.js +97 -0
  37. package/dist/evm/gas.js.map +1 -0
  38. package/dist/evm/index.d.ts +6 -8
  39. package/dist/evm/index.d.ts.map +1 -1
  40. package/dist/evm/index.js +36 -23
  41. package/dist/evm/index.js.map +1 -1
  42. package/dist/evm/offchain.d.ts.map +1 -1
  43. package/dist/evm/offchain.js +8 -8
  44. package/dist/evm/offchain.js.map +1 -1
  45. package/dist/execution.d.ts.map +1 -1
  46. package/dist/execution.js +8 -1
  47. package/dist/execution.js.map +1 -1
  48. package/dist/gas.d.ts +43 -19
  49. package/dist/gas.d.ts.map +1 -1
  50. package/dist/gas.js +48 -68
  51. package/dist/gas.js.map +1 -1
  52. package/dist/index.d.ts +15 -13
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +6 -5
  55. package/dist/index.js.map +1 -1
  56. package/dist/offchain.d.ts +5 -4
  57. package/dist/offchain.d.ts.map +1 -1
  58. package/dist/offchain.js +7 -6
  59. package/dist/offchain.js.map +1 -1
  60. package/dist/requests.d.ts +21 -13
  61. package/dist/requests.d.ts.map +1 -1
  62. package/dist/requests.js +79 -47
  63. package/dist/requests.js.map +1 -1
  64. package/dist/selectors.d.ts +2 -1
  65. package/dist/selectors.d.ts.map +1 -1
  66. package/dist/selectors.js +629 -274
  67. package/dist/selectors.js.map +1 -1
  68. package/dist/solana/exec.d.ts.map +1 -1
  69. package/dist/solana/exec.js +2 -1
  70. package/dist/solana/exec.js.map +1 -1
  71. package/dist/solana/index.d.ts +10 -10
  72. package/dist/solana/index.d.ts.map +1 -1
  73. package/dist/solana/index.js +82 -18
  74. package/dist/solana/index.js.map +1 -1
  75. package/dist/solana/offchain.js +2 -2
  76. package/dist/solana/offchain.js.map +1 -1
  77. package/dist/solana/send.d.ts.map +1 -1
  78. package/dist/solana/send.js +6 -9
  79. package/dist/solana/send.js.map +1 -1
  80. package/dist/solana/utils.d.ts +29 -1
  81. package/dist/solana/utils.d.ts.map +1 -1
  82. package/dist/solana/utils.js +39 -1
  83. package/dist/solana/utils.js.map +1 -1
  84. package/dist/sui/discovery.d.ts +7 -4
  85. package/dist/sui/discovery.d.ts.map +1 -1
  86. package/dist/sui/discovery.js +66 -19
  87. package/dist/sui/discovery.js.map +1 -1
  88. package/dist/sui/events.d.ts +23 -12
  89. package/dist/sui/events.d.ts.map +1 -1
  90. package/dist/sui/events.js +267 -128
  91. package/dist/sui/events.js.map +1 -1
  92. package/dist/sui/index.d.ts +32 -39
  93. package/dist/sui/index.d.ts.map +1 -1
  94. package/dist/sui/index.js +289 -163
  95. package/dist/sui/index.js.map +1 -1
  96. package/dist/sui/manuallyExec/encoder.d.ts.map +1 -1
  97. package/dist/sui/manuallyExec/encoder.js +1 -0
  98. package/dist/sui/manuallyExec/encoder.js.map +1 -1
  99. package/dist/sui/manuallyExec/index.d.ts.map +1 -1
  100. package/dist/sui/manuallyExec/index.js +1 -0
  101. package/dist/sui/manuallyExec/index.js.map +1 -1
  102. package/dist/sui/objects.d.ts +14 -4
  103. package/dist/sui/objects.d.ts.map +1 -1
  104. package/dist/sui/objects.js +63 -69
  105. package/dist/sui/objects.js.map +1 -1
  106. package/dist/sui/types.d.ts +33 -0
  107. package/dist/sui/types.d.ts.map +1 -1
  108. package/dist/sui/types.js.map +1 -1
  109. package/dist/ton/hasher.d.ts.map +1 -1
  110. package/dist/ton/hasher.js +1 -0
  111. package/dist/ton/hasher.js.map +1 -1
  112. package/dist/ton/index.d.ts +4 -4
  113. package/dist/ton/index.d.ts.map +1 -1
  114. package/dist/ton/index.js +8 -8
  115. package/dist/ton/index.js.map +1 -1
  116. package/dist/ton/utils.d.ts +3 -3
  117. package/dist/ton/utils.d.ts.map +1 -1
  118. package/dist/ton/utils.js +6 -5
  119. package/dist/ton/utils.js.map +1 -1
  120. package/dist/types.d.ts +34 -10
  121. package/dist/types.d.ts.map +1 -1
  122. package/dist/types.js +19 -5
  123. package/dist/types.js.map +1 -1
  124. package/dist/utils.d.ts +53 -1
  125. package/dist/utils.d.ts.map +1 -1
  126. package/dist/utils.js +109 -12
  127. package/dist/utils.js.map +1 -1
  128. package/package.json +17 -11
  129. package/src/api/index.ts +343 -9
  130. package/src/api/types.ts +165 -13
  131. package/src/aptos/index.ts +32 -32
  132. package/src/aptos/logs.ts +3 -3
  133. package/src/aptos/send.ts +1 -1
  134. package/src/chain.ts +165 -12
  135. package/src/errors/codes.ts +8 -3
  136. package/src/errors/index.ts +7 -4
  137. package/src/errors/recovery.ts +16 -5
  138. package/src/errors/specialized.ts +147 -45
  139. package/src/evm/gas.ts +149 -0
  140. package/src/evm/index.ts +66 -33
  141. package/src/evm/offchain.ts +15 -9
  142. package/src/execution.ts +8 -1
  143. package/src/gas.ts +95 -116
  144. package/src/index.ts +16 -6
  145. package/src/offchain.ts +12 -6
  146. package/src/requests.ts +113 -59
  147. package/src/selectors.ts +636 -276
  148. package/src/solana/exec.ts +3 -1
  149. package/src/solana/index.ts +119 -23
  150. package/src/solana/offchain.ts +2 -2
  151. package/src/solana/send.ts +5 -23
  152. package/src/solana/utils.ts +66 -0
  153. package/src/sui/discovery.ts +92 -31
  154. package/src/sui/events.ts +346 -239
  155. package/src/sui/index.ts +381 -224
  156. package/src/sui/manuallyExec/encoder.ts +2 -0
  157. package/src/sui/manuallyExec/index.ts +2 -0
  158. package/src/sui/objects.ts +77 -99
  159. package/src/sui/types.ts +35 -0
  160. package/src/ton/hasher.ts +2 -0
  161. package/src/ton/index.ts +12 -11
  162. package/src/ton/utils.ts +7 -6
  163. package/src/types.ts +36 -10
  164. package/src/utils.ts +153 -16
@@ -1,3 +1,5 @@
1
+ import { Buffer } from 'buffer'
2
+
1
3
  import { bcs } from '@mysten/sui/bcs'
2
4
  import type { BytesLike } from 'ethers'
3
5
 
@@ -1,3 +1,5 @@
1
+ import { Buffer } from 'buffer'
2
+
1
3
  import { Transaction } from '@mysten/sui/transactions'
2
4
 
3
5
  import { serializeExecutionReport } from './encoder.ts'
@@ -1,11 +1,21 @@
1
+ import { Buffer } from 'buffer'
2
+
1
3
  import { bcs } from '@mysten/sui/bcs'
2
4
  import type { SuiClient } from '@mysten/sui/client'
3
5
  import { Transaction } from '@mysten/sui/transactions'
4
6
  import { normalizeSuiAddress } from '@mysten/sui/utils'
5
- import { blake2b } from '@noble/hashes/blake2'
7
+ import { blake2b } from '@noble/hashes/blake2.js'
8
+ import { hexlify, toUtf8Bytes } from 'ethers'
9
+ import { memoize } from 'micro-memoize'
6
10
 
7
11
  import { CCIPDataFormatUnsupportedError } from '../errors/index.ts'
8
12
  import type { CCIPMessage, CCIPVersion } from '../types.ts'
13
+ import { toLeArray } from '../utils.ts'
14
+
15
+ const bcsBytes = (bytes: Uint8Array) => bcs.vector(bcs.u8()).serialize(bytes).toBytes()
16
+
17
+ const HASHING_INTENT_SCOPE_CHILD_OBJECT_ID = 0xf0
18
+ const SUI_FRAMEWORK_ADDRESS = '0x2'
9
19
 
10
20
  /**
11
21
  * Derive a dynamic field object ID using the Sui algorithm
@@ -17,27 +27,24 @@ export function deriveObjectID(parentAddress: string, keyBytes: Uint8Array): str
17
27
  const parentBytes = bcs.Address.serialize(normalizedParent).toBytes()
18
28
 
19
29
  // BCS serialize the key (vector<u8>)
20
- const bcsKeyBytes = bcs.vector(bcs.u8()).serialize(Array.from(keyBytes)).toBytes()
30
+ const bcsKeyBytes = bcsBytes(keyBytes)
31
+ const keyLenBytes = toLeArray(bcsKeyBytes.length, 8) // uint64
21
32
 
22
33
  // Construct TypeTag for DerivedObjectKey<vector<u8>>
23
- const suiFrameworkAddress = bcs.Address.serialize('0x2').toBytes()
34
+ const suiFrameworkAddress = bcs.Address.serialize(SUI_FRAMEWORK_ADDRESS).toBytes()
24
35
  const typeTagBytes = new Uint8Array([
25
36
  0x07, // TypeTag::Struct
26
37
  ...suiFrameworkAddress,
27
- 0x0e, // module length
28
- ...new TextEncoder().encode('derived_object'),
29
- 0x10, // struct name length
30
- ...new TextEncoder().encode('DerivedObjectKey'),
38
+ ...bcsBytes(toUtf8Bytes('derived_object')), //module
39
+ ...bcsBytes(toUtf8Bytes('DerivedObjectKey')), // struct name
31
40
  0x01, // type params count
32
- ...[0x06, 0x01], // vector<u8> TypeTag
41
+ 0x06, // TypeTag::Vector
42
+ 0x01, // TypeTag::U8
33
43
  ])
34
44
 
35
45
  // Build the hash input
36
- const keyLenBytes = new Uint8Array(8)
37
- new DataView(keyLenBytes.buffer).setBigUint64(0, BigInt(bcsKeyBytes.length), true)
38
-
39
46
  const hashInput = new Uint8Array([
40
- 0xf0, // HashingIntentScope::ChildObjectId
47
+ HASHING_INTENT_SCOPE_CHILD_OBJECT_ID,
41
48
  ...parentBytes,
42
49
  ...keyLenBytes,
43
50
  ...bcsKeyBytes,
@@ -47,101 +54,72 @@ export function deriveObjectID(parentAddress: string, keyBytes: Uint8Array): str
47
54
  // Hash with Blake2b-256
48
55
  const hash = blake2b(hashInput, { dkLen: 32 })
49
56
 
50
- // Convert to address string
51
- return normalizeSuiAddress('0x' + Buffer.from(hash).toString('hex'))
57
+ return hexlify(hash)
52
58
  }
53
59
 
54
60
  /**
55
- * Get the CCIPObjectRef ID for a CCIP package
61
+ * Finds the StatePointer object owned by a package.
62
+ * The StatePointer contains a reference to the parent object used for derivation.
56
63
  */
57
- export async function getCcipObjectRef(client: SuiClient, ccipPackageId: string): Promise<string> {
58
- // Get the pointer to find the CCIPObject ID
59
- const pointerResponse = await client.getOwnedObjects({
60
- owner: ccipPackageId,
61
- filter: {
62
- StructType: `${ccipPackageId}::state_object::CCIPObjectRefPointer`,
63
- },
64
- })
65
-
66
- if (!pointerResponse.data.length) {
67
- throw new CCIPDataFormatUnsupportedError(
68
- 'No CCIPObjectRefPointer found for the given packageId',
69
- )
70
- }
71
-
72
- // Get the pointer object to extract ccip_object_id
73
- const pointerId = pointerResponse.data[0]!.data?.objectId
74
- if (!pointerId) {
75
- throw new CCIPDataFormatUnsupportedError('Pointer does not have objectId')
76
- }
77
-
78
- const pointerObject = await client.getObject({
79
- id: pointerId,
80
- options: { showContent: true },
81
- })
82
-
83
- if (pointerObject.data?.content?.dataType !== 'moveObject') {
84
- throw new CCIPDataFormatUnsupportedError('Pointer object is not a Move object')
85
- }
86
-
87
- const ccipObjectId = (pointerObject.data.content.fields as Record<string, unknown>)[
88
- 'ccip_object_id'
89
- ] as string
90
-
91
- if (!ccipObjectId) {
92
- throw new CCIPDataFormatUnsupportedError('Could not find ccip_object_id in pointer')
93
- }
64
+ export const getObjectRef = memoize(
65
+ async function getPackageIds_(address: string, client: SuiClient): Promise<string> {
66
+ let stateObjectName
67
+ if (address.endsWith('::onramp')) stateObjectName = 'OnRampState'
68
+ else if (address.endsWith('::offramp')) stateObjectName = 'OffRampState'
69
+ else stateObjectName = 'CCIPObjectRef'
70
+
71
+ const fullStatePointerType = `${address}::${stateObjectName}Pointer`
72
+
73
+ const ownedObjects = await client.getOwnedObjects({
74
+ owner: address.split('::')[0]!,
75
+ filter: { StructType: fullStatePointerType },
76
+ options: { showContent: true },
77
+ })
94
78
 
95
- // Derive the CCIPObjectRef ID from the parent CCIPObject ID
96
- return deriveObjectID(ccipObjectId, new TextEncoder().encode('CCIPObjectRef'))
97
- }
79
+ const pointer = ownedObjects.data[0]?.data
80
+ if (!pointer?.objectId || pointer.content!.dataType !== 'moveObject')
81
+ throw new CCIPDataFormatUnsupportedError(
82
+ 'No CCIP ObjectRef Pointer found for the given packageId',
83
+ { context: { fullStatePointerType, pointer } },
84
+ )
85
+ // const statePointerObjectId = pointer.objectId
86
+ const parentObjectId = Object.entries(pointer.content!.fields).find(([key]) =>
87
+ key.endsWith('_object_id'),
88
+ )?.[1]
89
+ if (typeof parentObjectId !== 'string')
90
+ throw new CCIPDataFormatUnsupportedError('No parent object id found inthe given pointer', {
91
+ context: { fullStatePointerType, pointer },
92
+ })
93
+ return deriveObjectID(parentObjectId, toUtf8Bytes(stateObjectName))
94
+ },
95
+ { maxArgs: 1, expires: 300e3, async: true },
96
+ )
98
97
 
99
98
  /**
100
- * Get the OffRampState object ID for an offramp package
99
+ * Finds the StatePointer object owned by a package.
100
+ * The StatePointer contains a reference to the parent object used for derivation.
101
101
  */
102
- export async function getOffRampStateObject(
103
- client: SuiClient,
104
- offrampPackageId: string,
105
- ): Promise<string> {
106
- const offrampPointerResponse = await client.getOwnedObjects({
107
- owner: offrampPackageId,
108
- filter: {
109
- StructType: `${offrampPackageId}::offramp::OffRampStatePointer`,
110
- },
111
- })
112
-
113
- if (!offrampPointerResponse.data.length) {
114
- throw new CCIPDataFormatUnsupportedError(
115
- 'No OffRampStatePointer found for the given offramp package',
116
- )
117
- }
118
-
119
- const offrampPointerId = offrampPointerResponse.data[0]!.data?.objectId
120
-
121
- if (!offrampPointerId) {
122
- throw new CCIPDataFormatUnsupportedError('OffRampStatePointer does not have a valid objectId')
123
- }
124
-
125
- const offrampPointerObject = await client.getObject({
126
- id: offrampPointerId,
127
- options: { showContent: true },
128
- })
129
-
130
- if (offrampPointerObject.data?.content?.dataType !== 'moveObject') {
131
- throw new CCIPDataFormatUnsupportedError('OffRamp pointer object is not a Move object')
132
- }
133
-
134
- const offrampObjectId = (offrampPointerObject.data.content.fields as Record<string, unknown>)[
135
- 'off_ramp_object_id'
136
- ] as string
137
-
138
- if (!offrampObjectId) {
139
- throw new CCIPDataFormatUnsupportedError('Could not find off_ramp_object_id in pointer')
140
- }
141
-
142
- // Derive the OffRampState ID from the parent OffRamp Object ID
143
- return deriveObjectID(offrampObjectId, new TextEncoder().encode('OffRampState'))
144
- }
102
+ export const getLatestPackageId = memoize(
103
+ async function getLatestPackageId_(address: string, client: SuiClient): Promise<string> {
104
+ const suffix = address.split('::')[1]
105
+ try {
106
+ const stateObjectId = await getObjectRef(address, client)
107
+ const stateObject = await client.getObject({
108
+ id: stateObjectId,
109
+ options: { showContent: true },
110
+ })
111
+ const stateContent = stateObject.data?.content
112
+ if (stateContent?.dataType !== 'moveObject') return address
113
+ const packageIdsField = (stateContent.fields as Record<string, unknown>)['package_ids']
114
+ if (!Array.isArray(packageIdsField) || packageIdsField.length === 0) return address
115
+ const latest = packageIdsField[packageIdsField.length - 1] as string
116
+ return suffix ? `${latest}::${suffix}` : latest
117
+ } catch {
118
+ return address
119
+ }
120
+ },
121
+ { maxArgs: 1, expires: 60e3, async: true },
122
+ )
145
123
 
146
124
  /**
147
125
  * Get the receiver module configuration from the receiver registry.
package/src/sui/types.ts CHANGED
@@ -15,6 +15,16 @@ export const SuiExtraArgsV1Codec = bcs.struct('SuiExtraArgsV1', {
15
15
  receiverObjectIds: bcs.vector(bcs.vector(bcs.u8())),
16
16
  })
17
17
 
18
+ /** Token amount data structure for Sui CCIP messages. */
19
+ export type SuiTokenAmount = {
20
+ source_pool_address?: string
21
+ dest_token_address?: number[]
22
+ extra_data?: number[]
23
+ amount?: string | number
24
+ dest_exec_data?: number[]
25
+ dest_gas_amount?: string | number
26
+ }
27
+
18
28
  /**
19
29
  * Encodes Sui v1 extra arguments using BCS encoding.
20
30
  * @param args - Sui extra arguments to encode.
@@ -26,3 +36,28 @@ export function encodeSuiExtraArgsV1(args: SuiExtraArgsV1): string {
26
36
  const bcsData = SuiExtraArgsV1Codec.serialize({ ...args, tokenReceiver, receiverObjectIds })
27
37
  return concat([SuiExtraArgsV1Tag, bcsData.toBytes()])
28
38
  }
39
+
40
+ /**
41
+ * Sui-specific CCIP message log structure from events.
42
+ */
43
+ export type SuiCCIPMessageLog = {
44
+ dest_chain_selector: string
45
+ message: {
46
+ data: number[]
47
+ extra_args: number[]
48
+ fee_token: string
49
+ fee_token_amount: string
50
+ fee_value_juels: string
51
+ header: {
52
+ dest_chain_selector: string
53
+ message_id: number[]
54
+ nonce: string
55
+ sequence_number: string
56
+ source_chain_selector: string
57
+ }
58
+ receiver: number[]
59
+ sender: string
60
+ token_amounts: SuiTokenAmount[]
61
+ }
62
+ sequence_number: string
63
+ }
package/src/ton/hasher.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { Buffer } from 'buffer'
2
+
1
3
  import { type Cell, Address, beginCell } from '@ton/core'
2
4
  import { sha256, toBigInt } from 'ethers'
3
5
 
package/src/ton/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { Buffer } from 'buffer'
2
+
1
3
  import { type Transaction, Address, Cell, beginCell, toNano } from '@ton/core'
2
4
  import { TonClient } from '@ton/ton'
3
5
  import { type AxiosAdapter, getAdapter } from 'axios'
@@ -6,7 +8,7 @@ import { type Memoized, memoize } from 'micro-memoize'
6
8
  import type { PickDeep } from 'type-fest'
7
9
 
8
10
  import { streamTransactionsForAddress } from './logs.ts'
9
- import { type ChainContext, type LogFilter, Chain } from '../chain.ts'
11
+ import { type ChainContext, type GetBalanceOpts, type LogFilter, Chain } from '../chain.ts'
10
12
  import {
11
13
  CCIPArgumentInvalidError,
12
14
  CCIPExtraArgsInvalidError,
@@ -19,7 +21,6 @@ import {
19
21
  CCIPWalletInvalidError,
20
22
  } from '../errors/specialized.ts'
21
23
  import { type EVMExtraArgsV2, type ExtraArgs, EVMExtraArgsV2Tag } from '../extra-args.ts'
22
- import { getMessagesInTx } from '../requests.ts'
23
24
  import { supportedChains } from '../supported-chains.ts'
24
25
  import {
25
26
  type CCIPExecution,
@@ -162,13 +163,13 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
162
163
  ctx?: ChainContext & { fetchFn?: typeof fetch },
163
164
  ): Promise<TONChain> {
164
165
  // Verify connection by getting the latest block
165
- const isTestnet =
166
+ const isMainnet =
166
167
  (
167
168
  await client.getContractState(
168
169
  Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'), // mainnet USDT
169
170
  )
170
- ).state !== 'active'
171
- return new TONChain(client, networkInfo(isTestnet ? 'ton-testnet' : 'ton-mainnet'), ctx)
171
+ ).state === 'active'
172
+ return new TONChain(client, networkInfo(isMainnet ? 'ton-mainnet' : 'ton-testnet'), ctx)
172
173
  }
173
174
 
174
175
  /**
@@ -262,7 +263,7 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
262
263
  )
263
264
  const txInfo = await lookupTxByRawHash(
264
265
  cleanHash,
265
- this.network.isTestnet,
266
+ this.network.networkType,
266
267
  this.rateLimitedFetch,
267
268
  this,
268
269
  )
@@ -361,11 +362,6 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
361
362
  }
362
363
  }
363
364
 
364
- /** {@inheritDoc Chain.getMessagesInTx} */
365
- override async getMessagesInTx(tx: string | ChainTransaction): Promise<CCIPRequest[]> {
366
- return getMessagesInTx(this, typeof tx === 'string' ? await this.getTransaction(tx) : tx)
367
- }
368
-
369
365
  /** {@inheritDoc Chain.getMessagesInBatch} */
370
366
  override async getMessagesInBatch<
371
367
  R extends PickDeep<
@@ -523,6 +519,11 @@ export class TONChain extends Chain<typeof ChainFamily.TON> {
523
519
  }
524
520
  }
525
521
 
522
+ /** {@inheritDoc Chain.getBalance} */
523
+ async getBalance(_opts: GetBalanceOpts): Promise<bigint> {
524
+ return Promise.reject(new CCIPNotImplementedError('TONChain.getBalance'))
525
+ }
526
+
526
527
  /** {@inheritDoc Chain.getTokenAdminRegistryFor} */
527
528
  getTokenAdminRegistryFor(_address: string): Promise<string> {
528
529
  return Promise.reject(new CCIPNotImplementedError('getTokenAdminRegistryFor'))
package/src/ton/utils.ts CHANGED
@@ -2,7 +2,7 @@ import { Cell, Dictionary, beginCell } from '@ton/core'
2
2
  import { hexlify, toBeHex } from 'ethers'
3
3
 
4
4
  import { CCIPTransactionNotFoundError } from '../errors/specialized.ts'
5
- import type { WithLogger } from '../types.ts'
5
+ import { type WithLogger, NetworkType } from '../types.ts'
6
6
  import { bytesToBuffer } from '../utils.ts'
7
7
 
8
8
  /**
@@ -340,14 +340,14 @@ export async function parseJettonContent(
340
340
  * TonCenter V3 provides an index that allows hash-only lookups.
341
341
  *
342
342
  * @param hash - Raw 64-char hex transaction hash
343
- * @param isTestnet - Whether to use testnet API
343
+ * @param networkType - Network type (mainnet or testnet)
344
344
  * @param fetch - Rate-limited fetch function
345
345
  * @param logger - Logger instance
346
346
  * @returns Transaction identifier components needed for V4 API lookup
347
347
  */
348
348
  export async function lookupTxByRawHash(
349
349
  hash: string,
350
- isTestnet: boolean,
350
+ networkType: NetworkType,
351
351
  fetch = globalThis.fetch,
352
352
  { logger = console }: WithLogger = {},
353
353
  ): Promise<{
@@ -355,9 +355,10 @@ export async function lookupTxByRawHash(
355
355
  lt: string
356
356
  hash: string
357
357
  }> {
358
- const baseUrl = isTestnet
359
- ? 'https://testnet.toncenter.com/api/v3/transactions'
360
- : 'https://toncenter.com/api/v3/transactions'
358
+ const baseUrl =
359
+ networkType === NetworkType.Mainnet
360
+ ? 'https://toncenter.com/api/v3/transactions'
361
+ : 'https://testnet.toncenter.com/api/v3/transactions'
361
362
 
362
363
  // TonCenter V3 accepts hex directly
363
364
  const cleanHash = bytesToBuffer(hash).toString('hex')
package/src/types.ts CHANGED
@@ -60,15 +60,26 @@ export type MergeArrayElements<T, U> = {
60
60
  * Enumeration of supported blockchain families.
61
61
  */
62
62
  export const ChainFamily = {
63
- EVM: 'evm',
64
- Solana: 'solana',
65
- Aptos: 'aptos',
66
- Sui: 'sui',
67
- TON: 'ton',
63
+ EVM: 'EVM',
64
+ Solana: 'SVM',
65
+ Aptos: 'APTOS',
66
+ Sui: 'SUI',
67
+ TON: 'TON',
68
+ Unknown: 'UNKNOWN',
68
69
  } as const
69
70
  /** Type representing one of the supported chain families. */
70
71
  export type ChainFamily = (typeof ChainFamily)[keyof typeof ChainFamily]
71
72
 
73
+ /**
74
+ * Enumeration of network types (mainnet vs testnet).
75
+ */
76
+ export const NetworkType = {
77
+ Mainnet: 'MAINNET',
78
+ Testnet: 'TESTNET',
79
+ } as const
80
+ /** Type representing the network environment type. */
81
+ export type NetworkType = (typeof NetworkType)[keyof typeof NetworkType]
82
+
72
83
  /**
73
84
  * Enumeration of supported CCIP protocol versions.
74
85
  */
@@ -88,7 +99,7 @@ type ChainFamilyWithId<F extends ChainFamily> = F extends
88
99
  : F extends typeof ChainFamily.Solana
89
100
  ? { readonly family: F; readonly chainId: string }
90
101
  : F extends typeof ChainFamily.Aptos | typeof ChainFamily.Sui
91
- ? { readonly family: F; readonly chainId: `${F}:${number}` }
102
+ ? { readonly family: F; readonly chainId: `${Lowercase<F>}:${number}` }
92
103
  : never
93
104
 
94
105
  /**
@@ -99,8 +110,8 @@ export type NetworkInfo<F extends ChainFamily = ChainFamily> = {
99
110
  readonly chainSelector: bigint
100
111
  /** Human-readable network name. */
101
112
  readonly name: string
102
- /** Whether this is a testnet. */
103
- readonly isTestnet: boolean
113
+ /** Network environment type. */
114
+ readonly networkType: NetworkType
104
115
  } & ChainFamilyWithId<F>
105
116
 
106
117
  /**
@@ -216,6 +227,12 @@ export const MessageStatus = {
216
227
  Success: 'SUCCESS',
217
228
  /** Message execution failed on destination. */
218
229
  Failed: 'FAILED',
230
+ /** Message is being verified by the CCIP network */
231
+ Verifying: 'VERIFYING',
232
+ /** Message has been verified by the CCIP network */
233
+ Verified: 'VERIFIED',
234
+ /** Unknown status returned by API */
235
+ Unknown: 'UNKNOWN',
219
236
  } as const
220
237
  /** Type representing a CCIP message lifecycle status. */
221
238
  export type MessageStatus = (typeof MessageStatus)[keyof typeof MessageStatus]
@@ -294,12 +311,21 @@ export type ExecutionReport<M extends CCIPMessage = CCIPMessage> = {
294
311
  export type AnyMessage = {
295
312
  /** Receiver address on the destination chain. */
296
313
  receiver: BytesLike
297
- /** Arbitrary data payload. */
298
- data: BytesLike
299
314
  /** Extra arguments for gas limits and other settings. */
300
315
  extraArgs: ExtraArgs
316
+ /** Arbitrary data payload. */
317
+ data?: BytesLike
301
318
  /** Optional token transfers. */
302
319
  tokenAmounts?: readonly { token: string; amount: bigint }[]
303
320
  /** Optional fee token address (native if omitted). */
304
321
  feeToken?: string
305
322
  }
323
+
324
+ /**
325
+ * Partial [[AnyMessage]], which populates default fields like `extraArgs` if needed
326
+ */
327
+ export type MessageInput = Partial<AnyMessage> & {
328
+ receiver: AnyMessage['receiver']
329
+ extraArgs?: Partial<ExtraArgs>
330
+ fee?: bigint
331
+ }