@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.
- package/lib/__tests__/families/bitcoin/wallet-btc/utils.test.js +85 -0
- package/lib/__tests__/families/bitcoin/wallet-btc/utils.test.js.map +1 -1
- package/lib/__tests__/families/bitcoin/wallet-btc/wallet.estimateMaxSpendable.test.js +1 -1
- package/lib/__tests__/families/bitcoin/wallet-btc/wallet.estimateMaxSpendable.test.js.map +1 -1
- package/lib/__tests__/families/bitcoin/wallet-btc/wallet.integration.test.js +2 -2
- package/lib/__tests__/families/bitcoin/wallet-btc/wallet.integration.test.js.map +1 -1
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.pickingStrategies.integration.test.js +20 -10
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.pickingStrategies.integration.test.js.map +1 -1
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.NP2WPKH.integration.test.js +1 -1
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.NP2WPKH.integration.test.js.map +1 -1
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.P2WPKH.integration.test.js +1 -1
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.P2WPKH.integration.test.js.map +1 -1
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.integration.test.js +2 -2
- package/lib/__tests__/families/bitcoin/wallet-btc/xpub.txs.integration.test.js.map +1 -1
- package/lib/account/formatters.d.ts.map +1 -1
- package/lib/account/formatters.js +33 -1
- package/lib/account/formatters.js.map +1 -1
- package/lib/account/groupOperations.js +1 -1
- package/lib/account/groupOperations.js.map +1 -1
- package/lib/account/pending.d.ts +1 -0
- package/lib/account/pending.d.ts.map +1 -1
- package/lib/account/serialization.d.ts +6 -4
- package/lib/account/serialization.d.ts.map +1 -1
- package/lib/account/serialization.js +47 -9
- package/lib/account/serialization.js.map +1 -1
- package/lib/api/Ethereum.d.ts +22 -1
- package/lib/api/Ethereum.d.ts.map +1 -1
- package/lib/api/Ethereum.js +21 -1
- package/lib/api/Ethereum.js.map +1 -1
- package/lib/apps/polyfill.d.ts.map +1 -1
- package/lib/apps/polyfill.js +3 -0
- package/lib/apps/polyfill.js.map +1 -1
- package/lib/bridge/jsHelpers.d.ts +2 -1
- package/lib/bridge/jsHelpers.d.ts.map +1 -1
- package/lib/bridge/jsHelpers.js +27 -1
- package/lib/bridge/jsHelpers.js.map +1 -1
- package/lib/csvExport.d.ts.map +1 -1
- package/lib/csvExport.js +3 -1
- package/lib/csvExport.js.map +1 -1
- package/lib/currencies/sortByMarketcap.d.ts.map +1 -1
- package/lib/currencies/sortByMarketcap.js +8 -1
- package/lib/currencies/sortByMarketcap.js.map +1 -1
- package/lib/currencies/support.d.ts.map +1 -1
- package/lib/currencies/support.js.map +1 -1
- package/lib/env.d.ts +15 -5
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +11 -0
- package/lib/env.js.map +1 -1
- package/lib/env.react.d.ts +1 -1
- package/lib/env.react.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/bitcoin.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/bitcoin.js +4 -0
- package/lib/families/bitcoin/datasets/bitcoin.js.map +1 -1
- package/lib/families/bitcoin/datasets/bitcoin_cash.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/bitcoin_cash.js +4 -0
- package/lib/families/bitcoin/datasets/bitcoin_cash.js.map +1 -1
- package/lib/families/bitcoin/datasets/bitcoin_gold.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/bitcoin_gold.js +4 -0
- package/lib/families/bitcoin/datasets/bitcoin_gold.js.map +1 -1
- package/lib/families/bitcoin/datasets/dash.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/dash.js +4 -0
- package/lib/families/bitcoin/datasets/dash.js.map +1 -1
- package/lib/families/bitcoin/datasets/decred.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/decred.js +4 -0
- package/lib/families/bitcoin/datasets/decred.js.map +1 -1
- package/lib/families/bitcoin/datasets/digibyte.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/digibyte.js +4 -0
- package/lib/families/bitcoin/datasets/digibyte.js.map +1 -1
- package/lib/families/bitcoin/datasets/dogecoin.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/dogecoin.js +4 -0
- package/lib/families/bitcoin/datasets/dogecoin.js.map +1 -1
- package/lib/families/bitcoin/datasets/komodo.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/komodo.js +4 -0
- package/lib/families/bitcoin/datasets/komodo.js.map +1 -1
- package/lib/families/bitcoin/datasets/litecoin.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/litecoin.js +4 -0
- package/lib/families/bitcoin/datasets/litecoin.js.map +1 -1
- package/lib/families/bitcoin/datasets/peercoin.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/peercoin.js +4 -0
- package/lib/families/bitcoin/datasets/peercoin.js.map +1 -1
- package/lib/families/bitcoin/datasets/pivx.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/pivx.js +4 -0
- package/lib/families/bitcoin/datasets/pivx.js.map +1 -1
- package/lib/families/bitcoin/datasets/qtum.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/qtum.js +4 -0
- package/lib/families/bitcoin/datasets/qtum.js.map +1 -1
- package/lib/families/bitcoin/datasets/stakenet.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/stakenet.js +4 -0
- package/lib/families/bitcoin/datasets/stakenet.js.map +1 -1
- package/lib/families/bitcoin/datasets/vertcoin.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/vertcoin.js +4 -0
- package/lib/families/bitcoin/datasets/vertcoin.js.map +1 -1
- package/lib/families/bitcoin/datasets/viacoin.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/viacoin.js +4 -0
- package/lib/families/bitcoin/datasets/viacoin.js.map +1 -1
- package/lib/families/bitcoin/datasets/zcash.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/zcash.js +4 -0
- package/lib/families/bitcoin/datasets/zcash.js.map +1 -1
- package/lib/families/bitcoin/datasets/zencash.d.ts.map +1 -1
- package/lib/families/bitcoin/datasets/zencash.js +4 -0
- package/lib/families/bitcoin/datasets/zencash.js.map +1 -1
- package/lib/families/bitcoin/js-buildTransaction.d.ts.map +1 -1
- package/lib/families/bitcoin/js-buildTransaction.js +1 -1
- package/lib/families/bitcoin/js-buildTransaction.js.map +1 -1
- package/lib/families/bitcoin/js-estimateMaxSpendable.d.ts.map +1 -1
- package/lib/families/bitcoin/js-estimateMaxSpendable.js +1 -1
- package/lib/families/bitcoin/js-estimateMaxSpendable.js.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.d.ts.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.js +26 -14
- package/lib/families/bitcoin/js-synchronisation.js.map +1 -1
- package/lib/families/bitcoin/logic.d.ts +1 -1
- package/lib/families/bitcoin/logic.d.ts.map +1 -1
- package/lib/families/bitcoin/logic.js +6 -0
- package/lib/families/bitcoin/logic.js.map +1 -1
- package/lib/families/bitcoin/specs.d.ts.map +1 -1
- package/lib/families/bitcoin/specs.js +2 -1
- package/lib/families/bitcoin/specs.js.map +1 -1
- package/lib/families/bitcoin/test-dataset.js +2 -2
- package/lib/families/bitcoin/test-dataset.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.d.ts +2 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.js +16 -12
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.d.ts +2 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.js +12 -7
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.d.ts +2 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.js +12 -7
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/types.d.ts +2 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/types.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/types.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/utils.d.ts +38 -1
- package/lib/families/bitcoin/wallet-btc/utils.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/utils.js +104 -32
- package/lib/families/bitcoin/wallet-btc/utils.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/wallet.d.ts +1 -1
- package/lib/families/bitcoin/wallet-btc/wallet.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/wallet.js +6 -3
- package/lib/families/bitcoin/wallet-btc/wallet.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/xpub.js +2 -2
- package/lib/families/bitcoin/wallet-btc/xpub.js.map +1 -1
- package/lib/families/ethereum/signOperation.d.ts.map +1 -1
- package/lib/families/ethereum/signOperation.js +7 -0
- package/lib/families/ethereum/signOperation.js.map +1 -1
- package/lib/families/ethereum/synchronisation.d.ts.map +1 -1
- package/lib/families/ethereum/synchronisation.js +175 -15
- package/lib/families/ethereum/synchronisation.js.map +1 -1
- package/lib/families/ethereum/versions.d.ts +2 -0
- package/lib/families/ethereum/versions.d.ts.map +1 -0
- package/lib/families/ethereum/versions.js +5 -0
- package/lib/families/ethereum/versions.js.map +1 -0
- package/lib/nft/NftMetadataProvider/index.d.ts +17 -0
- package/lib/nft/NftMetadataProvider/index.d.ts.map +1 -0
- package/lib/nft/NftMetadataProvider/index.js +244 -0
- package/lib/nft/NftMetadataProvider/index.js.map +1 -0
- package/lib/nft/NftMetadataProvider/logic.d.ts +3 -0
- package/lib/nft/NftMetadataProvider/logic.d.ts.map +1 -0
- package/lib/nft/NftMetadataProvider/logic.js +22 -0
- package/lib/nft/NftMetadataProvider/logic.js.map +1 -0
- package/lib/nft/NftMetadataProvider/types.d.ts +44 -0
- package/lib/nft/NftMetadataProvider/types.d.ts.map +1 -0
- package/lib/nft/NftMetadataProvider/types.js +3 -0
- package/lib/nft/NftMetadataProvider/types.js.map +1 -0
- package/lib/nft/helpers.d.ts +10 -0
- package/lib/nft/helpers.d.ts.map +1 -0
- package/lib/nft/helpers.js +85 -0
- package/lib/nft/helpers.js.map +1 -0
- package/lib/nft/index.d.ts +4 -0
- package/lib/nft/index.d.ts.map +1 -0
- package/lib/nft/index.js +16 -0
- package/lib/nft/index.js.map +1 -0
- package/lib/nft/nftId.d.ts +3 -0
- package/lib/nft/nftId.d.ts.map +1 -0
- package/lib/nft/nftId.js +33 -0
- package/lib/nft/nftId.js.map +1 -0
- package/lib/operation.d.ts +1 -1
- package/lib/operation.d.ts.map +1 -1
- package/lib/operation.js +19 -5
- package/lib/operation.js.map +1 -1
- package/lib/reconciliation.d.ts.map +1 -1
- package/lib/reconciliation.js +6 -0
- package/lib/reconciliation.js.map +1 -1
- package/lib/types/account.d.ts +3 -0
- package/lib/types/account.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +1 -0
- package/lib/types/index.js.map +1 -1
- package/lib/types/nft.d.ts +29 -0
- package/lib/types/nft.d.ts.map +1 -0
- package/lib/types/nft.js +3 -0
- package/lib/types/nft.js.map +1 -0
- package/lib/types/operation.d.ts +12 -1
- package/lib/types/operation.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/.DS_Store +0 -0
- package/src/__tests__/__snapshots__/all.libcore.ts.snap +11643 -127265
- package/src/__tests__/families/bitcoin/wallet-btc/utils.test.ts +105 -0
- package/src/__tests__/families/bitcoin/wallet-btc/wallet.estimateMaxSpendable.test.ts +3 -2
- package/src/__tests__/families/bitcoin/wallet-btc/wallet.integration.test.ts +2 -2
- package/src/__tests__/families/bitcoin/wallet-btc/xpub.pickingStrategies.integration.test.ts +35 -31
- package/src/__tests__/families/bitcoin/wallet-btc/xpub.txs.NP2WPKH.integration.test.ts +3 -2
- package/src/__tests__/families/bitcoin/wallet-btc/xpub.txs.P2WPKH.integration.test.ts +3 -2
- package/src/__tests__/families/bitcoin/wallet-btc/xpub.txs.integration.test.ts +6 -4
- package/src/account/formatters.ts +43 -0
- package/src/account/groupOperations.ts +2 -2
- package/src/account/serialization.ts +52 -0
- package/src/api/Ethereum.ts +40 -2
- package/src/apps/polyfill.ts +3 -0
- package/src/bridge/jsHelpers.ts +35 -0
- package/src/csvExport.ts +3 -2
- package/src/currencies/.DS_Store +0 -0
- package/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap +1354 -1
- package/src/currencies/sortByMarketcap.ts +9 -1
- package/src/currencies/support.ts +1 -0
- package/src/env.ts +11 -0
- package/src/families/bitcoin/datasets/bitcoin.ts +4 -0
- package/src/families/bitcoin/datasets/bitcoin_cash.ts +4 -0
- package/src/families/bitcoin/datasets/bitcoin_gold.ts +4 -0
- package/src/families/bitcoin/datasets/dash.ts +4 -0
- package/src/families/bitcoin/datasets/decred.ts +4 -0
- package/src/families/bitcoin/datasets/digibyte.ts +4 -0
- package/src/families/bitcoin/datasets/dogecoin.ts +4 -0
- package/src/families/bitcoin/datasets/komodo.ts +4 -0
- package/src/families/bitcoin/datasets/litecoin.ts +4 -0
- package/src/families/bitcoin/datasets/peercoin.ts +4 -0
- package/src/families/bitcoin/datasets/pivx.ts +4 -0
- package/src/families/bitcoin/datasets/qtum.ts +4 -0
- package/src/families/bitcoin/datasets/stakenet.ts +4 -0
- package/src/families/bitcoin/datasets/vertcoin.ts +4 -0
- package/src/families/bitcoin/datasets/viacoin.ts +4 -0
- package/src/families/bitcoin/datasets/zcash.ts +4 -0
- package/src/families/bitcoin/datasets/zencash.ts +4 -0
- package/src/families/bitcoin/js-buildTransaction.ts +2 -1
- package/src/families/bitcoin/js-estimateMaxSpendable.ts +2 -1
- package/src/families/bitcoin/js-synchronisation.ts +30 -16
- package/src/families/bitcoin/logic.ts +7 -2
- package/src/families/bitcoin/specs.ts +6 -1
- package/src/families/bitcoin/test-dataset.ts +2 -2
- package/src/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.ts +34 -22
- package/src/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.ts +30 -9
- package/src/families/bitcoin/wallet-btc/pickingstrategies/Merge.ts +30 -9
- package/src/families/bitcoin/wallet-btc/pickingstrategies/types.ts +3 -3
- package/src/families/bitcoin/wallet-btc/utils.ts +118 -35
- package/src/families/bitcoin/wallet-btc/wallet.ts +9 -4
- package/src/families/bitcoin/wallet-btc/xpub.ts +5 -5
- package/src/families/ethereum/modules/__snapshots__/compound.resilience.test.ts.snap +2876 -0
- package/src/families/ethereum/signOperation.ts +8 -0
- package/src/families/ethereum/synchronisation.ts +185 -6
- package/src/families/ethereum/versions.ts +1 -0
- package/src/nft/NftMetadataProvider/index.tsx +205 -0
- package/src/nft/NftMetadataProvider/logic.ts +20 -0
- package/src/nft/NftMetadataProvider/types.ts +60 -0
- package/src/nft/helpers.ts +78 -0
- package/src/nft/index.ts +3 -0
- package/src/nft/nftId.ts +17 -0
- package/src/operation.ts +22 -3
- package/src/reconciliation.ts +7 -0
- package/src/types/account.ts +4 -0
- package/src/types/index.ts +1 -0
- package/src/types/nft.ts +38 -0
- 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
|
-
|
|
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.
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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 *
|
|
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.
|
|
121
|
+
utils.maxTxSizeCeil(
|
|
106
122
|
nbInput,
|
|
107
|
-
|
|
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.
|
|
133
|
+
utils.maxTxSizeCeil(
|
|
117
134
|
nbInput,
|
|
118
|
-
|
|
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.
|
|
191
|
+
utils.maxTxSizeCeil(
|
|
174
192
|
unspentUtxoSelected.length,
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
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.
|
|
37
|
+
const txSizeNoInput = utils.maxTxSize(
|
|
37
38
|
0,
|
|
38
|
-
|
|
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.
|
|
45
|
-
|
|
53
|
+
utils.maxTxSize(1, [], false, this.crypto, this.derivationMode) -
|
|
54
|
+
emptyTxSize;
|
|
46
55
|
|
|
47
56
|
const sizePerOutput =
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
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.
|
|
36
|
-
|
|
43
|
+
utils.maxTxSize(1, [], false, this.crypto, this.derivationMode) -
|
|
44
|
+
emptyTxSize;
|
|
37
45
|
|
|
38
46
|
const sizePerOutput =
|
|
39
|
-
|
|
40
|
-
|
|
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.
|
|
60
|
+
const txSizeNoInput = utils.maxTxSize(
|
|
45
61
|
0,
|
|
46
|
-
|
|
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();
|