mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-20 13:34:37 +01:00
Improve Lightning setup page (#2348)
* Redesign Lightning setup page * Improve Lightning setup page Closes #1811. * Test fix * Fix LightningNetworkPaymentMethodAPITests * Bootstrap customization fix
This commit is contained in:
parent
d24964e900
commit
76985838c4
7 changed files with 164 additions and 160 deletions
|
@ -111,7 +111,7 @@ namespace BTCPayServer.Tests
|
|||
s.GoToRegister();
|
||||
s.RegisterNewUser(true);
|
||||
var store = s.CreateNewStore();
|
||||
s.AddInternalLightningNode("BTC");
|
||||
s.AddLightningNode();
|
||||
s.GoToStore(store.storeId, StoreNavPages.Checkout);
|
||||
s.Driver.SetCheckbox(By.Id("LightningAmountInSatoshi"), true);
|
||||
var command = s.Driver.FindElement(By.Name("command"));
|
||||
|
|
|
@ -188,28 +188,39 @@ namespace BTCPayServer.Tests
|
|||
FindAlertMessage();
|
||||
}
|
||||
|
||||
public void AddLightningNode(string cryptoCode, LightningConnectionType connectionType)
|
||||
public void AddLightningNode(string cryptoCode = "BTC", LightningConnectionType? connectionType = null)
|
||||
{
|
||||
string connectionString;
|
||||
if (connectionType == LightningConnectionType.Charge)
|
||||
connectionString = $"type=charge;server={Server.MerchantCharge.Client.Uri.AbsoluteUri};allowinsecure=true";
|
||||
else if (connectionType == LightningConnectionType.CLightning)
|
||||
connectionString = "type=clightning;server=" + ((CLightningClient)Server.MerchantLightningD).Address.AbsoluteUri;
|
||||
else if (connectionType == LightningConnectionType.LndREST)
|
||||
connectionString = $"type=lnd-rest;server={Server.MerchantLnd.Swagger.BaseUrl};allowinsecure=true";
|
||||
Driver.FindElement(By.Id($"Modify-Lightning{cryptoCode}")).Click();
|
||||
|
||||
var connectionString = connectionType switch
|
||||
{
|
||||
LightningConnectionType.Charge =>
|
||||
$"type=charge;server={Server.MerchantCharge.Client.Uri.AbsoluteUri};allowinsecure=true",
|
||||
LightningConnectionType.CLightning =>
|
||||
$"type=clightning;server={((CLightningClient) Server.MerchantLightningD).Address.AbsoluteUri}",
|
||||
LightningConnectionType.LndREST =>
|
||||
$"type=lnd-rest;server={Server.MerchantLnd.Swagger.BaseUrl};allowinsecure=true",
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (connectionString == null)
|
||||
{
|
||||
Assert.True(Driver.FindElement(By.Id("LightningNodeType-Internal")).Enabled, "Usage of the internal Lightning node is disabled.");
|
||||
Driver.FindElement(By.CssSelector("label[for=\"LightningNodeType-Internal\"]")).Click();
|
||||
}
|
||||
else
|
||||
throw new NotSupportedException(connectionType.ToString());
|
||||
{
|
||||
Driver.FindElement(By.CssSelector("label[for=\"LightningNodeType-Custom\"]")).Click();
|
||||
Driver.FindElement(By.Id("ConnectionString")).SendKeys(connectionString);
|
||||
}
|
||||
|
||||
Driver.FindElement(By.Id($"Modify-Lightning{cryptoCode}")).Click();
|
||||
Driver.FindElement(By.Name($"ConnectionString")).SendKeys(connectionString);
|
||||
Driver.FindElement(By.Id($"save")).Click();
|
||||
}
|
||||
var enabled = Driver.FindElement(By.Id("Enabled"));
|
||||
if (!enabled.Selected) enabled.Click();
|
||||
|
||||
public void AddInternalLightningNode(string cryptoCode)
|
||||
{
|
||||
Driver.FindElement(By.Id($"Modify-Lightning{cryptoCode}")).Click();
|
||||
Driver.FindElement(By.Id($"internal-ln-node-setter")).Click();
|
||||
Driver.FindElement(By.Id($"save")).Click();
|
||||
Driver.FindElement(By.Id("test")).Click();
|
||||
Assert.Contains("Connection to the Lightning node succeeded.", FindAlertMessage().Text);
|
||||
|
||||
Driver.FindElement(By.Id("save")).Click();
|
||||
}
|
||||
|
||||
public void ClickOnAllSideMenus()
|
||||
|
|
|
@ -313,13 +313,15 @@ namespace BTCPayServer.Tests
|
|||
}
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
[Trait("Lightning", "Lightning")]
|
||||
public async Task CanCreateStores()
|
||||
{
|
||||
using (var s = SeleniumTester.Create())
|
||||
{
|
||||
s.Server.ActivateLightning();
|
||||
await s.StartAsync();
|
||||
var alice = s.RegisterNewUser();
|
||||
var storeData = s.CreateNewStore();
|
||||
var alice = s.RegisterNewUser(true);
|
||||
var (storeName, storeId) = s.CreateNewStore();
|
||||
var onchainHint = "Set up your wallet to receive payments at your store.";
|
||||
var offchainHint = "A connection to a Lightning node is required to receive Lightning payments.";
|
||||
|
||||
|
@ -328,23 +330,31 @@ namespace BTCPayServer.Tests
|
|||
Assert.True(s.Driver.PageSource.Contains(offchainHint), "Lightning hint not present");
|
||||
|
||||
s.GoToStores();
|
||||
Assert.True(s.Driver.PageSource.Contains("warninghint_" + storeData.storeId),
|
||||
"Warning hint on list not present");
|
||||
Assert.True(s.Driver.PageSource.Contains($"warninghint_{storeId}"), "Warning hint on list not present");
|
||||
|
||||
s.GoToStore(storeData.storeId);
|
||||
s.GoToStore(storeId);
|
||||
Assert.Contains(storeName, s.Driver.PageSource);
|
||||
Assert.True(s.Driver.PageSource.Contains(onchainHint), "Wallet hint should be present at this point");
|
||||
Assert.True(s.Driver.PageSource.Contains(offchainHint), "Lightning hint should be present at this point");
|
||||
|
||||
s.AddDerivationScheme(); // wallet hint should be dismissed
|
||||
// setup onchain wallet
|
||||
s.GoToStore(storeId);
|
||||
s.AddDerivationScheme();
|
||||
s.Driver.AssertNoError();
|
||||
Assert.False(s.Driver.PageSource.Contains(onchainHint),
|
||||
"Wallet hint not dismissed on derivation scheme add");// dismiss lightning hint
|
||||
Assert.False(s.Driver.PageSource.Contains(onchainHint), "Wallet hint not dismissed on derivation scheme add");
|
||||
|
||||
// setup offchain wallet
|
||||
s.GoToStore(storeId);
|
||||
s.AddLightningNode();
|
||||
s.Driver.AssertNoError();
|
||||
var successAlert = s.FindAlertMessage();
|
||||
Assert.Contains("BTC Lightning node modified.", successAlert.Text);
|
||||
Assert.False(s.Driver.PageSource.Contains(offchainHint), "Lightning hint should be dismissed at this point");
|
||||
|
||||
Assert.Contains(storeData.storeName, s.Driver.PageSource);
|
||||
var storeUrl = s.Driver.Url;
|
||||
s.ClickOnAllSideMenus();
|
||||
s.GoToInvoices();
|
||||
var invoiceId = s.CreateInvoice(storeData.storeName);
|
||||
var invoiceId = s.CreateInvoice(storeName);
|
||||
s.FindAlertMessage();
|
||||
s.Driver.FindElement(By.ClassName("invoice-details-link")).Click();
|
||||
var invoiceUrl = s.Driver.Url;
|
||||
|
@ -399,10 +409,6 @@ namespace BTCPayServer.Tests
|
|||
s.Logout();
|
||||
s.LogIn(alice);
|
||||
s.Driver.FindElement(By.Id("Stores")).Click();
|
||||
|
||||
// there shouldn't be any hints now
|
||||
Assert.False(s.Driver.PageSource.Contains(offchainHint), "Lightning hint should be dismissed at this point");
|
||||
|
||||
s.Driver.FindElement(By.LinkText("Remove")).Click();
|
||||
s.Driver.FindElement(By.Id("continue")).Click();
|
||||
s.Driver.FindElement(By.Id("Stores")).Click();
|
||||
|
|
|
@ -24,6 +24,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||
using Microsoft.CodeAnalysis.Operations;
|
||||
using NBitcoin;
|
||||
using BTCPayServer.BIP78.Sender;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using NBitcoin.Payment;
|
||||
using NBitpayClient;
|
||||
using NBXplorer.DerivationStrategy;
|
||||
|
@ -267,12 +268,13 @@ namespace BTCPayServer.Tests
|
|||
}
|
||||
public async Task RegisterLightningNodeAsync(string cryptoCode, LightningConnectionType? connectionType, bool isMerchant = true, string storeId = null)
|
||||
{
|
||||
var storeController = this.GetController<StoresController>();
|
||||
var storeController = GetController<StoresController>();
|
||||
|
||||
string connectionString = parent.GetLightningConnectionString(connectionType, isMerchant);
|
||||
var connectionString = parent.GetLightningConnectionString(connectionType, isMerchant);
|
||||
var nodeType = connectionString == LightningSupportedPaymentMethod.InternalNode ? LightningNodeType.Internal : LightningNodeType.Custom;
|
||||
|
||||
await storeController.AddLightningNode(storeId ?? StoreId,
|
||||
new LightningNodeViewModel() { ConnectionString = connectionString, SkipPortTest = true }, "save", "BTC");
|
||||
new LightningNodeViewModel { ConnectionString = connectionString, LightningNodeType = nodeType, SkipPortTest = true }, "save", "BTC");
|
||||
if (storeController.ModelState.ErrorCount != 0)
|
||||
Assert.False(true, storeController.ModelState.FirstOrDefault().Value.Errors[0].ErrorMessage);
|
||||
}
|
||||
|
|
|
@ -14,15 +14,14 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
public partial class StoresController
|
||||
{
|
||||
|
||||
[HttpGet]
|
||||
[Route("{storeId}/lightning/{cryptoCode}")]
|
||||
[HttpGet("{storeId}/lightning/{cryptoCode}")]
|
||||
public IActionResult AddLightningNode(string storeId, string cryptoCode)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
if (store == null)
|
||||
return NotFound();
|
||||
LightningNodeViewModel vm = new LightningNodeViewModel
|
||||
|
||||
var vm = new LightningNodeViewModel
|
||||
{
|
||||
CryptoCode = cryptoCode,
|
||||
StoreId = storeId
|
||||
|
@ -31,62 +30,50 @@ namespace BTCPayServer.Controllers
|
|||
return View(vm);
|
||||
}
|
||||
|
||||
private void SetExistingValues(StoreData store, LightningNodeViewModel vm)
|
||||
{
|
||||
if (GetExistingLightningSupportedPaymentMethod(vm.CryptoCode, store) is LightningSupportedPaymentMethod paymentMethod)
|
||||
{
|
||||
vm.ConnectionString = paymentMethod.GetDisplayableConnectionString();
|
||||
}
|
||||
vm.Enabled = !store.GetStoreBlob().IsExcluded(new PaymentMethodId(vm.CryptoCode, PaymentTypes.LightningLike));
|
||||
vm.CanUseInternalNode = CanUseInternalLightning();
|
||||
}
|
||||
private LightningSupportedPaymentMethod GetExistingLightningSupportedPaymentMethod(string cryptoCode, StoreData store)
|
||||
{
|
||||
var id = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);
|
||||
var existing = store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.OfType<LightningSupportedPaymentMethod>()
|
||||
.FirstOrDefault(d => d.PaymentId == id);
|
||||
return existing;
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("{storeId}/lightning/{cryptoCode}")]
|
||||
[HttpPost("{storeId}/lightning/{cryptoCode}")]
|
||||
public async Task<IActionResult> AddLightningNode(string storeId, LightningNodeViewModel vm, string command, string cryptoCode)
|
||||
{
|
||||
vm.CryptoCode = cryptoCode;
|
||||
var store = HttpContext.GetStoreData();
|
||||
if (store == null)
|
||||
return NotFound();
|
||||
var network = vm.CryptoCode == null ? null : _ExplorerProvider.GetNetwork(vm.CryptoCode);
|
||||
|
||||
vm.CanUseInternalNode = CanUseInternalLightning();
|
||||
|
||||
var network = vm.CryptoCode == null ? null : _ExplorerProvider.GetNetwork(vm.CryptoCode);
|
||||
if (network == null)
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.CryptoCode), "Invalid network");
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
PaymentMethodId paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.LightningLike);
|
||||
Payments.Lightning.LightningSupportedPaymentMethod paymentMethod = null;
|
||||
if (vm.ConnectionString == LightningSupportedPaymentMethod.InternalNode)
|
||||
var paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.LightningLike);
|
||||
LightningSupportedPaymentMethod paymentMethod = null;
|
||||
if (vm.LightningNodeType == LightningNodeType.Internal)
|
||||
{
|
||||
if (!CanUseInternalLightning())
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), $"You are not authorized to use the internal lightning node");
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), "You are not authorized to use the internal lightning node");
|
||||
return View(vm);
|
||||
}
|
||||
paymentMethod = new Payments.Lightning.LightningSupportedPaymentMethod()
|
||||
paymentMethod = new LightningSupportedPaymentMethod
|
||||
{
|
||||
CryptoCode = paymentMethodId.CryptoCode
|
||||
};
|
||||
paymentMethod.SetInternalNode();
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(vm.ConnectionString))
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrEmpty(vm.ConnectionString))
|
||||
{
|
||||
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))
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), $"Invalid URL ({error})");
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
if (connectionString.ConnectionType == LightningConnectionType.LndGRPC)
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), $"BTCPay does not support gRPC connections");
|
||||
|
@ -94,11 +81,11 @@ namespace BTCPayServer.Controllers
|
|||
}
|
||||
if (!User.IsInRole(Roles.ServerAdmin) && !connectionString.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 '.'.");
|
||||
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);
|
||||
}
|
||||
|
||||
paymentMethod = new Payments.Lightning.LightningSupportedPaymentMethod()
|
||||
paymentMethod = new LightningSupportedPaymentMethod
|
||||
{
|
||||
CryptoCode = paymentMethodId.CryptoCode
|
||||
};
|
||||
|
@ -114,24 +101,20 @@ namespace BTCPayServer.Controllers
|
|||
store.SetStoreBlob(storeBlob);
|
||||
store.SetSupportedPaymentMethod(paymentMethodId, paymentMethod);
|
||||
await _Repo.UpdateStore(store);
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"Lightning node modified ({network.CryptoCode})";
|
||||
return RedirectToAction(nameof(UpdateStore), new { storeId = storeId });
|
||||
case "test" when paymentMethod == null:
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), "Missing url parameter");
|
||||
return View(vm);
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"{network.CryptoCode} Lightning node modified.";
|
||||
return RedirectToAction(nameof(UpdateStore), new { storeId });
|
||||
|
||||
case "test":
|
||||
var handler = _ServiceProvider.GetRequiredService<LightningLikePaymentHandler>();
|
||||
try
|
||||
{
|
||||
var info = await handler.GetNodeInfo(this.Request.IsOnion(), paymentMethod, network);
|
||||
var info = await handler.GetNodeInfo(Request.IsOnion(), paymentMethod, network);
|
||||
if (!vm.SkipPortTest)
|
||||
{
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(20)))
|
||||
{
|
||||
await handler.TestConnection(info, cts.Token);
|
||||
}
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(20));
|
||||
await handler.TestConnection(info, cts.Token);
|
||||
}
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"Connection to the lightning node succeeded. Your node address: {info}";
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"Connection to the Lightning node succeeded. Your node address: {info}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -139,13 +122,36 @@ namespace BTCPayServer.Controllers
|
|||
return View(vm);
|
||||
}
|
||||
return View(vm);
|
||||
|
||||
default:
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanUseInternalLightning()
|
||||
{
|
||||
return User.IsInRole(Roles.ServerAdmin) || _CssThemeManager.AllowLightningInternalNodeForAll;
|
||||
}
|
||||
|
||||
private void SetExistingValues(StoreData store, LightningNodeViewModel vm)
|
||||
{
|
||||
var lightning = GetExistingLightningSupportedPaymentMethod(vm.CryptoCode, store);
|
||||
if (lightning != null)
|
||||
{
|
||||
vm.LightningNodeType = lightning.IsInternalNode ? LightningNodeType.Internal : LightningNodeType.Custom;
|
||||
vm.ConnectionString = lightning.GetDisplayableConnectionString();
|
||||
}
|
||||
vm.Enabled = !store.GetStoreBlob().IsExcluded(new PaymentMethodId(vm.CryptoCode, PaymentTypes.LightningLike)) && lightning != null;
|
||||
vm.CanUseInternalNode = CanUseInternalLightning();
|
||||
}
|
||||
|
||||
private LightningSupportedPaymentMethod GetExistingLightningSupportedPaymentMethod(string cryptoCode, StoreData store)
|
||||
{
|
||||
var id = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);
|
||||
var existing = store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.OfType<LightningSupportedPaymentMethod>()
|
||||
.FirstOrDefault(d => d.PaymentId == id);
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,27 +2,22 @@ using System.ComponentModel.DataAnnotations;
|
|||
|
||||
namespace BTCPayServer.Models.StoreViewModels
|
||||
{
|
||||
public enum LightningNodeType
|
||||
{
|
||||
None,
|
||||
Internal,
|
||||
Custom
|
||||
}
|
||||
|
||||
public class LightningNodeViewModel
|
||||
{
|
||||
public LightningNodeType LightningNodeType { get; set; }
|
||||
[Display(Name = "Connection string")]
|
||||
public string ConnectionString
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string CryptoCode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public string ConnectionString { get; set; }
|
||||
public string CryptoCode { get; set; }
|
||||
public bool CanUseInternalNode { get; set; }
|
||||
|
||||
public bool SkipPortTest { get; set; }
|
||||
|
||||
[Display(Name="Lightning enabled")]
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
public string StoreId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,49 +7,40 @@
|
|||
<partial name="_StatusMessage" />
|
||||
|
||||
<div class="alert alert-warning alert-dismissible mb-5" role="alert">
|
||||
<h4 class="alert-heading">Warning</h4>
|
||||
<p>
|
||||
<span>Before you proceed, please understand that the Lightning Network is still considered experimental and is under active development.</span>
|
||||
<p class="mb-0">
|
||||
Please understand that the Lightning Network is still under active development and considered experimental.
|
||||
Before you proceed, take time to familiarize yourself with the risks.
|
||||
<a href="https://docs.btcpayserver.org/LightningNetwork/" class="alert-link">More information</a>
|
||||
</p>
|
||||
<p><strong>Do not add money that you can't afford to lose - there's a high risk of loss of funds.</strong></p>
|
||||
<p class="mb-2">Take time to familiarize yourself with the risks, some of which are:</p>
|
||||
<ul class="mb-4">
|
||||
<li>Most BTCPay Server deployments run on a pruned node which, while working, is not officially supported by lightning network implementations.</li>
|
||||
<li>
|
||||
Lightning keys are NOT automatically backed up by BTCPay Server. Your keys are in a hot-wallet. This means:
|
||||
<ul>
|
||||
<li>If you erase your BTCPay Server virtual machine: you lose all the funds.</li>
|
||||
<li>If your server gets hacked: a hacker can take all of your funds by accessing your keys.</li>
|
||||
<li>If there is a bug in a lightning network implementation: you could lose all the funds.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<p class="mb-2">To proceed, please ensure that:</p>
|
||||
<ul>
|
||||
<li>You accept being #reckless and being the sole responsible party for any loss of funds.</li>
|
||||
<li>You agree to keep on your lightning node only what you can afford to lose.</li>
|
||||
</ul>
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3 class="mb-3">Lightning Node Connection</h3>
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<p class="mb-2">The connection string encapsulates the configuration for connecting to your lightning node. BTCPay Server currently supports:</p>
|
||||
<style>
|
||||
#CustomSetup { display: none; }
|
||||
#LightningNodeType-Custom:checked + * + #CustomSetup { display: block; }
|
||||
</style>
|
||||
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-radio">
|
||||
<input asp-for="LightningNodeType" value="@LightningNodeType.Internal" type="radio" id="LightningNodeType-@LightningNodeType.Internal" class="custom-control-input" disabled="@(!Model.CanUseInternalNode)">
|
||||
<label asp-for="LightningNodeType" for="@($"LightningNodeType-{LightningNodeType.Internal}")" class="custom-control-label">Use the internal Lightning node</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-radio">
|
||||
<input asp-for="LightningNodeType" value="@LightningNodeType.Custom" type="radio" id="LightningNodeType-@LightningNodeType.Custom" class="custom-control-input">
|
||||
<label asp-for="LightningNodeType" for="@($"LightningNodeType-{LightningNodeType.Custom}")" class="custom-control-label">Use a custom Lightning node <span class="text-muted">(requires connection string)</span></label>
|
||||
<div id="CustomSetup">
|
||||
<div class="form-group my-3">
|
||||
<label asp-for="ConnectionString">The connection string configuration for your custom Lightning node:</label>
|
||||
<input asp-for="ConnectionString" class="form-control" placeholder="type=…;server=…;" value="@(Model.LightningNodeType == LightningNodeType.Internal ? "" : Model.ConnectionString)" />
|
||||
<span asp-validation-for="ConnectionString" class="text-danger"></span>
|
||||
</div>
|
||||
<p class="mt-4 mb-2">BTCPay Server currently supports:</p>
|
||||
<ul>
|
||||
<li class="mb-2">
|
||||
<strong>Internal node</strong>, if you are administrator of the server:
|
||||
<ul>
|
||||
<li>
|
||||
<code>Internal Node</code>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<strong>c-lightning</strong> via TCP or unix domain socket connection:
|
||||
<ul>
|
||||
|
@ -105,37 +96,30 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label asp-for="ConnectionString"></label>
|
||||
<input asp-for="ConnectionString" class="form-control" />
|
||||
<span asp-validation-for="ConnectionString" class="text-danger"></span>
|
||||
@if (Model.CanUseInternalNode)
|
||||
{
|
||||
<p class="form-text text-muted">
|
||||
Use the internal lightning node of this BTCPay Server instance by
|
||||
<a href="#" id="internal-ln-node-setter" onclick="$('#ConnectionString').val('Internal Node');return false;">clicking here</a>.
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="form-group form-check">
|
||||
<input asp-for="Enabled" type="checkbox" class="form-check-input" />
|
||||
<label asp-for="Enabled" class="form-check-label"></label>
|
||||
</div>
|
||||
<button id="save" name="command" type="submit" value="save" class="btn btn-primary">Submit</button>
|
||||
<button name="command" type="submit" value="test" class="btn btn-secondary mr-3">Test connection</button>
|
||||
<a class="text-secondary"
|
||||
asp-controller="PublicLightningNodeInfo"
|
||||
asp-action="ShowLightningNodeInfo"
|
||||
asp-route-cryptoCode="@Model.CryptoCode"
|
||||
asp-route-storeId="@Model.StoreId"
|
||||
target="_blank">
|
||||
<span class="fa fa-info-circle" title="More information..."></span>
|
||||
Open Public Node Info Page
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group mt-4 mb-5">
|
||||
<label asp-for="Enabled" class="form-check-label"></label>
|
||||
<input asp-for="Enabled" type="checkbox" class="btcpay-toggle ml-2" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button id="save" name="command" type="submit" value="save" class="btn btn-primary mr-2">Submit</button>
|
||||
<button id="test" name="command" type="submit" value="test" class="btn btn-secondary mr-3">Test connection</button>
|
||||
|
||||
<a class="text-secondary"
|
||||
asp-controller="PublicLightningNodeInfo"
|
||||
asp-action="ShowLightningNodeInfo"
|
||||
asp-route-cryptoCode="@Model.CryptoCode"
|
||||
asp-route-storeId="@Model.StoreId"
|
||||
target="_blank">
|
||||
<span class="fa fa-info-circle" title="More information..."></span>
|
||||
Open Public Node Info Page
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@section Scripts {
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
|
|
Loading…
Add table
Reference in a new issue