Support Payjoin through Clearnet HTTPClient when Tor is explicitly turned off.
MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
@@ -3,6 +3,7 @@ using NBitcoin.Payment;
using ReactiveUI;
using System;
using System.Collections.Generic;
+using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using WalletWasabi.Blockchain.TransactionBuilding;
@@ -16,6 +17,7 @@ using WalletWasabi.Models;
using WalletWasabi.Wallets;
using WalletWasabi.WebClients.PayJoin;
using WalletWasabi.Gui.Validation;
+using WalletWasabi.Logging;
namespace WalletWasabi.Gui.Controls.WalletExplorer
{
@@ -80,12 +82,34 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
private IPayjoinClient GetPayjoinClient()
{
- if (!string.IsNullOrWhiteSpace(PayjoinEndPoint) && Uri.IsWellFormedUriString(PayjoinEndPoint, UriKind.Absolute))
+ if (!string.IsNullOrWhiteSpace(PayjoinEndPoint) &&
+ Uri.IsWellFormedUriString(PayjoinEndPoint, UriKind.Absolute))
{
var payjoinEndPointUri = new Uri(PayjoinEndPoint);
+ if (Global.Config.UseTor)
+ {
return new PayjoinClient(payjoinEndPointUri, Global.TorManager.TorSocks5EndPoint);
}
+ if (payjoinEndPointUri.DnsSafeHost.EndsWith(".onion", StringComparison.OrdinalIgnoreCase))
+ {
+ Logger.LogWarning("Payjoin server is a hidden service but Tor is disabled. Ignoring...");
+ return null;
+ }
+
+ // TODO: Use an IHttpClientFactory to construct the HttpClient
+ if (Global.Config.Network == Network.RegTest)
+ {
+ HttpClientHandler clientHandler = new HttpClientHandler();
+ clientHandler.ServerCertificateCustomValidationCallback =
+ (sender, cert, chain, sslPolicyErrors) => true;
+
+ return new PayjoinClient(payjoinEndPointUri, new HttpClient(clientHandler));
+ }
+
+ return new PayjoinClient(payjoinEndPointUri, new HttpClient());
+ }
+
return null;
}

MODIFY
WalletWasabi.Tests/UnitTests/Clients/MockTorHttpClient.cs
WalletWasabi.Tests/UnitTests/Clients/MockTorHttpClient.cs
@@ -3,6 +3,7 @@ using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
+using NBitcoin;
using WalletWasabi.TorSocks5;
namespace WalletWasabi.Tests.UnitTests.Clients
@@ -37,9 +38,20 @@ namespace WalletWasabi.Tests.UnitTests.Clients
}
}
- public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancel = default)
+ public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancel = default)
{
- throw new NotImplementedException();
+ var relativeUri = request.RequestUri?.ToString()?.Replace(TorSocks5EndPoint.ToEndpointString(), "");
+ if (string.IsNullOrWhiteSpace(relativeUri))
+ {
+ return await OnSendAsync(request.Method, "", await request.Content.ReadAsStringAsync());
+ }
+ else
+ {
+ var sepPos = relativeUri.IndexOf('?');
+ var action = relativeUri[..sepPos];
+ var parameters = relativeUri[(sepPos + 1)..].Split('&', StringSplitOptions.RemoveEmptyEntries);
+ return await OnSendAsync_Method(request.Method, action, parameters);
+ }
}
#region IDisposable Support

MODIFY
WalletWasabi/WebClients/PayJoin/PayjoinClient.cs
WalletWasabi/WebClients/PayJoin/PayjoinClient.cs
@@ -20,18 +20,24 @@ namespace WalletWasabi.WebClients.PayJoin
{
TorSocks5EndPoint = Guard.NotNull(nameof(torSocks5EndPoint), torSocks5EndPoint);
PaymentUrl = Guard.NotNull(nameof(paymentUrl), paymentUrl);
- HttpClient = new TorHttpClient(PaymentUrl, TorSocks5EndPoint);
+ TorHttpClient = new TorHttpClient(PaymentUrl, TorSocks5EndPoint);
+ }
+ public PayjoinClient(Uri paymentUrl, HttpClient httpClient)
+ {
+ PaymentUrl = Guard.NotNull(nameof(paymentUrl), paymentUrl);
+ ClearnetHttpClient = Guard.NotNull(nameof(httpClient), httpClient);
}
// For testing only
internal PayjoinClient(ITorHttpClient httpClient)
{
- HttpClient = Guard.NotNull(nameof(httpClient), httpClient);
+ TorHttpClient = Guard.NotNull(nameof(httpClient), httpClient);
}
public Uri PaymentUrl { get; }
private EndPoint TorSocks5EndPoint { get; }
- private ITorHttpClient HttpClient { get; }
+ private ITorHttpClient TorHttpClient { get; }
+ private HttpClient ClearnetHttpClient { get; }
public async Task<PSBT> RequestPayjoin(PSBT originalTx, IHDKey accountKey, RootedKeyPath rootedKeyPath, CancellationToken cancellationToken)
{
@@ -69,8 +75,19 @@ namespace WalletWasabi.WebClients.PayJoin
cloned.GlobalXPubs.Clear();
- var bpuResponse = await HttpClient.SendAsync(HttpMethod.Post, "",
- new StringContent(cloned.ToHex(), Encoding.UTF8, "text/plain"), cancellationToken).ConfigureAwait(false);
+ var request = new HttpRequestMessage(HttpMethod.Post, PaymentUrl)
+ {
+ Content = new StringContent(cloned.ToHex(), Encoding.UTF8, "text/plain")
+ };
+ HttpResponseMessage bpuResponse = null;
+ if (TorHttpClient == null)
+ {
+ bpuResponse = await new HttpClient().SendAsync(request, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ bpuResponse = await TorHttpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);
+ }
if (!bpuResponse.IsSuccessStatusCode)
{
var errorStr = await bpuResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

Support Payjoin through Clearnet HTTPClient when Tor is explicitly turned off.