Skip to content

Commit

Permalink
Add fee feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
nopara73 committed Dec 20, 2018
2 parents 922be4c + bc239be commit fa9aaee
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 13 deletions.
8 changes: 4 additions & 4 deletions WalletWasabi.Gui/Controls/WalletExplorer/SendTabView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@
</DrawingPresenter>
</Grid>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="4">
<TextBlock Text="Confirmation Expected In:" />
<TextBlock Foreground="YellowGreen" Text="{Binding ConfirmationExpectedText}" Width="80" />
<TextBlock Foreground="{DynamicResource ThemeBorderHighBrush}" Text="{Binding FeeText}" />
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Spacing="4">
<TextBlock Text="Confirmation Expected In:" VerticalAlignment="Center"/>
<TextBlock Foreground="YellowGreen" Text="{Binding ConfirmationExpectedText}" Width="80" VerticalAlignment="Center" />
<Button Content="{Binding FeeText}" Command="{Binding FeeRateCommand}" Padding="0" Background="{DynamicResource EditorBackgroundBrush}" BorderBrush="{DynamicResource EditorBackgroundBrush}" VerticalAlignment="Top" />
</StackPanel>
</StackPanel>
</StackPanel>
Expand Down
66 changes: 60 additions & 6 deletions WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using WalletWasabi.Gui.Tabs.WalletManager;
using WalletWasabi.Backend.Models.Responses;
using System.ComponentModel;
using WalletWasabi.Gui.Models;

namespace WalletWasabi.Gui.Controls.WalletExplorer
{
Expand Down Expand Up @@ -49,6 +50,7 @@ public class SendTabViewModel : WalletActionViewModel
private int _caretIndex;
private ObservableCollection<SuggestionViewModel> _suggestions;
private bool IgnoreAmountChanges { get; set; }
private FeeDisplayFormat FeeDisplayFormat { get; set; }

public SendTabViewModel(WalletViewModel walletViewModel)
: base("Send", walletViewModel)
Expand Down Expand Up @@ -189,10 +191,9 @@ public SendTabViewModel(WalletViewModel walletViewModel)
(this).WhenAny(x => x.IsMax, x => x.Amount, x => x.Address, x => x.IsBusy,
(isMax, amount, address, busy) => ((isMax.Value || !string.IsNullOrWhiteSpace(amount.Value)) && !string.IsNullOrWhiteSpace(Address) && !IsBusy)));

MaxCommand = ReactiveCommand.Create(() =>
{
SetMax();
});
MaxCommand = ReactiveCommand.Create(SetMax);

FeeRateCommand = ReactiveCommand.Create(ChangeFeeRateDisplay);

this.WhenAnyValue(x => x.IsBusy).Subscribe(busy =>
{
Expand Down Expand Up @@ -243,6 +244,16 @@ private void CoinList_SelectionChanged(object sender, CoinViewModel e)
SetFeesAndTexts();
}

private void ChangeFeeRateDisplay()
{
var nextval = (from FeeDisplayFormat val in Enum.GetValues(typeof(FeeDisplayFormat))
where val > FeeDisplayFormat
orderby val
select val).DefaultIfEmpty().First();
FeeDisplayFormat = nextval;
SetFeesAndTexts();
}

private void SetFeesAndTexts()
{
AllFeeEstimate allFeeEstimate = Global.Synchronizer?.AllFeeEstimate;
Expand Down Expand Up @@ -291,8 +302,27 @@ private void SetFeesAndTexts()

if (allFeeEstimate != null)
{
//FeeText = $"(~ {SatoshiPerByteFeeRate.Satoshi} sat/byte)";
FeeText = $"(~ {BtcFee.ToString(false, false)} BTC)";
switch (FeeDisplayFormat)
{
case FeeDisplayFormat.SatoshiPerByte:
FeeText = $"(~ {SatoshiPerByteFeeRate.Satoshi} sat/byte)";
break;

case FeeDisplayFormat.USD:
FeeText = $"(~ ${UsdFee.ToString("0.##")})";
break;

case FeeDisplayFormat.BTC:
FeeText = $"(~ {BtcFee.ToString(false, false)} BTC)";
break;

case FeeDisplayFormat.Percentage:
FeeText = $"(~ {FeePercentage.ToString("0.#")} %)";
break;

default:
throw new NotSupportedException("This is impossible.");
}
}
}

Expand Down Expand Up @@ -331,6 +361,28 @@ private void SetFees(AllFeeEstimate allFeeEstimate, int feeTarget)
}

BtcFee = Money.Satoshis(vsize * SatoshiPerByteFeeRate);

if (IsMax)
{
long all = selectedCoins.Sum(x => x.Amount);
if (all != 0)
{
FeePercentage = 100 * (decimal)BtcFee.Satoshi / all;
}
}
else
{
if (Money.TryParse(Amount, out Money amount) && amount.Satoshi != 0)
{
FeePercentage = 100 * (decimal)BtcFee.Satoshi / amount.Satoshi;
}
}

decimal exchangeRate = Global.Synchronizer.UsdExchangeRate;
if (exchangeRate != 0)
{
UsdFee = BtcFee.ToUsd(exchangeRate);
}
}

private void Synchronizer_PropertyChanged(object sender, PropertyChangedEventArgs e)
Expand Down Expand Up @@ -643,5 +695,7 @@ public string SuccessMessage
public ReactiveCommand BuildTransactionCommand { get; }

public ReactiveCommand MaxCommand { get; }

public ReactiveCommand FeeRateCommand { get; }
}
}
14 changes: 14 additions & 0 deletions WalletWasabi.Gui/Models/FeeDisplayFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace WalletWasabi.Gui.Models
{
public enum FeeDisplayFormat
{
USD,
BTC,
SatoshiPerByte,
Percentage
};
}
5 changes: 5 additions & 0 deletions WalletWasabi/Extensions/NBitcoinExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,10 @@ public static Money Percentange(this Money me, decimal perc)
{
return Money.Satoshis((me.Satoshi / 100m) * perc);
}

public static decimal ToUsd(this Money me, decimal btcExchangeRate)
{
return me.ToDecimal(MoneyUnit.BTC) * btcExchangeRate;
}
}
}
8 changes: 8 additions & 0 deletions WalletWasabi/Helpers/NBitcoinHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,13 @@ public static Money TakeAReasonableFee(Money outputValue)

return remaining;
}

public static int CalculateVsizeAssumeSegwit(int inNum, int outNum)
{
var origTxSize = inNum * Constants.P2pkhInputSizeInBytes + outNum * Constants.OutputSizeInBytes + 10;
var newTxSize = inNum * Constants.P2wpkhInputSizeInBytes + outNum * Constants.OutputSizeInBytes + 10; // BEWARE: This assumes segwit only inputs!
var vSize = (int)Math.Ceiling(((3 * newTxSize) + origTxSize) / 4m);
return vSize;
}
}
}
4 changes: 1 addition & 3 deletions WalletWasabi/Services/WalletService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -821,9 +821,7 @@ public BuildTransactionResult BuildTransaction(string password,
// https://bitcoincore.org/en/segwit_wallet_dev/#transaction-fee-estimation
// https://bitcoin.stackexchange.com/a/46379/26859
int outNum = spendAll ? toSend.Length : toSend.Length + 1; // number of addresses to send + 1 for change
var origTxSize = inNum * Constants.P2pkhInputSizeInBytes + outNum * Constants.OutputSizeInBytes + 10;
var newTxSize = inNum * Constants.P2wpkhInputSizeInBytes + outNum * Constants.OutputSizeInBytes + 10; // BEWARE: This assumes segwit only inputs!
var vSize = (int)Math.Ceiling(((3 * newTxSize) + origTxSize) / 4m);
int vSize = NBitcoinHelpers.CalculateVsizeAssumeSegwit(inNum, outNum);
Logger.LogInfo<WalletService>($"Estimated tx size: {vSize} vbytes.");
Money fee = feePerBytes * vSize;
Logger.LogInfo<WalletService>($"Fee: {fee.Satoshi} Satoshi.");
Expand Down

0 comments on commit fa9aaee

Please sign in to comment.