@ton-community/ton-ledger 7.0.1 → 7.1.0-pre.1

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 CHANGED
@@ -7,7 +7,7 @@ This library allows you to connect to a ledger device and with with TON from bro
7
7
  To add library to your project execute:
8
8
 
9
9
  ```bash
10
- yarn add ton-ledger
10
+ yarn add @ton-community/ton-ledger
11
11
  ```
12
12
 
13
13
  ## Connecting to a Device
@@ -29,7 +29,7 @@ React Native:
29
29
 
30
30
  After connecting to a device create a TonTransport instance:
31
31
  ```typescript
32
- import { TonTransport } from 'ton-ledger';
32
+ import { TonTransport } from '@ton-community/ton-ledger';
33
33
  let transport = new TonTransport(device);
34
34
  ```
35
35
 
@@ -83,7 +83,7 @@ Ledger Nanoapp works with Wallet v4 for now, we recommend you to continue to use
83
83
 
84
84
  ```typescript
85
85
  import { WalletV4Contract, WalletV4Source } from 'ton';
86
- import { TonPayloadFormat } from 'ton-ledger';
86
+ import { TonPayloadFormat } from '@ton-community/ton-ledger';
87
87
  import { TonClient, Address, SendMode, toNano } from 'ton-core';
88
88
 
89
89
  let client = new TonClient({ endpoint: 'https://toncenter.com/api/v2/jsonRPC' });
@@ -2,6 +2,9 @@
2
2
  import Transport from "@ledgerhq/hw-transport";
3
3
  import { Address, Cell, SendMode, StateInit } from "@ton/core";
4
4
  export type TonPayloadFormat = {
5
+ type: 'unsafe';
6
+ message: Cell;
7
+ } | {
5
8
  type: 'comment';
6
9
  text: string;
7
10
  } | {
@@ -21,7 +24,61 @@ export type TonPayloadFormat = {
21
24
  customPayload: Cell | null;
22
25
  forwardAmount: bigint;
23
26
  forwardPayload: Cell | null;
27
+ } | {
28
+ type: 'jetton-burn';
29
+ queryId: bigint | null;
30
+ amount: bigint;
31
+ responseDestination: Address;
32
+ customPayload: Cell | Buffer | null;
33
+ } | {
34
+ type: 'add-whitelist';
35
+ queryId: bigint | null;
36
+ address: Address;
37
+ } | {
38
+ type: 'single-nominator-withdraw';
39
+ queryId: bigint | null;
40
+ amount: bigint;
41
+ } | {
42
+ type: 'single-nominator-change-validator';
43
+ queryId: bigint | null;
44
+ address: Address;
45
+ } | {
46
+ type: 'tonstakers-deposit';
47
+ queryId: bigint | null;
48
+ appId: bigint | null;
49
+ } | {
50
+ type: 'vote-for-proposal';
51
+ queryId: bigint | null;
52
+ votingAddress: Address;
53
+ expirationDate: number;
54
+ vote: boolean;
55
+ needConfirmation: boolean;
56
+ } | {
57
+ type: 'change-dns-record';
58
+ queryId: bigint | null;
59
+ record: {
60
+ type: 'wallet';
61
+ value: {
62
+ address: Address;
63
+ capabilities: {
64
+ isWallet: boolean;
65
+ } | null;
66
+ } | null;
67
+ } | {
68
+ type: 'unknown';
69
+ key: Buffer;
70
+ value: Cell | null;
71
+ };
72
+ } | {
73
+ type: 'token-bridge-pay-swap';
74
+ queryId: bigint | null;
75
+ swapId: Buffer;
24
76
  };
77
+ export declare function parseMessage(cell: Cell, opts?: {
78
+ disallowUnsafe?: boolean;
79
+ disallowModification?: boolean;
80
+ encodeJettonBurnEthAddressAsHex?: boolean;
81
+ }): TonPayloadFormat | undefined;
25
82
  export type SignDataRequest = {
26
83
  type: 'plaintext';
27
84
  text: string;
@@ -82,5 +139,13 @@ export declare class TonTransport {
82
139
  amount: bigint;
83
140
  stateInit?: StateInit;
84
141
  payload?: TonPayloadFormat;
142
+ walletSpecifiers?: {
143
+ subwalletId?: number;
144
+ includeWalletOp: boolean;
145
+ };
85
146
  }) => Promise<Cell>;
147
+ getSettings(): Promise<{
148
+ blindSigningEnabled: boolean;
149
+ expertMode: boolean;
150
+ }>;
86
151
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TonTransport = void 0;
3
+ exports.TonTransport = exports.parseMessage = void 0;
4
4
  const core_1 = require("@ton/core");
5
5
  const crypto_1 = require("@ton/crypto");
6
6
  const teslabot_1 = require("teslabot");
@@ -13,6 +13,312 @@ const INS_ADDRESS = 0x05;
13
13
  const INS_SIGN_TX = 0x06;
14
14
  const INS_PROOF = 0x08;
15
15
  const INS_SIGN_DATA = 0x09;
16
+ const INS_SETTINGS = 0x0A;
17
+ const DEFAULT_SUBWALLET_ID = 698983191;
18
+ const dnsWalletKey = Buffer.from([0xe8, 0xd4, 0x40, 0x50, 0x87, 0x3d, 0xba, 0x86, 0x5a, 0xa7, 0xc1, 0x70, 0xab, 0x4c, 0xce, 0x64,
19
+ 0xd9, 0x08, 0x39, 0xa3, 0x4d, 0xcf, 0xd6, 0xcf, 0x71, 0xd1, 0x4e, 0x02, 0x05, 0x44, 0x3b, 0x1b]);
20
+ function normalizeQueryId(qid) {
21
+ return qid === 0n ? null : qid;
22
+ }
23
+ function parseMessage(cell, opts) {
24
+ const params = {
25
+ disallowUnsafe: false,
26
+ disallowModification: false,
27
+ encodeJettonBurnEthAddressAsHex: true,
28
+ ...opts,
29
+ };
30
+ if (cell.hash().equals(new core_1.Cell().hash())) {
31
+ return undefined;
32
+ }
33
+ let s = cell.beginParse();
34
+ try {
35
+ const op = s.loadUint(32);
36
+ switch (op) {
37
+ case 0: {
38
+ const str = s.loadStringTail();
39
+ s.endParse();
40
+ if (str.length > 120) {
41
+ throw new Error('Comment must be at most 120 ASCII characters long');
42
+ }
43
+ for (const c of str) {
44
+ if (c.charCodeAt(0) < 0x20 || c.charCodeAt(0) >= 0x7f) {
45
+ throw new Error('Comment must only contain printable ASCII characters');
46
+ }
47
+ }
48
+ return {
49
+ type: 'comment',
50
+ text: str,
51
+ };
52
+ }
53
+ case 0x0f8a7ea5: {
54
+ const queryId = normalizeQueryId(s.loadUintBig(64));
55
+ const amount = s.loadCoins();
56
+ const destination = s.loadAddress();
57
+ const responseDestination = s.loadAddress();
58
+ const customPayload = s.loadMaybeRef();
59
+ const forwardAmount = s.loadCoins();
60
+ let forwardPayload = null;
61
+ if (s.loadBit()) {
62
+ forwardPayload = s.loadRef();
63
+ }
64
+ else {
65
+ const p = s.asCell();
66
+ s = new core_1.Cell().beginParse(); // clear the slice
67
+ if (!p.hash().equals(new core_1.Cell().hash())) {
68
+ if (params.disallowModification) {
69
+ throw new Error('Jetton transfer message would be modified');
70
+ }
71
+ forwardPayload = p;
72
+ }
73
+ }
74
+ s.endParse();
75
+ return {
76
+ type: 'jetton-transfer',
77
+ queryId,
78
+ amount,
79
+ destination,
80
+ responseDestination,
81
+ customPayload,
82
+ forwardAmount,
83
+ forwardPayload,
84
+ };
85
+ }
86
+ case 0x5fcc3d14: {
87
+ const queryId = normalizeQueryId(s.loadUintBig(64));
88
+ const newOwner = s.loadAddress();
89
+ const responseDestination = s.loadAddress();
90
+ const customPayload = s.loadMaybeRef();
91
+ const forwardAmount = s.loadCoins();
92
+ let forwardPayload = null;
93
+ if (s.loadBit()) {
94
+ forwardPayload = s.loadRef();
95
+ }
96
+ else {
97
+ const p = s.asCell();
98
+ s = new core_1.Cell().beginParse(); // clear the slice
99
+ if (!p.hash().equals(new core_1.Cell().hash())) {
100
+ if (params.disallowModification) {
101
+ throw new Error('Jetton transfer message would be modified');
102
+ }
103
+ forwardPayload = p;
104
+ }
105
+ }
106
+ s.endParse();
107
+ return {
108
+ type: 'nft-transfer',
109
+ queryId,
110
+ newOwner,
111
+ responseDestination,
112
+ customPayload,
113
+ forwardAmount,
114
+ forwardPayload,
115
+ };
116
+ }
117
+ case 0x595f07bc: {
118
+ const queryId = normalizeQueryId(s.loadUintBig(64));
119
+ const amount = s.loadCoins();
120
+ const responseDestination = s.loadAddress();
121
+ let customPayload = s.loadMaybeRef();
122
+ s.endParse();
123
+ if (params.encodeJettonBurnEthAddressAsHex && customPayload !== null && customPayload.bits.length === 160 && customPayload.refs.length === 0) {
124
+ const cs = customPayload.beginParse();
125
+ customPayload = cs.loadBuffer(20);
126
+ cs.endParse();
127
+ }
128
+ return {
129
+ type: 'jetton-burn',
130
+ queryId,
131
+ amount,
132
+ responseDestination,
133
+ customPayload,
134
+ };
135
+ }
136
+ case 0x7258a69b: {
137
+ const queryId = normalizeQueryId(s.loadUintBig(64));
138
+ const address = s.loadAddress();
139
+ s.endParse();
140
+ return {
141
+ type: 'add-whitelist',
142
+ queryId,
143
+ address,
144
+ };
145
+ }
146
+ case 0x1000: {
147
+ const queryId = normalizeQueryId(s.loadUintBig(64));
148
+ const amount = s.loadCoins();
149
+ s.endParse();
150
+ return {
151
+ type: 'single-nominator-withdraw',
152
+ queryId,
153
+ amount,
154
+ };
155
+ }
156
+ case 0x1001: {
157
+ const queryId = normalizeQueryId(s.loadUintBig(64));
158
+ const address = s.loadAddress();
159
+ s.endParse();
160
+ return {
161
+ type: 'single-nominator-change-validator',
162
+ queryId,
163
+ address,
164
+ };
165
+ }
166
+ case 0x47d54391: {
167
+ const queryId = normalizeQueryId(s.loadUintBig(64));
168
+ let appId = null;
169
+ if (s.remainingBits > 0) {
170
+ appId = s.loadUintBig(64);
171
+ }
172
+ s.endParse();
173
+ return {
174
+ type: 'tonstakers-deposit',
175
+ queryId,
176
+ appId,
177
+ };
178
+ }
179
+ case 0x69fb306c: {
180
+ const queryId = normalizeQueryId(s.loadUintBig(64));
181
+ const votingAddress = s.loadAddress();
182
+ const expirationDate = s.loadUint(48);
183
+ const vote = s.loadBit();
184
+ const needConfirmation = s.loadBit();
185
+ s.endParse();
186
+ return {
187
+ type: 'vote-for-proposal',
188
+ queryId,
189
+ votingAddress,
190
+ expirationDate,
191
+ vote,
192
+ needConfirmation,
193
+ };
194
+ }
195
+ case 0x4eb1f0f9: {
196
+ const queryId = normalizeQueryId(s.loadUintBig(64));
197
+ const key = s.loadBuffer(32);
198
+ if (key.equals(dnsWalletKey)) {
199
+ if (s.remainingRefs > 0) {
200
+ const vs = s.loadRef().beginParse();
201
+ if (s.remainingBits > 0 && !params.disallowModification) {
202
+ // tolerate the Maybe bit
203
+ if (!s.loadBit())
204
+ throw new Error('Incorrect change DNS record message');
205
+ }
206
+ s.endParse();
207
+ const type = vs.loadUint(16);
208
+ if (type !== 0x9fd3) {
209
+ throw new Error('Wrong DNS record type');
210
+ }
211
+ const address = vs.loadAddress();
212
+ const flags = vs.loadUint(8);
213
+ if (flags > 1) {
214
+ throw new Error('DNS wallet record must have flags 0 or 1');
215
+ }
216
+ let capabilities = (flags & 1) > 0 ? { isWallet: false } : null;
217
+ if (capabilities !== null) {
218
+ while (vs.loadBit()) {
219
+ const cap = vs.loadUint(16);
220
+ if (cap === 0x2177) {
221
+ if (capabilities.isWallet && params.disallowModification) {
222
+ throw new Error('DNS change record message would be modified');
223
+ }
224
+ capabilities.isWallet = true;
225
+ }
226
+ else {
227
+ throw new Error('Unknown DNS wallet record capability');
228
+ }
229
+ }
230
+ }
231
+ return {
232
+ type: 'change-dns-record',
233
+ queryId,
234
+ record: {
235
+ type: 'wallet',
236
+ value: {
237
+ address,
238
+ capabilities,
239
+ },
240
+ },
241
+ };
242
+ }
243
+ else {
244
+ if (s.remainingBits > 0 && !params.disallowModification) {
245
+ // tolerate the Maybe bit
246
+ if (s.loadBit())
247
+ throw new Error('Incorrect change DNS record message');
248
+ }
249
+ s.endParse();
250
+ return {
251
+ type: 'change-dns-record',
252
+ queryId,
253
+ record: {
254
+ type: 'wallet',
255
+ value: null,
256
+ },
257
+ };
258
+ }
259
+ }
260
+ else {
261
+ if (s.remainingRefs > 0) {
262
+ const value = s.loadRef();
263
+ if (s.remainingBits > 0 && !params.disallowModification) {
264
+ // tolerate the Maybe bit
265
+ if (!s.loadBit())
266
+ throw new Error('Incorrect change DNS record message');
267
+ }
268
+ s.endParse();
269
+ return {
270
+ type: 'change-dns-record',
271
+ queryId,
272
+ record: {
273
+ type: 'unknown',
274
+ key,
275
+ value,
276
+ },
277
+ };
278
+ }
279
+ else {
280
+ if (s.remainingBits > 0 && !params.disallowModification) {
281
+ // tolerate the Maybe bit
282
+ if (s.loadBit())
283
+ throw new Error('Incorrect change DNS record message');
284
+ }
285
+ s.endParse();
286
+ return {
287
+ type: 'change-dns-record',
288
+ queryId,
289
+ record: {
290
+ type: 'unknown',
291
+ key,
292
+ value: null,
293
+ },
294
+ };
295
+ }
296
+ }
297
+ }
298
+ case 0x8: {
299
+ const queryId = normalizeQueryId(s.loadUintBig(64));
300
+ const swapId = s.loadBuffer(32);
301
+ s.endParse();
302
+ return {
303
+ type: 'token-bridge-pay-swap',
304
+ queryId,
305
+ swapId,
306
+ };
307
+ }
308
+ }
309
+ throw new Error('Unknown op: ' + op);
310
+ }
311
+ catch (e) {
312
+ if (params.disallowUnsafe) {
313
+ throw e;
314
+ }
315
+ }
316
+ return {
317
+ type: 'unsafe',
318
+ message: cell,
319
+ };
320
+ }
321
+ exports.parseMessage = parseMessage;
16
322
  function chunks(buf, n) {
17
323
  const nc = Math.ceil(buf.length / n);
18
324
  const cs = [];
@@ -34,6 +340,330 @@ function processAddressFlags(opts) {
34
340
  }
35
341
  return { bounceable, testOnly, chain, flags };
36
342
  }
343
+ function convertPayload(input) {
344
+ let payload = null;
345
+ let hints = Buffer.concat([(0, ledgerWriter_1.writeUint8)(0)]);
346
+ if (input === undefined) {
347
+ return {
348
+ payload,
349
+ hints,
350
+ };
351
+ }
352
+ switch (input.type) {
353
+ case 'unsafe': {
354
+ payload = input.message;
355
+ break;
356
+ }
357
+ case 'comment': {
358
+ hints = Buffer.concat([
359
+ (0, ledgerWriter_1.writeUint8)(1),
360
+ (0, ledgerWriter_1.writeUint32)(0x00),
361
+ (0, ledgerWriter_1.writeUint16)(Buffer.from(input.text).length),
362
+ Buffer.from(input.text)
363
+ ]);
364
+ payload = (0, core_1.beginCell)()
365
+ .storeUint(0, 32)
366
+ .storeBuffer(Buffer.from(input.text))
367
+ .endCell();
368
+ break;
369
+ }
370
+ case 'jetton-transfer':
371
+ case 'nft-transfer': {
372
+ hints = Buffer.concat([
373
+ (0, ledgerWriter_1.writeUint8)(1),
374
+ (0, ledgerWriter_1.writeUint32)(input.type === 'jetton-transfer' ? 0x01 : 0x02)
375
+ ]);
376
+ let b = (0, core_1.beginCell)()
377
+ .storeUint(input.type === 'jetton-transfer' ? 0x0f8a7ea5 : 0x5fcc3d14, 32);
378
+ let d = Buffer.alloc(0);
379
+ if (input.queryId !== null) {
380
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(input.queryId)]);
381
+ b = b.storeUint(input.queryId, 64);
382
+ }
383
+ else {
384
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
385
+ b = b.storeUint(0, 64);
386
+ }
387
+ if (input.type === 'jetton-transfer') {
388
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeVarUInt)(input.amount)]);
389
+ b = b.storeCoins(input.amount);
390
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(input.destination)]);
391
+ b = b.storeAddress(input.destination);
392
+ }
393
+ else {
394
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(input.newOwner)]);
395
+ b = b.storeAddress(input.newOwner);
396
+ }
397
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(input.responseDestination)]);
398
+ b = b.storeAddress(input.responseDestination);
399
+ if (input.customPayload !== null) {
400
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeCellRef)(input.customPayload)]);
401
+ b = b.storeMaybeRef(input.customPayload);
402
+ }
403
+ else {
404
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
405
+ b = b.storeMaybeRef(input.customPayload);
406
+ }
407
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeVarUInt)(input.forwardAmount)]);
408
+ b = b.storeCoins(input.forwardAmount);
409
+ if (input.forwardPayload !== null) {
410
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeCellRef)(input.forwardPayload)]);
411
+ b = b.storeMaybeRef(input.forwardPayload);
412
+ }
413
+ else {
414
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
415
+ b = b.storeMaybeRef(input.forwardPayload);
416
+ }
417
+ payload = b.endCell();
418
+ hints = Buffer.concat([
419
+ hints,
420
+ (0, ledgerWriter_1.writeUint16)(d.length),
421
+ d
422
+ ]);
423
+ break;
424
+ }
425
+ case 'jetton-burn': {
426
+ hints = Buffer.concat([
427
+ (0, ledgerWriter_1.writeUint8)(1),
428
+ (0, ledgerWriter_1.writeUint32)(0x03)
429
+ ]);
430
+ let b = (0, core_1.beginCell)()
431
+ .storeUint(0x595f07bc, 32);
432
+ let d = Buffer.alloc(0);
433
+ if (input.queryId !== null) {
434
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(input.queryId)]);
435
+ b = b.storeUint(input.queryId, 64);
436
+ }
437
+ else {
438
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
439
+ b = b.storeUint(0, 64);
440
+ }
441
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeVarUInt)(input.amount)]);
442
+ b = b.storeCoins(input.amount);
443
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(input.responseDestination)]);
444
+ b = b.storeAddress(input.responseDestination);
445
+ if (input.customPayload === null) {
446
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
447
+ b = b.storeMaybeRef(input.customPayload);
448
+ }
449
+ else if (input.customPayload instanceof core_1.Cell) {
450
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeCellRef)(input.customPayload)]);
451
+ b = b.storeMaybeRef(input.customPayload);
452
+ }
453
+ else {
454
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(2), (0, ledgerWriter_1.writeCellInline)(input.customPayload)]);
455
+ b = b.storeMaybeRef((0, core_1.beginCell)().storeBuffer(input.customPayload).endCell());
456
+ }
457
+ payload = b.endCell();
458
+ hints = Buffer.concat([
459
+ hints,
460
+ (0, ledgerWriter_1.writeUint16)(d.length),
461
+ d
462
+ ]);
463
+ break;
464
+ }
465
+ case 'add-whitelist':
466
+ case 'single-nominator-change-validator': {
467
+ hints = Buffer.concat([
468
+ (0, ledgerWriter_1.writeUint8)(1),
469
+ (0, ledgerWriter_1.writeUint32)(input.type === 'add-whitelist' ? 0x04 : 0x06)
470
+ ]);
471
+ let b = (0, core_1.beginCell)()
472
+ .storeUint(input.type === 'add-whitelist' ? 0x7258a69b : 0x1001, 32);
473
+ let d = Buffer.alloc(0);
474
+ if (input.queryId !== null) {
475
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(input.queryId)]);
476
+ b = b.storeUint(input.queryId, 64);
477
+ }
478
+ else {
479
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
480
+ b = b.storeUint(0, 64);
481
+ }
482
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(input.address)]);
483
+ b = b.storeAddress(input.address);
484
+ payload = b.endCell();
485
+ hints = Buffer.concat([
486
+ hints,
487
+ (0, ledgerWriter_1.writeUint16)(d.length),
488
+ d
489
+ ]);
490
+ break;
491
+ }
492
+ case 'single-nominator-withdraw': {
493
+ hints = Buffer.concat([
494
+ (0, ledgerWriter_1.writeUint8)(1),
495
+ (0, ledgerWriter_1.writeUint32)(0x05)
496
+ ]);
497
+ let b = (0, core_1.beginCell)()
498
+ .storeUint(0x1000, 32);
499
+ let d = Buffer.alloc(0);
500
+ if (input.queryId !== null) {
501
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(input.queryId)]);
502
+ b = b.storeUint(input.queryId, 64);
503
+ }
504
+ else {
505
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
506
+ b = b.storeUint(0, 64);
507
+ }
508
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeVarUInt)(input.amount)]);
509
+ b = b.storeCoins(input.amount);
510
+ payload = b.endCell();
511
+ hints = Buffer.concat([
512
+ hints,
513
+ (0, ledgerWriter_1.writeUint16)(d.length),
514
+ d
515
+ ]);
516
+ break;
517
+ }
518
+ case 'tonstakers-deposit': {
519
+ hints = Buffer.concat([
520
+ (0, ledgerWriter_1.writeUint8)(1),
521
+ (0, ledgerWriter_1.writeUint32)(0x07)
522
+ ]);
523
+ let b = (0, core_1.beginCell)()
524
+ .storeUint(0x47d54391, 32);
525
+ let d = Buffer.alloc(0);
526
+ if (input.queryId !== null) {
527
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(input.queryId)]);
528
+ b = b.storeUint(input.queryId, 64);
529
+ }
530
+ else {
531
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
532
+ b = b.storeUint(0, 64);
533
+ }
534
+ if (input.appId !== null) {
535
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(input.appId)]);
536
+ b = b.storeUint(input.appId, 64);
537
+ }
538
+ else {
539
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
540
+ }
541
+ payload = b.endCell();
542
+ hints = Buffer.concat([
543
+ hints,
544
+ (0, ledgerWriter_1.writeUint16)(d.length),
545
+ d
546
+ ]);
547
+ break;
548
+ }
549
+ case 'vote-for-proposal': {
550
+ hints = Buffer.concat([
551
+ (0, ledgerWriter_1.writeUint8)(1),
552
+ (0, ledgerWriter_1.writeUint32)(0x08)
553
+ ]);
554
+ let b = (0, core_1.beginCell)()
555
+ .storeUint(0x69fb306c, 32);
556
+ let d = Buffer.alloc(0);
557
+ if (input.queryId !== null) {
558
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(input.queryId)]);
559
+ b = b.storeUint(input.queryId, 64);
560
+ }
561
+ else {
562
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
563
+ b = b.storeUint(0, 64);
564
+ }
565
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(input.votingAddress)]);
566
+ b = b.storeAddress(input.votingAddress);
567
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint48)(input.expirationDate)]);
568
+ b = b.storeUint(input.expirationDate, 48);
569
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(input.vote ? 1 : 0), (0, ledgerWriter_1.writeUint8)(input.needConfirmation ? 1 : 0)]);
570
+ b = b.storeBit(input.vote).storeBit(input.needConfirmation);
571
+ payload = b.endCell();
572
+ hints = Buffer.concat([
573
+ hints,
574
+ (0, ledgerWriter_1.writeUint16)(d.length),
575
+ d
576
+ ]);
577
+ break;
578
+ }
579
+ case 'change-dns-record': {
580
+ hints = Buffer.concat([
581
+ (0, ledgerWriter_1.writeUint8)(1),
582
+ (0, ledgerWriter_1.writeUint32)(0x09)
583
+ ]);
584
+ let b = (0, core_1.beginCell)()
585
+ .storeUint(0x4eb1f0f9, 32);
586
+ let d = Buffer.alloc(0);
587
+ if (input.queryId !== null) {
588
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(input.queryId)]);
589
+ b = b.storeUint(input.queryId, 64);
590
+ }
591
+ else {
592
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
593
+ b = b.storeUint(0, 64);
594
+ }
595
+ if (input.record.type === 'unknown' && input.record.key.length !== 32) {
596
+ throw new Error('DNS record key length must be 32 bytes long');
597
+ }
598
+ b = b.storeBuffer(input.record.type === 'wallet' ? (0, crypto_1.sha256_sync)('wallet') : input.record.key);
599
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(input.record.value === null ? 0 : 1), (0, ledgerWriter_1.writeUint8)(input.record.type === 'wallet' ? 0 : 1)]);
600
+ if (input.record.type === 'wallet') {
601
+ if (input.record.value !== null) {
602
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(input.record.value.address), (0, ledgerWriter_1.writeUint8)(input.record.value.capabilities === null ? 0 : 1)]);
603
+ let rb = (0, core_1.beginCell)().storeUint(0x9fd3, 16).storeAddress(input.record.value.address).storeUint(input.record.value.capabilities === null ? 0 : 1, 8);
604
+ if (input.record.value.capabilities !== null) {
605
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(input.record.value.capabilities.isWallet ? 1 : 0)]);
606
+ if (input.record.value.capabilities.isWallet) {
607
+ rb = rb.storeBit(true).storeUint(0x2177, 16);
608
+ }
609
+ rb = rb.storeBit(false);
610
+ }
611
+ b = b.storeRef(rb);
612
+ }
613
+ }
614
+ else {
615
+ d = Buffer.concat([d, input.record.key]);
616
+ if (input.record.value !== null) {
617
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeCellRef)(input.record.value)]);
618
+ b = b.storeRef(input.record.value);
619
+ }
620
+ }
621
+ payload = b.endCell();
622
+ hints = Buffer.concat([
623
+ hints,
624
+ (0, ledgerWriter_1.writeUint16)(d.length),
625
+ d
626
+ ]);
627
+ break;
628
+ }
629
+ case 'token-bridge-pay-swap': {
630
+ hints = Buffer.concat([
631
+ (0, ledgerWriter_1.writeUint8)(1),
632
+ (0, ledgerWriter_1.writeUint32)(0x0A)
633
+ ]);
634
+ let b = (0, core_1.beginCell)()
635
+ .storeUint(8, 32);
636
+ let d = Buffer.alloc(0);
637
+ if (input.queryId !== null) {
638
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(input.queryId)]);
639
+ b = b.storeUint(input.queryId, 64);
640
+ }
641
+ else {
642
+ d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
643
+ b = b.storeUint(0, 64);
644
+ }
645
+ if (input.swapId.length !== 32) {
646
+ throw new Error('Token bridge swap ID must be 32 bytes long');
647
+ }
648
+ d = Buffer.concat([d, input.swapId]);
649
+ b = b.storeBuffer(input.swapId);
650
+ payload = b.endCell();
651
+ hints = Buffer.concat([
652
+ hints,
653
+ (0, ledgerWriter_1.writeUint16)(d.length),
654
+ d
655
+ ]);
656
+ break;
657
+ }
658
+ default: {
659
+ throw new Error('Unknown payload type: ' + input.type);
660
+ }
661
+ }
662
+ return {
663
+ payload,
664
+ hints,
665
+ };
666
+ }
37
667
  class TonTransport {
38
668
  transport;
39
669
  #lock = new teslabot_1.AsyncLock();
@@ -224,7 +854,17 @@ class TonTransport {
224
854
  // Create package
225
855
  //
226
856
  let pkg = Buffer.concat([
227
- (0, ledgerWriter_1.writeUint8)(0),
857
+ (0, ledgerWriter_1.writeUint8)(transaction.walletSpecifiers === undefined ? 0 : 1), // tag
858
+ ]);
859
+ if (transaction.walletSpecifiers !== undefined) {
860
+ pkg = Buffer.concat([
861
+ pkg,
862
+ (0, ledgerWriter_1.writeUint32)(transaction.walletSpecifiers.subwalletId ?? DEFAULT_SUBWALLET_ID),
863
+ (0, ledgerWriter_1.writeUint8)(transaction.walletSpecifiers.includeWalletOp ? 1 : 0),
864
+ ]);
865
+ }
866
+ pkg = Buffer.concat([
867
+ pkg,
228
868
  (0, ledgerWriter_1.writeUint32)(transaction.seqno),
229
869
  (0, ledgerWriter_1.writeUint32)(transaction.timeout),
230
870
  (0, ledgerWriter_1.writeVarUInt)(transaction.amount),
@@ -256,78 +896,7 @@ class TonTransport {
256
896
  //
257
897
  // Payload
258
898
  //
259
- let payload = null;
260
- let hints = Buffer.concat([(0, ledgerWriter_1.writeUint8)(0)]);
261
- if (transaction.payload) {
262
- if (transaction.payload.type === 'comment') {
263
- hints = Buffer.concat([
264
- (0, ledgerWriter_1.writeUint8)(1),
265
- (0, ledgerWriter_1.writeUint32)(0x00),
266
- (0, ledgerWriter_1.writeUint16)(Buffer.from(transaction.payload.text).length),
267
- Buffer.from(transaction.payload.text)
268
- ]);
269
- payload = (0, core_1.beginCell)()
270
- .storeUint(0, 32)
271
- .storeBuffer(Buffer.from(transaction.payload.text))
272
- .endCell();
273
- }
274
- else if (transaction.payload.type === 'jetton-transfer' || transaction.payload.type === 'nft-transfer') {
275
- hints = Buffer.concat([
276
- (0, ledgerWriter_1.writeUint8)(1),
277
- (0, ledgerWriter_1.writeUint32)(transaction.payload.type === 'jetton-transfer' ? 0x01 : 0x02)
278
- ]);
279
- let b = (0, core_1.beginCell)()
280
- .storeUint(transaction.payload.type === 'jetton-transfer' ? 0x0f8a7ea5 : 0x5fcc3d14, 32);
281
- let d = Buffer.alloc(0);
282
- if (transaction.payload.queryId !== null) {
283
- d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeUint64)(transaction.payload.queryId)]);
284
- b = b.storeUint(transaction.payload.queryId, 64);
285
- }
286
- else {
287
- d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
288
- b = b.storeUint(0, 64);
289
- }
290
- if (transaction.payload.type === 'jetton-transfer') {
291
- d = Buffer.concat([d, (0, ledgerWriter_1.writeVarUInt)(transaction.payload.amount)]);
292
- b = b.storeCoins(transaction.payload.amount);
293
- d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(transaction.payload.destination)]);
294
- b = b.storeAddress(transaction.payload.destination);
295
- }
296
- else {
297
- d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(transaction.payload.newOwner)]);
298
- b = b.storeAddress(transaction.payload.newOwner);
299
- }
300
- d = Buffer.concat([d, (0, ledgerWriter_1.writeAddress)(transaction.payload.responseDestination)]);
301
- b = b.storeAddress(transaction.payload.responseDestination);
302
- if (transaction.payload.customPayload !== null) {
303
- d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeCellRef)(transaction.payload.customPayload)]);
304
- b = b.storeMaybeRef(transaction.payload.customPayload);
305
- }
306
- else {
307
- d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
308
- b = b.storeMaybeRef(transaction.payload.customPayload);
309
- }
310
- d = Buffer.concat([d, (0, ledgerWriter_1.writeVarUInt)(transaction.payload.forwardAmount)]);
311
- b = b.storeCoins(transaction.payload.forwardAmount);
312
- if (transaction.payload.forwardPayload !== null) {
313
- d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(1), (0, ledgerWriter_1.writeCellRef)(transaction.payload.forwardPayload)]);
314
- b = b.storeMaybeRef(transaction.payload.forwardPayload);
315
- }
316
- else {
317
- d = Buffer.concat([d, (0, ledgerWriter_1.writeUint8)(0)]);
318
- b = b.storeMaybeRef(transaction.payload.forwardPayload);
319
- }
320
- payload = b.endCell();
321
- hints = Buffer.concat([
322
- hints,
323
- (0, ledgerWriter_1.writeUint16)(d.length),
324
- d
325
- ]);
326
- }
327
- }
328
- //
329
- // Serialize payload
330
- //
899
+ const { payload, hints } = convertPayload(transaction.payload);
331
900
  if (payload) {
332
901
  pkg = Buffer.concat([
333
902
  pkg,
@@ -391,12 +960,14 @@ class TonTransport {
391
960
  .storeBit(false);
392
961
  }
393
962
  // Transfer message
394
- let transfer = (0, core_1.beginCell)()
395
- .storeUint(698983191, 32)
963
+ let transferB = (0, core_1.beginCell)()
964
+ .storeUint(transaction.walletSpecifiers?.subwalletId ?? DEFAULT_SUBWALLET_ID, 32)
396
965
  .storeUint(transaction.timeout, 32)
397
- .storeUint(transaction.seqno, 32)
398
- .storeUint(0, 8)
399
- .storeUint(transaction.sendMode, 8)
966
+ .storeUint(transaction.seqno, 32);
967
+ if (transaction.walletSpecifiers?.includeWalletOp ?? true) {
968
+ transferB = transferB.storeUint(0, 8);
969
+ }
970
+ let transfer = transferB.storeUint(transaction.sendMode, 8)
400
971
  .storeRef(orderBuilder.endCell())
401
972
  .endCell();
402
973
  // Parse result
@@ -414,6 +985,13 @@ class TonTransport {
414
985
  .storeSlice(transfer.beginParse())
415
986
  .endCell();
416
987
  };
988
+ async getSettings() {
989
+ let loaded = await this.#doRequest(INS_SETTINGS, 0x00, 0x00, Buffer.alloc(0));
990
+ return {
991
+ blindSigningEnabled: (loaded[0] & 0x01) > 0,
992
+ expertMode: (loaded[0] & 0x02) > 0,
993
+ };
994
+ }
417
995
  #doRequest = async (ins, p1, p2, data) => {
418
996
  return this.#lock.inLock(async () => {
419
997
  let r = await this.transport.send(LEDGER_CLA, ins, p1, p2, data);
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { TonPayloadFormat, TonTransport, SignDataRequest } from './TonTransport';
1
+ export { TonPayloadFormat, TonTransport, SignDataRequest, parseMessage } from './TonTransport';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TonTransport = void 0;
3
+ exports.parseMessage = exports.TonTransport = void 0;
4
4
  var TonTransport_1 = require("./TonTransport");
5
5
  Object.defineProperty(exports, "TonTransport", { enumerable: true, get: function () { return TonTransport_1.TonTransport; } });
6
+ Object.defineProperty(exports, "parseMessage", { enumerable: true, get: function () { return TonTransport_1.parseMessage; } });
@@ -2,8 +2,10 @@
2
2
  import { Address, Cell } from '@ton/core';
3
3
  export declare function writeUint32(value: number): Buffer;
4
4
  export declare function writeUint16(value: number): Buffer;
5
+ export declare function writeUint48(value: number): Buffer;
5
6
  export declare function writeUint64(value: bigint): Buffer;
6
7
  export declare function writeVarUInt(value: bigint): Buffer;
7
8
  export declare function writeUint8(value: number): Buffer;
8
9
  export declare function writeAddress(address: Address): Buffer;
9
10
  export declare function writeCellRef(ref: Cell): Buffer;
11
+ export declare function writeCellInline(bytes: Buffer): Buffer;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.writeCellRef = exports.writeAddress = exports.writeUint8 = exports.writeVarUInt = exports.writeUint64 = exports.writeUint16 = exports.writeUint32 = void 0;
3
+ exports.writeCellInline = exports.writeCellRef = exports.writeAddress = exports.writeUint8 = exports.writeVarUInt = exports.writeUint64 = exports.writeUint48 = exports.writeUint16 = exports.writeUint32 = void 0;
4
4
  const core_1 = require("@ton/core");
5
5
  function writeUint32(value) {
6
6
  let b = Buffer.alloc(4);
@@ -14,6 +14,13 @@ function writeUint16(value) {
14
14
  return b;
15
15
  }
16
16
  exports.writeUint16 = writeUint16;
17
+ function writeUint48(value) {
18
+ let b = Buffer.alloc(6);
19
+ b.writeUint16BE(value >> 32, 0);
20
+ b.writeUint32BE(value & ((1 << 32) - 1), 2);
21
+ return b;
22
+ }
23
+ exports.writeUint48 = writeUint48;
17
24
  function writeUint64(value) {
18
25
  return (0, core_1.beginCell)().storeUint(value, 64).endCell().beginParse().loadBuffer(8);
19
26
  }
@@ -43,3 +50,10 @@ function writeCellRef(ref) {
43
50
  ]);
44
51
  }
45
52
  exports.writeCellRef = writeCellRef;
53
+ function writeCellInline(bytes) {
54
+ return Buffer.concat([
55
+ writeUint8(bytes.length),
56
+ bytes,
57
+ ]);
58
+ }
59
+ exports.writeCellInline = writeCellInline;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ton-community/ton-ledger",
3
- "version": "7.0.1",
3
+ "version": "7.1.0-pre.1",
4
4
  "repository": "https://github.com/ton-community/ton-ledger-ts",
5
5
  "author": "Steve Korshakov <steve@korshakov.com>",
6
6
  "license": "MIT",