From 34b2cca4928112434c928bb63c6d30e030913369 Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Mon, 7 Oct 2024 18:19:19 +0900 Subject: [PATCH] Simplify extension of payments extensions --- BTCPayServer.Tests/SeleniumTests.cs | 7 +++ BTCPayServer.Tests/TestAccount.cs | 2 - .../StoreRecentInvoices.cs | 2 +- .../Controllers/UIInvoiceController.UI.cs | 2 + .../Controllers/UIInvoiceController.cs | 3 - BTCPayServer/Extensions.cs | 5 +- BTCPayServer/Hosting/BTCPayServerServices.cs | 8 +-- .../InvoicingModels/InvoiceDetailsModel.cs | 1 + .../Payments/IPaymentMethodViewExtension.cs | 59 ------------------- .../LNURLPaymentMethodViewExtension.cs | 19 ------ .../Lightning/LightningLikePaymentHandler.cs | 4 +- .../Bitcoin/ViewBitcoinLikePaymentData.cshtml | 4 +- .../AdditionalPaymentMethodDetails.cshtml | 18 ------ .../ViewLightningLikePaymentData.cshtml | 38 ++++++++++-- .../ListInvoicesPaymentsPartial.cshtml | 9 +-- 15 files changed, 55 insertions(+), 126 deletions(-) delete mode 100644 BTCPayServer/Payments/IPaymentMethodViewExtension.cs delete mode 100644 BTCPayServer/Payments/LNURLPay/LNURLPaymentMethodViewExtension.cs delete mode 100644 BTCPayServer/Views/Shared/LNURL/AdditionalPaymentMethodDetails.cshtml diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index cdf579e9f..aae22c9b0 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -3264,6 +3264,7 @@ namespace BTCPayServer.Tests public async Task CanUseLNAddress() { using var s = CreateSeleniumTester(); + s.Server.DeleteStore = false; s.Server.ActivateLightning(); await s.StartAsync(); await s.Server.EnsureChannelsSetup(); @@ -3416,7 +3417,13 @@ namespace BTCPayServer.Tests var succ = JsonConvert.DeserializeObject(str); Assert.NotNull(succ.Pr); Assert.Equal(new LightMoney(2001), BOLT11PaymentRequest.Parse(succ.Pr, Network.RegTest).MinimumAmount); + await s.Server.CustomerLightningD.Pay(succ.Pr); } + + // Can we find our comment and address in the payment list? + s.GoToInvoices(); + var source = s.Driver.PageSource; + Assert.Contains(lnUsername, source); } [Fact] diff --git a/BTCPayServer.Tests/TestAccount.cs b/BTCPayServer.Tests/TestAccount.cs index 3a3b7e8a6..b143c441c 100644 --- a/BTCPayServer.Tests/TestAccount.cs +++ b/BTCPayServer.Tests/TestAccount.cs @@ -609,9 +609,7 @@ retry: var methods = await client.GetInvoicePaymentMethods(StoreId, invoiceId); var method = methods.First(m => m.PaymentMethodId == $"{cryptoCode}-LN"); var bolt11 = method.Destination; - TestLogs.LogInformation("PAYING"); await parent.CustomerLightningD.Pay(bolt11); - TestLogs.LogInformation("PAID"); await WaitInvoicePaid(invoiceId); } diff --git a/BTCPayServer/Components/StoreRecentInvoices/StoreRecentInvoices.cs b/BTCPayServer/Components/StoreRecentInvoices/StoreRecentInvoices.cs index d8876ed4c..c90e4fa61 100644 --- a/BTCPayServer/Components/StoreRecentInvoices/StoreRecentInvoices.cs +++ b/BTCPayServer/Components/StoreRecentInvoices/StoreRecentInvoices.cs @@ -68,7 +68,7 @@ public class StoreRecentInvoices : ViewComponent Details = new InvoiceDetailsModel { Archived = invoice.Archived, - Payments = invoice.GetPayments(false) + Payments = invoice.GetPayments(false) } }).ToList(); diff --git a/BTCPayServer/Controllers/UIInvoiceController.UI.cs b/BTCPayServer/Controllers/UIInvoiceController.UI.cs index 1f6a8f198..dc5444209 100644 --- a/BTCPayServer/Controllers/UIInvoiceController.UI.cs +++ b/BTCPayServer/Controllers/UIInvoiceController.UI.cs @@ -128,6 +128,7 @@ namespace BTCPayServer.Controllers StoreLink = Url.Action(nameof(UIStoresController.GeneralSettings), "UIStores", new { storeId = store.Id }), PaymentRequestLink = Url.Action(nameof(UIPaymentRequestController.ViewPaymentRequest), "UIPaymentRequest", new { payReqId = invoice.Metadata.PaymentRequestId }), Id = invoice.Id, + Entity = invoice, State = invoiceState, TransactionSpeed = invoice.SpeedPolicy == SpeedPolicy.HighSpeed ? "high" : invoice.SpeedPolicy == SpeedPolicy.MediumSpeed ? "medium" : @@ -554,6 +555,7 @@ namespace BTCPayServer.Controllers { Archived = invoice.Archived, Payments = invoice.GetPayments(false), + Entity = invoice, CryptoPayments = invoice.GetPaymentPrompts().Select( data => { diff --git a/BTCPayServer/Controllers/UIInvoiceController.cs b/BTCPayServer/Controllers/UIInvoiceController.cs index 3793800d8..b4dc71d39 100644 --- a/BTCPayServer/Controllers/UIInvoiceController.cs +++ b/BTCPayServer/Controllers/UIInvoiceController.cs @@ -63,7 +63,6 @@ namespace BTCPayServer.Controllers private readonly IAuthorizationService _authorizationService; private readonly TransactionLinkProviders _transactionLinkProviders; private readonly Dictionary _paymentModelExtensions; - private readonly PaymentMethodViewProvider _viewProvider; private readonly PrettyNameProvider _prettyName; private readonly AppService _appService; private readonly IFileService _fileService; @@ -99,7 +98,6 @@ namespace BTCPayServer.Controllers IAuthorizationService authorizationService, TransactionLinkProviders transactionLinkProviders, Dictionary paymentModelExtensions, - PaymentMethodViewProvider viewProvider, PrettyNameProvider prettyName) { _displayFormatter = displayFormatter; @@ -124,7 +122,6 @@ namespace BTCPayServer.Controllers _authorizationService = authorizationService; _transactionLinkProviders = transactionLinkProviders; _paymentModelExtensions = paymentModelExtensions; - _viewProvider = viewProvider; _prettyName = prettyName; _fileService = fileService; _uriResolver = uriResolver; diff --git a/BTCPayServer/Extensions.cs b/BTCPayServer/Extensions.cs index b270fe7ab..255f43db8 100644 --- a/BTCPayServer/Extensions.cs +++ b/BTCPayServer/Extensions.cs @@ -292,10 +292,9 @@ namespace BTCPayServer } - public static IServiceCollection AddUIExtension(this IServiceCollection services, string key, string partialView) + public static IServiceCollection AddUIExtension(this IServiceCollection services, string location, string partialViewName) { - services.AddSingleton(new UIExtension(partialView, - key)); + services.AddSingleton(new UIExtension(partialViewName, location)); return services; } public static IServiceCollection AddReportProvider(this IServiceCollection services) diff --git a/BTCPayServer/Hosting/BTCPayServerServices.cs b/BTCPayServer/Hosting/BTCPayServerServices.cs index 3fb78f7f6..ebf6f6369 100644 --- a/BTCPayServer/Hosting/BTCPayServerServices.cs +++ b/BTCPayServer/Hosting/BTCPayServerServices.cs @@ -158,8 +158,7 @@ namespace BTCPayServer.Hosting // AddOnchainWalletParsers(services); - services.AddSingleton(new UIExtension("Bitcoin/ViewBitcoinLikePaymentData", "store-invoices-payments")); - services.AddSingleton(new UIExtension("Lightning/ViewLightningLikePaymentData", "store-invoices-payments")); + services.AddStartupTask(); services.AddStartupTask(); @@ -367,6 +366,8 @@ namespace BTCPayServer.Hosting services.AddUIExtension("checkout-end", "Bitcoin/BitcoinLikeMethodCheckout"); services.AddUIExtension("checkout-end", "Lightning/LightningLikeMethodCheckout"); + services.AddUIExtension("store-invoices-payments", "Bitcoin/ViewBitcoinLikePaymentData"); + services.AddUIExtension("store-invoices-payments", "Lightning/ViewLightningLikePaymentData"); services.AddSingleton(); services.AddSingleton(o => o.GetRequiredService()); @@ -407,7 +408,6 @@ o.GetRequiredService>().ToDictionary(o => o.P services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); services.AddSingleton(); @@ -668,8 +668,6 @@ o.GetRequiredService>().ToDictionary(o => o.P (IPaymentLinkExtension)ActivatorUtilities.CreateInstance(provider, typeof(LNURLPayPaymentLinkExtension), new object[] { network, pmi })); services.AddSingleton(provider => (IPaymentModelExtension)ActivatorUtilities.CreateInstance(provider, typeof(LNURLPayPaymentModelExtension), new object[] { network, pmi })); - services.AddSingleton(provider => -(IPaymentMethodViewExtension)ActivatorUtilities.CreateInstance(provider, typeof(LNURLPaymentMethodViewExtension), new object[] { pmi })); services.AddSingleton(provider => (IPaymentMethodBitpayAPIExtension)ActivatorUtilities.CreateInstance(provider, typeof(LNURLPayPaymentMethodBitpayAPIExtension), new object[] { pmi })); } diff --git a/BTCPayServer/Models/InvoicingModels/InvoiceDetailsModel.cs b/BTCPayServer/Models/InvoicingModels/InvoiceDetailsModel.cs index 401456411..d62d6f6fd 100644 --- a/BTCPayServer/Models/InvoicingModels/InvoiceDetailsModel.cs +++ b/BTCPayServer/Models/InvoicingModels/InvoiceDetailsModel.cs @@ -136,5 +136,6 @@ namespace BTCPayServer.Models.InvoicingModels public bool HasRefund { get; set; } public bool StillDue { get; set; } public bool HasRates { get; set; } + public InvoiceEntity Entity { get; internal set; } } } diff --git a/BTCPayServer/Payments/IPaymentMethodViewExtension.cs b/BTCPayServer/Payments/IPaymentMethodViewExtension.cs deleted file mode 100644 index 72ad805b5..000000000 --- a/BTCPayServer/Payments/IPaymentMethodViewExtension.cs +++ /dev/null @@ -1,59 +0,0 @@ -#nullable enable -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using BTCPayServer.Services.Invoices; - -namespace BTCPayServer.Payments -{ - public interface IPaymentMethodViewExtension - { - PaymentMethodId PaymentMethodId { get; } - void RegisterViews(PaymentMethodViewContext context); - } - public record ViewViewModel(object View, object ViewModel); - public class PaymentMethodViewProvider - { - private readonly Dictionary _extensions; - private readonly PaymentMethodHandlerDictionary _handlers; - - public PaymentMethodViewProvider( - IEnumerable extensions, - PaymentMethodHandlerDictionary handlers) - { - _extensions = extensions.ToDictionary(o => o.PaymentMethodId, o => o); - _handlers = handlers; - } - public ViewViewModel? TryGetViewViewModel(PaymentPrompt paymentPrompt, string key) - { - if (!_extensions.TryGetValue(paymentPrompt.PaymentMethodId, out var extension)) - return null; - if (!_handlers.TryGetValue(paymentPrompt.PaymentMethodId, out var handler) || paymentPrompt.Details is null) - return null; - var ctx = new PaymentMethodViewContext() - { - Details = handler.ParsePaymentPromptDetails(paymentPrompt.Details) - }; - extension.RegisterViews(ctx); - object? view = null; - if (!ctx._Views.TryGetValue(key, out view)) - return null; - return new ViewViewModel(view, handler.ParsePaymentPromptDetails(paymentPrompt.Details)); - } - } - public class PaymentMethodViewContext - { - internal Dictionary _Views = new Dictionary(); - - public object? Details { get; internal set; } - - public void RegisterPaymentMethodDetails(string partialName) - { - _Views.Add("AdditionalPaymentMethodDetails", partialName); - } - public void Register(string key, object value) - { - _Views.Add(key, value); - } - } -} diff --git a/BTCPayServer/Payments/LNURLPay/LNURLPaymentMethodViewExtension.cs b/BTCPayServer/Payments/LNURLPay/LNURLPaymentMethodViewExtension.cs deleted file mode 100644 index d1677ec22..000000000 --- a/BTCPayServer/Payments/LNURLPay/LNURLPaymentMethodViewExtension.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace BTCPayServer.Payments.LNURLPay -{ - public class LNURLPaymentMethodViewExtension : IPaymentMethodViewExtension - { - public LNURLPaymentMethodViewExtension(PaymentMethodId paymentMethodId) - { - PaymentMethodId = paymentMethodId; - } - public PaymentMethodId PaymentMethodId { get; } - - public void RegisterViews(PaymentMethodViewContext context) - { - var details = context.Details; - if (details is not LNURLPayPaymentMethodDetails d) - return; - context.RegisterPaymentMethodDetails("LNURL/AdditionalPaymentMethodDetails"); - } - } -} diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs index 3bca13009..520e0e0b7 100644 --- a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs @@ -21,9 +21,9 @@ using Newtonsoft.Json.Linq; namespace BTCPayServer.Payments.Lightning { - public interface ILightningPaymentHandler : IHasNetwork + public interface ILightningPaymentHandler : IHasNetwork, IPaymentMethodHandler { - LightningPaymentData ParsePaymentDetails(JToken details); + new LightningPaymentData ParsePaymentDetails(JToken details); } public class LightningLikePaymentHandler : IPaymentMethodHandler, ILightningPaymentHandler { diff --git a/BTCPayServer/Views/Shared/Bitcoin/ViewBitcoinLikePaymentData.cshtml b/BTCPayServer/Views/Shared/Bitcoin/ViewBitcoinLikePaymentData.cshtml index d8978c28f..61c2273a4 100644 --- a/BTCPayServer/Views/Shared/Bitcoin/ViewBitcoinLikePaymentData.cshtml +++ b/BTCPayServer/Views/Shared/Bitcoin/ViewBitcoinLikePaymentData.cshtml @@ -7,10 +7,10 @@ @inject DisplayFormatter DisplayFormatter @inject TransactionLinkProviders TransactionLinkProviders @inject PaymentMethodHandlerDictionary handlers -@model IEnumerable +@model InvoiceDetailsModel @{ PayjoinInformation payjoinInformation = null; - var payments = Model + var payments = Model.Payments .Select(payment => { if (!handlers.TryGetValue(payment.PaymentMethodId, out var h) || h is not BitcoinLikePaymentHandler handler) diff --git a/BTCPayServer/Views/Shared/LNURL/AdditionalPaymentMethodDetails.cshtml b/BTCPayServer/Views/Shared/LNURL/AdditionalPaymentMethodDetails.cshtml deleted file mode 100644 index c3a93c5fa..000000000 --- a/BTCPayServer/Views/Shared/LNURL/AdditionalPaymentMethodDetails.cshtml +++ /dev/null @@ -1,18 +0,0 @@ -@model BTCPayServer.Payments.LNURLPayPaymentMethodDetails - -@if (!string.IsNullOrEmpty(Model.ProvidedComment)) -{ - - - LNURL Comment: @Model.ProvidedComment - - -} -@if (!string.IsNullOrEmpty(Model.ConsumedLightningAddress)) -{ - - - Lightning address used: @Model.ConsumedLightningAddress - - -} diff --git a/BTCPayServer/Views/Shared/Lightning/ViewLightningLikePaymentData.cshtml b/BTCPayServer/Views/Shared/Lightning/ViewLightningLikePaymentData.cshtml index c303a815a..9c3860e81 100644 --- a/BTCPayServer/Views/Shared/Lightning/ViewLightningLikePaymentData.cshtml +++ b/BTCPayServer/Views/Shared/Lightning/ViewLightningLikePaymentData.cshtml @@ -7,16 +7,31 @@ @inject DisplayFormatter DisplayFormatter @inject PaymentMethodHandlerDictionary handlers @inject PrettyNameProvider prettyName -@model IEnumerable +@model InvoiceDetailsModel @{ + string providedComment = null; + string consumedLightningAddress = null; var payments = Model + .Payments .Select(payment => { - + if (handlers.TryGet(payment.PaymentMethodId) is not ILightningPaymentHandler handler) return null; var offChainPaymentData = handler.ParsePaymentDetails(payment.Details); + + if (handler.ParsePaymentPromptDetails(Model.Entity.GetPaymentPrompt(payment.PaymentMethodId)?.Details) is LNURLPayPaymentMethodDetails lnurlPrompt) + { + if (lnurlPrompt.ConsumedLightningAddress is string consumed) + { + consumedLightningAddress = consumed; + } + if (lnurlPrompt.ProvidedComment is string comment) + { + providedComment = comment; + } + } return new OffChainPaymentViewModel { Type = prettyName.PrettyName(payment.PaymentMethodId), @@ -25,8 +40,8 @@ Amount = DisplayFormatter.Currency(payment.Value, handler.Network.CryptoCode, divisibility: payment.Divisibility) }; }) - .Where(model => model != null) - .ToList(); + .Where(model => model != null) + .ToList(); } @if (payments.Any()) @@ -37,7 +52,7 @@ - + @@ -61,6 +76,19 @@ }
TypeType Destination Payment Proof Paid
+ @if (!string.IsNullOrEmpty(providedComment)) + { +
+ LNURL Comment: @providedComment +
+ } + @if (!string.IsNullOrEmpty(consumedLightningAddress)) + { +
+ Lightning address used: @consumedLightningAddress +
+ } + } diff --git a/BTCPayServer/Views/UIInvoice/ListInvoicesPaymentsPartial.cshtml b/BTCPayServer/Views/UIInvoice/ListInvoicesPaymentsPartial.cshtml index 4b9d4f48f..37ec67b42 100644 --- a/BTCPayServer/Views/UIInvoice/ListInvoicesPaymentsPartial.cshtml +++ b/BTCPayServer/Views/UIInvoice/ListInvoicesPaymentsPartial.cshtml @@ -1,5 +1,4 @@ @using BTCPayServer.Payments -@inject PaymentMethodViewProvider paymentMethodViewProvider @model (InvoiceDetailsModel Invoice, bool ShowAddress) @{ var invoice = Model.Invoice; @@ -87,14 +86,10 @@ } - var vvm = paymentMethodViewProvider.TryGetViewViewModel(payment.PaymentMethodRaw, "AdditionalPaymentMethodDetails");; - if (vvm != null) - { - - } + } - +