@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.
Files changed (44) hide show
  1. package/dist/commands/lane-latency.d.ts +26 -0
  2. package/dist/commands/lane-latency.d.ts.map +1 -0
  3. package/dist/commands/lane-latency.js +73 -0
  4. package/dist/commands/lane-latency.js.map +1 -0
  5. package/dist/commands/manual-exec.d.ts.map +1 -1
  6. package/dist/commands/manual-exec.js +20 -269
  7. package/dist/commands/manual-exec.js.map +1 -1
  8. package/dist/commands/send.d.ts +1 -1
  9. package/dist/commands/send.js +30 -42
  10. package/dist/commands/send.js.map +1 -1
  11. package/dist/commands/show.d.ts.map +1 -1
  12. package/dist/commands/show.js +36 -16
  13. package/dist/commands/show.js.map +1 -1
  14. package/dist/commands/utils.d.ts.map +1 -1
  15. package/dist/commands/utils.js +2 -1
  16. package/dist/commands/utils.js.map +1 -1
  17. package/dist/index.d.ts +5 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +7 -3
  20. package/dist/index.js.map +1 -1
  21. package/dist/providers/aptos.js +1 -1
  22. package/dist/providers/aptos.js.map +1 -1
  23. package/dist/providers/evm.js +1 -1
  24. package/dist/providers/evm.js.map +1 -1
  25. package/dist/providers/index.d.ts +4 -2
  26. package/dist/providers/index.d.ts.map +1 -1
  27. package/dist/providers/index.js +11 -8
  28. package/dist/providers/index.js.map +1 -1
  29. package/dist/providers/ton.d.ts +8 -5
  30. package/dist/providers/ton.d.ts.map +1 -1
  31. package/dist/providers/ton.js +100 -26
  32. package/dist/providers/ton.js.map +1 -1
  33. package/package.json +20 -13
  34. package/src/commands/lane-latency.ts +93 -0
  35. package/src/commands/manual-exec.ts +18 -267
  36. package/src/commands/send.ts +34 -52
  37. package/src/commands/show.ts +40 -22
  38. package/src/commands/utils.ts +6 -4
  39. package/src/index.ts +8 -4
  40. package/src/providers/aptos.ts +1 -1
  41. package/src/providers/evm.ts +1 -1
  42. package/src/providers/index.ts +18 -14
  43. package/src/providers/ton.ts +109 -27
  44. package/tsconfig.json +3 -2
@@ -1,30 +1,106 @@
1
1
  import { existsSync, readFileSync } from 'node:fs'
2
2
 
3
- import { CCIPArgumentInvalidError, CCIPWalletInvalidError } from '@chainlink/ccip-sdk/src/index.ts'
3
+ import {
4
+ type UnsignedTONTx,
5
+ CCIPArgumentInvalidError,
6
+ CCIPWalletInvalidError,
7
+ bytesToBuffer,
8
+ } from '@chainlink/ccip-sdk/src/index.ts'
9
+ import HIDTransport from '@ledgerhq/hw-transport-node-hid'
4
10
  import { keyPairFromSecretKey, mnemonicToPrivateKey } from '@ton/crypto'
5
- import { WalletContractV4 } from '@ton/ton'
11
+ import { type TonClient, Address, SendMode, WalletContractV4, internal, toNano } from '@ton/ton'
12
+ import { TonTransport } from '@ton-community/ton-ledger'
6
13
 
7
14
  /**
8
15
  * Loads a TON wallet from the provided options.
16
+ * @param client - TON client instance
9
17
  * @param wallet - wallet options (as passed from yargs argv)
18
+ * @param isTestnet - whether the wallet is on the testnet
10
19
  * @returns Promise to TONWallet instance
11
20
  */
12
- export async function loadTonWallet({ wallet: walletOpt }: { wallet?: unknown } = {}) {
21
+ export async function loadTonWallet(
22
+ client: TonClient,
23
+ { wallet: walletOpt }: { wallet?: unknown } = {},
24
+ isTestnet?: boolean,
25
+ ) {
13
26
  if (typeof walletOpt !== 'string') throw new CCIPWalletInvalidError(walletOpt)
14
-
15
- // Handle mnemonic phrase
16
- if (walletOpt.includes(' ')) {
17
- const mnemonic = walletOpt.trim().split(' ')
18
- const keyPair = await mnemonicToPrivateKey(mnemonic)
27
+ if (walletOpt === 'ledger' || walletOpt.startsWith('ledger:')) {
28
+ const transport = await HIDTransport.default.create()
29
+ const ton = new TonTransport(transport)
30
+ let derivationPath = walletOpt.split(':')[1]
31
+ if (!derivationPath) derivationPath = `44'/607'/${isTestnet ? '1' : '0'}'/0/0/0`
32
+ else if (!isNaN(Number(derivationPath)))
33
+ derivationPath = `44'/607'/${isTestnet ? '1' : '0'}'/0/${derivationPath}/0`
34
+ const match = derivationPath.match(
35
+ /^(?:m\/)?(\d+)'?\/(\d+)'?\/(\d+)'?\/(\d+)'?\/(\d+)'?\/(\d+)'?$/,
36
+ )
37
+ if (!match) throw new CCIPWalletInvalidError(walletOpt)
38
+ const path = match.slice(1).map((x) => parseInt(x))
39
+ const { address, publicKey } = await ton.getAddress(path, {
40
+ chain: 0,
41
+ bounceable: false,
42
+ testOnly: isTestnet,
43
+ })
44
+ console.info('Ledger TON:', address, ', derivationPath:', derivationPath)
19
45
  const contract = WalletContractV4.create({
20
46
  workchain: 0,
21
- publicKey: keyPair.publicKey,
47
+ publicKey,
22
48
  })
23
- return { contract, keyPair }
49
+ const openedWallet = client.open(contract)
50
+ return {
51
+ getAddress: () => address,
52
+ sendTransaction: async ({ value, body, ...args }: UnsignedTONTx) => {
53
+ const seqno = await openedWallet.getSeqno()
54
+ const to = Address.parse(args.to)
55
+ if (!value) {
56
+ const { source_fees } = await client.estimateExternalMessageFee(to, {
57
+ ignoreSignature: true,
58
+ body,
59
+ initCode: null,
60
+ initData: null,
61
+ })
62
+ value =
63
+ BigInt(
64
+ source_fees.storage_fee +
65
+ source_fees.gas_fee +
66
+ source_fees.fwd_fee +
67
+ source_fees.in_fwd_fee,
68
+ ) + toNano('0.0001') // buffer
69
+ }
70
+ const signed = await ton.signTransaction(path, {
71
+ seqno,
72
+ amount: value,
73
+ sendMode: SendMode.IGNORE_ERRORS | SendMode.PAY_GAS_SEPARATELY,
74
+ timeout: Math.floor(Date.now() / 1000 + 60),
75
+ bounce: false,
76
+ ...args,
77
+ to,
78
+ payload: {
79
+ type: 'unsafe',
80
+ message: body,
81
+ },
82
+ })
83
+ await openedWallet.send(signed)
84
+ return seqno
85
+ },
86
+ }
24
87
  }
25
88
 
26
- // Handle hex private key
27
- if (walletOpt.startsWith('0x')) {
89
+ let keyPair
90
+ if (existsSync(walletOpt)) {
91
+ // Handle file path
92
+ const content = readFileSync(walletOpt, 'utf8').trim()
93
+ const secretKey = bytesToBuffer(content)
94
+ if (secretKey.length !== 64) {
95
+ throw new CCIPArgumentInvalidError('wallet', 'Invalid private key in file: must be 64 bytes')
96
+ }
97
+ keyPair = keyPairFromSecretKey(secretKey)
98
+ } else if (walletOpt.includes(' ')) {
99
+ // Handle mnemonic phrase
100
+ const mnemonic = walletOpt.trim().split(' ')
101
+ keyPair = await mnemonicToPrivateKey(mnemonic)
102
+ } else if (walletOpt.startsWith('0x')) {
103
+ // Handle hex private key
28
104
  const secretKey = Buffer.from(walletOpt.slice(2), 'hex')
29
105
  if (secretKey.length === 32) {
30
106
  throw new CCIPArgumentInvalidError(
@@ -35,27 +111,33 @@ export async function loadTonWallet({ wallet: walletOpt }: { wallet?: unknown }
35
111
  if (secretKey.length !== 64) {
36
112
  throw new CCIPArgumentInvalidError('wallet', 'must be 64 bytes (or use mnemonic)')
37
113
  }
38
- const keyPair = keyPairFromSecretKey(secretKey)
39
- const contract = WalletContractV4.create({
40
- workchain: 0,
41
- publicKey: keyPair.publicKey,
42
- })
43
- return { contract, keyPair }
114
+ keyPair = keyPairFromSecretKey(secretKey)
44
115
  }
45
116
 
46
- // Handle file path
47
- if (existsSync(walletOpt)) {
48
- const content = readFileSync(walletOpt, 'utf8').trim()
49
- const secretKey = Buffer.from(content.startsWith('0x') ? content.slice(2) : content, 'hex')
50
- if (secretKey.length !== 64) {
51
- throw new CCIPArgumentInvalidError('wallet', 'Invalid private key in file: must be 64 bytes')
52
- }
53
- const keyPair = keyPairFromSecretKey(secretKey)
117
+ if (keyPair) {
54
118
  const contract = WalletContractV4.create({
55
119
  workchain: 0,
56
120
  publicKey: keyPair.publicKey,
57
121
  })
58
- return { contract, keyPair }
122
+ const openedWallet = client.open(contract)
123
+ return {
124
+ getAddress: () => contract.address.toString(),
125
+ sendTransaction: async (args: UnsignedTONTx) => {
126
+ const seqno = await openedWallet.getSeqno()
127
+ const signed = await openedWallet.createTransfer({
128
+ ...keyPair,
129
+ seqno,
130
+ messages: [
131
+ internal({
132
+ value: toNano('0.3'), // TODO: FIXME: estimate proper value for execution costs instead of hardcoding.
133
+ ...args,
134
+ }),
135
+ ],
136
+ })
137
+ await openedWallet.send(signed)
138
+ return seqno
139
+ },
140
+ }
59
141
  }
60
142
 
61
143
  throw new CCIPArgumentInvalidError('wallet', 'Wallet not specified')
package/tsconfig.json CHANGED
@@ -14,6 +14,7 @@
14
14
  "verbatimModuleSyntax": true,
15
15
  "erasableSyntaxOnly": true,
16
16
  "resolveJsonModule": true,
17
- "noImplicitOverride": true
18
- }
17
+ "noImplicitOverride": true,
18
+ "noUncheckedIndexedAccess": true,
19
+ },
19
20
  }