From 9cf3b1828eb5c2d9ad4f27e3d44c76bcd6e20e3d Mon Sep 17 00:00:00 2001 From: Ichthus1604 <98904713+ichthus1604@users.noreply.github.com> Date: Thu, 25 Apr 2024 09:03:17 -0300 Subject: [PATCH] lots of changes --- .../Controls/AmountControl.axaml | 2 +- .../Transactions/PrivacySuggestionsModel.cs | 14 ++--- .../Models/Transactions/SendFlowModel.cs | 51 +++++++++++++++ .../Models/Transactions/SendParameters.cs | 27 -------- .../Models/Wallets/CoinListModel.cs | 62 +++++++++++++++++++ .../Models/Wallets/IWalletCoinsModel.cs | 7 +++ .../Wallets/UserSelectionCoinListModel.cs | 24 +++++++ .../Models/Wallets/WalletCoinsModel.cs | 60 +++--------------- .../Models/Wallets/WalletModel.cs | 4 +- .../CoinControl/SelectCoinsDialogViewModel.cs | 6 +- .../Wallets/Advanced/WalletCoinsViewModel.cs | 8 +-- .../Send/ManualControlDialogViewModel.cs | 9 +-- .../Send/PrivacySuggestionsFlyoutViewModel.cs | 2 +- .../ViewModels/Wallets/Send/SendViewModel.cs | 4 +- .../Send/TransactionPreviewViewModel.cs | 18 +++--- .../ViewModels/Wallets/WalletViewModel.cs | 2 +- .../ReceiveAddressViewModelTests.cs | 2 +- .../SuggestionLabelsViewModelTests.cs | 2 +- 18 files changed, 190 insertions(+), 114 deletions(-) create mode 100644 WalletWasabi.Fluent/Models/Transactions/SendFlowModel.cs delete mode 100644 WalletWasabi.Fluent/Models/Transactions/SendParameters.cs create mode 100644 WalletWasabi.Fluent/Models/Wallets/CoinListModel.cs create mode 100644 WalletWasabi.Fluent/Models/Wallets/IWalletCoinsModel.cs create mode 100644 WalletWasabi.Fluent/Models/Wallets/UserSelectionCoinListModel.cs diff --git a/WalletWasabi.Fluent/Controls/AmountControl.axaml b/WalletWasabi.Fluent/Controls/AmountControl.axaml index d237ab979c5..57d0ff29ec0 100644 --- a/WalletWasabi.Fluent/Controls/AmountControl.axaml +++ b/WalletWasabi.Fluent/Controls/AmountControl.axaml @@ -39,7 +39,7 @@ - (); } @@ -105,7 +105,7 @@ private IEnumerable VerifyLabels(Parameters parameters) private PrivacyItem? GetLabelWarning(BuildTransactionResult transactionResult, LabelsArray recipient) { - var pockets = _sendParameters.GetPockets(); + var pockets = _sendFlow.GetPockets(); var spentCoins = transactionResult.SpentCoins; var nonPrivateSpentCoins = spentCoins.Where(x => x.GetPrivacyLevel(_wallet.AnonScoreTarget) == PrivacyLevel.NonPrivate).ToList(); var usedPockets = pockets.Where(x => x.Coins.Any(coin => nonPrivateSpentCoins.Contains(coin))).ToList(); @@ -157,7 +157,7 @@ private IEnumerable VerifyPrivacyLevel(Parameters parameters) yield break; } - var availableCoins = _sendParameters.AvailableCoins; + var availableCoins = _sendFlow.AvailableCoins; ImmutableList coinsToExclude = _cjManager.CoinsInCriticalPhase[_wallet.WalletId]; bool wasCoinjoiningCoinUsed = parameters.Transaction.SpentCoins.Any(coinsToExclude.Contains); @@ -274,7 +274,7 @@ private async Task> CreateChangeAvoidanceSuggest // Only allow to create 1 more input with BnB. This accounts for the change created. int maxInputCount = transaction.SpentCoins.Count() + 1; - var pockets = _sendParameters.GetPockets(); + var pockets = _sendFlow.GetPockets(); var spentCoins = transaction.SpentCoins; var usedPockets = pockets.Where(x => x.Coins.Any(coin => spentCoins.Contains(coin))); ImmutableArray coinsToUse = usedPockets.SelectMany(x => x.Coins).ToImmutableArray(); diff --git a/WalletWasabi.Fluent/Models/Transactions/SendFlowModel.cs b/WalletWasabi.Fluent/Models/Transactions/SendFlowModel.cs new file mode 100644 index 00000000000..fa2fcc1aaf1 --- /dev/null +++ b/WalletWasabi.Fluent/Models/Transactions/SendFlowModel.cs @@ -0,0 +1,51 @@ +using NBitcoin; +using ReactiveUI; +using System.Collections.Generic; +using System.Linq; +using WalletWasabi.Blockchain.Analysis.Clustering; +using WalletWasabi.Blockchain.TransactionOutputs; +using WalletWasabi.Fluent.Helpers; +using WalletWasabi.Fluent.Models.Wallets; +using WalletWasabi.Fluent.ViewModels.Wallets.Send; +using WalletWasabi.Wallets; + +namespace WalletWasabi.Fluent.Models.Transactions; + +public record SendFlowModel +{ + private SendFlowModel(Wallet wallet, ICoinsView availableCoins, ICoinListModel coinListModel) + { + Wallet = wallet; + AvailableCoins = availableCoins; + CoinListModel = coinListModel; + } + + /// Regular Send Flow. Uses all wallet coins + public SendFlowModel(Wallet wallet, IWalletModel walletModel): + this(wallet, wallet.Coins, walletModel.Coins) + { + } + + /// Manual Control Send Flow. Uses only the specified coins. + public SendFlowModel(Wallet wallet, IWalletModel walletModel, IEnumerable coins): + this(wallet, new CoinsView(coins), new UserSelectionCoinListModel(wallet, walletModel, coins.ToArray())) + { + } + + public Wallet Wallet { get; } + + public ICoinsView AvailableCoins { get; } + + public ICoinListModel CoinListModel { get; } + + public TransactionInfo? TransactionInfo { get; init; } = null; + + public decimal AvailableAmountBtc => AvailableAmount.ToDecimal(MoneyUnit.BTC); + + public Money AvailableAmount => AvailableCoins.TotalAmount(); + + public bool IsManual => AvailableCoins.TotalAmount() != Wallet.Coins.TotalAmount(); + + public IEnumerable<(LabelsArray Labels, ICoinsView Coins)> GetPockets() => AvailableCoins.GetPockets(Wallet.AnonScoreTarget); + +} diff --git a/WalletWasabi.Fluent/Models/Transactions/SendParameters.cs b/WalletWasabi.Fluent/Models/Transactions/SendParameters.cs deleted file mode 100644 index 8263ba7ac57..00000000000 --- a/WalletWasabi.Fluent/Models/Transactions/SendParameters.cs +++ /dev/null @@ -1,27 +0,0 @@ -using NBitcoin; -using System.Collections.Generic; -using WalletWasabi.Blockchain.Analysis.Clustering; -using WalletWasabi.Blockchain.TransactionOutputs; -using WalletWasabi.Fluent.Helpers; -using WalletWasabi.Fluent.ViewModels.Wallets.Send; -using WalletWasabi.Wallets; - -namespace WalletWasabi.Fluent.Models.Transactions; - -public record SendParameters( - Wallet Wallet, - ICoinsView AvailableCoins, - TransactionInfo? TransactionInfo = null) -{ - public static SendParameters Create(Wallet wallet) => new SendParameters(wallet, wallet.Coins); - - public static SendParameters CreateManual(Wallet wallet, IEnumerable coins) => new SendParameters(wallet, new CoinsView(coins)); - - public decimal AvailableAmountBtc => AvailableAmount.ToDecimal(MoneyUnit.BTC); - - public Money AvailableAmount => AvailableCoins.TotalAmount(); - - public bool IsManual => AvailableCoins.TotalAmount() != Wallet.Coins.TotalAmount(); - - public IEnumerable<(LabelsArray Labels, ICoinsView Coins)> GetPockets() => AvailableCoins.GetPockets(Wallet.AnonScoreTarget); -} diff --git a/WalletWasabi.Fluent/Models/Wallets/CoinListModel.cs b/WalletWasabi.Fluent/Models/Wallets/CoinListModel.cs new file mode 100644 index 00000000000..e5e64f73d4f --- /dev/null +++ b/WalletWasabi.Fluent/Models/Wallets/CoinListModel.cs @@ -0,0 +1,62 @@ +using System.Linq; +using System.Reactive.Disposables; +using System.Reactive.Linq; +using DynamicData; +using ReactiveUI; +using WalletWasabi.Blockchain.Analysis.Clustering; +using WalletWasabi.Blockchain.TransactionOutputs; +using WalletWasabi.Fluent.Extensions; +using WalletWasabi.Logging; +using WalletWasabi.Wallets; + +namespace WalletWasabi.Fluent.Models.Wallets; + +[AutoInterface] +public abstract partial class CoinListModel : IDisposable +{ + private readonly CompositeDisposable _disposables = new(); + + public CoinListModel(Wallet wallet, IWalletModel walletModel) + { + Wallet = wallet; + WalletModel = walletModel; + var transactionProcessed = walletModel.Transactions.TransactionProcessed; + var anonScoreTargetChanged = this.WhenAnyValue(x => x.WalletModel.Settings.AnonScoreTarget).Skip(1).ToSignal(); + var isCoinjoinRunningChanged = walletModel.Coinjoin.IsRunning.ToSignal(); + + var signals = + transactionProcessed + .Merge(anonScoreTargetChanged) + .Merge(isCoinjoinRunningChanged) + .Publish(); + + List = signals.Fetch(GetCoins, x => x.Key).DisposeWith(_disposables); + Pockets = signals.Fetch(GetPockets, x => x.Labels).DisposeWith(_disposables); + + signals + .Do(_ => Logger.LogDebug($"Refresh signal emitted in {walletModel.Name}")) + .Subscribe() + .DisposeWith(_disposables); + + signals.Connect() + .DisposeWith(_disposables); + } + + protected Wallet Wallet { get; } + protected IWalletModel WalletModel { get; } + + public IObservableCache List { get; } + + public IObservableCache Pockets { get; } + + public ICoinModel GetCoinModel(SmartCoin smartCoin) + { + return new CoinModel(smartCoin, WalletModel.Settings.AnonScoreTarget); + } + + protected abstract Pocket[] GetPockets(); + + protected abstract ICoinModel[] GetCoins(); + + public void Dispose() => _disposables.Dispose(); +} diff --git a/WalletWasabi.Fluent/Models/Wallets/IWalletCoinsModel.cs b/WalletWasabi.Fluent/Models/Wallets/IWalletCoinsModel.cs new file mode 100644 index 00000000000..1a8de68884a --- /dev/null +++ b/WalletWasabi.Fluent/Models/Wallets/IWalletCoinsModel.cs @@ -0,0 +1,7 @@ +using DynamicData; +using WalletWasabi.Blockchain.Analysis.Clustering; +using WalletWasabi.Blockchain.TransactionOutputs; + +namespace WalletWasabi.Fluent.Models.Wallets; + +partial interface IWalletCoinsModel: ICoinListModel; diff --git a/WalletWasabi.Fluent/Models/Wallets/UserSelectionCoinListModel.cs b/WalletWasabi.Fluent/Models/Wallets/UserSelectionCoinListModel.cs new file mode 100644 index 00000000000..a9d592c0e5e --- /dev/null +++ b/WalletWasabi.Fluent/Models/Wallets/UserSelectionCoinListModel.cs @@ -0,0 +1,24 @@ +using System.Linq; +using System.Reactive.Linq; +using WalletWasabi.Blockchain.TransactionOutputs; +using WalletWasabi.Fluent.Helpers; +using WalletWasabi.Wallets; + +namespace WalletWasabi.Fluent.Models.Wallets; + +[AutoInterface] +public partial class UserSelectionCoinListModel(Wallet wallet, IWalletModel walletModel, SmartCoin[] selectedCoins) : CoinListModel(wallet, walletModel) +{ + protected override ICoinModel[] GetCoins() + { + return selectedCoins.Select(GetCoinModel).ToArray(); + } + + protected override Pocket[] GetPockets() + { + return + new CoinsView(selectedCoins).GetPockets(WalletModel.Settings.AnonScoreTarget) + .Select(x => new Pocket(x)) + .ToArray(); + } +} diff --git a/WalletWasabi.Fluent/Models/Wallets/WalletCoinsModel.cs b/WalletWasabi.Fluent/Models/Wallets/WalletCoinsModel.cs index 2fc9b34d369..01e49a4efd8 100644 --- a/WalletWasabi.Fluent/Models/Wallets/WalletCoinsModel.cs +++ b/WalletWasabi.Fluent/Models/Wallets/WalletCoinsModel.cs @@ -1,82 +1,36 @@ using System.Collections.Generic; using System.Linq; -using System.Reactive.Disposables; using System.Reactive.Linq; -using DynamicData; -using ReactiveUI; -using WalletWasabi.Blockchain.Analysis.Clustering; using WalletWasabi.Blockchain.TransactionBuilding; using WalletWasabi.Blockchain.TransactionOutputs; -using WalletWasabi.Fluent.Extensions; using WalletWasabi.Fluent.Helpers; using WalletWasabi.Fluent.ViewModels.Wallets.Send; -using WalletWasabi.Logging; using WalletWasabi.Wallets; namespace WalletWasabi.Fluent.Models.Wallets; [AutoInterface] -public partial class WalletCoinsModel : IDisposable +public partial class WalletCoinsModel(Wallet wallet, IWalletModel walletModel) : CoinListModel(wallet, walletModel) { - private readonly Wallet _wallet; - private readonly IWalletModel _walletModel; - private readonly CompositeDisposable _disposables = new(); - - public WalletCoinsModel(Wallet wallet, IWalletModel walletModel) - { - _wallet = wallet; - _walletModel = walletModel; - var transactionProcessed = walletModel.Transactions.TransactionProcessed; - var anonScoreTargetChanged = this.WhenAnyValue(x => x._walletModel.Settings.AnonScoreTarget).Skip(1).ToSignal(); - var isCoinjoinRunningChanged = walletModel.Coinjoin.IsRunning.ToSignal(); - - var signals = - transactionProcessed - .Merge(anonScoreTargetChanged) - .Merge(isCoinjoinRunningChanged) - .Publish(); - - List = signals.Fetch(GetCoins, x => x.Key).DisposeWith(_disposables); - Pockets = signals.Fetch(GetPockets, x => x.Labels).DisposeWith(_disposables); - - signals - .Do(_ => Logger.LogDebug($"Refresh signal emitted in {walletModel.Name}")) - .Subscribe() - .DisposeWith(_disposables); - - signals.Connect() - .DisposeWith(_disposables); - } - - public IObservableCache List { get; } - - public IObservableCache Pockets { get; } - public List GetSpentCoins(BuildTransactionResult? transaction) { var coins = (transaction?.SpentCoins ?? new List()).ToList(); return coins.Select(GetCoinModel).ToList(); } - public ICoinModel GetCoinModel(SmartCoin smartCoin) - { - return new CoinModel(smartCoin, _walletModel.Settings.AnonScoreTarget); - } - public bool AreEnoughToCreateTransaction(TransactionInfo transactionInfo, IEnumerable coins) { - return TransactionHelpers.TryBuildTransactionWithoutPrevTx(_wallet.KeyManager, transactionInfo, _wallet.Coins, coins.GetSmartCoins(), _wallet.Kitchen.SaltSoup(), out _); + return TransactionHelpers.TryBuildTransactionWithoutPrevTx(Wallet.KeyManager, transactionInfo, Wallet.Coins, coins.GetSmartCoins(), Wallet.Kitchen.SaltSoup(), out _); } - private Pocket[] GetPockets() + protected override Pocket[] GetPockets() { - return _wallet.GetPockets().ToArray(); + return Wallet.GetPockets().ToArray(); } - private ICoinModel[] GetCoins() + protected override ICoinModel[] GetCoins() { - return _wallet.Coins.Select(GetCoinModel).ToArray(); + return Wallet.Coins.Select(GetCoinModel).ToArray(); } - - public void Dispose() => _disposables.Dispose(); } + diff --git a/WalletWasabi.Fluent/Models/Wallets/WalletModel.cs b/WalletWasabi.Fluent/Models/Wallets/WalletModel.cs index c5a12217f1f..6a3590be2ec 100644 --- a/WalletWasabi.Fluent/Models/Wallets/WalletModel.cs +++ b/WalletWasabi.Fluent/Models/Wallets/WalletModel.cs @@ -122,9 +122,9 @@ public IWalletInfoModel GetWalletInfo() return new WalletInfoModel(Wallet); } - public IPrivacySuggestionsModel GetPrivacySuggestionsModel(SendParameters sendParameters) + public IPrivacySuggestionsModel GetPrivacySuggestionsModel(SendFlowModel sendFlow) { - return new PrivacySuggestionsModel(sendParameters); + return new PrivacySuggestionsModel(sendFlow); } public void Rename(string newWalletName) diff --git a/WalletWasabi.Fluent/ViewModels/CoinControl/SelectCoinsDialogViewModel.cs b/WalletWasabi.Fluent/ViewModels/CoinControl/SelectCoinsDialogViewModel.cs index 6b6e55da1e2..83d835ddb4f 100644 --- a/WalletWasabi.Fluent/ViewModels/CoinControl/SelectCoinsDialogViewModel.cs +++ b/WalletWasabi.Fluent/ViewModels/CoinControl/SelectCoinsDialogViewModel.cs @@ -5,6 +5,7 @@ using DynamicData.Binding; using ReactiveUI; using WalletWasabi.Blockchain.TransactionOutputs; +using WalletWasabi.Fluent.Models.Transactions; using WalletWasabi.Fluent.Models.Wallets; using WalletWasabi.Fluent.ViewModels.Dialogs.Base; using WalletWasabi.Fluent.ViewModels.Wallets.Coins; @@ -21,8 +22,11 @@ namespace WalletWasabi.Fluent.ViewModels.CoinControl; NavigationTarget = NavigationTarget.DialogScreen)] public partial class SelectCoinsDialogViewModel : DialogViewModelBase> { - public SelectCoinsDialogViewModel(IWalletModel wallet, IList selectedCoins, TransactionInfo transactionInfo) + public SelectCoinsDialogViewModel(IWalletModel wallet, IList selectedCoins, SendFlowModel sendFlow) { + var transactionInfo = sendFlow.TransactionInfo ?? throw new InvalidOperationException($"Missing required TransactionInfo."); + + // TODO: pass the SendFlow here to show only the relevant coins in the list CoinList = new CoinListViewModel(wallet, selectedCoins, true); EnoughSelected = CoinList.Selection.ToObservableChangeSet() diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/Advanced/WalletCoinsViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/Advanced/WalletCoinsViewModel.cs index 9ba91c2ce0c..ac8f5f413f5 100644 --- a/WalletWasabi.Fluent/ViewModels/Wallets/Advanced/WalletCoinsViewModel.cs +++ b/WalletWasabi.Fluent/ViewModels/Wallets/Advanced/WalletCoinsViewModel.cs @@ -93,9 +93,9 @@ private async Task OnSendCoinsAsync() // TODO: Remove this after TransactionPreviewViewModel is decoupled. var walletVm = MainViewModel.Instance.NavBar.Wallets.First(x => x.Wallet.WalletName == _wallet.Name).WalletViewModel; - - var sendParameters = SendParameters.CreateManual(walletVm.Wallet, selectedSmartCoins); - - Navigate().To().TransactionPreview(_wallet, sendParameters); + if (walletVm is null) + { + return; + } } } diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/Send/ManualControlDialogViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/Send/ManualControlDialogViewModel.cs index fb3ffcd8072..47536f067ef 100644 --- a/WalletWasabi.Fluent/ViewModels/Wallets/Send/ManualControlDialogViewModel.cs +++ b/WalletWasabi.Fluent/ViewModels/Wallets/Send/ManualControlDialogViewModel.cs @@ -55,16 +55,17 @@ private ManualControlDialogViewModel(IWalletModel walletModel, Wallet wallet) protected override void OnNavigatedFrom(bool isInHistory) { - CoinList.Dispose(); - - base.OnNavigatedFrom(isInHistory); + if (!isInHistory) + { + CoinList.Dispose(); + } } private void OnNext() { var coins = CoinList.Selection.GetSmartCoins().ToList(); - var sendParameters = SendParameters.CreateManual(_wallet, coins); + var sendParameters = new SendFlowModel(_wallet, _walletModel, coins); Navigate().To().Send(_walletModel, sendParameters); } diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacySuggestionsFlyoutViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacySuggestionsFlyoutViewModel.cs index f3b9ac97050..5200d8b508d 100644 --- a/WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacySuggestionsFlyoutViewModel.cs +++ b/WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacySuggestionsFlyoutViewModel.cs @@ -28,7 +28,7 @@ public partial class PrivacySuggestionsFlyoutViewModel : ViewModelBase [AutoNotify] private bool _goodPrivacy; [AutoNotify] private bool _maxPrivacy; - public PrivacySuggestionsFlyoutViewModel(IWalletModel wallet, SendParameters sendParameters) + public PrivacySuggestionsFlyoutViewModel(IWalletModel wallet, SendFlowModel sendParameters) { _privacySuggestionsModel = wallet.GetPrivacySuggestionsModel(sendParameters); } diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs index 8779a4c63ad..28233dbbc82 100644 --- a/WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs +++ b/WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs @@ -45,7 +45,7 @@ public partial class SendViewModel : RoutableViewModel private readonly object _parsingLock = new(); private readonly Wallet _wallet; private readonly IWalletModel _walletModel; - private readonly SendParameters _parameters; + private readonly SendFlowModel _parameters; private readonly CoinJoinManager? _coinJoinManager; private readonly ClipboardObserver _clipboardObserver; @@ -60,7 +60,7 @@ public partial class SendViewModel : RoutableViewModel [AutoNotify] private bool _conversionReversed; [AutoNotify(SetterModifier = AccessModifier.Private)] private SuggestionLabelsViewModel _suggestionLabels; - public SendViewModel(UiContext uiContext, IWalletModel walletModel, SendParameters parameters) + public SendViewModel(UiContext uiContext, IWalletModel walletModel, SendFlowModel parameters) { UiContext = uiContext; _to = ""; diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/Send/TransactionPreviewViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/Send/TransactionPreviewViewModel.cs index 3ccc0cb4c91..7ae213325a5 100644 --- a/WalletWasabi.Fluent/ViewModels/Wallets/Send/TransactionPreviewViewModel.cs +++ b/WalletWasabi.Fluent/ViewModels/Wallets/Send/TransactionPreviewViewModel.cs @@ -32,7 +32,7 @@ public partial class TransactionPreviewViewModel : RoutableViewModel private readonly Stack<(BuildTransactionResult, TransactionInfo)> _undoHistory; private readonly Wallet _wallet; private readonly IWalletModel _walletModel; - private readonly SendParameters _parameters; + private readonly SendFlowModel _sendFlow; private TransactionInfo _info; private TransactionInfo _currentTransactionInfo; private CancellationTokenSource _cancellationTokenSource; @@ -42,18 +42,18 @@ public partial class TransactionPreviewViewModel : RoutableViewModel [AutoNotify] private bool _canUndo; [AutoNotify] private bool _isCoinControlVisible; - public TransactionPreviewViewModel(UiContext uiContext, IWalletModel walletModel, SendParameters parameters) + public TransactionPreviewViewModel(UiContext uiContext, IWalletModel walletModel, SendFlowModel sendFlow) { _undoHistory = new(); - _wallet = parameters.Wallet; + _wallet = sendFlow.Wallet; _walletModel = walletModel; - _parameters = parameters; + _sendFlow = sendFlow; - _info = _parameters.TransactionInfo ?? throw new InvalidOperationException($"Missing required TransactionInfo."); + _info = _sendFlow.TransactionInfo ?? throw new InvalidOperationException($"Missing required TransactionInfo."); _currentTransactionInfo = _info.Clone(); _cancellationTokenSource = new CancellationTokenSource(); - PrivacySuggestions = new PrivacySuggestionsFlyoutViewModel(walletModel, _parameters); + PrivacySuggestions = new PrivacySuggestionsFlyoutViewModel(walletModel, _sendFlow); CurrentTransactionSummary = new TransactionSummaryViewModel(uiContext, this, walletModel, _info); PreviewTransactionSummary = new TransactionSummaryViewModel(uiContext, this, walletModel, _info, true); @@ -185,7 +185,7 @@ private async Task OnChangeCoinsAsync() { var currentCoins = _walletModel.Coins.GetSpentCoins(Transaction); - var selectedCoins = await Navigate().To().SelectCoinsDialog(_walletModel, currentCoins, _info).GetResultAsync(); + var selectedCoins = await Navigate().To().SelectCoinsDialog(_walletModel, currentCoins, _sendFlow).GetResultAsync(); if (selectedCoins is { }) { @@ -261,7 +261,7 @@ await ShowErrorAsync( } catch (InsufficientBalanceException) { - var canSelectMoreCoins = _parameters.AvailableCoins.Any(coin => !_info.Coins.Contains(coin)); + var canSelectMoreCoins = _sendFlow.AvailableCoins.Any(coin => !_info.Coins.Contains(coin)); if (canSelectMoreCoins) { @@ -478,7 +478,7 @@ private async Task CheckChangePocketAvailableAsync(BuildTransactionResult transa var cjManager = Services.HostedServices.Get(); var usedCoins = transaction.SpentCoins; - var pockets = _parameters.GetPockets().Select(x => new Pocket(x)).ToArray(); + var pockets = _sendFlow.GetPockets().Select(x => new Pocket(x)).ToArray(); var labelSelection = new LabelSelectionViewModel(_wallet.KeyManager, _wallet.Kitchen.SaltSoup(), _info, isSilent: true); await labelSelection.ResetAsync(pockets, coinsToExclude: cjManager.CoinsInCriticalPhase[_wallet.WalletId].ToList()); diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/WalletViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/WalletViewModel.cs index 12261caea4d..02dec9b8a22 100644 --- a/WalletWasabi.Fluent/ViewModels/Wallets/WalletViewModel.cs +++ b/WalletWasabi.Fluent/ViewModels/Wallets/WalletViewModel.cs @@ -80,7 +80,7 @@ public WalletViewModel(UiContext uiContext, IWalletModel walletModel, Wallet wal return (isSelected && !isWalletBalanceZero && (!areAllCoinsPrivate || pointerOver)) && !WalletModel.IsWatchOnlyWallet; }); - SendCommand = ReactiveCommand.Create(() => Navigate().To().Send(walletModel, SendParameters.Create(wallet))); + SendCommand = ReactiveCommand.Create(() => Navigate().To().Send(walletModel, new SendFlowModel(wallet, walletModel))); SendManualControlCommand = ReactiveCommand.Create(() => Navigate().To().ManualControlDialog(walletModel, wallet)); ReceiveCommand = ReactiveCommand.Create(() => Navigate().To().Receive(WalletModel)); diff --git a/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveAddressViewModelTests.cs b/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveAddressViewModelTests.cs index f2f1365da46..2caacf8bebb 100644 --- a/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveAddressViewModelTests.cs +++ b/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveAddressViewModelTests.cs @@ -94,7 +94,7 @@ public IWalletStatsModel GetWalletStats() throw new NotImplementedException(); } - public IPrivacySuggestionsModel GetPrivacySuggestionsModel(SendParameters sendParameters) + public IPrivacySuggestionsModel GetPrivacySuggestionsModel(SendFlowModel sendParameters) { throw new NotImplementedException(); } diff --git a/WalletWasabi.Tests/UnitTests/ViewModels/SuggestionLabelsViewModelTests.cs b/WalletWasabi.Tests/UnitTests/ViewModels/SuggestionLabelsViewModelTests.cs index 277cf1690ba..3ecebefe160 100644 --- a/WalletWasabi.Tests/UnitTests/ViewModels/SuggestionLabelsViewModelTests.cs +++ b/WalletWasabi.Tests/UnitTests/ViewModels/SuggestionLabelsViewModelTests.cs @@ -229,7 +229,7 @@ public IWalletStatsModel GetWalletStats() throw new NotImplementedException(); } - public IPrivacySuggestionsModel GetPrivacySuggestionsModel(SendParameters sendParameters) + public IPrivacySuggestionsModel GetPrivacySuggestionsModel(SendFlowModel sendParameters) { throw new NotImplementedException(); }