@ledgerhq/live-common 21.35.0 → 21.36.2

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 (236) hide show
  1. package/lib/__tests__/families/bitcoin/wallet-btc/bitcoin.test.js +290 -225
  2. package/lib/__tests__/families/bitcoin/wallet-btc/bitcoin.test.js.map +1 -1
  3. package/lib/__tests__/families/bitcoin/wallet-btc/utils.test.js +2 -0
  4. package/lib/__tests__/families/bitcoin/wallet-btc/utils.test.js.map +1 -1
  5. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.errorpropagation.test.d.ts +2 -0
  6. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.errorpropagation.test.d.ts.map +1 -0
  7. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.errorpropagation.test.js +86 -0
  8. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.errorpropagation.test.js.map +1 -0
  9. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.getAddress.js +38 -0
  10. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.getAddress.js.map +1 -1
  11. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.integration.test.js +4 -4
  12. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.integration.test.js.map +1 -1
  13. package/lib/account/support.js +1 -1
  14. package/lib/account/support.js.map +1 -1
  15. package/lib/apps/support.js +1 -1
  16. package/lib/bot/engine.d.ts.map +1 -1
  17. package/lib/bot/engine.js +77 -45
  18. package/lib/bot/engine.js.map +1 -1
  19. package/lib/bot/index.d.ts.map +1 -1
  20. package/lib/bot/index.js +44 -20
  21. package/lib/bot/index.js.map +1 -1
  22. package/lib/bot/types.d.ts +1 -0
  23. package/lib/bot/types.d.ts.map +1 -1
  24. package/lib/bridge/jsHelpers.d.ts +25 -2
  25. package/lib/bridge/jsHelpers.d.ts.map +1 -1
  26. package/lib/bridge/jsHelpers.js +94 -60
  27. package/lib/bridge/jsHelpers.js.map +1 -1
  28. package/lib/cross.d.ts.map +1 -1
  29. package/lib/cross.js +5 -3
  30. package/lib/cross.js.map +1 -1
  31. package/lib/exchange/swap/getCompleteSwapHistory.js +17 -14
  32. package/lib/exchange/swap/getCompleteSwapHistory.js.map +1 -1
  33. package/lib/families/algorand/js-synchronization.d.ts.map +1 -1
  34. package/lib/families/algorand/js-synchronization.js +2 -5
  35. package/lib/families/algorand/js-synchronization.js.map +1 -1
  36. package/lib/families/bitcoin/js-synchronisation.d.ts.map +1 -1
  37. package/lib/families/bitcoin/js-synchronisation.js +5 -2
  38. package/lib/families/bitcoin/js-synchronisation.js.map +1 -1
  39. package/lib/families/bitcoin/specs.d.ts.map +1 -1
  40. package/lib/families/bitcoin/specs.js +4 -2
  41. package/lib/families/bitcoin/specs.js.map +1 -1
  42. package/lib/families/bitcoin/wallet-btc/crypto/base.d.ts +5 -6
  43. package/lib/families/bitcoin/wallet-btc/crypto/base.d.ts.map +1 -1
  44. package/lib/families/bitcoin/wallet-btc/crypto/base.js +149 -59
  45. package/lib/families/bitcoin/wallet-btc/crypto/base.js.map +1 -1
  46. package/lib/families/bitcoin/wallet-btc/crypto/bip32.d.ts +1 -1
  47. package/lib/families/bitcoin/wallet-btc/crypto/bip32.d.ts.map +1 -1
  48. package/lib/families/bitcoin/wallet-btc/crypto/bip32.js +59 -9
  49. package/lib/families/bitcoin/wallet-btc/crypto/bip32.js.map +1 -1
  50. package/lib/families/bitcoin/wallet-btc/crypto/bitcoin.d.ts +1 -1
  51. package/lib/families/bitcoin/wallet-btc/crypto/bitcoin.d.ts.map +1 -1
  52. package/lib/families/bitcoin/wallet-btc/crypto/bitcoin.js +76 -24
  53. package/lib/families/bitcoin/wallet-btc/crypto/bitcoin.js.map +1 -1
  54. package/lib/families/bitcoin/wallet-btc/crypto/bitcoincash.d.ts +2 -2
  55. package/lib/families/bitcoin/wallet-btc/crypto/bitcoincash.d.ts.map +1 -1
  56. package/lib/families/bitcoin/wallet-btc/crypto/bitcoincash.js +55 -2
  57. package/lib/families/bitcoin/wallet-btc/crypto/bitcoincash.js.map +1 -1
  58. package/lib/families/bitcoin/wallet-btc/crypto/decred.d.ts +1 -1
  59. package/lib/families/bitcoin/wallet-btc/crypto/decred.d.ts.map +1 -1
  60. package/lib/families/bitcoin/wallet-btc/crypto/decred.js +61 -14
  61. package/lib/families/bitcoin/wallet-btc/crypto/decred.js.map +1 -1
  62. package/lib/families/bitcoin/wallet-btc/crypto/index.d.ts +1 -0
  63. package/lib/families/bitcoin/wallet-btc/crypto/index.d.ts.map +1 -1
  64. package/lib/families/bitcoin/wallet-btc/crypto/index.js +4 -1
  65. package/lib/families/bitcoin/wallet-btc/crypto/index.js.map +1 -1
  66. package/lib/families/bitcoin/wallet-btc/crypto/secp256k1.d.ts +16 -0
  67. package/lib/families/bitcoin/wallet-btc/crypto/secp256k1.d.ts.map +1 -0
  68. package/lib/families/bitcoin/wallet-btc/crypto/secp256k1.js +28 -0
  69. package/lib/families/bitcoin/wallet-btc/crypto/secp256k1.js.map +1 -0
  70. package/lib/families/bitcoin/wallet-btc/crypto/types.d.ts +2 -2
  71. package/lib/families/bitcoin/wallet-btc/crypto/types.d.ts.map +1 -1
  72. package/lib/families/bitcoin/wallet-btc/crypto/zec.d.ts +2 -2
  73. package/lib/families/bitcoin/wallet-btc/crypto/zec.d.ts.map +1 -1
  74. package/lib/families/bitcoin/wallet-btc/crypto/zec.js +72 -10
  75. package/lib/families/bitcoin/wallet-btc/crypto/zec.js.map +1 -1
  76. package/lib/families/bitcoin/wallet-btc/crypto/zen.d.ts +2 -2
  77. package/lib/families/bitcoin/wallet-btc/crypto/zen.d.ts.map +1 -1
  78. package/lib/families/bitcoin/wallet-btc/crypto/zen.js +60 -6
  79. package/lib/families/bitcoin/wallet-btc/crypto/zen.js.map +1 -1
  80. package/lib/families/bitcoin/wallet-btc/storage/index.d.ts +20 -4
  81. package/lib/families/bitcoin/wallet-btc/storage/index.d.ts.map +1 -1
  82. package/lib/families/bitcoin/wallet-btc/storage/index.js +45 -8
  83. package/lib/families/bitcoin/wallet-btc/storage/index.js.map +1 -1
  84. package/lib/families/bitcoin/wallet-btc/storage/types.d.ts +3 -3
  85. package/lib/families/bitcoin/wallet-btc/storage/types.d.ts.map +1 -1
  86. package/lib/families/bitcoin/wallet-btc/xpub.js +38 -31
  87. package/lib/families/bitcoin/wallet-btc/xpub.js.map +1 -1
  88. package/lib/families/celo/js-synchronisation.d.ts +2 -3
  89. package/lib/families/celo/js-synchronisation.d.ts.map +1 -1
  90. package/lib/families/celo/js-synchronisation.js +2 -5
  91. package/lib/families/celo/js-synchronisation.js.map +1 -1
  92. package/lib/families/cosmos/bridge/js.d.ts.map +1 -1
  93. package/lib/families/cosmos/bridge/js.js +1 -1
  94. package/lib/families/cosmos/bridge/js.js.map +1 -1
  95. package/lib/families/cosmos/js-synchronisation.d.ts +8 -2
  96. package/lib/families/cosmos/js-synchronisation.d.ts.map +1 -1
  97. package/lib/families/cosmos/js-synchronisation.js +3 -3
  98. package/lib/families/cosmos/js-synchronisation.js.map +1 -1
  99. package/lib/families/crypto_org/js-synchronisation.d.ts +2 -3
  100. package/lib/families/crypto_org/js-synchronisation.d.ts.map +1 -1
  101. package/lib/families/crypto_org/js-synchronisation.js +2 -3
  102. package/lib/families/crypto_org/js-synchronisation.js.map +1 -1
  103. package/lib/families/elrond/js-synchronisation.d.ts +2 -3
  104. package/lib/families/elrond/js-synchronisation.d.ts.map +1 -1
  105. package/lib/families/elrond/js-synchronisation.js +2 -3
  106. package/lib/families/elrond/js-synchronisation.js.map +1 -1
  107. package/lib/families/ethereum/bridge/js.js +2 -2
  108. package/lib/families/ethereum/bridge/js.js.map +1 -1
  109. package/lib/families/ethereum/synchronisation.d.ts.map +1 -1
  110. package/lib/families/ethereum/synchronisation.js +11 -10
  111. package/lib/families/ethereum/synchronisation.js.map +1 -1
  112. package/lib/families/filecoin/bridge/account.js +1 -1
  113. package/lib/families/filecoin/bridge/account.js.map +1 -1
  114. package/lib/families/filecoin/bridge/currency.js +1 -1
  115. package/lib/families/filecoin/bridge/currency.js.map +1 -1
  116. package/lib/families/filecoin/speculos-deviceActions.d.ts.map +1 -1
  117. package/lib/families/filecoin/speculos-deviceActions.js +14 -6
  118. package/lib/families/filecoin/speculos-deviceActions.js.map +1 -1
  119. package/lib/families/neo/bridge/js.js +2 -2
  120. package/lib/families/neo/bridge/js.js.map +1 -1
  121. package/lib/families/polkadot/js-synchronisation.d.ts.map +1 -1
  122. package/lib/families/polkadot/js-synchronisation.js +2 -5
  123. package/lib/families/polkadot/js-synchronisation.js.map +1 -1
  124. package/lib/families/solana/api/chain/index.d.ts +1 -1
  125. package/lib/families/solana/api/chain/index.d.ts.map +1 -1
  126. package/lib/families/solana/api/chain/index.js +13 -2
  127. package/lib/families/solana/api/chain/index.js.map +1 -1
  128. package/lib/families/solana/api/traced.d.ts +3 -0
  129. package/lib/families/solana/api/traced.d.ts.map +1 -0
  130. package/lib/families/solana/api/traced.js +82 -0
  131. package/lib/families/solana/api/traced.js.map +1 -0
  132. package/lib/families/solana/bridge/bridge.js +2 -2
  133. package/lib/families/solana/bridge/bridge.js.map +1 -1
  134. package/lib/families/solana/bridge/js.d.ts.map +1 -1
  135. package/lib/families/solana/bridge/js.js +12 -1
  136. package/lib/families/solana/bridge/js.js.map +1 -1
  137. package/lib/families/stellar/js-synchronization.d.ts +2 -3
  138. package/lib/families/stellar/js-synchronization.d.ts.map +1 -1
  139. package/lib/families/stellar/js-synchronization.js +2 -5
  140. package/lib/families/stellar/js-synchronization.js.map +1 -1
  141. package/lib/families/tezos/bridge/js.js +13 -12
  142. package/lib/families/tezos/bridge/js.js.map +1 -1
  143. package/lib/families/tezos/specs.d.ts.map +1 -1
  144. package/lib/families/tezos/specs.js +4 -3
  145. package/lib/families/tezos/specs.js.map +1 -1
  146. package/lib/families/tron/bridge/js.js +2 -2
  147. package/lib/families/tron/bridge/js.js.map +1 -1
  148. package/lib/featureFlags/FeatureToggle.d.ts +2 -2
  149. package/lib/featureFlags/FeatureToggle.d.ts.map +1 -1
  150. package/lib/featureFlags/FeatureToggle.js +1 -2
  151. package/lib/featureFlags/FeatureToggle.js.map +1 -1
  152. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  153. package/lib/featureFlags/defaultFeatures.js +3 -0
  154. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  155. package/lib/featureFlags/index.d.ts +3 -2
  156. package/lib/featureFlags/index.d.ts.map +1 -1
  157. package/lib/featureFlags/index.js +8 -2
  158. package/lib/featureFlags/index.js.map +1 -1
  159. package/lib/featureFlags/types.d.ts +1 -1
  160. package/lib/featureFlags/types.d.ts.map +1 -1
  161. package/lib/featureFlags/useFeature.d.ts +2 -1
  162. package/lib/featureFlags/useFeature.d.ts.map +1 -1
  163. package/lib/featureFlags/useFeature.js +2 -2
  164. package/lib/featureFlags/useFeature.js.map +1 -1
  165. package/lib/hw/actions/app.d.ts.map +1 -1
  166. package/lib/hw/actions/app.js +2 -1
  167. package/lib/hw/actions/app.js.map +1 -1
  168. package/lib/market/MarketDataProvider.d.ts +4 -3
  169. package/lib/market/MarketDataProvider.d.ts.map +1 -1
  170. package/lib/market/MarketDataProvider.js +21 -60
  171. package/lib/market/MarketDataProvider.js.map +1 -1
  172. package/lib/notifications/AnnouncementProvider/machine.d.ts +21 -4
  173. package/lib/notifications/AnnouncementProvider/machine.d.ts.map +1 -1
  174. package/lib/notifications/ServiceStatusProvider/machine.d.ts +21 -4
  175. package/lib/notifications/ServiceStatusProvider/machine.d.ts.map +1 -1
  176. package/lib/platform/providers/GlobalCatalogProvider/api/mock.json +13 -0
  177. package/lib/platform/providers/RemoteLiveAppProvider/api/mock.json +256 -65
  178. package/package.json +7 -7
  179. package/src/__tests__/families/bitcoin/wallet-btc/bitcoin.test.ts +17 -16
  180. package/src/__tests__/families/bitcoin/wallet-btc/utils.test.ts +2 -0
  181. package/src/__tests__/families/bitcoin/wallet-btc/wallet.errorpropagation.test.ts +41 -0
  182. package/src/__tests__/families/bitcoin/wallet-btc/xpub.getAddress.ts +46 -0
  183. package/src/__tests__/families/bitcoin/wallet-btc/xpub.txs.integration.test.ts +4 -4
  184. package/src/account/support.ts +1 -1
  185. package/src/apps/support.ts +1 -1
  186. package/src/bot/engine.ts +21 -1
  187. package/src/bot/index.ts +45 -5
  188. package/src/bot/types.ts +2 -0
  189. package/src/bridge/jsHelpers.ts +126 -72
  190. package/src/cross.ts +4 -3
  191. package/src/exchange/swap/getCompleteSwapHistory.ts +1 -1
  192. package/src/families/algorand/js-synchronization.ts +2 -6
  193. package/src/families/bitcoin/js-synchronisation.ts +5 -2
  194. package/src/families/bitcoin/specs.ts +3 -2
  195. package/src/families/bitcoin/wallet-btc/crypto/base.ts +59 -44
  196. package/src/families/bitcoin/wallet-btc/crypto/bip32.ts +8 -3
  197. package/src/families/bitcoin/wallet-btc/crypto/bitcoin.ts +8 -8
  198. package/src/families/bitcoin/wallet-btc/crypto/bitcoincash.ts +8 -6
  199. package/src/families/bitcoin/wallet-btc/crypto/decred.ts +4 -3
  200. package/src/families/bitcoin/wallet-btc/crypto/index.ts +1 -0
  201. package/src/families/bitcoin/wallet-btc/crypto/secp256k1.ts +32 -0
  202. package/src/families/bitcoin/wallet-btc/crypto/types.ts +2 -2
  203. package/src/families/bitcoin/wallet-btc/crypto/zec.ts +20 -9
  204. package/src/families/bitcoin/wallet-btc/crypto/zen.ts +5 -5
  205. package/src/families/bitcoin/wallet-btc/storage/index.ts +66 -22
  206. package/src/families/bitcoin/wallet-btc/storage/types.ts +3 -3
  207. package/src/families/bitcoin/wallet-btc/xpub.ts +3 -3
  208. package/src/families/celo/js-synchronisation.ts +2 -7
  209. package/src/families/cosmos/bridge/js.ts +3 -6
  210. package/src/families/cosmos/js-synchronisation.ts +9 -5
  211. package/src/families/crypto_org/js-synchronisation.ts +2 -5
  212. package/src/families/elrond/js-synchronisation.ts +2 -5
  213. package/src/families/ethereum/bridge/js.ts +2 -2
  214. package/src/families/ethereum/synchronisation.ts +6 -3
  215. package/src/families/filecoin/bridge/account.ts +1 -1
  216. package/src/families/filecoin/bridge/currency.ts +1 -1
  217. package/src/families/filecoin/speculos-deviceActions.ts +11 -3
  218. package/src/families/neo/bridge/js.ts +2 -2
  219. package/src/families/polkadot/js-synchronisation.ts +2 -6
  220. package/src/families/solana/api/chain/index.ts +19 -2
  221. package/src/families/solana/api/traced.ts +99 -0
  222. package/src/families/solana/bridge/bridge.ts +2 -2
  223. package/src/families/solana/bridge/js.ts +12 -1
  224. package/src/families/stellar/js-synchronization.ts +2 -7
  225. package/src/families/tezos/bridge/js.ts +12 -12
  226. package/src/families/tezos/specs.ts +5 -3
  227. package/src/families/tron/bridge/js.ts +2 -2
  228. package/src/featureFlags/FeatureToggle.tsx +3 -1
  229. package/src/featureFlags/defaultFeatures.ts +3 -0
  230. package/src/featureFlags/index.ts +5 -2
  231. package/src/featureFlags/types.ts +2 -1
  232. package/src/featureFlags/useFeature.ts +4 -2
  233. package/src/hw/actions/app.ts +2 -1
  234. package/src/market/MarketDataProvider.tsx +73 -98
  235. package/src/platform/providers/GlobalCatalogProvider/api/mock.json +14 -1
  236. package/src/platform/providers/RemoteLiveAppProvider/api/mock.json +930 -739
@@ -82,7 +82,7 @@ describe("Unit tests for various bitcoin functions", () => {
82
82
  testAddresses(p2shTestnet, "bitcoin_testnet");
83
83
  });
84
84
 
85
- it("Test taproot address generation", () => {
85
+ it("Test taproot address generation", async () => {
86
86
  const bitcoin = cryptoFactory("bitcoin_testnet");
87
87
  // Test data taken from project app-bitcoin-new, file test_get_wallet_address.py
88
88
  // Also generated using eg
@@ -298,28 +298,29 @@ describe("Unit tests for various bitcoin functions", () => {
298
298
  "tb1pkhlmr4xz5w8x8py8x7670zp9lzykhepw74jltvpleff3qpxc3m2sgsmgnu",
299
299
  "tb1ptp5mua0w462ahk56y8uvqgkv3pxk44dz67vjtax4jnu4ajm8ykgqd80ndj",
300
300
  ];
301
-
302
301
  const xpub =
303
302
  "tpubDDKYE6BREvDsSWMazgHoyQWiJwYaDDYPbCFjYxN3HFXJP5fokeiK4hwK5tTLBNEDBwrDXn8cQ4v9b2xdW62Xr5yxoQdMu1v6c7UDXYVH27U";
304
- extAddrs.forEach((expected, index) => {
303
+ extAddrs.forEach(async (expected, index) => {
305
304
  expect(
306
- bitcoin.getAddress(DerivationModes.TAPROOT, xpub, 0, index)
305
+ await bitcoin.getAddress(DerivationModes.TAPROOT, xpub, 0, index)
307
306
  ).toEqual(expected);
308
307
  });
309
- changeAddrs.forEach((expected, index) => {
308
+ changeAddrs.forEach(async (expected, index) => {
310
309
  expect(
311
- bitcoin.getAddress(DerivationModes.TAPROOT, xpub, 1, index)
310
+ await bitcoin.getAddress(DerivationModes.TAPROOT, xpub, 1, index)
312
311
  ).toEqual(expected);
313
312
  });
314
-
315
- expect(
316
- bitcoin.getAddress(DerivationModes.NATIVE_SEGWIT, xpub, 0, 0).slice(0, 4)
317
- ).toEqual("tb1q");
318
- expect(
319
- bitcoin.getAddress(DerivationModes.LEGACY, xpub, 0, 0).slice(0, 1)
320
- ).toMatch(new RegExp("[mn]"));
321
- expect(
322
- bitcoin.getAddress(DerivationModes.SEGWIT, xpub, 0, 0).slice(0, 1)
323
- ).toEqual("2");
313
+ let prefix = (
314
+ await bitcoin.getAddress(DerivationModes.NATIVE_SEGWIT, xpub, 0, 0)
315
+ ).slice(0, 4);
316
+ expect(prefix).toEqual("tb1q");
317
+ prefix = (
318
+ await bitcoin.getAddress(DerivationModes.LEGACY, xpub, 0, 0)
319
+ ).slice(0, 1);
320
+ expect(prefix).toMatch(new RegExp("[mn]"));
321
+ prefix = (
322
+ await bitcoin.getAddress(DerivationModes.SEGWIT, xpub, 0, 0)
323
+ ).slice(0, 1);
324
+ expect(prefix).toEqual("2");
324
325
  });
325
326
  });
@@ -162,6 +162,7 @@ describe("Unit tests for various utils functions", () => {
162
162
  validateAddrs(["Xh13o3cWixDBYJMGuJmFX17TZb9guXcBik"], "dash", true);
163
163
  validateAddrs(["MFYvHZcZ35typC4k2XyvRVooCDZxnoDS4B"], "qtum", true);
164
164
  validateAddrs(["t1b1Rbw2shhJkP6MCnCyxCPuyFedHrwKty8"], "zcash", true);
165
+ validateAddrs(["t3PU1j7YW3fJ67jUbkGhSRto8qK2qXCUiW3"], "zcash", true);
165
166
  validateAddrs(["AYRf8r4SJhmfaEwmWvY8ujmrepbrWyenFr"], "bitcoin_gold", true);
166
167
  validateAddrs(["D8cMCRimfjwQ9E8jJvgUswt18WnZbCUAaW"], "dogecoin", true);
167
168
  validateAddrs(
@@ -193,6 +194,7 @@ describe("Unit tests for various utils functions", () => {
193
194
  validateAddrs(["Xh13o3cWixDBYJMGuJmFX17TZb9guXcBii"], "dash", false);
194
195
  validateAddrs(["MFYvHZcZ35typC4k2XyvRVooCDZxnoDS44"], "qtum", false);
195
196
  validateAddrs(["t1b1Rbw2shhJkP6MCnCyxCPuyFedHrwKtyy"], "zcash", false);
197
+ validateAddrs(["t3PU1j7YW3fJ67jUbkGySRto8qK2qXCUiW3"], "zcash", false);
196
198
  validateAddrs(
197
199
  ["AYRf8r4SJhmfaEwmWvY8ujmrepbrWyenFF"],
198
200
  "bitcoin_gold",
@@ -0,0 +1,41 @@
1
+ import { DerivationModes } from "../../../../families/bitcoin/wallet-btc/types";
2
+ import BitcoinLikeWallet from "../../../../families/bitcoin/wallet-btc/wallet";
3
+ import {
4
+ getSecp256k1Instance,
5
+ setSecp256k1Instance,
6
+ } from "../../../../families/bitcoin/wallet-btc/crypto/secp256k1";
7
+
8
+ jest.setTimeout(180000);
9
+
10
+ describe("testing resilience of failures", () => {
11
+ const wallet = new BitcoinLikeWallet();
12
+ const defaultImpl = getSecp256k1Instance();
13
+ it("should generate an account", async () => {
14
+ setSecp256k1Instance({
15
+ publicKeyTweakAdd: () => {
16
+ throw new Error("FAILCRYPTO");
17
+ },
18
+ });
19
+ try {
20
+ await expect(
21
+ wallet
22
+ .generateAccount({
23
+ xpub: "xpub6CV2NfQJYxHn7MbSQjQip3JMjTZGUbeoKz5xqkBftSZZPc7ssVPdjKrgh6N8U1zoQDxtSo6jLarYAQahpd35SJoUKokfqf1DZgdJWZhSMqP",
24
+ path: "44'/0'",
25
+ index: 0,
26
+ currency: "bitcoin",
27
+ network: "mainnet",
28
+ derivationMode: DerivationModes.LEGACY,
29
+ explorer: "ledgerv3",
30
+ explorerURI:
31
+ "https://explorers.api.vault.ledger.com/blockchain/v3/btc",
32
+ storage: "mock",
33
+ storageParams: [],
34
+ })
35
+ .then((a) => wallet.syncAccount(a))
36
+ ).rejects.toEqual(new Error("FAILCRYPTO"));
37
+ } finally {
38
+ setSecp256k1Instance(defaultImpl);
39
+ }
40
+ });
41
+ });
@@ -62,11 +62,19 @@ describe("Unit tests for getAddress", () => {
62
62
  .toOutputScript("1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX")
63
63
  .toString("hex")
64
64
  ).toEqual("76a91499bc78ba577a95a11f1a344d4d2ae55f2f857b9888ac");
65
+ // Legacy zcash address
65
66
  expect(
66
67
  zecCrypto
67
68
  .toOutputScript("t1T5XJvzQhh2gTsi3c5Vn9x5SMhpSWLSnVy")
68
69
  .toString("hex")
69
70
  ).toEqual("76a91464fa33fb6f8d72455af2a4e73ae30412af2c97ba88ac");
71
+ // P2SH zcash address
72
+ expect(
73
+ zecCrypto
74
+ .toOutputScript("t3PU1j7YW3fJ67jUbkGhSRto8qK2qXCUiW3")
75
+ .toString("hex")
76
+ ).toEqual("a91435c929cb2ee32626e1f5c8d773ab4fe9d94686e087");
77
+ // Legacy zen address
70
78
  expect(
71
79
  zenCrypto
72
80
  .toOutputScript("znjbHth4PxBJM8FmHgvXYHkuq99nKFkWvMg")
@@ -74,5 +82,43 @@ describe("Unit tests for getAddress", () => {
74
82
  ).toEqual(
75
83
  "76a914cb009bf12fc17d28e61527951101fdabfeaa187288ac209ec9845acb02fab24e1c0368b3b517c1a4488fba97f0e3459ac053ea0100000003c01f02b4"
76
84
  );
85
+ // P2SH zen address
86
+ expect(
87
+ zenCrypto
88
+ .toOutputScript("zszpcLB6C5B8QvfDbF2dYWXsrpac5DL9WRk")
89
+ .toString("hex")
90
+ ).toEqual(
91
+ "a914df23c5eaba30b4d95798c5d5d0e2ecc2a3dc4ff287209ec9845acb02fab24e1c0368b3b517c1a4488fba97f0e3459ac053ea0100000003c01f02b4"
92
+ );
93
+ }, 30000);
94
+ it.skip("Get legacy address benchmark", async () => {
95
+ const btcCrypto = new BTCCrypto({
96
+ network: coininfo.bitcoin.main.toBitcoinJS(),
97
+ });
98
+ for (let i = 0; i < 1; i++) {
99
+ for (let j = 0; j < 1000; j++) {
100
+ btcCrypto.getAddress(
101
+ DerivationModes.LEGACY,
102
+ "xpub6CThYZbX4PTeA7KRYZ8YXP3F6HwT2eVKPQap3Avieds3p1eos35UzSsJtTbJ3vQ8d3fjRwk4bCEz4m4H6mkFW49q29ZZ6gS8tvahs4WCZ9X",
103
+ i,
104
+ j
105
+ );
106
+ }
107
+ }
108
+ }, 30000);
109
+ it.skip("Get taproot address benchmark", async () => {
110
+ const btcCrypto = new BTCCrypto({
111
+ network: coininfo.bitcoin.main.toBitcoinJS(),
112
+ });
113
+ for (let i = 0; i < 1; i++) {
114
+ for (let j = 0; j < 1000; j++) {
115
+ btcCrypto.getAddress(
116
+ DerivationModes.TAPROOT,
117
+ "xpub6CThYZbX4PTeA7KRYZ8YXP3F6HwT2eVKPQap3Avieds3p1eos35UzSsJtTbJ3vQ8d3fjRwk4bCEz4m4H6mkFW49q29ZZ6gS8tvahs4WCZ9X",
118
+ i,
119
+ j
120
+ );
121
+ }
122
+ }
77
123
  }, 30000);
78
124
  });
@@ -175,8 +175,8 @@ describe.skip("testing xpub legacy transactions", () => {
175
175
  expect((await xpubs[1].xpub.getXpubBalance()).toNumber()).toEqual(
176
176
  100000000
177
177
  );
178
- let pendings0 = await xpubs[0].xpub.storage.getLastTx({ confirmed: false });
179
- let pendings1 = await xpubs[1].xpub.storage.getLastTx({ confirmed: false });
178
+ let pendings0 = await xpubs[0].xpub.storage.getLastUnconfirmedTx();
179
+ let pendings1 = await xpubs[1].xpub.storage.getLastUnconfirmedTx();
180
180
  expect(pendings0).toBeTruthy();
181
181
  expect(pendings1).toBeTruthy();
182
182
 
@@ -200,8 +200,8 @@ describe.skip("testing xpub legacy transactions", () => {
200
200
  expect((await xpubs[1].xpub.getXpubBalance()).toNumber()).toEqual(
201
201
  100000000
202
202
  );
203
- pendings0 = await xpubs[0].xpub.storage.getLastTx({ confirmed: false });
204
- pendings1 = await xpubs[1].xpub.storage.getLastTx({ confirmed: false });
203
+ pendings0 = await xpubs[0].xpub.storage.getLastUnconfirmedTx();
204
+ pendings1 = await xpubs[1].xpub.storage.getLastUnconfirmedTx();
205
205
  expect(pendings0).toBeFalsy();
206
206
  expect(pendings1).toBeFalsy();
207
207
  }, 150000);
@@ -20,7 +20,7 @@ import { getMainAccount } from "../account";
20
20
  import { getAccountBridge } from "../bridge";
21
21
  import jsBridges from "../generated/bridge/js";
22
22
 
23
- const experimentalIntegrations = ["tezos", "cosmos"];
23
+ const experimentalIntegrations: string[] = [];
24
24
 
25
25
  export function shouldUseJS(currency: CryptoCurrency) {
26
26
  const jsBridge = jsBridges[currency.family];
@@ -29,7 +29,7 @@ export function shouldUpgrade(
29
29
  const appVersionsRequired = {
30
30
  Cosmos: ">= 2.14",
31
31
  Algorand: ">= 1.2.9",
32
- Polkadot: ">= 10.9160.1",
32
+ Polkadot: ">= 11.9170.0",
33
33
  Elrond: ">= 1.0.11",
34
34
  Ethereum: ">= 1.9.17",
35
35
  };
package/src/bot/engine.ts CHANGED
@@ -52,6 +52,8 @@ import type {
52
52
  TransactionRes,
53
53
  } from "./types";
54
54
  import { makeBridgeCacheSystem } from "../bridge/cache";
55
+ import { accountDataToAccount, accountToAccountData } from "../cross";
56
+
55
57
  let appCandidates;
56
58
  const localCache = {};
57
59
  const cache = makeBridgeCacheSystem({
@@ -64,6 +66,15 @@ const cache = makeBridgeCacheSystem({
64
66
  return Promise.resolve(localCache[c.id]);
65
67
  },
66
68
  });
69
+
70
+ // simulate the export/inport of an account
71
+ async function crossAccount(account: Account): Promise<Account> {
72
+ const a = accountDataToAccount(accountToAccountData(account));
73
+ const synced = await syncAccount(a);
74
+ synced.name += " cross";
75
+ return synced;
76
+ }
77
+
67
78
  export async function runWithAppSpec<T extends Transaction>(
68
79
  spec: AppSpec<T>,
69
80
  reportLog: (arg0: string) => void
@@ -146,6 +157,15 @@ export async function runWithAppSpec<T extends Transaction>(
146
157
  )
147
158
  .toPromise();
148
159
  appReport.scanTime = scanTime;
160
+ // "Migrate" the FIRST and every {crossAccountFrequency} account to simulate an export/import (same logic as export to mobile) – default to every 10
161
+ // this is made a subset of the accounts to help identify problem that would be specific to the "cross" or not.
162
+ for (
163
+ let i = 0;
164
+ i < accounts.length;
165
+ i += spec.crossAccountFrequency || 10
166
+ ) {
167
+ accounts[i] = await crossAccount(accounts[i]);
168
+ }
149
169
  appReport.accountsBefore = accounts;
150
170
  invariant(
151
171
  accounts.length > 0,
@@ -184,8 +204,8 @@ export async function runWithAppSpec<T extends Transaction>(
184
204
  let mutationsCount = {};
185
205
  // we sequentially iterate on the initial account set to perform mutations
186
206
  const length = accounts.length;
187
-
188
207
  const totalTries = spec.multipleRuns || 1;
208
+
189
209
  for (let j = 0; j < totalTries; j++) {
190
210
  for (let i = 0; i < length; i++) {
191
211
  log(
package/src/bot/index.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  /* eslint-disable no-console */
2
+ import fs from "fs";
3
+ import path from "path";
2
4
  import { BigNumber } from "bignumber.js";
3
5
  import groupBy from "lodash/groupBy";
4
6
  import { log } from "@ledgerhq/logs";
@@ -8,6 +10,7 @@ import { getEnv } from "../env";
8
10
  import allSpecs from "../generated/specs";
9
11
  import network from "../network";
10
12
  import { withLibcore } from "../libcore/access";
13
+ import type { Account } from "../types";
11
14
  import type { MutationReport, SpecReport } from "./types";
12
15
  import { promiseAllBatched } from "../promise";
13
16
  import {
@@ -16,7 +19,7 @@ import {
16
19
  formatCurrencyUnit,
17
20
  getFiatCurrencyByTicker,
18
21
  } from "../currencies";
19
- import { isAccountEmpty } from "../account";
22
+ import { isAccountEmpty, toAccountRaw } from "../account";
20
23
  import { runWithAppSpec } from "./engine";
21
24
  import { formatReportForConsole, formatError } from "./formatters";
22
25
  import {
@@ -32,6 +35,22 @@ type Arg = Partial<{
32
35
  mutation: string;
33
36
  }>;
34
37
  const usd = getFiatCurrencyByTicker("USD");
38
+
39
+ function makeAppJSON(accounts: Account[]) {
40
+ const jsondata = {
41
+ data: {
42
+ settings: {
43
+ hasCompletedOnboarding: true,
44
+ },
45
+ accounts: accounts.map((account) => ({
46
+ data: toAccountRaw(account),
47
+ version: 1,
48
+ })),
49
+ },
50
+ };
51
+ return JSON.stringify(jsondata);
52
+ }
53
+
35
54
  export async function bot({ currency, family, mutation }: Arg = {}) {
36
55
  const SEED = getEnv("SEED");
37
56
  invariant(SEED, "SEED required");
@@ -93,6 +112,7 @@ export async function bot({ currency, family, mutation }: Arg = {}) {
93
112
  }));
94
113
  }
95
114
  );
115
+ const allAccountsBefore = flatMap(results, (r) => r.accountsBefore || []);
96
116
  const allAccountsAfter = flatMap(results, (r) => r.accountsAfter || []);
97
117
  let countervaluesError;
98
118
  const countervaluesState = await loadCountervalues(initialState, {
@@ -400,17 +420,37 @@ export async function bot({ currency, family, mutation }: Arg = {}) {
400
420
  body += "|\n";
401
421
  });
402
422
  body += "\n</details>\n\n";
423
+
424
+ const { SLACK_API_TOKEN, SLACK_CHANNEL, BOT_REPORT_FOLDER } = process.env;
425
+
426
+ if (BOT_REPORT_FOLDER) {
427
+ await Promise.all([
428
+ fs.promises.writeFile(
429
+ path.join(BOT_REPORT_FOLDER, "full-report.md"),
430
+ body,
431
+ "utf-8"
432
+ ),
433
+ fs.promises.writeFile(
434
+ path.join(BOT_REPORT_FOLDER, "before-app.json"),
435
+ makeAppJSON(allAccountsBefore),
436
+ "utf-8"
437
+ ),
438
+ fs.promises.writeFile(
439
+ path.join(BOT_REPORT_FOLDER, "after-app.json"),
440
+ makeAppJSON(allAccountsAfter),
441
+ "utf-8"
442
+ ),
443
+ ]);
444
+ }
445
+
403
446
  const { data: githubComment } = await network({
404
447
  url: `https://api.github.com/repos/LedgerHQ/ledger-live-common/commits/${GITHUB_SHA}/comments`,
405
448
  method: "POST",
406
449
  headers: {
407
450
  Authorization: `Bearer ${GITHUB_TOKEN}`,
408
451
  },
409
- data: {
410
- body,
411
- },
452
+ data: { body },
412
453
  });
413
- const { SLACK_API_TOKEN, SLACK_CHANNEL } = process.env;
414
454
 
415
455
  if (SLACK_API_TOKEN && githubComment) {
416
456
  const text = `${String(GITHUB_WORKFLOW)}: ${title} (<${
package/src/bot/types.ts CHANGED
@@ -86,6 +86,8 @@ export type AppSpec<T extends Transaction> = {
86
86
  testTimeout?: number;
87
87
  // if define, will run the mutations {multipleRuns} times in order to cover 2 txs in the same run and detect possible issues at the "second tx time"
88
88
  multipleRuns?: number;
89
+ // define the frequency of exporting/importing back the account to simulate mobile export
90
+ crossAccountFrequency?: number;
89
91
  // if the nano app depends on an app, name of this app
90
92
  dependency?: string;
91
93
  // a query to select one nano app. the most up to date version is selected when fields aren't set.
@@ -42,6 +42,22 @@ import type { Result, GetAddressOptions } from "../hw/getAddress/types";
42
42
  import { open, close } from "../hw";
43
43
  import { withDevice } from "../hw/deviceAccess";
44
44
 
45
+ // Customize the way to iterate on the keychain derivation
46
+ type IterateResult = ({
47
+ transport: Transport,
48
+ index: number,
49
+ derivationsCache: Object,
50
+ derivationScheme: string,
51
+ derivationMode: DerivationMode,
52
+ currency: CryptoCurrency,
53
+ }) => Promise<Result | null>;
54
+
55
+ export type IterateResultBuilder = ({
56
+ result: Result, // derivation on the "root" of the derivation
57
+ derivationMode: DerivationMode, // identify the current derivation scheme
58
+ derivationScheme: string,
59
+ }) => Promise<IterateResult>;
60
+
45
61
  export type GetAccountShapeArg0 = {
46
62
  currency: CryptoCurrency;
47
63
  address: string;
@@ -151,10 +167,13 @@ export const mergeNfts = (oldNfts: NFT[], newNfts: NFT[]): NFT[] => {
151
167
  };
152
168
 
153
169
  export const makeSync =
154
- (
155
- getAccountShape: GetAccountShape,
156
- postSync: (initial: Account, synced: Account) => Account = (_, a) => a
157
- ): AccountBridge<any>["sync"] =>
170
+ ({
171
+ getAccountShape,
172
+ postSync = (_, a) => a,
173
+ }: {
174
+ getAccountShape: GetAccountShape;
175
+ postSync?: (initial: Account, synced: Account) => Account;
176
+ }): AccountBridge<any>["sync"] =>
158
177
  (initial, syncConfig): Observable<AccountUpdater> =>
159
178
  Observable.create((o) => {
160
179
  async function main() {
@@ -217,13 +236,45 @@ export const makeSync =
217
236
  main();
218
237
  });
219
238
 
239
+ const iterateResultWithAddressDerivation: IterateResult = async ({
240
+ transport,
241
+ index,
242
+ derivationsCache,
243
+ derivationScheme,
244
+ derivationMode,
245
+ currency,
246
+ }) => {
247
+ let res;
248
+ const freshAddressPath = runDerivationScheme(derivationScheme, currency, {
249
+ account: index,
250
+ });
251
+ res = derivationsCache[freshAddressPath];
252
+ if (!res) {
253
+ res = await getAddress(transport, {
254
+ currency,
255
+ path: freshAddressPath,
256
+ derivationMode,
257
+ });
258
+ derivationsCache[freshAddressPath] = res;
259
+ }
260
+ return res;
261
+ };
262
+
263
+ const defaultIterateResultBuilder = () =>
264
+ Promise.resolve(iterateResultWithAddressDerivation);
265
+
220
266
  export const makeScanAccounts =
221
- (
222
- getAccountShape: GetAccountShape,
267
+ ({
268
+ getAccountShape,
269
+ buildIterateResult = defaultIterateResultBuilder,
270
+ getAddressFn,
271
+ }: {
272
+ getAccountShape: GetAccountShape;
273
+ buildIterateResult?: IterateResultBuilder;
223
274
  getAddressFn?: (
224
275
  transport: Transport
225
- ) => (opts: GetAddressOptions) => Promise<Result>
226
- ): CurrencyBridge["scanAccounts"] =>
276
+ ) => (opts: GetAddressOptions) => Promise<Result>;
277
+ }): CurrencyBridge["scanAccounts"] =>
227
278
  ({ currency, deviceId, syncConfig }): Observable<ScanAccountEvent> =>
228
279
  Observable.create((o) => {
229
280
  let finished = false;
@@ -234,17 +285,17 @@ export const makeScanAccounts =
234
285
 
235
286
  const derivationsCache = {};
236
287
 
237
- // in future ideally what we want is:
238
- // return mergeMap(addressesObservable, address => fetchAccount(address))
239
288
  async function stepAccount(
240
289
  index,
241
- { address, path: freshAddressPath, ...rest },
290
+ res: Result,
242
291
  derivationMode,
243
292
  seedIdentifier,
244
293
  transport
245
294
  ): Promise<Account | null | undefined> {
246
295
  if (finished) return;
247
296
 
297
+ const { address, path: freshAddressPath, ...rest } = res;
298
+
248
299
  const accountShape: Partial<Account> = await getAccountShape(
249
300
  {
250
301
  transport,
@@ -313,6 +364,51 @@ export const makeScanAccounts =
313
364
  account.used = !isAccountEmpty(account);
314
365
  }
315
366
 
367
+ // Bitcoin needs to compute the freshAddressPath itself,
368
+ // so we update it afterwards
369
+ if (account?.freshAddressPath) {
370
+ res.address = account.freshAddress;
371
+ derivationsCache[account.freshAddressPath] = res;
372
+ }
373
+
374
+ log("scanAccounts", "derivationsCache", res);
375
+
376
+ log(
377
+ "scanAccounts",
378
+ `scanning ${currency.id} at ${freshAddressPath}: ${
379
+ res.address
380
+ } resulted of ${
381
+ account
382
+ ? `Account with ${account.operations.length} txs`
383
+ : "no account"
384
+ }`
385
+ );
386
+ if (!account) return;
387
+ account.name = !account.used
388
+ ? getNewAccountPlaceholderName({
389
+ currency,
390
+ index,
391
+ derivationMode,
392
+ })
393
+ : getAccountPlaceholderName({
394
+ currency,
395
+ index,
396
+ derivationMode,
397
+ });
398
+
399
+ const showNewAccount = shouldShowNewAccount(currency, derivationMode);
400
+
401
+ if (account.used || showNewAccount) {
402
+ log(
403
+ "debug",
404
+ `Emit 'discovered' event for a new account found. AccountUsed: ${account.used} - showNewAccount: ${showNewAccount}`
405
+ );
406
+ o.next({
407
+ type: "discovered",
408
+ account,
409
+ });
410
+ }
411
+
316
412
  return account;
317
413
  }
318
414
 
@@ -334,7 +430,7 @@ export const makeScanAccounts =
334
430
  "scanAccounts",
335
431
  `scanning ${currency.id} on derivationMode=${derivationMode}`
336
432
  );
337
- let result = derivationsCache[path];
433
+ let result: Result = derivationsCache[path];
338
434
 
339
435
  if (!result) {
340
436
  try {
@@ -343,6 +439,7 @@ export const makeScanAccounts =
343
439
  path,
344
440
  derivationMode,
345
441
  });
442
+
346
443
  derivationsCache[path] = result;
347
444
  } catch (e) {
348
445
  if (e instanceof UnsupportedDerivation) {
@@ -365,10 +462,7 @@ export const makeScanAccounts =
365
462
  derivationMode,
366
463
  currency,
367
464
  });
368
- const showNewAccount = shouldShowNewAccount(
369
- currency,
370
- derivationMode
371
- );
465
+
372
466
  const stopAt = isIterableDerivationMode(derivationMode) ? 255 : 1;
373
467
  const startsAt = getDerivationModeStartsAt(derivationMode);
374
468
 
@@ -377,6 +471,12 @@ export const makeScanAccounts =
377
471
  `start scanning account process. MandatoryEmptyAccountSkip ${mandatoryEmptyAccountSkip} / StartsAt: ${startsAt} - StopAt: ${stopAt}`
378
472
  );
379
473
 
474
+ const iterateResult = await buildIterateResult({
475
+ result,
476
+ derivationMode,
477
+ derivationScheme,
478
+ });
479
+
380
480
  for (let index = startsAt; index < stopAt; index++) {
381
481
  log("debug", `start to scan a new account. Index: ${index}`);
382
482
 
@@ -386,23 +486,17 @@ export const makeScanAccounts =
386
486
  }
387
487
 
388
488
  if (!derivationModeSupportsIndex(derivationMode, index)) continue;
389
- const freshAddressPath = runDerivationScheme(
489
+
490
+ const res = await iterateResult({
491
+ transport,
492
+ index,
493
+ derivationsCache,
494
+ derivationMode,
390
495
  derivationScheme,
391
496
  currency,
392
- {
393
- account: index,
394
- }
395
- );
396
- let res = derivationsCache[freshAddressPath];
497
+ });
397
498
 
398
- if (!res) {
399
- res = await getAddress(transport, {
400
- currency,
401
- path: freshAddressPath,
402
- derivationMode,
403
- });
404
- derivationsCache[freshAddressPath] = res;
405
- }
499
+ if (!res) break;
406
500
 
407
501
  const account = await stepAccount(
408
502
  index,
@@ -411,54 +505,14 @@ export const makeScanAccounts =
411
505
  seedIdentifier,
412
506
  transport
413
507
  );
414
- // Bitcoin needs to compute the freshAddressPath itself,
415
- // so we update it afterwards
416
- if (account?.freshAddressPath) {
417
- res.address = account.freshAddress;
418
- derivationsCache[account.freshAddressPath] = res;
419
- }
420
- log("scanAccounts", "derivationsCache", res);
421
-
422
- log(
423
- "scanAccounts",
424
- `scanning ${currency.id} at ${freshAddressPath}: ${
425
- res.address
426
- } resulted of ${
427
- account
428
- ? `Account with ${account.operations.length} txs`
429
- : "no account"
430
- }`
431
- );
432
- if (!account) return;
433
- account.name = !account.used
434
- ? getNewAccountPlaceholderName({
435
- currency,
436
- index,
437
- derivationMode,
438
- })
439
- : getAccountPlaceholderName({
440
- currency,
441
- index,
442
- derivationMode,
443
- });
444
-
445
- if (account.used || showNewAccount) {
446
- log(
447
- "debug",
448
- `Emit 'discovered' event for a new account found. AccountUsed: ${account.used} - showNewAccount: ${showNewAccount}`
449
- );
450
- o.next({
451
- type: "discovered",
452
- account,
453
- });
454
- }
455
508
 
456
- if (!account.used) {
509
+ if (account && !account.used) {
457
510
  if (emptyCount >= mandatoryEmptyAccountSkip) break;
458
511
  emptyCount++;
459
512
  }
460
513
  }
461
514
  }
515
+ // }
462
516
 
463
517
  o.complete();
464
518
  } catch (e) {
package/src/cross.ts CHANGED
@@ -307,14 +307,15 @@ export const accountDataToAccount = ({
307
307
  type === "libcore" ||
308
308
  // FIXME Dirty hack, since we have no way here to know if "xpubOrAddress" is one or the other.
309
309
  // Proposed fix: https://ledgerhq.atlassian.net/browse/LL-7437
310
- currency.family === "bitcoin" ||
311
- currency.family === "tezos"
310
+ currency.family === "bitcoin"
312
311
  ) {
313
312
  // In libcore implementation, xpubOrAddress field always go in the xpub
314
313
  // In JS implementation, only Bitcoin-like currencies store the xpub
315
314
  xpub = xpubOrAddress;
316
315
  } else {
317
- if (!freshAddress) {
316
+ if (currency.family === "tezos") {
317
+ xpub = xpubOrAddress;
318
+ } else if (!freshAddress) {
318
319
  // otherwise, it's the freshAddress
319
320
  freshAddress = xpubOrAddress;
320
321
  }