Add client ability to use multiple backend API
MODIFY
WalletWasabi.Gui/CommandLine/CommandInterpreter.cs
WalletWasabi.Gui/CommandLine/CommandInterpreter.cs
@@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
using System.Threading.Tasks;
using WalletWasabi.Helpers;
using WalletWasabi.Logging;
+using WalletWasabi.WebClients.Wasabi;
namespace WalletWasabi.Gui.CommandLine
{
@@ -70,7 +71,7 @@ namespace WalletWasabi.Gui.CommandLine
private static void ShowVersion()
{
Console.WriteLine($"Wasabi Client Version: {Constants.ClientVersion}");
- Console.WriteLine($"Compatible Coordinator Version: {Constants.BackendMajorVersion}");
+ Console.WriteLine($"Compatible Coordinator Version: {WasabiClient.CurrentBackendMajorVersion}");
Console.WriteLine($"Compatible Bitcoin Core and Bitcoin Knots Versions: {Constants.BitcoinCoreVersion}");
Console.WriteLine($"Compatible Hardware Wallet Interface Version: {Constants.HwiVersion}");
}

MODIFY
WalletWasabi.Gui/Tabs/AboutView.xaml
WalletWasabi.Gui/Tabs/AboutView.xaml
<controls:ExtendedTextBox Text="{Binding ClientVersion, Converter={StaticResource VersionStringConverter}}" Classes="selectableTextBlock" />
</StackPanel>
<StackPanel Orientation="Horizontal">
- <TextBlock Text="Compatible Coordinator Version: " />
+ <TextBlock Text="Compatible Coordinator Versions: " />
<controls:ExtendedTextBox Text="{Binding BackendMajorVersion}" Classes="selectableTextBlock" />
</StackPanel>
+ <StackPanel Orientation="Horizontal">
+ <TextBlock Text="Current Coordinator Versions: " />
+ <controls:ExtendedTextBox Text="{Binding CurrentBackendMajorVersion}" Classes="selectableTextBlock" />
+ </StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Compatible Bitcoin Core and Bitcoin Knots Versions: " />
<controls:ExtendedTextBox Text="{Binding BitcoinCoreVersion, Converter={StaticResource VersionStringConverter}}" Classes="selectableTextBlock" />

MODIFY
WalletWasabi.Gui/Tabs/AboutViewModel.cs
WalletWasabi.Gui/Tabs/AboutViewModel.cs
@@ -11,6 +11,7 @@ using System.Reactive;
using WalletWasabi.Helpers;
using WalletWasabi.Logging;
using System.Reactive.Linq;
+using WalletWasabi.WebClients.Wasabi;
namespace WalletWasabi.Gui.Tabs
{
@@ -28,7 +29,8 @@ namespace WalletWasabi.Gui.Tabs
public ReactiveCommand<string, Unit> OpenBrowserCommand { get; }
public Version ClientVersion => Constants.ClientVersion;
- public string BackendMajorVersion => Constants.BackendMajorVersion;
+ public string BackendMajorVersion => $"{Constants.BackendMajorVersion},{Constants.ClientCompatibleWithBackendVersion}";
+ public string CurrentBackendMajorVersion => WasabiClient.CurrentBackendMajorVersion;
public Version BitcoinCoreVersion => Constants.BitcoinCoreVersion;
public Version HwiVersion => Constants.HwiVersion;

MODIFY
WalletWasabi/CoinJoin/Client/Clients/AliceClient.cs
WalletWasabi/CoinJoin/Client/Clients/AliceClient.cs
@@ -13,6 +13,7 @@ using WalletWasabi.CoinJoin.Common.Crypto;
using WalletWasabi.CoinJoin.Common.Models;
using WalletWasabi.Exceptions;
using WalletWasabi.Logging;
+using WalletWasabi.WebClients.Wasabi;
using static WalletWasabi.Crypto.SchnorrBlinding;
using UnblindedSignature = WalletWasabi.Crypto.UnblindedSignature;
@@ -83,7 +84,7 @@ namespace WalletWasabi.CoinJoin.Client.Clients
throw new NotSupportedException($"InputRequest {nameof(roundId)} does not match to the provided {nameof(roundId)}: {request.RoundId} != {roundId}.");
}
}
- using HttpResponseMessage response = await client.TorClient.SendAsync(HttpMethod.Post, $"/api/v{Helpers.Constants.BackendMajorVersion}/btc/chaumiancoinjoin/inputs/", request.ToHttpStringContent()).ConfigureAwait(false);
+ using HttpResponseMessage response = await client.TorClient.SendAsync(HttpMethod.Post, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/chaumiancoinjoin/inputs/", request.ToHttpStringContent()).ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.OK)
{
await response.ThrowRequestExceptionFromContentAsync().ConfigureAwait(false);
@@ -146,7 +147,7 @@ namespace WalletWasabi.CoinJoin.Client.Clients
public async Task<(RoundPhase currentPhase, IEnumerable<ActiveOutput> activeOutputs)> PostConfirmationAsync()
{
- using HttpResponseMessage response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{Helpers.Constants.BackendMajorVersion}/btc/chaumiancoinjoin/confirmation?uniqueId={UniqueId}&roundId={RoundId}").ConfigureAwait(false);
+ using HttpResponseMessage response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/chaumiancoinjoin/confirmation?uniqueId={UniqueId}&roundId={RoundId}").ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.OK)
{
await response.ThrowRequestExceptionFromContentAsync().ConfigureAwait(false);
@@ -198,7 +199,7 @@ namespace WalletWasabi.CoinJoin.Client.Clients
{
try
{
- using HttpResponseMessage response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{Helpers.Constants.BackendMajorVersion}/btc/chaumiancoinjoin/unconfirmation?uniqueId={UniqueId}&roundId={RoundId}", cancel: cts.Token).ConfigureAwait(false);
+ using HttpResponseMessage response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/chaumiancoinjoin/unconfirmation?uniqueId={UniqueId}&roundId={RoundId}", cancel: cts.Token).ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.BadRequest || response.StatusCode == HttpStatusCode.Gone) // Otherwise maybe some internet connection issue there's. Let's consider that as timed out.
{
await response.ThrowRequestExceptionFromContentAsync().ConfigureAwait(false);
@@ -222,7 +223,7 @@ namespace WalletWasabi.CoinJoin.Client.Clients
public async Task<Transaction> GetUnsignedCoinJoinAsync()
{
- using HttpResponseMessage response = await TorClient.SendAsync(HttpMethod.Get, $"/api/v{Helpers.Constants.BackendMajorVersion}/btc/chaumiancoinjoin/coinjoin?uniqueId={UniqueId}&roundId={RoundId}").ConfigureAwait(false);
+ using HttpResponseMessage response = await TorClient.SendAsync(HttpMethod.Get, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/chaumiancoinjoin/coinjoin?uniqueId={UniqueId}&roundId={RoundId}").ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.OK)
{
await response.ThrowRequestExceptionFromContentAsync().ConfigureAwait(false);
@@ -242,7 +243,7 @@ namespace WalletWasabi.CoinJoin.Client.Clients
var jsonSignatures = JsonConvert.SerializeObject(myDic, Formatting.None);
var signatureRequestContent = new StringContent(jsonSignatures, Encoding.UTF8, "application/json");
- using HttpResponseMessage response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{Helpers.Constants.BackendMajorVersion}/btc/chaumiancoinjoin/signatures?uniqueId={UniqueId}&roundId={RoundId}", signatureRequestContent).ConfigureAwait(false);
+ using HttpResponseMessage response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/chaumiancoinjoin/signatures?uniqueId={UniqueId}&roundId={RoundId}", signatureRequestContent).ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.NoContent)
{
await response.ThrowRequestExceptionFromContentAsync().ConfigureAwait(false);

MODIFY
WalletWasabi/CoinJoin/Client/Clients/BobClient.cs
WalletWasabi/CoinJoin/Client/Clients/BobClient.cs
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using WalletWasabi.Bases;
using WalletWasabi.CoinJoin.Common.Models;
using WalletWasabi.Helpers;
+using WalletWasabi.WebClients.Wasabi;
namespace WalletWasabi.CoinJoin.Client.Clients
{
@@ -29,7 +30,7 @@ namespace WalletWasabi.CoinJoin.Client.Clients
Guard.NotNull(nameof(activeOutput), activeOutput);
var request = new OutputRequest { OutputAddress = activeOutput.Address, UnblindedSignature = activeOutput.Signature, Level = activeOutput.MixingLevel };
- using var response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{Constants.BackendMajorVersion}/btc/chaumiancoinjoin/output?roundId={roundId}", request.ToHttpStringContent()).ConfigureAwait(false);
+ using var response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/chaumiancoinjoin/output?roundId={roundId}", request.ToHttpStringContent()).ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.Conflict)
{
return false;

MODIFY
WalletWasabi/CoinJoin/Client/Clients/SatoshiClient.cs
WalletWasabi/CoinJoin/Client/Clients/SatoshiClient.cs
@@ -6,6 +6,7 @@ using System.Net.Http;
using System.Threading.Tasks;
using WalletWasabi.Bases;
using WalletWasabi.CoinJoin.Common.Models;
+using WalletWasabi.WebClients.Wasabi;
namespace WalletWasabi.CoinJoin.Client.Clients
{
@@ -23,7 +24,7 @@ namespace WalletWasabi.CoinJoin.Client.Clients
public async Task<IEnumerable<RoundStateResponse>> GetAllRoundStatesAsync()
{
- using var response = await TorClient.SendAsync(HttpMethod.Get, $"/api/v{Helpers.Constants.BackendMajorVersion}/btc/chaumiancoinjoin/states/").ConfigureAwait(false);
+ using var response = await TorClient.SendAsync(HttpMethod.Get, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/chaumiancoinjoin/states/").ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.OK)
{
await response.ThrowRequestExceptionFromContentAsync().ConfigureAwait(false);

MODIFY
WalletWasabi/Helpers/Constants.cs
WalletWasabi/Helpers/Constants.cs
@@ -9,6 +9,7 @@ namespace WalletWasabi.Helpers
public static class Constants
{
public static readonly Version ClientVersion = new Version(1, 1, 11, 1);
+ public const string ClientCompatibleWithBackendVersion = "4";
public const string BackendMajorVersion = "3";
public static readonly Version HwiVersion = new Version("1.1.0");
public static readonly Version BitcoinCoreVersion = new Version("0.19.1");

MODIFY
WalletWasabi/WebClients/Wasabi/WasabiClient.cs
WalletWasabi/WebClients/Wasabi/WasabiClient.cs
@@ -39,6 +39,8 @@ namespace WalletWasabi.WebClients.Wasabi
private static Queue<uint256> TransactionIdQueue { get; } = new Queue<uint256>();
public static object TransactionCacheLock { get; } = new object();
+ public static string CurrentBackendMajorVersion { get; private set; }
+
#region batch
/// <remarks>
@@ -46,7 +48,7 @@ namespace WalletWasabi.WebClients.Wasabi
/// </remarks>
public async Task<SynchronizeResponse> GetSynchronizeAsync(uint256 bestKnownBlockHash, int count, EstimateSmartFeeMode? estimateMode = null, CancellationToken cancel = default)
{
- string relativeUri = $"/api/v{Constants.BackendMajorVersion}/btc/batch/synchronize?bestKnownBlockHash={bestKnownBlockHash}&maxNumberOfFilters={count}";
+ string relativeUri = $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/batch/synchronize?bestKnownBlockHash={bestKnownBlockHash}&maxNumberOfFilters={count}";
if (estimateMode != null)
{
relativeUri = $"{relativeUri}&estimateSmartFeeMode={estimateMode}";
@@ -75,7 +77,7 @@ namespace WalletWasabi.WebClients.Wasabi
using var response = await TorClient.SendAndRetryAsync(
HttpMethod.Get,
HttpStatusCode.OK,
- $"/api/v{Constants.BackendMajorVersion}/btc/blockchain/filters?bestKnownBlockHash={bestKnownBlockHash}&count={count}",
+ $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/blockchain/filters?bestKnownBlockHash={bestKnownBlockHash}&count={count}",
cancel: cancel);
if (response.StatusCode == HttpStatusCode.NoContent)
{
@@ -109,7 +111,7 @@ namespace WalletWasabi.WebClients.Wasabi
using var response = await TorClient.SendAndRetryAsync(
HttpMethod.Get,
HttpStatusCode.OK,
- $"/api/v{Constants.BackendMajorVersion}/btc/blockchain/transaction-hexes?&transactionIds={string.Join("&transactionIds=", chunk.Select(x => x.ToString()))}",
+ $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/blockchain/transaction-hexes?&transactionIds={string.Join("&transactionIds=", chunk.Select(x => x.ToString()))}",
cancel: cancel);
if (response.StatusCode != HttpStatusCode.OK)
{
@@ -146,7 +148,7 @@ namespace WalletWasabi.WebClients.Wasabi
{
var confirmationTargetsString = string.Join(",", confirmationTargets);
- using var response = await TorClient.SendAndRetryAsync(HttpMethod.Get, HttpStatusCode.OK, $"/api/v{Constants.BackendMajorVersion}/btc/blockchain/fees/{confirmationTargetsString}");
+ using var response = await TorClient.SendAndRetryAsync(HttpMethod.Get, HttpStatusCode.OK, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/blockchain/fees/{confirmationTargetsString}");
if (response.StatusCode != HttpStatusCode.OK)
{
await response.ThrowRequestExceptionFromContentAsync();
@@ -160,7 +162,7 @@ namespace WalletWasabi.WebClients.Wasabi
public async Task BroadcastAsync(string hex)
{
using var content = new StringContent($"'{hex}'", Encoding.UTF8, "application/json");
- using var response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{Constants.BackendMajorVersion}/btc/blockchain/broadcast", content);
+ using var response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/blockchain/broadcast", content);
if (response.StatusCode != HttpStatusCode.OK)
{
await response.ThrowRequestExceptionFromContentAsync();
@@ -182,7 +184,7 @@ namespace WalletWasabi.WebClients.Wasabi
using var response = await TorClient.SendAndRetryAsync(
HttpMethod.Get,
HttpStatusCode.OK,
- $"/api/v{Constants.BackendMajorVersion}/btc/blockchain/mempool-hashes",
+ $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/blockchain/mempool-hashes",
cancel: cancel);
if (response.StatusCode != HttpStatusCode.OK)
{
@@ -204,7 +206,7 @@ namespace WalletWasabi.WebClients.Wasabi
using var response = await TorClient.SendAndRetryAsync(
HttpMethod.Get,
HttpStatusCode.OK,
- $"/api/v{Constants.BackendMajorVersion}/btc/blockchain/mempool-hashes?compactness={compactness}",
+ $"/api/v{CurrentBackendMajorVersion}/btc/blockchain/mempool-hashes?compactness={compactness}",
cancel: cancel);
if (response.StatusCode != HttpStatusCode.OK)
{
@@ -222,7 +224,7 @@ namespace WalletWasabi.WebClients.Wasabi
public async Task<IEnumerable<ExchangeRate>> GetExchangeRatesAsync()
{
- using var response = await TorClient.SendAndRetryAsync(HttpMethod.Get, HttpStatusCode.OK, $"/api/v{Constants.BackendMajorVersion}/btc/offchain/exchange-rates");
+ using var response = await TorClient.SendAndRetryAsync(HttpMethod.Get, HttpStatusCode.OK, $"/api/v{WasabiClient.CurrentBackendMajorVersion}/btc/offchain/exchange-rates");
if (response.StatusCode != HttpStatusCode.OK)
{
await response.ThrowRequestExceptionFromContentAsync();
@@ -256,7 +258,8 @@ namespace WalletWasabi.WebClients.Wasabi
{
var versions = await GetVersionsAsync(cancel);
var clientUpToDate = Constants.ClientVersion >= versions.ClientVersion; // If the client version locally is greater than or equal to the backend's reported client version, then good.
- var backendCompatible = int.Parse(Constants.BackendMajorVersion) == versions.BackendMajorVersion; // If the backend major and the client major are equal, then our software is compatible.
+ var backendCompatible = int.Parse(Constants.ClientCompatibleWithBackendVersion) >= versions.BackendMajorVersion; // If the backend major smaller or equal with the client major, then our software is compatible.
+ CurrentBackendMajorVersion = versions.BackendMajorVersion.ToString();
return new UpdateStatus(backendCompatible, clientUpToDate, versions.LegalDocumentsVersion);
}
@@ -270,7 +273,7 @@ namespace WalletWasabi.WebClients.Wasabi
using var response = await TorClient.SendAndRetryAsync(
HttpMethod.Get,
HttpStatusCode.OK,
- $"/api/v{Constants.BackendMajorVersion}/wasabi/legaldocuments",
+ $"/api/v{WasabiClient.CurrentBackendMajorVersion}/wasabi/legaldocuments",
cancel: cancel).ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.OK)
{

Add client ability to use multiple backend API