diff --git a/BTCPayServer/BTCPayServer.csproj b/BTCPayServer/BTCPayServer.csproj index 4fa071d51..9a7f773d6 100644 --- a/BTCPayServer/BTCPayServer.csproj +++ b/BTCPayServer/BTCPayServer.csproj @@ -33,7 +33,7 @@ - + diff --git a/BTCPayServer/Controllers/InvoiceController.cs b/BTCPayServer/Controllers/InvoiceController.cs index c58dba0e4..8f248f178 100644 --- a/BTCPayServer/Controllers/InvoiceController.cs +++ b/BTCPayServer/Controllers/InvoiceController.cs @@ -242,6 +242,7 @@ namespace BTCPayServer.Controllers paymentMethod.Network = network; paymentMethod.SetId(supportedPaymentMethod.PaymentId); paymentMethod.Rate = rate.BidAsk.Bid; + paymentMethod.PreferOnion = this.Request.IsOnion(); var paymentDetails = await handler.CreatePaymentMethodDetails(supportedPaymentMethod, paymentMethod, store, network, preparePayment); paymentMethod.SetPaymentMethodDetails(paymentDetails); diff --git a/BTCPayServer/Controllers/PublicLightningNodeInfoController.cs b/BTCPayServer/Controllers/PublicLightningNodeInfoController.cs index 8cce6d5ad..33111d947 100644 --- a/BTCPayServer/Controllers/PublicLightningNodeInfoController.cs +++ b/BTCPayServer/Controllers/PublicLightningNodeInfoController.cs @@ -43,7 +43,7 @@ namespace BTCPayServer.Controllers var paymentMethodDetails = GetExistingLightningSupportedPaymentMethod(cryptoCode, store); var network = _BtcPayNetworkProvider.GetNetwork(cryptoCode); var nodeInfo = - await _LightningLikePaymentHandler.GetNodeInfo(paymentMethodDetails, + await _LightningLikePaymentHandler.GetNodeInfo(this.Request.IsOnion(), paymentMethodDetails, network); return View(new ShowLightningNodeInfoViewModel() diff --git a/BTCPayServer/Controllers/StoresController.LightningLike.cs b/BTCPayServer/Controllers/StoresController.LightningLike.cs index 9becff7e1..f37c10b14 100644 --- a/BTCPayServer/Controllers/StoresController.LightningLike.cs +++ b/BTCPayServer/Controllers/StoresController.LightningLike.cs @@ -155,7 +155,7 @@ namespace BTCPayServer.Controllers var handler = (LightningLikePaymentHandler)_ServiceProvider.GetRequiredService>(); try { - var info = await handler.GetNodeInfo(paymentMethod, network); + var info = await handler.GetNodeInfo(this.Request.IsOnion(), paymentMethod, network); if (!vm.SkipPortTest) { using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(20))) diff --git a/BTCPayServer/Extensions.cs b/BTCPayServer/Extensions.cs index d961810eb..9b61a0f29 100644 --- a/BTCPayServer/Extensions.cs +++ b/BTCPayServer/Extensions.cs @@ -165,6 +165,11 @@ namespace BTCPayServer (derivationStrategyBase is DirectDerivationStrategy direct) && direct.Segwit; } + public static bool IsOnion(this HttpRequest request) + { + return request.Host.Host.EndsWith(".onion", StringComparison.OrdinalIgnoreCase); + } + public static string GetAbsoluteRoot(this HttpRequest request) { return string.Concat( diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs index e8a59c3e5..0493f1012 100644 --- a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs @@ -25,7 +25,7 @@ namespace BTCPayServer.Payments.Lightning public override async Task CreatePaymentMethodDetails(LightningSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network, object preparePaymentObject) { var storeBlob = store.GetStoreBlob(); - var test = GetNodeInfo(supportedPaymentMethod, network); + var test = GetNodeInfo(paymentMethod.PreferOnion, supportedPaymentMethod, network); var invoice = paymentMethod.ParentEntity; var due = Extensions.RoundUp(invoice.ProductInformation.Price / paymentMethod.Rate, 8); var client = supportedPaymentMethod.CreateClient(network); @@ -63,7 +63,7 @@ namespace BTCPayServer.Payments.Lightning }; } - public async Task GetNodeInfo(LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network) + public async Task GetNodeInfo(bool preferOnion, LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network) { if (!_Dashboard.IsFullySynched(network.CryptoCode, out var summary)) throw new PaymentMethodUnavailableException($"Full node not available"); @@ -84,8 +84,8 @@ namespace BTCPayServer.Payments.Lightning { throw new PaymentMethodUnavailableException($"Error while connecting to the API ({ex.Message})"); } - - if (info.NodeInfo == null) + var nodeInfo = info.NodeInfoList.FirstOrDefault(i => i.IsTor == preferOnion) ?? info.NodeInfoList.FirstOrDefault(); + if (nodeInfo == null) { throw new PaymentMethodUnavailableException($"No lightning node public address has been configured"); } @@ -96,7 +96,7 @@ namespace BTCPayServer.Payments.Lightning throw new PaymentMethodUnavailableException($"The lightning node is not synched ({blocksGap} blocks left)"); } - return info.NodeInfo; + return nodeInfo; } } diff --git a/BTCPayServer/Services/Invoices/InvoiceEntity.cs b/BTCPayServer/Services/Invoices/InvoiceEntity.cs index 541b9fb96..b6de4d301 100644 --- a/BTCPayServer/Services/Invoices/InvoiceEntity.cs +++ b/BTCPayServer/Services/Invoices/InvoiceEntity.cs @@ -717,6 +717,12 @@ namespace BTCPayServer.Services.Invoices [Obsolete("Use GetId().PaymentType instead")] public string PaymentType { get; set; } + /// + /// We only use this to pass a singleton asking to the payment handler to prefer payments through TOR, we don't really + /// need to save this information + /// + [JsonIgnore] + public bool PreferOnion { get; set; } public PaymentMethodId GetId() { diff --git a/BTCPayServer/Views/Server/Services.cshtml b/BTCPayServer/Views/Server/Services.cshtml index d4e02a09d..e5dc9a740 100644 --- a/BTCPayServer/Views/Server/Services.cshtml +++ b/BTCPayServer/Views/Server/Services.cshtml @@ -100,7 +100,9 @@ { @s.Name - See information + + See information + }