@chainlink/ccip-cli 0.92.1 → 0.94.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/dist/commands/lane-latency.d.ts +26 -0
- package/dist/commands/lane-latency.d.ts.map +1 -0
- package/dist/commands/lane-latency.js +73 -0
- package/dist/commands/lane-latency.js.map +1 -0
- package/dist/commands/manual-exec.d.ts.map +1 -1
- package/dist/commands/manual-exec.js +20 -269
- package/dist/commands/manual-exec.js.map +1 -1
- package/dist/commands/send.d.ts +1 -1
- package/dist/commands/send.js +30 -42
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +36 -16
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/utils.d.ts.map +1 -1
- package/dist/commands/utils.js +2 -1
- package/dist/commands/utils.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/providers/aptos.js +1 -1
- package/dist/providers/aptos.js.map +1 -1
- package/dist/providers/evm.js +1 -1
- package/dist/providers/evm.js.map +1 -1
- package/dist/providers/index.d.ts +4 -2
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +11 -8
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/ton.d.ts +8 -5
- package/dist/providers/ton.d.ts.map +1 -1
- package/dist/providers/ton.js +100 -26
- package/dist/providers/ton.js.map +1 -1
- package/package.json +20 -13
- package/src/commands/lane-latency.ts +93 -0
- package/src/commands/manual-exec.ts +18 -267
- package/src/commands/send.ts +34 -52
- package/src/commands/show.ts +40 -22
- package/src/commands/utils.ts +6 -4
- package/src/index.ts +8 -4
- package/src/providers/aptos.ts +1 -1
- package/src/providers/evm.ts +1 -1
- package/src/providers/index.ts +18 -14
- package/src/providers/ton.ts +109 -27
- package/tsconfig.json +3 -2
package/src/commands/send.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type AnyMessage,
|
|
3
2
|
type CCIPVersion,
|
|
4
3
|
type ChainStatic,
|
|
5
4
|
type EVMChain,
|
|
6
5
|
type ExtraArgs,
|
|
6
|
+
type MessageInput,
|
|
7
7
|
CCIPArgumentInvalidError,
|
|
8
8
|
CCIPChainFamilyUnsupportedError,
|
|
9
9
|
CCIPTokenNotFoundError,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
networkInfo,
|
|
14
14
|
sourceToDestTokenAmounts,
|
|
15
15
|
} from '@chainlink/ccip-sdk/src/index.ts'
|
|
16
|
-
import { type BytesLike,
|
|
16
|
+
import { type BytesLike, formatUnits, toUtf8Bytes } from 'ethers'
|
|
17
17
|
import type { Argv } from 'yargs'
|
|
18
18
|
|
|
19
19
|
import type { GlobalOpts } from '../index.ts'
|
|
@@ -67,7 +67,6 @@ export const builder = (yargs: Argv) =>
|
|
|
67
67
|
type: 'number',
|
|
68
68
|
describe:
|
|
69
69
|
'Gas limit for receiver callback execution; defaults to default configured on ramps',
|
|
70
|
-
default: 0,
|
|
71
70
|
},
|
|
72
71
|
'estimate-gas-limit': {
|
|
73
72
|
type: 'number',
|
|
@@ -105,10 +104,11 @@ export const builder = (yargs: Argv) =>
|
|
|
105
104
|
describe: "Address of the Solana tokenReceiver (if different than program's receiver)",
|
|
106
105
|
},
|
|
107
106
|
account: {
|
|
107
|
+
alias: 'receiver-object-id',
|
|
108
108
|
type: 'array',
|
|
109
109
|
string: true,
|
|
110
110
|
describe:
|
|
111
|
-
'List of accounts needed by Solana receiver program; append `=rw` to specify account as writable; can be specified multiple times',
|
|
111
|
+
'List of accounts needed by Solana receiver program, or receiverObjectIds needed by Sui; On Solana, append `=rw` to specify account as writable; can be specified multiple times',
|
|
112
112
|
example: 'requiredPdaAddress=rw',
|
|
113
113
|
},
|
|
114
114
|
'only-get-fee': {
|
|
@@ -159,15 +159,13 @@ async function sendMessage(
|
|
|
159
159
|
const getChain = fetchChainsFromRpcs(ctx, argv)
|
|
160
160
|
const source = await getChain(sourceNetwork.name)
|
|
161
161
|
|
|
162
|
-
let data: BytesLike
|
|
162
|
+
let data: BytesLike | undefined
|
|
163
163
|
if (argv.data) {
|
|
164
164
|
try {
|
|
165
165
|
data = getDataBytes(argv.data)
|
|
166
166
|
} catch (_) {
|
|
167
167
|
data = toUtf8Bytes(argv.data)
|
|
168
168
|
}
|
|
169
|
-
} else {
|
|
170
|
-
data = '0x'
|
|
171
169
|
}
|
|
172
170
|
|
|
173
171
|
const tokenAmounts: { token: string; amount: bigint }[] = argv.transferTokens?.length
|
|
@@ -175,25 +173,11 @@ async function sendMessage(
|
|
|
175
173
|
: []
|
|
176
174
|
|
|
177
175
|
let receiver = argv.receiver
|
|
178
|
-
let tokenReceiver
|
|
179
176
|
let accounts,
|
|
180
177
|
accountIsWritableBitmap = 0n
|
|
181
178
|
if (destNetwork.family === ChainFamily.Solana) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
tokenReceiver = '11111111111111111111111111111111'
|
|
185
|
-
} else if (!dataLength(data)) {
|
|
186
|
-
// sending tokens without data, i.e. not for a receiver contract
|
|
187
|
-
tokenReceiver = receiver
|
|
188
|
-
receiver = '11111111111111111111111111111111'
|
|
189
|
-
} else {
|
|
190
|
-
throw new CCIPArgumentInvalidError(
|
|
191
|
-
'token-receiver',
|
|
192
|
-
'required when sending tokens with data to Solana',
|
|
193
|
-
)
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (argv.account) {
|
|
179
|
+
// parse accounts with or without `=rw` suffix
|
|
180
|
+
if (argv.account?.length) {
|
|
197
181
|
accounts = argv.account.map((account, i) => {
|
|
198
182
|
if (account.endsWith('=rw')) {
|
|
199
183
|
accountIsWritableBitmap |= 1n << BigInt(i)
|
|
@@ -201,12 +185,7 @@ async function sendMessage(
|
|
|
201
185
|
}
|
|
202
186
|
return account
|
|
203
187
|
})
|
|
204
|
-
}
|
|
205
|
-
} else if (argv.tokenReceiver || argv.account?.length) {
|
|
206
|
-
throw new CCIPArgumentInvalidError(
|
|
207
|
-
'token-receiver/account',
|
|
208
|
-
'only valid for Solana destination',
|
|
209
|
-
)
|
|
188
|
+
}
|
|
210
189
|
}
|
|
211
190
|
|
|
212
191
|
let walletAddress, wallet
|
|
@@ -244,7 +223,7 @@ async function sendMessage(
|
|
|
244
223
|
message: {
|
|
245
224
|
sender: walletAddress,
|
|
246
225
|
receiver,
|
|
247
|
-
data,
|
|
226
|
+
data: data || '0x',
|
|
248
227
|
tokenAmounts: destTokenAmounts,
|
|
249
228
|
},
|
|
250
229
|
})
|
|
@@ -253,17 +232,19 @@ async function sendMessage(
|
|
|
253
232
|
if (argv.onlyEstimate) return
|
|
254
233
|
}
|
|
255
234
|
|
|
256
|
-
//
|
|
257
|
-
//
|
|
235
|
+
// builds a catch-all extraArgs object, which can be massaged by
|
|
236
|
+
// [[Chain.buildMessageForDest]] to create suitable extraArgs with defaults if needed
|
|
258
237
|
const extraArgs = {
|
|
259
|
-
...(argv.allowOutOfOrderExec != null
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
...(
|
|
263
|
-
? {
|
|
264
|
-
:
|
|
265
|
-
|
|
266
|
-
|
|
238
|
+
...(argv.allowOutOfOrderExec != null && {
|
|
239
|
+
allowOutOfOrderExecution: !!argv.allowOutOfOrderExec,
|
|
240
|
+
}),
|
|
241
|
+
...(argv.gasLimit == null
|
|
242
|
+
? {}
|
|
243
|
+
: destNetwork.family === ChainFamily.Solana
|
|
244
|
+
? { computeUnits: BigInt(argv.gasLimit) }
|
|
245
|
+
: { gasLimit: BigInt(argv.gasLimit) }),
|
|
246
|
+
...(!!argv.tokenReceiver && { tokenReceiver: argv.tokenReceiver }),
|
|
247
|
+
...(!!accounts && { accounts, accountIsWritableBitmap }), // accounts also used as Sui receiverObjectIds
|
|
267
248
|
}
|
|
268
249
|
|
|
269
250
|
let feeToken, feeTokenInfo
|
|
@@ -287,7 +268,7 @@ async function sendMessage(
|
|
|
287
268
|
feeTokenInfo = await source.getTokenInfo(nativeToken)
|
|
288
269
|
}
|
|
289
270
|
|
|
290
|
-
const message:
|
|
271
|
+
const message: MessageInput = {
|
|
291
272
|
receiver,
|
|
292
273
|
data,
|
|
293
274
|
extraArgs: extraArgs as ExtraArgs,
|
|
@@ -296,7 +277,11 @@ async function sendMessage(
|
|
|
296
277
|
}
|
|
297
278
|
|
|
298
279
|
// calculate fee
|
|
299
|
-
const fee = await source.getFee(
|
|
280
|
+
const fee = await source.getFee({
|
|
281
|
+
...argv,
|
|
282
|
+
destChainSelector: destNetwork.chainSelector,
|
|
283
|
+
message,
|
|
284
|
+
})
|
|
300
285
|
|
|
301
286
|
logger.info(
|
|
302
287
|
'Fee:',
|
|
@@ -310,17 +295,15 @@ async function sendMessage(
|
|
|
310
295
|
if (argv.onlyGetFee) return
|
|
311
296
|
|
|
312
297
|
if (!walletAddress) [walletAddress, wallet] = await loadChainWallet(source, argv)
|
|
313
|
-
const request = await source.sendMessage(
|
|
314
|
-
argv
|
|
315
|
-
destNetwork.chainSelector,
|
|
316
|
-
{ ...message, fee },
|
|
317
|
-
|
|
318
|
-
)
|
|
298
|
+
const request = await source.sendMessage({
|
|
299
|
+
...argv,
|
|
300
|
+
destChainSelector: destNetwork.chainSelector,
|
|
301
|
+
message: { ...message, fee },
|
|
302
|
+
wallet,
|
|
303
|
+
})
|
|
319
304
|
logger.info(
|
|
320
305
|
'🚀 Sending message to',
|
|
321
|
-
|
|
322
|
-
? tokenReceiver
|
|
323
|
-
: receiver,
|
|
306
|
+
receiver,
|
|
324
307
|
'@',
|
|
325
308
|
destNetwork.name,
|
|
326
309
|
', tx =>',
|
|
@@ -328,7 +311,6 @@ async function sendMessage(
|
|
|
328
311
|
', messageId =>',
|
|
329
312
|
request.message.messageId,
|
|
330
313
|
)
|
|
331
|
-
|
|
332
314
|
await showRequests(ctx, {
|
|
333
315
|
...argv,
|
|
334
316
|
txHash: request.tx.hash,
|
package/src/commands/show.ts
CHANGED
|
@@ -3,6 +3,8 @@ import {
|
|
|
3
3
|
type ChainTransaction,
|
|
4
4
|
CCIPExecTxRevertedError,
|
|
5
5
|
CCIPNotImplementedError,
|
|
6
|
+
ExecutionState,
|
|
7
|
+
MessageStatus,
|
|
6
8
|
bigIntReplacer,
|
|
7
9
|
discoverOffRamp,
|
|
8
10
|
isSupportedTxHash,
|
|
@@ -82,18 +84,18 @@ export async function showRequests(ctx: Ctx, argv: Parameters<typeof handler>[0]
|
|
|
82
84
|
getChain = fetchChainsFromRpcs(ctx, argv)
|
|
83
85
|
let idFromSource, onRamp
|
|
84
86
|
if (argv.idFromSource.includes('@')) {
|
|
85
|
-
;[onRamp, idFromSource] = argv.idFromSource.split('@')
|
|
87
|
+
;[onRamp, idFromSource] = argv.idFromSource.split('@') as [string, string]
|
|
86
88
|
} else idFromSource = argv.idFromSource
|
|
87
89
|
const sourceNetwork = networkInfo(idFromSource)
|
|
88
90
|
source = await getChain(sourceNetwork.chainId)
|
|
89
|
-
if (!source.
|
|
90
|
-
throw new CCIPNotImplementedError(`
|
|
91
|
-
request = await source.
|
|
91
|
+
if (!source.getMessageById)
|
|
92
|
+
throw new CCIPNotImplementedError(`getMessageById for ${source.constructor.name}`)
|
|
93
|
+
request = await source.getMessageById(argv.txHash, onRamp, argv)
|
|
92
94
|
} else {
|
|
93
95
|
const [getChain_, tx$] = fetchChainsFromRpcs(ctx, argv, argv.txHash)
|
|
94
96
|
getChain = getChain_
|
|
95
97
|
;[source, tx] = await tx$
|
|
96
|
-
request = await selectRequest(await source.
|
|
98
|
+
request = await selectRequest(await source.getMessagesInTx(tx), 'to know more', argv)
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
switch (argv.format) {
|
|
@@ -118,17 +120,16 @@ export async function showRequests(ctx: Ctx, argv: Parameters<typeof handler>[0]
|
|
|
118
120
|
let cancelWaitFinalized: (() => void) | undefined
|
|
119
121
|
const finalized$ = (async () => {
|
|
120
122
|
if (argv.wait) {
|
|
121
|
-
logger.info(
|
|
122
|
-
await source.waitFinalized(
|
|
123
|
+
logger.info(`[${MessageStatus.Sent}] Waiting for source chain finalization...`)
|
|
124
|
+
await source.waitFinalized({
|
|
123
125
|
request,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
)
|
|
127
|
-
logger.info(`Transaction "${request.log.transactionHash}" finalized ✅`)
|
|
126
|
+
cancel$: new Promise<void>((resolve) => (cancelWaitFinalized = resolve)),
|
|
127
|
+
})
|
|
128
|
+
logger.info(`[${MessageStatus.SourceFinalized}] Source chain finalized`)
|
|
128
129
|
}
|
|
129
130
|
|
|
130
|
-
const offchainTokenData = await source.
|
|
131
|
-
if (offchainTokenData
|
|
131
|
+
const offchainTokenData = await source.getOffchainTokenData(request)
|
|
132
|
+
if (offchainTokenData.length && offchainTokenData.some((d) => !!d)) {
|
|
132
133
|
switch (argv.format) {
|
|
133
134
|
case Format.log: {
|
|
134
135
|
logger.log('attestations =', offchainTokenData)
|
|
@@ -147,7 +148,8 @@ export async function showRequests(ctx: Ctx, argv: Parameters<typeof handler>[0]
|
|
|
147
148
|
}
|
|
148
149
|
}
|
|
149
150
|
|
|
150
|
-
if (argv.wait)
|
|
151
|
+
if (argv.wait)
|
|
152
|
+
logger.info(`[${MessageStatus.SourceFinalized}] Waiting for commit on destination chain...`)
|
|
151
153
|
else logger.info('Commit (dest):')
|
|
152
154
|
})()
|
|
153
155
|
|
|
@@ -157,13 +159,16 @@ export async function showRequests(ctx: Ctx, argv: Parameters<typeof handler>[0]
|
|
|
157
159
|
|
|
158
160
|
let cancelWaitCommit: (() => void) | undefined
|
|
159
161
|
const commit$ = (async () => {
|
|
160
|
-
const commit = await dest.
|
|
162
|
+
const commit = await dest.getCommitReport({
|
|
163
|
+
commitStore,
|
|
164
|
+
request,
|
|
161
165
|
...argv,
|
|
162
166
|
watch: argv.wait && new Promise<void>((resolve) => (cancelWaitCommit = resolve)),
|
|
163
167
|
})
|
|
164
168
|
cancelWaitFinalized?.()
|
|
165
|
-
if (!commit) return
|
|
166
169
|
await finalized$
|
|
170
|
+
if (argv.wait)
|
|
171
|
+
logger.info(`[${MessageStatus.Committed}] Commit report accepted on destination chain`)
|
|
167
172
|
switch (argv.format) {
|
|
168
173
|
case Format.log:
|
|
169
174
|
logger.log('commit =', commit)
|
|
@@ -175,20 +180,33 @@ export async function showRequests(ctx: Ctx, argv: Parameters<typeof handler>[0]
|
|
|
175
180
|
logger.info(JSON.stringify(commit, bigIntReplacer, 2))
|
|
176
181
|
break
|
|
177
182
|
}
|
|
178
|
-
if (argv.wait)
|
|
183
|
+
if (argv.wait)
|
|
184
|
+
logger.info(`[${MessageStatus.Blessed}] Waiting for execution on destination chain...`)
|
|
179
185
|
else logger.info('Receipts (dest):')
|
|
180
186
|
return commit
|
|
181
187
|
})()
|
|
182
188
|
|
|
183
189
|
let found = false
|
|
184
|
-
for await (const receipt of dest.
|
|
190
|
+
for await (const receipt of dest.getExecutionReceipts({
|
|
191
|
+
...argv,
|
|
185
192
|
offRamp,
|
|
186
|
-
request,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
193
|
+
messageId: request.message.messageId,
|
|
194
|
+
sourceChainSelector: request.message.sourceChainSelector,
|
|
195
|
+
startTime: request.tx.timestamp,
|
|
196
|
+
commit: !argv.wait ? await commit$ : undefined,
|
|
197
|
+
watch: argv.wait && ctx.destroy$,
|
|
198
|
+
})) {
|
|
190
199
|
cancelWaitCommit?.()
|
|
191
200
|
await commit$
|
|
201
|
+
const status =
|
|
202
|
+
receipt.receipt.state === ExecutionState.Success
|
|
203
|
+
? MessageStatus.Success
|
|
204
|
+
: MessageStatus.Failed
|
|
205
|
+
const statusMessage =
|
|
206
|
+
receipt.receipt.state === ExecutionState.Success
|
|
207
|
+
? 'Message executed on destination chain'
|
|
208
|
+
: 'Message execution failed on destination chain'
|
|
209
|
+
logger.info(`[${status}] ${statusMessage}`)
|
|
192
210
|
switch (argv.format) {
|
|
193
211
|
case Format.log:
|
|
194
212
|
logger.log('receipt =', withDateTimestamp(receipt))
|
package/src/commands/utils.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
CCIPError,
|
|
12
12
|
CCIPErrorCode,
|
|
13
13
|
ExecutionState,
|
|
14
|
+
getCCIPExplorerUrl,
|
|
14
15
|
networkInfo,
|
|
15
16
|
supportedChains,
|
|
16
17
|
} from '@chainlink/ccip-sdk/src/index.ts'
|
|
@@ -42,7 +43,7 @@ export async function selectRequest(
|
|
|
42
43
|
hints?: { logIndex?: number },
|
|
43
44
|
): Promise<CCIPRequest> {
|
|
44
45
|
if (hints?.logIndex != null) requests = requests.filter((req) => req.log.index === hints.logIndex)
|
|
45
|
-
if (requests.length === 1) return requests[0]
|
|
46
|
+
if (requests.length === 1) return requests[0]!
|
|
46
47
|
const answer = await select({
|
|
47
48
|
message: `${requests.length} messageIds found; select one${promptSuffix ? ' ' + promptSuffix : ''}`,
|
|
48
49
|
choices: [
|
|
@@ -66,7 +67,7 @@ tokenTransfers =\t[${req.message.tokenAmounts.map((ta) => ('token' in ta ? ta.to
|
|
|
66
67
|
],
|
|
67
68
|
})
|
|
68
69
|
if (answer < 0) throw new CCIPError(CCIPErrorCode.UNKNOWN, 'User requested exit')
|
|
69
|
-
return requests[answer]
|
|
70
|
+
return requests[answer]!
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
/**
|
|
@@ -142,7 +143,7 @@ async function formatToken(
|
|
|
142
143
|
* @returns Record with indexed keys.
|
|
143
144
|
*/
|
|
144
145
|
export function formatArray<T>(name: string, values: readonly T[]): Record<string, T> {
|
|
145
|
-
if (values.length <= 1) return { [name]: values[0] }
|
|
146
|
+
if (values.length <= 1) return { [name]: values[0]! }
|
|
146
147
|
return Object.fromEntries(values.map((v, i) => [`${name}[${i}]`, v] as const))
|
|
147
148
|
}
|
|
148
149
|
|
|
@@ -296,6 +297,7 @@ export async function prettyRequest(this: Ctx, source: Chain, request: CCIPReque
|
|
|
296
297
|
...('accounts' in request.message ? formatArray('accounts', request.message.accounts) : {}),
|
|
297
298
|
...rest,
|
|
298
299
|
})
|
|
300
|
+
this.logger.info('CCIP Explorer:', getCCIPExplorerUrl('msg', request.message.messageId))
|
|
299
301
|
}
|
|
300
302
|
|
|
301
303
|
/**
|
|
@@ -521,7 +523,7 @@ export function logParsedError(this: Ctx, err: unknown): boolean {
|
|
|
521
523
|
export async function parseTokenAmounts(source: Chain, transferTokens: readonly string[]) {
|
|
522
524
|
return Promise.all(
|
|
523
525
|
transferTokens.map(async (tokenAmount) => {
|
|
524
|
-
const [token, amount_] = tokenAmount.split('=')
|
|
526
|
+
const [token, amount_] = tokenAmount.split('=') as [string, string]
|
|
525
527
|
const { decimals } = await source.getTokenInfo(token)
|
|
526
528
|
const amount = parseUnits(amount_, decimals)
|
|
527
529
|
return { token, amount }
|
package/src/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { Format } from './commands/index.ts'
|
|
|
11
11
|
util.inspect.defaultOptions.depth = 6 // print down to tokenAmounts in requests
|
|
12
12
|
// generate:nofail
|
|
13
13
|
// `const VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'`
|
|
14
|
-
const VERSION = '0.
|
|
14
|
+
const VERSION = '0.94.0-aac4ae6'
|
|
15
15
|
// generate:end
|
|
16
16
|
|
|
17
17
|
const globalOpts = {
|
|
@@ -41,7 +41,11 @@ const globalOpts = {
|
|
|
41
41
|
page: {
|
|
42
42
|
type: 'number',
|
|
43
43
|
describe: 'getLogs page/range size',
|
|
44
|
-
|
|
44
|
+
},
|
|
45
|
+
'no-api': {
|
|
46
|
+
type: 'boolean',
|
|
47
|
+
describe: 'Disable CCIP API integration (full decentralization mode)',
|
|
48
|
+
default: false,
|
|
45
49
|
},
|
|
46
50
|
} as const
|
|
47
51
|
|
|
@@ -66,12 +70,12 @@ async function main() {
|
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
function wasCalledAsScript() {
|
|
69
|
-
const realPath = realpathSync(process.argv[1])
|
|
73
|
+
const realPath = realpathSync(process.argv[1]!)
|
|
70
74
|
const realPathAsUrl = pathToFileURL(realPath).href
|
|
71
75
|
return import.meta.url === realPathAsUrl
|
|
72
76
|
}
|
|
73
77
|
|
|
74
|
-
if (import.meta
|
|
78
|
+
if (import.meta.main || wasCalledAsScript()) {
|
|
75
79
|
const later = setTimeout(() => {}, 2 ** 31 - 1) // keep event-loop alive
|
|
76
80
|
await main()
|
|
77
81
|
.catch((err) => {
|
package/src/providers/aptos.ts
CHANGED
|
@@ -99,7 +99,7 @@ export class AptosLedgerSigner /*implements AptosAsyncAccount*/ {
|
|
|
99
99
|
*/
|
|
100
100
|
export async function loadAptosWallet({ wallet: walletOpt }: { wallet?: unknown }) {
|
|
101
101
|
if (typeof walletOpt !== 'string') throw new CCIPArgumentInvalidError('wallet', String(walletOpt))
|
|
102
|
-
if (
|
|
102
|
+
if (walletOpt.startsWith('ledger')) {
|
|
103
103
|
let derivationPath = walletOpt.split(':')[1]
|
|
104
104
|
if (!derivationPath) derivationPath = "m/44'/637'/0'/0'/0'"
|
|
105
105
|
else if (!isNaN(Number(derivationPath))) derivationPath = `m/44'/637'/${derivationPath}'/0'/0'`
|
package/src/providers/evm.ts
CHANGED
|
@@ -43,7 +43,7 @@ export async function loadEvmWallet(
|
|
|
43
43
|
)
|
|
44
44
|
}
|
|
45
45
|
if (typeof walletOpt !== 'string') throw new CCIPArgumentInvalidError('wallet', String(walletOpt))
|
|
46
|
-
if (
|
|
46
|
+
if (walletOpt.startsWith('ledger')) {
|
|
47
47
|
let derivationPath = walletOpt.split(':')[1]
|
|
48
48
|
if (derivationPath && !isNaN(Number(derivationPath)))
|
|
49
49
|
derivationPath = `m/44'/60'/${derivationPath}'/0/0`
|
package/src/providers/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type ChainGetter,
|
|
7
7
|
type ChainTransaction,
|
|
8
8
|
type EVMChain,
|
|
9
|
+
type TONChain,
|
|
9
10
|
CCIPChainFamilyUnsupportedError,
|
|
10
11
|
CCIPNetworkFamilyUnsupportedError,
|
|
11
12
|
CCIPRpcNotFoundError,
|
|
@@ -53,11 +54,11 @@ async function collectEndpoints(
|
|
|
53
54
|
|
|
54
55
|
export function fetchChainsFromRpcs(
|
|
55
56
|
ctx: Ctx,
|
|
56
|
-
argv: { rpcs?: string[]; rpcsFile?: string },
|
|
57
|
+
argv: { rpcs?: string[]; rpcsFile?: string; noApi?: boolean },
|
|
57
58
|
): ChainGetter
|
|
58
59
|
export function fetchChainsFromRpcs(
|
|
59
60
|
ctx: Ctx,
|
|
60
|
-
argv: { rpcs?: string[]; rpcsFile?: string },
|
|
61
|
+
argv: { rpcs?: string[]; rpcsFile?: string; noApi?: boolean },
|
|
61
62
|
txHash: string,
|
|
62
63
|
): [ChainGetter, Promise<[Chain, ChainTransaction]>]
|
|
63
64
|
|
|
@@ -66,13 +67,13 @@ export function fetchChainsFromRpcs(
|
|
|
66
67
|
* If txHash is provided, fetches matching families first and returns [chainGetter, txPromise];
|
|
67
68
|
* Otherwise, spawns racing URLs for each family asked by `getChain` getter
|
|
68
69
|
* @param ctx - Context object containing destroy$ promise and logger properties
|
|
69
|
-
* @param argv - Options containing rpcs (list) and
|
|
70
|
+
* @param argv - Options containing rpcs (list), rpcs file and noApi flag
|
|
70
71
|
* @param txHash - Optional txHash to fetch concurrently; causes the function to return a [ChainGetter, Promise<ChainTransaction>]
|
|
71
72
|
* @returns a ChainGetter (if txHash was provided), or a tuple of [ChainGetter, Promise<ChainTransaction>]
|
|
72
73
|
*/
|
|
73
74
|
export function fetchChainsFromRpcs(
|
|
74
75
|
ctx: Ctx,
|
|
75
|
-
argv: { rpcs?: string[]; rpcsFile?: string },
|
|
76
|
+
argv: { rpcs?: string[]; rpcsFile?: string; noApi?: boolean },
|
|
76
77
|
txHash?: string,
|
|
77
78
|
) {
|
|
78
79
|
const chains: Record<string, Promise<Chain>> = {}
|
|
@@ -82,7 +83,7 @@ export function fetchChainsFromRpcs(
|
|
|
82
83
|
> = {}
|
|
83
84
|
const finished: Partial<Record<ChainFamily, boolean>> = {}
|
|
84
85
|
const initFamily$: Partial<Record<ChainFamily, Promise<unknown>>> = {}
|
|
85
|
-
let endpoints$: Promise<Set<string>>
|
|
86
|
+
let endpoints$: Promise<Set<string>> | undefined
|
|
86
87
|
|
|
87
88
|
let txResolve: (value: [Chain, ChainTransaction]) => void, txReject: (reason?: unknown) => void
|
|
88
89
|
const txResult = new Promise<[Chain, ChainTransaction]>((resolve, reject) => {
|
|
@@ -100,7 +101,10 @@ export function fetchChainsFromRpcs(
|
|
|
100
101
|
const txs$: Promise<unknown>[] = []
|
|
101
102
|
let txFound = false
|
|
102
103
|
for (const url of endpoints) {
|
|
103
|
-
const chain$ = C.fromUrl(url,
|
|
104
|
+
const chain$ = C.fromUrl(url, {
|
|
105
|
+
...ctx,
|
|
106
|
+
apiClient: argv.noApi ? null : undefined,
|
|
107
|
+
})
|
|
104
108
|
chains$.push(chain$)
|
|
105
109
|
|
|
106
110
|
void chain$.then(
|
|
@@ -116,7 +120,7 @@ export function fetchChainsFromRpcs(
|
|
|
116
120
|
chains[chain.network.name] = Promise.resolve(chain)
|
|
117
121
|
} else if (chain.network.name in chainsCbs) {
|
|
118
122
|
// chain detected, and there's a "pending request" by getChain: resolve
|
|
119
|
-
const [resolve] = chainsCbs[chain.network.name]
|
|
123
|
+
const [resolve] = chainsCbs[chain.network.name]!
|
|
120
124
|
resolve(chain)
|
|
121
125
|
}
|
|
122
126
|
return chain
|
|
@@ -152,16 +156,16 @@ export function fetchChainsFromRpcs(
|
|
|
152
156
|
|
|
153
157
|
const chainGetter = async (idOrSelectorOrName: number | string | bigint): Promise<Chain> => {
|
|
154
158
|
const network = networkInfo(idOrSelectorOrName)
|
|
155
|
-
if (network.name in chains) return chains[network.name]
|
|
159
|
+
if (network.name in chains) return chains[network.name]!
|
|
156
160
|
if (finished[network.family]) throw new CCIPRpcNotFoundError(network.name)
|
|
157
|
-
chains[network.name] = new Promise((resolve, reject) => {
|
|
161
|
+
const c = (chains[network.name] = new Promise((resolve, reject) => {
|
|
158
162
|
chainsCbs[network.name] = [resolve, reject]
|
|
159
|
-
})
|
|
160
|
-
void
|
|
163
|
+
}))
|
|
164
|
+
void c.finally(() => {
|
|
161
165
|
delete chainsCbs[network.name] // when chain is settled, delete the callbacks
|
|
162
166
|
})
|
|
163
167
|
void loadChainFamily(network.family)
|
|
164
|
-
return
|
|
168
|
+
return c
|
|
165
169
|
}
|
|
166
170
|
|
|
167
171
|
if (!txHash) return chainGetter
|
|
@@ -210,8 +214,8 @@ export async function loadChainWallet(chain: Chain, argv: { wallet?: unknown; rp
|
|
|
210
214
|
wallet = loadSuiWallet(argv)
|
|
211
215
|
return [wallet.toSuiAddress(), wallet] as const
|
|
212
216
|
case ChainFamily.TON:
|
|
213
|
-
wallet = await loadTonWallet(argv)
|
|
214
|
-
return [wallet.
|
|
217
|
+
wallet = await loadTonWallet((chain as TONChain).provider, argv, chain.network.isTestnet)
|
|
218
|
+
return [wallet.getAddress(), wallet] as const
|
|
215
219
|
default:
|
|
216
220
|
// TypeScript exhaustiveness check - this should never be reached
|
|
217
221
|
throw new CCIPChainFamilyUnsupportedError((chain.network as { family: string }).family)
|