store custom fee in txn info
MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/AdvancedSendOptionsViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/AdvancedSendOptionsViewModel.cs
+using System.Reactive.Linq;
+using NBitcoin;
+using ReactiveUI;
+using WalletWasabi.Fluent.Validation;
using WalletWasabi.Fluent.ViewModels.Navigation;
+using WalletWasabi.Models;
namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
{
[NavigationMetaData(Title = "Advanced")]
public partial class AdvancedSendOptionsViewModel : RoutableViewModel
{
- public AdvancedSendOptionsViewModel()
+ private readonly TransactionInfo _transactionInfo;
+
+ [AutoNotify] private string _customFee = "";
+
+ public AdvancedSendOptionsViewModel(TransactionInfo transactionInfo)
{
+ _transactionInfo = transactionInfo;
EnableBack = false;
SetupCancel(enableCancel: true, enableCancelOnEscape: true, enableCancelOnPressed: true);
+
+ this.ValidateProperty(x => x.CustomFee, ValidateCustomFee);
+
+ var nextCommandCanExecute =
+ this.WhenAnyValue(x => x.CustomFee)
+ .Select(_ =>
+ {
+ var noError = !Validations.Any;
+ var somethingFilled = CustomFee is not null or "";
+
+ return noError && somethingFilled;
+ });
+
+ NextCommand = ReactiveCommand.Create(OnNext, nextCommandCanExecute);
+ }
+
+ private void OnNext()
+ {
+ if (decimal.TryParse(CustomFee, out var customFee))
+ {
+ _transactionInfo.CustomFeeRate = new FeeRate(customFee);
+ }
+
+ Navigate().Back();
+ }
+
+ private void ValidateCustomFee(IValidationErrors errors)
+ {
+ var customFeeString = CustomFee;
+
+ if (!decimal.TryParse(customFeeString, out _))
+ {
+ errors.Add(ErrorSeverity.Error, "The entered fee is not valid");
+ }
}
}
}

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
@@ -102,7 +102,7 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
}
});
- AdvancedOptionsCommand = ReactiveCommand.Create(() => Navigate(NavigationTarget.CompactDialogScreen).To(new AdvancedSendOptionsViewModel()));
+ AdvancedOptionsCommand = ReactiveCommand.Create(() => Navigate(NavigationTarget.CompactDialogScreen).To(new AdvancedSendOptionsViewModel(_transactionInfo)));
var nextCommandCanExecute =
this.WhenAnyValue(x => x.AmountBtc, x => x.To).Select(_ => Unit.Default)

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/TransactionInfo.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/TransactionInfo.cs
@@ -30,6 +30,8 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
public FeeRate FeeRate { get; set; } = FeeRate.Zero;
+ public FeeRate CustomFeeRate { get; set; } = FeeRate.Zero;
+
public TimeSpan ConfirmationTimeSpan { get; set; }
public IEnumerable<SmartCoin> Coins { get; set; } = Enumerable.Empty<SmartCoin>();

MODIFY
WalletWasabi.Fluent/Views/Wallets/Send/AdvancedSendOptionsView.axaml
WalletWasabi.Fluent/Views/Wallets/Send/AdvancedSendOptionsView.axaml
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="using:WalletWasabi.Fluent.Controls"
xmlns:vm="using:WalletWasabi.Fluent.ViewModels.Wallets.Send"
- xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
- xmlns:behaviors="using:WalletWasabi.Fluent.Behaviors"
mc:Ignorable="d"
x:DataType="vm:AdvancedSendOptionsViewModel"
x:CompileBindings="True"
NextContent="Done"
EnableCancel="{Binding EnableCancel}"
IsBusy="{Binding IsBusy}"
- Height="300" Width="400"
+ Height="300" Width="500"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<DockPanel>
+ <DockPanel.Styles>
+ <Style Selector="DockPanel > Label">
+ <Setter Property="MinWidth" Value="100" />
+ </Style>
+ </DockPanel.Styles>
+
+ <!-- Custom Fee -->
+ <DockPanel DockPanel.Dock="Top" Margin="0,0,0,10">
+ <Label DockPanel.Dock="Left" Content="_Custom Fee:" Target="customFeeTb" />
+ <TextBox x:Name="customFeeTb" MaxLength="250" Text="{Binding CustomFee}" Watermark="sat/vByte" VerticalAlignment="Top" />
+ </DockPanel>
</DockPanel>
</c:ContentArea>

store custom fee in txn info