mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 01:43:50 +01:00
BlockExplorer links should be using payment method ids (#6273)
This commit is contained in:
parent
c3e51f51b6
commit
5704919b3a
@ -19,6 +19,7 @@ using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NBitcoin;
|
||||
using NBXplorer;
|
||||
using NBXplorer.Client;
|
||||
using static BTCPayServer.Components.StoreRecentTransactions.StoreRecentTransactionsViewModel;
|
||||
|
||||
@ -80,7 +81,7 @@ public class StoreRecentTransactions : ViewComponent
|
||||
Balance = tx.BalanceChange.ShowMoney(network),
|
||||
Currency = vm.CryptoCode,
|
||||
IsConfirmed = tx.Confirmations != 0,
|
||||
Link = _transactionLinkProviders.GetTransactionLink(network.CryptoCode, tx.TransactionId.ToString()),
|
||||
Link = _transactionLinkProviders.GetTransactionLink(pmi, tx.TransactionId.ToString()),
|
||||
Timestamp = tx.SeenAt,
|
||||
Labels = labels
|
||||
};
|
||||
|
@ -334,7 +334,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
Labels = info?.LegacyLabels ?? new Dictionary<string, LabelData>(),
|
||||
#pragma warning restore CS0612 // Type or member is obsolete
|
||||
Link = _transactionLinkProviders.GetTransactionLink(network.CryptoCode, coin.OutPoint.ToString()),
|
||||
Link = _transactionLinkProviders.GetTransactionLink(pmi, coin.OutPoint.ToString()),
|
||||
Timestamp = coin.Timestamp,
|
||||
KeyPath = coin.KeyPath,
|
||||
Confirmations = coin.Confirmations,
|
||||
|
@ -362,7 +362,7 @@ namespace BTCPayServer.Controllers
|
||||
return View(settings);
|
||||
}
|
||||
settings.BlockExplorerLinks = settings.BlockExplorerLinks
|
||||
.Where(tuple => _transactionLinkProviders.GetDefaultBlockExplorerLink(tuple.CryptoCode) != tuple.Link)
|
||||
.Where(tuple => _transactionLinkProviders.GetDefaultBlockExplorerLink(tuple.PaymentMethodId) != tuple.Link)
|
||||
.Where(tuple => tuple.Link is not null)
|
||||
.ToList();
|
||||
|
||||
|
@ -266,7 +266,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
var vm = new ListTransactionsViewModel.TransactionViewModel();
|
||||
vm.Id = tx.TransactionId.ToString();
|
||||
vm.Link = _transactionLinkProviders.GetTransactionLink(network.CryptoCode, vm.Id);
|
||||
vm.Link = _transactionLinkProviders.GetTransactionLink(pmi, vm.Id);
|
||||
vm.Timestamp = tx.SeenAt;
|
||||
vm.Positive = tx.BalanceChange.GetValue(wallet.Network) >= 0;
|
||||
vm.Balance = tx.BalanceChange.ShowMoney(wallet.Network);
|
||||
@ -600,7 +600,7 @@ namespace BTCPayServer.Controllers
|
||||
Amount = coin.Value.GetValue(network),
|
||||
Comment = info?.Comment,
|
||||
Labels = _labelService.CreateTransactionTagModels(info, Request),
|
||||
Link = _transactionLinkProviders.GetTransactionLink(network.CryptoCode, coin.OutPoint.ToString()),
|
||||
Link = _transactionLinkProviders.GetTransactionLink(pmi, coin.OutPoint.ToString()),
|
||||
Confirmations = coin.Confirmations
|
||||
};
|
||||
}).ToArray();
|
||||
|
@ -126,7 +126,6 @@ public class BitcoinLikePayoutHandler : IPayoutHandler, IHasNetwork
|
||||
var payoutMethodId = payout.GetPayoutMethodId();
|
||||
if (payoutMethodId is null)
|
||||
return null;
|
||||
var cryptoCode = Network.CryptoCode;
|
||||
ParseProofType(payout.Proof, out var raw, out var proofType);
|
||||
if (proofType == PayoutTransactionOnChainBlob.Type)
|
||||
{
|
||||
@ -135,7 +134,7 @@ public class BitcoinLikePayoutHandler : IPayoutHandler, IHasNetwork
|
||||
JsonSerializer.Create(_jsonSerializerSettings.GetSerializer(payoutMethodId)));
|
||||
if (res == null)
|
||||
return null;
|
||||
res.LinkTemplate = _transactionLinkProviders.GetBlockExplorerLink(cryptoCode);
|
||||
res.LinkTemplate = _transactionLinkProviders.GetBlockExplorerLink(PaymentTypes.CHAIN.GetPaymentMethodId(Network.CryptoCode));
|
||||
return res;
|
||||
}
|
||||
return raw.ToObject<ManualPayoutProof>();
|
||||
|
@ -662,10 +662,13 @@ o.GetRequiredService<IEnumerable<IPaymentLinkExtension>>().ToDictionary(o => o.P
|
||||
}
|
||||
return services;
|
||||
}
|
||||
public static void AddTransactionLinkProvider(this IServiceCollection services, string cryptoCode, TransactionLinkProvider provider)
|
||||
public static void AddTransactionLinkProvider(this IServiceCollection services, PaymentMethodId paymentMethodId, TransactionLinkProvider provider)
|
||||
{
|
||||
services.AddSingleton<TransactionLinkProviders.Entry>(new TransactionLinkProviders.Entry(cryptoCode, provider));
|
||||
services.AddSingleton<TransactionLinkProviders.Entry>(new TransactionLinkProviders.Entry(paymentMethodId, provider));
|
||||
}
|
||||
[Obsolete("Use AddTransactionLinkProvider(services, PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode), provider) instead")]
|
||||
public static void AddTransactionLinkProvider(this IServiceCollection services, string cryptoCode, TransactionLinkProvider provider) =>
|
||||
AddTransactionLinkProvider(services, PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode), provider);
|
||||
public static void AddRateProviderExchangeSharp<T>(this IServiceCollection services, RateSourceInfo rateInfo) where T : ExchangeSharp.ExchangeAPI
|
||||
{
|
||||
services.AddSingleton<IRateProvider, ExchangeSharpRateProvider<T>>(o =>
|
||||
|
@ -211,6 +211,12 @@ namespace BTCPayServer.Hosting
|
||||
settings.MigrateToStoreConfig = true;
|
||||
await _Settings.UpdateSetting(settings);
|
||||
}
|
||||
if (!settings.MigrateBlockExplorerLinks)
|
||||
{
|
||||
await MigrateBlockExplorerLinks();
|
||||
settings.MigrateBlockExplorerLinks = true;
|
||||
await _Settings.UpdateSetting(settings);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -219,6 +225,28 @@ namespace BTCPayServer.Hosting
|
||||
}
|
||||
}
|
||||
|
||||
private async Task MigrateBlockExplorerLinks()
|
||||
{
|
||||
await using var ctx = _DBContextFactory.CreateContext();
|
||||
var settings = await ctx.Settings.Where(s => s.Id == "BTCPayServer.Services.PoliciesSettings").FirstOrDefaultAsync();
|
||||
if (settings is null)
|
||||
return;
|
||||
var obj = JObject.Parse(settings.Value);
|
||||
var arr = obj["BlockExplorerLinks"] as JArray;
|
||||
if (arr is null or { Count: 0 })
|
||||
return;
|
||||
foreach (var item in arr.OfType<JObject>())
|
||||
{
|
||||
var cryptoCode = item["CryptoCode"]?.Value<string>();
|
||||
if (cryptoCode is null)
|
||||
continue;
|
||||
item.Remove("CryptoCode");
|
||||
item["PaymentMethodId"] = PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode).ToString();
|
||||
}
|
||||
settings.Value = obj.ToString();
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private async Task MigrateToStoreConfig()
|
||||
{
|
||||
await using var ctx = _DBContextFactory.CreateContext();
|
||||
@ -315,33 +343,33 @@ namespace BTCPayServer.Hosting
|
||||
private async Task MigrateAppYmlToJson()
|
||||
{
|
||||
await using var ctx = _DBContextFactory.CreateContext();
|
||||
var apps = await ctx.Apps.Where(data => CrowdfundAppType.AppType == data.AppType || PointOfSaleAppType.AppType == data.AppType)
|
||||
var apps = await ctx.Apps.Where(data => CrowdfundAppType.AppType == data.AppType || PointOfSaleAppType.AppType == data.AppType)
|
||||
.ToListAsync();
|
||||
foreach (var app in apps)
|
||||
foreach (var app in apps)
|
||||
{
|
||||
switch (app.AppType)
|
||||
{
|
||||
case CrowdfundAppType.AppType :
|
||||
var cfSettings = app.GetSettings<CrowdfundSettings>();
|
||||
if (!string.IsNullOrEmpty(cfSettings?.PerksTemplate))
|
||||
{
|
||||
cfSettings.PerksTemplate = AppService.SerializeTemplate(ParsePOSYML(cfSettings?.PerksTemplate));
|
||||
app.SetSettings(cfSettings);
|
||||
}
|
||||
break;
|
||||
case PointOfSaleAppType.AppType:
|
||||
var pSettings = app.GetSettings<PointOfSaleSettings>();
|
||||
if (!string.IsNullOrEmpty(pSettings?.Template))
|
||||
{
|
||||
pSettings.Template = AppService.SerializeTemplate(ParsePOSYML(pSettings?.Template));
|
||||
app.SetSettings(pSettings);
|
||||
}
|
||||
break;
|
||||
case CrowdfundAppType.AppType:
|
||||
var cfSettings = app.GetSettings<CrowdfundSettings>();
|
||||
if (!string.IsNullOrEmpty(cfSettings?.PerksTemplate))
|
||||
{
|
||||
cfSettings.PerksTemplate = AppService.SerializeTemplate(ParsePOSYML(cfSettings?.PerksTemplate));
|
||||
app.SetSettings(cfSettings);
|
||||
}
|
||||
break;
|
||||
case PointOfSaleAppType.AppType:
|
||||
var pSettings = app.GetSettings<PointOfSaleSettings>();
|
||||
if (!string.IsNullOrEmpty(pSettings?.Template))
|
||||
{
|
||||
pSettings.Template = AppService.SerializeTemplate(ParsePOSYML(pSettings?.Template));
|
||||
app.SetSettings(pSettings);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
|
||||
}
|
||||
public static ViewPointOfSaleViewModel.Item[] ParsePOSYML(string yaml)
|
||||
{
|
||||
@ -349,10 +377,10 @@ namespace BTCPayServer.Hosting
|
||||
var stream = new YamlStream();
|
||||
if (string.IsNullOrEmpty(yaml))
|
||||
return items.ToArray();
|
||||
|
||||
|
||||
stream.Load(new StringReader(yaml));
|
||||
|
||||
if(stream.Documents.FirstOrDefault()?.RootNode is not YamlMappingNode root)
|
||||
if (stream.Documents.FirstOrDefault()?.RootNode is not YamlMappingNode root)
|
||||
return items.ToArray();
|
||||
foreach (var posItem in root.Children)
|
||||
{
|
||||
@ -364,12 +392,14 @@ namespace BTCPayServer.Hosting
|
||||
|
||||
var currentItem = new ViewPointOfSaleViewModel.Item
|
||||
{
|
||||
Id = trimmedKey, Title = trimmedKey, PriceType = ViewPointOfSaleViewModel.ItemPriceType.Fixed
|
||||
Id = trimmedKey,
|
||||
Title = trimmedKey,
|
||||
PriceType = ViewPointOfSaleViewModel.ItemPriceType.Fixed
|
||||
};
|
||||
var itemSpecs = (YamlMappingNode)posItem.Value;
|
||||
foreach (var spec in itemSpecs)
|
||||
{
|
||||
if (spec.Key is not YamlScalarNode {Value: string keyString} || string.IsNullOrEmpty(keyString))
|
||||
if (spec.Key is not YamlScalarNode { Value: string keyString } || string.IsNullOrEmpty(keyString))
|
||||
continue;
|
||||
var scalarValue = spec.Value as YamlScalarNode;
|
||||
switch (keyString)
|
||||
|
@ -12,7 +12,7 @@ namespace BTCPayServer.Models.InvoicingModels
|
||||
{
|
||||
public class OnchainPaymentViewModel
|
||||
{
|
||||
public string Crypto { get; set; }
|
||||
public PaymentMethodId PaymentMethodId { get; set; }
|
||||
public string Confirmations { get; set; }
|
||||
public BitcoinAddress DepositAddress { get; set; }
|
||||
public string Amount { get; set; }
|
||||
@ -26,6 +26,7 @@ namespace BTCPayServer.Models.InvoicingModels
|
||||
public string AdditionalInformation { get; set; }
|
||||
public decimal NetworkFee { get; set; }
|
||||
public string PaymentProof { get; set; }
|
||||
public string Currency { get; set; }
|
||||
}
|
||||
|
||||
public class OffChainPaymentViewModel
|
||||
|
@ -213,9 +213,7 @@ namespace BTCPayServer.Models.PaymentRequestViewModels
|
||||
}
|
||||
string txId = paymentEntity.Id;
|
||||
|
||||
// TODO: Move that in an extension
|
||||
var cryptoCode = handlers.TryGetNetwork(paymentMethodId)?.CryptoCode;
|
||||
string link = cryptoCode is null ? null : txLinkProvider.GetTransactionLink(cryptoCode, txId);
|
||||
string link = paymentMethodId is null ? null : txLinkProvider.GetTransactionLink(paymentMethodId, txId);
|
||||
|
||||
return new ViewPaymentRequestViewModel.PaymentRequestInvoicePayment
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Payments;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
@ -9,7 +10,7 @@ namespace BTCPayServer.Models.StoreReportsViewModels;
|
||||
public class StoreReportsViewModel
|
||||
{
|
||||
public string InvoiceTemplateUrl { get; set; }
|
||||
public Dictionary<string,string> ExplorerTemplateUrls { get; set; }
|
||||
public Dictionary<PaymentMethodId,string> ExplorerTemplateUrls { get; set; }
|
||||
public StoreReportRequest Request { get; set; }
|
||||
public List<string> AvailableViews { get; set; }
|
||||
public StoreReportResponse Result { get; set; }
|
||||
|
@ -30,6 +30,6 @@ public partial class AltcoinsPlugin
|
||||
}.SetDefaultElectrumMapping(ChainName);
|
||||
var blockExplorerLink = ChainName == ChainName.Mainnet ? "https://btgexplorer.com/tx/{0}" : "https://testnet.btgexplorer.com/tx/{0}";
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,6 @@ public partial class AltcoinsPlugin
|
||||
? "https://insight.dash.org/insight/tx/{0}"
|
||||
: "https://testnet-insight.dashevo.org/insight/tx/{0}";
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public partial class AltcoinsPlugin
|
||||
|
||||
var blockExplorerLink = ChainName == ChainName.Mainnet ? "https://dogechain.info/tx/{0}" : "https://dogechain.info/tx/{0}";
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ public partial class AltcoinsPlugin
|
||||
? "https://chainz.cryptoid.info/grs/tx.dws?{0}.htm"
|
||||
: "https://chainz.cryptoid.info/grs-test/tx.dws?{0}.htm";
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ public partial class AltcoinsPlugin
|
||||
? "https://live.blockcypher.com/ltc/tx/{0}/"
|
||||
: "http://explorer.litecointools.com/tx/{0}";
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(blockExplorerLinks));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(blockExplorerLinks));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ public partial class AltcoinsPlugin
|
||||
|
||||
var blockExplorerLink = ChainName == ChainName.Mainnet ? "https://mona.insight.monaco-ex.org/insight/tx/{0}" : "https://testnet-mona.insight.monaco-ex.org/insight/tx/{0}";
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,6 @@ public partial class AltcoinsPlugin
|
||||
|
||||
var blockExplorerLink = ChainName == ChainName.Mainnet ? "https://liquid.network/tx/{0}" : "https://liquid.network/testnet/tx/{0}";
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(blockExplorerLink));
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public partial class AltcoinsPlugin
|
||||
SupportLightning = false
|
||||
}.SetDefaultElectrumMapping(ChainName);
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(LiquidBlockExplorer));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(LiquidBlockExplorer));
|
||||
selectedChains.Add("LBTC");
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ public partial class AltcoinsPlugin
|
||||
}.SetDefaultElectrumMapping(ChainName);
|
||||
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(LiquidBlockExplorer));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(LiquidBlockExplorer));
|
||||
selectedChains.Add("LBTC");
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ public partial class AltcoinsPlugin
|
||||
SupportLightning = false
|
||||
}.SetDefaultElectrumMapping(ChainName);
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(nbxplorerNetwork.CryptoCode, new DefaultTransactionLinkProvider(LiquidBlockExplorer));
|
||||
.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), new DefaultTransactionLinkProvider(LiquidBlockExplorer));
|
||||
selectedChains.Add("LBTC");
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ public partial class AltcoinsPlugin
|
||||
: "https://testnet.xmrchain.net/tx/{0}";
|
||||
var pmi = PaymentTypes.CHAIN.GetPaymentMethodId("XMR");
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(network.CryptoCode, new SimpleTransactionLinkProvider(blockExplorerLink));
|
||||
.AddTransactionLinkProvider(pmi, new SimpleTransactionLinkProvider(blockExplorerLink));
|
||||
services.AddSingleton<IPaymentMethodViewExtension>(provider =>
|
||||
(IPaymentMethodViewExtension)ActivatorUtilities.CreateInstance(provider, typeof(BitcoinPaymentMethodViewExtension), new object[] { pmi }));
|
||||
|
||||
|
@ -42,7 +42,7 @@ public partial class AltcoinsPlugin
|
||||
: "https://testnet.xmrchain.net/tx/{0}";
|
||||
var pmi = PaymentTypes.CHAIN.GetPaymentMethodId("ZEC");
|
||||
services.AddBTCPayNetwork(network)
|
||||
.AddTransactionLinkProvider(network.CryptoCode, new SimpleTransactionLinkProvider(blockExplorerLink));
|
||||
.AddTransactionLinkProvider(pmi, new SimpleTransactionLinkProvider(blockExplorerLink));
|
||||
services.AddSingleton<IPaymentMethodViewExtension>(provider =>
|
||||
(IPaymentMethodViewExtension)ActivatorUtilities.CreateInstance(provider, typeof(BitcoinPaymentMethodViewExtension), new object[] { pmi }));
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#nullable enable
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using BTCPayServer.Hosting;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NBitcoin;
|
||||
@ -47,7 +48,7 @@ namespace BTCPayServer.Plugins.Bitcoin
|
||||
}.SetDefaultElectrumMapping(chainName);
|
||||
|
||||
applicationBuilder.AddBTCPayNetwork(network);
|
||||
applicationBuilder.AddTransactionLinkProvider(network.CryptoCode, defaultTransactionLinkProvider);
|
||||
applicationBuilder.AddTransactionLinkProvider(PaymentTypes.CHAIN.GetPaymentMethodId(nbxplorerNetwork.CryptoCode), defaultTransactionLinkProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
using System;
|
||||
using BTCPayServer.Payments;
|
||||
|
||||
namespace BTCPayServer.Services.Altcoins.Monero.UI
|
||||
{
|
||||
public class MoneroPaymentViewModel
|
||||
{
|
||||
public string Crypto { get; set; }
|
||||
public PaymentMethodId PaymentMethodId { get; set; }
|
||||
public string Confirmations { get; set; }
|
||||
public string DepositAddress { get; set; }
|
||||
public string Amount { get; set; }
|
||||
public string TransactionId { get; set; }
|
||||
public DateTimeOffset ReceivedTime { get; set; }
|
||||
public string TransactionLink { get; set; }
|
||||
public string Currency { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
using System;
|
||||
using BTCPayServer.Payments;
|
||||
|
||||
namespace BTCPayServer.Services.Altcoins.Zcash.UI
|
||||
{
|
||||
public class ZcashPaymentViewModel
|
||||
{
|
||||
public string Crypto { get; set; }
|
||||
public PaymentMethodId PaymentMethodId { get; set; }
|
||||
public string Confirmations { get; set; }
|
||||
public string DepositAddress { get; set; }
|
||||
public string Amount { get; set; }
|
||||
public string TransactionId { get; set; }
|
||||
public DateTimeOffset ReceivedTime { get; set; }
|
||||
public string TransactionLink { get; set; }
|
||||
public string Currency { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -31,5 +31,6 @@ namespace BTCPayServer.Services
|
||||
public bool FixMappedDomainAppType { get; set; }
|
||||
public bool MigrateAppYmlToJson { get; set; }
|
||||
public bool MigrateToStoreConfig { get; set; }
|
||||
public bool MigrateBlockExplorerLinks { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using BTCPayServer.JsonConverters;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Validation;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Services
|
||||
{
|
||||
@ -98,7 +101,8 @@ namespace BTCPayServer.Services
|
||||
|
||||
public class BlockExplorerOverrideItem
|
||||
{
|
||||
public string CryptoCode { get; set; }
|
||||
[JsonConverter(typeof(PaymentMethodIdJsonConverter))]
|
||||
public PaymentMethodId PaymentMethodId { get; set; }
|
||||
public string Link { get; set; }
|
||||
}
|
||||
|
||||
|
@ -8,16 +8,16 @@ using System.Linq;
|
||||
|
||||
namespace BTCPayServer.Services;
|
||||
|
||||
public class TransactionLinkProviders : Dictionary<string, TransactionLinkProvider>
|
||||
public class TransactionLinkProviders : Dictionary<PaymentMethodId, TransactionLinkProvider>
|
||||
{
|
||||
public SettingsRepository SettingsRepository { get; }
|
||||
|
||||
public record Entry(string CryptoCode, TransactionLinkProvider Provider);
|
||||
public record Entry(PaymentMethodId PaymentMethodId, TransactionLinkProvider Provider);
|
||||
public TransactionLinkProviders(IEnumerable<Entry> entries, SettingsRepository settingsRepository)
|
||||
{
|
||||
foreach (var e in entries)
|
||||
{
|
||||
TryAdd(e.CryptoCode, e.Provider);
|
||||
TryAdd(e.PaymentMethodId, e.Provider);
|
||||
}
|
||||
SettingsRepository = settingsRepository;
|
||||
}
|
||||
@ -29,29 +29,28 @@ public class TransactionLinkProviders : Dictionary<string, TransactionLinkProvid
|
||||
{
|
||||
foreach ((var pmi, var prov) in this)
|
||||
{
|
||||
var overrideLink = links.FirstOrDefault(item =>
|
||||
item.CryptoCode.Equals(pmi, StringComparison.InvariantCultureIgnoreCase));
|
||||
var overrideLink = links.FirstOrDefault(item => item.PaymentMethodId == pmi);
|
||||
prov.OverrideBlockExplorerLink = overrideLink?.Link ?? prov.BlockExplorerLinkDefault;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string? GetTransactionLink(string cryptoCode, string paymentId)
|
||||
public string? GetTransactionLink(PaymentMethodId paymentMethodId, string paymentId)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(cryptoCode);
|
||||
ArgumentNullException.ThrowIfNull(paymentMethodId);
|
||||
ArgumentNullException.ThrowIfNull(paymentId);
|
||||
TryGetValue(cryptoCode, out var p);
|
||||
TryGetValue(paymentMethodId, out var p);
|
||||
return p?.GetTransactionLink(paymentId);
|
||||
}
|
||||
|
||||
public string? GetBlockExplorerLink(string cryptoCode)
|
||||
public string? GetBlockExplorerLink(PaymentMethodId paymentMethodId)
|
||||
{
|
||||
TryGetValue(cryptoCode, out var p);
|
||||
TryGetValue(paymentMethodId, out var p);
|
||||
return p?.BlockExplorerLink;
|
||||
}
|
||||
public string? GetDefaultBlockExplorerLink(string cryptoCode)
|
||||
public string? GetDefaultBlockExplorerLink(PaymentMethodId paymentMethodId)
|
||||
{
|
||||
TryGetValue(cryptoCode, out var p);
|
||||
TryGetValue(paymentMethodId, out var p);
|
||||
return p?.BlockExplorerLinkDefault;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
var network = handler.Network;
|
||||
var m = new OnchainPaymentViewModel();
|
||||
var onChainPaymentData = handler.ParsePaymentDetails(payment.Details);
|
||||
m.Crypto = network.CryptoCode;
|
||||
m.PaymentMethodId = payment.PaymentMethodId;
|
||||
m.DepositAddress = BitcoinAddress.Create(payment.Destination, network.NBitcoinNetwork);
|
||||
|
||||
var confReq = NBXplorerListener.ConfirmationRequired(payment.InvoiceEntity, onChainPaymentData);
|
||||
@ -37,12 +37,13 @@
|
||||
}
|
||||
m.TransactionId = onChainPaymentData.Outpoint.Hash.ToString();
|
||||
m.ReceivedTime = payment.ReceivedTime;
|
||||
m.TransactionLink = TransactionLinkProviders.GetTransactionLink(network.CryptoCode, onChainPaymentData.Outpoint.ToString());
|
||||
m.TransactionLink = TransactionLinkProviders.GetTransactionLink(payment.PaymentMethodId, onChainPaymentData.Outpoint.ToString());
|
||||
m.Replaced = !payment.Accounted;
|
||||
m.CryptoPaymentData = onChainPaymentData;
|
||||
m.Value = payment.Value;
|
||||
m.NetworkFee = payment.PaymentMethodFee;
|
||||
m.PaymentProof = onChainPaymentData.Outpoint.ToString();
|
||||
m.Currency = payment.Currency;
|
||||
return m;
|
||||
})
|
||||
.Where(model => model != null)
|
||||
@ -58,7 +59,7 @@
|
||||
<table class="table table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-75px">Crypto</th>
|
||||
<th class="w-75px">Payment Method</th>
|
||||
<th class="w-100px">Index</th>
|
||||
<th class="w-175px">Destination</th>
|
||||
<th class="text-nowrap">Payment Proof</th>
|
||||
@ -79,7 +80,7 @@
|
||||
@foreach (var payment in payments)
|
||||
{
|
||||
<tr style="@(payment.Replaced ? "text-decoration: line-through" : "")">
|
||||
<td>@payment.Crypto</td>
|
||||
<td>@payment.PaymentMethodId</td>
|
||||
<td>@(payment.CryptoPaymentData.KeyPath?.ToString()?? "Unknown")</td>
|
||||
<td>
|
||||
<vc:truncate-center text="@payment.DepositAddress.ToString()" classes="truncate-center-id" />
|
||||
@ -93,7 +94,7 @@
|
||||
}
|
||||
<td class="text-end">@payment.Confirmations</td>
|
||||
<td class="payment-value text-end text-nowrap">
|
||||
<span data-sensitive class="text-success">@DisplayFormatter.Currency(payment.Value, payment.Crypto)</span>
|
||||
<span data-sensitive class="text-success">@DisplayFormatter.Currency(payment.Value, payment.Currency)</span>
|
||||
@if (!string.IsNullOrEmpty(payment.AdditionalInformation))
|
||||
{
|
||||
<div>(@payment.AdditionalInformation)</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
return null;
|
||||
var m = new MoneroPaymentViewModel();
|
||||
var onChainPaymentData = handler.ParsePaymentDetails(payment.Details);
|
||||
m.Crypto = handler.Network.CryptoCode;
|
||||
m.PaymentMethodId = handler.PaymentMethodId;
|
||||
m.DepositAddress = payment.Destination;
|
||||
m.Amount = payment.Value.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
@ -28,7 +28,8 @@
|
||||
|
||||
m.TransactionId = onChainPaymentData.TransactionId;
|
||||
m.ReceivedTime = payment.ReceivedTime;
|
||||
m.TransactionLink = TransactionLinkProviders.GetTransactionLink(m.Crypto, onChainPaymentData.TransactionId);
|
||||
m.TransactionLink = TransactionLinkProviders.GetTransactionLink(m.PaymentMethodId, onChainPaymentData.TransactionId);
|
||||
m.Currency = payment.Currency;
|
||||
return m;
|
||||
}).Where(c => c != null).ToList();
|
||||
}
|
||||
@ -40,7 +41,7 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-75px">Crypto</th>
|
||||
<th class="w-75px">Payment Method</th>
|
||||
<th class="w-175px">Destination</th>
|
||||
<th class="text-nowrap">Payment Proof</th>
|
||||
<th class="text-end">Confirmations</th>
|
||||
@ -51,12 +52,12 @@
|
||||
@foreach (var payment in payments)
|
||||
{
|
||||
<tr >
|
||||
<td>@payment.Crypto</td>
|
||||
<td>@payment.PaymentMethodId</td>
|
||||
<td><vc:truncate-center text="@payment.DepositAddress" classes="truncate-center-id" /></td>
|
||||
<td><vc:truncate-center text="@payment.TransactionId" link="@payment.TransactionLink" classes="truncate-center-id" /></td>
|
||||
<td class="text-end">@payment.Confirmations</td>
|
||||
<td class="payment-value text-end text-nowrap">
|
||||
<span data-sensitive class="text-success">@DisplayFormatter.Currency(payment.Amount, payment.Crypto)</span>
|
||||
<span data-sensitive class="text-success">@DisplayFormatter.Currency(payment.Amount, payment.Currency)</span>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
return null;
|
||||
var m = new ZcashPaymentViewModel();
|
||||
var onChainPaymentData = handler.ParsePaymentDetails(payment.Details);
|
||||
m.Crypto = handler.Network.CryptoCode;
|
||||
m.PaymentMethodId = handler.PaymentMethodId;
|
||||
m.DepositAddress = payment.Destination;
|
||||
m.Amount = payment.Value.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
@ -29,7 +29,8 @@
|
||||
|
||||
m.TransactionId = onChainPaymentData.TransactionId;
|
||||
m.ReceivedTime = payment.ReceivedTime;
|
||||
m.TransactionLink = TransactionLinkProviders.GetTransactionLink(m.Crypto, onChainPaymentData.TransactionId);
|
||||
m.TransactionLink = TransactionLinkProviders.GetTransactionLink(m.PaymentMethodId, onChainPaymentData.TransactionId);
|
||||
m.Currency = payment.Currency;
|
||||
return m;
|
||||
}).Where(c => c != null).ToList();
|
||||
}
|
||||
@ -41,7 +42,7 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-75px">Crypto</th>
|
||||
<th class="w-75px">Payment Method</th>
|
||||
<th class="w-175px">Destination</th>
|
||||
<th class="text-nowrap">Payment Proof</th>
|
||||
<th class="text-end">Confirmations</th>
|
||||
@ -52,12 +53,12 @@
|
||||
@foreach (var payment in payments)
|
||||
{
|
||||
<tr >
|
||||
<td>@payment.Crypto</td>
|
||||
<td>@payment.PaymentMethodId</td>
|
||||
<td><vc:truncate-center text="@payment.DepositAddress" classes="truncate-center-id" /></td>
|
||||
<td><vc:truncate-center text="@payment.TransactionId" link="@payment.TransactionLink" classes="truncate-center-id" /></td>
|
||||
<td class="text-end">@payment.Confirmations</td>
|
||||
<td class="payment-value text-end text-nowrap">
|
||||
<span data-sensitive class="text-success">@DisplayFormatter.Currency(payment.Amount, payment.Crypto)</span>
|
||||
<span data-sensitive class="text-success">@DisplayFormatter.Currency(payment.Amount, payment.Currency)</span>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
@ -242,12 +242,12 @@
|
||||
|
||||
@for (var lpi = 0; lpi < linkProviders.Length; lpi++)
|
||||
{
|
||||
var cryptoCode = linkProviders[lpi].Key;
|
||||
var pmi = linkProviders[lpi].Key;
|
||||
var defaultLink = linkProviders[lpi].Value.BlockExplorerLinkDefault;
|
||||
var existingOverride = Model.BlockExplorerLinks?.FirstOrDefault(tuple => tuple.CryptoCode == cryptoCode);
|
||||
var existingOverride = Model.BlockExplorerLinks?.FirstOrDefault(tuple => tuple.PaymentMethodId == pmi);
|
||||
if (existingOverride is null)
|
||||
{
|
||||
existingOverride = new PoliciesSettings.BlockExplorerOverrideItem { CryptoCode = cryptoCode, Link = null };
|
||||
existingOverride = new PoliciesSettings.BlockExplorerOverrideItem { PaymentMethodId = pmi, Link = null };
|
||||
Model.BlockExplorerLinks ??= new ();
|
||||
Model.BlockExplorerLinks.Add(existingOverride);
|
||||
}
|
||||
@ -255,12 +255,12 @@
|
||||
var linkValue = existingOverride.Link ?? defaultLink;
|
||||
<div class="form-group" data-default="@defaultLink">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between gap-3">
|
||||
<label asp-for="BlockExplorerLinks[i].Link" class="form-label">@cryptoCode</label>
|
||||
<label asp-for="BlockExplorerLinks[i].Link" class="form-label">@pmi</label>
|
||||
<button type="button" class="btn btn-link p-0 only-for-js revert-default" title="Revert to default">
|
||||
Set to default
|
||||
</button>
|
||||
</div>
|
||||
<input type="hidden" asp-for="BlockExplorerLinks[i].CryptoCode" value="@cryptoCode" />
|
||||
<input type="hidden" asp-for="BlockExplorerLinks[i].PaymentMethodId" value="@pmi" />
|
||||
<input type="text" class="form-control block-explorer-link" asp-for="BlockExplorerLinks[i].Link" value="@linkValue" rel="noreferrer noopener" />
|
||||
</div>
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user