mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 22:14:26 +01:00
Use PaymentUrlBuilder for ensuring proper formatting of BIP21 addresses (#2723)
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#if ALTCOINS
|
#if ALTCOINS
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using BTCPayServer.Common;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBXplorer;
|
using NBXplorer;
|
||||||
using NBXplorer.Models;
|
using NBXplorer.Models;
|
||||||
@@ -33,13 +34,15 @@ namespace BTCPayServer
|
|||||||
output.Value is AssetMoney assetMoney && assetMoney.AssetId == AssetId));
|
output.Value is AssetMoney assetMoney && assetMoney.AssetId == AssetId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GenerateBIP21(string cryptoInfoAddress, Money cryptoInfoDue)
|
public override PaymentUrlBuilder GenerateBIP21(string cryptoInfoAddress, Money cryptoInfoDue)
|
||||||
{
|
{
|
||||||
//precision 0: 10 = 0.00000010
|
//precision 0: 10 = 0.00000010
|
||||||
//precision 2: 10 = 0.00001000
|
//precision 2: 10 = 0.00001000
|
||||||
//precision 8: 10 = 10
|
//precision 8: 10 = 10
|
||||||
var money = cryptoInfoDue is null ? null : new Money(cryptoInfoDue.ToDecimal(MoneyUnit.BTC) / decimal.Parse("1".PadRight(1 + 8 - Divisibility, '0')), MoneyUnit.BTC);
|
var money = cryptoInfoDue is null ? null : new Money(cryptoInfoDue.ToDecimal(MoneyUnit.BTC) / decimal.Parse("1".PadRight(1 + 8 - Divisibility, '0')), MoneyUnit.BTC);
|
||||||
return $"{base.GenerateBIP21(cryptoInfoAddress, money)}{(money is null? "?": "&")}assetid={AssetId}";
|
var builder = base.GenerateBIP21(cryptoInfoAddress, money);
|
||||||
|
builder.QueryParams.Add("assetid", AssetId.ToString());
|
||||||
|
return builder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using BTCPayServer.Common;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBXplorer;
|
using NBXplorer;
|
||||||
using NBXplorer.Models;
|
using NBXplorer.Models;
|
||||||
@@ -121,9 +122,15 @@ namespace BTCPayServer
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string GenerateBIP21(string cryptoInfoAddress, Money cryptoInfoDue)
|
public virtual PaymentUrlBuilder GenerateBIP21(string cryptoInfoAddress, Money cryptoInfoDue)
|
||||||
{
|
{
|
||||||
return $"{UriScheme}:{cryptoInfoAddress}{(cryptoInfoDue is null? string.Empty: $"?amount={cryptoInfoDue.ToString(false, true)}")}";
|
var builder = new PaymentUrlBuilder(UriScheme);
|
||||||
|
builder.Host = cryptoInfoAddress;
|
||||||
|
if (cryptoInfoDue != null && cryptoInfoDue != Money.Zero)
|
||||||
|
{
|
||||||
|
builder.QueryParams.Add("amount", cryptoInfoDue.ToString(false, true));
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual List<TransactionInformation> FilterValidTransactions(List<TransactionInformation> transactionInformationSet)
|
public virtual List<TransactionInformation> FilterValidTransactions(List<TransactionInformation> transactionInformationSet)
|
||||||
|
|||||||
30
BTCPayServer.Common/PaymentUrlBuilder.cs
Normal file
30
BTCPayServer.Common/PaymentUrlBuilder.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Common
|
||||||
|
{
|
||||||
|
public class PaymentUrlBuilder
|
||||||
|
{
|
||||||
|
public PaymentUrlBuilder(string uriScheme)
|
||||||
|
{
|
||||||
|
UriScheme = uriScheme;
|
||||||
|
}
|
||||||
|
public string UriScheme { get; set; }
|
||||||
|
public Dictionary<string, string> QueryParams { get; set; } = new Dictionary<string, string>();
|
||||||
|
public string? Host { get; set; }
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder($"{UriScheme}:{Host}");
|
||||||
|
if (QueryParams.Count != 0)
|
||||||
|
{
|
||||||
|
var parts = QueryParams.Select(q => Uri.EscapeDataString(q.Key) + "=" + System.Web.NBitcoin.HttpUtility.UrlEncode(q.Value))
|
||||||
|
.ToArray();
|
||||||
|
builder.Append($"?{string.Join('&', parts)}");
|
||||||
|
}
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -127,17 +127,16 @@ namespace BTCPayServer.Controllers.GreenField
|
|||||||
return BadRequest();
|
return BadRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
var bip21 = network.GenerateBIP21(kpi.Address.ToString(), null);
|
var bip21 = network.GenerateBIP21(kpi.Address?.ToString(), null);
|
||||||
var allowedPayjoin = derivationScheme.IsHotWallet && Store.GetStoreBlob().PayJoinEnabled;
|
var allowedPayjoin = derivationScheme.IsHotWallet && Store.GetStoreBlob().PayJoinEnabled;
|
||||||
if (allowedPayjoin)
|
if (allowedPayjoin)
|
||||||
{
|
{
|
||||||
bip21 +=
|
bip21.QueryParams.Add(PayjoinClient.BIP21EndpointKey, Request.GetAbsoluteUri(Url.Action(nameof(PayJoinEndpointController.Submit), "PayJoinEndpoint", new { cryptoCode })));
|
||||||
$"?{PayjoinClient.BIP21EndpointKey}={Request.GetAbsoluteUri(Url.Action(nameof(PayJoinEndpointController.Submit), "PayJoinEndpoint", new {cryptoCode}))}";
|
|
||||||
}
|
}
|
||||||
return Ok(new OnChainWalletAddressData()
|
return Ok(new OnChainWalletAddressData()
|
||||||
{
|
{
|
||||||
Address = kpi.Address.ToString(),
|
Address = kpi.Address?.ToString(),
|
||||||
PaymentLink = bip21,
|
PaymentLink = bip21.ToString(),
|
||||||
KeyPath = kpi.KeyPath
|
KeyPath = kpi.KeyPath
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||||||
using BTCPayServer.Abstractions.Extensions;
|
using BTCPayServer.Abstractions.Extensions;
|
||||||
using BTCPayServer.Abstractions.Models;
|
using BTCPayServer.Abstractions.Models;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
using BTCPayServer.Common;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.HostedServices;
|
using BTCPayServer.HostedServices;
|
||||||
using BTCPayServer.ModelBinders;
|
using BTCPayServer.ModelBinders;
|
||||||
@@ -285,7 +286,7 @@ namespace BTCPayServer.Controllers
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var blob = payout.GetBlob(_jsonSerializerSettings);
|
var blob = payout.GetBlob(_jsonSerializerSettings);
|
||||||
bip21.Add(network.GenerateBIP21(payout.Destination, new Money(blob.CryptoAmount.Value, MoneyUnit.BTC)));
|
bip21.Add(network.GenerateBIP21(payout.Destination, new Money(blob.CryptoAmount.Value, MoneyUnit.BTC)).ToString());
|
||||||
|
|
||||||
}
|
}
|
||||||
if(bip21.Any())
|
if(bip21.Any())
|
||||||
|
|||||||
@@ -368,18 +368,17 @@ namespace BTCPayServer.Controllers
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
var address = _walletReceiveService.Get(walletId)?.Address;
|
var address = _walletReceiveService.Get(walletId)?.Address;
|
||||||
var allowedPayjoin = paymentMethod.IsHotWallet && CurrentStore.GetStoreBlob().PayJoinEnabled;
|
var allowedPayjoin = paymentMethod.IsHotWallet && CurrentStore.GetStoreBlob().PayJoinEnabled;
|
||||||
var bip21 = address is null ? null : network.GenerateBIP21(address.ToString(), null);
|
var bip21 = network.GenerateBIP21(address?.ToString(), null);
|
||||||
if (allowedPayjoin)
|
if (allowedPayjoin)
|
||||||
{
|
{
|
||||||
bip21 +=
|
bip21.QueryParams.Add(PayjoinClient.BIP21EndpointKey, Request.GetAbsoluteUri(Url.Action(nameof(PayJoinEndpointController.Submit), "PayJoinEndpoint", new { walletId.CryptoCode })));
|
||||||
$"?{PayjoinClient.BIP21EndpointKey}={Request.GetAbsoluteUri(Url.Action(nameof(PayJoinEndpointController.Submit), "PayJoinEndpoint", new {walletId.CryptoCode}))}";
|
|
||||||
}
|
}
|
||||||
return View(new WalletReceiveViewModel()
|
return View(new WalletReceiveViewModel()
|
||||||
{
|
{
|
||||||
CryptoCode = walletId.CryptoCode,
|
CryptoCode = walletId.CryptoCode,
|
||||||
Address = address?.ToString(),
|
Address = address?.ToString(),
|
||||||
CryptoImage = GetImage(paymentMethod.PaymentId, network),
|
CryptoImage = GetImage(paymentMethod.PaymentId, network),
|
||||||
PaymentLink = bip21
|
PaymentLink = bip21.ToString()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,9 +79,9 @@ namespace BTCPayServer.Payments
|
|||||||
|
|
||||||
if ((paymentMethodDetails as BitcoinLikeOnChainPaymentMethod)?.PayjoinEnabled is true && serverUri != null)
|
if ((paymentMethodDetails as BitcoinLikeOnChainPaymentMethod)?.PayjoinEnabled is true && serverUri != null)
|
||||||
{
|
{
|
||||||
bip21 += $"&{PayjoinClient.BIP21EndpointKey}={serverUri.WithTrailingSlash()}{network.CryptoCode}/{PayjoinClient.BIP21EndpointKey}";
|
bip21.QueryParams.Add(PayjoinClient.BIP21EndpointKey, $"{serverUri.WithTrailingSlash()}{network.CryptoCode}/{PayjoinClient.BIP21EndpointKey}");
|
||||||
}
|
}
|
||||||
return bip21;
|
return bip21.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string InvoiceViewPaymentPartialName { get; } = "Bitcoin/ViewBitcoinLikePaymentData";
|
public override string InvoiceViewPaymentPartialName { get; } = "Bitcoin/ViewBitcoinLikePaymentData";
|
||||||
|
|||||||
Reference in New Issue
Block a user