@ledgerhq/live-common 21.32.2 → 21.33.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 (115) hide show
  1. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.integration.test.js +2 -1
  2. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.integration.test.js.map +1 -1
  3. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.getAddress.js +26 -0
  4. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.getAddress.js.map +1 -1
  5. package/lib/account/support.js +1 -1
  6. package/lib/account/support.js.map +1 -1
  7. package/lib/apps/hw.d.ts.map +1 -1
  8. package/lib/apps/hw.js +4 -3
  9. package/lib/apps/hw.js.map +1 -1
  10. package/lib/apps/logic.d.ts.map +1 -1
  11. package/lib/apps/logic.js +7 -5
  12. package/lib/apps/logic.js.map +1 -1
  13. package/lib/apps/support.js +1 -1
  14. package/lib/apps/support.js.map +1 -1
  15. package/lib/env.d.ts +10 -5
  16. package/lib/env.d.ts.map +1 -1
  17. package/lib/env.js +5 -0
  18. package/lib/env.js.map +1 -1
  19. package/lib/env.react.d.ts +1 -1
  20. package/lib/env.react.d.ts.map +1 -1
  21. package/lib/errors.d.ts +3 -0
  22. package/lib/errors.d.ts.map +1 -1
  23. package/lib/errors.js +3 -2
  24. package/lib/errors.js.map +1 -1
  25. package/lib/families/bitcoin/wallet-btc/crypto/bip32.js +2 -2
  26. package/lib/families/bitcoin/wallet-btc/crypto/bip32.js.map +1 -1
  27. package/lib/families/bitcoin/wallet-btc/crypto/zec.d.ts +2 -2
  28. package/lib/families/bitcoin/wallet-btc/crypto/zec.d.ts.map +1 -1
  29. package/lib/families/bitcoin/wallet-btc/crypto/zec.js +37 -16
  30. package/lib/families/bitcoin/wallet-btc/crypto/zec.js.map +1 -1
  31. package/lib/families/bitcoin/wallet-btc/crypto/zen.d.ts +0 -1
  32. package/lib/families/bitcoin/wallet-btc/crypto/zen.d.ts.map +1 -1
  33. package/lib/families/bitcoin/wallet-btc/crypto/zen.js +46 -24
  34. package/lib/families/bitcoin/wallet-btc/crypto/zen.js.map +1 -1
  35. package/lib/families/crypto_org/js-getTransactionStatus.d.ts.map +1 -1
  36. package/lib/families/crypto_org/js-getTransactionStatus.js +3 -0
  37. package/lib/families/crypto_org/js-getTransactionStatus.js.map +1 -1
  38. package/lib/families/ethereum/signOperation.js +1 -1
  39. package/lib/families/ethereum/signOperation.js.map +1 -1
  40. package/lib/families/ethereum/speculos-deviceActions.d.ts.map +1 -1
  41. package/lib/families/ethereum/speculos-deviceActions.js +4 -0
  42. package/lib/families/ethereum/speculos-deviceActions.js.map +1 -1
  43. package/lib/families/solana/test-dataset.d.ts.map +1 -1
  44. package/lib/families/solana/test-dataset.js +1 -2
  45. package/lib/families/solana/test-dataset.js.map +1 -1
  46. package/lib/families/tezos/bridge/js.d.ts.map +1 -1
  47. package/lib/families/tezos/bridge/js.js +52 -26
  48. package/lib/families/tezos/bridge/js.js.map +1 -1
  49. package/lib/families/tezos/datasets/tezos.scanAccounts.1.d.ts.map +1 -1
  50. package/lib/families/tezos/datasets/tezos.scanAccounts.1.js +1 -1
  51. package/lib/families/tezos/datasets/tezos.scanAccounts.1.js.map +1 -1
  52. package/lib/families/tezos/synchronisation.d.ts.map +1 -1
  53. package/lib/families/tezos/synchronisation.js +32 -7
  54. package/lib/families/tezos/synchronisation.js.map +1 -1
  55. package/lib/families/tezos/test-dataset.d.ts.map +1 -1
  56. package/lib/families/tezos/test-dataset.js +60 -6
  57. package/lib/families/tezos/test-dataset.js.map +1 -1
  58. package/lib/families/tron/synchronisation.test.js +1 -0
  59. package/lib/families/tron/synchronisation.test.js.map +1 -1
  60. package/lib/featureFlags/FeatureToggle.js +2 -2
  61. package/lib/featureFlags/FeatureToggle.js.map +1 -1
  62. package/lib/featureFlags/defaultFeatures.js +1 -1
  63. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  64. package/lib/featureFlags/types.d.ts +1 -1
  65. package/lib/featureFlags/types.d.ts.map +1 -1
  66. package/lib/market/MarketDataProvider.d.ts.map +1 -1
  67. package/lib/market/MarketDataProvider.js +5 -3
  68. package/lib/market/MarketDataProvider.js.map +1 -1
  69. package/lib/market/api/api.d.ts.map +1 -1
  70. package/lib/market/api/api.js +22 -7
  71. package/lib/market/api/api.js.map +1 -1
  72. package/lib/market/types.d.ts +1 -0
  73. package/lib/market/types.d.ts.map +1 -1
  74. package/lib/platform/PlatformAppProvider/helpers.d.ts +1 -0
  75. package/lib/platform/PlatformAppProvider/helpers.d.ts.map +1 -1
  76. package/lib/platform/PlatformAppProvider/helpers.js +23 -1
  77. package/lib/platform/PlatformAppProvider/helpers.js.map +1 -1
  78. package/lib/platform/PlatformAppProvider/index.d.ts.map +1 -1
  79. package/lib/platform/PlatformAppProvider/index.js +2 -1
  80. package/lib/platform/PlatformAppProvider/index.js.map +1 -1
  81. package/lib/types/manager.d.ts +4 -3
  82. package/lib/types/manager.d.ts.map +1 -1
  83. package/lib/types/manager.js +4 -3
  84. package/lib/types/manager.js.map +1 -1
  85. package/package.json +6 -5
  86. package/src/__tests__/__snapshots__/all.libcore.ts.snap +109 -0
  87. package/src/__tests__/families/bitcoin/wallet-btc/wallet.integration.test.ts +3 -1
  88. package/src/__tests__/families/bitcoin/wallet-btc/xpub.getAddress.ts +31 -0
  89. package/src/account/support.ts +1 -1
  90. package/src/apps/hw.ts +4 -3
  91. package/src/apps/logic.ts +6 -3
  92. package/src/apps/support.ts +1 -1
  93. package/src/env.ts +5 -0
  94. package/src/errors.ts +3 -0
  95. package/src/families/bitcoin/wallet-btc/crypto/bip32.ts +2 -2
  96. package/src/families/bitcoin/wallet-btc/crypto/zec.ts +19 -19
  97. package/src/families/bitcoin/wallet-btc/crypto/zen.ts +26 -27
  98. package/src/families/crypto_org/js-getTransactionStatus.ts +3 -0
  99. package/src/families/ethereum/signOperation.ts +1 -1
  100. package/src/families/ethereum/speculos-deviceActions.ts +4 -0
  101. package/src/families/solana/test-dataset.ts +3 -4
  102. package/src/families/tezos/bridge/js.ts +25 -5
  103. package/src/families/tezos/datasets/tezos.scanAccounts.1.ts +0 -10
  104. package/src/families/tezos/synchronisation.ts +28 -13
  105. package/src/families/tezos/test-dataset.ts +65 -6
  106. package/src/families/tron/synchronisation.test.ts +2 -0
  107. package/src/featureFlags/FeatureToggle.tsx +2 -2
  108. package/src/featureFlags/defaultFeatures.ts +1 -1
  109. package/src/featureFlags/types.ts +1 -1
  110. package/src/market/MarketDataProvider.tsx +5 -3
  111. package/src/market/api/api.ts +19 -8
  112. package/src/market/types.ts +1 -0
  113. package/src/platform/PlatformAppProvider/helpers.ts +29 -0
  114. package/src/platform/PlatformAppProvider/index.tsx +3 -2
  115. package/src/types/manager.ts +4 -3
@@ -1,11 +1,8 @@
1
1
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
2
  // @ts-ignore
3
- import { toOutputScript } from "bitcoinjs-lib/src/address";
4
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5
- // @ts-ignore
6
3
  import zec from "zcash-bitcore-lib";
7
4
  import bs58check from "bs58check";
8
- import coininfo from "coininfo";
5
+ import * as bjs from "bitcoinjs-lib";
9
6
  import { InvalidAddress } from "@ledgerhq/errors";
10
7
  import { DerivationModes } from "../types";
11
8
  import Base from "./base";
@@ -32,19 +29,13 @@ class ZCash extends Base {
32
29
  return bs58check.encode(Buffer.from(taddr));
33
30
  }
34
31
 
35
- private static toBitcoinAddr(taddr: string) {
36
- // refer to https://runkitcdn.com/gojomo/baddr2taddr/1.0.2
37
- const baddr = new Uint8Array(21);
38
- baddr.set(bs58check.decode(taddr).slice(2), 1);
39
- return bs58check.encode(Buffer.from(baddr));
40
- }
41
-
42
32
  // eslint-disable-next-line
43
33
  getLegacyAddress(xpub: string, account: number, index: number): string {
44
- const pubkey = new zec.HDPublicKey(xpub);
45
- const child = pubkey.derive(account).derive(index);
46
- const address = new zec.Address(child.publicKey, zec.Networks.livenet);
47
- return address.toString();
34
+ const pk = bjs.crypto.hash160(this.getPubkeyAt(xpub, account, index));
35
+ const payload = Buffer.allocUnsafe(22);
36
+ payload.writeUInt16BE(this.network.pubKeyHash, 0);
37
+ pk.copy(payload, 2);
38
+ return bs58check.encode(payload);
48
39
  }
49
40
 
50
41
  customGetAddress(
@@ -65,11 +56,20 @@ class ZCash extends Base {
65
56
  if (!this.validateAddress(address)) {
66
57
  throw new InvalidAddress();
67
58
  }
68
- // TODO find a better way to calculate the script from zec address instead of converting to bitcoin address
69
- return toOutputScript(
70
- ZCash.toBitcoinAddr(address),
71
- coininfo.bitcoin.main.toBitcoinJS()
59
+ const version = Number(
60
+ "0x" + bs58check.decode(address).slice(0, 2).toString("hex")
72
61
  );
62
+ if (version === this.network.pubKeyHash) {
63
+ //Pay-to-PubkeyHash
64
+ return bjs.payments.p2pkh({ hash: bs58check.decode(address).slice(2) })
65
+ .output as Buffer;
66
+ }
67
+ if (version === this.network.scriptHash) {
68
+ //Pay-to-Script-Hash
69
+ return bjs.payments.p2sh({ hash: bs58check.decode(address).slice(2) })
70
+ .output as Buffer;
71
+ }
72
+ throw new InvalidAddress();
73
73
  }
74
74
 
75
75
  // eslint-disable-next-line class-methods-use-this
@@ -1,14 +1,8 @@
1
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
- // @ts-ignore
3
- import { toOutputScript } from "bitcoinjs-lib/src/address";
4
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5
- // @ts-ignore
6
- import zec from "zcash-bitcore-lib";
7
1
  import bs58check from "bs58check";
8
- import coininfo from "coininfo";
9
2
  import { InvalidAddress } from "@ledgerhq/errors";
10
3
  import { DerivationModes } from "../types";
11
4
  import Base from "./base";
5
+ import * as bjs from "bitcoinjs-lib";
12
6
 
13
7
  class Zen extends Base {
14
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -26,15 +20,15 @@ class Zen extends Base {
26
20
  },
27
21
  bip44: 121,
28
22
  private: 0x80,
29
- public: 0x2096,
30
- scripthash: 0x2089,
23
+ public: 0x2089,
24
+ scripthash: 0x2096,
31
25
  };
32
26
  this.network.name = "Zencash";
33
27
  this.network.unit = "ZEN";
34
28
  this.network.messagePrefix = "Zencash Signed Message:\n";
35
29
  this.network.wif = 0x80;
36
- this.network.pubKeyHash = 0x2096;
37
- this.network.scriptHash = 0x2089;
30
+ this.network.pubKeyHash = 0x2089;
31
+ this.network.scriptHash = 0x2096;
38
32
  this.network.dustThreshold = 10000;
39
33
  this.network.dustPolicy = "FIXED";
40
34
  this.network.usesTimestampedTransaction = false;
@@ -50,21 +44,13 @@ class Zen extends Base {
50
44
  return bs58check.encode(Buffer.from(taddr));
51
45
  }
52
46
 
53
- private static toBitcoinAddr(taddr: string) {
54
- // refer to https://runkitcdn.com/gojomo/baddr2taddr/1.0.2
55
- const baddr = new Uint8Array(21);
56
- baddr.set(bs58check.decode(taddr).slice(2), 1);
57
- return bs58check.encode(Buffer.from(baddr));
58
- }
59
-
60
47
  // eslint-disable-next-line
61
48
  getLegacyAddress(xpub: string, account: number, index: number): string {
62
- const pubkey = new zec.HDPublicKey(xpub);
63
- const child = pubkey.derive(account).derive(index);
64
- const address = new zec.Address(child.publicKey, zec.Networks.livenet);
65
- const baddr = new Uint8Array(21);
66
- baddr.set(bs58check.decode(address.toString()).slice(2), 1);
67
- return this.baddrToTaddr(bs58check.encode(Buffer.from(baddr)));
49
+ const pk = bjs.crypto.hash160(this.getPubkeyAt(xpub, account, index));
50
+ const payload = Buffer.allocUnsafe(22);
51
+ payload.writeUInt16BE(this.network.pubKeyHash, 0);
52
+ pk.copy(payload, 2);
53
+ return bs58check.encode(payload);
68
54
  }
69
55
 
70
56
  customGetAddress(
@@ -85,10 +71,23 @@ class Zen extends Base {
85
71
  if (!this.validateAddress(address)) {
86
72
  throw new InvalidAddress();
87
73
  }
88
- const outputScript = toOutputScript(
89
- Zen.toBitcoinAddr(address),
90
- coininfo.bitcoin.main.toBitcoinJS()
74
+ let outputScript: Buffer;
75
+ const version = Number(
76
+ "0x" + bs58check.decode(address).slice(0, 2).toString("hex")
91
77
  );
78
+ if (version === this.network.pubKeyHash) {
79
+ //Pay-to-PubkeyHash
80
+ outputScript = bjs.payments.p2pkh({
81
+ hash: bs58check.decode(address).slice(2),
82
+ }).output as Buffer;
83
+ } else if (version === this.network.scriptHash) {
84
+ //Pay-to-Script-Hash
85
+ outputScript = bjs.payments.p2sh({
86
+ hash: bs58check.decode(address).slice(2),
87
+ }).output as Buffer;
88
+ } else {
89
+ throw new InvalidAddress();
90
+ }
92
91
  // refer to https://github.com/LedgerHQ/lib-ledger-core/blob/fc9d762b83fc2b269d072b662065747a64ab2816/core/src/wallet/bitcoin/scripts/BitcoinLikeScript.cpp#L139 and https://github.com/LedgerHQ/lib-ledger-core/blob/fc9d762b83fc2b269d072b662065747a64ab2816/core/src/wallet/bitcoin/networks.cpp#L39 for bip115 Script and its network parameters
93
92
  const bip115Script = Buffer.from(
94
93
  "209ec9845acb02fab24e1c0368b3b517c1a4488fba97f0e3459ac053ea0100000003c01f02b4",
@@ -5,6 +5,7 @@ import {
5
5
  InvalidAddress,
6
6
  FeeNotLoaded,
7
7
  AmountRequired,
8
+ InvalidAddressBecauseDestinationIsAlsoSource,
8
9
  } from "@ledgerhq/errors";
9
10
  import type { Account, TransactionStatus } from "../../types";
10
11
  import type { Transaction } from "./types";
@@ -46,6 +47,8 @@ const getTransactionStatus = async (
46
47
  errors.recipient = new RecipientRequired();
47
48
  } else if (!isValidAddress(t.recipient, a.currency.id)) {
48
49
  errors.recipient = new InvalidAddress();
50
+ } else if (t.mode === "send" && a.freshAddress === t.recipient) {
51
+ errors.recipient = new InvalidAddressBecauseDestinationIsAlsoSource();
49
52
  }
50
53
 
51
54
  return Promise.resolve({
@@ -65,7 +65,7 @@ export const signOperation = ({
65
65
  // rawData Format: `rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])`
66
66
  const rawData = tx.raw();
67
67
  rawData[6] = Buffer.from([common.chainIdBN().toNumber()]);
68
- const txHex = encode(rawData).toString("hex");
68
+ const txHex = Buffer.from(encode(rawData)).toString("hex");
69
69
  const loadConfig: LoadConfig = {};
70
70
  if (isNFTActive(account.currency)) {
71
71
  loadConfig.nftExplorerBaseURL =
@@ -101,6 +101,10 @@ const acceptTransaction: DeviceAction<Transaction, any> = deviceActionFlow({
101
101
  title: "Contract",
102
102
  button: "Rr",
103
103
  },
104
+ {
105
+ title: "Network",
106
+ button: "Rr",
107
+ },
104
108
  {
105
109
  title: "Max fees",
106
110
  button: "Rr",
@@ -1,5 +1,5 @@
1
1
  import BigNumber from "bignumber.js";
2
- import { DatasetTest, encodeAccountId } from "../../types";
2
+ import { CurrenciesData, DatasetTest, encodeAccountId } from "../../types";
3
3
 
4
4
  import { Transaction, TransactionModel } from "./types";
5
5
 
@@ -75,8 +75,7 @@ const fees = (signatureCount: number) =>
75
75
 
76
76
  const zero = new BigNumber(0);
77
77
 
78
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
79
- const solana = {
78
+ const solana: CurrenciesData<Transaction> = {
80
79
  scanAccounts: [scanAccounts1],
81
80
  accounts: [
82
81
  {
@@ -438,7 +437,7 @@ const solana = {
438
437
  const dataset: DatasetTest<Transaction> = {
439
438
  implementations: [getEnv("MOCK") ? "mock" : "js"], // FIXME we should actually put both mock and js like other dataset do
440
439
  currencies: {
441
- // solana, // TODO re enable when it's ready
440
+ solana,
442
441
  },
443
442
  };
444
443
 
@@ -12,6 +12,7 @@ import {
12
12
  FeeTooHigh,
13
13
  InvalidAddressBecauseDestinationIsAlsoSource,
14
14
  RecommendUndelegation,
15
+ NotEnoughBalanceBecauseDestinationNotCreated,
15
16
  } from "@ledgerhq/errors";
16
17
  import { validateRecipient } from "../../../bridge/shared";
17
18
  import type {
@@ -35,9 +36,12 @@ import { signOperation } from "../signOperation";
35
36
  import { patchOperationWithHash } from "../../../operation";
36
37
  import { log } from "@ledgerhq/logs";
37
38
  import { InvalidAddressBecauseAlreadyDelegated } from "../../../errors";
39
+ import api from "../api/tzkt";
38
40
 
39
41
  const receive = makeAccountBridgeReceive();
40
42
 
43
+ const EXISTENTIAL_DEPOSIT = new BigNumber(275000);
44
+
41
45
  const createTransaction: () => Transaction = () => ({
42
46
  family: "tezos",
43
47
  mode: "send",
@@ -71,6 +75,7 @@ const getTransactionStatus = async (
71
75
  } = {};
72
76
 
73
77
  const estimatedFees = t.estimatedFees || new BigNumber(0);
78
+ let amount = t.amount;
74
79
 
75
80
  const { tezosResources } = account;
76
81
  if (!tezosResources) throw new Error("tezosResources is missing");
@@ -95,14 +100,30 @@ const getTransactionStatus = async (
95
100
  }
96
101
 
97
102
  if (t.mode === "send") {
98
- if (!errors.amount && t.amount.eq(0)) {
103
+ const spendableBalance = account.balance.minus(EXISTENTIAL_DEPOSIT).lt(0)
104
+ ? account.balance.minus(EXISTENTIAL_DEPOSIT)
105
+ : account.balance;
106
+ if (!errors.amount && t.amount.eq(0) && !t.useAllAmount) {
99
107
  errors.amount = new AmountRequired();
100
- } else if (!errors.amount && t.amount.lt(0)) {
108
+ } else if (!errors.amount && t.amount.gt(spendableBalance)) {
101
109
  errors.amount = new NotEnoughBalance();
110
+ if (t.useAllAmount) {
111
+ amount = new BigNumber(0);
112
+ }
102
113
  } else if (t.amount.gt(0) && estimatedFees.times(10).gt(t.amount)) {
103
114
  warnings.feeTooHigh = new FeeTooHigh();
104
115
  }
105
116
 
117
+ if (
118
+ !errors.amount &&
119
+ (await api.getAccountByAddress(t.recipient)).type === "empty" &&
120
+ t.amount.lt(EXISTENTIAL_DEPOSIT)
121
+ ) {
122
+ errors.amount = new NotEnoughBalanceBecauseDestinationNotCreated("", {
123
+ minimalAmount: "0.275 XTZ",
124
+ });
125
+ }
126
+
106
127
  const thresholdWarning = 0.5 * 10 ** account.currency.units[0].magnitude;
107
128
 
108
129
  if (
@@ -146,8 +167,8 @@ const getTransactionStatus = async (
146
167
  errors,
147
168
  warnings,
148
169
  estimatedFees,
149
- amount: t.amount,
150
- totalSpent: t.amount.plus(estimatedFees),
170
+ amount: amount,
171
+ totalSpent: amount.plus(estimatedFees),
151
172
  };
152
173
  return Promise.resolve(result);
153
174
  };
@@ -222,7 +243,6 @@ const prepareTransaction = async (
222
243
  default:
223
244
  throw new Error("unsupported mode=" + transaction.mode);
224
245
  }
225
-
226
246
  if (t.useAllAmount) {
227
247
  const totalFees = out.suggestedFeeMutez + out.burnFeeMutez;
228
248
  const maxAmount = account.balance
@@ -5,18 +5,10 @@ export default {
5
5
  apdus: `
6
6
  => 800200000d038000002c800006c180000000
7
7
  <= 2102ac76ba226118e2d593d09cd7e395546b7540c0e7fb3eb430da59f7982af632969000
8
- => 8002000015058000002c800006c1800000008000000080000000
9
- <= 2102f7ed85c519f7d39a664935a410d1a41ca302dfa3eee228e92cbe0dc12aba7a189000
10
8
  => 8002000015058000002c800006c1800000008000000080000001
11
9
  <= 2102b058662fd530e6463d774e3951a40ddd5e430dbeb62673f90caca0cec58735fd9000
12
- => 800200000d038000002c800006c180000000
13
- <= 2102ac76ba226118e2d593d09cd7e395546b7540c0e7fb3eb430da59f7982af632969000
14
- => 8002000011048000002c800006c18000000080000000
15
- <= 210294e8344ae6df2d3123fa100b5abd40cee339c67838b1c34c4f243cc582f4d2d89000
16
10
  => 8002000011048000002c800006c18000000080000001
17
11
  <= 2102670e5e92d06e725b68edda589678fdf0f85a582df06ee634d841cf8042db63839000
18
- => 800200000d038000002c800006c180000000
19
- <= 2102ac76ba226118e2d593d09cd7e395546b7540c0e7fb3eb430da59f7982af632969000
20
12
  => 8002000015058000002c800006c1800000008000000080000000
21
13
  <= 2102f7ed85c519f7d39a664935a410d1a41ca302dfa3eee228e92cbe0dc12aba7a189000
22
14
  => 8002000015058000002c800006c1800000018000000080000000
@@ -31,8 +23,6 @@ export default {
31
23
  <= 21020162dc75ad3c2b6e097d15a1513033c60d8a033f2312ff5a6ead812228d9d6539000
32
24
  => 8002000015058000002c800006c1800000068000000080000000
33
25
  <= 21021831897c4224296519d496d32fdf9e17fb4af680635c5dbbc46cde84fe11dcc99000
34
- => 800200000d038000002c800006c180000000
35
- <= 2102ac76ba226118e2d593d09cd7e395546b7540c0e7fb3eb430da59f7982af632969000
36
26
  => 8002000011048000002c800006c18000000080000000
37
27
  <= 210294e8344ae6df2d3123fa100b5abd40cee339c67838b1c34c4f243cc582f4d2d89000
38
28
  => 8002000011048000002c800006c18000000180000000
@@ -14,6 +14,23 @@ import { DerivationType } from "@taquito/ledger-signer";
14
14
  import { compressPublicKey } from "@taquito/ledger-signer/dist/lib/utils";
15
15
  import { b58cencode, prefix, Prefix } from "@taquito/utils";
16
16
 
17
+ function isStringHex(s: string): boolean {
18
+ for (let i = 0; i < s.length; i += 2) {
19
+ const ss = s.slice(i, i + 2);
20
+ const x = parseInt(ss, 16);
21
+ if (Number.isNaN(x)) {
22
+ return false;
23
+ }
24
+ }
25
+ return true;
26
+ }
27
+
28
+ function encodeHexToPubKey(publicKeyHex: string) {
29
+ return b58cencode(
30
+ compressPublicKey(Buffer.from(publicKeyHex, "hex"), DerivationType.ED25519),
31
+ prefix[Prefix.EDPK]
32
+ );
33
+ }
17
34
  function restorePublicKey(
18
35
  publicKey: string,
19
36
  initialAccount: Account | undefined,
@@ -23,19 +40,16 @@ function restorePublicKey(
23
40
  if (initialAccount) {
24
41
  const { tezosResources } = initialAccount;
25
42
  if (tezosResources) {
43
+ if (isStringHex(tezosResources.publicKey)) {
44
+ return encodeHexToPubKey(tezosResources.publicKey);
45
+ }
26
46
  return tezosResources.publicKey;
27
47
  }
28
48
  const { xpubOrAddress } = decodeAccountId(initialAccount.id);
29
49
  if (xpubOrAddress) return xpubOrAddress;
30
50
  }
31
51
  invariant(rest.publicKey, "publicKey must not be empty");
32
- return b58cencode(
33
- compressPublicKey(
34
- Buffer.from(rest.publicKey, "hex"),
35
- DerivationType.ED25519
36
- ),
37
- prefix[Prefix.EDPK]
38
- );
52
+ return encodeHexToPubKey(rest.publicKey);
39
53
  }
40
54
 
41
55
  export const getAccountShape: GetAccountShape = async (infoInput) => {
@@ -74,6 +88,7 @@ export const getAccountShape: GetAccountShape = async (infoInput) => {
74
88
  if (apiAccount.type === "empty") {
75
89
  return {
76
90
  id: accountId,
91
+ xpub: address,
77
92
  blockHeight,
78
93
  lastSyncDate: new Date(),
79
94
  tezosResources: {
@@ -83,13 +98,12 @@ export const getAccountShape: GetAccountShape = async (infoInput) => {
83
98
  },
84
99
  };
85
100
  }
86
- invariant(
87
- apiAccount.type === "user",
88
- "unsupported account of type ",
89
- apiAccount.type
90
- );
91
101
 
92
- const apiOperations = await fetchAllTransactions(address, lastId);
102
+ const fullySupported = apiAccount.type === "user";
103
+
104
+ const apiOperations = fullySupported
105
+ ? await fetchAllTransactions(address, lastId)
106
+ : [];
93
107
 
94
108
  const { revealed, counter, publicKey } = apiAccount;
95
109
 
@@ -110,6 +124,7 @@ export const getAccountShape: GetAccountShape = async (infoInput) => {
110
124
 
111
125
  const accountShape = {
112
126
  id: accountId,
127
+ xpub: address,
113
128
  operations,
114
129
  balance,
115
130
  subAccounts,
@@ -1,8 +1,13 @@
1
+ import {
2
+ AmountRequired,
3
+ NotEnoughBalance,
4
+ NotEnoughBalanceBecauseDestinationNotCreated,
5
+ } from "@ledgerhq/errors";
6
+ import BigNumber from "bignumber.js";
1
7
  import type { DatasetTest } from "../../types";
2
8
  import type { Transaction } from "./types";
3
9
 
4
- // TODO restore
5
- // import tezosScanAccounts1 from "./datasets/tezos.scanAccounts.1";
10
+ import tezosScanAccounts1 from "./datasets/tezos.scanAccounts.1";
6
11
 
7
12
  // FIXME these accounts no longer reflect their expected states..
8
13
  export const accountTZrevealedDelegating = makeAccount(
@@ -45,12 +50,37 @@ const dataset: DatasetTest<Transaction> = {
45
50
  currencies: {
46
51
  tezos: {
47
52
  FIXME_ignoreOperationFields: ["blockHeight"],
48
- // scanAccounts: [tezosScanAccounts1],
49
- scanAccounts: [],
53
+ scanAccounts: [tezosScanAccounts1],
50
54
  accounts: [
51
55
  {
52
56
  raw: accountTZrevealedDelegating,
53
- transactions: [],
57
+ transactions: [
58
+ {
59
+ name: "No amount",
60
+ transaction: (t) => ({
61
+ ...t,
62
+ recipient: "tz1VSichevvJSNkSSntgwKDKikWNB6iqNJii",
63
+ }),
64
+ expectedStatus: {
65
+ errors: { amount: new AmountRequired() },
66
+ warnings: {},
67
+ },
68
+ },
69
+ {
70
+ name: "send more than min allowed",
71
+ transaction: (t, account) => ({
72
+ ...t,
73
+ amount: account.balance.minus("100"),
74
+ recipient: "tz1VSichevvJSNkSSntgwKDKikWNB6iqNJii",
75
+ }),
76
+ expectedStatus: {
77
+ errors: {
78
+ amount: new NotEnoughBalance(),
79
+ },
80
+ warnings: {},
81
+ },
82
+ },
83
+ ],
54
84
  },
55
85
  {
56
86
  raw: accountTZRevealedNoDelegate,
@@ -58,7 +88,36 @@ const dataset: DatasetTest<Transaction> = {
58
88
  },
59
89
  {
60
90
  raw: accountTZnotRevealed,
61
- transactions: [],
91
+ transactions: [
92
+ {
93
+ name: "Send to new account",
94
+ transaction: (t) => ({
95
+ ...t,
96
+ amount: new BigNumber(100),
97
+ recipient: accountTZnew.freshAddress,
98
+ }),
99
+ expectedStatus: {
100
+ errors: {
101
+ amount: new NotEnoughBalanceBecauseDestinationNotCreated(),
102
+ },
103
+ warnings: {},
104
+ },
105
+ },
106
+ {
107
+ name: "Amount > spendablebalance",
108
+ transaction: (t, account) => ({
109
+ ...t,
110
+ amount: account.balance,
111
+ recipient: accountTZnew.freshAddress,
112
+ }),
113
+ expectedStatus: {
114
+ errors: {
115
+ amount: new NotEnoughBalance(),
116
+ },
117
+ warnings: {},
118
+ },
119
+ },
120
+ ],
62
121
  },
63
122
  {
64
123
  raw: accountTZnew,
@@ -6,6 +6,8 @@ import { defaultTronResources } from "./utils";
6
6
  import bridge from "./bridge/js";
7
7
  import { Account } from "../../types";
8
8
 
9
+ jest.setTimeout(30000);
10
+
9
11
  const tron = getCryptoCurrencyById("tron");
10
12
  const defaultSyncConfig = {
11
13
  paginationConfig: {},
@@ -17,8 +17,8 @@ export const FeatureToggle = ({
17
17
  const feature = useFeature(featureId);
18
18
 
19
19
  if (!feature || !feature.enabled) {
20
- return fallback;
20
+ return fallback ?? null;
21
21
  }
22
22
 
23
- return children;
23
+ return children ?? null;
24
24
  };
@@ -1,7 +1,7 @@
1
1
  import { DefaultFeatures } from "./types";
2
2
 
3
3
  export const defaultFeatures: DefaultFeatures = {
4
- market: {
4
+ learn: {
5
5
  enabled: false,
6
6
  },
7
7
  };
@@ -1,4 +1,4 @@
1
- export type FeatureId = "market"; // Add others with union
1
+ export type FeatureId = "learn"; // Add others with union (e.g. "learn" | "market" | "foo")
2
2
 
3
3
  // We use objects instead of direct booleans for potential future improvements
4
4
  // like feature versioning etc
@@ -220,7 +220,8 @@ export const MarketDataProvider = ({
220
220
  }, []);
221
221
 
222
222
  useEffect(() => {
223
- if (countervalue)
223
+ if (countervalue) {
224
+ const ticker = countervalue.ticker.toLowerCase();
224
225
  api.supportedCounterCurrencies().then(
225
226
  (supportedCounterCurrencies) =>
226
227
  api.setSupportedCoinsList().then((coins) => {
@@ -233,13 +234,14 @@ export const MarketDataProvider = ({
233
234
  });
234
235
  dispatch({
235
236
  type: ACTIONS.UPDATE_COUNTERVALUE,
236
- payload: supportedCounterCurrencies.includes(countervalue.ticker)
237
- ? countervalue.ticker
237
+ payload: supportedCounterCurrencies.includes(ticker)
238
+ ? ticker
238
239
  : "usd",
239
240
  });
240
241
  }, handleError),
241
242
  handleError
242
243
  );
244
+ }
243
245
  }, [api, countervalue, handleError]);
244
246
 
245
247
  useEffect(() => {
@@ -52,6 +52,8 @@ const matchSearch =
52
52
  };
53
53
 
54
54
  function distributedCopy(items: number[], n: number): number[] {
55
+ if (!items) return [];
56
+ if (items.length <= n) return items;
55
57
  const elements = [items[0]];
56
58
  const totalItems = items.length - 2;
57
59
  const interval = Math.floor(totalItems / (n - 2));
@@ -83,6 +85,7 @@ function sparklineAsSvgData(points: number[]): SparklineSvgData {
83
85
  })
84
86
  .join(" "),
85
87
  viewBox: `0 0 ${totalXSteps} ${sparklineYHeight + 3}`,
88
+ isPositive: points[0] <= points[points.length - 1],
86
89
  };
87
90
  }
88
91
 
@@ -102,14 +105,6 @@ async function listPaginated({
102
105
  }: MarketListRequestParams): Promise<CurrencyData[]> {
103
106
  let ids = _ids;
104
107
 
105
- if (liveCompatible) {
106
- ids = ids.concat(LIVE_COINS_LIST);
107
- }
108
-
109
- if (starred.length > 0) {
110
- ids = ids.concat(starred);
111
- }
112
-
113
108
  if (search) {
114
109
  ids = SUPPORTED_COINS_LIST.filter(matchSearch(search)).map(({ id }) => id);
115
110
  if (!ids.length) {
@@ -117,6 +112,22 @@ async function listPaginated({
117
112
  }
118
113
  }
119
114
 
115
+ if (liveCompatible) {
116
+ if (ids.length > 0) {
117
+ ids = LIVE_COINS_LIST.filter((id) => ids.includes(id));
118
+ } else {
119
+ ids = ids.concat(LIVE_COINS_LIST);
120
+ }
121
+ }
122
+
123
+ if (starred.length > 0) {
124
+ if (ids.length > 0) {
125
+ ids = starred.filter((id) => ids.includes(id));
126
+ } else {
127
+ ids = ids.concat(starred);
128
+ }
129
+ }
130
+
120
131
  ids = ids.slice((page - 1) * limit, limit * page);
121
132
 
122
133
  const url =
@@ -34,6 +34,7 @@ export type MarketCurrencyChartDataRequestParams = {
34
34
  export type SparklineSvgData = {
35
35
  path: string;
36
36
  viewBox: string;
37
+ isPositive: boolean;
37
38
  };
38
39
 
39
40
  export type CurrencyData = {
@@ -6,6 +6,7 @@ export type FilterParams = {
6
6
  private?: boolean;
7
7
  version?: string;
8
8
  };
9
+ import { getEnv } from "../../env";
9
10
 
10
11
  function matchVersion(filterParams: FilterParams, manifest: AppManifest) {
11
12
  return (
@@ -52,3 +53,31 @@ export function mergeManifestLists(
52
53
  const newIds = new Set(list2.map((elem) => elem.id));
53
54
  return [...list1.filter((elem) => !newIds.has(elem.id)), ...list2];
54
55
  }
56
+
57
+ export const initializeLocalManifest = (): Map<string, AppManifest> => {
58
+ const localManifestJsonRaw: string | null | undefined = getEnv(
59
+ "PLATFORM_LOCAL_MANIFEST_JSON"
60
+ );
61
+
62
+ if (!localManifestJsonRaw) {
63
+ return new Map();
64
+ }
65
+
66
+ try {
67
+ const manifest: AppManifest | [AppManifest] =
68
+ JSON.parse(localManifestJsonRaw);
69
+
70
+ const manifestArray = Array.isArray(manifest) ? manifest : [manifest];
71
+
72
+ const map = new Map(manifestArray.map((m) => [m.id, m]));
73
+
74
+ return map;
75
+ } catch (error) {
76
+ /**
77
+ * Probable error during `JSON.parse` call, log error and return empty map
78
+ * as if env variable was not defined
79
+ */
80
+ console.error(error);
81
+ return new Map();
82
+ }
83
+ };