diff --git a/BTCPayServer.Common/BTCPayNetwork.cs b/BTCPayServer.Common/BTCPayNetwork.cs index 6cceb9363..0733ee98c 100644 --- a/BTCPayServer.Common/BTCPayNetwork.cs +++ b/BTCPayServer.Common/BTCPayNetwork.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading.Tasks; using NBitcoin; using NBXplorer; +using Newtonsoft.Json; namespace BTCPayServer { @@ -42,38 +43,18 @@ namespace BTCPayServer public string DefaultConfigurationFile { get; set; } public int DefaultPort { get; set; } } - public class BTCPayNetwork + + public class BTCPayNetwork:BTCPayNetworkBase { public Network NBitcoinNetwork { get; set; } - 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")] - public bool IsBTC - { - get - { - return CryptoCode == "BTC"; - } - } - - public string CryptoImagePath { get; set; } - public string LightningImagePath { get; set; } public NBXplorer.NBXplorerNetwork NBXplorerNetwork { get; set; } - + public bool SupportRBF { get; internal set; } + public string LightningImagePath { get; set; } public BTCPayDefaultSettings DefaultSettings { get; set; } public KeyPath CoinType { get; internal set; } - public int MaxTrackedConfirmation { get; internal set; } = 6; - public string[] DefaultRateRules { get; internal set; } = Array.Empty(); - public bool SupportRBF { get; internal set; } public Dictionary ElectrumMapping = new Dictionary(); - public override string ToString() - { - return CryptoCode; - } - + + public KeyPath GetRootKeyPath(DerivationType type) { KeyPath baseKey; @@ -105,7 +86,54 @@ namespace BTCPayServer public KeyPath GetRootKeyPath() { return new KeyPath(NBitcoinNetwork.Consensus.SupportSegwit ? "49'" : "44'") - .Derive(CoinType); + .Derive(CoinType); + } + + public override T ToObject(string json) + { + return NBXplorerNetwork.Serializer.ToObject(json); + } + + public override string ToString(T obj) + { + return NBXplorerNetwork.Serializer.ToString(obj); + } + } + + public abstract class BTCPayNetworkBase + { + + 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")] + public bool IsBTC + { + get + { + return CryptoCode == "BTC"; + } + } + + public string CryptoImagePath { get; set; } + + public int MaxTrackedConfirmation { get; internal set; } = 6; + public string[] DefaultRateRules { get; internal set; } = Array.Empty(); + public override string ToString() + { + return CryptoCode; + } + + public virtual T ToObject(string json) + { + return JsonConvert.DeserializeObject(json); + } + + public virtual string ToString(T obj) + { + return JsonConvert.SerializeObject(obj); } } } diff --git a/BTCPayServer.Common/BTCPayNetworkProvider.cs b/BTCPayServer.Common/BTCPayNetworkProvider.cs index 974150f25..15951d397 100644 --- a/BTCPayServer.Common/BTCPayNetworkProvider.cs +++ b/BTCPayServer.Common/BTCPayNetworkProvider.cs @@ -10,7 +10,7 @@ namespace BTCPayServer { public partial class BTCPayNetworkProvider { - Dictionary _Networks = new Dictionary(); + Dictionary _Networks = new Dictionary(); private readonly NBXplorerNetworkProvider _NBXplorerNetworkProvider; @@ -26,7 +26,7 @@ namespace BTCPayServer { NetworkType = filtered.NetworkType; _NBXplorerNetworkProvider = new NBXplorerNetworkProvider(filtered.NetworkType); - _Networks = new Dictionary(); + _Networks = new Dictionary(); cryptoCodes = cryptoCodes.Select(c => c.ToUpperInvariant()).ToArray(); foreach (var network in filtered._Networks) { @@ -54,15 +54,15 @@ namespace BTCPayServer InitViacoin(); // Assume that electrum mappings are same as BTC if not specified - foreach (var network in _Networks) + foreach (var network in _Networks.Values.OfType()) { - if(network.Value.ElectrumMapping.Count == 0) + if(network.ElectrumMapping.Count == 0) { - network.Value.ElectrumMapping = GetNetwork("BTC").ElectrumMapping; - if (!network.Value.NBitcoinNetwork.Consensus.SupportSegwit) + network.ElectrumMapping = GetNetwork("BTC").ElectrumMapping; + if (!network.NBitcoinNetwork.Consensus.SupportSegwit) { - network.Value.ElectrumMapping = - network.Value.ElectrumMapping + network.ElectrumMapping = + network.ElectrumMapping .Where(kv => kv.Value == DerivationType.Legacy) .ToDictionary(k => k.Key, k => k.Value); } @@ -86,14 +86,14 @@ namespace BTCPayServer } [Obsolete("To use only for legacy stuff")] - public BTCPayNetwork BTC => GetNetwork("BTC"); + public BTCPayNetwork BTC => GetNetwork("BTC"); - public void Add(BTCPayNetwork network) + public void Add(BTCPayNetworkBase network) { _Networks.Add(network.CryptoCode.ToUpperInvariant(), network); } - public IEnumerable GetAll() + public IEnumerable GetAll() { return _Networks.Values.ToArray(); } @@ -103,14 +103,14 @@ namespace BTCPayServer return _Networks.ContainsKey(cryptoCode.ToUpperInvariant()); } - public BTCPayNetwork GetNetwork(string cryptoCode) + public T GetNetwork(string cryptoCode) where T: BTCPayNetworkBase { - if(!_Networks.TryGetValue(cryptoCode.ToUpperInvariant(), out BTCPayNetwork network)) + if(!_Networks.TryGetValue(cryptoCode.ToUpperInvariant(), out BTCPayNetworkBase network)) { if (cryptoCode == "XBT") - return GetNetwork("BTC"); + return GetNetwork("BTC"); } - return network; + return network as T; } } } diff --git a/BTCPayServer.Rating/CurrencyPair.cs b/BTCPayServer.Rating/CurrencyPair.cs index adeacd603..af4d3ab96 100644 --- a/BTCPayServer.Rating/CurrencyPair.cs +++ b/BTCPayServer.Rating/CurrencyPair.cs @@ -53,7 +53,7 @@ namespace BTCPayServer.Rating for (int i = 3; i < 5; i++) { var potentialCryptoName = currencyPair.Substring(0, i); - var network = _NetworkProvider.GetNetwork(potentialCryptoName); + var network = _NetworkProvider.GetNetwork(potentialCryptoName); if (network != null) { value = new CurrencyPair(network.CryptoCode, currencyPair.Substring(i)); diff --git a/BTCPayServer.Tests/ServerTester.cs b/BTCPayServer.Tests/ServerTester.cs index 24c22887f..433625dcb 100644 --- a/BTCPayServer.Tests/ServerTester.cs +++ b/BTCPayServer.Tests/ServerTester.cs @@ -44,14 +44,14 @@ namespace BTCPayServer.Tests Directory.CreateDirectory(_Directory); NetworkProvider = new BTCPayNetworkProvider(NetworkType.Regtest); - ExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_BTCRPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("BTC").NBitcoinNetwork); + ExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_BTCRPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("BTC").NBitcoinNetwork); ExplorerNode.ScanRPCCapabilities(); - LTCExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_LTCRPCCONNECTION", "server=http://127.0.0.1:43783;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("LTC").NBitcoinNetwork); + LTCExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_LTCRPCCONNECTION", "server=http://127.0.0.1:43783;ceiwHEbqWI83:DwubwWsoo3")), NetworkProvider.GetNetwork("LTC").NBitcoinNetwork); - ExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("BTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_BTCNBXPLORERURL", "http://127.0.0.1:32838/"))); - LTCExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("LTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_LTCNBXPLORERURL", "http://127.0.0.1:32838/"))); + ExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("BTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_BTCNBXPLORERURL", "http://127.0.0.1:32838/"))); + LTCExplorerClient = new ExplorerClient(NetworkProvider.GetNetwork("LTC").NBXplorerNetwork, new Uri(GetEnvironment("TESTS_LTCNBXPLORERURL", "http://127.0.0.1:32838/"))); - var btc = NetworkProvider.GetNetwork("BTC").NBitcoinNetwork; + var btc = NetworkProvider.GetNetwork("BTC").NBitcoinNetwork; CustomerLightningD = LightningClientFactory.CreateClient(GetEnvironment("TEST_CUSTOMERLIGHTNINGD", "type=clightning;server=tcp://127.0.0.1:30992/"), btc); MerchantLightningD = LightningClientFactory.CreateClient(GetEnvironment("TEST_MERCHANTLIGHTNINGD", "type=clightning;server=tcp://127.0.0.1:30993/"), btc); diff --git a/BTCPayServer.Tests/TestAccount.cs b/BTCPayServer.Tests/TestAccount.cs index 88647077c..e93a18b3f 100644 --- a/BTCPayServer.Tests/TestAccount.cs +++ b/BTCPayServer.Tests/TestAccount.cs @@ -95,7 +95,7 @@ namespace BTCPayServer.Tests } public async Task RegisterDerivationSchemeAsync(string cryptoCode, bool segwit = false) { - SupportedNetwork = parent.NetworkProvider.GetNetwork(cryptoCode); + SupportedNetwork = parent.NetworkProvider.GetNetwork(cryptoCode); var store = parent.PayTester.GetController(UserId, StoreId); ExtKey = new ExtKey().GetWif(SupportedNetwork.NBitcoinNetwork); DerivationScheme = new DerivationStrategyFactory(SupportedNetwork.NBitcoinNetwork).Parse(ExtKey.Neuter().ToString() + (segwit ? "" : "-[legacy]")); diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index 225c2f439..780e6c20b 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -1499,8 +1499,8 @@ namespace BTCPayServer.Tests var testnetNetworkProvider = new BTCPayNetworkProvider(NetworkType.Testnet); var regtestNetworkProvider = new BTCPayNetworkProvider(NetworkType.Regtest); var mainnetNetworkProvider = new BTCPayNetworkProvider(NetworkType.Mainnet); - var testnetParser = new DerivationSchemeParser(testnetNetworkProvider.GetNetwork("BTC")); - var mainnetParser = new DerivationSchemeParser(mainnetNetworkProvider.GetNetwork("BTC")); + var testnetParser = new DerivationSchemeParser(testnetNetworkProvider.GetNetwork("BTC")); + var mainnetParser = new DerivationSchemeParser(mainnetNetworkProvider.GetNetwork("BTC")); NBXplorer.DerivationStrategy.DerivationStrategyBase result; // Passing electrum stuff // Passing a native segwit from mainnet to a testnet parser, means the testnet parser will try to convert it into segwit @@ -1543,16 +1543,16 @@ namespace BTCPayServer.Tests result = testnetParser.Parse(tpub); Assert.Equal($"{tpub}-[p2sh]", result.ToString()); - var regtestParser = new DerivationSchemeParser(regtestNetworkProvider.GetNetwork("BTC")); + var regtestParser = new DerivationSchemeParser(regtestNetworkProvider.GetNetwork("BTC")); var parsed = regtestParser.Parse("xpub6DG1rMYXiQtCc6CfdLFD9CtxqhzzRh7j6Sq6EdE9abgYy3cfDRrniLLv2AdwqHL1exiLnnKR5XXcaoiiexf3Y9R6J6rxkJtqJHzNzMW9QMZ-[p2sh]"); Assert.Equal("tpubDDdeNbNDRgqestPX5XEJM8ELAq6eR5cne5RPbBHHvWSSiLHNHehsrn1kGCijMnHFSsFFQMqHcdMfGzDL3pWHRasPMhcGRqZ4tFankQ3i4ok-[p2sh]", parsed.ToString()); // Let's make sure we can't generate segwit with dogecoin - regtestParser = new DerivationSchemeParser(regtestNetworkProvider.GetNetwork("DOGE")); + regtestParser = new DerivationSchemeParser(regtestNetworkProvider.GetNetwork("DOGE")); parsed = regtestParser.Parse("xpub6DG1rMYXiQtCc6CfdLFD9CtxqhzzRh7j6Sq6EdE9abgYy3cfDRrniLLv2AdwqHL1exiLnnKR5XXcaoiiexf3Y9R6J6rxkJtqJHzNzMW9QMZ-[p2sh]"); Assert.Equal("tpubDDdeNbNDRgqestPX5XEJM8ELAq6eR5cne5RPbBHHvWSSiLHNHehsrn1kGCijMnHFSsFFQMqHcdMfGzDL3pWHRasPMhcGRqZ4tFankQ3i4ok-[legacy]", parsed.ToString()); - regtestParser = new DerivationSchemeParser(regtestNetworkProvider.GetNetwork("DOGE")); + regtestParser = new DerivationSchemeParser(regtestNetworkProvider.GetNetwork("DOGE")); parsed = regtestParser.Parse("tpubDDdeNbNDRgqestPX5XEJM8ELAq6eR5cne5RPbBHHvWSSiLHNHehsrn1kGCijMnHFSsFFQMqHcdMfGzDL3pWHRasPMhcGRqZ4tFankQ3i4ok-[p2sh]"); Assert.Equal("tpubDDdeNbNDRgqestPX5XEJM8ELAq6eR5cne5RPbBHHvWSSiLHNHehsrn1kGCijMnHFSsFFQMqHcdMfGzDL3pWHRasPMhcGRqZ4tFankQ3i4ok-[legacy]", parsed.ToString()); } @@ -1569,7 +1569,7 @@ namespace BTCPayServer.Tests user.RegisterDerivationScheme("BTC"); user.RegisterDerivationScheme("LTC"); user.RegisterLightningNode("BTC", LightningConnectionType.CLightning); - var btcNetwork = tester.PayTester.Networks.GetNetwork("BTC"); + var btcNetwork = tester.PayTester.Networks.GetNetwork("BTC"); var invoice = user.BitPay.CreateInvoice(new Invoice() { Price = 1.5m, @@ -2709,7 +2709,7 @@ donation: [Trait("Fast", "Fast")] public void ParseDerivationSchemeSettings() { - var mainnet = new BTCPayNetworkProvider(NetworkType.Mainnet).GetNetwork("BTC"); + var mainnet = new BTCPayNetworkProvider(NetworkType.Mainnet).GetNetwork("BTC"); var root = new Mnemonic("usage fever hen zero slide mammal silent heavy donate budget pulse say brain thank sausage brand craft about save attract muffin advance illegal cabbage").DeriveExtKey(); Assert.True(DerivationSchemeSettings.TryParseFromColdcard("{\"keystore\": {\"ckcc_xpub\": \"xpub661MyMwAqRbcGVBsTGeNZN6QGVHmMHLdSA4FteGsRrEriu4pnVZMZWnruFFFXkMnyoBjyHndD3Qwcfz4MPzBUxjSevweNFQx7SAYZATtcDw\", \"xpub\": \"ypub6WWc2gWwHbdnAAyJDnR4SPL1phRh7REqrPBfZeizaQ1EmTshieRXJC3Z5YoU4wkcdKHEjQGkh6AYEzCQC1Kz3DNaWSwdc1pc8416hAjzqyD\", \"label\": \"Coldcard Import 0x60d1af8b\", \"ckcc_xfp\": 1624354699, \"type\": \"hardware\", \"hw_type\": \"coldcard\", \"derivation\": \"m/49'/0'/0'\"}, \"wallet_type\": \"standard\", \"use_encryption\": false, \"seed_version\": 17}", mainnet, out var settings)); Assert.Equal(root.GetPublicKey().GetHDFingerPrint(), settings.AccountKeySettings[0].RootFingerprint); @@ -2719,7 +2719,7 @@ donation: Assert.Equal("ypub6WWc2gWwHbdnAAyJDnR4SPL1phRh7REqrPBfZeizaQ1EmTshieRXJC3Z5YoU4wkcdKHEjQGkh6AYEzCQC1Kz3DNaWSwdc1pc8416hAjzqyD", settings.AccountOriginal); Assert.Equal(root.Derive(new KeyPath("m/49'/0'/0'")).Neuter().PubKey.WitHash.ScriptPubKey.Hash.ScriptPubKey, settings.AccountDerivation.Derive(new KeyPath()).ScriptPubKey); - var testnet = new BTCPayNetworkProvider(NetworkType.Testnet).GetNetwork("BTC"); + var testnet = new BTCPayNetworkProvider(NetworkType.Testnet).GetNetwork("BTC"); // Should be legacy Assert.True(DerivationSchemeSettings.TryParseFromColdcard("{\"keystore\": {\"ckcc_xpub\": \"tpubD6NzVbkrYhZ4YHNiuTdTmHRmbcPRLfqgyneZFCL1mkzkUBjXriQShxTh9HL34FK2mhieasJVk9EzJrUfkFqRNQBjiXgx3n5BhPkxKBoFmaS\", \"xpub\": \"tpubDDWYqT3P24znfsaGX7kZcQhNc5LAjnQiKQvUCHF2jS6dsgJBRtymopEU5uGpMaR5YChjuiExZG1X2aTbqXkp82KqH5qnqwWHp6EWis9ZvKr\", \"label\": \"Coldcard Import 0x60d1af8b\", \"ckcc_xfp\": 1624354699, \"type\": \"hardware\", \"hw_type\": \"coldcard\", \"derivation\": \"m/44'/1'/0'\"}, \"wallet_type\": \"standard\", \"use_encryption\": false, \"seed_version\": 17}", testnet, out settings)); diff --git a/BTCPayServer/Configuration/BTCPayServerOptions.cs b/BTCPayServer/Configuration/BTCPayServerOptions.cs index 4f1d604c9..36796f41a 100644 --- a/BTCPayServer/Configuration/BTCPayServerOptions.cs +++ b/BTCPayServer/Configuration/BTCPayServerOptions.cs @@ -81,12 +81,12 @@ namespace BTCPayServer.Configuration NetworkProvider = new BTCPayNetworkProvider(NetworkType).Filter(supportedChains.ToArray()); foreach (var chain in supportedChains) { - if (NetworkProvider.GetNetwork(chain) == null) + if (NetworkProvider.GetNetwork(chain) == null) throw new ConfigException($"Invalid chains \"{chain}\""); } var validChains = new List(); - foreach (var net in NetworkProvider.GetAll()) + foreach (var net in NetworkProvider.GetAll().OfType()) { NBXplorerConnectionSetting setting = new NBXplorerConnectionSetting(); setting.CryptoCode = net.CryptoCode; diff --git a/BTCPayServer/Configuration/DefaultConfiguration.cs b/BTCPayServer/Configuration/DefaultConfiguration.cs index df3e5eaca..d1c831a92 100644 --- a/BTCPayServer/Configuration/DefaultConfiguration.cs +++ b/BTCPayServer/Configuration/DefaultConfiguration.cs @@ -46,7 +46,7 @@ namespace BTCPayServer.Configuration app.Option("--debuglog", "A rolling log file for debug messages.", CommandOptionType.SingleValue); app.Option("--debugloglevel", "The severity you log (default:information)", CommandOptionType.SingleValue); app.Option("--disable-registration", "Disables new user registrations (default:true)", CommandOptionType.SingleValue); - foreach (var network in provider.GetAll()) + foreach (var network in provider.GetAll().OfType()) { var crypto = network.CryptoCode.ToLowerInvariant(); app.Option($"--{crypto}explorerurl", $"URL of the NBXplorer for {network.CryptoCode} (default: {network.NBXplorerNetwork.DefaultSettings.DefaultUrl})", CommandOptionType.SingleValue); @@ -121,7 +121,7 @@ namespace BTCPayServer.Configuration builder.AppendLine("#mysql=User ID=root;Password=myPassword;Host=localhost;Port=3306;Database=myDataBase;"); builder.AppendLine(); builder.AppendLine("### NBXplorer settings ###"); - foreach (var n in new BTCPayNetworkProvider(networkType).GetAll()) + foreach (var n in new BTCPayNetworkProvider(networkType).GetAll().OfType()) { builder.AppendLine($"#{n.CryptoCode}.explorer.url={n.NBXplorerNetwork.DefaultSettings.DefaultUrl}"); builder.AppendLine($"#{n.CryptoCode}.explorer.cookiefile={ n.NBXplorerNetwork.DefaultSettings.DefaultCookieFile}"); diff --git a/BTCPayServer/Controllers/InvoiceController.UI.cs b/BTCPayServer/Controllers/InvoiceController.UI.cs index 4d63be560..06f6b0f26 100644 --- a/BTCPayServer/Controllers/InvoiceController.UI.cs +++ b/BTCPayServer/Controllers/InvoiceController.UI.cs @@ -91,7 +91,7 @@ namespace BTCPayServer.Controllers return View(model); } - + //TODO: abstract private InvoiceDetailsModel InvoicePopulatePayments(InvoiceEntity invoice) { var model = new InvoiceDetailsModel(); @@ -117,8 +117,14 @@ namespace BTCPayServer.Controllers foreach (var payment in invoice.GetPayments()) { - var paymentNetwork = _NetworkProvider.GetNetwork(payment.GetCryptoCode()); + //TODO: abstract + var paymentNetwork = _NetworkProvider.GetNetwork(payment.GetCryptoCode()); + if (paymentNetwork == null) + { + continue; + } var paymentData = payment.GetCryptoPaymentData(); + //TODO: abstract if (paymentData is Payments.Bitcoin.BitcoinLikePaymentData onChainPaymentData) { var m = new InvoiceDetailsModel.Payment(); @@ -236,10 +242,10 @@ namespace BTCPayServer.Controllers paymentMethodId = store.GetDefaultPaymentId(_NetworkProvider); isDefaultPaymentId = true; } - var network = _NetworkProvider.GetNetwork(paymentMethodId.CryptoCode); + BTCPayNetworkBase network = _NetworkProvider.GetNetwork(paymentMethodId.CryptoCode); if (network == null && isDefaultPaymentId) { - network = _NetworkProvider.GetAll().FirstOrDefault(); + network = _NetworkProvider.GetAll().OfType().FirstOrDefault(); paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike); } if (invoice == null || network == null) @@ -352,16 +358,17 @@ namespace BTCPayServer.Controllers return model; } - private string GetDisplayName(PaymentMethodId paymentMethodId, BTCPayNetwork network) + private string GetDisplayName(PaymentMethodId paymentMethodId, BTCPayNetworkBase network) { return paymentMethodId.PaymentType == PaymentTypes.BTCLike ? network.DisplayName : network.DisplayName + " (Lightning)"; } - private string GetImage(PaymentMethodId paymentMethodId, BTCPayNetwork network) + private string GetImage(PaymentMethodId paymentMethodId, BTCPayNetworkBase network) { + //the direct casting ((BTCPayNetwork)network) ) for ln image is only temp..this method is offloaded to payment handlers in other pull requests return paymentMethodId.PaymentType == PaymentTypes.BTCLike ? - this.Request.GetRelativePathOrAbsolute(network.CryptoImagePath) : this.Request.GetRelativePathOrAbsolute(network.LightningImagePath); + this.Request.GetRelativePathOrAbsolute(network.CryptoImagePath) : this.Request.GetRelativePathOrAbsolute(((BTCPayNetwork)network).LightningImagePath); } private string OrderAmountFromInvoice(string cryptoCode, ProductInformation productInformation) diff --git a/BTCPayServer/Controllers/InvoiceController.cs b/BTCPayServer/Controllers/InvoiceController.cs index ed075be7f..3c16060c2 100644 --- a/BTCPayServer/Controllers/InvoiceController.cs +++ b/BTCPayServer/Controllers/InvoiceController.cs @@ -152,7 +152,7 @@ namespace BTCPayServer.Controllers foreach (var network in store.GetSupportedPaymentMethods(_NetworkProvider) .Where(s => !excludeFilter.Match(s.PaymentId)) - .Select(c => _NetworkProvider.GetNetwork(c.PaymentId.CryptoCode)) + .Select(c => _NetworkProvider.GetNetwork(c.PaymentId.CryptoCode)) .Where(c => c != null)) { currencyPairsToFetch.Add(new CurrencyPair(network.CryptoCode, invoice.Currency)); @@ -170,7 +170,7 @@ namespace BTCPayServer.Controllers .Select(c => (Handler: (IPaymentMethodHandler)_ServiceProvider.GetService(typeof(IPaymentMethodHandler<>).MakeGenericType(c.GetType())), SupportedPaymentMethod: c, - Network: _NetworkProvider.GetNetwork(c.PaymentId.CryptoCode))) + Network: _NetworkProvider.GetNetwork(c.PaymentId.CryptoCode))) .Where(c => c.Network != null) .Select(o => (SupportedPaymentMethod: o.SupportedPaymentMethod, @@ -247,7 +247,7 @@ namespace BTCPayServer.Controllers }).ToArray()); } - private async Task CreatePaymentMethodAsync(Dictionary> fetchingByCurrencyPair, IPaymentMethodHandler handler, ISupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network, InvoiceEntity entity, StoreData store, InvoiceLogs logs) + private async Task CreatePaymentMethodAsync(Dictionary> fetchingByCurrencyPair, IPaymentMethodHandler handler, ISupportedPaymentMethod supportedPaymentMethod, BTCPayNetworkBase network, InvoiceEntity entity, StoreData store, InvoiceLogs logs) { try { diff --git a/BTCPayServer/Controllers/PublicLightningNodeInfoController.cs b/BTCPayServer/Controllers/PublicLightningNodeInfoController.cs index 33111d947..3095bc507 100644 --- a/BTCPayServer/Controllers/PublicLightningNodeInfoController.cs +++ b/BTCPayServer/Controllers/PublicLightningNodeInfoController.cs @@ -41,7 +41,7 @@ namespace BTCPayServer.Controllers try { var paymentMethodDetails = GetExistingLightningSupportedPaymentMethod(cryptoCode, store); - var network = _BtcPayNetworkProvider.GetNetwork(cryptoCode); + var network = _BtcPayNetworkProvider.GetNetwork(cryptoCode); var nodeInfo = await _LightningLikePaymentHandler.GetNodeInfo(this.Request.IsOnion(), paymentMethodDetails, network); diff --git a/BTCPayServer/Controllers/StoresController.BTCLike.cs b/BTCPayServer/Controllers/StoresController.BTCLike.cs index cc4d6e59f..98ea11f86 100644 --- a/BTCPayServer/Controllers/StoresController.BTCLike.cs +++ b/BTCPayServer/Controllers/StoresController.BTCLike.cs @@ -66,7 +66,7 @@ namespace BTCPayServer.Controllers var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); var hw = new LedgerHardwareWalletService(webSocket); object result = null; - var network = _NetworkProvider.GetNetwork(cryptoCode); + var network = _NetworkProvider.GetNetwork(cryptoCode); using (var normalOperationTimeout = new CancellationTokenSource()) { diff --git a/BTCPayServer/Controllers/StoresController.LightningLike.cs b/BTCPayServer/Controllers/StoresController.LightningLike.cs index f37c10b14..a5f998c8f 100644 --- a/BTCPayServer/Controllers/StoresController.LightningLike.cs +++ b/BTCPayServer/Controllers/StoresController.LightningLike.cs @@ -152,7 +152,7 @@ namespace BTCPayServer.Controllers ModelState.AddModelError(nameof(vm.ConnectionString), "Missing url parameter"); return View(vm); case "test": - var handler = (LightningLikePaymentHandler)_ServiceProvider.GetRequiredService>(); + var handler = _ServiceProvider.GetRequiredService(); try { var info = await handler.GetNodeInfo(this.Request.IsOnion(), paymentMethod, network); diff --git a/BTCPayServer/Controllers/StoresController.cs b/BTCPayServer/Controllers/StoresController.cs index 22939923d..ab1fbf731 100644 --- a/BTCPayServer/Controllers/StoresController.cs +++ b/BTCPayServer/Controllers/StoresController.cs @@ -372,7 +372,7 @@ namespace BTCPayServer.Controllers private string GetDisplayName(PaymentMethodId paymentMethodId) { - var display = _NetworkProvider.GetNetwork(paymentMethodId.CryptoCode)?.DisplayName ?? paymentMethodId.CryptoCode; + var display = _NetworkProvider.GetNetwork(paymentMethodId.CryptoCode)?.DisplayName ?? paymentMethodId.CryptoCode; return paymentMethodId.PaymentType == PaymentTypes.BTCLike ? display : $"{display} (Lightning)"; } diff --git a/BTCPayServer/Controllers/WalletsController.PSBT.cs b/BTCPayServer/Controllers/WalletsController.PSBT.cs index d70867b9e..365304760 100644 --- a/BTCPayServer/Controllers/WalletsController.PSBT.cs +++ b/BTCPayServer/Controllers/WalletsController.PSBT.cs @@ -52,7 +52,7 @@ namespace BTCPayServer.Controllers public async Task WalletPSBT([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId, WalletPSBTViewModel vm) { - var network = NetworkProvider.GetNetwork(walletId.CryptoCode); + var network = NetworkProvider.GetNetwork(walletId.CryptoCode); if (await vm.GetPSBT(network.NBitcoinNetwork) is PSBT psbt) { vm.Decoded = psbt.ToString(); @@ -67,7 +67,7 @@ namespace BTCPayServer.Controllers WalletId walletId, WalletPSBTViewModel vm, string command = null) { - var network = NetworkProvider.GetNetwork(walletId.CryptoCode); + var network = NetworkProvider.GetNetwork(walletId.CryptoCode); var psbt = await vm.GetPSBT(network.NBitcoinNetwork); if (psbt == null) { @@ -110,7 +110,7 @@ namespace BTCPayServer.Controllers string signingKey = null, string signingKeyPath = null) { - var network = NetworkProvider.GetNetwork(walletId.CryptoCode); + var network = NetworkProvider.GetNetwork(walletId.CryptoCode); var vm = new WalletPSBTReadyViewModel() { PSBT = psbt }; vm.SigningKey = signingKey; vm.SigningKeyPath = signingKeyPath; @@ -209,7 +209,7 @@ namespace BTCPayServer.Controllers WalletId walletId, WalletPSBTReadyViewModel vm, string command = null) { PSBT psbt = null; - var network = NetworkProvider.GetNetwork(walletId.CryptoCode); + var network = NetworkProvider.GetNetwork(walletId.CryptoCode); try { psbt = PSBT.Parse(vm.PSBT, network.NBitcoinNetwork); @@ -286,7 +286,7 @@ namespace BTCPayServer.Controllers public async Task WalletPSBTCombine([ModelBinder(typeof(WalletIdModelBinder))] WalletId walletId, WalletPSBTCombineViewModel vm) { - var network = NetworkProvider.GetNetwork(walletId.CryptoCode); + var network = NetworkProvider.GetNetwork(walletId.CryptoCode); var psbt = await vm.GetPSBT(network.NBitcoinNetwork); if (psbt == null) { diff --git a/BTCPayServer/Controllers/WalletsController.cs b/BTCPayServer/Controllers/WalletsController.cs index 8f52f839c..1d14d716e 100644 --- a/BTCPayServer/Controllers/WalletsController.cs +++ b/BTCPayServer/Controllers/WalletsController.cs @@ -156,7 +156,7 @@ namespace BTCPayServer.Controllers DerivationSchemeSettings paymentMethod = GetDerivationSchemeSettings(walletId, store); if (paymentMethod == null) return NotFound(); - var network = this.NetworkProvider.GetNetwork(walletId?.CryptoCode); + var network = this.NetworkProvider.GetNetwork(walletId?.CryptoCode); if (network == null) return NotFound(); var storeData = store.GetStoreBlob(); @@ -218,7 +218,7 @@ namespace BTCPayServer.Controllers var store = await Repository.FindStore(walletId.StoreId, GetUserId()); if (store == null) return NotFound(); - var network = this.NetworkProvider.GetNetwork(walletId?.CryptoCode); + var network = this.NetworkProvider.GetNetwork(walletId?.CryptoCode); if (network == null) return NotFound(); vm.SupportRBF = network.SupportRBF; @@ -360,7 +360,7 @@ namespace BTCPayServer.Controllers { return View(viewModel); } - var network = NetworkProvider.GetNetwork(walletId.CryptoCode); + var network = NetworkProvider.GetNetwork(walletId.CryptoCode); if (network == null) throw new FormatException("Invalid value for crypto code"); @@ -413,7 +413,7 @@ namespace BTCPayServer.Controllers return await WalletPSBTReady(walletId, psbt.ToBase64(), signingKey.GetWif(network.NBitcoinNetwork).ToString(), rootedKeyPath.ToString()); } - private string ValueToString(Money v, BTCPayNetwork network) + private string ValueToString(Money v, BTCPayNetworkBase network) { return v.ToString() + " " + network.CryptoCode; } @@ -433,7 +433,7 @@ namespace BTCPayServer.Controllers private async Task RedirectToWalletTransaction(WalletId walletId, Transaction transaction) { - var network = NetworkProvider.GetNetwork(walletId.CryptoCode); + var network = NetworkProvider.GetNetwork(walletId.CryptoCode); if (transaction != null) { var wallet = _walletProvider.GetWallet(network); @@ -578,7 +578,7 @@ namespace BTCPayServer.Controllers if (!HttpContext.WebSockets.IsWebSocketRequest) return NotFound(); - var network = NetworkProvider.GetNetwork(walletId.CryptoCode); + var network = NetworkProvider.GetNetwork(walletId.CryptoCode); if (network == null) throw new FormatException("Invalid value for crypto code"); var storeData = (await Repository.FindStore(walletId.StoreId, GetUserId())); diff --git a/BTCPayServer/Data/StoreData.cs b/BTCPayServer/Data/StoreData.cs index 9212ed1c2..e8fe7d360 100644 --- a/BTCPayServer/Data/StoreData.cs +++ b/BTCPayServer/Data/StoreData.cs @@ -84,7 +84,7 @@ namespace BTCPayServer.Data foreach (var strat in strategies.Properties()) { var paymentMethodId = PaymentMethodId.Parse(strat.Name); - var network = networks.GetNetwork(paymentMethodId.CryptoCode); + var network = networks.GetNetwork(paymentMethodId.CryptoCode); if (network != null) { if (network == networks.BTC && paymentMethodId.PaymentType == PaymentTypes.BTCLike && btcReturned) @@ -282,7 +282,7 @@ namespace BTCPayServer.Data public double Multiplier { get; set; } - public decimal Apply(BTCPayNetwork network, decimal rate) + public decimal Apply(BTCPayNetworkBase network, decimal rate) { return rate * (decimal)Multiplier; } diff --git a/BTCPayServer/Events/InvoiceNewAddressEvent.cs b/BTCPayServer/Events/InvoiceNewAddressEvent.cs index b485cfa19..5c7c68153 100644 --- a/BTCPayServer/Events/InvoiceNewAddressEvent.cs +++ b/BTCPayServer/Events/InvoiceNewAddressEvent.cs @@ -7,7 +7,7 @@ namespace BTCPayServer.Events { public class InvoiceNewAddressEvent { - public InvoiceNewAddressEvent(string invoiceId, string address, BTCPayNetwork network) + public InvoiceNewAddressEvent(string invoiceId, string address, BTCPayNetworkBase network) { Address = address; InvoiceId = invoiceId; @@ -16,7 +16,7 @@ namespace BTCPayServer.Events public string Address { get; set; } public string InvoiceId { get; set; } - public BTCPayNetwork Network { get; set; } + public BTCPayNetworkBase Network { get; set; } public override string ToString() { return $"{Network.CryptoCode}: New address {Address} for invoice {InvoiceId}"; diff --git a/BTCPayServer/Events/NBXplorerStateChangedEvent.cs b/BTCPayServer/Events/NBXplorerStateChangedEvent.cs index 5774140ff..62d7ba8c4 100644 --- a/BTCPayServer/Events/NBXplorerStateChangedEvent.cs +++ b/BTCPayServer/Events/NBXplorerStateChangedEvent.cs @@ -8,14 +8,14 @@ namespace BTCPayServer.Events { public class NBXplorerStateChangedEvent { - public NBXplorerStateChangedEvent(BTCPayNetwork network, NBXplorerState old, NBXplorerState newState) + public NBXplorerStateChangedEvent(BTCPayNetworkBase network, NBXplorerState old, NBXplorerState newState) { Network = network; NewState = newState; OldState = old; } - public BTCPayNetwork Network { get; set; } + public BTCPayNetworkBase Network { get; set; } public NBXplorerState NewState { get; set; } public NBXplorerState OldState { get; set; } diff --git a/BTCPayServer/ExplorerClientProvider.cs b/BTCPayServer/ExplorerClientProvider.cs index b3888e30c..44614243b 100644 --- a/BTCPayServer/ExplorerClientProvider.cs +++ b/BTCPayServer/ExplorerClientProvider.cs @@ -33,7 +33,7 @@ namespace BTCPayServer Logs.Configuration.LogInformation($"{setting.CryptoCode}: Cookie file is {(setting.CookieFile ?? "not set")}"); if (setting.ExplorerUri != null) { - _Clients.TryAdd(setting.CryptoCode, CreateExplorerClient(httpClientFactory.CreateClient($"NBXPLORER_{setting.CryptoCode}"), _NetworkProviders.GetNetwork(setting.CryptoCode), setting.ExplorerUri, setting.CookieFile)); + _Clients.TryAdd(setting.CryptoCode, CreateExplorerClient(httpClientFactory.CreateClient($"NBXPLORER_{setting.CryptoCode}"), _NetworkProviders.GetNetwork(setting.CryptoCode), setting.ExplorerUri, setting.CookieFile)); } } } @@ -58,21 +58,21 @@ namespace BTCPayServer public ExplorerClient GetExplorerClient(string cryptoCode) { - var network = _NetworkProviders.GetNetwork(cryptoCode); + var network = _NetworkProviders.GetNetwork(cryptoCode); if (network == null) return null; _Clients.TryGetValue(network.CryptoCode, out ExplorerClient client); return client; } - public ExplorerClient GetExplorerClient(BTCPayNetwork network) + public ExplorerClient GetExplorerClient(BTCPayNetworkBase network) { if (network == null) throw new ArgumentNullException(nameof(network)); return GetExplorerClient(network.CryptoCode); } - public bool IsAvailable(BTCPayNetwork network) + public bool IsAvailable(BTCPayNetworkBase network) { return IsAvailable(network.CryptoCode); } @@ -84,7 +84,7 @@ namespace BTCPayServer public BTCPayNetwork GetNetwork(string cryptoCode) { - var network = _NetworkProviders.GetNetwork(cryptoCode); + var network = _NetworkProviders.GetNetwork(cryptoCode); if (network == null) return null; if (_Clients.ContainsKey(network.CryptoCode)) @@ -94,7 +94,7 @@ namespace BTCPayServer public IEnumerable<(BTCPayNetwork, ExplorerClient)> GetAll() { - foreach (var net in _NetworkProviders.GetAll()) + foreach (var net in _NetworkProviders.GetAll().OfType()) { if (_Clients.TryGetValue(net.CryptoCode, out ExplorerClient explorer)) { diff --git a/BTCPayServer/HostedServices/InvoiceWatcher.cs b/BTCPayServer/HostedServices/InvoiceWatcher.cs index 7c143ff74..e74187a36 100644 --- a/BTCPayServer/HostedServices/InvoiceWatcher.cs +++ b/BTCPayServer/HostedServices/InvoiceWatcher.cs @@ -78,7 +78,7 @@ namespace BTCPayServer.HostedServices var paymentMethod = GetNearestClearedPayment(allPaymentMethods, out var accounting, _NetworkProvider); if (paymentMethod == null) return; - var network = _NetworkProvider.GetNetwork(paymentMethod.GetId().CryptoCode); + var network = _NetworkProvider.GetNetwork(paymentMethod.GetId().CryptoCode); if (invoice.Status == InvoiceStatus.New || invoice.Status == InvoiceStatus.Expired) { if (accounting.Paid >= accounting.MinimumTotalDue) @@ -173,7 +173,7 @@ namespace BTCPayServer.HostedServices decimal nearestToZero = 0.0m; foreach (var paymentMethod in allPaymentMethods) { - if (networkProvider != null && networkProvider.GetNetwork(paymentMethod.GetId().CryptoCode) == null) + if (networkProvider != null && networkProvider.GetNetwork(paymentMethod.GetId().CryptoCode) == null) continue; var currentAccounting = paymentMethod.Calculate(); var distanceFromZero = Math.Abs(currentAccounting.DueUncapped.ToDecimal(MoneyUnit.BTC)); @@ -324,7 +324,7 @@ namespace BTCPayServer.HostedServices .GetPayments() .Select>(async payment => { - var paymentNetwork = _NetworkProvider.GetNetwork(payment.GetCryptoCode()); + var paymentNetwork = _NetworkProvider.GetNetwork(payment.GetCryptoCode()); var paymentData = payment.GetCryptoPaymentData(); if (paymentData is Payments.Bitcoin.BitcoinLikePaymentData onChainPaymentData) { diff --git a/BTCPayServer/HostedServices/NBXplorerWaiter.cs b/BTCPayServer/HostedServices/NBXplorerWaiter.cs index 1fe07bb6e..04cdf858c 100644 --- a/BTCPayServer/HostedServices/NBXplorerWaiter.cs +++ b/BTCPayServer/HostedServices/NBXplorerWaiter.cs @@ -24,13 +24,13 @@ namespace BTCPayServer.HostedServices { public class NBXplorerSummary { - public BTCPayNetwork Network { get; set; } + public BTCPayNetworkBase Network { get; set; } public NBXplorerState State { get; set; } public StatusResult Status { get; set; } public string Error { get; set; } } ConcurrentDictionary _Summaries = new ConcurrentDictionary(); - public void Publish(BTCPayNetwork network, NBXplorerState state, StatusResult status, string error) + public void Publish(BTCPayNetworkBase network, NBXplorerState state, StatusResult status, string error) { var summary = new NBXplorerSummary() { Network = network, State = state, Status = status, Error = error }; _Summaries.AddOrUpdate(network.CryptoCode, summary, (k, v) => summary); diff --git a/BTCPayServer/ModelBinders/DerivationSchemeModelBinder.cs b/BTCPayServer/ModelBinders/DerivationSchemeModelBinder.cs index 2b47c1024..e7fc7f32f 100644 --- a/BTCPayServer/ModelBinders/DerivationSchemeModelBinder.cs +++ b/BTCPayServer/ModelBinders/DerivationSchemeModelBinder.cs @@ -39,7 +39,7 @@ namespace BTCPayServer.ModelBinders var networkProvider = (BTCPayNetworkProvider)bindingContext.HttpContext.RequestServices.GetService(typeof(BTCPayNetworkProvider)); var cryptoCode = bindingContext.ValueProvider.GetValue("cryptoCode").FirstValue; - var network = networkProvider.GetNetwork(cryptoCode ?? "BTC"); + var network = networkProvider.GetNetwork(cryptoCode ?? "BTC"); try { var data = new DerivationStrategyFactory(network.NBitcoinNetwork).Parse(key); diff --git a/BTCPayServer/PaymentRequest/PaymentRequestService.cs b/BTCPayServer/PaymentRequest/PaymentRequestService.cs index 44918ca85..42b19ff95 100644 --- a/BTCPayServer/PaymentRequest/PaymentRequestService.cs +++ b/BTCPayServer/PaymentRequest/PaymentRequestService.cs @@ -104,7 +104,8 @@ namespace BTCPayServer.PaymentRequest Status = entity.GetInvoiceState().ToString(), Payments = entity.GetPayments().Select(paymentEntity => { - var paymentNetwork = _BtcPayNetworkProvider.GetNetwork(paymentEntity.GetCryptoCode()); + //TODO: abstract + var paymentNetwork = _BtcPayNetworkProvider.GetNetwork(paymentEntity.GetCryptoCode()); var paymentData = paymentEntity.GetCryptoPaymentData(); string link = null; string txId = null; diff --git a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentData.cs b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentData.cs index 2f1f236fb..885262127 100644 --- a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentData.cs +++ b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentData.cs @@ -54,12 +54,12 @@ namespace BTCPayServer.Payments.Bitcoin return Output.Value.ToDecimal(MoneyUnit.BTC); } - public bool PaymentCompleted(PaymentEntity entity, BTCPayNetwork network) + public bool PaymentCompleted(PaymentEntity entity, BTCPayNetworkBase network) { return ConfirmationCount >= network.MaxTrackedConfirmation; } - public bool PaymentConfirmed(PaymentEntity entity, SpeedPolicy speedPolicy, BTCPayNetwork network) + public bool PaymentConfirmed(PaymentEntity entity, SpeedPolicy speedPolicy, BTCPayNetworkBase network) { if (speedPolicy == SpeedPolicy.HighSpeed) { @@ -80,12 +80,12 @@ namespace BTCPayServer.Payments.Bitcoin return false; } - public BitcoinAddress GetDestination(BTCPayNetwork network) + public BitcoinAddress GetDestination(BTCPayNetworkBase network) { - return Output.ScriptPubKey.GetDestinationAddress(network.NBitcoinNetwork); + return Output.ScriptPubKey.GetDestinationAddress(((BTCPayNetwork)network).NBitcoinNetwork); } - string CryptoPaymentData.GetDestination(BTCPayNetwork network) + string CryptoPaymentData.GetDestination(BTCPayNetworkBase network) { return GetDestination(network).ToString(); } diff --git a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs index 3fbb21dfd..ba7896265 100644 --- a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs @@ -33,7 +33,7 @@ namespace BTCPayServer.Payments.Bitcoin public Task ReserveAddress; } - public override object PreparePayment(DerivationSchemeSettings supportedPaymentMethod, StoreData store, BTCPayNetwork network) + public override object PreparePayment(DerivationSchemeSettings supportedPaymentMethod, StoreData store, BTCPayNetworkBase network) { return new Prepare() { @@ -45,7 +45,9 @@ namespace BTCPayServer.Payments.Bitcoin public override string PrettyDescription => "On-Chain"; public override PaymentTypes PaymentType => PaymentTypes.BTCLike; - public override async Task CreatePaymentMethodDetails(DerivationSchemeSettings supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network, object preparePaymentObject) + public override async Task CreatePaymentMethodDetails( + DerivationSchemeSettings supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, + BTCPayNetworkBase network, object preparePaymentObject) { if (!_ExplorerProvider.IsAvailable(network)) throw new PaymentMethodUnavailableException($"Full node not available"); diff --git a/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs b/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs index f6bef01af..4963bc8e6 100644 --- a/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs +++ b/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs @@ -310,7 +310,7 @@ namespace BTCPayServer.Payments.Bitcoin return new TransactionConflicts(conflictsByOutpoint.Where(c => c.Value.Transactions.Count > 1).Select(c => c.Value)); } - private async Task FindPaymentViaPolling(BTCPayWallet wallet, BTCPayNetwork network) + private async Task FindPaymentViaPolling(BTCPayWallet wallet, BTCPayNetworkBase network) { int totalPayment = 0; var invoices = await _InvoiceRepository.GetPendingInvoices(); @@ -347,7 +347,7 @@ namespace BTCPayServer.Payments.Bitcoin return totalPayment; } - private DerivationStrategyBase GetDerivationStrategy(InvoiceEntity invoice, BTCPayNetwork network) + private DerivationStrategyBase GetDerivationStrategy(InvoiceEntity invoice, BTCPayNetworkBase network) { return invoice.GetSupportedPaymentMethod(new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike)) .Select(d => d.AccountDerivation) diff --git a/BTCPayServer/Payments/IPaymentMethodHandler.cs b/BTCPayServer/Payments/IPaymentMethodHandler.cs index ab60a68b4..0867a6e0b 100644 --- a/BTCPayServer/Payments/IPaymentMethodHandler.cs +++ b/BTCPayServer/Payments/IPaymentMethodHandler.cs @@ -19,8 +19,9 @@ namespace BTCPayServer.Payments /// /// /// + /// /// - Task CreatePaymentMethodDetails(ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network, object preparePaymentObject); + Task CreatePaymentMethodDetails(ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetworkBase network, object preparePaymentObject); /// /// This method called before the rate have been fetched @@ -29,7 +30,7 @@ namespace BTCPayServer.Payments /// /// /// - object PreparePayment(ISupportedPaymentMethod supportedPaymentMethod, StoreData store, BTCPayNetwork network); + object PreparePayment(ISupportedPaymentMethod supportedPaymentMethod, StoreData store, BTCPayNetworkBase network); bool CanHandle(PaymentMethodId paymentMethodId); @@ -38,20 +39,23 @@ namespace BTCPayServer.Payments public interface IPaymentMethodHandler : IPaymentMethodHandler where T : ISupportedPaymentMethod { - Task CreatePaymentMethodDetails(T supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network, object preparePaymentObject); + Task CreatePaymentMethodDetails(T supportedPaymentMethod, PaymentMethod paymentMethod, + StoreData store, BTCPayNetworkBase network, object preparePaymentObject); } public abstract class PaymentMethodHandlerBase : IPaymentMethodHandler where T : ISupportedPaymentMethod { public abstract string PrettyDescription { get; } public abstract PaymentTypes PaymentType { get; } - public abstract Task CreatePaymentMethodDetails(T supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network, object preparePaymentObject); - public virtual object PreparePayment(T supportedPaymentMethod, StoreData store, BTCPayNetwork network) + public abstract Task CreatePaymentMethodDetails(T supportedPaymentMethod, + PaymentMethod paymentMethod, StoreData store, BTCPayNetworkBase network, object preparePaymentObject); + public virtual object PreparePayment(T supportedPaymentMethod, StoreData store, BTCPayNetworkBase network) { return null; } - object IPaymentMethodHandler.PreparePayment(ISupportedPaymentMethod supportedPaymentMethod, StoreData store, BTCPayNetwork network) + object IPaymentMethodHandler.PreparePayment(ISupportedPaymentMethod supportedPaymentMethod, StoreData store, + BTCPayNetworkBase network) { if (supportedPaymentMethod is T method) { @@ -70,7 +74,9 @@ namespace BTCPayServer.Payments return $"{paymentMethodId.CryptoCode} ({PrettyDescription})"; } - Task IPaymentMethodHandler.CreatePaymentMethodDetails(ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network, object preparePaymentObject) + Task IPaymentMethodHandler.CreatePaymentMethodDetails( + ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, + BTCPayNetworkBase network, object preparePaymentObject) { if (supportedPaymentMethod is T method) { diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentData.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentData.cs index e7246e34a..47f85f8e3 100644 --- a/BTCPayServer/Payments/Lightning/LightningLikePaymentData.cs +++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentData.cs @@ -20,7 +20,7 @@ namespace BTCPayServer.Payments.Lightning [JsonConverter(typeof(NBitcoin.JsonConverters.UInt256JsonConverter))] public uint256 PaymentHash { get; set; } - public string GetDestination(BTCPayNetwork network) + public string GetDestination(BTCPayNetworkBase network) { return BOLT11; } @@ -49,12 +49,12 @@ namespace BTCPayServer.Payments.Lightning return Amount.ToDecimal(LightMoneyUnit.BTC); } - public bool PaymentCompleted(PaymentEntity entity, BTCPayNetwork network) + public bool PaymentCompleted(PaymentEntity entity, BTCPayNetworkBase network) { return true; } - public bool PaymentConfirmed(PaymentEntity entity, SpeedPolicy speedPolicy, BTCPayNetwork network) + public bool PaymentConfirmed(PaymentEntity entity, SpeedPolicy speedPolicy, BTCPayNetworkBase network) { return true; } diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs index 2c4990d91..f6a44e9f4 100644 --- a/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentHandler.cs @@ -34,13 +34,16 @@ namespace BTCPayServer.Payments.Lightning public override string PrettyDescription => "Off-Chain"; public override PaymentTypes PaymentType => PaymentTypes.LightningLike; - public override async Task CreatePaymentMethodDetails(LightningSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetwork network, object preparePaymentObject) + public override async Task CreatePaymentMethodDetails( + LightningSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, + BTCPayNetworkBase network, object preparePaymentObject) { + //direct casting to (BTCPayNetwork) is fixed in other pull requests with better generic interfacing for handlers var storeBlob = store.GetStoreBlob(); - var test = GetNodeInfo(paymentMethod.PreferOnion, supportedPaymentMethod, network); + var test = GetNodeInfo(paymentMethod.PreferOnion, supportedPaymentMethod, (BTCPayNetwork)network); var invoice = paymentMethod.ParentEntity; var due = Extensions.RoundUp(invoice.ProductInformation.Price / paymentMethod.Rate, 8); - var client = _lightningClientFactory.Create(supportedPaymentMethod.GetLightningUrl(), network); + var client = _lightningClientFactory.Create(supportedPaymentMethod.GetLightningUrl(), (BTCPayNetwork)network); var expiry = invoice.ExpirationTime - DateTimeOffset.UtcNow; if (expiry < TimeSpan.Zero) expiry = TimeSpan.FromSeconds(1); diff --git a/BTCPayServer/Payments/Lightning/LightningListener.cs b/BTCPayServer/Payments/Lightning/LightningListener.cs index 3e4ad8df8..57101a677 100644 --- a/BTCPayServer/Payments/Lightning/LightningListener.cs +++ b/BTCPayServer/Payments/Lightning/LightningListener.cs @@ -105,7 +105,7 @@ namespace BTCPayServer.Payments.Lightning .FirstOrDefault(c => c.CryptoCode == paymentMethod.GetId().CryptoCode); if (lightningSupportedMethod == null) continue; - var network = _NetworkProvider.GetNetwork(paymentMethod.GetId().CryptoCode); + var network = _NetworkProvider.GetNetwork(paymentMethod.GetId().CryptoCode); listenedInvoices.Add(new ListenedInvoice() { diff --git a/BTCPayServer/Payments/PaymentMethodExtensions.cs b/BTCPayServer/Payments/PaymentMethodExtensions.cs index e2ab69676..8df1a10db 100644 --- a/BTCPayServer/Payments/PaymentMethodExtensions.cs +++ b/BTCPayServer/Payments/PaymentMethodExtensions.cs @@ -10,20 +10,21 @@ namespace BTCPayServer.Payments { public class PaymentMethodExtensions { - public static ISupportedPaymentMethod Deserialize(PaymentMethodId paymentMethodId, JToken value, BTCPayNetwork network) + public static ISupportedPaymentMethod Deserialize(PaymentMethodId paymentMethodId, JToken value, BTCPayNetworkBase network) { if (paymentMethodId.PaymentType == PaymentTypes.BTCLike) { + var bitcoinSpecificBtcPayNetwork = (BTCPayNetwork)network; if (value is JObject jobj) { - var scheme = network.NBXplorerNetwork.Serializer.ToObject(jobj); - scheme.Network = network; + var scheme = bitcoinSpecificBtcPayNetwork.NBXplorerNetwork.Serializer.ToObject(jobj); + scheme.Network = bitcoinSpecificBtcPayNetwork; return scheme; } // Legacy else { - return BTCPayServer.DerivationSchemeSettings.Parse(((JValue)value).Value(), network); + return BTCPayServer.DerivationSchemeSettings.Parse(((JValue)value).Value(), bitcoinSpecificBtcPayNetwork); } } ////////// diff --git a/BTCPayServer/Services/Fees/IFeeProviderFactory.cs b/BTCPayServer/Services/Fees/IFeeProviderFactory.cs index 07d2af778..3b2cb5bec 100644 --- a/BTCPayServer/Services/Fees/IFeeProviderFactory.cs +++ b/BTCPayServer/Services/Fees/IFeeProviderFactory.cs @@ -7,6 +7,6 @@ namespace BTCPayServer.Services { public interface IFeeProviderFactory { - IFeeProvider CreateFeeProvider(BTCPayNetwork network); + IFeeProvider CreateFeeProvider(BTCPayNetworkBase network); } } diff --git a/BTCPayServer/Services/Fees/NBxplorerFeeProvider.cs b/BTCPayServer/Services/Fees/NBxplorerFeeProvider.cs index f5f1f8d3b..a2129d04b 100644 --- a/BTCPayServer/Services/Fees/NBxplorerFeeProvider.cs +++ b/BTCPayServer/Services/Fees/NBxplorerFeeProvider.cs @@ -21,7 +21,7 @@ namespace BTCPayServer.Services.Fees public FeeRate Fallback { get; set; } public int BlockTarget { get; set; } - public IFeeProvider CreateFeeProvider(BTCPayNetwork network) + public IFeeProvider CreateFeeProvider(BTCPayNetworkBase network) { return new NBXplorerFeeProvider(this, _ExplorerClients.GetExplorerClient(network)); } diff --git a/BTCPayServer/Services/Invoices/Export/InvoiceExport.cs b/BTCPayServer/Services/Invoices/Export/InvoiceExport.cs index 248f23e55..b8f2bfd7e 100644 --- a/BTCPayServer/Services/Invoices/Export/InvoiceExport.cs +++ b/BTCPayServer/Services/Invoices/Export/InvoiceExport.cs @@ -78,7 +78,7 @@ namespace BTCPayServer.Services.Invoices.Export CryptoCode = cryptoCode, ConversionRate = pmethod.Rate, PaymentType = payment.GetPaymentMethodId().PaymentType == Payments.PaymentTypes.BTCLike ? "OnChain" : "OffChain", - Destination = payment.GetCryptoPaymentData().GetDestination(Networks.GetNetwork(cryptoCode)), + Destination = payment.GetCryptoPaymentData().GetDestination(Networks.GetNetwork(cryptoCode)), Paid = pdata.GetValue().ToString(CultureInfo.InvariantCulture), PaidCurrency = Math.Round(pdata.GetValue() * pmethod.Rate, currency.NumberDecimalDigits).ToString(CultureInfo.InvariantCulture), // Adding NetworkFee because Paid doesn't take into account network fees diff --git a/BTCPayServer/Services/Invoices/InvoiceEntity.cs b/BTCPayServer/Services/Invoices/InvoiceEntity.cs index 353f7eb48..bda745b69 100644 --- a/BTCPayServer/Services/Invoices/InvoiceEntity.cs +++ b/BTCPayServer/Services/Invoices/InvoiceEntity.cs @@ -213,7 +213,7 @@ namespace BTCPayServer.Services.Invoices foreach (var strat in strategies.Properties()) { var paymentMethodId = PaymentMethodId.Parse(strat.Name); - var network = Networks.GetNetwork(paymentMethodId.CryptoCode); + var network = Networks.GetNetwork(paymentMethodId.CryptoCode); if (network != null) { if (network == Networks.BTC && paymentMethodId.PaymentType == PaymentTypes.BTCLike) @@ -280,7 +280,7 @@ namespace BTCPayServer.Services.Invoices { return Payments.Where(p => p.CryptoCode == cryptoCode).ToList(); } - public List GetPayments(BTCPayNetwork network) + public List GetPayments(BTCPayNetworkBase network) { return GetPayments(network.CryptoCode); } @@ -521,7 +521,7 @@ namespace BTCPayServer.Services.Invoices GetPaymentMethods().TryGetValue(paymentMethodId, out var data); return data; } - public PaymentMethod GetPaymentMethod(BTCPayNetwork network, PaymentTypes paymentType, BTCPayNetworkProvider networkProvider) + public PaymentMethod GetPaymentMethod(BTCPayNetworkBase network, PaymentTypes paymentType, BTCPayNetworkProvider networkProvider) { return GetPaymentMethod(new PaymentMethodId(network.CryptoCode, paymentType), networkProvider); } @@ -540,7 +540,7 @@ namespace BTCPayServer.Services.Invoices r.CryptoCode = paymentMethodId.CryptoCode; r.PaymentType = paymentMethodId.PaymentType.ToString(); r.ParentEntity = this; - r.Network = Networks?.GetNetwork(r.CryptoCode); + r.Network = Networks?.GetNetwork(r.CryptoCode); if (r.Network != null || Networks == null) paymentMethods.Add(r); } @@ -732,7 +732,7 @@ namespace BTCPayServer.Services.Invoices [JsonIgnore] public InvoiceEntity ParentEntity { get; set; } [JsonIgnore] - public BTCPayNetwork Network { get; set; } + public BTCPayNetworkBase Network { get; set; } [JsonProperty(PropertyName = "cryptoCode", DefaultValueHandling = DefaultValueHandling.Ignore)] [Obsolete("Use GetId().CryptoCode instead")] public string CryptoCode { get; set; } @@ -1026,10 +1026,10 @@ namespace BTCPayServer.Services.Invoices /// /// The amount paid decimal GetValue(); - bool PaymentCompleted(PaymentEntity entity, BTCPayNetwork network); - bool PaymentConfirmed(PaymentEntity entity, SpeedPolicy speedPolicy, BTCPayNetwork network); + bool PaymentCompleted(PaymentEntity entity, BTCPayNetworkBase network); + bool PaymentConfirmed(PaymentEntity entity, SpeedPolicy speedPolicy, BTCPayNetworkBase network); PaymentTypes GetPaymentType(); - string GetDestination(BTCPayNetwork network); + string GetDestination(BTCPayNetworkBase network); } } diff --git a/BTCPayServer/Services/Invoices/InvoiceRepository.cs b/BTCPayServer/Services/Invoices/InvoiceRepository.cs index 41b0524de..bcd356527 100644 --- a/BTCPayServer/Services/Invoices/InvoiceRepository.cs +++ b/BTCPayServer/Services/Invoices/InvoiceRepository.cs @@ -137,7 +137,7 @@ retry: public async Task CreateInvoiceAsync(string storeId, InvoiceEntity invoice) { List textSearch = new List(); - invoice = NBitcoin.JsonConverters.Serializer.ToObject(ToString(invoice, null), null); + invoice = ToObject(ToBytes(invoice)); invoice.Networks = _Networks; invoice.Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(16)); #pragma warning disable CS0618 @@ -166,7 +166,7 @@ retry: throw new InvalidOperationException("CryptoCode unsupported"); var paymentDestination = paymentMethod.GetPaymentMethodDetails().GetPaymentDestination(); - string address = GetDestination(paymentMethod, paymentMethod.Network.NBitcoinNetwork); + string address = GetDestination(paymentMethod); context.AddressInvoices.Add(new AddressInvoiceData() { InvoiceDataId = invoice.Id, @@ -215,18 +215,19 @@ retry: } } - private static string GetDestination(PaymentMethod paymentMethod, Network network) + private string GetDestination(PaymentMethod paymentMethod) { // For legacy reason, BitcoinLikeOnChain is putting the hashes of addresses in database if (paymentMethod.GetId().PaymentType == Payments.PaymentTypes.BTCLike) { - return ((Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod)paymentMethod.GetPaymentMethodDetails()).GetDepositAddress(network).ScriptPubKey.Hash.ToString(); + var network = (BTCPayNetwork)paymentMethod.Network; + return ((Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod)paymentMethod.GetPaymentMethodDetails()).GetDepositAddress(network.NBitcoinNetwork).ScriptPubKey.Hash.ToString(); } /////////////// return paymentMethod.GetPaymentMethodDetails().GetPaymentDestination(); } - public async Task NewAddress(string invoiceId, Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod paymentMethod, BTCPayNetwork network) + public async Task NewAddress(string invoiceId, Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod paymentMethod, BTCPayNetworkBase network) { using (var context = _ContextFactory.CreateContext()) { @@ -254,14 +255,14 @@ retry: } #pragma warning restore CS0618 invoiceEntity.SetPaymentMethod(currencyData); - invoice.Blob = ToBytes(invoiceEntity, network.NBitcoinNetwork); + invoice.Blob = ToBytes(invoiceEntity, network); context.AddressInvoices.Add(new AddressInvoiceData() { InvoiceDataId = invoiceId, CreatedTime = DateTimeOffset.UtcNow } - .Set(GetDestination(currencyData, network.NBitcoinNetwork), currencyData.GetId())); + .Set(GetDestination(currencyData), currencyData.GetId())); context.HistoricalAddressInvoices.Add(new HistoricalAddressInvoiceData() { InvoiceDataId = invoiceId, @@ -592,7 +593,7 @@ retry: return status; } - public async Task AddRefundsAsync(string invoiceId, TxOut[] outputs, Network network) + public async Task AddRefundsAsync(string invoiceId, TxOut[] outputs, BTCPayNetwork network) { if (outputs.Length == 0) return; @@ -613,7 +614,7 @@ retry: await context.SaveChangesAsync().ConfigureAwait(false); } - var addresses = outputs.Select(o => o.ScriptPubKey.GetDestinationAddress(network)).Where(a => a != null).ToArray(); + var addresses = outputs.Select(o => o.ScriptPubKey.GetDestinationAddress(network.NBitcoinNetwork)).Where(a => a != null).ToArray(); AddToTextSearch(invoiceId, addresses.Select(a => a.ToString()).ToArray()); } @@ -626,7 +627,7 @@ retry: /// /// /// The PaymentEntity or null if already added - public async Task AddPayment(string invoiceId, DateTimeOffset date, CryptoPaymentData paymentData, BTCPayNetwork network, bool accounted = false) + public async Task AddPayment(string invoiceId, DateTimeOffset date, CryptoPaymentData paymentData, BTCPayNetworkBase network, bool accounted = false) { using (var context = _ContextFactory.CreateContext()) { @@ -655,7 +656,7 @@ retry: bitcoinPaymentMethod.NextNetworkFee = bitcoinPaymentMethod.FeeRate.GetFee(100); // assume price for 100 bytes paymentMethod.SetPaymentMethodDetails(bitcoinPaymentMethod); invoiceEntity.SetPaymentMethod(paymentMethod); - invoice.Blob = ToBytes(invoiceEntity, network.NBitcoinNetwork); + invoice.Blob = ToBytes(invoiceEntity, network); } PaymentData data = new PaymentData { @@ -704,20 +705,27 @@ retry: entity.Networks = _Networks; return entity; } - private T ToObject(byte[] value, Network network) + private T ToObject(byte[] value, BTCPayNetworkBase network) { - return NBitcoin.JsonConverters.Serializer.ToObject(ZipUtils.Unzip(value), network); + if (network == null) + { + return NBitcoin.JsonConverters.Serializer.ToObject(ZipUtils.Unzip(value), null); + } + return network.ToObject(ZipUtils.Unzip(value)); } - - private byte[] ToBytes(T obj, Network network) + private byte[] ToBytes(T obj, BTCPayNetworkBase network = null) { - return ZipUtils.Zip(NBitcoin.JsonConverters.Serializer.ToString(obj, network)); + return ZipUtils.Zip(ToString(obj, network)); } - private string ToString(T data, Network network) + private string ToString(T data, BTCPayNetworkBase network) { - return NBitcoin.JsonConverters.Serializer.ToString(data, network); + if (network == null) + { + return NBitcoin.JsonConverters.Serializer.ToString(data, null); + } + return network.ToString(data); } public void Dispose() diff --git a/BTCPayServer/Services/TorServices.cs b/BTCPayServer/Services/TorServices.cs index 39a771ffb..abaec7fef 100644 --- a/BTCPayServer/Services/TorServices.cs +++ b/BTCPayServer/Services/TorServices.cs @@ -80,13 +80,13 @@ namespace BTCPayServer.Services Services = result.ToArray(); } - private bool TryParseP2PService(string name, out BTCPayNetwork network) + private bool TryParseP2PService(string name, out BTCPayNetworkBase network) { network = null; var splitted = name.Trim().Split('-'); if (splitted.Length != 2 || splitted[1] != "P2P") return false; - network = _networks.GetNetwork(splitted[0]); + network = _networks.GetNetwork(splitted[0]); return network != null; } } @@ -94,7 +94,7 @@ namespace BTCPayServer.Services public class TorService { public TorServiceType ServiceType { get; set; } = TorServiceType.Other; - public BTCPayNetwork Network { get; set; } + public BTCPayNetworkBase Network { get; set; } public string Name { get; set; } public string OnionHost { get; set; } public int VirtualPort { get; set; } diff --git a/BTCPayServer/Services/Wallets/BTCPayWalletProvider.cs b/BTCPayServer/Services/Wallets/BTCPayWalletProvider.cs index 1bdd0f05d..de5c0e7e2 100644 --- a/BTCPayServer/Services/Wallets/BTCPayWalletProvider.cs +++ b/BTCPayServer/Services/Wallets/BTCPayWalletProvider.cs @@ -22,7 +22,7 @@ namespace BTCPayServer.Services.Wallets _NetworkProvider = networkProvider; _Options = memoryCacheOption; - foreach(var network in networkProvider.GetAll()) + foreach(var network in networkProvider.GetAll().OfType()) { var explorerClient = _Client.GetExplorerClient(network.CryptoCode); if (explorerClient == null) @@ -33,7 +33,7 @@ namespace BTCPayServer.Services.Wallets Dictionary _Wallets = new Dictionary(); - public BTCPayWallet GetWallet(BTCPayNetwork network) + public BTCPayWallet GetWallet(BTCPayNetworkBase network) { if (network == null) throw new ArgumentNullException(nameof(network)); @@ -47,7 +47,7 @@ namespace BTCPayServer.Services.Wallets return result; } - public bool IsAvailable(BTCPayNetwork network) + public bool IsAvailable(BTCPayNetworkBase network) { return _Client.IsAvailable(network); }