@ledgerhq/live-common 21.15.0 → 21.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/families/bitcoin/js-synchronisation.d.ts.map +1 -1
- package/lib/families/bitcoin/js-synchronisation.js +6 -17
- 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/wallet-btc/pickingstrategies/CoinSelect.js +3 -3
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.js +5 -5
- package/lib/families/bitcoin/wallet-btc/pickingstrategies/Merge.js +5 -5
- package/lib/families/bitcoin/wallet-btc/utils.d.ts +1 -0
- package/lib/families/bitcoin/wallet-btc/utils.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/utils.js +8 -4
- package/lib/families/bitcoin/wallet-btc/utils.js.map +1 -1
- package/lib/families/bitcoin/wallet-btc/wallet.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/wallet.js +4 -2
- package/lib/families/bitcoin/wallet-btc/wallet.js.map +1 -1
- package/package.json +11 -11
- package/src/__tests__/__snapshots__/all.libcore.ts.snap +50567 -51469
- package/src/currencies/sortByMarketcap.ts +9 -1
- package/src/families/bitcoin/js-synchronisation.ts +9 -23
- package/src/families/bitcoin/logic.ts +7 -2
- package/src/families/bitcoin/specs.ts +6 -1
- package/src/families/bitcoin/wallet-btc/pickingstrategies/CoinSelect.ts +3 -3
- package/src/families/bitcoin/wallet-btc/pickingstrategies/DeepFirst.ts +5 -5
- package/src/families/bitcoin/wallet-btc/pickingstrategies/Merge.ts +5 -5
- package/src/families/bitcoin/wallet-btc/utils.ts +14 -3
- package/src/families/bitcoin/wallet-btc/wallet.ts +3 -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
|
};
|
|
@@ -128,34 +128,20 @@ 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
|
+
// Change output is the last one
|
|
133
|
+
const changeOutputIndex = tx.outputs
|
|
134
|
+
.map((o) => o.output_index)
|
|
135
|
+
.reduce((p, c) => (p > c ? p : c));
|
|
132
136
|
|
|
133
137
|
for (const output of tx.outputs) {
|
|
134
138
|
if (output.address) {
|
|
135
139
|
if (accountAddresses.includes(output.address)) {
|
|
136
140
|
accountOutputs.push(output);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
output.output_hash ===
|
|
142
|
-
tx.outputs[tx.outputs.length - 1].output_hash) ||
|
|
143
|
-
hasSpentNothing
|
|
144
|
-
) {
|
|
145
|
-
recipients.push(
|
|
146
|
-
syncReplaceAddress
|
|
147
|
-
? syncReplaceAddress(output.address)
|
|
148
|
-
: output.address
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
} else {
|
|
152
|
-
recipients.push(
|
|
153
|
-
syncReplaceAddress
|
|
154
|
-
? syncReplaceAddress(output.address)
|
|
155
|
-
: output.address
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
} else {
|
|
141
|
+
} else if (
|
|
142
|
+
!changeAddresses.includes(output.address) ||
|
|
143
|
+
output.output_index !== changeOutputIndex
|
|
144
|
+
) {
|
|
159
145
|
recipients.push(
|
|
160
146
|
syncReplaceAddress
|
|
161
147
|
? syncReplaceAddress(output.address)
|
|
@@ -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
|
];
|
|
@@ -34,7 +34,7 @@ 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.
|
|
37
|
+
const fixedSize = utils.accurateTxSize(
|
|
38
38
|
0,
|
|
39
39
|
0,
|
|
40
40
|
this.crypto,
|
|
@@ -42,10 +42,10 @@ export class CoinSelect extends PickingStrategy {
|
|
|
42
42
|
);
|
|
43
43
|
// Size of only 1 output (without fixed size)
|
|
44
44
|
const oneOutputSize =
|
|
45
|
-
utils.
|
|
45
|
+
utils.accurateTxSize(0, 1, this.crypto, this.derivationMode) - fixedSize;
|
|
46
46
|
// Size 1 signed UTXO (signed input)
|
|
47
47
|
const oneInputSize =
|
|
48
|
-
utils.
|
|
48
|
+
utils.accurateTxSize(1, 0, this.crypto, this.derivationMode) - fixedSize;
|
|
49
49
|
|
|
50
50
|
// Calculate effective value of outputs
|
|
51
51
|
let currentAvailableValue = 0;
|
|
@@ -33,7 +33,7 @@ export class DeepFirst extends PickingStrategy {
|
|
|
33
33
|
|
|
34
34
|
unspentUtxos = sortBy(unspentUtxos, "block_height");
|
|
35
35
|
// https://metamug.com/article/security/bitcoin-transaction-fee-satoshi-per-byte.html
|
|
36
|
-
const txSizeNoInput = utils.
|
|
36
|
+
const txSizeNoInput = utils.accurateTxSize(
|
|
37
37
|
0,
|
|
38
38
|
nbOutputsWithoutChange,
|
|
39
39
|
this.crypto,
|
|
@@ -41,12 +41,12 @@ export class DeepFirst extends PickingStrategy {
|
|
|
41
41
|
);
|
|
42
42
|
let fee = txSizeNoInput * feePerByte;
|
|
43
43
|
const sizePerInput =
|
|
44
|
-
utils.
|
|
45
|
-
utils.
|
|
44
|
+
utils.accurateTxSize(1, 0, this.crypto, this.derivationMode) -
|
|
45
|
+
utils.accurateTxSize(0, 0, this.crypto, this.derivationMode);
|
|
46
46
|
|
|
47
47
|
const sizePerOutput =
|
|
48
|
-
utils.
|
|
49
|
-
utils.
|
|
48
|
+
utils.accurateTxSize(0, 1, this.crypto, this.derivationMode) -
|
|
49
|
+
utils.accurateTxSize(0, 0, this.crypto, this.derivationMode);
|
|
50
50
|
|
|
51
51
|
let total = new BigNumber(0);
|
|
52
52
|
const unspentUtxoSelected: Output[] = [];
|
|
@@ -32,16 +32,16 @@ export class Merge extends PickingStrategy {
|
|
|
32
32
|
);
|
|
33
33
|
|
|
34
34
|
const sizePerInput =
|
|
35
|
-
utils.
|
|
36
|
-
utils.
|
|
35
|
+
utils.accurateTxSize(1, 0, this.crypto, this.derivationMode) -
|
|
36
|
+
utils.accurateTxSize(0, 0, this.crypto, this.derivationMode);
|
|
37
37
|
|
|
38
38
|
const sizePerOutput =
|
|
39
|
-
utils.
|
|
40
|
-
utils.
|
|
39
|
+
utils.accurateTxSize(0, 1, this.crypto, this.derivationMode) -
|
|
40
|
+
utils.accurateTxSize(0, 0, this.crypto, this.derivationMode);
|
|
41
41
|
|
|
42
42
|
unspentUtxos = sortBy(unspentUtxos, (utxo) => parseInt(utxo.value, 10));
|
|
43
43
|
// https://metamug.com/article/security/bitcoin-transaction-fee-satoshi-per-byte.html
|
|
44
|
-
const txSizeNoInput = utils.
|
|
44
|
+
const txSizeNoInput = utils.accurateTxSize(
|
|
45
45
|
0,
|
|
46
46
|
nbOutputsWithoutChange,
|
|
47
47
|
this.crypto,
|
|
@@ -92,7 +92,7 @@ export function byteSize(count: number) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
// refer to https://github.com/LedgerHQ/lib-ledger-core/blob/fc9d762b83fc2b269d072b662065747a64ab2816/core/src/wallet/bitcoin/api_impl/BitcoinLikeTransactionApi.cpp#L217
|
|
95
|
-
export function
|
|
95
|
+
export function accurateTxSize(
|
|
96
96
|
inputCount: number,
|
|
97
97
|
outputCount: number,
|
|
98
98
|
currency: ICrypto,
|
|
@@ -114,7 +114,7 @@ export function estimateTxSize(
|
|
|
114
114
|
// and https://bitcoinops.org/en/tools/calc-size/
|
|
115
115
|
if (derivationMode === DerivationModes.TAPROOT) {
|
|
116
116
|
txSize = fixedSize + 57.75 * inputCount + 43 * outputCount;
|
|
117
|
-
return
|
|
117
|
+
return txSize;
|
|
118
118
|
}
|
|
119
119
|
const isSegwit =
|
|
120
120
|
derivationMode === DerivationModes.NATIVE_SEGWIT ||
|
|
@@ -131,7 +131,18 @@ export function estimateTxSize(
|
|
|
131
131
|
} else {
|
|
132
132
|
txSize = fixedSize + 148 * inputCount + 43 * outputCount;
|
|
133
133
|
}
|
|
134
|
-
return
|
|
134
|
+
return txSize;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function estimateTxSize(
|
|
138
|
+
inputCount: number,
|
|
139
|
+
outputCount: number,
|
|
140
|
+
currency: ICrypto,
|
|
141
|
+
derivationMode: string
|
|
142
|
+
) {
|
|
143
|
+
return Math.ceil(
|
|
144
|
+
accurateTxSize(inputCount, outputCount, currency, derivationMode)
|
|
145
|
+
); // We don't allow floating value
|
|
135
146
|
}
|
|
136
147
|
|
|
137
148
|
// refer to https://github.com/LedgerHQ/lib-ledger-core/blob/fc9d762b83fc2b269d072b662065747a64ab2816/core/src/wallet/bitcoin/api_impl/BitcoinLikeTransactionApi.cpp#L253
|
|
@@ -133,6 +133,7 @@ class BitcoinLikeWallet {
|
|
|
133
133
|
)
|
|
134
134
|
);
|
|
135
135
|
let balance = new BigNumber(0);
|
|
136
|
+
let availableUtxoCount = 0;
|
|
136
137
|
log("btcwallet", "estimateAccountMaxSpendable utxos", utxos);
|
|
137
138
|
utxos.forEach((utxo) => {
|
|
138
139
|
if (
|
|
@@ -144,6 +145,7 @@ class BitcoinLikeWallet {
|
|
|
144
145
|
) {
|
|
145
146
|
if ((pickUnconfirmedRBF && utxo.rbf) || utxo.block_height !== null) {
|
|
146
147
|
balance = balance.plus(utxo.value);
|
|
148
|
+
availableUtxoCount += 1;
|
|
147
149
|
}
|
|
148
150
|
}
|
|
149
151
|
});
|
|
@@ -151,7 +153,7 @@ class BitcoinLikeWallet {
|
|
|
151
153
|
const fees =
|
|
152
154
|
feePerByte *
|
|
153
155
|
utils.estimateTxSize(
|
|
154
|
-
|
|
156
|
+
availableUtxoCount,
|
|
155
157
|
1,
|
|
156
158
|
account.xpub.crypto,
|
|
157
159
|
account.xpub.derivationMode
|