diff --git a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs index d75c4a423..0c7d59099 100644 --- a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs @@ -79,6 +79,20 @@ namespace BTCPayServer.Payments.Bitcoin model.InvoiceBitcoinUrl = (cryptoInfo.PaymentUrls?.BIP21 ?? "") + lightningFallback; model.InvoiceBitcoinUrlQR = (cryptoInfo.PaymentUrls?.BIP21 ?? "") + lightningFallback .Replace("LIGHTNING=", "lightning=", StringComparison.OrdinalIgnoreCase); + + // Most wallets still don't support BITCOIN: schema, so we're leaving this for better days + // Ref: https://github.com/btcpayserver/btcpayserver/pull/2060#issuecomment-723828348 + //model.InvoiceBitcoinUrlQR = cryptoInfo.PaymentUrls.BIP21 + // .Replace("bitcoin:", "BITCOIN:", StringComparison.OrdinalIgnoreCase) + + // We're leading the way in Bitcoin community with adding UPPERCASE Bech32 addresses in QR Code + if (network.CryptoCode.Equals("BTC", StringComparison.InvariantCultureIgnoreCase) && _bech32Prefix.TryGetValue(model.CryptoCode, out var prefix) && model.BtcAddress.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) + { + model.InvoiceBitcoinUrlQR = model.InvoiceBitcoinUrlQR.Replace( + $"{network.NBitcoinNetwork.UriScheme}:{model.BtcAddress}", $"{network.NBitcoinNetwork.UriScheme}:{model.BtcAddress.ToUpperInvariant()}", + StringComparison.OrdinalIgnoreCase + ); + } } else { @@ -86,19 +100,7 @@ namespace BTCPayServer.Payments.Bitcoin model.InvoiceBitcoinUrlQR = ""; } - // Most wallets still don't support BITCOIN: schema, so we're leaving this for better days - // Ref: https://github.com/btcpayserver/btcpayserver/pull/2060#issuecomment-723828348 - //model.InvoiceBitcoinUrlQR = cryptoInfo.PaymentUrls.BIP21 - // .Replace("bitcoin:", "BITCOIN:", StringComparison.OrdinalIgnoreCase) - - // We're leading the way in Bitcoin community with adding UPPERCASE Bech32 addresses in QR Code - if (network.CryptoCode.Equals("BTC", StringComparison.InvariantCultureIgnoreCase) && _bech32Prefix.TryGetValue(model.CryptoCode, out var prefix) && model.BtcAddress.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - { - model.InvoiceBitcoinUrlQR = model.InvoiceBitcoinUrlQR.Replace( - $"{network.NBitcoinNetwork.UriScheme}:{model.BtcAddress}", $"{network.NBitcoinNetwork.UriScheme}:{model.BtcAddress.ToUpperInvariant()}", - StringComparison.OrdinalIgnoreCase - ); - } + } public override string GetCryptoImage(PaymentMethodId paymentMethodId) @@ -155,6 +157,19 @@ namespace BTCPayServer.Payments.Bitcoin DerivationSchemeSettings supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network, object preparePaymentObject, IEnumerable invoicePaymentMethods) { + + if (!_ExplorerProvider.IsAvailable(network)) + throw new PaymentMethodUnavailableException($"Full node not available"); + if (paymentMethod.ParentEntity.Type != InvoiceType.TopUp) + { + var txOut = network.NBitcoinNetwork.Consensus.ConsensusFactory.CreateTxOut(); + txOut.ScriptPubKey = + new Key().GetScriptPubKey(supportedPaymentMethod.AccountDerivation.ScriptPubKeyType()); + var dust = txOut.GetDustThreshold(); + var amount = paymentMethod.Calculate().Due; + if (amount < dust) + throw new PaymentMethodUnavailableException("Amount below the dust threshold. For amounts of this size, it is recommended to enable an off-chain (Lightning) payment method"); + } if (preparePaymentObject is null) { return new BitcoinLikeOnChainPaymentMethod() @@ -162,8 +177,6 @@ namespace BTCPayServer.Payments.Bitcoin Activated = false }; } - if (!_ExplorerProvider.IsAvailable(network)) - throw new PaymentMethodUnavailableException($"Full node not available"); var prepare = (Prepare)preparePaymentObject; var onchainMethod = new BitcoinLikeOnChainPaymentMethod(); var blob = store.GetStoreBlob(); @@ -190,15 +203,7 @@ namespace BTCPayServer.Payments.Bitcoin } var reserved = await prepare.ReserveAddress; - if (paymentMethod.ParentEntity.Type != InvoiceType.TopUp) - { - var txOut = network.NBitcoinNetwork.Consensus.ConsensusFactory.CreateTxOut(); - txOut.ScriptPubKey = reserved.Address.ScriptPubKey; - var dust = txOut.GetDustThreshold(); - var amount = paymentMethod.Calculate().Due; - if (amount < dust) - throw new PaymentMethodUnavailableException("Amount below the dust threshold. For amounts of this size, it is recommended to enable an off-chain (Lightning) payment method"); - } + onchainMethod.DepositAddress = reserved.Address.ToString(); onchainMethod.KeyPath = reserved.KeyPath; onchainMethod.PayjoinEnabled = blob.PayJoinEnabled &&