SendUX - add validation of amount and to fields.
MODIFY
WalletWasabi.Fluent/Controls/CurrencyEntryBox.axaml.cs
WalletWasabi.Fluent/Controls/CurrencyEntryBox.axaml.cs
@@ -16,9 +16,12 @@ namespace WalletWasabi.Fluent.Controls
{
public class CurrencyEntryBox : TextBox
{
- public static readonly StyledProperty<decimal> AmountBtcProperty =
- AvaloniaProperty.Register<CurrencyEntryBox, decimal>(
+ public static readonly DirectProperty<CurrencyEntryBox, decimal> AmountBtcProperty =
+ AvaloniaProperty.RegisterDirect<CurrencyEntryBox, decimal>(
nameof(AmountBtc),
+ o => o.AmountBtc,
+ (o, v) => o.AmountBtc = v,
+ enableDataValidation: true,
defaultBindingMode: BindingMode.TwoWay);
public static readonly StyledProperty<string> ConversionTextProperty =
@@ -46,6 +49,7 @@ namespace WalletWasabi.Fluent.Controls
private Button? _swapButton;
private CompositeDisposable? _disposable;
private bool _canUpdateDisplay = true;
+ private decimal _amountBtc;
public CurrencyEntryBox()
{
@@ -89,8 +93,8 @@ namespace WalletWasabi.Fluent.Controls
public decimal AmountBtc
{
- get => GetValue(AmountBtcProperty);
- set => SetValue(AmountBtcProperty, value);
+ get => _amountBtc;
+ set => SetAndRaise(AmountBtcProperty, ref _amountBtc, value);
}
public string ConversionText
@@ -133,6 +137,14 @@ namespace WalletWasabi.Fluent.Controls
return btcValue * ConversionRate;
}
+ protected override void UpdateDataValidation<T>(AvaloniaProperty<T> property, BindingValue<T> value)
+ {
+ if (property == AmountBtcProperty)
+ {
+ DataValidationErrors.SetError(this, value.Error);
+ }
+ }
+
protected override void OnGotFocus(GotFocusEventArgs e)
{
base.OnGotFocus(e);

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
@@ -13,8 +13,11 @@ using NBitcoin;
using NBitcoin.Payment;
using ReactiveUI;
using WalletWasabi.Blockchain.Analysis.Clustering;
+using WalletWasabi.Fluent.Validation;
using WalletWasabi.Fluent.ViewModels.NavBar;
using WalletWasabi.Gui.Converters;
+using WalletWasabi.Helpers;
+using WalletWasabi.Models;
using WalletWasabi.Userfacing;
namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
@@ -54,6 +57,9 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
ExchangeRate = walletVm.Wallet.Synchronizer.UsdExchangeRate;
PriorLabels = new();
+ this.ValidateProperty(x=>x.To, ValidateToField);
+ this.ValidateProperty(x=>x.AmountBtc, ValidateAmount);
+
this.WhenAnyValue(x => x.To)
.Subscribe(ParseToField);
@@ -96,6 +102,31 @@ namespace WalletWasabi.Fluent.ViewModels.Wallets.Send
});
}
+ private void ValidateAmount(IValidationErrors errors)
+ {
+ if (AmountBtc > Constants.MaximumNumberOfBitcoins)
+ {
+ errors.Add(ErrorSeverity.Error, "Amount must be less than the total supply of BTC.");
+ }
+ else if (AmountBtc > _owner.Wallet.Coins.TotalAmount().ToDecimal(MoneyUnit.BTC))
+ {
+ errors.Add(ErrorSeverity.Error, "Insufficient funds to cover the amount requested.");
+ }
+ else if (AmountBtc <= 0)
+ {
+ errors.Add(ErrorSeverity.Error, "Amount must be more than 0 BTC");
+ }
+ }
+
+ private void ValidateToField(IValidationErrors errors)
+ {
+ if (!string.IsNullOrWhiteSpace(To) &&
+ !AddressStringParser.TryParse(To, _owner.Wallet.Network, out BitcoinUrlBuilder? url))
+ {
+ errors.Add(ErrorSeverity.Error, "Input a valid BTC address or URL.");
+ }
+ }
+
private void ParseToField(string s)
{
if (_parsingUrl)

SendUX - add validation of amount and to fields.