mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-22 06:28:39 +02:00
rbf fixes issues sum utxo and fee calculation (#1625)
* total out amount issue * fix empty inputs and outputs addresses for new tx * fix sum value of utxo not spending * Update configure.dart * Update electrum_wallet.dart * receiving address * review fixes
This commit is contained in:
@@ -398,9 +398,10 @@ class CWBitcoin extends Bitcoin {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> canReplaceByFee(Object wallet, String transactionHash) async {
|
||||
Future<bool> canReplaceByFee(Object wallet, Object transactionInfo) async {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
return bitcoinWallet.canReplaceByFee(transactionHash);
|
||||
final tx = transactionInfo as ElectrumTransactionInfo;
|
||||
return bitcoinWallet.canReplaceByFee(tx);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -18,6 +18,7 @@ import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
|
||||
import 'package:cake_wallet/wownero/wownero.dart';
|
||||
import 'package:cw_core/exceptions.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
import 'package:cake_wallet/view_model/send/send_template_view_model.dart';
|
||||
@@ -392,25 +393,38 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> replaceByFee(String txId, String newFee) async {
|
||||
Future<void> replaceByFee(TransactionInfo tx, String newFee) async {
|
||||
state = IsExecutingState();
|
||||
|
||||
final isSufficient = await bitcoin!.isChangeSufficientForFee(wallet, txId, newFee);
|
||||
try {
|
||||
final isSufficient = await bitcoin!.isChangeSufficientForFee(wallet, tx.id, newFee);
|
||||
|
||||
if (!isSufficient) {
|
||||
state = AwaitingConfirmationState(
|
||||
title: S.current.confirm_fee_deduction,
|
||||
message: S.current.confirm_fee_deduction_content,
|
||||
onConfirm: () async {
|
||||
pendingTransaction = await bitcoin!.replaceByFee(wallet, txId, newFee);
|
||||
state = ExecutedSuccessfullyState();
|
||||
},
|
||||
onCancel: () {
|
||||
state = FailureState('Insufficient change for fee');
|
||||
});
|
||||
} else {
|
||||
pendingTransaction = await bitcoin!.replaceByFee(wallet, txId, newFee);
|
||||
if (!isSufficient) {
|
||||
state = AwaitingConfirmationState(
|
||||
title: S.current.confirm_fee_deduction,
|
||||
message: S.current.confirm_fee_deduction_content,
|
||||
onConfirm: () async => await _executeReplaceByFee(tx, newFee),
|
||||
onCancel: () => state = FailureState('Insufficient change for fee'));
|
||||
} else {
|
||||
await _executeReplaceByFee(tx, newFee);
|
||||
}
|
||||
} catch (e) {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _executeReplaceByFee(TransactionInfo tx, String newFee) async {
|
||||
|
||||
|
||||
clearOutputs();
|
||||
final output = outputs.first;
|
||||
output.address = tx.outputAddresses?.first ?? '';
|
||||
|
||||
try {
|
||||
pendingTransaction = await bitcoin!.replaceByFee(wallet, tx.id, newFee);
|
||||
state = ExecutedSuccessfullyState();
|
||||
} catch (e) {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
case WalletType.bitcoin:
|
||||
_addElectrumListItems(tx, dateFormat);
|
||||
_addBumpFeesListItems(tx);
|
||||
_checkForRBF();
|
||||
_checkForRBF(tx);
|
||||
break;
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
@@ -349,12 +349,15 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
|
||||
void _addBumpFeesListItems(TransactionInfo tx) {
|
||||
transactionPriority = bitcoin!.getBitcoinTransactionPriorityMedium();
|
||||
final inputsCount = (transactionInfo.inputAddresses?.isEmpty ?? true)
|
||||
? 1
|
||||
: transactionInfo.inputAddresses!.length;
|
||||
final outputsCount = (transactionInfo.outputAddresses?.isEmpty ?? true)
|
||||
? 1
|
||||
: transactionInfo.outputAddresses!.length;
|
||||
|
||||
newFee = bitcoin!.getFeeAmountForPriority(
|
||||
wallet,
|
||||
bitcoin!.getBitcoinTransactionPriorityMedium(),
|
||||
transactionInfo.inputAddresses?.length ?? 1,
|
||||
transactionInfo.outputAddresses?.length ?? 1);
|
||||
wallet, bitcoin!.getBitcoinTransactionPriorityMedium(), inputsCount, outputsCount);
|
||||
|
||||
RBFListItems.add(StandartListItem(title: S.current.old_fee, value: tx.feeFormatted() ?? '0.0'));
|
||||
|
||||
@@ -383,12 +386,12 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return setNewFee(value: sliderValue, priority: transactionPriority!);
|
||||
}));
|
||||
|
||||
if (transactionInfo.inputAddresses != null) {
|
||||
if (transactionInfo.inputAddresses != null && transactionInfo.inputAddresses!.isNotEmpty) {
|
||||
RBFListItems.add(StandardExpandableListItem(
|
||||
title: S.current.inputs, expandableItems: transactionInfo.inputAddresses!));
|
||||
}
|
||||
|
||||
if (transactionInfo.outputAddresses != null) {
|
||||
if (transactionInfo.outputAddresses != null && transactionInfo.outputAddresses!.isNotEmpty) {
|
||||
RBFListItems.add(StandardExpandableListItem(
|
||||
title: S.current.outputs, expandableItems: transactionInfo.outputAddresses!));
|
||||
}
|
||||
@@ -416,10 +419,10 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> _checkForRBF() async {
|
||||
Future<void> _checkForRBF(TransactionInfo tx) async {
|
||||
if (wallet.type == WalletType.bitcoin &&
|
||||
transactionInfo.direction == TransactionDirection.outgoing) {
|
||||
if (await bitcoin!.canReplaceByFee(wallet, transactionInfo.id)) {
|
||||
if (await bitcoin!.canReplaceByFee(wallet, tx)) {
|
||||
_canReplaceByFee = true;
|
||||
}
|
||||
}
|
||||
@@ -441,7 +444,7 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return bitcoin!.formatterBitcoinAmountToString(amount: newFee);
|
||||
}
|
||||
|
||||
void replaceByFee(String newFee) => sendViewModel.replaceByFee(transactionInfo.id, newFee);
|
||||
void replaceByFee(String newFee) => sendViewModel.replaceByFee(transactionInfo, newFee,);
|
||||
|
||||
@computed
|
||||
String get pendingTransactionFiatAmountValueFormatted => sendViewModel.isFiatDisabled
|
||||
|
||||
Reference in New Issue
Block a user