Convert HwiClient to use new API.
MODIFY
WalletWasabi.Tests/UnitTests/Hwi/DefaultResponseTests.cs
WalletWasabi.Tests/UnitTests/Hwi/DefaultResponseTests.cs
using NBitcoin;
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@@ -8,6 +9,7 @@ using WalletWasabi.Hwi;
using WalletWasabi.Hwi.Models;
using WalletWasabi.Hwi.Parsers;
using WalletWasabi.Hwi.ProcessBridge;
+using WalletWasabi.Microservices;
using Xunit;
namespace WalletWasabi.Tests.UnitTests.Hwi
@@ -36,7 +38,7 @@ namespace WalletWasabi.Tests.UnitTests.Hwi
[Fact]
public void ConstructorThrowsArgumentNullException()
{
- Assert.Throws<ArgumentNullException>(() => new HwiClient(null));
+ Assert.Throws<ArgumentNullException>(() => new HwiClient(null!));
}
[Theory]
@@ -83,15 +85,15 @@ namespace WalletWasabi.Tests.UnitTests.Hwi
{
var wrongDeviePaths = new[] { "", " " };
using var cts = new CancellationTokenSource(ReasonableRequestTimeout);
- foreach (HardwareWalletModels deviceType in Enum.GetValues(typeof(HardwareWalletModels)))
+ foreach (HardwareWalletModels deviceType in Enum.GetValues(typeof(HardwareWalletModels)).Cast<HardwareWalletModels>())
{
foreach (var wrongDevicePath in wrongDeviePaths)
{
await Assert.ThrowsAsync<ArgumentException>(async () => await client.WipeAsync(deviceType, wrongDevicePath, cts.Token));
await Assert.ThrowsAsync<ArgumentException>(async () => await client.SetupAsync(deviceType, wrongDevicePath, false, cts.Token));
}
- await Assert.ThrowsAsync<ArgumentNullException>(async () => await client.WipeAsync(deviceType, null, cts.Token));
- await Assert.ThrowsAsync<ArgumentNullException>(async () => await client.SetupAsync(deviceType, null, false, cts.Token));
+ await Assert.ThrowsAsync<ArgumentNullException>(async () => await client.WipeAsync(deviceType, null!, cts.Token));
+ await Assert.ThrowsAsync<ArgumentNullException>(async () => await client.SetupAsync(deviceType, null!, false, cts.Token));
}
}
@@ -118,17 +120,17 @@ namespace WalletWasabi.Tests.UnitTests.Hwi
[Fact]
public async Task OpenConsoleDoesntThrowAsync()
{
- HwiProcessBridge pb = new HwiProcessBridge();
+ var pb = new HwiProcessBridge(new ProcessInvoker());
using var cts = new CancellationTokenSource(ReasonableRequestTimeout);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
- var res = await pb.SendCommandAsync("version", true, cts.Token);
+ var res = await pb.SendCommandAsync("version", openConsole: true, cts.Token);
Assert.Contains("success", res.response);
}
else
{
- await Assert.ThrowsAsync<PlatformNotSupportedException>(async () => await pb.SendCommandAsync("enumerate", true, cts.Token));
+ await Assert.ThrowsAsync<PlatformNotSupportedException>(async () => await pb.SendCommandAsync("enumerate", openConsole: true, cts.Token));
}
}

MODIFY
WalletWasabi.Tests/UnitTests/Hwi/HwiProcessBridgeMock.cs
WalletWasabi.Tests/UnitTests/Hwi/HwiProcessBridgeMock.cs
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WalletWasabi.Hwi.Models;
using WalletWasabi.Hwi.Parsers;
-using WalletWasabi.Microservices;
+using WalletWasabi.Hwi.ProcessBridge;
namespace WalletWasabi.Tests.UnitTests.Hwi
{
- public class HwiProcessBridgeMock : IProcessBridge
+ public class HwiProcessBridgeMock : IHwiProcessInvoker
{
public HwiProcessBridgeMock(HardwareWalletModels model)
{
@@ -20,7 +17,7 @@ namespace WalletWasabi.Tests.UnitTests.Hwi
public HardwareWalletModels Model { get; }
- public Task<(string response, int exitCode)> SendCommandAsync(string arguments, bool openConsole, CancellationToken cancel, Action<StreamWriter> standardInputWriter = null)
+ public Task<(string response, int exitCode)> SendCommandAsync(string arguments, bool openConsole, CancellationToken cancel, Action<StreamWriter>? standardInputWriter = null)
{
if (openConsole)
{
@@ -60,7 +57,7 @@ namespace WalletWasabi.Tests.UnitTests.Hwi
const string SuccessTrueResponse = "{\"success\": true}\r\n";
- string response = null;
+ string? response = null;
int code = 0;
if (CompareArguments(arguments, "enumerate"))
@@ -172,7 +169,7 @@ namespace WalletWasabi.Tests.UnitTests.Hwi
response = "{\"error\": \"The Ledger Nano S does not need a PIN sent from the host\", \"code\": -9}\r\n";
}
}
- else if (CompareGetXbpubArguments(arguments, out string xpub))
+ else if (CompareGetXbpubArguments(arguments, out string? xpub))
{
if (Model == HardwareWalletModels.Trezor_T || Model == HardwareWalletModels.Coldcard || Model == HardwareWalletModels.Trezor_1 || Model == HardwareWalletModels.Ledger_Nano_S)
{
@@ -241,7 +238,7 @@ namespace WalletWasabi.Tests.UnitTests.Hwi
private static bool CompareArguments(string arguments, string desired, bool useStartWith = false)
=> CompareArguments(out _, arguments, desired, useStartWith);
- private static bool CompareGetXbpubArguments(string arguments, out string extPubKey)
+ private static bool CompareGetXbpubArguments(string arguments, out string? extPubKey)
{
extPubKey = null;
string command = "getxpub";
@@ -263,10 +260,5 @@ namespace WalletWasabi.Tests.UnitTests.Hwi
return extPubKey != null;
}
-
- public Process Start(string arguments, bool openConsole, bool redirectStandardInput)
- {
- throw new NotImplementedException();
- }
}
}

MODIFY
WalletWasabi.Tests/UnitTests/Hwi/SerialDefaultResponseTests.cs
WalletWasabi.Tests/UnitTests/Hwi/SerialDefaultResponseTests.cs
@@ -2,6 +2,7 @@ using System;
using System.Threading;
using System.Threading.Tasks;
using WalletWasabi.Hwi.ProcessBridge;
+using WalletWasabi.Microservices;
using Xunit;
namespace WalletWasabi.Tests.UnitTests.Hwi
@@ -19,7 +20,7 @@ namespace WalletWasabi.Tests.UnitTests.Hwi
[Fact]
public async Task HwiProcessBridgeTestAsync()
{
- HwiProcessBridge pb = new HwiProcessBridge();
+ var pb = new HwiProcessBridge(new ProcessInvoker());
using var cts = new CancellationTokenSource(ReasonableRequestTimeout);
var res = await pb.SendCommandAsync("version", false, cts.Token);

MODIFY
WalletWasabi/Hwi/HwiClient.cs
WalletWasabi/Hwi/HwiClient.cs
@@ -23,10 +23,10 @@ namespace WalletWasabi.Hwi
{
#region ConstructorsAndInitializers
- public HwiClient(Network network, IProcessBridge bridge = null)
+ public HwiClient(Network network, IHwiProcessInvoker? bridge = null)
{
Network = Guard.NotNull(nameof(network), network);
- Bridge = bridge ?? new HwiProcessBridge();
+ Bridge = bridge ?? new HwiProcessBridge(new ProcessInvoker());
}
#endregion ConstructorsAndInitializers
@@ -34,13 +34,13 @@ namespace WalletWasabi.Hwi
#region PropertiesAndMembers
public Network Network { get; }
- public IProcessBridge Bridge { get; }
+ public IHwiProcessInvoker Bridge { get; }
#endregion PropertiesAndMembers
#region Commands
- private async Task<string> SendCommandAsync(IEnumerable<HwiOption> options, HwiCommands? command, string commandArguments, bool openConsole, CancellationToken cancel, bool isRecursion = false, Action<StreamWriter> standardInputWriter = null)
+ private async Task<string> SendCommandAsync(IEnumerable<HwiOption> options, HwiCommands? command, string commandArguments, bool openConsole, CancellationToken cancel, bool isRecursion = false, Action<StreamWriter>? standardInputWriter = null)
{
if (standardInputWriter is { } && !options.Contains(HwiOption.StdIn))
{

MODIFY
WalletWasabi/Hwi/ProcessBridge/HwiProcessBridge.cs
WalletWasabi/Hwi/ProcessBridge/HwiProcessBridge.cs
using System;
-using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
-using System.Runtime.InteropServices;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using WalletWasabi.Helpers;
-using WalletWasabi.Interfaces;
-using WalletWasabi.Logging;
using WalletWasabi.Microservices;
namespace WalletWasabi.Hwi.ProcessBridge
{
- public class HwiProcessBridge : Microservices.ProcessBridge
+ public class HwiProcessBridge : IHwiProcessInvoker
{
- public HwiProcessBridge() : base(MicroserviceHelpers.GetBinaryPath("hwi"))
+ public HwiProcessBridge(ProcessInvoker processInvoker)
{
+ ProcessPath = MicroserviceHelpers.GetBinaryPath("hwi");
+ ProcessInvoker = processInvoker;
}
- public new async Task<(string response, int exitCode)> SendCommandAsync(string arguments, bool openConsole, CancellationToken cancel, Action<StreamWriter> standardInputWriter = null)
+ private string ProcessPath { get; }
+ private ProcessInvoker ProcessInvoker { get; }
+
+ public async Task<(string response, int exitCode)> SendCommandAsync(string arguments, bool openConsole, CancellationToken cancel, Action<StreamWriter>? standardInputWriter = null)
{
- var (responseString, exitCode) = await base.SendCommandAsync(arguments, openConsole, cancel, standardInputWriter).ConfigureAwait(false);
+ ProcessStartInfo startInfo = ProcessStartInfoFactory.Make(ProcessPath, arguments, openConsole);
+
+ (string rawResponse, int exitCode) = await ProcessInvoker.SendCommandAsync(startInfo, cancel, standardInputWriter).ConfigureAwait(false);
- string modifiedResponseString;
+ string response;
if (!openConsole)
{
- modifiedResponseString = responseString;
+ response = rawResponse;
}
else
{
- modifiedResponseString = exitCode == 0
+ response = exitCode == 0
? "{\"success\":\"true\"}"
: $"{{\"success\":\"false\",\"error\":\"Process terminated with exit code: {exitCode}.\"}}";
}
- return (modifiedResponseString, exitCode);
+ return (response, exitCode);
}
}
}

ADD
WalletWasabi/Hwi/ProcessBridge/IHwiProcessInvoker.cs
+using System;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace WalletWasabi.Hwi.ProcessBridge
+{
+ public interface IHwiProcessInvoker
+ {
+ Task<(string response, int exitCode)> SendCommandAsync(string arguments, bool openConsole, CancellationToken cancel, Action<StreamWriter>? standardInputWriter = null);
+ }
+}

Convert HwiClient to use new API.