mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 01:43:50 +01:00
Support the new LN lib (#5422)
* Support the new LN lib * fix test * do not cache factories * try without useless userinfo in lnd * Remove monero wallet files * support simpler DI too --------- Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
This commit is contained in:
parent
6d288271cd
commit
2f23bad3bc
@ -12,7 +12,8 @@ namespace BTCPayServer.Tests
|
||||
{
|
||||
this._Parent = serverTester;
|
||||
var url = serverTester.GetEnvironment(environmentName, defaultValue);
|
||||
Client = (ChargeClient)LightningClientFactory.CreateClient(url, network);
|
||||
|
||||
Client = (ChargeClient)new LightningClientFactory(network).Create(url);
|
||||
P2PHost = _Parent.GetEnvironment(environmentName + "_HOST", defaultHost);
|
||||
}
|
||||
public ChargeClient Client { get; set; }
|
||||
|
@ -295,17 +295,12 @@ namespace BTCPayServer.Tests
|
||||
|
||||
public void AddLightningNode()
|
||||
{
|
||||
AddLightningNode(null, null, true);
|
||||
AddLightningNode(null, true);
|
||||
}
|
||||
|
||||
public void AddLightningNode(LightningConnectionType? connectionType = null, bool test = true)
|
||||
public void AddLightningNode(string? connectionType = null, bool test = true)
|
||||
{
|
||||
AddLightningNode(null, connectionType, test);
|
||||
}
|
||||
|
||||
public void AddLightningNode(string cryptoCode = null, LightningConnectionType? connectionType = null, bool test = true)
|
||||
{
|
||||
cryptoCode ??= "BTC";
|
||||
var cryptoCode = "BTC";
|
||||
if (!Driver.PageSource.Contains("Connect to a Lightning node"))
|
||||
{
|
||||
GoToLightningSettings();
|
||||
|
@ -94,17 +94,18 @@ namespace BTCPayServer.Tests
|
||||
{
|
||||
ActivateLightning(LightningConnectionType.CLightning);
|
||||
}
|
||||
public void ActivateLightning(LightningConnectionType internalNode)
|
||||
public void ActivateLightning(string internalNode)
|
||||
{
|
||||
var btc = NetworkProvider.GetNetwork<BTCPayNetwork>("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);
|
||||
var factory = new LightningClientFactory(btc);
|
||||
CustomerLightningD = factory.Create(GetEnvironment("TEST_CUSTOMERLIGHTNINGD", "type=clightning;server=tcp://127.0.0.1:30992/"));
|
||||
MerchantLightningD = factory.Create(GetEnvironment("TEST_MERCHANTLIGHTNINGD", "type=clightning;server=tcp://127.0.0.1:30993/"));
|
||||
MerchantCharge = new ChargeTester(this, "TEST_MERCHANTCHARGE", "type=charge;server=http://127.0.0.1:54938/;api-token=foiewnccewuify;allowinsecure=true", "merchant_lightningd", btc);
|
||||
MerchantLnd = new LndMockTester(this, "TEST_MERCHANTLND", "http://lnd:lnd@127.0.0.1:35531/", "merchant_lnd", btc);
|
||||
PayTester.UseLightning = true;
|
||||
PayTester.IntegratedLightning = GetLightningConnectionString(internalNode, true);
|
||||
}
|
||||
public string GetLightningConnectionString(LightningConnectionType? connectionType, bool isMerchant)
|
||||
public string GetLightningConnectionString(string? connectionType, bool isMerchant)
|
||||
{
|
||||
string connectionString = null;
|
||||
if (connectionType is null)
|
||||
|
@ -278,7 +278,7 @@ namespace BTCPayServer.Tests
|
||||
|
||||
public bool IsAdmin { get; internal set; }
|
||||
|
||||
public void RegisterLightningNode(string cryptoCode, LightningConnectionType? connectionType = null, bool isMerchant = true)
|
||||
public void RegisterLightningNode(string cryptoCode, string? connectionType = null, bool isMerchant = true)
|
||||
{
|
||||
RegisterLightningNodeAsync(cryptoCode, connectionType, isMerchant).GetAwaiter().GetResult();
|
||||
}
|
||||
@ -286,7 +286,7 @@ namespace BTCPayServer.Tests
|
||||
{
|
||||
return RegisterLightningNodeAsync(cryptoCode, null, isMerchant, storeId);
|
||||
}
|
||||
public async Task RegisterLightningNodeAsync(string cryptoCode, LightningConnectionType? connectionType, bool isMerchant = true, string storeId = null)
|
||||
public async Task RegisterLightningNodeAsync(string cryptoCode, string? connectionType, bool isMerchant = true, string storeId = null)
|
||||
{
|
||||
var storeController = GetController<UIStoresController>();
|
||||
|
||||
|
@ -23,6 +23,7 @@ using BTCPayServer.Fido2.Models;
|
||||
using BTCPayServer.HostedServices;
|
||||
using BTCPayServer.Hosting;
|
||||
using BTCPayServer.Lightning;
|
||||
using BTCPayServer.Lightning.Charge;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Models.AccountViewModels;
|
||||
using BTCPayServer.Models.AppViewModels;
|
||||
@ -68,6 +69,7 @@ using Newtonsoft.Json.Schema;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
using CreateInvoiceRequest = BTCPayServer.Client.Models.CreateInvoiceRequest;
|
||||
using RatesViewModel = BTCPayServer.Models.StoreViewModels.RatesViewModel;
|
||||
|
||||
namespace BTCPayServer.Tests
|
||||
@ -475,7 +477,7 @@ namespace BTCPayServer.Tests
|
||||
await ProcessLightningPayment(LightningConnectionType.LndREST);
|
||||
}
|
||||
|
||||
async Task ProcessLightningPayment(LightningConnectionType type)
|
||||
async Task ProcessLightningPayment(string type)
|
||||
{
|
||||
// For easier debugging and testing
|
||||
// LightningLikePaymentHandler.LIGHTNING_TIMEOUT = int.MaxValue;
|
||||
@ -2390,9 +2392,14 @@ namespace BTCPayServer.Tests
|
||||
Assert.NotNull(lnMethod.GetExternalLightningUrl());
|
||||
|
||||
var url = lnMethod.GetExternalLightningUrl();
|
||||
Assert.Equal(LightningConnectionType.Charge, url.ConnectionType);
|
||||
Assert.Equal("pass", url.Password);
|
||||
Assert.Equal("usr", url.Username);
|
||||
var kv = LightningConnectionStringHelper.ExtractValues(url, out var connType);
|
||||
Assert.Equal(LightningConnectionType.Charge,connType);
|
||||
var client = Assert.IsType<ChargeClient>(tester.PayTester.GetService<LightningClientFactoryService>()
|
||||
.Create(url, tester.NetworkProvider.GetNetwork<BTCPayNetwork>("BTC")));
|
||||
var auth = Assert.IsType<ChargeAuthentication.UserPasswordAuthentication>(client.ChargeAuthentication);
|
||||
|
||||
Assert.Equal("pass", auth.NetworkCredential.Password);
|
||||
Assert.Equal("usr", auth.NetworkCredential.UserName);
|
||||
|
||||
// Test if lightning connection strings get migrated to internal
|
||||
store.DerivationStrategies = new JObject()
|
||||
|
@ -24,7 +24,7 @@ services:
|
||||
TESTS_AzureBlobStorageConnectionString: ${TESTS_AzureBlobStorageConnectionString:-none}
|
||||
TEST_MERCHANTLIGHTNINGD: "type=clightning;server=unix://etc/merchant_lightningd_datadir/lightning-rpc"
|
||||
TEST_CUSTOMERLIGHTNINGD: "type=clightning;server=unix://etc/customer_lightningd_datadir/lightning-rpc"
|
||||
TEST_MERCHANTLND: "http://lnd:lnd@merchant_lnd:8080/"
|
||||
TEST_MERCHANTLND: "http://merchant_lnd:8080/"
|
||||
TESTS_INCONTAINER: "true"
|
||||
TESTS_SSHCONNECTION: "root@sshd:22"
|
||||
TESTS_SSHPASSWORD: ""
|
||||
|
@ -22,7 +22,7 @@ services:
|
||||
TESTS_AzureBlobStorageConnectionString: ${TESTS_AzureBlobStorageConnectionString:-none}
|
||||
TEST_MERCHANTLIGHTNINGD: "type=clightning;server=unix://etc/merchant_lightningd_datadir/lightning-rpc"
|
||||
TEST_CUSTOMERLIGHTNINGD: "type=clightning;server=unix://etc/customer_lightningd_datadir/lightning-rpc"
|
||||
TEST_MERCHANTLND: "http://lnd:lnd@merchant_lnd:8080/"
|
||||
TEST_MERCHANTLND: "http://merchant_lnd:8080/"
|
||||
TESTS_INCONTAINER: "true"
|
||||
TESTS_SSHCONNECTION: "root@sshd:22"
|
||||
TESTS_SSHPASSWORD: ""
|
||||
|
@ -48,7 +48,7 @@
|
||||
<PackageReference Include="YamlDotNet" Version="8.0.0" />
|
||||
<PackageReference Include="BIP78.Sender" Version="0.2.2" />
|
||||
<PackageReference Include="BTCPayServer.Hwi" Version="2.0.2" />
|
||||
<PackageReference Include="BTCPayServer.Lightning.All" Version="1.4.31" />
|
||||
<PackageReference Include="BTCPayServer.Lightning.All" Version="1.5.1" />
|
||||
<PackageReference Include="CsvHelper" Version="15.0.5" />
|
||||
<PackageReference Include="Dapper" Version="2.1.21" />
|
||||
<PackageReference Include="Fido2" Version="2.0.2" />
|
||||
|
@ -101,7 +101,7 @@ public class StoreLightningBalance : ViewComponent
|
||||
}
|
||||
if (existing.IsInternalNode && _lightningNetworkOptions.Value.InternalLightningByCryptoCode.TryGetValue(cryptoCode, out var internalLightningNode))
|
||||
{
|
||||
return _lightningClientFactory.Create(internalLightningNode, network);
|
||||
return internalLightningNode;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -5,7 +5,6 @@ namespace BTCPayServer.Configuration
|
||||
{
|
||||
public class LightningNetworkOptions
|
||||
{
|
||||
public Dictionary<string, LightningConnectionString> InternalLightningByCryptoCode { get; set; } =
|
||||
new Dictionary<string, LightningConnectionString>();
|
||||
public Dictionary<string, ILightningClient> InternalLightningByCryptoCode { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +147,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
{
|
||||
throw ErrorShouldBeAdminForInternalNode();
|
||||
}
|
||||
return _lightningClientFactory.Create(internalLightningNode, network);
|
||||
|
||||
return internalLightningNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
.FirstOrDefault(d => d.PaymentId == id);
|
||||
if (existing == null)
|
||||
throw ErrorLightningNodeNotConfiguredForStore();
|
||||
if (existing.GetExternalLightningUrl() is LightningConnectionString connectionString)
|
||||
if (existing.GetExternalLightningUrl() is {} connectionString)
|
||||
{
|
||||
return Task.FromResult(_lightningClientFactory.Create(connectionString, network));
|
||||
}
|
||||
@ -168,7 +168,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
{
|
||||
throw ErrorShouldBeAdminForInternalNode();
|
||||
}
|
||||
return Task.FromResult(_lightningClientFactory.Create(internalLightningNode, network));
|
||||
return Task.FromResult(internalLightningNode);
|
||||
}
|
||||
throw ErrorLightningNodeNotConfiguredForStore();
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
@ -37,17 +38,19 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
private readonly StoreRepository _storeRepository;
|
||||
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly LightningClientFactoryService _lightningClientFactoryService;
|
||||
|
||||
public GreenfieldStoreLightningNetworkPaymentMethodsController(
|
||||
StoreRepository storeRepository,
|
||||
BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
IAuthorizationService authorizationService,
|
||||
ISettingsRepository settingsRepository,
|
||||
LightningClientFactoryService lightningClientFactoryService,
|
||||
PoliciesSettings policiesSettings)
|
||||
{
|
||||
_storeRepository = storeRepository;
|
||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||
_authorizationService = authorizationService;
|
||||
_lightningClientFactoryService = lightningClientFactoryService;
|
||||
PoliciesSettings = policiesSettings;
|
||||
}
|
||||
|
||||
@ -155,21 +158,26 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!LightningConnectionString.TryParse(request.ConnectionString, false,
|
||||
out var connectionString, out var error))
|
||||
ILightningClient? lightningClient;
|
||||
try
|
||||
{
|
||||
ModelState.AddModelError(nameof(request.ConnectionString), $"Invalid URL ({error})");
|
||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||
lightningClient = _lightningClientFactoryService.Create(request.ConnectionString, network);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ModelState.AddModelError(nameof(request.ConnectionString), $"Invalid URL ({e.Message})");
|
||||
return this.CreateValidationError(ModelState);
|
||||
}
|
||||
|
||||
if (connectionString.ConnectionType == LightningConnectionType.LndGRPC)
|
||||
{
|
||||
ModelState.AddModelError(nameof(request.ConnectionString),
|
||||
$"BTCPay does not support gRPC connections");
|
||||
return this.CreateValidationError(ModelState);
|
||||
}
|
||||
// if (connectionString.ConnectionType == LightningConnectionType.LndGRPC)
|
||||
// {
|
||||
// ModelState.AddModelError(nameof(request.ConnectionString),
|
||||
// $"BTCPay does not support gRPC connections");
|
||||
// return this.CreateValidationError(ModelState);
|
||||
// }
|
||||
|
||||
if (!await CanManageServer() && !connectionString.IsSafe())
|
||||
if (!await CanManageServer() && !lightningClient.IsSafe())
|
||||
{
|
||||
ModelState.AddModelError(nameof(request.ConnectionString),
|
||||
$"You do not have 'btcpay.server.canmodifyserversettings' rights, so the connection string should not contain 'cookiefilepath', 'macaroondirectorypath', 'macaroonfilepath', and should not point to a local ip or to a dns name ending with '.internal', '.local', '.lan' or '.'.");
|
||||
@ -180,7 +188,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
{
|
||||
CryptoCode = paymentMethodId.CryptoCode
|
||||
};
|
||||
paymentMethod.SetLightningUrl(connectionString);
|
||||
paymentMethod.SetLightningUrl(lightningClient);
|
||||
}
|
||||
}
|
||||
store.SetSupportedPaymentMethod(paymentMethodId, paymentMethod);
|
||||
|
@ -29,14 +29,17 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
[HttpPost("i/{invoiceId}/test-payment")]
|
||||
[CheatModeRoute]
|
||||
public async Task<IActionResult> TestPayment(string invoiceId, FakePaymentRequest request, [FromServices] Cheater cheater)
|
||||
public async Task<IActionResult> TestPayment(string invoiceId, FakePaymentRequest request,
|
||||
[FromServices] Cheater cheater,
|
||||
[FromServices] LightningClientFactoryService lightningClientFactoryService)
|
||||
{
|
||||
var invoice = await _InvoiceRepository.GetInvoice(invoiceId);
|
||||
var store = await _StoreRepository.FindStore(invoice.StoreId);
|
||||
var isSats = request.CryptoCode.ToUpper(CultureInfo.InvariantCulture) == "SATS";
|
||||
var cryptoCode = isSats ? "BTC" : request.CryptoCode;
|
||||
var amount = new Money(request.Amount, isSats ? MoneyUnit.Satoshi : MoneyUnit.BTC);
|
||||
var network = _NetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode).NBitcoinNetwork;
|
||||
var btcpayNetwork = _NetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||
var network = btcpayNetwork.NBitcoinNetwork;
|
||||
var paymentMethodId = new[] { store.GetDefaultPaymentId() }
|
||||
.Concat(store.GetEnabledPaymentIds(_NetworkProvider))
|
||||
.FirstOrDefault(p => p?.ToString() == request.PaymentMethodId);
|
||||
@ -61,8 +64,10 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
case LightningPaymentType:
|
||||
// requires the channels to be set up using the BTCPayServer.Tests/docker-lightning-channel-setup.sh script
|
||||
LightningConnectionString.TryParse(Environment.GetEnvironmentVariable("BTCPAY_BTCEXTERNALLNDREST"), false, out var lnConnection);
|
||||
var lnClient = LightningClientFactory.CreateClient(lnConnection, network);
|
||||
var lnClient = lightningClientFactoryService.Create(
|
||||
Environment.GetEnvironmentVariable("BTCPAY_BTCEXTERNALLNDREST"),
|
||||
btcpayNetwork);
|
||||
|
||||
var lnAmount = new LightMoney(amount.Satoshi, LightMoneyUnit.Satoshi);
|
||||
var response = await lnClient.Pay(destination, new PayInvoiceParams { Amount = lnAmount });
|
||||
|
||||
|
@ -140,17 +140,18 @@ namespace BTCPayServer.Controllers
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), "Please provide a connection string");
|
||||
return View(vm);
|
||||
}
|
||||
if (!LightningConnectionString.TryParse(vm.ConnectionString, false, out var connectionString, out var error))
|
||||
|
||||
ILightningClient? lightningClient = null;
|
||||
try
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), $"Invalid URL ({error})");
|
||||
lightningClient = _lightningClientFactoryService.Create(vm.ConnectionString, network);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), $"Invalid URL ({e.Message})");
|
||||
return View(vm);
|
||||
}
|
||||
if (connectionString.ConnectionType == LightningConnectionType.LndGRPC)
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), $"BTCPay does not support gRPC connections");
|
||||
return View(vm);
|
||||
}
|
||||
if (!User.IsInRole(Roles.ServerAdmin) && !connectionString.IsSafe())
|
||||
if (!User.IsInRole(Roles.ServerAdmin) && !lightningClient.IsSafe())
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), "You are not a server admin, so the connection string should not contain 'cookiefilepath', 'macaroondirectorypath', 'macaroonfilepath', and should not point to a local ip or to a dns name ending with '.internal', '.local', '.lan' or '.'.");
|
||||
return View(vm);
|
||||
@ -163,7 +164,7 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
try
|
||||
{
|
||||
paymentMethod.SetLightningUrl(connectionString);
|
||||
paymentMethod.SetLightningUrl(lightningClient);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -66,7 +66,8 @@ namespace BTCPayServer.Controllers
|
||||
IDataProtectionProvider dataProtector,
|
||||
IOptions<LightningNetworkOptions> lightningNetworkOptions,
|
||||
IOptions<ExternalServicesOptions> externalServiceOptions,
|
||||
IHtmlHelper html)
|
||||
IHtmlHelper html,
|
||||
LightningClientFactoryService lightningClientFactoryService)
|
||||
{
|
||||
_RateFactory = rateFactory;
|
||||
_Repo = repo;
|
||||
@ -90,6 +91,7 @@ namespace BTCPayServer.Controllers
|
||||
_BtcpayServerOptions = btcpayServerOptions;
|
||||
_BTCPayEnv = btcpayEnv;
|
||||
_externalServiceOptions = externalServiceOptions;
|
||||
_lightningClientFactoryService = lightningClientFactoryService;
|
||||
Html = html;
|
||||
}
|
||||
|
||||
@ -112,6 +114,7 @@ namespace BTCPayServer.Controllers
|
||||
private readonly IFileService _fileService;
|
||||
private readonly EventAggregator _EventAggregator;
|
||||
private readonly IOptions<ExternalServicesOptions> _externalServiceOptions;
|
||||
private readonly LightningClientFactoryService _lightningClientFactoryService;
|
||||
|
||||
public string? GeneratedPairingCode { get; set; }
|
||||
public WebhookSender WebhookNotificationManager { get; }
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -83,19 +84,42 @@ namespace BTCPayServer
|
||||
return endpoint != null;
|
||||
}
|
||||
|
||||
public static bool IsSafe(this LightningConnectionString connectionString)
|
||||
public static Uri GetServerUri(this ILightningClient client)
|
||||
{
|
||||
if (connectionString.CookieFilePath != null ||
|
||||
connectionString.MacaroonDirectoryPath != null ||
|
||||
connectionString.MacaroonFilePath != null)
|
||||
var kv = LightningConnectionStringHelper.ExtractValues(client.ToString(), out var type);
|
||||
|
||||
return !kv.TryGetValue("server", out var server) ? null : new Uri(server, UriKind.Absolute);
|
||||
}
|
||||
|
||||
public static string GetDisplayName(this ILightningClient client)
|
||||
{
|
||||
LightningConnectionStringHelper.ExtractValues(client.ToString(), out var type);
|
||||
|
||||
var field = typeof(LightningConnectionType).GetField(type, BindingFlags.Public | BindingFlags.Static);
|
||||
if (field == null) return type;
|
||||
DisplayAttribute attr = field.GetCustomAttribute<DisplayAttribute>();
|
||||
return attr?.Name ?? type;
|
||||
|
||||
}
|
||||
|
||||
public static bool IsSafe(this ILightningClient connectionString)
|
||||
{
|
||||
var kv = LightningConnectionStringHelper.ExtractValues(connectionString.ToString(), out var type);
|
||||
if (kv.TryGetValue("cookiefilepath", out var cookieFilePath) ||
|
||||
kv.TryGetValue("macaroondirectorypath", out var macaroonDirectoryPath) ||
|
||||
kv.TryGetValue("macaroonfilepath", out var macaroonFilePath) )
|
||||
return false;
|
||||
|
||||
var uri = connectionString.BaseUri;
|
||||
if (!kv.TryGetValue("server", out var server))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var uri = new Uri(server, UriKind.Absolute);
|
||||
if (uri.Scheme.Equals("unix", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
if (!NBitcoin.Utils.TryParseEndpoint(uri.DnsSafeHost, 80, out var endpoint))
|
||||
if (!Utils.TryParseEndpoint(uri.DnsSafeHost, 80, out var endpoint))
|
||||
return false;
|
||||
return !Extensions.IsLocalNetwork(uri.DnsSafeHost);
|
||||
return !IsLocalNetwork(uri.DnsSafeHost);
|
||||
}
|
||||
|
||||
public static IQueryable<TEntity> Where<TEntity>(this Microsoft.EntityFrameworkCore.DbSet<TEntity> obj, System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) where TEntity : class
|
||||
|
@ -19,6 +19,12 @@ using BTCPayServer.Data.Payouts.LightningLike;
|
||||
using BTCPayServer.Forms;
|
||||
using BTCPayServer.HostedServices;
|
||||
using BTCPayServer.Lightning;
|
||||
using BTCPayServer.Lightning.Charge;
|
||||
using BTCPayServer.Lightning.CLightning;
|
||||
using BTCPayServer.Lightning.Eclair;
|
||||
using BTCPayServer.Lightning.LNbank;
|
||||
using BTCPayServer.Lightning.LND;
|
||||
using BTCPayServer.Lightning.LNDhub;
|
||||
using BTCPayServer.Logging;
|
||||
using BTCPayServer.PaymentRequest;
|
||||
using BTCPayServer.Payments;
|
||||
@ -122,9 +128,24 @@ namespace BTCPayServer.Hosting
|
||||
services.AddSingleton<IHostedService>(provider => provider.GetRequiredService<TorServices>());
|
||||
services.AddSingleton<ISwaggerProvider, DefaultSwaggerProvider>();
|
||||
services.TryAddSingleton<SocketFactory>();
|
||||
|
||||
services.AddSingleton<Func<HttpClient, ILightningConnectionStringHandler>>(client =>
|
||||
new ChargeLightningConnectionStringHandler(client));
|
||||
services.AddSingleton<Func<HttpClient, ILightningConnectionStringHandler>>(_ =>
|
||||
new CLightningConnectionStringHandler());
|
||||
services.AddSingleton<Func<HttpClient, ILightningConnectionStringHandler>>(client =>
|
||||
new EclairConnectionStringHandler(client));
|
||||
services.AddSingleton<Func<HttpClient, ILightningConnectionStringHandler>>(client =>
|
||||
new LndConnectionStringHandler(client));
|
||||
services.AddSingleton<Func<HttpClient, ILightningConnectionStringHandler>>(client =>
|
||||
new LndHubConnectionStringHandler(client));
|
||||
services.AddSingleton<Func<HttpClient, ILightningConnectionStringHandler>>(client =>
|
||||
new LNbankConnectionStringHandler(client));
|
||||
services.TryAddSingleton<LightningClientFactoryService>();
|
||||
services.AddHttpClient(LightningClientFactoryService.OnionNamedClient)
|
||||
.ConfigurePrimaryHttpMessageHandler<Socks5HttpClientHandler>();
|
||||
|
||||
|
||||
services.TryAddSingleton<InvoicePaymentNotification>();
|
||||
services.TryAddSingleton<BTCPayServerOptions>(o =>
|
||||
o.GetRequiredService<IOptions<BTCPayServerOptions>>().Value);
|
||||
@ -211,16 +232,26 @@ namespace BTCPayServer.Hosting
|
||||
}
|
||||
}
|
||||
});
|
||||
services.AddOptions<LightningNetworkOptions>().Configure<BTCPayNetworkProvider>(
|
||||
(options, btcPayNetworkProvider) =>
|
||||
services.AddOptions<LightningNetworkOptions>().Configure<BTCPayNetworkProvider, LightningClientFactoryService>(
|
||||
(options, btcPayNetworkProvider, lightningClientFactoryService) =>
|
||||
{
|
||||
foreach (var net in btcPayNetworkProvider.GetAll().OfType<BTCPayNetwork>())
|
||||
{
|
||||
var lightning = configuration.GetOrDefault<string>($"{net.CryptoCode}.lightning", string.Empty);
|
||||
if (lightning.Length != 0)
|
||||
{
|
||||
if (!LightningConnectionString.TryParse(lightning, true, out var connectionString,
|
||||
out var error))
|
||||
string error = null;
|
||||
ILightningClient lightningClient = null;
|
||||
try
|
||||
{
|
||||
lightningClient = lightningClientFactoryService.Create(lightning, net);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = e.Message;
|
||||
}
|
||||
|
||||
if (error is not null)
|
||||
{
|
||||
logs.Configuration.LogWarning($"Invalid setting {net.CryptoCode}.lightning, " +
|
||||
Environment.NewLine +
|
||||
@ -241,12 +272,12 @@ namespace BTCPayServer.Hosting
|
||||
}
|
||||
else
|
||||
{
|
||||
if (connectionString.IsLegacy)
|
||||
if (lightningClient.ToString() != lightning)
|
||||
{
|
||||
logs.Configuration.LogWarning(
|
||||
$"Setting {net.CryptoCode}.lightning is a deprecated format, it will work now, but please replace it for future versions with '{connectionString.ToString()}'");
|
||||
$"Setting {net.CryptoCode}.lightning is a deprecated format ({lightning}), it will work now, but please replace it for future versions with '{lightningClient.ToString()}'");
|
||||
}
|
||||
options.InternalLightningByCryptoCode.Add(net.CryptoCode, connectionString);
|
||||
options.InternalLightningByCryptoCode.Add(net.CryptoCode, lightningClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Configuration;
|
||||
using BTCPayServer.Data;
|
||||
@ -27,12 +25,10 @@ using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NBitcoin;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PeterO.Cbor;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
using YamlDotNet.Serialization;
|
||||
using LightningAddressData = BTCPayServer.Data.LightningAddressData;
|
||||
using Serializer = NBXplorer.Serializer;
|
||||
|
||||
@ -50,6 +46,7 @@ namespace BTCPayServer.Hosting
|
||||
private readonly BTCPayNetworkJsonSerializerSettings _btcPayNetworkJsonSerializerSettings;
|
||||
private readonly LightningAddressService _lightningAddressService;
|
||||
private readonly ILogger<MigrationStartupTask> _logger;
|
||||
private readonly LightningClientFactoryService _lightningClientFactoryService;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
|
||||
public IOptions<LightningNetworkOptions> LightningOptions { get; }
|
||||
@ -65,7 +62,8 @@ namespace BTCPayServer.Hosting
|
||||
IEnumerable<IPayoutHandler> payoutHandlers,
|
||||
BTCPayNetworkJsonSerializerSettings btcPayNetworkJsonSerializerSettings,
|
||||
LightningAddressService lightningAddressService,
|
||||
ILogger<MigrationStartupTask> logger)
|
||||
ILogger<MigrationStartupTask> logger,
|
||||
LightningClientFactoryService lightningClientFactoryService)
|
||||
{
|
||||
_DBContextFactory = dbContextFactory;
|
||||
_StoreRepository = storeRepository;
|
||||
@ -76,6 +74,7 @@ namespace BTCPayServer.Hosting
|
||||
_btcPayNetworkJsonSerializerSettings = btcPayNetworkJsonSerializerSettings;
|
||||
_lightningAddressService = lightningAddressService;
|
||||
_logger = logger;
|
||||
_lightningClientFactoryService = lightningClientFactoryService;
|
||||
_userManager = userManager;
|
||||
LightningOptions = lightningOptions;
|
||||
}
|
||||
@ -1052,15 +1051,20 @@ retry:
|
||||
|
||||
private async Task DeprecatedLightningConnectionStringCheck()
|
||||
{
|
||||
using var ctx = _DBContextFactory.CreateContext();
|
||||
await using var ctx = _DBContextFactory.CreateContext();
|
||||
foreach (var store in await ctx.Stores.AsQueryable().ToArrayAsync())
|
||||
{
|
||||
foreach (var method in store.GetSupportedPaymentMethods(_NetworkProvider).OfType<Payments.Lightning.LightningSupportedPaymentMethod>())
|
||||
foreach (var method in store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.OfType<LightningSupportedPaymentMethod>())
|
||||
{
|
||||
var lightning = method.GetExternalLightningUrl();
|
||||
if (lightning?.IsLegacy is true)
|
||||
if (lightning is null)
|
||||
continue;
|
||||
var client = _lightningClientFactoryService.Create(lightning,
|
||||
_NetworkProvider.GetNetwork<BTCPayNetwork>(method.PaymentId.CryptoCode));
|
||||
if (client?.ToString() != lightning)
|
||||
{
|
||||
method.SetLightningUrl(lightning);
|
||||
method.SetLightningUrl(client);
|
||||
store.SetSupportedPaymentMethod(method);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace BTCPayServer.Payments.Lightning
|
||||
{
|
||||
if (!options.InternalLightningByCryptoCode.TryGetValue(network.CryptoCode, out var connectionString))
|
||||
throw new PaymentMethodUnavailableException("No internal node configured");
|
||||
return lightningClientFactory.Create(connectionString, network);
|
||||
return connectionString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,17 +175,7 @@ namespace BTCPayServer.Payments.Lightning
|
||||
|
||||
public ILightningClient CreateLightningClient(LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network)
|
||||
{
|
||||
var external = supportedPaymentMethod.GetExternalLightningUrl();
|
||||
if (external != null)
|
||||
{
|
||||
return _lightningClientFactory.Create(external, network);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Options.Value.InternalLightningByCryptoCode.TryGetValue(network.CryptoCode, out var connectionString))
|
||||
throw new PaymentMethodUnavailableException("No internal node configured");
|
||||
return _lightningClientFactory.Create(connectionString, network);
|
||||
}
|
||||
return supportedPaymentMethod.CreateLightningClient(network, Options.Value, _lightningClientFactory);
|
||||
}
|
||||
|
||||
public async Task TestConnection(NodeInfo nodeInfo, CancellationToken cancellation)
|
||||
|
@ -175,7 +175,6 @@ namespace BTCPayServer.Payments.Lightning
|
||||
if (lnUri == null)
|
||||
continue;
|
||||
listenedInvoices.Add(new ListenedInvoice(
|
||||
lnUri.BaseUri,
|
||||
invoice.ExpirationTime,
|
||||
lightningMethod,
|
||||
lightningSupportedMethod,
|
||||
@ -359,7 +358,6 @@ namespace BTCPayServer.Payments.Lightning
|
||||
if (url is null)
|
||||
continue;
|
||||
instanceListener.AddListenedInvoice(new ListenedInvoice(
|
||||
url.BaseUri,
|
||||
invoice.ExpirationTime,
|
||||
newPaymentMethodDetails,
|
||||
supportedMethod,
|
||||
@ -384,14 +382,12 @@ namespace BTCPayServer.Payments.Lightning
|
||||
|
||||
}
|
||||
|
||||
private LightningConnectionString? GetLightningUrl(LightningSupportedPaymentMethod supportedMethod)
|
||||
private string? GetLightningUrl(LightningSupportedPaymentMethod supportedMethod)
|
||||
{
|
||||
var url = supportedMethod.GetExternalLightningUrl();
|
||||
if (url != null)
|
||||
return url;
|
||||
if (Options.Value.InternalLightningByCryptoCode.TryGetValue(supportedMethod.CryptoCode, out var conn))
|
||||
return conn;
|
||||
return null;
|
||||
return Options.Value.InternalLightningByCryptoCode.TryGetValue(supportedMethod.CryptoCode, out var conn) ? conn.ToString() : null;
|
||||
}
|
||||
|
||||
TimeSpan _PollInterval = TimeSpan.FromMinutes(1.0);
|
||||
@ -452,13 +448,13 @@ namespace BTCPayServer.Payments.Lightning
|
||||
private readonly PaymentService _paymentService;
|
||||
private readonly LightningClientFactoryService _lightningClientFactory;
|
||||
|
||||
public LightningConnectionString ConnectionString { get; }
|
||||
public string ConnectionString { get; }
|
||||
|
||||
public LightningInstanceListener(InvoiceRepository invoiceRepository,
|
||||
EventAggregator eventAggregator,
|
||||
LightningClientFactoryService lightningClientFactory,
|
||||
BTCPayNetwork network,
|
||||
LightningConnectionString connectionString,
|
||||
string connectionString,
|
||||
PaymentService paymentService,
|
||||
Logs logs)
|
||||
{
|
||||
@ -504,16 +500,18 @@ namespace BTCPayServer.Payments.Lightning
|
||||
public CancellationTokenSource? StopListeningCancellationTokenSource;
|
||||
async Task Listen(CancellationToken cancellation)
|
||||
{
|
||||
Logs.PayServer.LogInformation($"{_network.CryptoCode} (Lightning): Start listening {ConnectionString.BaseUri}");
|
||||
Uri? uri = null;
|
||||
try
|
||||
{
|
||||
var lightningClient = _lightningClientFactory.Create(ConnectionString, _network);
|
||||
uri = lightningClient.GetServerUri();
|
||||
Logs.PayServer.LogInformation($"{_network.CryptoCode} (Lightning): Start listening {uri}");
|
||||
using var session = await lightningClient.Listen(cancellation);
|
||||
// Just in case the payment arrived after our last poll but before we listened.
|
||||
await PollAllListenedInvoices(cancellation);
|
||||
if (_ErrorAlreadyLogged)
|
||||
{
|
||||
Logs.PayServer.LogInformation($"{_network.CryptoCode} (Lightning): Could reconnect successfully to {ConnectionString.BaseUri}");
|
||||
Logs.PayServer.LogInformation($"{_network.CryptoCode} (Lightning): Could reconnect successfully to {uri}");
|
||||
}
|
||||
_ErrorAlreadyLogged = false;
|
||||
while (!_ListenedInvoices.IsEmpty)
|
||||
@ -542,15 +540,16 @@ namespace BTCPayServer.Payments.Lightning
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception ex) when (!cancellation.IsCancellationRequested && !_ErrorAlreadyLogged)
|
||||
{
|
||||
_ErrorAlreadyLogged = true;
|
||||
Logs.PayServer.LogError(ex, $"{_network.CryptoCode} (Lightning): Error while contacting {ConnectionString.BaseUri}");
|
||||
Logs.PayServer.LogInformation($"{_network.CryptoCode} (Lightning): Stop listening {ConnectionString.BaseUri}");
|
||||
Logs.PayServer.LogError(ex, $"{_network.CryptoCode} (Lightning): Error while contacting {uri}");
|
||||
Logs.PayServer.LogInformation($"{_network.CryptoCode} (Lightning): Stop listening {uri}");
|
||||
}
|
||||
catch (OperationCanceledException) when (cancellation.IsCancellationRequested) { }
|
||||
if (_ListenedInvoices.IsEmpty)
|
||||
Logs.PayServer.LogInformation($"{_network.CryptoCode} (Lightning): No more invoice to listen on {ConnectionString.BaseUri}, releasing the connection.");
|
||||
Logs.PayServer.LogInformation($"{_network.CryptoCode} (Lightning): No more invoice to listen on {uri}, releasing the connection.");
|
||||
}
|
||||
|
||||
public DateTimeOffset? LastFullPoll { get; set; }
|
||||
@ -609,7 +608,6 @@ namespace BTCPayServer.Payments.Lightning
|
||||
}
|
||||
|
||||
public record ListenedInvoice(
|
||||
Uri Uri,
|
||||
DateTimeOffset Expiration,
|
||||
LightningLikePaymentMethodDetails PaymentMethodDetails,
|
||||
LightningSupportedPaymentMethod SupportedPaymentMethod,
|
||||
|
@ -17,20 +17,20 @@ namespace BTCPayServer.Payments.Lightning
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public string? LightningConnectionString { get; set; }
|
||||
|
||||
public LightningConnectionString? GetExternalLightningUrl()
|
||||
public string? GetExternalLightningUrl()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (string.IsNullOrEmpty(LightningConnectionString))
|
||||
return null;
|
||||
if (!BTCPayServer.Lightning.LightningConnectionString.TryParse(LightningConnectionString, false, out var connectionString, out var error))
|
||||
{
|
||||
throw new FormatException(error);
|
||||
}
|
||||
return connectionString;
|
||||
// if (!BTCPayServer.Lightning.LightningConnectionString.TryParse(LightningConnectionString, false, out var connectionString, out var error))
|
||||
// {
|
||||
// throw new FormatException(error);
|
||||
// }
|
||||
return LightningConnectionString;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
|
||||
public void SetLightningUrl(LightningConnectionString connectionString)
|
||||
public void SetLightningUrl(ILightningClient connectionString)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(connectionString);
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
@ -41,9 +41,8 @@ namespace BTCPayServer.Payments.Lightning
|
||||
public string GetDisplayableConnectionString()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (!string.IsNullOrEmpty(LightningConnectionString) &&
|
||||
BTCPayServer.Lightning.LightningConnectionString.TryParse(LightningConnectionString, false, out var conn))
|
||||
return conn.ToString();
|
||||
if (!string.IsNullOrEmpty(LightningConnectionString))
|
||||
return LightningConnectionString;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
if (InternalNodeRef is string s)
|
||||
return s;
|
||||
|
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using BTCPayServer.Lightning;
|
||||
|
||||
@ -8,24 +10,40 @@ namespace BTCPayServer.Services
|
||||
{
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public LightningClientFactoryService(IHttpClientFactory httpClientFactory)
|
||||
private readonly IEnumerable<Func<HttpClient, ILightningConnectionStringHandler>>
|
||||
_lightningConnectionStringHandlersFactories;
|
||||
|
||||
private readonly IEnumerable<ILightningConnectionStringHandler> _lightningConnectionStringHandlers;
|
||||
|
||||
public LightningClientFactoryService(IHttpClientFactory httpClientFactory,
|
||||
IEnumerable<Func<HttpClient, ILightningConnectionStringHandler>> lightningConnectionStringHandlersFactories, IEnumerable<ILightningConnectionStringHandler> lightningConnectionStringHandlers)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_lightningConnectionStringHandlersFactories = lightningConnectionStringHandlersFactories;
|
||||
_lightningConnectionStringHandlers = lightningConnectionStringHandlers;
|
||||
}
|
||||
|
||||
private LightningClientFactory GetFactory(string namedClient, BTCPayNetwork network)
|
||||
{
|
||||
var httpClient = _httpClientFactory.CreateClient(namedClient);
|
||||
|
||||
return new LightningClientFactory(_lightningConnectionStringHandlersFactories
|
||||
.Select(handler => handler(httpClient)).Concat(_lightningConnectionStringHandlers)
|
||||
.ToArray(), network.NBitcoinNetwork);
|
||||
}
|
||||
|
||||
public static string OnionNamedClient { get; set; } = "lightning.onion";
|
||||
|
||||
public ILightningClient Create(LightningConnectionString lightningConnectionString, BTCPayNetwork network)
|
||||
public ILightningClient Create(string lightningConnectionString, BTCPayNetwork network)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(lightningConnectionString);
|
||||
ArgumentNullException.ThrowIfNull(network);
|
||||
|
||||
return new LightningClientFactory(network.NBitcoinNetwork)
|
||||
{
|
||||
HttpClient = _httpClientFactory.CreateClient(lightningConnectionString.BaseUri.IsOnion()
|
||||
? OnionNamedClient
|
||||
: $"{network.CryptoCode}: Lightning client")
|
||||
}.Create(lightningConnectionString);
|
||||
var httpClient = lightningConnectionString.Contains(".onion")
|
||||
? OnionNamedClient
|
||||
: $"{network.CryptoCode}: Lightning client";
|
||||
|
||||
return GetFactory(httpClient, network).Create(lightningConnectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@
|
||||
<td>@payment.Crypto</td>
|
||||
<td>@(payment.CryptoPaymentData.KeyPath?.ToString()?? "Unknown")</td>
|
||||
<td>
|
||||
<vc:truncate-center text="@payment.DepositAddress" classes="truncate-center-id" />
|
||||
<vc:truncate-center text="@payment.DepositAddress.ToString()" classes="truncate-center-id" />
|
||||
</td>
|
||||
<td>
|
||||
<vc:truncate-center text="@payment.PaymentProof" link="@payment.TransactionLink" classes="truncate-center-id" />
|
||||
|
@ -1,5 +1,6 @@
|
||||
@using BTCPayServer.Lightning
|
||||
@using BTCPayServer.Client
|
||||
@using BTCPayServer.Services
|
||||
@model LightningViewModel
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
@ -7,6 +8,8 @@
|
||||
ViewData.SetActivePage(StoreNavPages.Lightning, $"{Model.CryptoCode} Lightning", Context.GetStoreData().Id);
|
||||
}
|
||||
|
||||
@inject LightningClientFactoryService LightningClientFactoryService
|
||||
@inject BTCPayNetworkProvider NetworkProvider
|
||||
<div class="mb-5">
|
||||
<h3 class="mb-3">@ViewData["Title"]</h3>
|
||||
<div class="mb-3">
|
||||
@ -15,12 +18,17 @@
|
||||
@if (Model.LightningNodeType != LightningNodeType.Internal)
|
||||
{
|
||||
<span class="me-3" id="CustomNodeInfo">
|
||||
@if (LightningConnectionString.TryParse(Model.ConnectionString, out var cs))
|
||||
@try
|
||||
{
|
||||
@typeof(LightningConnectionType).DisplayName(cs.ConnectionType.ToString())
|
||||
<span>(@cs.BaseUri.Host)</span>
|
||||
var client = LightningClientFactoryService.Create(Model.ConnectionString, NetworkProvider.GetNetwork<BTCPayNetwork>(Model.CryptoCode));
|
||||
client.GetDisplayName();
|
||||
var uri = client.GetServerUri();
|
||||
if (uri is not null)
|
||||
{
|
||||
<span>(@uri.Host)</span>
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
@Model.ConnectionString
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
@using BTCPayServer.Lightning
|
||||
@using BTCPayServer.Services
|
||||
@model LightningSettingsViewModel
|
||||
@inject LightningClientFactoryService LightningClientFactoryService
|
||||
@inject BTCPayNetworkProvider NetworkProvider
|
||||
@{
|
||||
Layout = "../Shared/_NavLayout.cshtml";
|
||||
ViewData["NavPartialName"] = "../UILightning/_Nav";
|
||||
@ -15,12 +18,17 @@
|
||||
@if (Model.LightningNodeType != LightningNodeType.Internal)
|
||||
{
|
||||
<span class="me-3" id="CustomNodeInfo">
|
||||
@if (LightningConnectionString.TryParse(Model.ConnectionString, out var cs))
|
||||
@try
|
||||
{
|
||||
@typeof(LightningConnectionType).DisplayName(cs.ConnectionType.ToString())
|
||||
<span>(@cs.BaseUri.Host)</span>
|
||||
var client = LightningClientFactoryService.Create(Model.ConnectionString, NetworkProvider.GetNetwork<BTCPayNetwork>(Model.CryptoCode));
|
||||
client.GetDisplayName();
|
||||
var uri = client.GetServerUri();
|
||||
if (uri is not null)
|
||||
{
|
||||
<span>(@uri.Host)</span>
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
@Model.ConnectionString
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user