@ledgerhq/live-common 21.16.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/apps/polyfill.d.ts.map +1 -1
- package/lib/apps/polyfill.js +3 -0
- package/lib/apps/polyfill.js.map +1 -1
- package/lib/currencies/support.d.ts.map +1 -1
- package/lib/currencies/support.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 +3 -2
- package/lib/families/bitcoin/js-synchronisation.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 -2
- package/lib/families/bitcoin/wallet-btc/utils.d.ts.map +1 -1
- package/lib/families/bitcoin/wallet-btc/utils.js +103 -35
- 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 -5
- 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/operation.js +1 -1
- package/lib/operation.js.map +1 -1
- package/package.json +5 -5
- package/src/.DS_Store +0 -0
- package/src/__tests__/__snapshots__/all.libcore.ts.snap +1188 -630
- 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/apps/polyfill.ts +3 -0
- package/src/currencies/.DS_Store +0 -0
- package/src/currencies/__snapshots__/sortByMarketcap.test.ts.snap +3 -1
- package/src/currencies/support.ts +1 -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 +4 -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 +113 -41
- package/src/families/bitcoin/wallet-btc/wallet.ts +9 -6
- package/src/families/bitcoin/wallet-btc/xpub.ts +5 -5
- package/src/operation.ts +1 -1
|
@@ -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();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
|
+
import { OutputInfo } from "..";
|
|
2
3
|
import { ICrypto } from "../crypto/types";
|
|
3
4
|
import { Output } from "../storage/types";
|
|
4
5
|
import Xpub from "../xpub";
|
|
@@ -29,9 +30,8 @@ export abstract class PickingStrategy {
|
|
|
29
30
|
|
|
30
31
|
abstract selectUnspentUtxosToUse(
|
|
31
32
|
xpub: Xpub,
|
|
32
|
-
|
|
33
|
-
feePerByte: number
|
|
34
|
-
nbOutputsWithoutChange: number
|
|
33
|
+
outputs: OutputInfo[],
|
|
34
|
+
feePerByte: number
|
|
35
35
|
): Promise<{
|
|
36
36
|
unspentUtxos: Output[];
|
|
37
37
|
totalValue: BigNumber;
|
|
@@ -6,6 +6,7 @@ import { DerivationModes } from "./types";
|
|
|
6
6
|
import { Currency, ICrypto } from "./crypto/types";
|
|
7
7
|
import cryptoFactory from "./crypto/factory";
|
|
8
8
|
import { fallbackValidateAddress } from "./crypto/base";
|
|
9
|
+
import { UnsupportedDerivation } from "../../../errors";
|
|
9
10
|
|
|
10
11
|
export function parseHexString(str: any) {
|
|
11
12
|
const result: Array<number> = [];
|
|
@@ -91,58 +92,129 @@ export function byteSize(count: number) {
|
|
|
91
92
|
return 9;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
derivationMode: string
|
|
100
|
-
) {
|
|
101
|
-
let txSize = 0;
|
|
102
|
-
let fixedSize = 0;
|
|
103
|
-
// Fixed size computation
|
|
104
|
-
fixedSize = 4; // Transaction version
|
|
105
|
-
if (currency.network.usesTimestampedTransaction) fixedSize += 4; // Timestamp
|
|
106
|
-
fixedSize += byteSize(inputCount); // Number of inputs
|
|
107
|
-
fixedSize += byteSize(outputCount); // Number of outputs
|
|
108
|
-
fixedSize += 4; // Timelock
|
|
95
|
+
const baseByte = 4;
|
|
96
|
+
function fixedWeight(currency: ICrypto, derivationMode: string): number {
|
|
97
|
+
let fixedWeight = 4 * baseByte; // Transaction version
|
|
98
|
+
if (currency.network.usesTimestampedTransaction) fixedWeight += 4 * baseByte; // Timestamp
|
|
99
|
+
fixedWeight += 4 * baseByte; // Timelock
|
|
109
100
|
if (derivationMode !== DerivationModes.LEGACY) {
|
|
110
|
-
|
|
101
|
+
fixedWeight += 2; // Segwit marker & segwit flag, 1 WU per byte
|
|
111
102
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
103
|
+
return fixedWeight;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function inputWeight(derivationMode: string): number {
|
|
107
|
+
let inputWeight = (32 + 4 + 1 + 4) * baseByte;
|
|
115
108
|
if (derivationMode === DerivationModes.TAPROOT) {
|
|
116
|
-
|
|
117
|
-
|
|
109
|
+
inputWeight += 1 + 1 + 65;
|
|
110
|
+
} else if (derivationMode === DerivationModes.NATIVE_SEGWIT) {
|
|
111
|
+
inputWeight += 1 + 1 + 72 + 1 + 33;
|
|
112
|
+
} else if (derivationMode === DerivationModes.SEGWIT) {
|
|
113
|
+
inputWeight += 22 * baseByte + 1 + 1 + 72 + 1 + 33;
|
|
114
|
+
} else if (derivationMode === DerivationModes.LEGACY) {
|
|
115
|
+
inputWeight += 107 * baseByte;
|
|
116
|
+
} else {
|
|
117
|
+
throw UnsupportedDerivation(`Derivation mode ${derivationMode} unknown`);
|
|
118
118
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
119
|
+
return inputWeight;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function outputWeight(derivationMode: string): number {
|
|
123
|
+
let outputSize = 8 + 1; // amount + script size
|
|
124
|
+
if (derivationMode === DerivationModes.TAPROOT) {
|
|
125
|
+
outputSize += 34; // "1" + PUSH32 + <32 bytes>
|
|
126
|
+
} else if (derivationMode === DerivationModes.NATIVE_SEGWIT) {
|
|
127
|
+
outputSize += 22; // "0" + PUSH20 + <20 bytes>
|
|
128
|
+
} else if (derivationMode === DerivationModes.SEGWIT) {
|
|
129
|
+
outputSize += 23; // HASH160 + PUSH20 + <20 bytes> + EQUAL
|
|
130
|
+
} else if (derivationMode === DerivationModes.LEGACY) {
|
|
131
|
+
outputSize += 25; // DUP + HASH160 + PUSH20 + <20 bytes> + EQUALVERIFY + CHECKSIG
|
|
131
132
|
} else {
|
|
132
|
-
|
|
133
|
+
throw UnsupportedDerivation(derivationMode);
|
|
133
134
|
}
|
|
134
|
-
return
|
|
135
|
+
return outputSize * 4;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function outputSize(currency: ICrypto, addr: string): number {
|
|
139
|
+
const scriptLen = currency.toOutputScript(addr).length;
|
|
140
|
+
return 1 + 8 + scriptLen;
|
|
135
141
|
}
|
|
136
142
|
|
|
137
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Calculates the maximun size of an imaginary transaction in virtual bytes
|
|
145
|
+
* (vB). 1vB = 4 WU (weight units). If a cryptocurrency doesn't use segwit, then
|
|
146
|
+
* 1 byte = 1 vB. Weight units are used for segwit transactions, where certain
|
|
147
|
+
* bytes of the transaction is counted as 4 WU and some as 1 WU. The resulting
|
|
148
|
+
* size is then ceil(totalWU/4) vB.
|
|
149
|
+
*
|
|
150
|
+
* refer to https://medium.com/coinmonks/on-bitcoin-transaction-sizes-part-2-9445373d17f4
|
|
151
|
+
* and https://bitcoin.stackexchange.com/questions/96017/what-are-the-sizes-of-single-sig-and-2-of-3-multisig-taproot-inputs
|
|
152
|
+
* and https://bitcoinops.org/en/tools/calc-size/
|
|
153
|
+
*
|
|
154
|
+
* Suggested improvement: I assume that these calculations won't be exactly
|
|
155
|
+
* correct for altcoins (but I don't know). Therefore we should move this
|
|
156
|
+
* functionality into ICrypto, to make it easier to provide slightly different
|
|
157
|
+
* calculations for different cryptocurrencies.
|
|
158
|
+
*
|
|
159
|
+
* The reason for the name maxTxSize, instead of just txSize, is that the size
|
|
160
|
+
* of modern ecdsa signatures aren't know beforehand. They are either 71 or
|
|
161
|
+
* 72 bytes. This function always count with 72 byte signatures.
|
|
162
|
+
*
|
|
163
|
+
* The size of schnorr signatures is expected to be 65 bytes, since the Bitcoin
|
|
164
|
+
* hardware app appends the optional sighash type 01 at the end of the
|
|
165
|
+
* signature. If the app removes that optional byte, this functions should be
|
|
166
|
+
* updated to use 64 byte schnorr signatures, even if 65 still is an acceptable
|
|
167
|
+
* maximum.
|
|
168
|
+
*
|
|
169
|
+
* @param inputCount Number of inputs of the imaginary transaction
|
|
170
|
+
* @param outputAddrs The addresses of the outputs, excluding change.
|
|
171
|
+
* @param includeChange Indicates whether we should add a change output. The
|
|
172
|
+
* change output will have the same derivation mode as the inputs. See
|
|
173
|
+
* derivationMode parameter.
|
|
174
|
+
* @param currency The currency for which the calculation is done.
|
|
175
|
+
* @param derivationMode The derivation mode used for calculating the size of
|
|
176
|
+
* the inputs.
|
|
177
|
+
*/
|
|
178
|
+
export function maxTxSize(
|
|
138
179
|
inputCount: number,
|
|
139
|
-
|
|
180
|
+
outputAddrs: string[],
|
|
181
|
+
includeChange: boolean,
|
|
140
182
|
currency: ICrypto,
|
|
141
183
|
derivationMode: string
|
|
142
|
-
) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
); //
|
|
184
|
+
): number {
|
|
185
|
+
const fixed = fixedWeight(currency, derivationMode);
|
|
186
|
+
|
|
187
|
+
let outputsWeight = byteSize(outputAddrs.length) * baseByte; // Number of outputs;
|
|
188
|
+
outputAddrs.forEach((addr) => {
|
|
189
|
+
outputsWeight += outputSize(currency, addr) * baseByte;
|
|
190
|
+
});
|
|
191
|
+
if (includeChange) {
|
|
192
|
+
outputsWeight += outputWeight(derivationMode);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Input: 32 PrevTxHash + 4 Index + 1 scriptSigLength + 4 sequence
|
|
196
|
+
let inputsWeight = byteSize(inputCount) * baseByte; // Number of inputs
|
|
197
|
+
inputsWeight += inputWeight(derivationMode) * inputCount;
|
|
198
|
+
|
|
199
|
+
const txWeight = fixed + inputsWeight + outputsWeight;
|
|
200
|
+
return txWeight / 4;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function maxTxSizeCeil(
|
|
204
|
+
inputCount: number,
|
|
205
|
+
outputAddrs: string[],
|
|
206
|
+
includeChange: boolean,
|
|
207
|
+
currency: ICrypto,
|
|
208
|
+
derivationMode: string
|
|
209
|
+
): number {
|
|
210
|
+
const s = maxTxSize(
|
|
211
|
+
inputCount,
|
|
212
|
+
outputAddrs,
|
|
213
|
+
includeChange,
|
|
214
|
+
currency,
|
|
215
|
+
derivationMode
|
|
216
|
+
);
|
|
217
|
+
return Math.ceil(s);
|
|
146
218
|
}
|
|
147
219
|
|
|
148
220
|
// refer to https://github.com/LedgerHQ/lib-ledger-core/blob/fc9d762b83fc2b269d072b662065747a64ab2816/core/src/wallet/bitcoin/api_impl/BitcoinLikeTransactionApi.cpp#L253
|
|
@@ -122,7 +122,8 @@ class BitcoinLikeWallet {
|
|
|
122
122
|
account: Account,
|
|
123
123
|
feePerByte: number,
|
|
124
124
|
excludeUTXOs: Array<{ hash: string; outputIndex: number }>,
|
|
125
|
-
pickUnconfirmedRBF: boolean
|
|
125
|
+
pickUnconfirmedRBF: boolean,
|
|
126
|
+
outputAddresses: string[] = []
|
|
126
127
|
) {
|
|
127
128
|
const addresses = await account.xpub.getXpubAddresses();
|
|
128
129
|
const utxos = flatten(
|
|
@@ -133,8 +134,8 @@ class BitcoinLikeWallet {
|
|
|
133
134
|
)
|
|
134
135
|
);
|
|
135
136
|
let balance = new BigNumber(0);
|
|
136
|
-
let availableUtxoCount = 0;
|
|
137
137
|
log("btcwallet", "estimateAccountMaxSpendable utxos", utxos);
|
|
138
|
+
let usableUtxoCount = 0;
|
|
138
139
|
utxos.forEach((utxo) => {
|
|
139
140
|
if (
|
|
140
141
|
!excludeUTXOs.find(
|
|
@@ -144,20 +145,22 @@ class BitcoinLikeWallet {
|
|
|
144
145
|
)
|
|
145
146
|
) {
|
|
146
147
|
if ((pickUnconfirmedRBF && utxo.rbf) || utxo.block_height !== null) {
|
|
148
|
+
usableUtxoCount++;
|
|
147
149
|
balance = balance.plus(utxo.value);
|
|
148
|
-
availableUtxoCount += 1;
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
});
|
|
152
153
|
// fees if we use all utxo
|
|
153
154
|
const fees =
|
|
154
155
|
feePerByte *
|
|
155
|
-
utils.
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
utils.maxTxSizeCeil(
|
|
157
|
+
usableUtxoCount,
|
|
158
|
+
outputAddresses,
|
|
159
|
+
outputAddresses.length == 0,
|
|
158
160
|
account.xpub.crypto,
|
|
159
161
|
account.xpub.derivationMode
|
|
160
162
|
);
|
|
163
|
+
|
|
161
164
|
log("btcwallet", "estimateAccountMaxSpendable balance", balance);
|
|
162
165
|
log("btcwallet", "estimateAccountMaxSpendable fees", fees);
|
|
163
166
|
const maxSpendable = balance.minus(fees);
|
|
@@ -288,9 +288,8 @@ class Xpub extends EventEmitter {
|
|
|
288
288
|
needChangeoutput,
|
|
289
289
|
} = await params.utxoPickingStrategy.selectUnspentUtxosToUse(
|
|
290
290
|
this,
|
|
291
|
-
|
|
292
|
-
params.feePerByte
|
|
293
|
-
outputs.length
|
|
291
|
+
outputs,
|
|
292
|
+
params.feePerByte
|
|
294
293
|
);
|
|
295
294
|
|
|
296
295
|
const txHexs = await Promise.all(
|
|
@@ -320,9 +319,10 @@ class Xpub extends EventEmitter {
|
|
|
320
319
|
(utxo, index) => [txs[index].account, txs[index].index]
|
|
321
320
|
);
|
|
322
321
|
|
|
323
|
-
const txSize = utils.
|
|
322
|
+
const txSize = utils.maxTxSizeCeil(
|
|
324
323
|
unspentUtxoSelected.length,
|
|
325
|
-
outputs.
|
|
324
|
+
outputs.map((o) => o.address),
|
|
325
|
+
true,
|
|
326
326
|
this.crypto,
|
|
327
327
|
this.derivationMode
|
|
328
328
|
);
|
package/src/operation.ts
CHANGED
|
@@ -167,5 +167,5 @@ export const isConfirmedOperation = (
|
|
|
167
167
|
confirmationsNb: number
|
|
168
168
|
): boolean =>
|
|
169
169
|
operation.blockHeight
|
|
170
|
-
? account.blockHeight - operation.blockHeight + 1
|
|
170
|
+
? account.blockHeight - operation.blockHeight + 1 >= confirmationsNb
|
|
171
171
|
: false;
|