@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
@@ -1,15 +1,18 @@
1
- import { findLast, filter, uniqBy, findIndex, has } from "lodash";
1
+ import { findLast, filter, uniqBy, findIndex, isEmpty } from "lodash";
2
2
  import Base from "../crypto/base";
3
3
  import { Input, IStorage, Output, TX, Address } from "./types";
4
4
 
5
5
  // a mock storage class that just use js objects
6
6
  // sql.js would be perfect for the job
7
7
  class BitcoinLikeStorage implements IStorage {
8
- txs: TX[] = [];
8
+ private txs: TX[] = [];
9
9
 
10
- // indexes
10
+ // indexe: address + hash -> tx
11
11
  primaryIndex: { [key: string]: number } = {};
12
12
 
13
+ // indexe: account + index -> tx
14
+ accountIndex: { [key: string]: number[] } = {};
15
+
13
16
  // accounting
14
17
  unspentUtxos: { [key: string]: Output[] } = {};
15
18
 
@@ -20,23 +23,35 @@ class BitcoinLikeStorage implements IStorage {
20
23
  // returning unordered tx within the same block)
21
24
  spentUtxos: { [key: string]: Input[] } = {};
22
25
 
23
- getLastTx(txFilter: {
24
- account?: number;
25
- index?: number;
26
- address?: string;
27
- confirmed?: boolean;
28
- }) {
26
+ getLastTx(txFilter: { account: number; index: number; confirmed?: boolean }) {
27
+ if (
28
+ typeof this.accountIndex[`${txFilter.account}-${txFilter.index}`] ===
29
+ "undefined"
30
+ ) {
31
+ return undefined;
32
+ }
29
33
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
30
34
  // @ts-ignore
31
- const tx: TX | undefined = findLast(this.txs, (t) => {
32
- return (
33
- (!has(txFilter, "account") || t.account === txFilter.account) &&
34
- (!has(txFilter, "index") || t.index === txFilter.index) &&
35
- (!has(txFilter, "address") || t.address === txFilter.address) &&
36
- (!has(txFilter, "confirmed") ||
35
+ const tx: TX | undefined = findLast(
36
+ this.accountIndex[`${txFilter.account}-${txFilter.index}`].map(
37
+ (i) => this.txs[i]
38
+ ),
39
+ (t) => {
40
+ return (
41
+ typeof txFilter.confirmed === "undefined" ||
37
42
  (txFilter.confirmed && t.block) ||
38
- (!txFilter.confirmed && !t.block))
39
- );
43
+ (!txFilter.confirmed && !t.block)
44
+ );
45
+ }
46
+ );
47
+ return tx;
48
+ }
49
+
50
+ getLastUnconfirmedTx() {
51
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
52
+ // @ts-ignore
53
+ const tx: TX | undefined = findLast(this.txs, (t) => {
54
+ return !t.block;
40
55
  });
41
56
  return tx;
42
57
  }
@@ -63,8 +78,14 @@ class BitcoinLikeStorage implements IStorage {
63
78
  if (this.txs[this.primaryIndex[index]]) {
64
79
  return;
65
80
  }
66
-
67
- this.primaryIndex[index] = this.txs.push(tx) - 1;
81
+ if (
82
+ typeof this.accountIndex[`${tx.account}-${tx.index}`] === "undefined"
83
+ ) {
84
+ this.accountIndex[`${tx.account}-${tx.index}`] = [];
85
+ }
86
+ const idx = this.txs.push(tx) - 1;
87
+ this.primaryIndex[index] = idx;
88
+ this.accountIndex[`${tx.account}-${tx.index}`].push(idx);
68
89
  this.unspentUtxos[indexAddress] = this.unspentUtxos[indexAddress] || [];
69
90
  this.spentUtxos[indexAddress] = this.spentUtxos[indexAddress] || [];
70
91
 
@@ -117,7 +138,7 @@ class BitcoinLikeStorage implements IStorage {
117
138
  removeTxs(txsFilter: { account: number; index: number }) {
118
139
  const newTxs: TX[] = [];
119
140
  this.primaryIndex = {};
120
-
141
+ this.accountIndex = {};
121
142
  this.txs.forEach((tx: TX) => {
122
143
  // clean
123
144
  const indexAddress = tx.address;
@@ -131,8 +152,8 @@ class BitcoinLikeStorage implements IStorage {
131
152
  delete this.unspentUtxos[indexAddress];
132
153
  delete this.spentUtxos[indexAddress];
133
154
  });
134
-
135
155
  this.txs = newTxs;
156
+ this.createAccountIndex();
136
157
  }
137
158
 
138
159
  // We are a bit ugly because we can't rely undo unspentUTXO
@@ -141,7 +162,7 @@ class BitcoinLikeStorage implements IStorage {
141
162
  const newTxs: TX[] = [];
142
163
  const txsToReAdd: TX[] = [];
143
164
  this.primaryIndex = {};
144
-
165
+ this.accountIndex = {};
145
166
  this.txs.forEach((tx: TX) => {
146
167
  // clean
147
168
  const indexAddress = tx.address;
@@ -161,6 +182,7 @@ class BitcoinLikeStorage implements IStorage {
161
182
  });
162
183
 
163
184
  this.txs = newTxs;
185
+ this.createAccountIndex();
164
186
  this.appendTxs(txsToReAdd);
165
187
  }
166
188
 
@@ -175,6 +197,7 @@ class BitcoinLikeStorage implements IStorage {
175
197
  return {
176
198
  txs: this.txs,
177
199
  primaryIndex: this.primaryIndex,
200
+ accountIndex: this.accountIndex,
178
201
  unspentUtxos: this.unspentUtxos,
179
202
  addressCache: this.addressCache,
180
203
  };
@@ -183,14 +206,23 @@ class BitcoinLikeStorage implements IStorage {
183
206
  loadSync(data: {
184
207
  txs: TX[];
185
208
  primaryIndex: { [key: string]: number };
209
+ accountIndex: { [key: string]: number[] };
186
210
  unspentUtxos: { [key: string]: Output[] };
187
211
  addressCache: { [key: string]: string };
188
212
  }) {
189
213
  this.txs = data.txs;
190
214
  this.primaryIndex = data.primaryIndex;
215
+ this.accountIndex = data.accountIndex;
191
216
  this.unspentUtxos = data.unspentUtxos;
192
217
  this.addressCache = data.addressCache;
193
218
  Base.addressCache = { ...Base.addressCache, ...this.addressCache };
219
+ if (
220
+ (!this.accountIndex || isEmpty(this.accountIndex)) &&
221
+ this.txs.length > 0
222
+ ) {
223
+ this.accountIndex = {};
224
+ this.createAccountIndex();
225
+ }
194
226
  }
195
227
 
196
228
  async export() {
@@ -200,11 +232,23 @@ class BitcoinLikeStorage implements IStorage {
200
232
  async load(data: {
201
233
  txs: TX[];
202
234
  primaryIndex: { [key: string]: number };
235
+ accountIndex: { [key: string]: number[] };
203
236
  unspentUtxos: { [key: string]: Output[] };
204
237
  addressCache: { [key: string]: string };
205
238
  }) {
206
239
  return this.loadSync(data);
207
240
  }
241
+
242
+ private createAccountIndex() {
243
+ this.txs.forEach((tx: TX, idx: number) => {
244
+ if (
245
+ typeof this.accountIndex[`${tx.account}-${tx.index}`] === "undefined"
246
+ ) {
247
+ this.accountIndex[`${tx.account}-${tx.index}`] = [];
248
+ }
249
+ this.accountIndex[`${tx.account}-${tx.index}`].push(idx);
250
+ });
251
+ }
208
252
  }
209
253
 
210
254
  export default BitcoinLikeStorage;
@@ -45,11 +45,11 @@ export interface IStorage {
45
45
  appendTxs(txs: TX[]): number;
46
46
  getAddressUnspentUtxos(address: Address): Output[];
47
47
  getLastTx(txFilter: {
48
- account?: number;
49
- index?: number;
50
- address?: string;
48
+ account: number;
49
+ index: number;
51
50
  confirmed?: boolean;
52
51
  }): TX | undefined;
52
+ getLastUnconfirmedTx(): TX | undefined;
53
53
  getTx(address: string, hash: string): TX | undefined;
54
54
  getUniquesAddresses(addressesFilter: {
55
55
  account?: number;
@@ -59,7 +59,7 @@ class Xpub extends EventEmitter {
59
59
  }
60
60
 
61
61
  async syncAddress(account: number, index: number) {
62
- const address = this.crypto.getAddress(
62
+ const address = await this.crypto.getAddress(
63
63
  this.derivationMode,
64
64
  this.xpub,
65
65
  account,
@@ -176,7 +176,7 @@ class Xpub extends EventEmitter {
176
176
  }
177
177
 
178
178
  this.emitSynced({ type: "all", account });
179
- this.freshAddress = this.crypto.getAddress(
179
+ this.freshAddress = await this.crypto.getAddress(
180
180
  this.derivationMode,
181
181
  this.xpub,
182
182
  0,
@@ -234,7 +234,7 @@ class Xpub extends EventEmitter {
234
234
  index = lastIndex + gap;
235
235
  }
236
236
  const address: Address = {
237
- address: this.crypto.getAddress(
237
+ address: await this.crypto.getAddress(
238
238
  this.derivationMode,
239
239
  this.xpub,
240
240
  account,
@@ -1,4 +1,3 @@
1
- import type { Account } from "../../types";
2
1
  import { encodeAccountId } from "../../account";
3
2
  import type { GetAccountShape } from "../../bridge/jsHelpers";
4
3
  import { makeSync, makeScanAccounts, mergeOps } from "../../bridge/jsHelpers";
@@ -32,9 +31,5 @@ const getAccountShape: GetAccountShape = async (info) => {
32
31
  return { ...shape, operations };
33
32
  };
34
33
 
35
- const postSync = (_initial: Account, parent: Account) => {
36
- return parent;
37
- };
38
-
39
- export const scanAccounts = makeScanAccounts(getAccountShape);
40
- export const sync = makeSync(getAccountShape, postSync);
34
+ export const scanAccounts = makeScanAccounts({ getAccountShape });
35
+ export const sync = makeSync({ getAccountShape });
@@ -3,15 +3,12 @@ import estimateMaxSpendable from "../js-estimateMaxSpendable";
3
3
  import getTransactionStatus from "../js-getTransactionStatus";
4
4
  import prepareTransaction from "../js-prepareTransaction";
5
5
  import signOperation from "../js-signOperation";
6
- import { sync, getAccountShape } from "../js-synchronisation";
6
+ import { sync, scanAccounts } from "../js-synchronisation";
7
7
  import updateTransaction from "../js-updateTransaction";
8
8
  import { AccountBridge, CurrencyBridge, CryptoCurrency } from "../../../types";
9
9
  import type { CosmosValidatorItem, Transaction } from "../types";
10
10
  import { getValidators, hydrateValidators } from "../validators";
11
- import {
12
- makeAccountBridgeReceive,
13
- makeScanAccounts,
14
- } from "../../../bridge/jsHelpers";
11
+ import { makeAccountBridgeReceive } from "../../../bridge/jsHelpers";
15
12
  import { broadcast } from "../api/Cosmos";
16
13
  import {
17
14
  asSafeCosmosPreloadData,
@@ -47,7 +44,7 @@ const currencyBridge: CurrencyBridge = {
47
44
  hydrateValidators(validators);
48
45
  setCosmosPreloadData(asSafeCosmosPreloadData(data));
49
46
  },
50
- scanAccounts: makeScanAccounts(getAccountShape),
47
+ scanAccounts,
51
48
  };
52
49
 
53
50
  const accountBridge: AccountBridge<Transaction> = {
@@ -1,6 +1,11 @@
1
- import { Account, Operation, OperationType } from "../../types";
1
+ import { Operation, OperationType } from "../../types";
2
2
  import { BigNumber } from "bignumber.js";
3
- import { makeSync, GetAccountShape, mergeOps } from "../../bridge/jsHelpers";
3
+ import {
4
+ makeSync,
5
+ makeScanAccounts,
6
+ GetAccountShape,
7
+ mergeOps,
8
+ } from "../../bridge/jsHelpers";
4
9
  import { encodeAccountId } from "../../account";
5
10
  import { getAccountInfo } from "./api/Cosmos";
6
11
  import { pubkeyToAddress, decodeBech32Pubkey } from "@cosmjs/amino";
@@ -153,8 +158,6 @@ const txToOps = (info: any, id: string, txs: any): Operation[] => {
153
158
  return ops;
154
159
  };
155
160
 
156
- const postSync = (initial: Account, parent: Account) => parent;
157
-
158
161
  export const getAccountShape: GetAccountShape = async (info) => {
159
162
  const { address, currency, derivationMode, initialAccount } = info;
160
163
  let xpubOrAddress = address;
@@ -235,4 +238,5 @@ export const getAccountShape: GetAccountShape = async (info) => {
235
238
  return { ...shape, operations };
236
239
  };
237
240
 
238
- export const sync = makeSync(getAccountShape, postSync);
241
+ export const scanAccounts = makeScanAccounts({ getAccountShape });
242
+ export const sync = makeSync({ getAccountShape });
@@ -1,4 +1,3 @@
1
- import type { Account } from "../../types";
2
1
  import { encodeAccountId } from "../../account";
3
2
  import type { GetAccountShape } from "../../bridge/jsHelpers";
4
3
  import { makeSync, makeScanAccounts, mergeOps } from "../../bridge/jsHelpers";
@@ -59,7 +58,5 @@ const getAccountShape: GetAccountShape = async (info) => {
59
58
  return { ...shape, operations };
60
59
  };
61
60
 
62
- const postSync = (initial: Account, parent: Account) => parent;
63
-
64
- export const scanAccounts = makeScanAccounts(getAccountShape);
65
- export const sync = makeSync(getAccountShape, postSync);
61
+ export const scanAccounts = makeScanAccounts({ getAccountShape });
62
+ export const sync = makeSync({ getAccountShape });
@@ -1,4 +1,3 @@
1
- import type { Account } from "../../types";
2
1
  import { encodeAccountId } from "../../account";
3
2
  import type { GetAccountShape } from "../../bridge/jsHelpers";
4
3
  import { makeSync, makeScanAccounts, mergeOps } from "../../bridge/jsHelpers";
@@ -36,7 +35,5 @@ const getAccountShape: GetAccountShape = async (info) => {
36
35
  return { ...shape, operations };
37
36
  };
38
37
 
39
- const postSync = (initial: Account, parent: Account) => parent;
40
-
41
- export const scanAccounts = makeScanAccounts(getAccountShape);
42
- export const sync = makeSync(getAccountShape, postSync);
38
+ export const scanAccounts = makeScanAccounts({ getAccountShape });
39
+ export const sync = makeSync({ getAccountShape });
@@ -45,8 +45,8 @@ const broadcast = async ({
45
45
  return patchOperationWithHash(operation, hash);
46
46
  };
47
47
 
48
- const scanAccounts = makeScanAccounts(getAccountShape);
49
- const sync = makeSync(getAccountShape, postSyncPatch);
48
+ const scanAccounts = makeScanAccounts({ getAccountShape });
49
+ const sync = makeSync({ getAccountShape, postSync: postSyncPatch });
50
50
 
51
51
  const createTransaction = (): Transaction => ({
52
52
  family: "ethereum",
@@ -59,20 +59,23 @@ export const getAccountShape: GetAccountShape = async (
59
59
  const txsP = fetchAllTransactions(api, address, pullFromBlockHash);
60
60
  const currentBlockP = fetchCurrentBlock(currency);
61
61
  const balanceP = api.getAccountBalance(address);
62
- const [txs, currentBlock] = await Promise.all([txsP, currentBlockP]);
62
+ const [txs, currentBlock, balance] = await Promise.all([
63
+ txsP,
64
+ currentBlockP,
65
+ balanceP,
66
+ ]);
63
67
  const blockHeight = currentBlock.height.toNumber();
64
68
 
65
69
  if (!pullFromBlockHash && txs.length === 0) {
66
70
  log("ethereum", "no ops on " + address);
67
71
  return {
68
72
  id: accountId,
69
- balance: new BigNumber(0),
73
+ balance,
70
74
  subAccounts: [],
71
75
  blockHeight,
72
76
  };
73
77
  }
74
78
 
75
- const balance = await balanceP;
76
79
  // transform transactions into operations
77
80
  let newOps = flatMap(txs, txToOps({ address, id: accountId, currency }));
78
81
  // extracting out the sub operations by token account
@@ -173,7 +173,7 @@ const prepareTransaction = async (
173
173
  return t;
174
174
  };
175
175
 
176
- const sync = makeSync(getAccountShape);
176
+ const sync = makeSync({ getAccountShape });
177
177
 
178
178
  const broadcast: BroadcastFnSignature = async ({
179
179
  signedOperation: { operation, signature },
@@ -2,7 +2,7 @@ import { makeScanAccounts } from "../../../bridge/jsHelpers";
2
2
  import { getAccountShape } from "./utils/utils";
3
3
  import { CurrencyBridge } from "../../../types";
4
4
 
5
- const scanAccounts = makeScanAccounts(getAccountShape);
5
+ const scanAccounts = makeScanAccounts({ getAccountShape });
6
6
 
7
7
  export const currencyBridge: CurrencyBridge = {
8
8
  preload: () => Promise.resolve({}),
@@ -23,9 +23,10 @@ const acceptTransaction: DeviceAction<Transaction, any> = deviceActionFlow({
23
23
  {
24
24
  title: "Value",
25
25
  button: "Rr",
26
- expectedValue: ({ account, transaction }) =>
27
- formatCurrencyUnit(account.unit, transaction.amount, {
26
+ expectedValue: ({ account, status }) =>
27
+ formatCurrencyUnit(account.unit, status.amount, {
28
28
  disableRounding: true,
29
+ showAllDigits: true,
29
30
  }),
30
31
  },
31
32
  {
@@ -39,6 +40,7 @@ const acceptTransaction: DeviceAction<Transaction, any> = deviceActionFlow({
39
40
  expectedValue: ({ account, transaction }) =>
40
41
  formatCurrencyUnit(account.unit, transaction.gasPremium, {
41
42
  disableRounding: true,
43
+ showAllDigits: true,
42
44
  }),
43
45
  },
44
46
  {
@@ -47,10 +49,16 @@ const acceptTransaction: DeviceAction<Transaction, any> = deviceActionFlow({
47
49
  expectedValue: ({ account, transaction }) =>
48
50
  formatCurrencyUnit(account.unit, transaction.gasFeeCap, {
49
51
  disableRounding: true,
52
+ showAllDigits: true,
50
53
  }),
51
54
  },
52
55
  {
53
- title: "Approve",
56
+ title: "Method",
57
+ button: "Rr",
58
+ expectedValue: () => "Transfer",
59
+ },
60
+ {
61
+ title: "APPROVE",
54
62
  button: "LRlr",
55
63
  },
56
64
  ],
@@ -132,8 +132,8 @@ const getAccountShape = async (info) => {
132
132
  };
133
133
  };
134
134
 
135
- const scanAccounts = makeScanAccounts(getAccountShape);
136
- const sync = makeSync(getAccountShape);
135
+ const scanAccounts = makeScanAccounts({ getAccountShape });
136
+ const sync = makeSync({ getAccountShape });
137
137
  const currencyBridge: CurrencyBridge = {
138
138
  preload: () => Promise.resolve({}),
139
139
  hydrate: () => {},
@@ -54,9 +54,5 @@ const getAccountShape: GetAccountShape = async (info) => {
54
54
  return { ...shape, operations } as Partial<Account>;
55
55
  };
56
56
 
57
- const postSync = (_initial: Account, parent: Account) => {
58
- return parent;
59
- };
60
-
61
- export const scanAccounts = makeScanAccounts(getAccountShape);
62
- export const sync = makeSync(getAccountShape, postSync);
57
+ export const scanAccounts = makeScanAccounts({ getAccountShape });
58
+ export const sync = makeSync({ getAccountShape });
@@ -6,6 +6,7 @@ import {
6
6
  import {
7
7
  Connection,
8
8
  FeeCalculator,
9
+ FetchMiddleware,
9
10
  PublicKey,
10
11
  sendAndConfirmRawTransaction,
11
12
  SignaturesForAddressOptions,
@@ -57,8 +58,24 @@ export type ChainAPI = Readonly<{
57
58
  config: Config;
58
59
  }>;
59
60
 
60
- export function getChainAPI(config: Config): ChainAPI {
61
- const connection = () => new Connection(config.endpoint, "finalized");
61
+ export function getChainAPI(
62
+ config: Config,
63
+ logger?: (url: string, options: any) => void
64
+ ): ChainAPI {
65
+ const fetchMiddleware: FetchMiddleware | undefined =
66
+ logger === undefined
67
+ ? undefined
68
+ : (url, options, fetch) => {
69
+ logger(url, options);
70
+ fetch(url, options);
71
+ };
72
+
73
+ const connection = () => {
74
+ return new Connection(config.endpoint, {
75
+ commitment: "finalized",
76
+ fetchMiddleware,
77
+ });
78
+ };
62
79
 
63
80
  return {
64
81
  getBalance: (address: string) =>
@@ -0,0 +1,99 @@
1
+ import { log } from "@ledgerhq/logs";
2
+ import { getEnv } from "../../../env";
3
+ import { ChainAPI } from "./chain";
4
+
5
+ export function traced(api: ChainAPI): ChainAPI {
6
+ const state = {
7
+ reqId: 0,
8
+ reqStartTime: new Map<number, number>(),
9
+ };
10
+
11
+ const startReqTrace = () => {
12
+ state.reqId += 1;
13
+ state.reqStartTime.set(state.reqId, Date.now());
14
+ return state.reqId;
15
+ };
16
+
17
+ const stopReqTrace = (reqId: number) => {
18
+ const reqStartTime = state.reqStartTime.get(reqId);
19
+ if (reqStartTime === undefined) {
20
+ log("warn", `request start time not found for request id <${reqId}>`);
21
+ return {
22
+ duration: 0,
23
+ };
24
+ }
25
+ state.reqStartTime.delete(reqId);
26
+ return {
27
+ duration: Date.now() - reqStartTime,
28
+ };
29
+ };
30
+
31
+ const proxy: ChainAPI = new Proxy(api, {
32
+ get(target, propKey, receiver) {
33
+ if (typeof propKey === "symbol") {
34
+ throw new Error("symbols not supported");
35
+ }
36
+ const targetValue = Reflect.get(target, propKey, receiver);
37
+ if (typeof targetValue === "function") {
38
+ return function (...args: unknown[]) {
39
+ const reqId = startReqTrace();
40
+ log("network", formatMsg({ reqId, msg: `calling <${propKey}>` }), {
41
+ args,
42
+ });
43
+ const result = targetValue.apply(this, args);
44
+ if (result instanceof Promise) {
45
+ return result
46
+ .then((answer) => {
47
+ const { duration } = stopReqTrace(reqId);
48
+ log(
49
+ "network-success",
50
+ formatMsg({ reqId, msg: "success", duration }),
51
+ getEnv("DEBUG_HTTP_RESPONSE") ? { answer } : undefined
52
+ );
53
+ return answer;
54
+ })
55
+ .catch((error) => {
56
+ const { duration } = stopReqTrace(reqId);
57
+ log(
58
+ "network-error",
59
+ formatMsg({ reqId, msg: "error", duration }),
60
+ { error }
61
+ );
62
+ throw error;
63
+ });
64
+ } else {
65
+ const { duration } = stopReqTrace(reqId);
66
+ log(
67
+ "info",
68
+ formatMsg({ reqId, msg: "sync result", duration }),
69
+ getEnv("DEBUG_HTTP_RESPONSE") ? { result } : undefined
70
+ );
71
+ return result;
72
+ }
73
+ };
74
+ } else {
75
+ return targetValue;
76
+ }
77
+ },
78
+ });
79
+
80
+ return proxy;
81
+ }
82
+
83
+ function formatMsg({
84
+ reqId,
85
+ msg,
86
+ duration,
87
+ }: {
88
+ reqId: number;
89
+ msg?: string;
90
+ duration?: number;
91
+ }) {
92
+ const parts = [
93
+ `solana req id: ${reqId}`,
94
+ msg ?? "",
95
+ duration === undefined ? "" : `took ${duration.toFixed(0)}ms`,
96
+ ];
97
+
98
+ return parts.join(", ");
99
+ }
@@ -69,8 +69,8 @@ function makeSyncAndScan(getChainAPI: (config: Config) => Promise<ChainAPI>) {
69
69
  return getAccountShapeWithAPI(info, chainAPI);
70
70
  };
71
71
  return {
72
- sync: makeSyncHelper(getAccountShape),
73
- scan: makeScanHelper(getAccountShape),
72
+ sync: makeSyncHelper({ getAccountShape }),
73
+ scan: makeScanHelper({ getAccountShape }),
74
74
  };
75
75
  }
76
76
 
@@ -2,9 +2,20 @@ import { cached, Config, getChainAPI, queued } from "../api";
2
2
  import { makeLRUCache } from "../../../cache";
3
3
  import { makeBridges } from "./bridge";
4
4
  import { minutes } from "../api/cached";
5
+ import { log } from "@ledgerhq/logs";
6
+ import { traced } from "../api/traced";
7
+
8
+ const httpRequestLogger = (url: string, options: any) => {
9
+ log("network", url, {
10
+ method: options?.method,
11
+ body: options?.body,
12
+ params: options?.params,
13
+ });
14
+ };
5
15
 
6
16
  const getAPI = makeLRUCache(
7
- (config: Config) => Promise.resolve(getChainAPI(config)),
17
+ (config: Config) =>
18
+ Promise.resolve(traced(getChainAPI(config, httpRequestLogger))),
8
19
  (config) => config.endpoint,
9
20
  minutes(1000)
10
21
  );
@@ -1,4 +1,3 @@
1
- import type { Account } from "../../types";
2
1
  import { encodeAccountId } from "../../account";
3
2
  import type { GetAccountShape } from "../../bridge/jsHelpers";
4
3
  import { makeScanAccounts, makeSync, mergeOps } from "../../bridge/jsHelpers";
@@ -32,9 +31,5 @@ const getAccountShape: GetAccountShape = async (info) => {
32
31
  return { ...shape, operations };
33
32
  };
34
33
 
35
- const postSync = (initial: Account, parent: Account) => {
36
- return parent;
37
- };
38
-
39
- export const sync = makeSync(getAccountShape, postSync);
40
- export const scanAccounts = makeScanAccounts(getAccountShape);
34
+ export const sync = makeSync({ getAccountShape });
35
+ export const scanAccounts = makeScanAccounts({ getAccountShape });