correct transaction fee if overpayment is detected
MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/FeeChartViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/FeeChartViewModel.cs
@@ -163,7 +163,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
return SliderMaximum;
}
- private double GetConfirmationTarget(FeeRate feeRate)
+ public double GetConfirmationTarget(FeeRate feeRate)
{
if (SatoshiPerByteValues is null || ConfirmationTargetValues is null) // Should not happen
{

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendFeeViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendFeeViewModel.cs
@@ -119,14 +119,14 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
return blockTargetThreshold;
}
- private TimeSpan CalculateConfirmationTime(double targetBlock)
+ public static TimeSpan CalculateConfirmationTime(double targetBlock)
{
var timeInMinutes = Math.Ceiling(targetBlock) * 10;
var time = TimeSpan.FromMinutes(timeInMinutes);
return time;
}
- private static readonly Dictionary<int, int> TestNetFeeEstimates = new ()
+ public static readonly Dictionary<int, int> TestNetFeeEstimates = new ()
{
[1] = 17,
[2] = 12,

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/TransactionPreviewViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/TransactionPreviewViewModel.cs
@@ -177,6 +177,12 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
return await Task.Run(() => TransactionHelpers.BuildTransaction(_wallet, _info));
}
+ catch (TransactionFeeOverpaymentException ex)
+ {
+ SetMaximumPossibleFee(ex.PercentageOfOverpayment, _wallet, _info);
+
+ return await BuildTransactionAsync();
+ }
catch (InsufficientBalanceException)
{
if (_info.IsPayJoin)
@@ -201,6 +207,20 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
}
}
+ private void SetMaximumPossibleFee(decimal percentageOfOverpayment, Wallet wallet, TransactionInfo transactionInfo)
+ {
+ var currentFeeRate = transactionInfo.FeeRate;
+ var lowestPossibleFeeRateInSatoshiPerByte = (currentFeeRate.SatoshiPerByte / percentageOfOverpayment) * 100;
+ var lowestPossibleFeeRate = new FeeRate(lowestPossibleFeeRateInSatoshiPerByte);
+ transactionInfo.FeeRate = lowestPossibleFeeRate;
+
+ var feeChartViewModel = new FeeChartViewModel();
+ var feeEstimations = wallet.Network == Network.Main ? wallet.FeeProvider.AllFeeEstimate.Estimations : SendFeeViewModel.TestNetFeeEstimates;
+ feeChartViewModel.UpdateFeeEstimates(feeEstimations);
+ var blockTarget = feeChartViewModel.GetConfirmationTarget(lowestPossibleFeeRate);
+ transactionInfo.ConfirmationTimeSpan = SendFeeViewModel.CalculateConfirmationTime(blockTarget);
+ }
+
private async Task<BuildTransactionResult?> HandleInsufficientBalanceWhenNormalAsync(Wallet wallet, TransactionInfo transactionInfo)
{
var dialog = new InsufficientBalanceDialogViewModel(transactionInfo.IsPrivatePocketUsed ? BalanceType.Private : BalanceType.Pocket);
@@ -286,14 +306,14 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
TransactionHasChange = _transaction.OuterWalletOutputs.Sum(x => x.Amount) > fee && _transaction.InnerWalletOutputs.Sum(x => x.Amount) > 0;
TransactionHasPockets = !_info.IsPrivatePocketUsed;
+
+ ConfirmationTimeText = $"Approximately {TextHelpers.TimeSpanToFriendlyString(_info.ConfirmationTimeSpan)} ";
}
protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disposables)
{
base.OnNavigatedTo(isInHistory, disposables);
- ConfirmationTimeText = $"Approximately {TextHelpers.TimeSpanToFriendlyString(_info.ConfirmationTimeSpan)} ";
-
if (!isInHistory)
{
RxApp.MainThreadScheduler.Schedule(async () =>

correct transaction fee if overpayment is detected