@ledgerhq/live-common 21.14.1 → 21.16.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 (265) hide show
  1. package/lib/__tests__/families/bitcoin/wallet-btc/utils.test.js +85 -0
  2. package/lib/__tests__/families/bitcoin/wallet-btc/utils.test.js.map +1 -1
  3. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.estimateMaxSpendable.test.js +1 -1
  4. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.estimateMaxSpendable.test.js.map +1 -1
  5. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.integration.test.js +2 -2
  6. package/lib/__tests__/families/bitcoin/wallet-btc/wallet.integration.test.js.map +1 -1
  7. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.pickingStrategies.integration.test.js +20 -10
  8. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.pickingStrategies.integration.test.js.map +1 -1
  9. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.NP2WPKH.integration.test.js +1 -1
  10. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.NP2WPKH.integration.test.js.map +1 -1
  11. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.P2WPKH.integration.test.js +1 -1
  12. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.P2WPKH.integration.test.js.map +1 -1
  13. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.integration.test.js +2 -2
  14. package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.integration.test.js.map +1 -1
  15. package/lib/account/formatters.d.ts.map +1 -1
  16. package/lib/account/formatters.js +33 -1
  17. package/lib/account/formatters.js.map +1 -1
  18. package/lib/account/groupOperations.js +1 -1
  19. package/lib/account/groupOperations.js.map +1 -1
  20. package/lib/account/pending.d.ts +1 -0
  21. package/lib/account/pending.d.ts.map +1 -1
  22. package/lib/account/serialization.d.ts +6 -4
  23. package/lib/account/serialization.d.ts.map +1 -1
  24. package/lib/account/serialization.js +47 -9
  25. package/lib/account/serialization.js.map +1 -1
  26. package/lib/api/Ethereum.d.ts +22 -1
  27. package/lib/api/Ethereum.d.ts.map +1 -1
  28. package/lib/api/Ethereum.js +21 -1
  29. package/lib/api/Ethereum.js.map +1 -1
  30. package/lib/apps/polyfill.d.ts.map +1 -1
  31. package/lib/apps/polyfill.js +3 -0
  32. package/lib/apps/polyfill.js.map +1 -1
  33. package/lib/bridge/jsHelpers.d.ts +2 -1
  34. package/lib/bridge/jsHelpers.d.ts.map +1 -1
  35. package/lib/bridge/jsHelpers.js +27 -1
  36. package/lib/bridge/jsHelpers.js.map +1 -1
  37. package/lib/csvExport.d.ts.map +1 -1
  38. package/lib/csvExport.js +3 -1
  39. package/lib/csvExport.js.map +1 -1
  40. package/lib/currencies/sortByMarketcap.d.ts.map +1 -1
  41. package/lib/currencies/sortByMarketcap.js +8 -1
  42. package/lib/currencies/sortByMarketcap.js.map +1 -1
  43. package/lib/currencies/support.d.ts.map +1 -1
  44. package/lib/currencies/support.js.map +1 -1
  45. package/lib/env.d.ts +15 -5
  46. package/lib/env.d.ts.map +1 -1
  47. package/lib/env.js +11 -0
  48. package/lib/env.js.map +1 -1
  49. package/lib/env.react.d.ts +1 -1
  50. package/lib/env.react.d.ts.map +1 -1
  51. package/lib/families/bitcoin/datasets/bitcoin.d.ts.map +1 -1
  52. package/lib/families/bitcoin/datasets/bitcoin.js +4 -0
  53. package/lib/families/bitcoin/datasets/bitcoin.js.map +1 -1
  54. package/lib/families/bitcoin/datasets/bitcoin_cash.d.ts.map +1 -1
  55. package/lib/families/bitcoin/datasets/bitcoin_cash.js +4 -0
  56. package/lib/families/bitcoin/datasets/bitcoin_cash.js.map +1 -1
  57. package/lib/families/bitcoin/datasets/bitcoin_gold.d.ts.map +1 -1
  58. package/lib/families/bitcoin/datasets/bitcoin_gold.js +4 -0
  59. package/lib/families/bitcoin/datasets/bitcoin_gold.js.map +1 -1
  60. package/lib/families/bitcoin/datasets/dash.d.ts.map +1 -1
  61. package/lib/families/bitcoin/datasets/dash.js +4 -0
  62. package/lib/families/bitcoin/datasets/dash.js.map +1 -1
  63. package/lib/families/bitcoin/datasets/decred.d.ts.map +1 -1
  64. package/lib/families/bitcoin/datasets/decred.js +4 -0
  65. package/lib/families/bitcoin/datasets/decred.js.map +1 -1
  66. package/lib/families/bitcoin/datasets/digibyte.d.ts.map +1 -1
  67. package/lib/families/bitcoin/datasets/digibyte.js +4 -0
  68. package/lib/families/bitcoin/datasets/digibyte.js.map +1 -1
  69. package/lib/families/bitcoin/datasets/dogecoin.d.ts.map +1 -1
  70. package/lib/families/bitcoin/datasets/dogecoin.js +4 -0
  71. package/lib/families/bitcoin/datasets/dogecoin.js.map +1 -1
  72. package/lib/families/bitcoin/datasets/komodo.d.ts.map +1 -1
  73. package/lib/families/bitcoin/datasets/komodo.js +4 -0
  74. package/lib/families/bitcoin/datasets/komodo.js.map +1 -1
  75. package/lib/families/bitcoin/datasets/litecoin.d.ts.map +1 -1
  76. package/lib/families/bitcoin/datasets/litecoin.js +4 -0
  77. package/lib/families/bitcoin/datasets/litecoin.js.map +1 -1
  78. package/lib/families/bitcoin/datasets/peercoin.d.ts.map +1 -1
  79. package/lib/families/bitcoin/datasets/peercoin.js +4 -0
  80. package/lib/families/bitcoin/datasets/peercoin.js.map +1 -1
  81. package/lib/families/bitcoin/datasets/pivx.d.ts.map +1 -1
  82. package/lib/families/bitcoin/datasets/pivx.js +4 -0
  83. package/lib/families/bitcoin/datasets/pivx.js.map +1 -1
  84. package/lib/families/bitcoin/datasets/qtum.d.ts.map +1 -1
  85. package/lib/families/bitcoin/datasets/qtum.js +4 -0
  86. package/lib/families/bitcoin/datasets/qtum.js.map +1 -1
  87. package/lib/families/bitcoin/datasets/stakenet.d.ts.map +1 -1
  88. package/lib/families/bitcoin/datasets/stakenet.js +4 -0
  89. package/lib/families/bitcoin/datasets/stakenet.js.map +1 -1
  90. package/lib/families/bitcoin/datasets/vertcoin.d.ts.map +1 -1
  91. package/lib/families/bitcoin/datasets/vertcoin.js +4 -0
  92. package/lib/families/bitcoin/datasets/vertcoin.js.map +1 -1
  93. package/lib/families/bitcoin/datasets/viacoin.d.ts.map +1 -1
  94. package/lib/families/bitcoin/datasets/viacoin.js +4 -0
  95. package/lib/families/bitcoin/datasets/viacoin.js.map +1 -1
  96. package/lib/families/bitcoin/datasets/zcash.d.ts.map +1 -1
  97. package/lib/families/bitcoin/datasets/zcash.js +4 -0
  98. package/lib/families/bitcoin/datasets/zcash.js.map +1 -1
  99. package/lib/families/bitcoin/datasets/zencash.d.ts.map +1 -1
  100. package/lib/families/bitcoin/datasets/zencash.js +4 -0
  101. package/lib/families/bitcoin/datasets/zencash.js.map +1 -1
  102. package/lib/families/bitcoin/js-buildTransaction.d.ts.map +1 -1
  103. package/lib/families/bitcoin/js-buildTransaction.js +1 -1
  104. package/lib/families/bitcoin/js-buildTransaction.js.map +1 -1
  105. package/lib/families/bitcoin/js-estimateMaxSpendable.d.ts.map +1 -1
  106. package/lib/families/bitcoin/js-estimateMaxSpendable.js +1 -1
  107. package/lib/families/bitcoin/js-estimateMaxSpendable.js.map +1 -1
  108. package/lib/families/bitcoin/js-synchronisation.d.ts.map +1 -1
  109. package/lib/families/bitcoin/js-synchronisation.js +26 -14
  110. package/lib/families/bitcoin/js-synchronisation.js.map +1 -1
  111. package/lib/families/bitcoin/logic.d.ts +1 -1
  112. package/lib/families/bitcoin/logic.d.ts.map +1 -1
  113. package/lib/families/bitcoin/logic.js +6 -0
  114. package/lib/families/bitcoin/logic.js.map +1 -1
  115. package/lib/families/bitcoin/specs.d.ts.map +1 -1
  116. package/lib/families/bitcoin/specs.js +2 -1
  117. package/lib/families/bitcoin/specs.js.map +1 -1
  118. package/lib/families/bitcoin/test-dataset.js +2 -2
  119. package/lib/families/bitcoin/test-dataset.js.map +1 -1
  120. package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.d.ts +2 -1
  121. package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.d.ts.map +1 -1
  122. package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.js +16 -12
  123. package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.js.map +1 -1
  124. package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.d.ts +2 -1
  125. package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.d.ts.map +1 -1
  126. package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.js +12 -7
  127. package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.js.map +1 -1
  128. package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.d.ts +2 -1
  129. package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.d.ts.map +1 -1
  130. package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.js +12 -7
  131. package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.js.map +1 -1
  132. package/lib/families/bitcoin/wallet-btc/pickingstrategies/types.d.ts +2 -1
  133. package/lib/families/bitcoin/wallet-btc/pickingstrategies/types.d.ts.map +1 -1
  134. package/lib/families/bitcoin/wallet-btc/pickingstrategies/types.js.map +1 -1
  135. package/lib/families/bitcoin/wallet-btc/utils.d.ts +38 -1
  136. package/lib/families/bitcoin/wallet-btc/utils.d.ts.map +1 -1
  137. package/lib/families/bitcoin/wallet-btc/utils.js +104 -32
  138. package/lib/families/bitcoin/wallet-btc/utils.js.map +1 -1
  139. package/lib/families/bitcoin/wallet-btc/wallet.d.ts +1 -1
  140. package/lib/families/bitcoin/wallet-btc/wallet.d.ts.map +1 -1
  141. package/lib/families/bitcoin/wallet-btc/wallet.js +6 -3
  142. package/lib/families/bitcoin/wallet-btc/wallet.js.map +1 -1
  143. package/lib/families/bitcoin/wallet-btc/xpub.js +2 -2
  144. package/lib/families/bitcoin/wallet-btc/xpub.js.map +1 -1
  145. package/lib/families/ethereum/signOperation.d.ts.map +1 -1
  146. package/lib/families/ethereum/signOperation.js +7 -0
  147. package/lib/families/ethereum/signOperation.js.map +1 -1
  148. package/lib/families/ethereum/synchronisation.d.ts.map +1 -1
  149. package/lib/families/ethereum/synchronisation.js +175 -15
  150. package/lib/families/ethereum/synchronisation.js.map +1 -1
  151. package/lib/families/ethereum/versions.d.ts +2 -0
  152. package/lib/families/ethereum/versions.d.ts.map +1 -0
  153. package/lib/families/ethereum/versions.js +5 -0
  154. package/lib/families/ethereum/versions.js.map +1 -0
  155. package/lib/nft/NftMetadataProvider/index.d.ts +17 -0
  156. package/lib/nft/NftMetadataProvider/index.d.ts.map +1 -0
  157. package/lib/nft/NftMetadataProvider/index.js +244 -0
  158. package/lib/nft/NftMetadataProvider/index.js.map +1 -0
  159. package/lib/nft/NftMetadataProvider/logic.d.ts +3 -0
  160. package/lib/nft/NftMetadataProvider/logic.d.ts.map +1 -0
  161. package/lib/nft/NftMetadataProvider/logic.js +22 -0
  162. package/lib/nft/NftMetadataProvider/logic.js.map +1 -0
  163. package/lib/nft/NftMetadataProvider/types.d.ts +44 -0
  164. package/lib/nft/NftMetadataProvider/types.d.ts.map +1 -0
  165. package/lib/nft/NftMetadataProvider/types.js +3 -0
  166. package/lib/nft/NftMetadataProvider/types.js.map +1 -0
  167. package/lib/nft/helpers.d.ts +10 -0
  168. package/lib/nft/helpers.d.ts.map +1 -0
  169. package/lib/nft/helpers.js +85 -0
  170. package/lib/nft/helpers.js.map +1 -0
  171. package/lib/nft/index.d.ts +4 -0
  172. package/lib/nft/index.d.ts.map +1 -0
  173. package/lib/nft/index.js +16 -0
  174. package/lib/nft/index.js.map +1 -0
  175. package/lib/nft/nftId.d.ts +3 -0
  176. package/lib/nft/nftId.d.ts.map +1 -0
  177. package/lib/nft/nftId.js +33 -0
  178. package/lib/nft/nftId.js.map +1 -0
  179. package/lib/operation.d.ts +1 -1
  180. package/lib/operation.d.ts.map +1 -1
  181. package/lib/operation.js +19 -5
  182. package/lib/operation.js.map +1 -1
  183. package/lib/reconciliation.d.ts.map +1 -1
  184. package/lib/reconciliation.js +6 -0
  185. package/lib/reconciliation.js.map +1 -1
  186. package/lib/types/account.d.ts +3 -0
  187. package/lib/types/account.d.ts.map +1 -1
  188. package/lib/types/index.d.ts +1 -0
  189. package/lib/types/index.d.ts.map +1 -1
  190. package/lib/types/index.js +1 -0
  191. package/lib/types/index.js.map +1 -1
  192. package/lib/types/nft.d.ts +29 -0
  193. package/lib/types/nft.d.ts.map +1 -0
  194. package/lib/types/nft.js +3 -0
  195. package/lib/types/nft.js.map +1 -0
  196. package/lib/types/operation.d.ts +12 -1
  197. package/lib/types/operation.d.ts.map +1 -1
  198. package/package.json +13 -13
  199. package/src/.DS_Store +0 -0
  200. package/src/__tests__/__snapshots__/all.libcore.ts.snap +11643 -127265
  201. package/src/__tests__/families/bitcoin/wallet-btc/utils.test.ts +105 -0
  202. package/src/__tests__/families/bitcoin/wallet-btc/wallet.estimateMaxSpendable.test.ts +3 -2
  203. package/src/__tests__/families/bitcoin/wallet-btc/wallet.integration.test.ts +2 -2
  204. package/src/__tests__/families/bitcoin/wallet-btc/xpub.pickingStrategies.integration.test.ts +35 -31
  205. package/src/__tests__/families/bitcoin/wallet-btc/xpub.txs.NP2WPKH.integration.test.ts +3 -2
  206. package/src/__tests__/families/bitcoin/wallet-btc/xpub.txs.P2WPKH.integration.test.ts +3 -2
  207. package/src/__tests__/families/bitcoin/wallet-btc/xpub.txs.integration.test.ts +6 -4
  208. package/src/account/formatters.ts +43 -0
  209. package/src/account/groupOperations.ts +2 -2
  210. package/src/account/serialization.ts +52 -0
  211. package/src/api/Ethereum.ts +40 -2
  212. package/src/apps/polyfill.ts +3 -0
  213. package/src/bridge/jsHelpers.ts +35 -0
  214. package/src/csvExport.ts +3 -2
  215. package/src/currencies/.DS_Store +0 -0
  216. package/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap +1354 -1
  217. package/src/currencies/sortByMarketcap.ts +9 -1
  218. package/src/currencies/support.ts +1 -0
  219. package/src/env.ts +11 -0
  220. package/src/families/bitcoin/datasets/bitcoin.ts +4 -0
  221. package/src/families/bitcoin/datasets/bitcoin_cash.ts +4 -0
  222. package/src/families/bitcoin/datasets/bitcoin_gold.ts +4 -0
  223. package/src/families/bitcoin/datasets/dash.ts +4 -0
  224. package/src/families/bitcoin/datasets/decred.ts +4 -0
  225. package/src/families/bitcoin/datasets/digibyte.ts +4 -0
  226. package/src/families/bitcoin/datasets/dogecoin.ts +4 -0
  227. package/src/families/bitcoin/datasets/komodo.ts +4 -0
  228. package/src/families/bitcoin/datasets/litecoin.ts +4 -0
  229. package/src/families/bitcoin/datasets/peercoin.ts +4 -0
  230. package/src/families/bitcoin/datasets/pivx.ts +4 -0
  231. package/src/families/bitcoin/datasets/qtum.ts +4 -0
  232. package/src/families/bitcoin/datasets/stakenet.ts +4 -0
  233. package/src/families/bitcoin/datasets/vertcoin.ts +4 -0
  234. package/src/families/bitcoin/datasets/viacoin.ts +4 -0
  235. package/src/families/bitcoin/datasets/zcash.ts +4 -0
  236. package/src/families/bitcoin/datasets/zencash.ts +4 -0
  237. package/src/families/bitcoin/js-buildTransaction.ts +2 -1
  238. package/src/families/bitcoin/js-estimateMaxSpendable.ts +2 -1
  239. package/src/families/bitcoin/js-synchronisation.ts +30 -16
  240. package/src/families/bitcoin/logic.ts +7 -2
  241. package/src/families/bitcoin/specs.ts +6 -1
  242. package/src/families/bitcoin/test-dataset.ts +2 -2
  243. package/src/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.ts +34 -22
  244. package/src/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.ts +30 -9
  245. package/src/families/bitcoin/wallet-btc/pickingstrategies/Merge.ts +30 -9
  246. package/src/families/bitcoin/wallet-btc/pickingstrategies/types.ts +3 -3
  247. package/src/families/bitcoin/wallet-btc/utils.ts +118 -35
  248. package/src/families/bitcoin/wallet-btc/wallet.ts +9 -4
  249. package/src/families/bitcoin/wallet-btc/xpub.ts +5 -5
  250. package/src/families/ethereum/modules/__snapshots__/compound.resilience.test.ts.snap +2876 -0
  251. package/src/families/ethereum/signOperation.ts +8 -0
  252. package/src/families/ethereum/synchronisation.ts +185 -6
  253. package/src/families/ethereum/versions.ts +1 -0
  254. package/src/nft/NftMetadataProvider/index.tsx +205 -0
  255. package/src/nft/NftMetadataProvider/logic.ts +20 -0
  256. package/src/nft/NftMetadataProvider/types.ts +60 -0
  257. package/src/nft/helpers.ts +78 -0
  258. package/src/nft/index.ts +3 -0
  259. package/src/nft/nftId.ts +17 -0
  260. package/src/operation.ts +22 -3
  261. package/src/reconciliation.ts +7 -0
  262. package/src/types/account.ts +4 -0
  263. package/src/types/index.ts +1 -0
  264. package/src/types/nft.ts +38 -0
  265. package/src/types/operation.ts +23 -1
@@ -81,7 +81,15 @@ export const getMarketcapTickers: () => Promise<string[]> = makeLRUCache(() =>
81
81
  export const useMarketcapTickers = (): string[] | null | undefined => {
82
82
  const [tickers, setMarketcapTickers] = useState(marketcapTickersCache);
83
83
  useEffect(() => {
84
- getMarketcapTickers().then(setMarketcapTickers);
84
+ let isMounted = true;
85
+
86
+ getMarketcapTickers().then((data) => {
87
+ if (isMounted) setMarketcapTickers(data);
88
+ });
89
+
90
+ return () => {
91
+ isMounted = false;
92
+ };
85
93
  }, []);
86
94
  return tickers;
87
95
  };
@@ -9,6 +9,7 @@ import {
9
9
  hasCryptoCurrencyId,
10
10
  } from "@ledgerhq/cryptoassets";
11
11
  import { getEnv } from "../env";
12
+
12
13
  // set by user side effect to precise which currencies are considered supported (typically by live)
13
14
  let userSupportedCurrencies: CryptoCurrency[] = [];
14
15
  let userSupportedFiats: FiatCurrency[] = [];
package/src/env.ts CHANGED
@@ -376,6 +376,17 @@ const envDefinitions = {
376
376
  parser: stringParser,
377
377
  desc: "mock the server response for the exchange KYC check, options are 'open', 'pending', 'closed' or 'approved'.",
378
378
  },
379
+ NFT: {
380
+ def: false,
381
+ parser: boolParser,
382
+ desc: "synchronizing nfts",
383
+ },
384
+ NFT_ETH_METADATA_SERVICE: {
385
+ // FIXME LL-8001
386
+ def: "https://nft.staging.aws.ledger.fr/v1/ethereum/1/contracts/tokens/infos",
387
+ parser: stringParser,
388
+ desc: "service uri used to get the metadata of an nft",
389
+ },
379
390
  OPERATION_ADDRESSES_LIMIT: {
380
391
  def: 100,
381
392
  parser: intParser,
@@ -28,6 +28,10 @@ const networkInfo: NetworkInfoRaw = {
28
28
  },
29
29
  };
30
30
  const dataset: CurrenciesData<Transaction> = {
31
+ FIXME_ignoreAccountFields: [
32
+ "bitcoinResources.walletAccount", // it is not "stable"
33
+ "bitcoinResources.utxos", // TODO: fix ordering
34
+ ],
31
35
  scanAccounts: [scanAccounts1],
32
36
  accounts: [
33
37
  {
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "bitcoin_cash seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "bitcoin_gold seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "dash seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "decred seed 1",
@@ -27,6 +27,10 @@ const networkInfo: NetworkInfoRaw = {
27
27
  },
28
28
  };
29
29
  const dataset: CurrenciesData<Transaction> = {
30
+ FIXME_ignoreAccountFields: [
31
+ "bitcoinResources.walletAccount", // it is not "stable"
32
+ "bitcoinResources.utxos", // TODO: fix ordering
33
+ ],
30
34
  scanAccounts: [scanAccounts1],
31
35
  accounts: [
32
36
  {
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "dogecoin seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "komodo seed 1",
@@ -27,6 +27,10 @@ const networkInfo: NetworkInfoRaw = {
27
27
  },
28
28
  };
29
29
  const dataset: CurrenciesData<Transaction> = {
30
+ FIXME_ignoreAccountFields: [
31
+ "bitcoinResources.walletAccount", // it is not "stable"
32
+ "bitcoinResources.utxos", // TODO: fix ordering
33
+ ],
30
34
  scanAccounts: [scanAccounts1],
31
35
  accounts: [
32
36
  {
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "peercoin seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "pivx seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "qtum seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "stakenet seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "vertcoin seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "viacoin seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "zcash seed 1",
@@ -1,6 +1,10 @@
1
1
  import type { CurrenciesData } from "../../../types";
2
2
  import type { Transaction } from "../types";
3
3
  const dataset: CurrenciesData<Transaction> = {
4
+ FIXME_ignoreAccountFields: [
5
+ "bitcoinResources.walletAccount", // it is not "stable"
6
+ "bitcoinResources.utxos", // TODO: fix ordering
7
+ ],
4
8
  scanAccounts: [
5
9
  {
6
10
  name: "zencash seed 1",
@@ -44,7 +44,8 @@ export const buildTransaction = async (
44
44
  walletAccount,
45
45
  transaction.feePerByte.toNumber(), //!\ wallet-btc handles fees as JS number
46
46
  transaction.utxoStrategy.excludeUTXOs,
47
- transaction.utxoStrategy.pickUnconfirmedRBF
47
+ transaction.utxoStrategy.pickUnconfirmedRBF,
48
+ [transaction.recipient]
48
49
  );
49
50
  log("btcwallet", "building transaction", transaction);
50
51
  const txInfo = await wallet.buildAccountTx({
@@ -30,7 +30,8 @@ const estimateMaxSpendable = async ({
30
30
  walletAccount,
31
31
  feePerByte.toNumber(), //!\ wallet-btc handles fees as JS number
32
32
  transaction?.utxoStrategy?.excludeUTXOs || [],
33
- transaction?.utxoStrategy?.pickUnconfirmedRBF || false
33
+ transaction?.utxoStrategy?.pickUnconfirmedRBF || false,
34
+ transaction ? [transaction.recipient] : []
34
35
  );
35
36
  return maxSpendable.lt(0) ? new BigNumber(0) : maxSpendable;
36
37
  };
@@ -128,18 +128,44 @@ const mapTxToOperations = (
128
128
  // All inputs of a same transaction have the same sequence
129
129
  const transactionSequenceNumber =
130
130
  (accountInputs.length > 0 && accountInputs[0].sequence) || undefined;
131
+
131
132
  const hasSpentNothing = value.eq(0);
133
+ // Change output is always the last one
134
+ const changeOutputIndex = tx.outputs
135
+ .map((o) => o.output_index)
136
+ .reduce((p, c) => (p > c ? p : c));
132
137
 
133
138
  for (const output of tx.outputs) {
134
139
  if (output.address) {
135
- if (accountAddresses.includes(output.address)) {
140
+ if (!accountAddresses.includes(output.address)) {
141
+ // The output doesn't belong to this account
142
+ if (
143
+ tx.outputs.length === 1 || // The transaction has only 1 output
144
+ output.output_index < changeOutputIndex // The output isn't the change output
145
+ ) {
146
+ recipients.push(
147
+ syncReplaceAddress
148
+ ? syncReplaceAddress(output.address)
149
+ : output.address
150
+ );
151
+ }
152
+ } else {
153
+ // The output belongs to this account
136
154
  accountOutputs.push(output);
137
155
 
138
- if (changeAddresses.includes(output.address)) {
156
+ if (!changeAddresses.includes(output.address)) {
157
+ // The output isn't a change output of this account
158
+ recipients.push(
159
+ syncReplaceAddress
160
+ ? syncReplaceAddress(output.address)
161
+ : output.address
162
+ );
163
+ } else {
164
+ // The output is a change output of this account,
165
+ // we count it as a recipient only in some special cases
139
166
  if (
140
167
  (recipients.length === 0 &&
141
- output.output_hash ===
142
- tx.outputs[tx.outputs.length - 1].output_hash) ||
168
+ output.output_index >= changeOutputIndex) ||
143
169
  hasSpentNothing
144
170
  ) {
145
171
  recipients.push(
@@ -148,19 +174,7 @@ const mapTxToOperations = (
148
174
  : output.address
149
175
  );
150
176
  }
151
- } else {
152
- recipients.push(
153
- syncReplaceAddress
154
- ? syncReplaceAddress(output.address)
155
- : output.address
156
- );
157
177
  }
158
- } else {
159
- recipients.push(
160
- syncReplaceAddress
161
- ? syncReplaceAddress(output.address)
162
- : output.address
163
- );
164
178
  }
165
179
  }
166
180
  }
@@ -79,7 +79,7 @@ export function isChangeOutput(output: BitcoinOutput): boolean {
79
79
  type UTXOStatus =
80
80
  | {
81
81
  excluded: true;
82
- reason: "pickUnconfirmedRBF" | "userExclusion";
82
+ reason: "pickUnconfirmedRBF" | "pickPendingNonRBF" | "userExclusion";
83
83
  }
84
84
  | {
85
85
  excluded: false;
@@ -94,7 +94,12 @@ export const getUTXOStatus = (
94
94
  reason: "pickUnconfirmedRBF",
95
95
  };
96
96
  }
97
-
97
+ if (!utxo.rbf && !utxo.blockHeight) {
98
+ return {
99
+ excluded: true,
100
+ reason: "pickPendingNonRBF",
101
+ };
102
+ }
98
103
  if (
99
104
  utxoStrategy.excludeUTXOs.some(
100
105
  (u) => u.hash === utxo.hash && u.outputIndex === utxo.outputIndex
@@ -254,7 +254,12 @@ const bitcoinLikeMutations = ({
254
254
  },
255
255
  recoverBadTransactionStatus,
256
256
  test: ({ account }) => {
257
- expect(account.balance.toString()).toBe("0");
257
+ expect(
258
+ account.bitcoinResources?.utxos
259
+ .filter((u) => u.blockHeight) // Exclude pending UTXOs
260
+ .reduce((p, c) => p.plus(c.value), new BigNumber(0))
261
+ .toString()
262
+ ).toBe("0");
258
263
  },
259
264
  },
260
265
  ];
@@ -1,7 +1,7 @@
1
1
  import type { DatasetTest } from "../../types";
2
2
  import type { Transaction } from "./types";
3
3
  import bitcoin_cash from "./datasets/bitcoin_cash";
4
- import bitcoin_gold from "./datasets/bitcoin_gold";
4
+ // import bitcoin_gold from "./datasets/bitcoin_gold";
5
5
  import bitcoin from "./datasets/bitcoin";
6
6
  import dash from "./datasets/dash";
7
7
  // import decred from "./datasets/decred";
@@ -22,7 +22,7 @@ const dataset: DatasetTest<Transaction> = {
22
22
  currencies: {
23
23
  bitcoin,
24
24
  bitcoin_cash,
25
- bitcoin_gold,
25
+ // bitcoin_gold,
26
26
  dash,
27
27
  // decred, // BACK-2443
28
28
  digibyte,
@@ -7,14 +7,14 @@ import { PickingStrategy } from "./types";
7
7
  import * as utils from "../utils";
8
8
  import { DeepFirst } from "./DeepFirst";
9
9
  import { log } from "@ledgerhq/logs";
10
+ import { OutputInfo } from "..";
10
11
 
11
12
  export class CoinSelect extends PickingStrategy {
12
13
  // eslint-disable-next-line class-methods-use-this
13
14
  async selectUnspentUtxosToUse(
14
15
  xpub: Xpub,
15
- amount: BigNumber,
16
- feePerByte: number,
17
- nbOutputsWithoutChange: number
16
+ outputs: OutputInfo[],
17
+ feePerByte: number
18
18
  ) {
19
19
  // get the utxos to use as input
20
20
  // from all addresses of the account
@@ -34,18 +34,30 @@ export class CoinSelect extends PickingStrategy {
34
34
  const TOTAL_TRIES = 100000;
35
35
  log("picking strategy", "utxos", unspentUtxos);
36
36
  // Compute cost of change
37
- const fixedSize = utils.estimateTxSize(
38
- 0,
37
+ const fixedSize = utils.maxTxSize(
39
38
  0,
39
+ [],
40
+ false,
40
41
  this.crypto,
41
42
  this.derivationMode
42
43
  );
44
+ const outputAddresses = outputs.map((o) => o.address);
43
45
  // Size of only 1 output (without fixed size)
44
46
  const oneOutputSize =
45
- utils.estimateTxSize(0, 1, this.crypto, this.derivationMode) - fixedSize;
47
+ outputAddresses.length > 0
48
+ ? utils.maxTxSize(
49
+ 0,
50
+ [outputAddresses[0]],
51
+ false,
52
+ this.crypto,
53
+ this.derivationMode
54
+ ) - fixedSize
55
+ : utils.maxTxSize(0, [], true, this.crypto, this.derivationMode) -
56
+ fixedSize;
46
57
  // Size 1 signed UTXO (signed input)
47
58
  const oneInputSize =
48
- utils.estimateTxSize(1, 0, this.crypto, this.derivationMode) - fixedSize;
59
+ utils.maxTxSize(1, [], false, this.crypto, this.derivationMode) -
60
+ fixedSize;
49
61
 
50
62
  // Calculate effective value of outputs
51
63
  let currentAvailableValue = 0;
@@ -70,12 +82,16 @@ export class CoinSelect extends PickingStrategy {
70
82
  // Get no inputs fees
71
83
  // At beginning, there are no outputs in tx, so noInputFees are fixed fees
72
84
  const notInputFees =
73
- feePerByte * (fixedSize + oneOutputSize * nbOutputsWithoutChange);
85
+ feePerByte * (fixedSize + oneOutputSize * outputs.length);
74
86
 
75
87
  // Start coin selection algorithm (according to SelectCoinBnb from Bitcoin Core)
76
88
  let currentValue = 0;
77
89
  const currentSelection: boolean[] = [];
78
90
 
91
+ const amount = outputs.reduce(
92
+ (sum, output) => sum.plus(output.value),
93
+ new BigNumber(0)
94
+ );
79
95
  // Actual amount we are targetting
80
96
  const actualTarget = notInputFees + amount.toNumber();
81
97
 
@@ -102,9 +118,10 @@ export class CoinSelect extends PickingStrategy {
102
118
  currentSelectionNeedChangeoutput = true;
103
119
  currentWaste =
104
120
  feePerByte *
105
- utils.estimateTxSize(
121
+ utils.maxTxSizeCeil(
106
122
  nbInput,
107
- nbOutputsWithoutChange + 1,
123
+ outputAddresses,
124
+ true,
108
125
  this.crypto,
109
126
  this.derivationMode
110
127
  );
@@ -113,9 +130,10 @@ export class CoinSelect extends PickingStrategy {
113
130
  currentSelectionNeedChangeoutput = false;
114
131
  currentWaste =
115
132
  feePerByte *
116
- utils.estimateTxSize(
133
+ utils.maxTxSizeCeil(
117
134
  nbInput,
118
- nbOutputsWithoutChange,
135
+ outputAddresses,
136
+ false,
119
137
  this.crypto,
120
138
  this.derivationMode
121
139
  ) +
@@ -170,11 +188,10 @@ export class CoinSelect extends PickingStrategy {
170
188
  }
171
189
  const fee =
172
190
  feePerByte *
173
- utils.estimateTxSize(
191
+ utils.maxTxSizeCeil(
174
192
  unspentUtxoSelected.length,
175
- bestSelectionNeedChangeoutput
176
- ? nbOutputsWithoutChange + 1
177
- : nbOutputsWithoutChange,
193
+ outputAddresses,
194
+ bestSelectionNeedChangeoutput,
178
195
  this.crypto,
179
196
  this.derivationMode
180
197
  );
@@ -191,11 +208,6 @@ export class CoinSelect extends PickingStrategy {
191
208
  this.derivationMode,
192
209
  this.excludedUTXOs
193
210
  );
194
- return pickingStrategy.selectUnspentUtxosToUse(
195
- xpub,
196
- amount,
197
- feePerByte,
198
- nbOutputsWithoutChange
199
- );
211
+ return pickingStrategy.selectUnspentUtxosToUse(xpub, outputs, feePerByte);
200
212
  }
201
213
  }
@@ -6,14 +6,14 @@ import Xpub from "../xpub";
6
6
  import { PickingStrategy } from "./types";
7
7
  import * as utils from "../utils";
8
8
  import { log } from "@ledgerhq/logs";
9
+ import { OutputInfo } from "..";
9
10
 
10
11
  export class DeepFirst extends PickingStrategy {
11
12
  // eslint-disable-next-line class-methods-use-this
12
13
  async selectUnspentUtxosToUse(
13
14
  xpub: Xpub,
14
- amount: BigNumber,
15
- feePerByte: number,
16
- nbOutputsWithoutChange: number
15
+ outputs: OutputInfo[],
16
+ feePerByte: number
17
17
  ) {
18
18
  // get the utxos to use as input
19
19
  // from all addresses of the account
@@ -31,26 +31,47 @@ export class DeepFirst extends PickingStrategy {
31
31
  ).length
32
32
  );
33
33
 
34
+ const outputAddresses = outputs.map((o) => o.address);
34
35
  unspentUtxos = sortBy(unspentUtxos, "block_height");
35
36
  // https://metamug.com/article/security/bitcoin-transaction-fee-satoshi-per-byte.html
36
- const txSizeNoInput = utils.estimateTxSize(
37
+ const txSizeNoInput = utils.maxTxSize(
37
38
  0,
38
- nbOutputsWithoutChange,
39
+ outputAddresses,
40
+ false,
39
41
  this.crypto,
40
42
  this.derivationMode
41
43
  );
42
44
  let fee = txSizeNoInput * feePerByte;
45
+ const emptyTxSize = utils.maxTxSizeCeil(
46
+ 0,
47
+ [],
48
+ false,
49
+ this.crypto,
50
+ this.derivationMode
51
+ );
43
52
  const sizePerInput =
44
- utils.estimateTxSize(1, 0, this.crypto, this.derivationMode) -
45
- utils.estimateTxSize(0, 0, this.crypto, this.derivationMode);
53
+ utils.maxTxSize(1, [], false, this.crypto, this.derivationMode) -
54
+ emptyTxSize;
46
55
 
47
56
  const sizePerOutput =
48
- utils.estimateTxSize(0, 1, this.crypto, this.derivationMode) -
49
- utils.estimateTxSize(0, 0, this.crypto, this.derivationMode);
57
+ (outputAddresses[0]
58
+ ? utils.maxTxSize(
59
+ 0,
60
+ [outputAddresses[0]],
61
+ false,
62
+ this.crypto,
63
+ this.derivationMode
64
+ )
65
+ : utils.maxTxSize(0, [], true, this.crypto, this.derivationMode)) -
66
+ emptyTxSize;
50
67
 
51
68
  let total = new BigNumber(0);
52
69
  const unspentUtxoSelected: Output[] = [];
53
70
 
71
+ const amount = outputs.reduce(
72
+ (sum, output) => sum.plus(output.value),
73
+ new BigNumber(0)
74
+ );
54
75
  let i = 0;
55
76
  while (total.lt(amount.plus(fee))) {
56
77
  if (!unspentUtxos[i]) {
@@ -6,14 +6,14 @@ import Xpub from "../xpub";
6
6
  import { PickingStrategy } from "./types";
7
7
  import * as utils from "../utils";
8
8
  import { log } from "@ledgerhq/logs";
9
+ import { OutputInfo } from "..";
9
10
 
10
11
  export class Merge extends PickingStrategy {
11
12
  // eslint-disable-next-line class-methods-use-this
12
13
  async selectUnspentUtxosToUse(
13
14
  xpub: Xpub,
14
- amount: BigNumber,
15
- feePerByte: number,
16
- nbOutputsWithoutChange: number
15
+ outputs: OutputInfo[],
16
+ feePerByte: number
17
17
  ) {
18
18
  // get the utxos to use as input
19
19
  // from all addresses of the account
@@ -31,19 +31,36 @@ export class Merge extends PickingStrategy {
31
31
  ).length
32
32
  );
33
33
 
34
+ const outputAddresses = outputs.map((o) => o.address);
35
+ const emptyTxSize = utils.maxTxSizeCeil(
36
+ 0,
37
+ [],
38
+ false,
39
+ this.crypto,
40
+ this.derivationMode
41
+ );
34
42
  const sizePerInput =
35
- utils.estimateTxSize(1, 0, this.crypto, this.derivationMode) -
36
- utils.estimateTxSize(0, 0, this.crypto, this.derivationMode);
43
+ utils.maxTxSize(1, [], false, this.crypto, this.derivationMode) -
44
+ emptyTxSize;
37
45
 
38
46
  const sizePerOutput =
39
- utils.estimateTxSize(0, 1, this.crypto, this.derivationMode) -
40
- utils.estimateTxSize(0, 0, this.crypto, this.derivationMode);
47
+ (outputAddresses[0]
48
+ ? utils.maxTxSize(
49
+ 0,
50
+ [outputAddresses[0]],
51
+ false,
52
+ this.crypto,
53
+ this.derivationMode
54
+ )
55
+ : utils.maxTxSize(0, [], true, this.crypto, this.derivationMode)) -
56
+ emptyTxSize;
41
57
 
42
58
  unspentUtxos = sortBy(unspentUtxos, (utxo) => parseInt(utxo.value, 10));
43
59
  // https://metamug.com/article/security/bitcoin-transaction-fee-satoshi-per-byte.html
44
- const txSizeNoInput = utils.estimateTxSize(
60
+ const txSizeNoInput = utils.maxTxSize(
45
61
  0,
46
- nbOutputsWithoutChange,
62
+ outputAddresses,
63
+ false,
47
64
  this.crypto,
48
65
  this.derivationMode
49
66
  );
@@ -53,6 +70,10 @@ export class Merge extends PickingStrategy {
53
70
  const unspentUtxoSelected: Output[] = [];
54
71
 
55
72
  let i = 0;
73
+ const amount = outputs.reduce(
74
+ (sum, output) => sum.plus(output.value),
75
+ new BigNumber(0)
76
+ );
56
77
  while (total.lt(amount.plus(fee))) {
57
78
  if (!unspentUtxos[i]) {
58
79
  throw new NotEnoughBalance();