Merge pull request #2419 from BlueWallet/limpbrains-recalc-fee

FIX: show more accurate precalculation fee on "Not enough balance." exception
This commit is contained in:
GLaDOS 2020-12-24 17:39:43 +00:00 committed by GitHub
commit 3af05a08ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 40 deletions

View file

@ -276,8 +276,8 @@ export class LegacyWallet extends AbstractWallet {
if (!changeAddress) throw new Error('No change address provided');
let algo = coinSelectAccumulative;
if (targets.length === 1 && targets[0] && !targets[0].value) {
// we want to send MAX
// if targets has output without a value, we want send MAX to it
if (targets.some(i => !('value' in i))) {
algo = coinSelectSplit;
}
@ -285,7 +285,7 @@ export class LegacyWallet extends AbstractWallet {
// .inputs and .outputs will be undefined if no solution was found
if (!inputs || !outputs) {
throw new Error('Not enough balance. Try sending smaller amount');
throw new Error('Not enough balance. Try sending smaller amount or decrease the fee.');
}
return { inputs, outputs, fee };

View file

@ -3,8 +3,6 @@ import bip39 from 'bip39';
import b58 from 'bs58check';
import { decodeUR } from 'bc-ur';
const BlueElectrum = require('../../blue_modules/BlueElectrum');
const coinSelectAccumulative = require('coinselect/accumulative');
const coinSelectSplit = require('coinselect/split');
const HDNode = require('bip32');
const bitcoin = require('bitcoinjs-lib');
const createHash = require('create-hash');
@ -809,22 +807,9 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet {
if (targets.length === 0) throw new Error('No destination provided');
if (this.howManySignaturesCanWeMake() === 0) skipSigning = true;
if (!changeAddress) throw new Error('No change address provided');
const { inputs, outputs, fee } = this.coinselect(utxos, targets, feeRate, changeAddress);
sequence = sequence || AbstractHDElectrumWallet.defaultRBFSequence;
let algo = coinSelectAccumulative;
if (targets.length === 1 && targets[0] && !targets[0].value) {
// we want to send MAX
algo = coinSelectSplit;
}
const { inputs, outputs, fee } = algo(utxos, targets, feeRate);
// .inputs and .outputs will be undefined if no solution was found
if (!inputs || !outputs) {
throw new Error('Not enough balance. Try sending smaller amount');
}
let psbt = new bitcoin.Psbt();
let c = 0;

View file

@ -557,6 +557,11 @@ export default class SendDetails extends Component {
}
}
// if targets is empty, insert dust
if (targets.length === 0) {
targets.push({ address: '36JxaUrpDzkEerkTf1FzwHNE1Hb7cCjgJV', value: 546 });
}
// replace wrong addresses with dump
targets = targets.map(t => {
try {
@ -570,21 +575,15 @@ export default class SendDetails extends Component {
let flag = false;
while (true) {
try {
const { fee } = wallet.coinselect(
utxo,
targets,
opt.fee,
changeAddress,
this.state.isTransactionReplaceable ? HDSegwitBech32Wallet.defaultRBFSequence : HDSegwitBech32Wallet.finalRBFSequence,
);
const { fee } = wallet.coinselect(utxo, targets, opt.fee, changeAddress);
feePrecalc[opt.key] = fee;
break;
} catch (e) {
if (e.message.includes('Not enough') && !flag) {
flag = true;
// if the outputs are too big, replace them with dust
targets = targets.map(t => ({ ...t, value: 546 }));
// if we don't have enough funds, construct maximum possible transaction
targets = targets.map((t, index) => (index > 0 ? { ...t, value: 546 } : { address: t.address }));
continue;
}
@ -1291,13 +1290,15 @@ export default class SendDetails extends Component {
item.address = address || text;
item.amount = amount || item.amount;
transactions[index] = item;
this.setState({
addresses: transactions,
memo: memo || this.state.memo,
isLoading: false,
payjoinUrl,
});
this.reCalcTx();
this.setState(
{
addresses: transactions,
memo: memo || this.state.memo,
isLoading: false,
payjoinUrl,
},
this.reCalcTx,
);
}}
onBarScanned={this.processAddressData}
address={item.address}
@ -1326,11 +1327,14 @@ export default class SendDetails extends Component {
recipient.amount = BitcoinUnit.MAX;
recipient.amountSats = BitcoinUnit.MAX;
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
this.setState({
addresses: [recipient],
units: [BitcoinUnit.BTC],
isAdvancedTransactionOptionsVisible: false,
});
this.setState(
{
addresses: [recipient],
units: [BitcoinUnit.BTC],
isAdvancedTransactionOptionsVisible: false,
},
this.reCalcTx,
);
},
style: 'default',
},