Move enabling toggle to store overview

This commit is contained in:
Dennis Reimann
2021-04-16 15:31:09 +02:00
parent 1ada87ca31
commit 5fda21373e
9 changed files with 175 additions and 100 deletions

View File

@@ -50,13 +50,14 @@ namespace BTCPayServer.Tests
tester.ActivateLightning(); tester.ActivateLightning();
await tester.StartAsync(); await tester.StartAsync();
var user = tester.NewAccount(); var user = tester.NewAccount();
user.GrantAccess(true); var cryptoCode = "BTC";
user.RegisterDerivationScheme("BTC"); await user.GrantAccessAsync(true);
user.RegisterDerivationScheme(cryptoCode);
user.RegisterDerivationScheme("LTC"); user.RegisterDerivationScheme("LTC");
user.RegisterLightningNode("BTC", LightningConnectionType.CLightning); user.RegisterLightningNode(cryptoCode, LightningConnectionType.CLightning);
var btcNetwork = tester.PayTester.Networks.GetNetwork<BTCPayNetwork>("BTC"); var btcNetwork = tester.PayTester.Networks.GetNetwork<BTCPayNetwork>(cryptoCode);
var invoice = user.BitPay.CreateInvoice( var invoice = await user.BitPay.CreateInvoiceAsync(
new Invoice() new Invoice
{ {
Price = 1.5m, Price = 1.5m,
Currency = "USD", Currency = "USD",
@@ -69,36 +70,43 @@ namespace BTCPayServer.Tests
Assert.Equal(3, invoice.CryptoInfo.Length); Assert.Equal(3, invoice.CryptoInfo.Length);
var controller = user.GetController<StoresController>(); var controller = user.GetController<StoresController>();
var lightningVm = (LightningNodeViewModel)Assert.IsType<ViewResult>(controller.AddLightningNode(user.StoreId, "BTC")).Model; var lightningVm = (LightningNodeViewModel)Assert.IsType<ViewResult>(controller.AddLightningNode(user.StoreId, cryptoCode)).Model;
Assert.True(lightningVm.Enabled); Assert.True(lightningVm.Enabled);
lightningVm.Enabled = false; var response = await controller.SetLightningNodeEnabled(user.StoreId, cryptoCode, false);
controller.AddLightningNode(user.StoreId, lightningVm, "save", "BTC").GetAwaiter().GetResult(); Assert.IsType<RedirectToActionResult>(response);
lightningVm = (LightningNodeViewModel)Assert.IsType<ViewResult>(controller.AddLightningNode(user.StoreId, "BTC")).Model;
Assert.False(lightningVm.Enabled); // Get enabled state from overview action
StoreViewModel storeModel;
response = controller.UpdateStore();
storeModel = (StoreViewModel)Assert.IsType<ViewResult>(response).Model;
var lnNode = storeModel.LightningNodes.Find(node => node.CryptoCode == cryptoCode);
Assert.NotNull(lnNode);
Assert.False(lnNode.Enabled);
WalletSetupViewModel setupVm; WalletSetupViewModel setupVm;
var storeId = user.StoreId; var storeId = user.StoreId;
var cryptoCode = "BTC"; response = await controller.GenerateWallet(storeId, cryptoCode, WalletSetupMethod.GenerateOptions, new GenerateWalletRequest());
var response = await controller.GenerateWallet(storeId, cryptoCode, WalletSetupMethod.GenerateOptions, new GenerateWalletRequest());
Assert.IsType<ViewResult>(response); Assert.IsType<ViewResult>(response);
// Get setup view model from modify action // Get enabled state from overview action
response = await controller.ModifyWallet(new WalletSetupViewModel { StoreId = storeId, CryptoCode = cryptoCode }); response = controller.UpdateStore();
setupVm = (WalletSetupViewModel)Assert.IsType<ViewResult>(response).Model; storeModel = (StoreViewModel)Assert.IsType<ViewResult>(response).Model;
Assert.True(setupVm.Enabled); var derivationScheme = storeModel.DerivationSchemes.Find(scheme => scheme.Crypto == cryptoCode);
Assert.NotNull(derivationScheme);
Assert.True(derivationScheme.Enabled);
// Only Enabling/Disabling the payment method must redirect to store page // Disable wallet
setupVm.Enabled = false; response = controller.SetWalletEnabled(storeId, cryptoCode, false).GetAwaiter().GetResult();
response = controller.UpdateWallet(setupVm).GetAwaiter().GetResult();
Assert.IsType<RedirectToActionResult>(response); Assert.IsType<RedirectToActionResult>(response);
response = controller.UpdateStore();
storeModel = (StoreViewModel)Assert.IsType<ViewResult>(response).Model;
derivationScheme = storeModel.DerivationSchemes.Find(scheme => scheme.Crypto == cryptoCode);
Assert.NotNull(derivationScheme);
Assert.False(derivationScheme.Enabled);
response = await controller.ModifyWallet(new WalletSetupViewModel { StoreId = storeId, CryptoCode = cryptoCode }); var oldScheme = derivationScheme.Value;
setupVm = (WalletSetupViewModel)Assert.IsType<ViewResult>(response).Model;
Assert.False(setupVm.Enabled);
var oldScheme = setupVm.DerivationScheme; invoice = await user.BitPay.CreateInvoiceAsync(
invoice = user.BitPay.CreateInvoice(
new Invoice new Invoice
{ {
Price = 1.5m, Price = 1.5m,
@@ -113,7 +121,7 @@ namespace BTCPayServer.Tests
Assert.Equal("LTC", invoice.CryptoInfo[0].CryptoCode); Assert.Equal("LTC", invoice.CryptoInfo[0].CryptoCode);
// Removing the derivation scheme, should redirect to store page // Removing the derivation scheme, should redirect to store page
response = controller.ConfirmDeleteWallet(user.StoreId, "BTC").GetAwaiter().GetResult(); response = controller.ConfirmDeleteWallet(user.StoreId, cryptoCode).GetAwaiter().GetResult();
Assert.IsType<RedirectToActionResult>(response); Assert.IsType<RedirectToActionResult>(response);
// Setting it again should show the confirmation page // Setting it again should show the confirmation page
@@ -172,8 +180,8 @@ namespace BTCPayServer.Tests
Assert.Equal(expected.ToJson(), onchainBTC.ToJson()); Assert.Equal(expected.ToJson(), onchainBTC.ToJson());
// Let's check that the root hdkey and account key path are taken into account when making a PSBT // Let's check that the root hdkey and account key path are taken into account when making a PSBT
invoice = user.BitPay.CreateInvoice( invoice = await user.BitPay.CreateInvoiceAsync(
new Invoice() new Invoice
{ {
Price = 1.5m, Price = 1.5m,
Currency = "USD", Currency = "USD",
@@ -184,7 +192,7 @@ namespace BTCPayServer.Tests
}, Facade.Merchant); }, Facade.Merchant);
tester.ExplorerNode.Generate(1); tester.ExplorerNode.Generate(1);
var invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo.First(c => c.CryptoCode == "BTC").Address, var invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo.First(c => c.CryptoCode == cryptoCode).Address,
tester.ExplorerNode.Network); tester.ExplorerNode.Network);
tester.ExplorerNode.SendToAddress(invoiceAddress, Money.Coins(1m)); tester.ExplorerNode.SendToAddress(invoiceAddress, Money.Coins(1m));
TestUtils.Eventually(() => TestUtils.Eventually(() =>
@@ -196,9 +204,9 @@ namespace BTCPayServer.Tests
var psbt = wallet.CreatePSBT(btcNetwork, onchainBTC, var psbt = wallet.CreatePSBT(btcNetwork, onchainBTC,
new WalletSendModel() new WalletSendModel()
{ {
Outputs = new List<WalletSendModel.TransactionOutput>() Outputs = new List<WalletSendModel.TransactionOutput>
{ {
new WalletSendModel.TransactionOutput() new WalletSendModel.TransactionOutput
{ {
Amount = 0.5m, Amount = 0.5m,
DestinationAddress = new Key().PubKey.GetAddress(ScriptPubKeyType.Legacy, btcNetwork.NBitcoinNetwork) DestinationAddress = new Key().PubKey.GetAddress(ScriptPubKeyType.Legacy, btcNetwork.NBitcoinNetwork)
@@ -304,7 +312,7 @@ namespace BTCPayServer.Tests
var controller = tester.PayTester.GetController<InvoiceController>(null); var controller = tester.PayTester.GetController<InvoiceController>(null);
var checkout = var checkout =
(Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id, null) (Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id)
.GetAwaiter().GetResult()).Value; .GetAwaiter().GetResult()).Value;
Assert.Single(checkout.AvailableCryptos); Assert.Single(checkout.AvailableCryptos);
Assert.Equal("LTC", checkout.CryptoCode); Assert.Equal("LTC", checkout.CryptoCode);
@@ -321,7 +329,7 @@ namespace BTCPayServer.Tests
{ {
invoice = user.BitPay.GetInvoice(invoice.Id); invoice = user.BitPay.GetInvoice(invoice.Id);
Assert.Equal("paid", invoice.Status); Assert.Equal("paid", invoice.Status);
checkout = (Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id, null) checkout = (Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id)
.GetAwaiter().GetResult()).Value; .GetAwaiter().GetResult()).Value;
Assert.Equal("paid", checkout.Status); Assert.Equal("paid", checkout.Status);
}); });

View File

@@ -219,13 +219,18 @@ namespace BTCPayServer.Tests
Driver.FindElement(By.Id("ConnectionString")).SendKeys(connectionString); Driver.FindElement(By.Id("ConnectionString")).SendKeys(connectionString);
} }
var enabled = Driver.FindElement(By.Id("Enabled"));
if (!enabled.Selected) enabled.Click();
Driver.FindElement(By.Id("test")).Click(); Driver.FindElement(By.Id("test")).Click();
Assert.Contains("Connection to the Lightning node succeeded.", FindAlertMessage().Text); Assert.Contains("Connection to the Lightning node succeeded.", FindAlertMessage().Text);
Driver.FindElement(By.Id("save")).Click(); Driver.FindElement(By.Id("save")).Click();
Assert.Contains($"{cryptoCode} Lightning node modified.", FindAlertMessage().Text);
var enabled = Driver.FindElement(By.Id($"{cryptoCode}LightningEnabled"));
if (enabled.Text == "Enable")
{
enabled.Click();
Assert.Contains($"{cryptoCode} Lightning payments are now enabled for this store.", FindAlertMessage().Text);
}
} }
public void ClickOnAllSideMenus() public void ClickOnAllSideMenus()

View File

@@ -274,7 +274,7 @@ namespace BTCPayServer.Tests
var nodeType = connectionString == LightningSupportedPaymentMethod.InternalNode ? LightningNodeType.Internal : LightningNodeType.Custom; var nodeType = connectionString == LightningSupportedPaymentMethod.InternalNode ? LightningNodeType.Internal : LightningNodeType.Custom;
await storeController.AddLightningNode(storeId ?? StoreId, await storeController.AddLightningNode(storeId ?? StoreId,
new LightningNodeViewModel { ConnectionString = connectionString, LightningNodeType = nodeType, SkipPortTest = true }, "save", "BTC"); new LightningNodeViewModel { ConnectionString = connectionString, LightningNodeType = nodeType, SkipPortTest = true }, "save", cryptoCode);
if (storeController.ModelState.ErrorCount != 0) if (storeController.ModelState.ErrorCount != 0)
Assert.False(true, storeController.ModelState.FirstOrDefault().Value.Errors[0].ErrorMessage); Assert.False(true, storeController.ModelState.FirstOrDefault().Value.Errors[0].ErrorMessage);
} }

View File

@@ -48,6 +48,8 @@ namespace BTCPayServer.Controllers
} }
var paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.LightningLike); var paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.LightningLike);
var lightning = GetExistingLightningSupportedPaymentMethod(vm.CryptoCode, store);
LightningSupportedPaymentMethod paymentMethod = null; LightningSupportedPaymentMethod paymentMethod = null;
if (vm.LightningNodeType == LightningNodeType.Internal) if (vm.LightningNodeType == LightningNodeType.Internal)
{ {
@@ -96,7 +98,6 @@ namespace BTCPayServer.Controllers
{ {
case "save": case "save":
var storeBlob = store.GetStoreBlob(); var storeBlob = store.GetStoreBlob();
storeBlob.SetExcluded(paymentMethodId, !vm.Enabled);
storeBlob.Hints.Lightning = false; storeBlob.Hints.Lightning = false;
store.SetStoreBlob(storeBlob); store.SetStoreBlob(storeBlob);
store.SetSupportedPaymentMethod(paymentMethodId, paymentMethod); store.SetSupportedPaymentMethod(paymentMethodId, paymentMethod);
@@ -128,6 +129,38 @@ namespace BTCPayServer.Controllers
} }
} }
[HttpPost("{storeId}/lightning/{cryptoCode}/status")]
public async Task<IActionResult> SetLightningNodeEnabled(string storeId, string cryptoCode, bool enabled)
{
var store = HttpContext.GetStoreData();
if (store == null)
return NotFound();
var network = cryptoCode == null ? null : _ExplorerProvider.GetNetwork(cryptoCode);
if (network == null)
return NotFound();
var lightning = GetExistingLightningSupportedPaymentMethod(cryptoCode, store);
if (lightning == null)
return NotFound();
if (!User.IsInRole(Roles.ServerAdmin))
{
TempData[WellKnownTempData.ErrorMessage] = $"Only the server admin can {(enabled ? "enable" : "disable")} the lightning node";
}
else
{
var paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.LightningLike);
var storeBlob = store.GetStoreBlob();
storeBlob.SetExcluded(paymentMethodId, !enabled);
store.SetStoreBlob(storeBlob);
await _Repo.UpdateStore(store);
TempData[WellKnownTempData.SuccessMessage] = $"{network.CryptoCode} Lightning payments are now {(enabled ? "enabled" : "disabled")} for this store.";
}
return RedirectToAction(nameof(UpdateStore), new { storeId });
}
private bool CanUseInternalLightning() private bool CanUseInternalLightning()
{ {
return User.IsInRole(Roles.ServerAdmin) || _CssThemeManager.AllowLightningInternalNodeForAll; return User.IsInRole(Roles.ServerAdmin) || _CssThemeManager.AllowLightningInternalNodeForAll;
@@ -141,7 +174,6 @@ namespace BTCPayServer.Controllers
vm.LightningNodeType = lightning.IsInternalNode ? LightningNodeType.Internal : LightningNodeType.Custom; vm.LightningNodeType = lightning.IsInternalNode ? LightningNodeType.Internal : LightningNodeType.Custom;
vm.ConnectionString = lightning.GetDisplayableConnectionString(); vm.ConnectionString = lightning.GetDisplayableConnectionString();
} }
vm.Enabled = !store.GetStoreBlob().IsExcluded(new PaymentMethodId(vm.CryptoCode, PaymentTypes.LightningLike)) && lightning != null;
vm.CanUseInternalNode = CanUseInternalLightning(); vm.CanUseInternalNode = CanUseInternalLightning();
} }

View File

@@ -157,9 +157,7 @@ namespace BTCPayServer.Controllers
var configChanged = oldConfig != vm.Config; var configChanged = oldConfig != vm.Config;
PaymentMethodId paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike); PaymentMethodId paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike);
var storeBlob = store.GetStoreBlob(); var storeBlob = store.GetStoreBlob();
var wasExcluded = storeBlob.GetExcludedPaymentMethods().Match(paymentMethodId);
var willBeExcluded = !vm.Enabled; var willBeExcluded = !vm.Enabled;
var excludedChanged = willBeExcluded != wasExcluded;
var showAddress = // Show addresses if: var showAddress = // Show addresses if:
// - If the user is testing the hint address in confirmation screen // - If the user is testing the hint address in confirmation screen
@@ -188,17 +186,7 @@ namespace BTCPayServer.Controllers
await _Repo.UpdateStore(store); await _Repo.UpdateStore(store);
_EventAggregator.Publish(new WalletChangedEvent {WalletId = new WalletId(vm.StoreId, vm.CryptoCode)}); _EventAggregator.Publish(new WalletChangedEvent {WalletId = new WalletId(vm.StoreId, vm.CryptoCode)});
if (excludedChanged) TempData[WellKnownTempData.SuccessMessage] = $"Derivation settings for {network.CryptoCode} have been modified.";
{
var label = willBeExcluded ? "disabled" : "enabled";
TempData[WellKnownTempData.SuccessMessage] =
$"On-Chain payments for {network.CryptoCode} have been {label}.";
}
else
{
TempData[WellKnownTempData.SuccessMessage] =
$"Derivation settings for {network.CryptoCode} have been modified.";
}
// This is success case when derivation scheme is added to the store // This is success case when derivation scheme is added to the store
return RedirectToAction(nameof(UpdateStore), new {storeId = vm.StoreId}); return RedirectToAction(nameof(UpdateStore), new {storeId = vm.StoreId});
@@ -506,6 +494,40 @@ namespace BTCPayServer.Controllers
}); });
} }
[HttpPost("{storeId}/onchain/{cryptoCode}/status")]
public async Task<IActionResult> SetWalletEnabled(string storeId, string cryptoCode, bool enabled)
{
var checkResult = IsAvailable(cryptoCode, out var store, out var network);
if (checkResult != null)
{
return checkResult;
}
var derivation = GetExistingDerivationStrategy(cryptoCode, store);
if (derivation == null)
{
return NotFound();
}
var wallet = _WalletProvider.GetWallet(network);
if (wallet == null)
{
return NotFound();
}
var paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike);
var storeBlob = store.GetStoreBlob();
storeBlob.SetExcluded(paymentMethodId, !enabled);
store.SetStoreBlob(storeBlob);
await _Repo.UpdateStore(store);
_EventAggregator.Publish(new WalletChangedEvent {WalletId = new WalletId(storeId, cryptoCode)});
TempData[WellKnownTempData.SuccessMessage] =
$"{network.CryptoCode} on-chain payments are now {(enabled ? "enabled" : "disabled")} for this store.";
return RedirectToAction(nameof(UpdateStore), new {storeId});
}
[HttpPost("{storeId}/onchain/{cryptoCode}/delete")] [HttpPost("{storeId}/onchain/{cryptoCode}/delete")]
public async Task<IActionResult> ConfirmDeleteWallet(string storeId, string cryptoCode) public async Task<IActionResult> ConfirmDeleteWallet(string storeId, string cryptoCode)
{ {

View File

@@ -544,11 +544,12 @@ namespace BTCPayServer.Controllers
break; break;
case LightningPaymentType _: case LightningPaymentType _:
var lightning = lightningByCryptoCode.TryGet(paymentMethodId.CryptoCode); var lightning = lightningByCryptoCode.TryGet(paymentMethodId.CryptoCode);
vm.LightningNodes.Add(new StoreViewModel.LightningNode() var isEnabled = !excludeFilters.Match(paymentMethodId) && lightning != null;
vm.LightningNodes.Add(new StoreViewModel.LightningNode
{ {
CryptoCode = paymentMethodId.CryptoCode, CryptoCode = paymentMethodId.CryptoCode,
Address = lightning?.GetDisplayableConnectionString(), Address = lightning?.GetDisplayableConnectionString(),
Enabled = !excludeFilters.Match(paymentMethodId) && lightning != null Enabled = isEnabled
}); });
break; break;
} }

View File

@@ -97,12 +97,6 @@
</ul> </ul>
</div> </div>
</div> </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>
<div> <div>

View File

@@ -48,14 +48,6 @@
<th>Type</th> <th>Type</th>
<td>@(Model.IsHotWallet ? "Hot wallet" : "Watch-only wallet")</td> <td>@(Model.IsHotWallet ? "Hot wallet" : "Watch-only wallet")</td>
</tr> </tr>
<tr>
<th>
Enabled
</th>
<td>
<button type="submit" class="btcpay-toggle @if (Model.Enabled) { @("btcpay-toggle--active") }" id="Modify" name="Enabled" value="@(Model.Enabled ? "false" : "true")">Save</button>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</form> </form>

View File

@@ -42,30 +42,36 @@
} }
</span> </span>
<span class="d-flex align-items-center fw-semibold"> <span class="d-flex align-items-center fw-semibold">
@if (scheme.Enabled) <form method="post"
{ asp-action="SetWalletEnabled"
<span class="d-flex align-items-center text-success"> asp-route-cryptoCode="@scheme.Crypto"
<span class="mr-2 btcpay-status btcpay-status--enabled"></span> asp-route-storeId="@Model.Id"
Enabled class="d-flex align-items-center"
</span> style="min-width:7.65rem">
} <button type="submit" class="btcpay-toggle mr-2 @if (scheme.Enabled) { @("btcpay-toggle--active") }" name="Enabled" value="@(scheme.Enabled ? "false" : "true")" id="@($"{scheme.Crypto}WalletEnabled")">@(scheme.Enabled ? "Disable" : "Enable")</button>
else @if (scheme.Enabled)
{ {
<span class="d-flex align-items-center text-danger"> <span class="text-primary">
<span class="mr-2 btcpay-status btcpay-status--disabled"></span> Enabled
Disabled </span>
</span> }
} else
{
<span class="text-muted">
Disabled
</span>
}
</form>
@if (isSetUp) @if (isSetUp)
{ {
<span class="text-light ml-3 mr-2">|</span> <span class="text-light ml-3 mr-2">|</span>
<a asp-action="ModifyWallet" asp-route-cryptoCode="@scheme.Crypto" asp-route-storeId="@Context.GetRouteValue("storeId")" id="@($"Modify{scheme.Crypto}")" class="btn btn-link px-1 py-1 fw-semibold"> <a asp-action="ModifyWallet" asp-route-cryptoCode="@scheme.Crypto" asp-route-storeId="@Model.Id" id="@($"Modify{scheme.Crypto}")" class="btn btn-link px-1 py-1 fw-semibold">
Modify Modify
</a> </a>
} }
else else
{ {
<a asp-action="SetupWallet" asp-route-cryptoCode="@scheme.Crypto" asp-route-storeId="@Context.GetRouteValue("storeId")" id="@($"Modify{scheme.Crypto}")" class="btn btn-primary btn-sm ml-4 px-3 py-1 fw-semibold"> <a asp-action="SetupWallet" asp-route-cryptoCode="@scheme.Crypto" asp-route-storeId="@Model.Id" id="@($"Modify{scheme.Crypto}")" class="btn btn-primary btn-sm ml-4 px-3 py-1 fw-semibold">
Setup Setup
</a> </a>
} }
@@ -107,27 +113,42 @@
{ {
<span class="smMaxWidth text-truncate text-secondary mr-3">@scheme.Address</span> <span class="smMaxWidth text-truncate text-secondary mr-3">@scheme.Address</span>
} }
<a class="text-secondary"
asp-controller="PublicLightningNodeInfo"
asp-action="ShowLightningNodeInfo"
asp-route-cryptoCode="@scheme.CryptoCode"
asp-route-storeId="@Model.Id"
target="_blank">
Public Node Info
</a>
</span> </span>
<span class="d-flex align-items-center fw-semibold"> <span class="d-flex align-items-center fw-semibold">
@if (scheme.Enabled) <form method="post"
{ asp-action="SetLightningNodeEnabled"
<span class="d-flex align-items-center text-success"> asp-route-cryptoCode="@scheme.CryptoCode"
<span class="mr-2 btcpay-status btcpay-status--enabled"></span> asp-route-storeId="@Model.Id"
Enabled class="d-flex align-items-center"
</span> style="min-width:7.65rem">
} <button type="submit" class="btcpay-toggle mr-2 @if (scheme.Enabled) { @("btcpay-toggle--active") }" name="Enabled" value="@(scheme.Enabled ? "false" : "true")" id="@($"{scheme.CryptoCode}LightningEnabled")">@(scheme.Enabled ? "Disable" : "Enable")e</button>
else @if (scheme.Enabled)
{ {
<span class="d-flex align-items-center text-danger"> <span class="text-primary">
<span class="mr-2 btcpay-status btcpay-status--disabled"></span> Enabled
Disabled </span>
</span> }
} else
{
<span class="text-muted">
Disabled
</span>
}
</form>
@if (isSetUp) @if (isSetUp)
{ {
<span class="text-light ml-3 mr-2">|</span> <span class="text-light ml-3 mr-2">|</span>
} }
<a asp-action="AddLightningNode" asp-route-cryptoCode="@scheme.CryptoCode" asp-route-storeId="@Context.GetRouteValue("storeId")" id="@($"Modify-Lightning{scheme.CryptoCode}")" class="btn btn-@(isSetUp ? "link px-1" : "primary btn-sm ml-4 px-3") py-1 fw-semibold"> <a asp-action="AddLightningNode" asp-route-cryptoCode="@scheme.CryptoCode" asp-route-storeId="@Model.Id" id="@($"Modify-Lightning{scheme.CryptoCode}")" class="btn btn-@(isSetUp ? "link px-1" : "primary btn-sm ml-4 px-3") py-1 fw-semibold">
@(isSetUp ? "Modify" : "Setup") @(isSetUp ? "Modify" : "Setup")
</a> </a>
</span> </span>