@ledgerhq/live-common 21.36.3 → 21.36.4

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 (39) hide show
  1. package/lib/bridge/jsHelpers.d.ts.map +1 -1
  2. package/lib/bridge/jsHelpers.js +245 -238
  3. package/lib/bridge/jsHelpers.js.map +1 -1
  4. package/lib/families/bitcoin/js-signOperation.d.ts.map +1 -1
  5. package/lib/families/bitcoin/js-signOperation.js +139 -130
  6. package/lib/families/bitcoin/js-signOperation.js.map +1 -1
  7. package/lib/families/bitcoin/wallet-btc/storage/index.d.ts.map +1 -1
  8. package/lib/families/bitcoin/wallet-btc/storage/index.js +1 -2
  9. package/lib/families/bitcoin/wallet-btc/storage/index.js.map +1 -1
  10. package/lib/families/crypto_org/js-signOperation.d.ts.map +1 -1
  11. package/lib/families/crypto_org/js-signOperation.js +62 -55
  12. package/lib/families/crypto_org/js-signOperation.js.map +1 -1
  13. package/lib/families/elrond/js-signOperation.d.ts.map +1 -1
  14. package/lib/families/elrond/js-signOperation.js +50 -43
  15. package/lib/families/elrond/js-signOperation.js.map +1 -1
  16. package/lib/families/polkadot/js-signOperation.d.ts.map +1 -1
  17. package/lib/families/polkadot/js-signOperation.js +61 -54
  18. package/lib/families/polkadot/js-signOperation.js.map +1 -1
  19. package/lib/families/ripple/bridge/js.d.ts.map +1 -1
  20. package/lib/families/ripple/bridge/js.js +313 -299
  21. package/lib/families/ripple/bridge/js.js.map +1 -1
  22. package/lib/families/stellar/js-signOperation.d.ts.map +1 -1
  23. package/lib/families/stellar/js-signOperation.js +51 -44
  24. package/lib/families/stellar/js-signOperation.js.map +1 -1
  25. package/lib/families/tron/bridge/js.d.ts.map +1 -1
  26. package/lib/families/tron/bridge/js.js +167 -159
  27. package/lib/families/tron/bridge/js.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/bridge/jsHelpers.ts +213 -213
  30. package/src/families/bitcoin/js-signOperation.ts +17 -14
  31. package/src/families/bitcoin/wallet-btc/storage/index.ts +1 -4
  32. package/src/families/crypto_org/js-signOperation.ts +16 -12
  33. package/src/families/elrond/js-signOperation.ts +14 -10
  34. package/src/families/polkadot/js-signOperation.ts +61 -61
  35. package/src/families/ripple/bridge/js.ts +260 -257
  36. package/src/families/stellar/js-signOperation.ts +14 -10
  37. package/src/families/tron/bridge/js.ts +58 -57
  38. package/src/.DS_Store +0 -0
  39. package/src/data/flags/.DS_Store +0 -0
@@ -32,7 +32,7 @@ import {
32
32
  emptyHistoryCache,
33
33
  } from "../../../account";
34
34
  import getAddress from "../../../hw/getAddress";
35
- import { withDevice } from "../../../hw/deviceAccess";
35
+ import { open, close } from "../../../hw";
36
36
  import {
37
37
  parseAPIValue,
38
38
  parseAPICurrencyObject,
@@ -89,104 +89,106 @@ const signOperation = ({
89
89
  transaction,
90
90
  deviceId,
91
91
  }): Observable<SignOperationEvent> =>
92
- withDevice(deviceId)(
93
- (transport) =>
94
- new Observable((o) => {
95
- delete cacheRecipientsNew[transaction.recipient];
96
- const { fee } = transaction;
97
- if (!fee) throw new FeeNotLoaded();
98
-
99
- async function main() {
100
- const amount = formatAPICurrencyXRP(transaction.amount);
101
- const tag = transaction.tag ? transaction.tag : undefined;
102
- const payment = {
103
- source: {
104
- address: account.freshAddress,
105
- amount,
106
- },
107
- destination: {
108
- address: transaction.recipient,
109
- minAmount: amount,
110
- tag,
111
- },
112
- };
113
- const instruction = {
114
- fee: formatAPICurrencyXRP(fee).value,
115
- maxLedgerVersionOffset: 12,
116
- };
117
- if (tag)
118
- invariant(
119
- validateTag(new BigNumber(tag)),
120
- `tag is set but is not in a valid format, should be between [0 - ${uint32maxPlus1
121
- .minus(1)
122
- .toString()}]`
123
- );
124
- const prepared = await preparePayment(
125
- account.freshAddress,
126
- payment,
127
- instruction
92
+ new Observable((o) => {
93
+ delete cacheRecipientsNew[transaction.recipient];
94
+ const { fee } = transaction;
95
+ if (!fee) throw new FeeNotLoaded();
96
+
97
+ async function main() {
98
+ try {
99
+ const amount = formatAPICurrencyXRP(transaction.amount);
100
+ const tag = transaction.tag ? transaction.tag : undefined;
101
+ const payment = {
102
+ source: {
103
+ address: account.freshAddress,
104
+ amount,
105
+ },
106
+ destination: {
107
+ address: transaction.recipient,
108
+ minAmount: amount,
109
+ tag,
110
+ },
111
+ };
112
+ const instruction = {
113
+ fee: formatAPICurrencyXRP(fee).value,
114
+ maxLedgerVersionOffset: 12,
115
+ };
116
+ if (tag)
117
+ invariant(
118
+ validateTag(new BigNumber(tag)),
119
+ `tag is set but is not in a valid format, should be between [0 - ${uint32maxPlus1
120
+ .minus(1)
121
+ .toString()}]`
128
122
  );
129
- let signature;
123
+ const prepared = await preparePayment(
124
+ account.freshAddress,
125
+ payment,
126
+ instruction
127
+ );
128
+ let signature;
129
+ const transport = await open(deviceId);
130
130
 
131
- try {
132
- o.next({
133
- type: "device-signature-requested",
134
- });
135
- signature = await signTransaction(
136
- account.currency,
137
- transport,
138
- account.freshAddressPath,
139
- JSON.parse(prepared.txJSON)
140
- );
141
- o.next({
142
- type: "device-signature-granted",
143
- });
131
+ try {
132
+ o.next({
133
+ type: "device-signature-requested",
134
+ });
135
+ signature = await signTransaction(
136
+ account.currency,
137
+ transport,
138
+ account.freshAddressPath,
139
+ JSON.parse(prepared.txJSON)
140
+ );
141
+ o.next({
142
+ type: "device-signature-granted",
143
+ });
144
+ } finally {
145
+ close(transport, deviceId);
146
+ }
144
147
 
145
- const hash = "";
146
- const operation: Operation = {
147
- id: `${account.id}-${hash}-OUT`,
148
- hash,
149
- accountId: account.id,
150
- type: "OUT",
151
- value: transaction.amount,
152
- fee,
153
- blockHash: null,
154
- blockHeight: null,
155
- senders: [account.freshAddress],
156
- recipients: [transaction.recipient],
157
- date: new Date(),
158
- // we probably can't get it so it's a predictive value
159
- transactionSequenceNumber: await getSequenceNumber(account),
160
- extra: {} as any,
161
- };
162
-
163
- if (transaction.tag) {
164
- operation.extra.tag = transaction.tag;
165
- }
148
+ const hash = "";
149
+ const operation: Operation = {
150
+ id: `${account.id}-${hash}-OUT`,
151
+ hash,
152
+ accountId: account.id,
153
+ type: "OUT",
154
+ value: transaction.amount,
155
+ fee,
156
+ blockHash: null,
157
+ blockHeight: null,
158
+ senders: [account.freshAddress],
159
+ recipients: [transaction.recipient],
160
+ date: new Date(),
161
+ // we probably can't get it so it's a predictive value
162
+ transactionSequenceNumber: await getSequenceNumber(account),
163
+ extra: {} as any,
164
+ };
166
165
 
167
- o.next({
168
- type: "signed",
169
- signedOperation: {
170
- operation,
171
- signature,
172
- expirationDate: null,
173
- },
174
- });
175
- } catch (e: any) {
176
- if (e && e.name === "RippledError" && e.data.resultMessage) {
177
- throw new Error(e.data.resultMessage);
178
- }
166
+ if (transaction.tag) {
167
+ operation.extra.tag = transaction.tag;
168
+ }
179
169
 
180
- throw e;
181
- }
170
+ o.next({
171
+ type: "signed",
172
+ signedOperation: {
173
+ operation,
174
+ signature,
175
+ expirationDate: null,
176
+ },
177
+ });
178
+ } catch (e: any) {
179
+ if (e && e.name === "RippledError" && e.data.resultMessage) {
180
+ throw new Error(e.data.resultMessage);
182
181
  }
183
182
 
184
- main().then(
185
- () => o.complete(),
186
- (e) => o.error(e)
187
- );
188
- })
189
- );
183
+ throw e;
184
+ }
185
+ }
186
+
187
+ main().then(
188
+ () => o.complete(),
189
+ (e) => o.error(e)
190
+ );
191
+ });
190
192
 
191
193
  const broadcast = async ({ signedOperation: { signature, operation } }) => {
192
194
  const submittedPayment = await submit(signature);
@@ -358,184 +360,185 @@ const currencyBridge: CurrencyBridge = {
358
360
  preload: () => Promise.resolve({}),
359
361
  hydrate: () => {},
360
362
  scanAccounts: ({ currency, deviceId }) =>
361
- withDevice(deviceId)(
362
- (transport) =>
363
- new Observable((o) => {
364
- let finished = false;
363
+ new Observable((o) => {
364
+ let finished = false;
365
365
 
366
- const unsubscribe = () => {
367
- finished = true;
368
- };
366
+ const unsubscribe = () => {
367
+ finished = true;
368
+ };
369
369
 
370
- async function main() {
371
- try {
372
- const serverInfo = await getServerInfo();
373
- const ledgers = serverInfo.completeLedgers.split("-");
374
- const minLedgerVersion = Number(ledgers[0]);
375
- const maxLedgerVersion = Number(ledgers[1]);
376
- const derivationModes = getDerivationModesForCurrency(currency);
370
+ async function main() {
371
+ let transport;
377
372
 
378
- for (const derivationMode of derivationModes) {
379
- const derivationScheme = getDerivationScheme({
380
- derivationMode,
381
- currency,
382
- });
383
- const stopAt = isIterableDerivationMode(derivationMode)
384
- ? 255
385
- : 1;
386
-
387
- for (let index = 0; index < stopAt; index++) {
388
- if (!derivationModeSupportsIndex(derivationMode, index))
389
- continue;
390
- const freshAddressPath = runDerivationScheme(
391
- derivationScheme,
392
- currency,
393
- {
394
- account: index,
395
- }
396
- );
397
- const { address } = await getAddress(transport, {
398
- currency,
399
- path: freshAddressPath,
400
- derivationMode,
401
- });
402
- if (finished) return;
403
- const accountId = `ripplejs:2:${currency.id}:${address}:${derivationMode}`;
404
- let info;
405
-
406
- try {
407
- info = await getAccountInfo(address);
408
- } catch (e) {
409
- if (checkAccountNotFound(e)) {
410
- throw e;
411
- }
412
- }
413
-
414
- // fresh address is address. ripple never changes.
415
- const freshAddress = address;
416
-
417
- if (!info) {
418
- // account does not exist in Ripple server
419
- // we are generating a new account locally
420
- if (derivationMode === "") {
421
- o.next({
422
- type: "discovered",
423
- account: {
424
- type: "Account",
425
- id: accountId,
426
- seedIdentifier: freshAddress,
427
- derivationMode,
428
- name: getNewAccountPlaceholderName({
429
- currency,
430
- index,
431
- derivationMode,
432
- }),
433
- starred: false,
434
- used: false,
435
- freshAddress,
436
- freshAddressPath,
437
- freshAddresses: [
438
- {
439
- address: freshAddress,
440
- derivationPath: freshAddressPath,
441
- },
442
- ],
443
- balance: new BigNumber(0),
444
- spendableBalance: new BigNumber(0),
445
- blockHeight: maxLedgerVersion,
446
- index,
447
- currency,
448
- operationsCount: 0,
449
- operations: [],
450
- pendingOperations: [],
451
- unit: currency.units[0],
452
- // @ts-expect-error archived does not exists on type Account
453
- archived: false,
454
- lastSyncDate: new Date(),
455
- creationDate: new Date(),
456
- swapHistory: [],
457
- balanceHistoryCache: emptyHistoryCache, // calculated in the jsHelpers
458
- },
459
- });
460
- }
461
-
462
- break;
463
- }
464
-
465
- if (finished) return;
466
- const balance = parseAPIValue(info.xrpBalance);
467
- invariant(
468
- !balance.isNaN() && balance.isFinite(),
469
- `Ripple: invalid balance=${balance.toString()} for address ${address}`
470
- );
471
- const transactions = await getTransactions(address, {
472
- minLedgerVersion,
473
- maxLedgerVersion,
474
- types: ["payment"],
475
- });
476
- if (finished) return;
477
- const account: Account = {
478
- type: "Account",
479
- id: accountId,
480
- seedIdentifier: freshAddress,
481
- derivationMode,
482
- name: getAccountPlaceholderName({
483
- currency,
484
- index,
485
- derivationMode,
486
- }),
487
- starred: false,
488
- used: true,
489
- freshAddress,
490
- freshAddressPath,
491
- freshAddresses: [
492
- {
493
- address: freshAddress,
494
- derivationPath: freshAddressPath,
495
- },
496
- ],
497
- balance,
498
- spendableBalance: balance,
499
- // TODO calc with base reserve
500
- blockHeight: maxLedgerVersion,
501
- index,
502
- currency,
503
- operationsCount: 0,
504
- operations: [],
505
- pendingOperations: [],
506
- unit: currency.units[0],
507
- lastSyncDate: new Date(),
508
- creationDate: new Date(),
509
- swapHistory: [],
510
- balanceHistoryCache: emptyHistoryCache, // calculated in the jsHelpers
511
- };
512
- account.operations = transactions
513
- .map(txToOperation(account))
514
- .filter(Boolean);
515
- account.operationsCount = account.operations.length;
516
-
517
- if (account.operations.length > 0) {
518
- account.creationDate =
519
- account.operations[account.operations.length - 1].date;
520
- }
373
+ try {
374
+ transport = await open(deviceId);
375
+ const serverInfo = await getServerInfo();
376
+ const ledgers = serverInfo.completeLedgers.split("-");
377
+ const minLedgerVersion = Number(ledgers[0]);
378
+ const maxLedgerVersion = Number(ledgers[1]);
379
+ const derivationModes = getDerivationModesForCurrency(currency);
380
+
381
+ for (const derivationMode of derivationModes) {
382
+ const derivationScheme = getDerivationScheme({
383
+ derivationMode,
384
+ currency,
385
+ });
386
+ const stopAt = isIterableDerivationMode(derivationMode) ? 255 : 1;
387
+
388
+ for (let index = 0; index < stopAt; index++) {
389
+ if (!derivationModeSupportsIndex(derivationMode, index)) continue;
390
+ const freshAddressPath = runDerivationScheme(
391
+ derivationScheme,
392
+ currency,
393
+ {
394
+ account: index,
395
+ }
396
+ );
397
+ const { address } = await getAddress(transport, {
398
+ currency,
399
+ path: freshAddressPath,
400
+ derivationMode,
401
+ });
402
+ if (finished) return;
403
+ const accountId = `ripplejs:2:${currency.id}:${address}:${derivationMode}`;
404
+ let info;
405
+
406
+ try {
407
+ info = await getAccountInfo(address);
408
+ } catch (e) {
409
+ if (checkAccountNotFound(e)) {
410
+ throw e;
411
+ }
412
+ }
413
+
414
+ // fresh address is address. ripple never changes.
415
+ const freshAddress = address;
521
416
 
417
+ if (!info) {
418
+ // account does not exist in Ripple server
419
+ // we are generating a new account locally
420
+ if (derivationMode === "") {
522
421
  o.next({
523
422
  type: "discovered",
524
- account,
423
+ account: {
424
+ type: "Account",
425
+ id: accountId,
426
+ seedIdentifier: freshAddress,
427
+ derivationMode,
428
+ name: getNewAccountPlaceholderName({
429
+ currency,
430
+ index,
431
+ derivationMode,
432
+ }),
433
+ starred: false,
434
+ used: false,
435
+ freshAddress,
436
+ freshAddressPath,
437
+ freshAddresses: [
438
+ {
439
+ address: freshAddress,
440
+ derivationPath: freshAddressPath,
441
+ },
442
+ ],
443
+ balance: new BigNumber(0),
444
+ spendableBalance: new BigNumber(0),
445
+ blockHeight: maxLedgerVersion,
446
+ index,
447
+ currency,
448
+ operationsCount: 0,
449
+ operations: [],
450
+ pendingOperations: [],
451
+ unit: currency.units[0],
452
+ // @ts-expect-error archived does not exists on type Account
453
+ archived: false,
454
+ lastSyncDate: new Date(),
455
+ creationDate: new Date(),
456
+ swapHistory: [],
457
+ balanceHistoryCache: emptyHistoryCache, // calculated in the jsHelpers
458
+ },
525
459
  });
526
460
  }
461
+
462
+ break;
527
463
  }
528
464
 
529
- o.complete();
530
- } catch (e) {
531
- o.error(e);
465
+ if (finished) return;
466
+ const balance = parseAPIValue(info.xrpBalance);
467
+ invariant(
468
+ !balance.isNaN() && balance.isFinite(),
469
+ `Ripple: invalid balance=${balance.toString()} for address ${address}`
470
+ );
471
+ const transactions = await getTransactions(address, {
472
+ minLedgerVersion,
473
+ maxLedgerVersion,
474
+ types: ["payment"],
475
+ });
476
+ if (finished) return;
477
+ const account: Account = {
478
+ type: "Account",
479
+ id: accountId,
480
+ seedIdentifier: freshAddress,
481
+ derivationMode,
482
+ name: getAccountPlaceholderName({
483
+ currency,
484
+ index,
485
+ derivationMode,
486
+ }),
487
+ starred: false,
488
+ used: true,
489
+ freshAddress,
490
+ freshAddressPath,
491
+ freshAddresses: [
492
+ {
493
+ address: freshAddress,
494
+ derivationPath: freshAddressPath,
495
+ },
496
+ ],
497
+ balance,
498
+ spendableBalance: balance,
499
+ // TODO calc with base reserve
500
+ blockHeight: maxLedgerVersion,
501
+ index,
502
+ currency,
503
+ operationsCount: 0,
504
+ operations: [],
505
+ pendingOperations: [],
506
+ unit: currency.units[0],
507
+ lastSyncDate: new Date(),
508
+ creationDate: new Date(),
509
+ swapHistory: [],
510
+ balanceHistoryCache: emptyHistoryCache, // calculated in the jsHelpers
511
+ };
512
+ account.operations = transactions
513
+ .map(txToOperation(account))
514
+ .filter(Boolean);
515
+ account.operationsCount = account.operations.length;
516
+
517
+ if (account.operations.length > 0) {
518
+ account.creationDate =
519
+ account.operations[account.operations.length - 1].date;
520
+ }
521
+
522
+ o.next({
523
+ type: "discovered",
524
+ account,
525
+ });
532
526
  }
533
527
  }
534
528
 
535
- main();
536
- return unsubscribe;
537
- })
538
- ),
529
+ o.complete();
530
+ } catch (e) {
531
+ o.error(e);
532
+ } finally {
533
+ if (transport) {
534
+ await close(transport, deviceId);
535
+ }
536
+ }
537
+ }
538
+
539
+ main();
540
+ return unsubscribe;
541
+ }),
539
542
  };
540
543
 
541
544
  const sync = ({
@@ -3,7 +3,7 @@ import { Observable } from "rxjs";
3
3
  import Stellar from "@ledgerhq/hw-app-str";
4
4
  import { FeeNotLoaded } from "@ledgerhq/errors";
5
5
  import type { Account, Operation, SignOperationEvent } from "../../types";
6
- import { withDevice } from "../../hw/deviceAccess";
6
+ import { open, close } from "../../hw";
7
7
  import type { Transaction } from "./types";
8
8
  import { buildTransaction } from "./js-buildTransaction";
9
9
  import { fetchSequence } from "./api";
@@ -48,9 +48,11 @@ const signOperation = ({
48
48
  deviceId: any;
49
49
  transaction: Transaction;
50
50
  }): Observable<SignOperationEvent> =>
51
- withDevice(deviceId)((transport) =>
52
- Observable.create((o) => {
53
- async function main() {
51
+ Observable.create((o) => {
52
+ async function main() {
53
+ const transport = await open(deviceId);
54
+
55
+ try {
54
56
  o.next({
55
57
  type: "device-signature-requested",
56
58
  });
@@ -84,13 +86,15 @@ const signOperation = ({
84
86
  expirationDate: null,
85
87
  },
86
88
  });
89
+ } finally {
90
+ close(transport, deviceId);
87
91
  }
92
+ }
88
93
 
89
- main().then(
90
- () => o.complete(),
91
- (e) => o.error(e)
92
- );
93
- })
94
- );
94
+ main().then(
95
+ () => o.complete(),
96
+ (e) => o.error(e)
97
+ );
98
+ });
95
99
 
96
100
  export default signOperation;