BlockExplorer links should be using payment method ids (#6273)

This commit is contained in:
Nicolas Dorier 2024-10-04 16:58:13 +09:00 committed by GitHub
parent c3e51f51b6
commit 5704919b3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 130 additions and 85 deletions

View File

@ -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
};

View File

@ -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,

View File

@ -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();

View File

@ -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();

View File

@ -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>();

View File

@ -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 =>

View File

@ -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)

View File

@ -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

View File

@ -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
{

View File

@ -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; }

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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");
}

View File

@ -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 }));

View File

@ -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 }));

View File

@ -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);
}
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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>
}

View File

@ -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>
}

View File

@ -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>
}