mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-10 09:34:30 +01:00
Merge pull request #1046 from Kukks/pre-monero
General optimizations and fixes
This commit is contained in:
@@ -54,7 +54,8 @@ namespace BTCPayServer
|
||||
public KeyPath CoinType { get; internal set; }
|
||||
public Dictionary<uint, DerivationType> ElectrumMapping = new Dictionary<uint, DerivationType>();
|
||||
|
||||
|
||||
public int MaxTrackedConfirmation { get; internal set; } = 6;
|
||||
public string UriScheme { get; internal set; }
|
||||
public KeyPath GetRootKeyPath(DerivationType type)
|
||||
{
|
||||
KeyPath baseKey;
|
||||
@@ -105,7 +106,6 @@ namespace BTCPayServer
|
||||
|
||||
public string CryptoCode { get; internal set; }
|
||||
public string BlockExplorerLink { get; internal set; }
|
||||
public string UriScheme { get; internal set; }
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
[Obsolete("Should not be needed")]
|
||||
@@ -118,8 +118,6 @@ namespace BTCPayServer
|
||||
}
|
||||
|
||||
public string CryptoImagePath { get; set; }
|
||||
|
||||
public int MaxTrackedConfirmation { get; internal set; } = 6;
|
||||
public string[] DefaultRateRules { get; internal set; } = Array.Empty<string>();
|
||||
public override string ToString()
|
||||
{
|
||||
|
||||
7
BTCPayServer/Contracts/IStoreNavExtension.cs
Normal file
7
BTCPayServer/Contracts/IStoreNavExtension.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace BTCPayServer.Contracts
|
||||
{
|
||||
public interface IStoreNavExtension
|
||||
{
|
||||
string Partial { get; }
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
var invoice = (await _InvoiceRepository.GetInvoices(new InvoiceQuery()
|
||||
{
|
||||
InvoiceId = id,
|
||||
InvoiceId = new[] {id},
|
||||
StoreId = new[] { HttpContext.GetStoreData().Id }
|
||||
})).FirstOrDefault();
|
||||
if (invoice == null)
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
var invoice = (await _InvoiceRepository.GetInvoices(new InvoiceQuery()
|
||||
{
|
||||
InvoiceId = invoiceId,
|
||||
InvoiceId = new[] {invoiceId},
|
||||
UserId = GetUserId(),
|
||||
IncludeAddresses = true,
|
||||
IncludeEvents = true
|
||||
@@ -582,7 +582,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
var invoice = (await _InvoiceRepository.GetInvoices(new InvoiceQuery()
|
||||
{
|
||||
InvoiceId = invoiceId,
|
||||
InvoiceId = new[] {invoiceId},
|
||||
UserId = GetUserId()
|
||||
})).FirstOrDefault();
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace BTCPayServer.Data
|
||||
foreach (var strat in strategies.Properties())
|
||||
{
|
||||
var paymentMethodId = PaymentMethodId.Parse(strat.Name);
|
||||
var network = networks.GetNetwork<BTCPayNetwork>(paymentMethodId.CryptoCode);
|
||||
var network = networks.GetNetwork<BTCPayNetworkBase>(paymentMethodId.CryptoCode);
|
||||
if (network != null)
|
||||
{
|
||||
if (network == networks.BTC && paymentMethodId.PaymentType == PaymentTypes.BTCLike && btcReturned)
|
||||
|
||||
@@ -315,8 +315,9 @@ namespace BTCPayServer.HostedServices
|
||||
var paymentData = payment.GetCryptoPaymentData();
|
||||
if (paymentData is Payments.Bitcoin.BitcoinLikePaymentData onChainPaymentData)
|
||||
{
|
||||
var network = payment.Network as BTCPayNetwork;
|
||||
// Do update if confirmation count in the paymentData is not up to date
|
||||
if ((onChainPaymentData.ConfirmationCount < payment.Network.MaxTrackedConfirmation && payment.Accounted)
|
||||
if ((onChainPaymentData.ConfirmationCount < network.MaxTrackedConfirmation && payment.Accounted)
|
||||
&& (onChainPaymentData.Legacy || invoice.MonitoringExpiration < DateTimeOffset.UtcNow))
|
||||
{
|
||||
var transactionResult = await _ExplorerClientProvider.GetExplorerClient(payment.GetCryptoCode())?.GetTransactionAsync(onChainPaymentData.Outpoint.Hash);
|
||||
@@ -325,7 +326,7 @@ namespace BTCPayServer.HostedServices
|
||||
payment.SetCryptoPaymentData(onChainPaymentData);
|
||||
|
||||
// we want to extend invoice monitoring until we reach max confirmations on all onchain payment methods
|
||||
if (confirmationCount < payment.Network.MaxTrackedConfirmation)
|
||||
if (confirmationCount < network.MaxTrackedConfirmation)
|
||||
extendInvoiceMonitoring = true;
|
||||
|
||||
return payment;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace BTCPayServer.Payments.Bitcoin
|
||||
|
||||
public bool PaymentCompleted(PaymentEntity entity)
|
||||
{
|
||||
return ConfirmationCount >= Network.MaxTrackedConfirmation;
|
||||
return ConfirmationCount >= ((BTCPayNetwork)Network).MaxTrackedConfirmation;
|
||||
}
|
||||
|
||||
public bool PaymentConfirmed(PaymentEntity entity, SpeedPolicy speedPolicy)
|
||||
|
||||
@@ -87,7 +87,9 @@ namespace BTCPayServer.Payments.Bitcoin
|
||||
|
||||
public override IEnumerable<PaymentMethodId> GetSupportedPaymentMethods()
|
||||
{
|
||||
return _networkProvider.GetAll()
|
||||
return _networkProvider
|
||||
.GetAll()
|
||||
.OfType<BTCPayNetwork>()
|
||||
.Select(network => new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike));
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,8 @@ namespace BTCPayServer.Payments.Bitcoin
|
||||
foreach (var txCoin in evt.TransactionData.Transaction.Outputs.AsCoins()
|
||||
.Where(o => o.ScriptPubKey == output.ScriptPubKey))
|
||||
{
|
||||
var invoice = await _InvoiceRepository.GetInvoiceFromScriptPubKey(output.ScriptPubKey, network.CryptoCode);
|
||||
var key = output.ScriptPubKey.Hash + "#" + network.CryptoCode;
|
||||
var invoice = (await _InvoiceRepository.GetInvoicesFromAddresses(new [] {key})).FirstOrDefault();
|
||||
if (invoice != null)
|
||||
{
|
||||
var paymentData = new BitcoinLikePaymentData(txCoin, evt.TransactionData.Transaction.RBF);
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace BTCPayServer.Payments.Lightning
|
||||
}
|
||||
catch (OperationCanceledException) when (cts.IsCancellationRequested)
|
||||
{
|
||||
throw new PaymentMethodUnavailableException($"The lightning node did not reply in a timely maner");
|
||||
throw new PaymentMethodUnavailableException($"The lightning node did not reply in a timely manner");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -139,7 +139,10 @@ namespace BTCPayServer.Payments.Lightning
|
||||
|
||||
public override IEnumerable<PaymentMethodId> GetSupportedPaymentMethods()
|
||||
{
|
||||
return _networkProvider.GetAll()
|
||||
return _networkProvider
|
||||
.GetAll()
|
||||
.OfType<BTCPayNetwork>()
|
||||
.Where(network => network.NBitcoinNetwork.Consensus.SupportSegwit)
|
||||
.Select(network => new PaymentMethodId(network.CryptoCode, PaymentTypes.LightningLike));
|
||||
}
|
||||
|
||||
|
||||
@@ -461,7 +461,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
}
|
||||
else if (paymentId.PaymentType == PaymentTypes.BTCLike)
|
||||
{
|
||||
var scheme = info.Network.UriScheme;
|
||||
var scheme = ((BTCPayNetwork)info.Network).UriScheme;
|
||||
|
||||
var minerInfo = new MinerFeeInfo();
|
||||
minerInfo.TotalFee = accounting.NetworkFee.Satoshi;
|
||||
@@ -911,7 +911,7 @@ namespace BTCPayServer.Services.Invoices
|
||||
{
|
||||
[NotMapped]
|
||||
[JsonIgnore]
|
||||
public BTCPayNetwork Network { get; set; }
|
||||
public BTCPayNetworkBase Network { get; set; }
|
||||
public int Version { get; set; }
|
||||
public DateTimeOffset ReceivedTime
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using DBriize;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NBitpayClient;
|
||||
@@ -80,30 +81,31 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<InvoiceEntity> GetInvoiceFromScriptPubKey(Script scriptPubKey, string cryptoCode)
|
||||
public async Task<IEnumerable<InvoiceEntity>> GetInvoicesFromAddresses(string[] addresses)
|
||||
{
|
||||
using (var db = _ContextFactory.CreateContext())
|
||||
{
|
||||
var key = scriptPubKey.Hash.ToString() + "#" + cryptoCode;
|
||||
var result = (await db.AddressInvoices
|
||||
return (await db.AddressInvoices
|
||||
#pragma warning disable CS0618
|
||||
.Where(a => a.Address == key)
|
||||
.Where(a => addresses.Contains(a.Address))
|
||||
#pragma warning restore CS0618
|
||||
.Select(a => a.InvoiceData)
|
||||
.Include(a => a.Payments)
|
||||
.Include(a => a.RefundAddresses)
|
||||
.ToListAsync()).FirstOrDefault();
|
||||
if (result == null)
|
||||
return null;
|
||||
return ToEntity(result);
|
||||
.Select(a => a.InvoiceData)
|
||||
.Include(a => a.Payments)
|
||||
.Include(a => a.RefundAddresses)
|
||||
.ToListAsync()).Select(ToEntity);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string[]> GetPendingInvoices()
|
||||
public async Task<string[]> GetPendingInvoices(Func<IQueryable<PendingInvoiceData>, IQueryable<PendingInvoiceData>> filter = null )
|
||||
{
|
||||
using (var ctx = _ContextFactory.CreateContext())
|
||||
{
|
||||
return await ctx.PendingInvoices.Select(p => p.Id).ToArrayAsync();
|
||||
var queryable = ctx.PendingInvoices.AsQueryable();
|
||||
if (filter != null)
|
||||
{
|
||||
queryable = filter.Invoke(queryable);
|
||||
}
|
||||
return await queryable.Select(p => p.Id).ToArrayAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +241,7 @@ retry:
|
||||
return paymentMethod.GetPaymentMethodDetails().GetPaymentDestination();
|
||||
}
|
||||
|
||||
public async Task<bool> NewAddress(string invoiceId, Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod paymentMethod, BTCPayNetworkBase network)
|
||||
public async Task<bool> NewAddress(string invoiceId, IPaymentMethodDetails paymentMethod, BTCPayNetworkBase network)
|
||||
{
|
||||
using (var context = _ContextFactory.CreateContext())
|
||||
{
|
||||
@@ -252,7 +254,7 @@ retry:
|
||||
if (currencyData == null)
|
||||
return false;
|
||||
|
||||
var existingPaymentMethod = (Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod)currencyData.GetPaymentMethodDetails();
|
||||
var existingPaymentMethod = currencyData.GetPaymentMethodDetails();
|
||||
if (existingPaymentMethod.GetPaymentDestination() != null)
|
||||
{
|
||||
MarkUnassigned(invoiceId, invoiceEntity, context, currencyData.GetId());
|
||||
@@ -441,7 +443,7 @@ retry:
|
||||
entity.Payments = invoice.Payments.Select(p =>
|
||||
{
|
||||
var paymentEntity = ToObject<PaymentEntity>(p.Blob, null);
|
||||
paymentEntity.Network = _Networks.GetNetwork<BTCPayNetwork>(paymentEntity.CryptoCode);
|
||||
paymentEntity.Network = _Networks.GetNetwork<BTCPayNetworkBase>(paymentEntity.CryptoCode);
|
||||
paymentEntity.Accounted = p.Accounted;
|
||||
// PaymentEntity on version 0 does not have their own fee, because it was assumed that the payment method have fixed fee.
|
||||
// We want to hide this legacy detail in InvoiceRepository, so we fetch the fee from the PaymentMethod and assign it to the PaymentEntity.
|
||||
@@ -487,11 +489,12 @@ retry:
|
||||
{
|
||||
IQueryable<Data.InvoiceData> query = context.Invoices;
|
||||
|
||||
if (!string.IsNullOrEmpty(queryObject.InvoiceId))
|
||||
if (queryObject.InvoiceId != null && queryObject.InvoiceId.Length > 0)
|
||||
{
|
||||
query = query.Where(i => i.Id == queryObject.InvoiceId);
|
||||
var statusSet = queryObject.InvoiceId.ToHashSet();
|
||||
query = query.Where(i => statusSet.Contains(i.Id));
|
||||
}
|
||||
|
||||
|
||||
if (queryObject.StoreId != null && queryObject.StoreId.Length > 0)
|
||||
{
|
||||
var stores = queryObject.StoreId.ToHashSet();
|
||||
@@ -663,10 +666,10 @@ retry:
|
||||
ReceivedTime = date.UtcDateTime,
|
||||
Accounted = accounted,
|
||||
NetworkFee = paymentMethodDetails.GetNextNetworkFee(),
|
||||
Network = network as BTCPayNetwork
|
||||
Network = network
|
||||
};
|
||||
entity.SetCryptoPaymentData(paymentData);
|
||||
|
||||
//TODO: abstract
|
||||
if (paymentMethodDetails is Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod bitcoinPaymentMethod &&
|
||||
bitcoinPaymentMethod.NetworkFeeMode == NetworkFeeMode.MultiplePaymentsOnly &&
|
||||
bitcoinPaymentMethod.NextNetworkFee == Money.Zero)
|
||||
@@ -811,7 +814,7 @@ retry:
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string InvoiceId
|
||||
public string[] InvoiceId
|
||||
{
|
||||
get;
|
||||
set;
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
m.DepositAddress = onChainPaymentData.GetDestination();
|
||||
|
||||
int confirmationCount = onChainPaymentData.ConfirmationCount;
|
||||
if (confirmationCount >= payment.Network.MaxTrackedConfirmation)
|
||||
var network = payment.Network as BTCPayNetwork;
|
||||
if (confirmationCount >= network.MaxTrackedConfirmation)
|
||||
{
|
||||
m.Confirmations = "At least " + (payment.Network.MaxTrackedConfirmation);
|
||||
m.Confirmations = "At least " + (network.MaxTrackedConfirmation);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
@{
|
||||
Layout = "/Views/Shared/_Layout.cshtml";
|
||||
ViewBag.ShowMenu = ViewBag.ShowMenu ?? true;
|
||||
Layout = "/Views/Shared/_Layout.cshtml";
|
||||
ViewBag.ShowMenu = ViewBag.ShowMenu ?? true;
|
||||
if (!ViewData.ContainsKey("NavPartialName"))
|
||||
{
|
||||
ViewData["NavPartialName"] = "_Nav";
|
||||
}
|
||||
var title = $"{(ViewData.ContainsKey("MainTitle")? $"{ViewData["MainTitle"]}:" : String.Empty)} {ViewData["Title"]}";
|
||||
}
|
||||
|
||||
<section>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h4 class="section-heading">@ViewData["MainTitle"]: @ViewData["Title"]</h4>
|
||||
<h4 class="section-heading">@title</h4>
|
||||
<hr class="primary ml-0">
|
||||
</div>
|
||||
</div>
|
||||
@@ -17,7 +22,7 @@ ViewBag.ShowMenu = ViewBag.ShowMenu ?? true;
|
||||
<div class="col-md-3">
|
||||
@if (ViewBag.ShowMenu)
|
||||
{
|
||||
@await Html.PartialAsync("_Nav")
|
||||
@await Html.PartialAsync(ViewData["NavPartialName"].ToString())
|
||||
}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
@@ -28,9 +33,9 @@ ViewBag.ShowMenu = ViewBag.ShowMenu ?? true;
|
||||
</div>
|
||||
</section>
|
||||
@section HeadScripts {
|
||||
@RenderSection("HeadScripts", required: false)
|
||||
@RenderSection("HeadScripts", required: false)
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
@RenderSection("Scripts", required: false)
|
||||
@RenderSection("Scripts", required: false)
|
||||
}
|
||||
|
||||
@@ -4,19 +4,6 @@
|
||||
ViewData.SetActivePageAndTitle(StoreNavPages.Index, "Profile");
|
||||
}
|
||||
|
||||
<style type="text/css">
|
||||
.smMaxWidth {
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
@@media (min-width: 768px) {
|
||||
.smMaxWidth {
|
||||
max-width: 300px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||
|
||||
<div class="row">
|
||||
|
||||
@@ -5,5 +5,9 @@
|
||||
<a id="@(nameof(StoreNavPages.Tokens))"class="nav-link @ViewData.IsActivePage(StoreNavPages.Tokens)" asp-action="ListTokens">Access Tokens</a>
|
||||
<a id="@(nameof(StoreNavPages.Users))"class="nav-link @ViewData.IsActivePage(StoreNavPages.Users)" asp-action="StoreUsers">Users</a>
|
||||
<a id="@(nameof(StoreNavPages.PayButton))"class="nav-link @ViewData.IsActivePage(StoreNavPages.PayButton)" asp-action="PayButton">Pay Button</a>
|
||||
@inject IEnumerable<BTCPayServer.Contracts.IStoreNavExtension> Extensions;
|
||||
@foreach (var extension in Extensions)
|
||||
{
|
||||
<partial name="@extension.Partial"/>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -118,4 +118,14 @@ a.nav-link {
|
||||
.invoice-details a{
|
||||
/* Prevent layout from breaking on hyperlinks with very long URLs as the visible text */
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
.smMaxWidth {
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.smMaxWidth {
|
||||
max-width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user