Ensure that there is no LN/Bitcoin specific logic in the Invoice UI endpoint

This commit is contained in:
Kukks 2020-11-06 11:09:17 +01:00
parent a729dd1380
commit e021d42551
11 changed files with 35 additions and 45 deletions

View file

@ -875,7 +875,7 @@ normal:
var paymentMethodHandlerDictionary = new PaymentMethodHandlerDictionary(new IPaymentMethodHandler[]
{
new BitcoinLikePaymentHandler(null, networkProvider, null, null, null),
new LightningLikePaymentHandler(null, null, networkProvider, null),
new LightningLikePaymentHandler(null, null, networkProvider, null, null),
});
var networkBTC = networkProvider.GetNetwork("BTC");
var networkLTC = networkProvider.GetNetwork("LTC");

View file

@ -364,7 +364,7 @@ namespace BTCPayServer.Tests
var paymentMethodHandlerDictionary = new PaymentMethodHandlerDictionary(new IPaymentMethodHandler[]
{
new BitcoinLikePaymentHandler(null, networkProvider, null, null, null),
new LightningLikePaymentHandler(null, null, networkProvider, null),
new LightningLikePaymentHandler(null, null, networkProvider, null, null),
});
var entity = new InvoiceEntity();
entity.Networks = networkProvider;
@ -563,7 +563,7 @@ namespace BTCPayServer.Tests
var paymentMethodHandlerDictionary = new PaymentMethodHandlerDictionary(new IPaymentMethodHandler[]
{
new BitcoinLikePaymentHandler(null, networkProvider, null, null, null),
new LightningLikePaymentHandler(null, null, networkProvider, null),
new LightningLikePaymentHandler(null, null, networkProvider, null, null),
});
var entity = new InvoiceEntity();
entity.Networks = networkProvider;

View file

@ -464,12 +464,9 @@ namespace BTCPayServer.Controllers
var paymentMethod = invoice.GetPaymentMethod(paymentMethodId);
var paymentMethodDetails = paymentMethod.GetPaymentMethodDetails();
var dto = invoice.EntityToDTO();
var cryptoInfo = dto.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
var storeBlob = store.GetStoreBlob();
var currency = invoice.Currency;
var accounting = paymentMethod.Calculate();
CoinSwitchSettings coinswitch = (storeBlob.CoinSwitchSettings != null && storeBlob.CoinSwitchSettings.Enabled &&
storeBlob.CoinSwitchSettings.IsConfigured())
? storeBlob.CoinSwitchSettings
@ -492,12 +489,11 @@ namespace BTCPayServer.Controllers
CryptoImage = Request.GetRelativePathOrAbsolute(paymentMethodHandler.GetCryptoImage(paymentMethodId)),
BtcAddress = paymentMethodDetails.GetPaymentDestination(),
BtcDue = accounting.Due.ShowMoney(divisibility),
InvoiceCurrency = invoice.Currency,
OrderAmount = (accounting.TotalDue - accounting.NetworkFee).ShowMoney(divisibility),
OrderAmountFiat = OrderAmountFromInvoice(network.CryptoCode, invoice),
CustomerEmail = invoice.RefundMail,
RequiresRefundEmail = storeBlob.RequiresRefundEmail,
ShowRecommendedFee = storeBlob.ShowRecommendedFee,
FeeRate = paymentMethodDetails.GetFeeRate(),
ExpirationSeconds = Math.Max(0, (int)(invoice.ExpirationTime - DateTimeOffset.UtcNow).TotalSeconds),
MaxTimeSeconds = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalSeconds,
MaxTimeMinutes = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalMinutes,
@ -506,7 +502,6 @@ namespace BTCPayServer.Controllers
MerchantRefLink = invoice.RedirectURL?.AbsoluteUri ?? "/",
RedirectAutomatically = invoice.RedirectAutomatically,
StoreName = store.StoreName,
PeerInfo = (paymentMethodDetails as LightningLikePaymentMethodDetails)?.NodeInfo,
TxCount = accounting.TxRequired,
BtcPaid = accounting.Paid.ShowMoney(divisibility),
#pragma warning disable CS0618 // Type or member is obsolete
@ -544,12 +539,7 @@ namespace BTCPayServer.Controllers
.OrderByDescending(a => a.CryptoCode == "BTC").ThenBy(a => a.PaymentMethodName).ThenBy(a => a.IsLightning ? 1 : 0)
.ToList()
};
paymentMethodHandler.PreparePaymentModel(model, dto, storeBlob);
if (model.IsLightning && storeBlob.LightningAmountInSatoshi && model.CryptoCode == "Sats")
{
model.Rate = _CurrencyNameTable.DisplayFormatCurrency(paymentMethod.Rate / 100_000_000, paymentMethod.ParentEntity.Currency);
}
paymentMethodHandler.PreparePaymentModel(model, dto, storeBlob, paymentMethod);
model.UISettings = paymentMethodHandler.GetCheckoutUISettings();
model.PaymentMethodId = paymentMethodId.ToString();
var expiration = TimeSpan.FromSeconds(model.ExpirationSeconds);

View file

@ -25,10 +25,8 @@ namespace BTCPayServer.Models.InvoicingModels
public string CustomLogoLink { get; set; }
public string HtmlTitle { get; set; }
public string DefaultLang { get; set; }
public bool LightningAmountInSatoshi { get; set; }
public List<AvailableCrypto> AvailableCryptos { get; set; } = new List<AvailableCrypto>();
public bool IsModal { get; set; }
public bool IsLightning { get; set; }
public string CryptoCode { get; set; }
public string InvoiceId { get; set; }
public string BtcAddress { get; set; }
@ -71,5 +69,6 @@ namespace BTCPayServer.Models.InvoicingModels
public string RootPath { get; set; }
public decimal CoinSwitchAmountMarkupPercentage { get; set; }
public bool RedirectAutomatically { get; set; }
public string InvoiceCurrency { get; set; }
}
}

View file

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -8,10 +7,8 @@ using BTCPayServer.HostedServices;
using BTCPayServer.Logging;
using BTCPayServer.Models;
using BTCPayServer.Models.InvoicingModels;
using BTCPayServer.Rating;
using BTCPayServer.Services;
using BTCPayServer.Services.Invoices;
using BTCPayServer.Services.Rates;
using NBitcoin;
using NBXplorer.Models;
using StoreData = BTCPayServer.Data.StoreData;
@ -47,13 +44,13 @@ namespace BTCPayServer.Payments.Bitcoin
}
public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
StoreBlob storeBlob)
StoreBlob storeBlob, IPaymentMethod paymentMethod)
{
var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentTypes.BTCLike);
var paymentMethodId = paymentMethod.GetId();
var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
var network = _networkProvider.GetNetwork<BTCPayNetwork>(model.CryptoCode);
model.IsLightning = false;
model.ShowRecommendedFee = storeBlob.ShowRecommendedFee;
model.FeeRate = ((BitcoinLikeOnChainPaymentMethod) paymentMethod.GetPaymentMethodDetails()).GetFeeRate();
model.PaymentMethodName = GetPaymentMethodName(network);
model.InvoiceBitcoinUrl = cryptoInfo.PaymentUrls.BIP21;
model.InvoiceBitcoinUrlQR = cryptoInfo.PaymentUrls.BIP21;

View file

@ -16,10 +16,5 @@ namespace BTCPayServer.Payments
/// </summary>
/// <returns></returns>
decimal GetNextNetworkFee();
/// <summary>
/// Returns recommended fee rate for a transaction
/// </summary>
/// <returns></returns>
decimal GetFeeRate();
}
}

View file

@ -38,7 +38,8 @@ namespace BTCPayServer.Payments
/// <returns></returns>
object PreparePayment(ISupportedPaymentMethod supportedPaymentMethod, StoreData store, BTCPayNetworkBase network);
void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, StoreBlob storeBlob);
void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, StoreBlob storeBlob,
IPaymentMethod paymentMethod);
string GetCryptoImage(PaymentMethodId paymentMethodId);
string GetPaymentMethodName(PaymentMethodId paymentMethodId);
@ -67,7 +68,7 @@ namespace BTCPayServer.Payments
PaymentMethod paymentMethod, StoreData store, TBTCPayNetwork network, object preparePaymentObject);
public abstract void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
StoreBlob storeBlob);
StoreBlob storeBlob, IPaymentMethod paymentMethod);
public abstract string GetCryptoImage(PaymentMethodId paymentMethodId);
public abstract string GetPaymentMethodName(PaymentMethodId paymentMethodId);

View file

@ -25,17 +25,20 @@ namespace BTCPayServer.Payments.Lightning
private readonly LightningClientFactoryService _lightningClientFactory;
private readonly BTCPayNetworkProvider _networkProvider;
private readonly SocketFactory _socketFactory;
private readonly CurrencyNameTable _currencyNameTable;
public LightningLikePaymentHandler(
NBXplorerDashboard dashboard,
LightningClientFactoryService lightningClientFactory,
BTCPayNetworkProvider networkProvider,
SocketFactory socketFactory)
SocketFactory socketFactory,
CurrencyNameTable currencyNameTable)
{
_Dashboard = dashboard;
_lightningClientFactory = lightningClientFactory;
_networkProvider = networkProvider;
_socketFactory = socketFactory;
_currencyNameTable = currencyNameTable;
}
public override PaymentType PaymentType => PaymentTypes.LightningLike;
@ -159,28 +162,27 @@ namespace BTCPayServer.Payments.Lightning
}
public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
StoreBlob storeBlob)
StoreBlob storeBlob, IPaymentMethod paymentMethod)
{
var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentTypes.LightningLike);
var paymentMethodId = paymentMethod.GetId();
var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
var network = _networkProvider.GetNetwork<BTCPayNetwork>(model.CryptoCode);
model.IsLightning = true;
model.PaymentMethodName = GetPaymentMethodName(network);
model.InvoiceBitcoinUrl = cryptoInfo.PaymentUrls.BOLT11;
model.InvoiceBitcoinUrlQR = $"lightning:{cryptoInfo.PaymentUrls.BOLT11.ToUpperInvariant().Substring("LIGHTNING:".Length)}";
model.LightningAmountInSatoshi = storeBlob.LightningAmountInSatoshi;
model.PeerInfo = ((LightningLikePaymentMethodDetails) paymentMethod.GetPaymentMethodDetails()).NodeInfo;
if (storeBlob.LightningAmountInSatoshi && model.CryptoCode == "BTC")
{
var satoshiCulture = new CultureInfo(CultureInfo.InvariantCulture.Name);
satoshiCulture.NumberFormat.NumberGroupSeparator = " ";
model.CryptoCode = "Sats";
model.BtcDue = Money.Parse(model.BtcDue).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture);
model.BtcPaid = Money.Parse(model.BtcPaid).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture);
model.OrderAmount = Money.Parse(model.OrderAmount).ToUnit(MoneyUnit.Satoshi).ToString("N0", satoshiCulture);
model.NetworkFee = new Money(model.NetworkFee, MoneyUnit.BTC).ToUnit(MoneyUnit.Satoshi);
model.Rate = _currencyNameTable.DisplayFormatCurrency(paymentMethod.Rate / 100_000_000, model.InvoiceCurrency);
}
}
public override string GetCryptoImage(PaymentMethodId paymentMethodId)

View file

@ -71,12 +71,11 @@ namespace BTCPayServer.Services.Altcoins.Ethereum.Payments
}
public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
StoreBlob storeBlob)
StoreBlob storeBlob, IPaymentMethod paymentMethod)
{
var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentType);
var paymentMethodId = paymentMethod.GetId();
var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
var network = _networkProvider.GetNetwork<EthereumBTCPayNetwork>(model.CryptoCode);
model.IsLightning = false;
model.PaymentMethodName = GetPaymentMethodName(network);
model.CryptoImage = GetCryptoImage(network);
model.InvoiceBitcoinUrl = "";

View file

@ -73,12 +73,12 @@ namespace BTCPayServer.Services.Altcoins.Monero.Payments
public Func<string, Task<CreateAddressResponse>> ReserveAddress;
}
public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse, StoreBlob storeBlob)
public override void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse,
StoreBlob storeBlob, IPaymentMethod paymentMethod)
{
var paymentMethodId = new PaymentMethodId(model.CryptoCode, PaymentType);
var paymentMethodId = paymentMethod.GetId();
var cryptoInfo = invoiceResponse.CryptoInfo.First(o => o.GetpaymentMethodId() == paymentMethodId);
var network = _networkProvider.GetNetwork<MoneroLikeSpecificBtcPayNetwork>(model.CryptoCode);
model.IsLightning = false;
model.PaymentMethodName = GetPaymentMethodName(network);
model.CryptoImage = GetCryptoImage(network);
model.InvoiceBitcoinUrl = MoneroPaymentType.Instance.GetPaymentLink(network, new MoneroLikeOnChainPaymentMethodDetails()

View file

@ -908,7 +908,14 @@ namespace BTCPayServer.Services.Invoices
public Money MinimumTotalDue { get; set; }
}
public class PaymentMethod
public interface IPaymentMethod
{
PaymentMethodId GetId();
decimal Rate { get; set; }
IPaymentMethodDetails GetPaymentMethodDetails();
}
public class PaymentMethod : IPaymentMethod
{
[JsonIgnore]
public InvoiceEntity ParentEntity { get; set; }