make HardwareWalletOperations static
MODIFY
WalletWasabi.Fluent/ViewModels/AddWallet/HardwareWallet/ConnectHardwareWalletViewModel.cs
WalletWasabi.Fluent/ViewModels/AddWallet/HardwareWallet/ConnectHardwareWalletViewModel.cs
@@ -33,9 +33,9 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
WalletManager = walletManager;
Wallets = wallets;
AbandonedTasks = new AbandonedTasks();
- HardwareWalletOperations = new HardwareWalletOperations(WalletManager.Network);
+ CancelCts = new CancellationTokenSource();
- NextCommand = ReactiveCommand.Create(() => StartDetection(HardwareWalletOperations));
+ NextCommand = ReactiveCommand.Create(StartDetection);
OpenBrowserCommand = ReactiveCommand.CreateFromTask(async () =>
await IoHelpers.OpenBrowserAsync("https://docs.wasabiwallet.io/using-wasabi/ColdWasabi.html#using-hardware-wallet-step-by-step"));
@@ -57,6 +57,8 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
.Subscribe(message => NextButtonEnable = !string.IsNullOrEmpty(message));
}
+ public CancellationTokenSource CancelCts { get; }
+
private AbandonedTasks AbandonedTasks { get; }
public string WalletName { get; }
@@ -67,13 +69,11 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
public WalletViewModelBase? ExistingWallet { get; set; }
- public HardwareWalletOperations? HardwareWalletOperations { get; set; }
-
public ICommand OpenBrowserCommand { get; }
public ICommand NavigateToExistingWalletLoginCommand { get; }
- private void StartDetection(HardwareWalletOperations hwo)
+ private void StartDetection()
{
Message = "";
@@ -83,10 +83,10 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
}
ExistingWalletFound = false;
- AbandonedTasks.AddAndClearCompleted(DetectionAsync(hwo));
+ AbandonedTasks.AddAndClearCompleted(DetectionAsync());
}
- private async Task DetectionAsync(HardwareWalletOperations hwo)
+ private async Task DetectionAsync()
{
IsSearching = true;
@@ -94,9 +94,9 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
{
CancellationTokenSource cts = new();
AbandonedTasks.AddAndClearCompleted(CheckForPassphraseAsync(cts.Token));
- var result = await hwo.DetectAsync();
+ var result = await HardwareWalletOperations.DetectAsync(WalletManager.Network, CancelCts.Token);
cts.Cancel();
- EvaluateDetectionResult(result, hwo);
+ EvaluateDetectionResult(result);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
@@ -121,7 +121,7 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
}
}
- private void EvaluateDetectionResult(HwiEnumerateEntry[] devices, HardwareWalletOperations hwo)
+ private void EvaluateDetectionResult(HwiEnumerateEntry[] devices)
{
if (devices.Length == 0)
{
@@ -154,7 +154,7 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
else
{
Message = "Check your device and finish the initialization.";
- AbandonedTasks.AddAndClearCompleted(hwo.InitHardwareWalletAsync(device));
+ AbandonedTasks.AddAndClearCompleted(HardwareWalletOperations.InitHardwareWalletAsync(device, WalletManager.Network, CancelCts.Token));
}
return;
@@ -185,14 +185,12 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
{
base.OnNavigatedTo(inStack, disposable);
- HardwareWalletOperations ??= new HardwareWalletOperations(WalletManager.Network);
-
- StartDetection(HardwareWalletOperations);
+ StartDetection();
Disposable.Create(async () =>
{
- HardwareWalletOperations.Dispose();
- HardwareWalletOperations = null;
+ CancelCts.Cancel();
+ CancelCts.Dispose();
await AbandonedTasks.WhenAllAsync();
})
.DisposeWith(disposable);

MODIFY
WalletWasabi.Fluent/ViewModels/AddWallet/HardwareWallet/DetectedHardwareWalletViewModel.cs
WalletWasabi.Fluent/ViewModels/AddWallet/HardwareWallet/DetectedHardwareWalletViewModel.cs
using System;
using System.Reactive.Disposables;
+using System.Threading;
using System.Windows.Input;
using ReactiveUI;
using WalletWasabi.Extensions;
@@ -17,7 +18,7 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
Title = "Hardware Wallet";
WalletManager = walletManager;
WalletName = walletName;
- HardwareWalletOperations = new HardwareWalletOperations(walletManager.Network);
+ CancelCts = new CancellationTokenSource();
Type = device.Model switch
{
@@ -34,7 +35,7 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
try
{
var walletFilePath = WalletManager.WalletDirectories.GetWalletFilePaths(WalletName).walletFilePath;
- var km = await HardwareWalletOperations.GenerateWalletAsync(device, walletFilePath);
+ var km = await HardwareWalletOperations.GenerateWalletAsync(device, walletFilePath, WalletManager.Network, CancelCts.Token);
km.SetIcon(Type);
Navigate().To(new AddedWalletPageViewModel(walletManager, km));
@@ -52,7 +53,10 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
EnableAutoBusyOn(NextCommand);
}
+ public CancellationTokenSource CancelCts { get; }
+
public WalletManager WalletManager { get; }
+
public string WalletName { get; }
public WalletType Type { get; }
@@ -61,13 +65,15 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
public ICommand NoCommand { get; }
- private HardwareWalletOperations HardwareWalletOperations { get; }
-
protected override void OnNavigatedTo(bool inStack, CompositeDisposable disposable)
{
base.OnNavigatedTo(inStack, disposable);
- Disposable.Create(() => HardwareWalletOperations.Dispose()).DisposeWith(disposable);
+ Disposable.Create(() =>
+ {
+ CancelCts.Cancel();
+ CancelCts.Dispose();
+ });
}
}
}

MODIFY
WalletWasabi.Fluent/ViewModels/AddWallet/HardwareWallet/HardwareWalletOperations.cs
WalletWasabi.Fluent/ViewModels/AddWallet/HardwareWallet/HardwareWalletOperations.cs
@@ -10,30 +10,22 @@ using WalletWasabi.Logging;
namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
{
- public class HardwareWalletOperations : IDisposable
+ public static class HardwareWalletOperations
{
- public HardwareWalletOperations(Network network)
- {
- Client = new HwiClient(network);
- DisposeCts = new CancellationTokenSource();
- }
-
- public HwiClient Client { get; }
-
- private CancellationTokenSource DisposeCts { get; }
-
- public async Task<KeyManager> GenerateWalletAsync(HwiEnumerateEntry device, string walletFilePath)
+ public static async Task<KeyManager> GenerateWalletAsync(HwiEnumerateEntry device, string walletFilePath, Network network, CancellationToken cancelToken)
{
if (device.Fingerprint is null)
{
throw new Exception("Fingerprint cannot be null.");
}
+ var client = new HwiClient(network);
var fingerPrint = (HDFingerprint)device.Fingerprint;
+
using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
- using var genCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, DisposeCts.Token);
+ using var genCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancelToken);
- var extPubKey = await Client.GetXpubAsync(
+ var extPubKey = await client.GetXpubAsync(
device.Model,
device.Path,
KeyManager.DefaultAccountKeyPath,
@@ -42,17 +34,18 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
return KeyManager.CreateNewHardwareWalletWatchOnly(fingerPrint, extPubKey, walletFilePath);
}
- public async Task InitHardwareWalletAsync(HwiEnumerateEntry device)
+ public static async Task InitHardwareWalletAsync(HwiEnumerateEntry device, Network network, CancellationToken cancelToken)
{
+ var client = new HwiClient(network);
using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(21));
- using var initCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, DisposeCts.Token);
+ using var initCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancelToken);
// Trezor T doesn't require interactive mode.
var interactiveMode = !(device.Model == HardwareWalletModels.Trezor_T || device.Model == HardwareWalletModels.Trezor_T_Simulator);
try
{
- await Client.SetupAsync(device.Model, device.Path, interactiveMode, initCts.Token);
+ await client.SetupAsync(device.Model, device.Path, interactiveMode, initCts.Token).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -60,22 +53,17 @@ namespace WalletWasabi.Fluent.ViewModels.AddWallet.HardwareWallet
}
}
- public async Task<HwiEnumerateEntry[]> DetectAsync()
+ public static async Task<HwiEnumerateEntry[]> DetectAsync(Network network, CancellationToken cancelToken)
{
+ var client = new HwiClient(network);
using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
- using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, DisposeCts.Token);
+ using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancelToken);
- var detectedHardwareWallets = (await Client.EnumerateAsync(timeoutCts.Token).ConfigureAwait(false)).ToArray();
+ var detectedHardwareWallets = (await client.EnumerateAsync(timeoutCts.Token).ConfigureAwait(false)).ToArray();
- DisposeCts.Token.ThrowIfCancellationRequested();
+ cancelToken.ThrowIfCancellationRequested();
return detectedHardwareWallets;
}
-
- public void Dispose()
- {
- DisposeCts.Cancel();
- DisposeCts.Dispose();
- }
}
}

make HardwareWalletOperations static