mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 22:14:26 +01:00
The Big Cleanup: Refactor BTCPay internals (#5809)
This commit is contained in:
@@ -34,6 +34,7 @@ using Microsoft.AspNetCore.Cors;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using NBitcoin;
|
||||
using NBitpayClient;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using LightningAddressData = BTCPayServer.Data.LightningAddressData;
|
||||
@@ -47,8 +48,6 @@ namespace BTCPayServer
|
||||
{
|
||||
private readonly InvoiceRepository _invoiceRepository;
|
||||
private readonly EventAggregator _eventAggregator;
|
||||
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
||||
private readonly LightningLikePaymentHandler _lightningLikePaymentHandler;
|
||||
private readonly StoreRepository _storeRepository;
|
||||
private readonly AppService _appService;
|
||||
private readonly UIInvoiceController _invoiceController;
|
||||
@@ -59,11 +58,11 @@ namespace BTCPayServer
|
||||
private readonly BTCPayNetworkJsonSerializerSettings _btcPayNetworkJsonSerializerSettings;
|
||||
private readonly IPluginHookService _pluginHookService;
|
||||
private readonly InvoiceActivator _invoiceActivator;
|
||||
private readonly PaymentMethodHandlerDictionary _handlers;
|
||||
|
||||
public UILNURLController(InvoiceRepository invoiceRepository,
|
||||
EventAggregator eventAggregator,
|
||||
BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
LightningLikePaymentHandler lightningLikePaymentHandler,
|
||||
PaymentMethodHandlerDictionary handlers,
|
||||
StoreRepository storeRepository,
|
||||
AppService appService,
|
||||
UIInvoiceController invoiceController,
|
||||
@@ -77,8 +76,7 @@ namespace BTCPayServer
|
||||
{
|
||||
_invoiceRepository = invoiceRepository;
|
||||
_eventAggregator = eventAggregator;
|
||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||
_lightningLikePaymentHandler = lightningLikePaymentHandler;
|
||||
_handlers = handlers;
|
||||
_storeRepository = storeRepository;
|
||||
_appService = appService;
|
||||
_invoiceController = invoiceController;
|
||||
@@ -98,13 +96,13 @@ namespace BTCPayServer
|
||||
[NonAction]
|
||||
internal async Task<IActionResult> GetLNURLForPullPayment(string cryptoCode, string pullPaymentId, string pr, string k1, CancellationToken cancellationToken)
|
||||
{
|
||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||
var network = GetNetwork(cryptoCode);
|
||||
if (network is null || !network.SupportLightning)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var pmi = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);
|
||||
var pmi = PaymentTypes.LN.GetPaymentMethodId(cryptoCode);
|
||||
var pp = await _pullPaymentHostedService.GetPullPayment(pullPaymentId, true);
|
||||
if (!pp.IsRunning() || !pp.IsSupported(pmi))
|
||||
{
|
||||
@@ -149,9 +147,7 @@ namespace BTCPayServer
|
||||
if (result.MinimumAmount < request.MinWithdrawable || result.MinimumAmount > request.MaxWithdrawable)
|
||||
return BadRequest(new LNUrlStatusResponse { Status = "ERROR", Reason = $"Payment request was not within bounds ({request.MinWithdrawable.ToUnit(LightMoneyUnit.Satoshi)} - {request.MaxWithdrawable.ToUnit(LightMoneyUnit.Satoshi)} sats)" });
|
||||
var store = await _storeRepository.FindStore(pp.StoreId);
|
||||
var pm = store!.GetSupportedPaymentMethods(_btcPayNetworkProvider)
|
||||
.OfType<LightningSupportedPaymentMethod>()
|
||||
.FirstOrDefault(method => method.PaymentId == pmi);
|
||||
var pm = store!.GetPaymentMethodConfig<LightningPaymentMethodConfig>(pmi, _handlers);
|
||||
if (pm is null)
|
||||
{
|
||||
return NotFound();
|
||||
@@ -169,12 +165,13 @@ namespace BTCPayServer
|
||||
if (claimResponse.Result != ClaimRequest.ClaimResult.Ok)
|
||||
return BadRequest(new LNUrlStatusResponse { Status = "ERROR", Reason = "Payment request could not be paid" });
|
||||
|
||||
var lightningHandler = _handlers.GetLightningHandler(network);
|
||||
switch (claimResponse.PayoutData.State)
|
||||
{
|
||||
case PayoutState.AwaitingPayment:
|
||||
{
|
||||
var client =
|
||||
_lightningLikePaymentHandler.CreateLightningClient(pm, network);
|
||||
lightningHandler.CreateLightningClient(pm);
|
||||
var payResult = await UILightningLikePayoutController.TrypayBolt(client,
|
||||
claimResponse.PayoutData.GetBlob(_btcPayNetworkJsonSerializerSettings),
|
||||
claimResponse.PayoutData, result, pmi, cancellationToken);
|
||||
@@ -226,10 +223,18 @@ namespace BTCPayServer
|
||||
return Ok(request);
|
||||
}
|
||||
|
||||
private BTCPayNetwork GetNetwork(string cryptoCode)
|
||||
{
|
||||
if (!_handlers.TryGetValue(PaymentTypes.LNURL.GetPaymentMethodId(cryptoCode), out var o) ||
|
||||
o is not LNURLPayPaymentHandler { Network: var network })
|
||||
return null;
|
||||
return network;
|
||||
}
|
||||
|
||||
[HttpGet("pay/app/{appId}/{itemCode}")]
|
||||
public async Task<IActionResult> GetLNURLForApp(string cryptoCode, string appId, string itemCode = null)
|
||||
{
|
||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||
var network = GetNetwork(cryptoCode);
|
||||
if (network is null || !network.SupportLightning)
|
||||
{
|
||||
return NotFound();
|
||||
@@ -514,7 +519,7 @@ namespace BTCPayServer
|
||||
{
|
||||
createInvoice.Checkout ??= new InvoiceDataBase.CheckoutOptions();
|
||||
createInvoice.Checkout.LazyPaymentMethods = false;
|
||||
createInvoice.Checkout.PaymentMethods = new[] { pmi.ToStringNormalized() };
|
||||
createInvoice.Checkout.PaymentMethods = new[] { pmi.ToString() };
|
||||
i = await _invoiceController.CreateInvoiceCoreRaw(createInvoice, store, Request.GetAbsoluteRoot(), additionalTags);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -540,14 +545,17 @@ namespace BTCPayServer
|
||||
lnurlRequest ??= new LNURLPayRequest();
|
||||
lnUrlMetadata ??= new Dictionary<string, string>();
|
||||
|
||||
var pm = i.GetPaymentMethod(pmi);
|
||||
var pm = i.GetPaymentPrompt(pmi);
|
||||
if (pm is null)
|
||||
return null;
|
||||
var paymentMethodDetails = (LNURLPayPaymentMethodDetails)pm.GetPaymentMethodDetails();
|
||||
var handler = ((LNURLPayPaymentHandler)_handlers[pmi]);
|
||||
var paymentMethodDetails = handler.ParsePaymentPromptDetails(pm.Details);
|
||||
bool updatePaymentMethodDetails = false;
|
||||
List<string> searchTerms = new List<string>();
|
||||
if (lnUrlMetadata?.TryGetValue("text/identifier", out var lnAddress) is true && lnAddress is not null)
|
||||
{
|
||||
paymentMethodDetails.ConsumedLightningAddress = lnAddress;
|
||||
searchTerms.Add(lnAddress);
|
||||
updatePaymentMethodDetails = true;
|
||||
}
|
||||
|
||||
@@ -561,7 +569,7 @@ namespace BTCPayServer
|
||||
lnurlRequest.Callback = new Uri(_linkGenerator.GetUriByAction(
|
||||
action: nameof(GetLNURLForInvoice),
|
||||
controller: "UILNURL",
|
||||
values: new { pmi.CryptoCode, invoiceId = i.Id }, Request.Scheme, Request.Host, Request.PathBase));
|
||||
values: new { cryptoCode, invoiceId = i.Id }, Request.Scheme, Request.Host, Request.PathBase));
|
||||
lnurlRequest.Metadata = JsonConvert.SerializeObject(lnUrlMetadata.Select(kv => new[] { kv.Key, kv.Value }));
|
||||
if (i.Type != InvoiceType.TopUp)
|
||||
{
|
||||
@@ -580,8 +588,10 @@ namespace BTCPayServer
|
||||
}
|
||||
if (updatePaymentMethodDetails)
|
||||
{
|
||||
pm.SetPaymentMethodDetails(paymentMethodDetails);
|
||||
await _invoiceRepository.UpdateInvoicePaymentMethod(i.Id, pm);
|
||||
pm.Details = JToken.FromObject(paymentMethodDetails, handler.Serializer);
|
||||
await _invoiceRepository.UpdatePaymentDetails(i.Id, handler, paymentMethodDetails);
|
||||
await _invoiceRepository.AddSearchTerms(i.Id, searchTerms);
|
||||
_eventAggregator.Publish(new InvoiceNewPaymentDetailsEvent(i.Id, paymentMethodDetails, pmi));
|
||||
}
|
||||
return lnurlRequest;
|
||||
}
|
||||
@@ -605,18 +615,16 @@ namespace BTCPayServer
|
||||
lnurlRequest.MaxSendable = LightMoney.FromUnit(6.12m, LightMoneyUnit.BTC);
|
||||
}
|
||||
|
||||
PaymentMethodId GetLNUrlPaymentMethodId(string cryptoCode, Data.StoreData store, out LNURLPaySupportedPaymentMethod lnUrlSettings)
|
||||
PaymentMethodId GetLNUrlPaymentMethodId(string cryptoCode, Data.StoreData store, out LNURLPaymentMethodConfig lnUrlSettings)
|
||||
{
|
||||
lnUrlSettings = null;
|
||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||
var network = GetNetwork(cryptoCode);
|
||||
if (network is null || !network.SupportLightning)
|
||||
return null;
|
||||
var pmi = new PaymentMethodId(cryptoCode, PaymentTypes.LNURLPay);
|
||||
var lnpmi = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);
|
||||
var methods = store.GetSupportedPaymentMethods(_btcPayNetworkProvider);
|
||||
var lnUrlMethod =
|
||||
methods.FirstOrDefault(method => method.PaymentId == pmi) as LNURLPaySupportedPaymentMethod;
|
||||
var lnMethod = methods.FirstOrDefault(method => method.PaymentId == lnpmi);
|
||||
var pmi = PaymentTypes.LNURL.GetPaymentMethodId(cryptoCode);
|
||||
var lnpmi = PaymentTypes.LN.GetPaymentMethodId(cryptoCode);
|
||||
var lnUrlMethod = store.GetPaymentMethodConfig<LNURLPaymentMethodConfig>(pmi, _handlers);
|
||||
var lnMethod = store.GetPaymentMethodConfig<LightningPaymentMethodConfig>(lnpmi, _handlers);
|
||||
if (lnUrlMethod is null || lnMethod is null)
|
||||
return null;
|
||||
var blob = store.GetStoreBlob();
|
||||
@@ -632,7 +640,7 @@ namespace BTCPayServer
|
||||
public async Task<IActionResult> GetLNURLForInvoice(string invoiceId, string cryptoCode,
|
||||
[FromQuery] long? amount = null, string comment = null)
|
||||
{
|
||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||
var network = GetNetwork(cryptoCode);
|
||||
if (network is null || !network.SupportLightning)
|
||||
{
|
||||
return NotFound();
|
||||
@@ -651,25 +659,25 @@ namespace BTCPayServer
|
||||
var pmi = GetLNUrlPaymentMethodId(cryptoCode, store, out var lnurlSupportedPaymentMethod);
|
||||
if (pmi is null)
|
||||
return NotFound();
|
||||
|
||||
var lightningPaymentMethod = i.GetPaymentMethod(pmi);
|
||||
var paymentMethodDetails =
|
||||
lightningPaymentMethod?.GetPaymentMethodDetails() as LNURLPayPaymentMethodDetails;
|
||||
if (paymentMethodDetails is not null && !paymentMethodDetails.Activated)
|
||||
var handler = ((LNURLPayPaymentHandler)_handlers[pmi]);
|
||||
var lightningPaymentMethod = i.GetPaymentPrompt(pmi);
|
||||
var promptDetails = handler.ParsePaymentPromptDetails(lightningPaymentMethod.Details);
|
||||
if (promptDetails is null)
|
||||
{
|
||||
if (!await _invoiceActivator.ActivateInvoicePaymentMethod(pmi, i, store))
|
||||
if (!await _invoiceActivator.ActivateInvoicePaymentMethod(i.Id, pmi))
|
||||
return NotFound();
|
||||
i = await _invoiceRepository.GetInvoice(invoiceId, true);
|
||||
lightningPaymentMethod = i.GetPaymentMethod(pmi);
|
||||
paymentMethodDetails = lightningPaymentMethod.GetPaymentMethodDetails() as LNURLPayPaymentMethodDetails;
|
||||
lightningPaymentMethod = i.GetPaymentPrompt(pmi);
|
||||
promptDetails = handler.ParsePaymentPromptDetails(lightningPaymentMethod.Details);
|
||||
}
|
||||
|
||||
if (paymentMethodDetails?.LightningSupportedPaymentMethod is null)
|
||||
var lnConfig = _handlers.GetLightningConfig(store, network);
|
||||
if (lnConfig is null)
|
||||
return NotFound();
|
||||
|
||||
LNURLPayRequest lnurlPayRequest = paymentMethodDetails.PayRequest;
|
||||
LNURLPayRequest lnurlPayRequest = promptDetails.PayRequest;
|
||||
var blob = store.GetStoreBlob();
|
||||
if (paymentMethodDetails.PayRequest is null)
|
||||
if (promptDetails.PayRequest is null)
|
||||
{
|
||||
lnurlPayRequest = await CreateLNUrlRequestFromInvoice(cryptoCode, i, store, blob, allowOverpay: false);
|
||||
if (lnurlPayRequest is null)
|
||||
@@ -705,23 +713,20 @@ namespace BTCPayServer
|
||||
if (lnurlSupportedPaymentMethod.LUD12Enabled)
|
||||
{
|
||||
comment = comment?.Truncate(2000);
|
||||
if (paymentMethodDetails.ProvidedComment != comment)
|
||||
if (promptDetails.ProvidedComment != comment)
|
||||
{
|
||||
paymentMethodDetails.ProvidedComment = comment;
|
||||
promptDetails.ProvidedComment = comment;
|
||||
updatePaymentMethod = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(paymentMethodDetails.BOLT11) || paymentMethodDetails.GeneratedBoltAmount != amt)
|
||||
if (string.IsNullOrEmpty(lightningPaymentMethod.Destination) || promptDetails.GeneratedBoltAmount != amt)
|
||||
{
|
||||
var client =
|
||||
_lightningLikePaymentHandler.CreateLightningClient(
|
||||
paymentMethodDetails.LightningSupportedPaymentMethod, network);
|
||||
if (!string.IsNullOrEmpty(paymentMethodDetails.BOLT11))
|
||||
var client = _handlers.GetLightningHandler(network).CreateLightningClient(lnConfig);
|
||||
if (!string.IsNullOrEmpty(lightningPaymentMethod.Destination))
|
||||
{
|
||||
try
|
||||
{
|
||||
await client.CancelInvoice(paymentMethodDetails.InvoiceId);
|
||||
await client.CancelInvoice(promptDetails.InvoiceId);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -764,26 +769,26 @@ namespace BTCPayServer
|
||||
});
|
||||
}
|
||||
|
||||
paymentMethodDetails.BOLT11 = invoice.BOLT11;
|
||||
paymentMethodDetails.PaymentHash = string.IsNullOrEmpty(invoice.PaymentHash) ? null : uint256.Parse(invoice.PaymentHash);
|
||||
paymentMethodDetails.Preimage = string.IsNullOrEmpty(invoice.Preimage) ? null : uint256.Parse(invoice.Preimage);
|
||||
paymentMethodDetails.InvoiceId = invoice.Id;
|
||||
paymentMethodDetails.GeneratedBoltAmount = amt;
|
||||
lightningPaymentMethod.Destination = invoice.BOLT11;
|
||||
promptDetails.PaymentHash = string.IsNullOrEmpty(invoice.PaymentHash) ? null : uint256.Parse(invoice.PaymentHash);
|
||||
promptDetails.Preimage = string.IsNullOrEmpty(invoice.Preimage) ? null : uint256.Parse(invoice.Preimage);
|
||||
promptDetails.InvoiceId = invoice.Id;
|
||||
promptDetails.GeneratedBoltAmount = amt;
|
||||
lightningPaymentMethod.Details = JToken.FromObject(promptDetails, handler.Serializer);
|
||||
updatePaymentMethod = true;
|
||||
}
|
||||
|
||||
if (updatePaymentMethod)
|
||||
{
|
||||
lightningPaymentMethod.SetPaymentMethodDetails(paymentMethodDetails);
|
||||
await _invoiceRepository.UpdateInvoicePaymentMethod(invoiceId, lightningPaymentMethod);
|
||||
_eventAggregator.Publish(new InvoiceNewPaymentDetailsEvent(invoiceId, paymentMethodDetails, pmi));
|
||||
await _invoiceRepository.UpdatePrompt(invoiceId, lightningPaymentMethod);
|
||||
_eventAggregator.Publish(new InvoiceNewPaymentDetailsEvent(invoiceId, promptDetails, pmi));
|
||||
}
|
||||
|
||||
return Ok(new LNURLPayRequest.LNURLPayRequestCallbackResponse
|
||||
{
|
||||
Disposable = true,
|
||||
Routes = Array.Empty<string>(),
|
||||
Pr = paymentMethodDetails.BOLT11,
|
||||
Pr = lightningPaymentMethod.Destination,
|
||||
SuccessAction = successAction
|
||||
});
|
||||
}
|
||||
@@ -800,8 +805,8 @@ namespace BTCPayServer
|
||||
[HttpGet("~/stores/{storeId}/plugins/lightning-address")]
|
||||
public async Task<IActionResult> EditLightningAddress(string storeId)
|
||||
{
|
||||
if (ControllerContext.HttpContext.GetStoreData().GetEnabledPaymentIds(_btcPayNetworkProvider)
|
||||
.All(id => id.PaymentType != LNURLPayPaymentType.Instance))
|
||||
if (ControllerContext.HttpContext.GetStoreData().GetEnabledPaymentIds()
|
||||
.All(id => _handlers.TryGet(id) is not LNURLPayPaymentHandler))
|
||||
{
|
||||
TempData.SetStatusMessageModel(new StatusMessageModel
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user