@chainlink/ccip-sdk 0.91.0 → 0.92.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -80
- package/dist/aptos/hasher.d.ts.map +1 -1
- package/dist/aptos/hasher.js +7 -6
- package/dist/aptos/hasher.js.map +1 -1
- package/dist/aptos/index.d.ts +7 -2
- package/dist/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +29 -20
- package/dist/aptos/index.js.map +1 -1
- package/dist/aptos/logs.d.ts +5 -3
- package/dist/aptos/logs.d.ts.map +1 -1
- package/dist/aptos/logs.js +64 -27
- package/dist/aptos/logs.js.map +1 -1
- package/dist/aptos/token.d.ts.map +1 -1
- package/dist/aptos/token.js +2 -1
- package/dist/aptos/token.js.map +1 -1
- package/dist/aptos/types.js +6 -6
- package/dist/aptos/types.js.map +1 -1
- package/dist/chain.d.ts +36 -11
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +34 -2
- package/dist/chain.js.map +1 -1
- package/dist/commits.d.ts +2 -3
- package/dist/commits.d.ts.map +1 -1
- package/dist/commits.js +19 -8
- package/dist/commits.js.map +1 -1
- package/dist/errors/CCIPError.d.ts +48 -0
- package/dist/errors/CCIPError.d.ts.map +1 -0
- package/dist/errors/CCIPError.js +65 -0
- package/dist/errors/CCIPError.js.map +1 -0
- package/dist/errors/codes.d.ts +120 -0
- package/dist/errors/codes.d.ts.map +1 -0
- package/dist/errors/codes.js +156 -0
- package/dist/errors/codes.js.map +1 -0
- package/dist/errors/index.d.ts +26 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +51 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/recovery.d.ts +6 -0
- package/dist/errors/recovery.d.ts.map +1 -0
- package/dist/errors/recovery.js +118 -0
- package/dist/errors/recovery.js.map +1 -0
- package/dist/errors/specialized.d.ts +637 -0
- package/dist/errors/specialized.d.ts.map +1 -0
- package/dist/errors/specialized.js +1298 -0
- package/dist/errors/specialized.js.map +1 -0
- package/dist/errors/utils.d.ts +11 -0
- package/dist/errors/utils.d.ts.map +1 -0
- package/dist/errors/utils.js +61 -0
- package/dist/errors/utils.js.map +1 -0
- package/dist/evm/abi/CommitStore_1_5.js +1 -1
- package/dist/evm/abi/LockReleaseTokenPool_1_5.js +1 -1
- package/dist/evm/abi/OffRamp_1_5.js +1 -1
- package/dist/evm/abi/OnRamp_1_5.js +1 -1
- package/dist/evm/abi/PriceRegistry_1_2.d.ts +443 -0
- package/dist/evm/abi/PriceRegistry_1_2.d.ts.map +1 -0
- package/dist/evm/abi/PriceRegistry_1_2.js +439 -0
- package/dist/evm/abi/PriceRegistry_1_2.js.map +1 -0
- package/dist/evm/const.d.ts +1 -0
- package/dist/evm/const.d.ts.map +1 -1
- package/dist/evm/const.js +2 -0
- package/dist/evm/const.js.map +1 -1
- package/dist/evm/hasher.d.ts.map +1 -1
- package/dist/evm/hasher.js +7 -6
- package/dist/evm/hasher.js.map +1 -1
- package/dist/evm/index.d.ts +9 -13
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +85 -68
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/logs.d.ts.map +1 -1
- package/dist/evm/logs.js +47 -16
- package/dist/evm/logs.js.map +1 -1
- package/dist/evm/messages.d.ts +7 -6
- package/dist/evm/messages.d.ts.map +1 -1
- package/dist/evm/offchain.js +1 -1
- package/dist/evm/offchain.js.map +1 -1
- package/dist/evm/types.d.ts +10 -0
- package/dist/evm/types.d.ts.map +1 -0
- package/dist/evm/types.js +2 -0
- package/dist/evm/types.js.map +1 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +9 -5
- package/dist/execution.js.map +1 -1
- package/dist/extra-args.d.ts.map +1 -1
- package/dist/extra-args.js +4 -3
- package/dist/extra-args.js.map +1 -1
- package/dist/gas.d.ts.map +1 -1
- package/dist/gas.js +3 -2
- package/dist/gas.js.map +1 -1
- package/dist/hasher/hasher.d.ts.map +1 -1
- package/dist/hasher/hasher.js +2 -1
- package/dist/hasher/hasher.js.map +1 -1
- package/dist/hasher/merklemulti.d.ts.map +1 -1
- package/dist/hasher/merklemulti.js +9 -8
- package/dist/hasher/merklemulti.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/offchain.d.ts.map +1 -1
- package/dist/offchain.js +5 -8
- package/dist/offchain.js.map +1 -1
- package/dist/requests.d.ts +1 -1
- package/dist/requests.d.ts.map +1 -1
- package/dist/requests.js +37 -43
- package/dist/requests.js.map +1 -1
- package/dist/selectors.d.ts.map +1 -1
- package/dist/selectors.js +22 -0
- package/dist/selectors.js.map +1 -1
- package/dist/solana/cleanup.d.ts +2 -2
- package/dist/solana/cleanup.d.ts.map +1 -1
- package/dist/solana/cleanup.js +2 -3
- package/dist/solana/cleanup.js.map +1 -1
- package/dist/solana/exec.d.ts.map +1 -1
- package/dist/solana/exec.js +12 -12
- package/dist/solana/exec.js.map +1 -1
- package/dist/solana/hasher.d.ts.map +1 -1
- package/dist/solana/hasher.js +6 -5
- package/dist/solana/hasher.js.map +1 -1
- package/dist/solana/index.d.ts +30 -13
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +96 -143
- package/dist/solana/index.js.map +1 -1
- package/dist/solana/logs.d.ts +15 -0
- package/dist/solana/logs.d.ts.map +1 -0
- package/dist/solana/logs.js +106 -0
- package/dist/solana/logs.js.map +1 -0
- package/dist/solana/offchain.d.ts.map +1 -1
- package/dist/solana/offchain.js +6 -5
- package/dist/solana/offchain.js.map +1 -1
- package/dist/solana/patchBorsh.d.ts.map +1 -1
- package/dist/solana/patchBorsh.js +3 -2
- package/dist/solana/patchBorsh.js.map +1 -1
- package/dist/solana/send.d.ts.map +1 -1
- package/dist/solana/send.js +8 -7
- package/dist/solana/send.js.map +1 -1
- package/dist/solana/utils.d.ts +7 -8
- package/dist/solana/utils.d.ts.map +1 -1
- package/dist/solana/utils.js +23 -11
- package/dist/solana/utils.js.map +1 -1
- package/dist/sui/discovery.d.ts +18 -0
- package/dist/sui/discovery.d.ts.map +1 -0
- package/dist/sui/discovery.js +116 -0
- package/dist/sui/discovery.js.map +1 -0
- package/dist/sui/events.d.ts +36 -0
- package/dist/sui/events.d.ts.map +1 -0
- package/dist/sui/events.js +179 -0
- package/dist/sui/events.js.map +1 -0
- package/dist/sui/hasher.d.ts.map +1 -1
- package/dist/sui/hasher.js +6 -5
- package/dist/sui/hasher.js.map +1 -1
- package/dist/sui/index.d.ts +69 -41
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +402 -65
- package/dist/sui/index.js.map +1 -1
- package/dist/sui/manuallyExec/encoder.d.ts +8 -0
- package/dist/sui/manuallyExec/encoder.d.ts.map +1 -0
- package/dist/sui/manuallyExec/encoder.js +76 -0
- package/dist/sui/manuallyExec/encoder.js.map +1 -0
- package/dist/sui/manuallyExec/index.d.ts +37 -0
- package/dist/sui/manuallyExec/index.d.ts.map +1 -0
- package/dist/sui/manuallyExec/index.js +81 -0
- package/dist/sui/manuallyExec/index.js.map +1 -0
- package/dist/sui/objects.d.ts +46 -0
- package/dist/sui/objects.d.ts.map +1 -0
- package/dist/sui/objects.js +259 -0
- package/dist/sui/objects.js.map +1 -0
- package/dist/ton/bindings/offramp.d.ts +48 -0
- package/dist/ton/bindings/offramp.d.ts.map +1 -0
- package/dist/ton/bindings/offramp.js +63 -0
- package/dist/ton/bindings/offramp.js.map +1 -0
- package/dist/ton/bindings/onramp.d.ts +40 -0
- package/dist/ton/bindings/onramp.d.ts.map +1 -0
- package/dist/ton/bindings/onramp.js +51 -0
- package/dist/ton/bindings/onramp.js.map +1 -0
- package/dist/ton/bindings/router.d.ts +47 -0
- package/dist/ton/bindings/router.d.ts.map +1 -0
- package/dist/ton/bindings/router.js +51 -0
- package/dist/ton/bindings/router.js.map +1 -0
- package/dist/ton/exec.d.ts +18 -0
- package/dist/ton/exec.d.ts.map +1 -0
- package/dist/ton/exec.js +28 -0
- package/dist/ton/exec.js.map +1 -0
- package/dist/ton/hasher.d.ts +27 -0
- package/dist/ton/hasher.d.ts.map +1 -0
- package/dist/ton/hasher.js +134 -0
- package/dist/ton/hasher.js.map +1 -0
- package/dist/ton/index.d.ts +247 -0
- package/dist/ton/index.d.ts.map +1 -0
- package/dist/ton/index.js +781 -0
- package/dist/ton/index.js.map +1 -0
- package/dist/ton/logs.d.ts +26 -0
- package/dist/ton/logs.d.ts.map +1 -0
- package/dist/ton/logs.js +126 -0
- package/dist/ton/logs.js.map +1 -0
- package/dist/ton/types.d.ts +37 -0
- package/dist/ton/types.d.ts.map +1 -0
- package/dist/ton/types.js +92 -0
- package/dist/ton/types.js.map +1 -0
- package/dist/ton/utils.d.ts +67 -0
- package/dist/ton/utils.d.ts.map +1 -0
- package/dist/ton/utils.js +425 -0
- package/dist/ton/utils.js.map +1 -0
- package/dist/types.d.ts +4 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +10 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +52 -17
- package/dist/utils.js.map +1 -1
- package/package.json +12 -10
- package/src/aptos/hasher.ts +10 -6
- package/src/aptos/index.ts +50 -31
- package/src/aptos/logs.ts +85 -29
- package/src/aptos/token.ts +5 -1
- package/src/aptos/types.ts +6 -6
- package/src/chain.ts +83 -12
- package/src/commits.ts +23 -11
- package/src/errors/CCIPError.ts +86 -0
- package/src/errors/codes.ts +179 -0
- package/src/errors/index.ts +175 -0
- package/src/errors/recovery.ts +170 -0
- package/src/errors/specialized.ts +1655 -0
- package/src/errors/utils.ts +73 -0
- package/src/evm/abi/CommitStore_1_5.ts +1 -1
- package/src/evm/abi/LockReleaseTokenPool_1_5.ts +1 -1
- package/src/evm/abi/OffRamp_1_5.ts +1 -1
- package/src/evm/abi/OnRamp_1_5.ts +1 -1
- package/src/evm/abi/PriceRegistry_1_2.ts +438 -0
- package/src/evm/const.ts +2 -0
- package/src/evm/hasher.ts +7 -6
- package/src/evm/index.ts +104 -86
- package/src/evm/logs.ts +64 -16
- package/src/evm/messages.ts +14 -14
- package/src/evm/offchain.ts +1 -1
- package/src/evm/types.ts +11 -0
- package/src/execution.ts +13 -9
- package/src/extra-args.ts +4 -3
- package/src/gas.ts +10 -3
- package/src/hasher/hasher.ts +2 -1
- package/src/hasher/merklemulti.ts +18 -8
- package/src/index.ts +14 -2
- package/src/offchain.ts +10 -14
- package/src/requests.ts +51 -53
- package/src/selectors.ts +23 -0
- package/src/solana/cleanup.ts +2 -4
- package/src/solana/exec.ts +13 -13
- package/src/solana/hasher.ts +9 -5
- package/src/solana/index.ts +126 -200
- package/src/solana/logs.ts +155 -0
- package/src/solana/offchain.ts +10 -7
- package/src/solana/patchBorsh.ts +3 -2
- package/src/solana/send.ts +14 -7
- package/src/solana/utils.ts +31 -17
- package/src/sui/discovery.ts +163 -0
- package/src/sui/events.ts +328 -0
- package/src/sui/hasher.ts +6 -5
- package/src/sui/index.ts +528 -80
- package/src/sui/manuallyExec/encoder.ts +88 -0
- package/src/sui/manuallyExec/index.ts +137 -0
- package/src/sui/objects.ts +358 -0
- package/src/ton/bindings/offramp.ts +96 -0
- package/src/ton/bindings/onramp.ts +72 -0
- package/src/ton/bindings/router.ts +65 -0
- package/src/ton/exec.ts +44 -0
- package/src/ton/hasher.ts +184 -0
- package/src/ton/index.ts +989 -0
- package/src/ton/logs.ts +157 -0
- package/src/ton/types.ts +143 -0
- package/src/ton/utils.ts +514 -0
- package/src/types.ts +6 -2
- package/src/utils.ts +58 -23
- package/tsconfig.json +2 -1
package/src/ton/logs.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { Address } from '@ton/core'
|
|
2
|
+
import type { TonClient4 } from '@ton/ton'
|
|
3
|
+
|
|
4
|
+
import type { LogFilter } from '../chain.ts'
|
|
5
|
+
import { CCIPArgumentInvalidError } from '../errors/specialized.ts'
|
|
6
|
+
import type { Log_ } from '../types.ts'
|
|
7
|
+
|
|
8
|
+
/** Decoder functions passed to fetchLogs to identify and parse TON log events avoiding circular imports */
|
|
9
|
+
export interface LogDecoders {
|
|
10
|
+
/** Try to decode as CCIP message, returns messageId if successful */
|
|
11
|
+
tryDecodeAsMessage: (log: Pick<Log_, 'data'>) => { messageId: string } | undefined
|
|
12
|
+
/** Try to decode as commit report, returns truthy if successful */
|
|
13
|
+
tryDecodeAsCommit: (log: Pick<Log_, 'data'>) => unknown[] | undefined
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Fetches logs from a TON address by iterating through account transactions.
|
|
18
|
+
*
|
|
19
|
+
* Note: For TON, `startBlock` and `endBlock` in opts represent logical time (lt),
|
|
20
|
+
* not block sequence numbers. This is because TON transaction APIs are indexed by lt.
|
|
21
|
+
* The lt is monotonically increasing per account and suitable for ordering.
|
|
22
|
+
*
|
|
23
|
+
* @param provider - TonClient4 instance
|
|
24
|
+
* @param opts - Log filter options (startBlock/endBlock are lt values)
|
|
25
|
+
* @param ltTimestampCache - Cache mapping lt to Unix timestamp
|
|
26
|
+
* @param decoders - Message decoder functions
|
|
27
|
+
*/
|
|
28
|
+
export async function* fetchLogs(
|
|
29
|
+
provider: TonClient4,
|
|
30
|
+
opts: LogFilter,
|
|
31
|
+
ltTimestampCache: Map<number, number>,
|
|
32
|
+
decoders: LogDecoders,
|
|
33
|
+
): AsyncIterableIterator<Log_> {
|
|
34
|
+
if (!opts.address) {
|
|
35
|
+
throw new CCIPArgumentInvalidError('address', 'Address is required for TON log filtering')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const address = Address.parse(opts.address)
|
|
39
|
+
const searchForward = !!(opts.startBlock || opts.startTime)
|
|
40
|
+
|
|
41
|
+
// Get the latest block for account state lookup
|
|
42
|
+
const lastBlock = await provider.getLastBlock()
|
|
43
|
+
|
|
44
|
+
// Get account state to find the last transaction
|
|
45
|
+
const account = await provider.getAccountLite(lastBlock.last.seqno, address)
|
|
46
|
+
if (!account.account.last) {
|
|
47
|
+
return // No transactions
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Pagination cursor
|
|
51
|
+
let cursorLt: bigint = BigInt(account.account.last.lt)
|
|
52
|
+
let cursorHash: Buffer = Buffer.from(account.account.last.hash, 'base64')
|
|
53
|
+
|
|
54
|
+
const collectedLogs: Log_[] = []
|
|
55
|
+
let isFirstBatch = true
|
|
56
|
+
|
|
57
|
+
while (true) {
|
|
58
|
+
const txs = await provider.getAccountTransactions(address, cursorLt, cursorHash)
|
|
59
|
+
if (!txs || txs.length === 0) break
|
|
60
|
+
|
|
61
|
+
// Skip first tx when paginating (it's the same as last from previous batch)
|
|
62
|
+
const startIdx = isFirstBatch ? 0 : 1
|
|
63
|
+
isFirstBatch = false
|
|
64
|
+
|
|
65
|
+
for (let i = startIdx; i < txs.length; i++) {
|
|
66
|
+
const { tx } = txs[i]
|
|
67
|
+
const txLt = Number(tx.lt)
|
|
68
|
+
const timestamp = tx.now
|
|
69
|
+
|
|
70
|
+
// Cache lt → timestamp
|
|
71
|
+
ltTimestampCache.set(txLt, timestamp)
|
|
72
|
+
|
|
73
|
+
// Range filters
|
|
74
|
+
if (opts.startBlock && typeof opts.startBlock === 'number' && txLt < opts.startBlock) {
|
|
75
|
+
if (searchForward) yield* collectedLogs.reverse()
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
if (opts.startTime && timestamp < opts.startTime) {
|
|
79
|
+
if (searchForward) yield* collectedLogs.reverse()
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
if (opts.endBlock && typeof opts.endBlock === 'number' && txLt > opts.endBlock) {
|
|
83
|
+
continue
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Extract logs from external-out messages
|
|
87
|
+
const compositeHash = `${address.toRawString()}:${tx.lt}:${tx.hash().toString('hex')}`
|
|
88
|
+
let index = 0
|
|
89
|
+
|
|
90
|
+
for (const msg of tx.outMessages.values()) {
|
|
91
|
+
if (msg.info.type !== 'external-out') {
|
|
92
|
+
index++
|
|
93
|
+
continue
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const data = msg.body.toBoc().toString('base64')
|
|
97
|
+
const topicFilter = opts.topics?.[0]
|
|
98
|
+
|
|
99
|
+
// Try to identify log type and build topics array
|
|
100
|
+
const topics: string[] = []
|
|
101
|
+
|
|
102
|
+
if (topicFilter === 'CommitReportAccepted') {
|
|
103
|
+
// Looking for commits - skip if not a valid commit
|
|
104
|
+
if (!decoders.tryDecodeAsCommit({ data })) {
|
|
105
|
+
index++
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
108
|
+
topics.push('CommitReportAccepted')
|
|
109
|
+
} else {
|
|
110
|
+
// Try to decode as CCIP message
|
|
111
|
+
const message = decoders.tryDecodeAsMessage({ data })
|
|
112
|
+
if (topicFilter && !message) {
|
|
113
|
+
// Topic filter set but couldn't decode as message - skip
|
|
114
|
+
index++
|
|
115
|
+
continue
|
|
116
|
+
}
|
|
117
|
+
if (message) {
|
|
118
|
+
topics.push('CCIPMessageSent')
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const log: Log_ = {
|
|
123
|
+
address: address.toRawString(),
|
|
124
|
+
topics,
|
|
125
|
+
data,
|
|
126
|
+
blockNumber: txLt,
|
|
127
|
+
transactionHash: compositeHash,
|
|
128
|
+
index,
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (searchForward) {
|
|
132
|
+
collectedLogs.push(log)
|
|
133
|
+
} else {
|
|
134
|
+
yield log
|
|
135
|
+
}
|
|
136
|
+
index++
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Update pagination cursor
|
|
141
|
+
if (txs.length < 2) break
|
|
142
|
+
const lastTx = txs[txs.length - 1].tx
|
|
143
|
+
cursorLt = lastTx.lt
|
|
144
|
+
cursorHash = Buffer.from(lastTx.hash())
|
|
145
|
+
|
|
146
|
+
// Early exit if past start boundary
|
|
147
|
+
if (
|
|
148
|
+
opts.startBlock &&
|
|
149
|
+
typeof opts.startBlock === 'number' &&
|
|
150
|
+
Number(cursorLt) < opts.startBlock
|
|
151
|
+
)
|
|
152
|
+
break
|
|
153
|
+
if (opts.startTime && lastTx.now < opts.startTime) break
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (searchForward) yield* collectedLogs.reverse()
|
|
157
|
+
}
|
package/src/ton/types.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { type Builder, Address, Cell, beginCell } from '@ton/core'
|
|
2
|
+
import type { KeyPair } from '@ton/crypto'
|
|
3
|
+
import type { WalletContractV4 } from '@ton/ton'
|
|
4
|
+
import { toBigInt } from 'ethers'
|
|
5
|
+
|
|
6
|
+
import { CCIPDataFormatUnsupportedError } from '../errors/specialized.ts'
|
|
7
|
+
import type { EVMExtraArgsV2 } from '../extra-args.ts'
|
|
8
|
+
import type { CCIPMessage_V1_6, ChainFamily, ExecutionReport } from '../types.ts'
|
|
9
|
+
import { bytesToBuffer } from '../utils.ts'
|
|
10
|
+
|
|
11
|
+
/** TON-specific CCIP v1.6 message type with EVMExtraArgsV2 (GenericExtraArgsV2) */
|
|
12
|
+
export type CCIPMessage_V1_6_TON = CCIPMessage_V1_6 & EVMExtraArgsV2
|
|
13
|
+
|
|
14
|
+
/** Opcode for OffRamp_ManuallyExecute message on TON */
|
|
15
|
+
export const MANUALLY_EXECUTE_OPCODE = 0xa00785cf
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* TON wallet with keypair for signing transactions
|
|
19
|
+
*/
|
|
20
|
+
export interface TONWallet {
|
|
21
|
+
contract: WalletContractV4
|
|
22
|
+
keyPair: KeyPair
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Unsigned TON transaction data.
|
|
27
|
+
* Contains the payload needed to construct a transaction.
|
|
28
|
+
* Value is determined at execution time, not included here.
|
|
29
|
+
*/
|
|
30
|
+
export type UnsignedTONTx = {
|
|
31
|
+
family: typeof ChainFamily.TON
|
|
32
|
+
/** Target contract address */
|
|
33
|
+
to: string
|
|
34
|
+
/** Message payload as BOC-serialized Cell */
|
|
35
|
+
body: Cell
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Typeguard for TON Wallet */
|
|
39
|
+
export function isTONWallet(wallet: unknown): wallet is TONWallet {
|
|
40
|
+
return (
|
|
41
|
+
typeof wallet === 'object' &&
|
|
42
|
+
wallet !== null &&
|
|
43
|
+
'contract' in wallet &&
|
|
44
|
+
'keyPair' in wallet &&
|
|
45
|
+
typeof wallet.contract === 'object' &&
|
|
46
|
+
wallet.contract !== null &&
|
|
47
|
+
'address' in wallet.contract &&
|
|
48
|
+
typeof wallet.keyPair === 'object' &&
|
|
49
|
+
wallet.keyPair !== null &&
|
|
50
|
+
'secretKey' in wallet.keyPair
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// asSnakeData helper for encoding variable-length arrays
|
|
55
|
+
function asSnakeData<T>(array: T[], builderFn: (item: T) => Builder): Cell {
|
|
56
|
+
const cells: Builder[] = []
|
|
57
|
+
let builder = beginCell()
|
|
58
|
+
|
|
59
|
+
for (const value of array) {
|
|
60
|
+
const itemBuilder = builderFn(value)
|
|
61
|
+
if (itemBuilder.refs > 3) {
|
|
62
|
+
throw new CCIPDataFormatUnsupportedError(
|
|
63
|
+
'Cannot pack more than 3 refs per item; store it in a separate ref cell.',
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
if (builder.availableBits < itemBuilder.bits || builder.availableRefs <= 1) {
|
|
67
|
+
cells.push(builder)
|
|
68
|
+
builder = beginCell()
|
|
69
|
+
}
|
|
70
|
+
builder.storeBuilder(itemBuilder)
|
|
71
|
+
}
|
|
72
|
+
cells.push(builder)
|
|
73
|
+
|
|
74
|
+
// Build the linked structure from the end
|
|
75
|
+
let current = cells[cells.length - 1].endCell()
|
|
76
|
+
for (let i = cells.length - 2; i >= 0; i--) {
|
|
77
|
+
const b = cells[i]
|
|
78
|
+
b.storeRef(current)
|
|
79
|
+
current = b.endCell()
|
|
80
|
+
}
|
|
81
|
+
return current
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Serializes an execution report into a TON Cell for OffRamp execution.
|
|
86
|
+
* @param execReport - Execution report containing message, proofs, and proof flag bits.
|
|
87
|
+
* @returns BOC-serialized Cell containing the execution report.
|
|
88
|
+
*/
|
|
89
|
+
export function serializeExecutionReport(
|
|
90
|
+
execReport: ExecutionReport<CCIPMessage_V1_6_TON>,
|
|
91
|
+
): Builder {
|
|
92
|
+
return beginCell()
|
|
93
|
+
.storeUint(execReport.message.sourceChainSelector, 64)
|
|
94
|
+
.storeRef(asSnakeData([execReport.message], serializeMessage))
|
|
95
|
+
.storeRef(Cell.EMPTY) // TODO: FIXME: offchainTokenData empty for now, add when implemented
|
|
96
|
+
.storeRef(
|
|
97
|
+
asSnakeData(execReport.proofs.map(toBigInt), (proof: bigint) => {
|
|
98
|
+
return beginCell().storeUint(proof, 256)
|
|
99
|
+
}),
|
|
100
|
+
)
|
|
101
|
+
.storeUint(execReport.proofFlagBits, 256)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function serializeMessage(message: CCIPMessage_V1_6_TON): Builder {
|
|
105
|
+
return beginCell()
|
|
106
|
+
.storeUint(BigInt(message.messageId), 256)
|
|
107
|
+
.storeUint(message.sourceChainSelector, 64)
|
|
108
|
+
.storeUint(message.destChainSelector, 64)
|
|
109
|
+
.storeUint(message.sequenceNumber, 64)
|
|
110
|
+
.storeUint(message.nonce, 64)
|
|
111
|
+
.storeRef(
|
|
112
|
+
beginCell()
|
|
113
|
+
.storeUint(bytesToBuffer(message.sender).length, 8)
|
|
114
|
+
.storeBuffer(bytesToBuffer(message.sender))
|
|
115
|
+
.endCell(),
|
|
116
|
+
)
|
|
117
|
+
.storeRef(beginCell().storeBuffer(bytesToBuffer(message.data)).endCell())
|
|
118
|
+
.storeAddress(Address.parse(message.receiver))
|
|
119
|
+
.storeCoins(message.gasLimit)
|
|
120
|
+
.storeMaybeRef(
|
|
121
|
+
message.tokenAmounts?.length > 0 ? serializeTokenAmounts(message.tokenAmounts) : null,
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function serializeTokenAmounts(tokenAmounts: CCIPMessage_V1_6['tokenAmounts']): Cell {
|
|
126
|
+
const builder = beginCell()
|
|
127
|
+
for (const ta of tokenAmounts) {
|
|
128
|
+
builder.storeRef(
|
|
129
|
+
beginCell()
|
|
130
|
+
.storeRef(serializeSourcePool(ta.sourcePoolAddress))
|
|
131
|
+
.storeAddress(Address.parse(ta.destTokenAddress))
|
|
132
|
+
.storeUint(BigInt(ta.amount), 256)
|
|
133
|
+
.storeRef(beginCell().storeBuffer(bytesToBuffer(ta.extraData)).endCell())
|
|
134
|
+
.endCell(),
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
return builder.endCell()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function serializeSourcePool(address: string): Cell {
|
|
141
|
+
const bytes = bytesToBuffer(address)
|
|
142
|
+
return beginCell().storeUint(bytes.length, 8).storeBuffer(bytes).endCell()
|
|
143
|
+
}
|