From 54c7c0d696691f2ee9790220a2a4547db2689b1b Mon Sep 17 00:00:00 2001 From: Andrew Camilleri Date: Tue, 21 Jan 2020 14:28:13 +0100 Subject: [PATCH] Add currency precision based on network (#1294) --- .../Altcoins/Liquid/ElementsLikeBtcPayNetwork.cs | 10 +++++----- .../Altcoins/Monero/BTCPayNetworkProvider.Monero.cs | 1 + BTCPayServer.Common/BTCPayNetwork.cs | 6 +++--- .../Lightning/LightningLikePaymentHandler.cs | 2 +- BTCPayServer/Payments/PaymentTypes.cs | 1 - BTCPayServer/Services/Invoices/InvoiceEntity.cs | 12 ++++++------ BTCPayServer/Services/Rates/CurrencyNameTable.cs | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/BTCPayServer.Common/Altcoins/Liquid/ElementsLikeBtcPayNetwork.cs b/BTCPayServer.Common/Altcoins/Liquid/ElementsLikeBtcPayNetwork.cs index dc0d789ed..8ab4dc883 100644 --- a/BTCPayServer.Common/Altcoins/Liquid/ElementsLikeBtcPayNetwork.cs +++ b/BTCPayServer.Common/Altcoins/Liquid/ElementsLikeBtcPayNetwork.cs @@ -6,16 +6,16 @@ using NBXplorer.Models; namespace BTCPayServer { - public class ElementsBTCPayNetwork:BTCPayNetwork + public class ElementsBTCPayNetwork : BTCPayNetwork { public string NetworkCryptoCode { get; set; } public uint256 AssetId { get; set; } public override bool ReadonlyWallet { get; set; } = true; - public int Divisibility { get; set; } = 8; - public override IEnumerable<(MatchedOutput matchedOutput, OutPoint outPoint)> GetValidOutputs(NewTransactionEvent evtOutputs) + public override IEnumerable<(MatchedOutput matchedOutput, OutPoint outPoint)> GetValidOutputs( + NewTransactionEvent evtOutputs) { - return evtOutputs.Outputs.Where(output => + return evtOutputs.Outputs.Where(output => output.Value is AssetMoney assetMoney && assetMoney.AssetId == AssetId).Select(output => { var outpoint = new OutPoint(evtOutputs.TransactionData.TransactionHash, output.Index); @@ -23,7 +23,7 @@ namespace BTCPayServer }); } - public override string GenerateBIP21(string cryptoInfoAddress, string cryptoInfoDue) + public override string GenerateBIP21(string cryptoInfoAddress, Money cryptoInfoDue) { return $"{base.GenerateBIP21(cryptoInfoAddress, cryptoInfoDue)}&assetid={AssetId}"; } diff --git a/BTCPayServer.Common/Altcoins/Monero/BTCPayNetworkProvider.Monero.cs b/BTCPayServer.Common/Altcoins/Monero/BTCPayNetworkProvider.Monero.cs index f81731ff0..012c4bdd3 100644 --- a/BTCPayServer.Common/Altcoins/Monero/BTCPayNetworkProvider.Monero.cs +++ b/BTCPayServer.Common/Altcoins/Monero/BTCPayNetworkProvider.Monero.cs @@ -10,6 +10,7 @@ namespace BTCPayServer { CryptoCode = "XMR", DisplayName = "Monero", + Divisibility = 12, BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://www.exploremonero.com/transaction/{0}" diff --git a/BTCPayServer.Common/BTCPayNetwork.cs b/BTCPayServer.Common/BTCPayNetwork.cs index 2b67edfc8..6c71a8a2f 100644 --- a/BTCPayServer.Common/BTCPayNetwork.cs +++ b/BTCPayServer.Common/BTCPayNetwork.cs @@ -113,9 +113,9 @@ namespace BTCPayServer }); } - public virtual string GenerateBIP21(string cryptoInfoAddress, string cryptoInfoDue) + public virtual string GenerateBIP21(string cryptoInfoAddress, Money cryptoInfoDue) { - return $"{UriScheme}:{cryptoInfoAddress}?amount={cryptoInfoDue}"; + return $"{UriScheme}:{cryptoInfoAddress}?amount={cryptoInfoDue.ToString(false, true)}"; } } @@ -124,7 +124,7 @@ namespace BTCPayServer public string CryptoCode { get; internal set; } public string BlockExplorerLink { get; internal set; } public string DisplayName { get; set; } - + public int Divisibility { get; set; } = 8; [Obsolete("Should not be needed")] public bool IsBTC { diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs index ca085c4f6..ea3546b6e 100644 --- a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs @@ -47,7 +47,7 @@ namespace BTCPayServer.Payments.Lightning var storeBlob = store.GetStoreBlob(); var test = GetNodeInfo(paymentMethod.PreferOnion, supportedPaymentMethod, (BTCPayNetwork)network); var invoice = paymentMethod.ParentEntity; - var due = Extensions.RoundUp(invoice.ProductInformation.Price / paymentMethod.Rate, 8); + var due = Extensions.RoundUp(invoice.ProductInformation.Price / paymentMethod.Rate, network.Divisibility); var client = _lightningClientFactory.Create(supportedPaymentMethod.GetLightningUrl(), (BTCPayNetwork)network); var expiry = invoice.ExpirationTime - DateTimeOffset.UtcNow; if (expiry < TimeSpan.Zero) diff --git a/BTCPayServer/Payments/PaymentTypes.cs b/BTCPayServer/Payments/PaymentTypes.cs index 524099274..bb5088bc9 100644 --- a/BTCPayServer/Payments/PaymentTypes.cs +++ b/BTCPayServer/Payments/PaymentTypes.cs @@ -64,7 +64,6 @@ namespace BTCPayServer.Payments public abstract string SerializePaymentData(BTCPayNetworkBase network, CryptoPaymentData paymentData); public abstract IPaymentMethodDetails DeserializePaymentMethodDetails(string str); public abstract ISupportedPaymentMethod DeserializeSupportedPaymentMethod(BTCPayNetworkBase network, JToken value); - public abstract string GetTransactionLink(BTCPayNetworkBase network, string txId); public abstract string InvoiceViewPaymentPartialName { get; } } diff --git a/BTCPayServer/Services/Invoices/InvoiceEntity.cs b/BTCPayServer/Services/Invoices/InvoiceEntity.cs index 181faa637..5576eed58 100644 --- a/BTCPayServer/Services/Invoices/InvoiceEntity.cs +++ b/BTCPayServer/Services/Invoices/InvoiceEntity.cs @@ -847,7 +847,7 @@ namespace BTCPayServer.Services.Invoices var paid = 0m; var cryptoPaid = 0.0m; - int precision = 8; + int precision = Network?.Divisibility ?? 8; var totalDueNoNetworkCost = Money.Coins(Extensions.RoundUp(totalDue, precision)); bool paidEnough = paid >= Extensions.RoundUp(totalDue, precision); int txRequired = 0; @@ -857,8 +857,8 @@ namespace BTCPayServer.Services.Invoices .OrderBy(p => p.ReceivedTime) .Select(_ => { - var txFee = _.GetValue(paymentMethods, GetId(), _.NetworkFee); - paid += _.GetValue(paymentMethods, GetId()); + var txFee = _.GetValue(paymentMethods, GetId(), _.NetworkFee, precision); + paid += _.GetValue(paymentMethods, GetId(), null, precision); if (!paidEnough) { totalDue += txFee; @@ -991,18 +991,18 @@ namespace BTCPayServer.Services.Invoices #pragma warning restore CS0618 return this; } - internal decimal GetValue(PaymentMethodDictionary paymentMethods, PaymentMethodId paymentMethodId, decimal? value = null) + internal decimal GetValue(PaymentMethodDictionary paymentMethods, PaymentMethodId paymentMethodId, decimal? value, int precision) { value = value ?? this.GetCryptoPaymentData().GetValue(); var to = paymentMethodId; var from = this.GetPaymentMethodId(); if (to == from) - return decimal.Round(value.Value, 8); + return decimal.Round(value.Value, precision); var fromRate = paymentMethods[from].Rate; var toRate = paymentMethods[to].Rate; - var fiatValue = fromRate * decimal.Round(value.Value, 8); + var fiatValue = fromRate * decimal.Round(value.Value, precision); var otherCurrencyValue = toRate == 0 ? 0.0m : fiatValue / toRate; return otherCurrencyValue; } diff --git a/BTCPayServer/Services/Rates/CurrencyNameTable.cs b/BTCPayServer/Services/Rates/CurrencyNameTable.cs index ee3a72a09..78362bd34 100644 --- a/BTCPayServer/Services/Rates/CurrencyNameTable.cs +++ b/BTCPayServer/Services/Rates/CurrencyNameTable.cs @@ -96,7 +96,7 @@ namespace BTCPayServer.Services.Rates foreach (var network in new BTCPayNetworkProvider(NetworkType.Mainnet).GetAll()) { - AddCurrency(_CurrencyProviders, network.CryptoCode, 8, network.CryptoCode); + AddCurrency(_CurrencyProviders, network.CryptoCode, network.Divisibility, network.CryptoCode); } } return _CurrencyProviders.TryGet(currency.ToUpperInvariant()); @@ -180,7 +180,7 @@ namespace BTCPayServer.Services.Rates if (!dico.TryAdd(network.CryptoCode, new CurrencyData() { Code = network.CryptoCode, - Divisibility = 8, + Divisibility = network.Divisibility, Name = network.CryptoCode, Crypto = true }))