diff --git a/WalletWasabi.Fluent/Models/Wallets/Address.cs b/WalletWasabi.Fluent/Models/Wallets/Address.cs
index 46e08e1f12e..dae0a11e147 100644
--- a/WalletWasabi.Fluent/Models/Wallets/Address.cs
+++ b/WalletWasabi.Fluent/Models/Wallets/Address.cs
@@ -1,4 +1,3 @@
-using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NBitcoin;
@@ -12,13 +11,16 @@ namespace WalletWasabi.Fluent.Models.Wallets;
public class Address : ReactiveObject, IAddress
{
- public Address(KeyManager keyManager, HdPubKey hdPubKey)
+ private readonly Action
_onHide;
+
+ public Address(KeyManager keyManager, HdPubKey hdPubKey, Action onHide)
{
KeyManager = keyManager;
HdPubKey = hdPubKey;
Network = keyManager.GetNetwork();
HdFingerprint = KeyManager.MasterFingerprint;
BitcoinAddress = HdPubKey.GetAddress(Network);
+ _onHide = onHide;
}
public KeyManager KeyManager { get; }
@@ -31,15 +33,9 @@ public Address(KeyManager keyManager, HdPubKey hdPubKey)
public KeyPath FullKeyPath => HdPubKey.FullKeyPath;
public string Text => BitcoinAddress.ToString();
- private bool IsUnused => Labels.Any() && !HdPubKey.IsInternal && HdPubKey.KeyState == KeyState.Clean;
-
- public bool IsUsed => !IsUnused;
-
public void Hide()
{
- KeyManager.SetKeyState(KeyState.Locked, HdPubKey);
- KeyManager.ToFile();
- this.RaisePropertyChanged(nameof(IsUsed));
+ _onHide(this);
}
public void SetLabels(LabelsArray labels)
@@ -77,4 +73,13 @@ public async Task ShowOnHwWalletAsync()
throw;
}
}
+
+ public override int GetHashCode() => Text.GetHashCode();
+
+ public override bool Equals(object? obj)
+ {
+ return obj is IAddress address && Equals(address);
+ }
+
+ protected bool Equals(IAddress other) => Text.Equals(other.Text);
}
diff --git a/WalletWasabi.Fluent/Models/Wallets/AddressesModel.cs b/WalletWasabi.Fluent/Models/Wallets/AddressesModel.cs
index 8eaf74521cd..ca77b06e555 100644
--- a/WalletWasabi.Fluent/Models/Wallets/AddressesModel.cs
+++ b/WalletWasabi.Fluent/Models/Wallets/AddressesModel.cs
@@ -1,47 +1,75 @@
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
-using System.Reactive;
-using System.Reactive.Disposables;
+using System.Reactive.Linq;
+using System.Reactive.Subjects;
using DynamicData;
using WalletWasabi.Blockchain.Keys;
-using WalletWasabi.Fluent.Extensions;
+using WalletWasabi.Blockchain.TransactionProcessing;
+using WalletWasabi.Wallets;
namespace WalletWasabi.Fluent.Models.Wallets;
[AutoInterface]
-public partial class AddressesModel : IDisposable
+public partial class AddressesModel
{
- private readonly CompositeDisposable _disposable = new();
- private readonly KeyManager _keyManager;
+ private readonly ISubject _newAddressGenerated = new Subject();
+ private readonly Wallet _wallet;
+ private readonly SourceList _source;
- public AddressesModel(IObservable addressesUpdated, KeyManager keyManager)
+ public AddressesModel(Wallet wallet)
{
- _keyManager = keyManager;
+ _wallet = wallet;
+ _source = new SourceList();
+ _source.AddRange(GetUnusedKeys());
- Cache =
- addressesUpdated.Fetch(GetAddresses, address => address.Text)
- .DisposeWith(_disposable);
+ Observable.FromEventPattern(
+ h => wallet.WalletRelevantTransactionProcessed += h,
+ h => wallet.WalletRelevantTransactionProcessed -= h)
+ .Do(_ => UpdateUnusedKeys())
+ .Subscribe();
- UnusedAddressesCache =
- Cache.Connect()
- .AutoRefresh(x => x.IsUsed)
- .Filter(x => !x.IsUsed)
- .AsObservableCache()
- .DisposeWith(_disposable);
+ _newAddressGenerated
+ .Do(address => _source.Add(address))
+ .Subscribe();
- HasUnusedAddresses = UnusedAddressesCache.NotEmpty();
+ _source.Connect()
+ .Transform(key => (IAddress) new Address(_wallet.KeyManager, key, Hide))
+ .Bind(out var unusedAddresses)
+ .Subscribe();
+
+ Unused = unusedAddresses;
}
- public IObservableCache Cache { get; }
+ private IEnumerable GetUnusedKeys() => _wallet.KeyManager.GetKeys(x => x is { IsInternal: false, KeyState: KeyState.Clean, Labels.Count: > 0 });
- public IObservableCache UnusedAddressesCache { get; }
+ public IAddress NextReceiveAddress(IEnumerable destinationLabels)
+ {
+ var pubKey = _wallet.GetNextReceiveAddress(destinationLabels);
+ var nextReceiveAddress = new Address(_wallet.KeyManager, pubKey, Hide);
+ _newAddressGenerated.OnNext(pubKey);
- public IObservable HasUnusedAddresses { get; }
+ return nextReceiveAddress;
+ }
- public void Dispose() => _disposable.Dispose();
+ public ReadOnlyObservableCollection Unused { get; }
- private IEnumerable GetAddresses() => _keyManager
- .GetKeys()
- .Reverse()
- .Select(x => new Address(_keyManager, x));
+ public void Hide(Address address)
+ {
+ _wallet.KeyManager.SetKeyState(KeyState.Locked, address.HdPubKey);
+ _wallet.KeyManager.ToFile();
+ _source.Remove(address.HdPubKey);
+ }
+
+ private void UpdateUnusedKeys()
+ {
+ var itemsToRemove = _source.Items
+ .Where(item => item.KeyState != KeyState.Clean)
+ .ToList();
+
+ foreach (var item in itemsToRemove)
+ {
+ _source.Remove(item);
+ }
+ }
}
diff --git a/WalletWasabi.Fluent/Models/Wallets/IAddress.cs b/WalletWasabi.Fluent/Models/Wallets/IAddress.cs
index ccbd658d7b3..e57594f6e0c 100644
--- a/WalletWasabi.Fluent/Models/Wallets/IAddress.cs
+++ b/WalletWasabi.Fluent/Models/Wallets/IAddress.cs
@@ -14,8 +14,6 @@ public interface IAddress : IReactiveObject
LabelsArray Labels { get; }
- bool IsUsed { get; }
-
void Hide();
void SetLabels(LabelsArray labels);
diff --git a/WalletWasabi.Fluent/Models/Wallets/WalletModel.cs b/WalletWasabi.Fluent/Models/Wallets/WalletModel.cs
index 1aae528bd95..0555cda0cd9 100644
--- a/WalletWasabi.Fluent/Models/Wallets/WalletModel.cs
+++ b/WalletWasabi.Fluent/Models/Wallets/WalletModel.cs
@@ -1,20 +1,16 @@
using System.Collections.Generic;
using System.ComponentModel;
-using System.IO;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using NBitcoin;
using ReactiveUI;
-using WalletWasabi.Fluent.Extensions;
using WalletWasabi.Fluent.Helpers;
using WalletWasabi.Fluent.ViewModels.Wallets.Labels;
using WalletWasabi.Wallets;
namespace WalletWasabi.Fluent.Models.Wallets;
-public partial interface IWalletModel : INotifyPropertyChanged
-{
-}
+public partial interface IWalletModel : INotifyPropertyChanged;
[AutoInterface]
public partial class WalletModel : ReactiveObject
@@ -39,7 +35,7 @@ public WalletModel(Wallet wallet, IAmountProvider amountProvider)
Transactions = new WalletTransactionsModel(this, wallet);
- AddressesModel = new AddressesModel(Transactions.TransactionProcessed.ToSignal().Merge(_newAddressGenerated.ToSignal()), Wallet.KeyManager);
+ Addresses = new AddressesModel(Wallet);
State =
Observable.FromEventPattern(Wallet, nameof(Wallet.StateChanged))
@@ -69,7 +65,7 @@ public WalletModel(Wallet wallet, IAmountProvider amountProvider)
this.WhenAnyValue(x => x.Auth.IsLoggedIn).BindTo(this, x => x.IsLoggedIn);
}
- public IAddressesModel AddressesModel { get; }
+ public IAddressesModel Addresses { get; }
internal Wallet Wallet { get; }
@@ -120,15 +116,6 @@ public IWalletInfoModel GetWalletInfo()
return new WalletInfoModel(Wallet);
}
- public IAddress GetNextReceiveAddress(IEnumerable destinationLabels)
- {
- var pubKey = Wallet.GetNextReceiveAddress(destinationLabels);
- var nextReceiveAddress = new Address(Wallet.KeyManager, pubKey);
- _newAddressGenerated.OnNext(nextReceiveAddress);
-
- return nextReceiveAddress;
- }
-
public void Rename(string newWalletName)
{
Services.WalletManager.RenameWallet(Wallet, newWalletName);
diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/Receive/AddressViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/Receive/AddressViewModel.cs
index 9a75b16d569..f2e647119cf 100644
--- a/WalletWasabi.Fluent/ViewModels/Wallets/Receive/AddressViewModel.cs
+++ b/WalletWasabi.Fluent/ViewModels/Wallets/Receive/AddressViewModel.cs
@@ -1,4 +1,3 @@
-using System.Collections.Generic;
using System.Reactive;
using System.Threading.Tasks;
using System.Windows.Input;
diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressViewModel.cs
index aff19531e8c..fcf0388a127 100644
--- a/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressViewModel.cs
+++ b/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressViewModel.cs
@@ -3,6 +3,7 @@
using System.Threading.Tasks;
using System.Windows.Input;
using DynamicData;
+using DynamicData.Binding;
using ReactiveUI;
using WalletWasabi.Blockchain.Analysis.Clustering;
using WalletWasabi.Fluent.Extensions;
@@ -63,12 +64,17 @@ public ReceiveAddressViewModel(UiContext uiContext, IWalletModel wallet, IAddres
protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disposables)
{
- _wallet.AddressesModel.Cache
- .Connect()
- .AutoRefresh(x => x.IsUsed)
- .Watch(Model.Text)
- .Where(change => change.Current.IsUsed)
- .Do(_ => Navigate().Back())
+ _wallet.Addresses.Unused
+ .ToObservableChangeSet()
+ .ObserveOn(RxApp.MainThreadScheduler)
+ .OnItemRemoved(
+ address =>
+ {
+ if (Equals(address, Model))
+ {
+ Navigate().BackTo();
+ }
+ })
.Subscribe()
.DisposeWith(disposables);
diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressesViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressesViewModel.cs
index 7f222def701..839c792944e 100644
--- a/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressesViewModel.cs
+++ b/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveAddressesViewModel.cs
@@ -3,8 +3,8 @@
using System.Threading.Tasks;
using Avalonia.Controls;
using DynamicData;
+using DynamicData.Binding;
using WalletWasabi.Fluent.Models.Wallets;
-using WalletWasabi.Fluent.ViewModels.Dialogs.Base;
using WalletWasabi.Fluent.ViewModels.Navigation;
namespace WalletWasabi.Fluent.ViewModels.Wallets.Receive;
@@ -26,15 +26,14 @@ private ReceiveAddressesViewModel(IWalletModel wallet)
protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disposables)
{
- _wallet
- .AddressesModel.UnusedAddressesCache
- .Connect()
+ _wallet.Addresses.Unused
+ .ToObservableChangeSet()
.Transform(CreateAddressViewModel)
- .Bind(out var addresses)
+ .Bind(out var unusedAddresses)
.Subscribe()
.DisposeWith(disposables);
- var source = ReceiveAddressesDataGridSource.Create(addresses);
+ var source = ReceiveAddressesDataGridSource.Create(unusedAddresses);
Source = source;
Source.RowSelection!.SingleSelect = true;
@@ -45,7 +44,7 @@ protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disp
private AddressViewModel CreateAddressViewModel(IAddress address)
{
- return new AddressViewModel(UiContext, OnEditAddressAsync, address1 => OnShowAddressAsync(address1), address);
+ return new AddressViewModel(UiContext, OnEditAddressAsync, OnShowAddressAsync, address);
}
private void OnShowAddressAsync(IAddress a)
diff --git a/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveViewModel.cs b/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveViewModel.cs
index 9ddb1720cef..5bdf4fafbfe 100644
--- a/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveViewModel.cs
+++ b/WalletWasabi.Fluent/ViewModels/Wallets/Receive/ReceiveViewModel.cs
@@ -1,5 +1,7 @@
using System.Reactive.Linq;
using System.Windows.Input;
+using DynamicData.Binding;
+using DynamicData.Aggregation;
using ReactiveUI;
using WalletWasabi.Fluent.Extensions;
using WalletWasabi.Fluent.Models.Wallets;
@@ -41,9 +43,7 @@ private ReceiveViewModel(IWalletModel wallet)
ShowExistingAddressesCommand = ReactiveCommand.Create(OnShowExistingAddresses);
- AddressesModel = wallet.AddressesModel;
-
- HasUnusedAddresses = _wallet.AddressesModel.HasUnusedAddresses.StartWith(false);
+ AddressesModel = wallet.Addresses;
}
public IAddressesModel AddressesModel { get; }
@@ -52,12 +52,12 @@ private ReceiveViewModel(IWalletModel wallet)
public ICommand ShowExistingAddressesCommand { get; }
- public IObservable HasUnusedAddresses { get; }
+ public IObservable HasUnusedAddresses => _wallet.Addresses.Unused.ToObservableChangeSet().Count().Select(i => i > 0);
private void OnNext()
{
SuggestionLabels.ForceAdd = true;
- var address = _wallet.GetNextReceiveAddress(SuggestionLabels.Labels);
+ var address = _wallet.Addresses.NextReceiveAddress(SuggestionLabels.Labels);
SuggestionLabels.Labels.Clear();
Navigate().To().ReceiveAddress(_wallet, address, Services.UiConfig.Autocopy);
diff --git a/WalletWasabi.Fluent/Views/Wallets/Receive/ReceiveView.axaml b/WalletWasabi.Fluent/Views/Wallets/Receive/ReceiveView.axaml
index 867e9f3884d..bb7ee67bc4c 100644
--- a/WalletWasabi.Fluent/Views/Wallets/Receive/ReceiveView.axaml
+++ b/WalletWasabi.Fluent/Views/Wallets/Receive/ReceiveView.axaml
@@ -16,7 +16,7 @@
EnableBack="{Binding EnableBack}">
diff --git a/WalletWasabi.Tests/UnitTests/ViewModels/AddressViewModelTests.cs b/WalletWasabi.Tests/UnitTests/ViewModels/AddressViewModelTests.cs
index 6fb0f903f5a..75271f66ace 100644
--- a/WalletWasabi.Tests/UnitTests/ViewModels/AddressViewModelTests.cs
+++ b/WalletWasabi.Tests/UnitTests/ViewModels/AddressViewModelTests.cs
@@ -1,7 +1,4 @@
-using System.Threading.Tasks;
-using Moq;
using WalletWasabi.Blockchain.Analysis.Clustering;
-using WalletWasabi.Fluent.Models.Wallets;
using WalletWasabi.Fluent.ViewModels.Wallets.Receive;
using WalletWasabi.Tests.UnitTests.ViewModels.TestDoubles;
using Xunit;
@@ -10,29 +7,13 @@ namespace WalletWasabi.Tests.UnitTests.ViewModels;
public class AddressViewModelTests
{
- [Fact]
- public void HideCommandShouldInvokeCorrectMethod()
- {
- var address = Mock.Of(MockBehavior.Loose);
- var context = new UiContextBuilder().WithDialogThatReturns(true).Build();
- var sut = new AddressViewModel(
- context,
- _ => Task.CompletedTask,
- _ => { },
- address);
-
- sut.HideAddressCommand.Execute(null);
-
- Mock.Get(address).Verify(x => x.Hide(), Times.Once);
- }
-
[Fact]
public void AddressPropertiesAreExposedCorrectly()
{
var testAddress = new TestAddress("ad");
var labels = new LabelsArray("Label 1", "Label 2");
testAddress.SetLabels(labels);
- var sut = new AddressViewModel(MockUtils.ContextStub(), _ => Task.CompletedTask, _ => { }, testAddress);
+ var sut = new AddressViewModel(MockUtils.ContextStub(), async _ => { }, address => { }, testAddress);
Assert.Equal(testAddress.Text, sut.AddressText);
Assert.Equal(labels, sut.Labels);
diff --git a/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveAddressViewModelTests.cs b/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveAddressViewModelTests.cs
index 9f30a82e04e..f30381b1dc7 100644
--- a/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveAddressViewModelTests.cs
+++ b/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveAddressViewModelTests.cs
@@ -1,12 +1,9 @@
using System.Collections.Generic;
using System.ComponentModel;
-using System.Reactive.Linq;
-using DynamicData;
using Moq;
using NBitcoin;
using WalletWasabi.Fluent.Models.UI;
using WalletWasabi.Fluent.Models.Wallets;
-using WalletWasabi.Fluent.ViewModels.Navigation;
using WalletWasabi.Fluent.ViewModels.Wallets.Labels;
using WalletWasabi.Fluent.ViewModels.Wallets.Receive;
using WalletWasabi.Tests.UnitTests.ViewModels.TestDoubles;
@@ -40,31 +37,11 @@ public void AutoCopyEnabledShouldCopyToClipboard()
mock.Verify(x => x.SetTextAsync("SomeAddress"));
}
- [Fact]
- public void WhenAddressBecomesUsedNavigationGoesBack()
- {
- var ns = Mock.Of>(MockBehavior.Loose);
- var uiContext = MockUtils.ContextWith(ns);
- var address = new TestAddress("SomeAddress");
- var wallet = WalletWithAddresses(address);
- var vm = new ReceiveAddressViewModel(uiContext, wallet, address, true);
- vm.OnNavigatedTo(false);
-
- address.IsUsed = true;
-
- Mock.Get(ns).Verify(x => x.Back(), Times.Once);
- }
-
- private static IWalletModel WalletWithAddresses(IAddress address)
- {
- return new AddressTestingMocks.TestWallet(new[] { address }.AsObservableChangeSet(x => x.Text).AsObservableCache() );
- }
-
private class TestWallet : IWalletModel
{
public event PropertyChangedEventHandler? PropertyChanged;
- public IAddressesModel AddressesModel => throw new NotSupportedException();
+ public IAddressesModel Addresses => throw new NotSupportedException();
public WalletId Id => throw new NotSupportedException();
public string Name
diff --git a/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveViewModelTests.cs b/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveViewModelTests.cs
deleted file mode 100644
index f55f85bbe5f..00000000000
--- a/WalletWasabi.Tests/UnitTests/ViewModels/ReceiveViewModelTests.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System.Linq;
-using WalletWasabi.Fluent.ViewModels.Wallets.Receive;
-using WalletWasabi.Tests.UnitTests.ViewModels.TestDoubles;
-using Xunit;
-
-namespace WalletWasabi.Tests.UnitTests.ViewModels;
-
-public class ReceiveViewModelTests
-{
- [Fact]
- public void EmptyAddressList()
- {
- Assert.False(HasUnusedAddresses(_ => { }));
- }
-
- [Fact]
- public void UsedAddress()
- {
- Assert.False(HasUnusedAddresses(configuration => configuration.SetUsed("addr")));
- }
-
- [Fact]
- public void UnusedAddress()
- {
- Assert.True(HasUnusedAddresses(configuration => configuration.SetUnused("addr")));
- }
-
- [Fact]
- public void UnusedBecomesUsed()
- {
- Assert.False(
- HasUnusedAddresses(
- configuration =>
- {
- configuration.SetUnused("addr");
- configuration.SetUsed("addr");
- }));
- }
-
- private static bool HasUnusedAddresses(Action configureAddresses)
- {
- var addresses = new AddressTestingMocks.AddressConfiguration();
- var receiveViewModel = new ReceiveViewModel(MockUtils.ContextStub(), new AddressTestingMocks.TestWallet(addresses.Addresses));
- var history = receiveViewModel.HasUnusedAddresses.SubscribeList();
- configureAddresses(addresses);
- return history.Last();
- }
-}
diff --git a/WalletWasabi.Tests/UnitTests/ViewModels/SuggestionLabelsViewModelTests.cs b/WalletWasabi.Tests/UnitTests/ViewModels/SuggestionLabelsViewModelTests.cs
index 669bb526e66..bf65f916210 100644
--- a/WalletWasabi.Tests/UnitTests/ViewModels/SuggestionLabelsViewModelTests.cs
+++ b/WalletWasabi.Tests/UnitTests/ViewModels/SuggestionLabelsViewModelTests.cs
@@ -167,7 +167,7 @@ public TestWallet(List<(string Label, int Score)> mostUsedLabels)
public event PropertyChangedEventHandler? PropertyChanged;
- public IAddressesModel AddressesModel => throw new NotSupportedException();
+ public IAddressesModel Addresses => throw new NotSupportedException();
public WalletId Id => throw new NotSupportedException();
public string Name
diff --git a/WalletWasabi.Tests/UnitTests/ViewModels/TestDoubles/AddressTestingMocks.cs b/WalletWasabi.Tests/UnitTests/ViewModels/TestDoubles/AddressTestingMocks.cs
deleted file mode 100644
index ba0b08fa625..00000000000
--- a/WalletWasabi.Tests/UnitTests/ViewModels/TestDoubles/AddressTestingMocks.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.ComponentModel;
-using System.Reactive.Linq;
-using DynamicData;
-using NBitcoin;
-using ReactiveUI;
-using WalletWasabi.Fluent.Extensions;
-using WalletWasabi.Fluent.Models.Wallets;
-using WalletWasabi.Fluent.ViewModels.Wallets.Labels;
-using WalletWasabi.Wallets;
-
-namespace WalletWasabi.Tests.UnitTests.ViewModels.TestDoubles;
-
-internal class AddressTestingMocks
-{
- public class TestWallet : IWalletModel
- {
- private readonly IObservableCache _addresses;
-
- public TestWallet(IObservableCache addresses)
- {
- _addresses = addresses;
- }
-
- public event PropertyChangedEventHandler? PropertyChanged;
-
- public IAddressesModel AddressesModel => new TestAddressesModel(_addresses);
- public WalletId Id { get; }
- public string Name { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
- public IObservable State => throw new NotSupportedException();
- public bool IsHardwareWallet => false;
- public bool IsWatchOnlyWallet => throw new NotSupportedException();
- public bool IsLoggedIn { get; set; }
- public IWalletAuthModel Auth => throw new NotSupportedException();
- public IObservable HasBalance => throw new NotSupportedException();
- public IWalletLoadWorkflow Loader => throw new NotSupportedException();
- public IWalletSettingsModel Settings => throw new NotSupportedException();
- public IWalletPrivacyModel Privacy => throw new NotSupportedException();
- public IWalletCoinjoinModel Coinjoin => throw new NotSupportedException();
- public IObservable Balances => throw new NotSupportedException();
- IWalletCoinsModel IWalletModel.Coins => throw new NotSupportedException();
- public Network Network => throw new NotSupportedException();
- IWalletTransactionsModel IWalletModel.Transactions => throw new NotSupportedException();
- public IAmountProvider AmountProvider => throw new NotSupportedException();
-
- public IAddress GetNextReceiveAddress(IEnumerable destinationLabels)
- {
- throw new NotSupportedException();
- }
-
- public void Rename(string newWalletName) => throw new NotSupportedException();
-
- public IWalletStatsModel GetWalletStats() => throw new NotSupportedException();
-
- public IEnumerable<(string Label, int Score)> GetMostUsedLabels(Intent intent)
- {
- return ImmutableArray<(string Label, int Score)>.Empty;
- }
-
- public IWalletInfoModel GetWalletInfo()
- {
- throw new NotSupportedException();
- }
- }
-
- public class AddressConfiguration
- {
- private readonly SourceCache _cache;
-
- public AddressConfiguration()
- {
- _cache = new SourceCache(address => address.Text);
- }
-
- public ISourceCache Addresses => _cache;
-
- public void SetUnused(string address)
- {
- _cache.AddOrUpdate(new TestAddress(address) { IsUsed = false });
- }
-
- public void SetUsed(string address)
- {
- _cache.AddOrUpdate(new TestAddress(address) { IsUsed = true });
- }
- }
-
- private class TestAddressesModel : IAddressesModel
- {
- public TestAddressesModel(IObservableCache cache)
- {
- Cache = cache;
- UnusedAddressesCache = Cache.Connect().AutoRefresh(x => x.IsUsed).Filter(address => !address.IsUsed).AsObservableCache();
- HasUnusedAddresses = UnusedAddressesCache.NotEmpty();
- }
-
- public IObservableCache UnusedAddressesCache { get; set; }
- public IObservableCache Cache { get; }
- public IObservable HasUnusedAddresses { get; }
-
- public void Dispose()
- {
- }
- }
-}