diff --git a/BTCPayServer.Tests/AltcoinTests/AltcoinTests.cs b/BTCPayServer.Tests/AltcoinTests/AltcoinTests.cs index 503db3668..8ec19f555 100644 --- a/BTCPayServer.Tests/AltcoinTests/AltcoinTests.cs +++ b/BTCPayServer.Tests/AltcoinTests/AltcoinTests.cs @@ -70,7 +70,7 @@ namespace BTCPayServer.Tests Assert.Equal(3, invoice.CryptoInfo.Length); var controller = user.GetController(); - var lightningVm = (LightningNodeViewModel)Assert.IsType(controller.AddLightningNode(user.StoreId, cryptoCode)).Model; + var lightningVm = (LightningNodeViewModel)Assert.IsType(controller.SetupLightningNode(user.StoreId, cryptoCode)).Model; Assert.True(lightningVm.Enabled); var response = await controller.SetLightningNodeEnabled(user.StoreId, cryptoCode, false); Assert.IsType(response); diff --git a/BTCPayServer.Tests/SeleniumTester.cs b/BTCPayServer.Tests/SeleniumTester.cs index 1414f0b0d..641c4c09f 100644 --- a/BTCPayServer.Tests/SeleniumTester.cs +++ b/BTCPayServer.Tests/SeleniumTester.cs @@ -68,7 +68,7 @@ namespace BTCPayServer.Tests cds.Port = Utils.FreeTcpPort(); cds.HostName = "127.0.0.1"; cds.Start(); - Driver = new ChromeDriver(cds, options, + Driver = new ChromeDriver(cds, options, // A bit less than test timeout TimeSpan.FromSeconds(50)); @@ -217,10 +217,10 @@ namespace BTCPayServer.Tests { Driver.FindElement(By.CssSelector("label[for=\"LightningNodeType-Custom\"]")).Click(); Driver.FindElement(By.Id("ConnectionString")).SendKeys(connectionString); - } - Driver.FindElement(By.Id("test")).Click(); - Assert.Contains("Connection to the Lightning node successful.", FindAlertMessage().Text); + Driver.FindElement(By.Id("test")).Click(); + Assert.Contains("Connection to the Lightning node successful.", FindAlertMessage().Text); + } Driver.FindElement(By.Id("save")).Click(); Assert.Contains($"{cryptoCode} Lightning node updated.", FindAlertMessage().Text); @@ -378,14 +378,14 @@ namespace BTCPayServer.Tests private void CheckForJSErrors() { //wait for seleniun update: https://stackoverflow.com/questions/57520296/selenium-webdriver-3-141-0-driver-manage-logs-availablelogtypes-throwing-syste - // var errorStrings = new List - // { - // "SyntaxError", - // "EvalError", - // "ReferenceError", - // "RangeError", - // "TypeError", - // "URIError" + // var errorStrings = new List + // { + // "SyntaxError", + // "EvalError", + // "ReferenceError", + // "RangeError", + // "TypeError", + // "URIError" // }; // // var jsErrors = Driver.Manage().Logs.GetLog(LogType.Browser).Where(x => errorStrings.Any(e => x.Message.Contains(e))); @@ -412,7 +412,7 @@ namespace BTCPayServer.Tests { Driver.Navigate().GoToUrl(new Uri(Server.PayTester.ServerUri, relativeUrl)); } - + public void GoToServer(ServerNavPages navPages = ServerNavPages.Index) { Driver.FindElement(By.Id("ServerSettings")).Click(); diff --git a/BTCPayServer.Tests/TestAccount.cs b/BTCPayServer.Tests/TestAccount.cs index 9ca8ce943..66771847d 100644 --- a/BTCPayServer.Tests/TestAccount.cs +++ b/BTCPayServer.Tests/TestAccount.cs @@ -273,7 +273,7 @@ namespace BTCPayServer.Tests var connectionString = parent.GetLightningConnectionString(connectionType, isMerchant); var nodeType = connectionString == LightningSupportedPaymentMethod.InternalNode ? LightningNodeType.Internal : LightningNodeType.Custom; - await storeController.AddLightningNode(storeId ?? StoreId, + await storeController.SetupLightningNode(storeId ?? StoreId, new LightningNodeViewModel { ConnectionString = connectionString, LightningNodeType = nodeType, SkipPortTest = true }, "save", cryptoCode); if (storeController.ModelState.ErrorCount != 0) Assert.False(true, storeController.ModelState.FirstOrDefault().Value.Errors[0].ErrorMessage); diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index f2dadb392..8204c474d 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -988,9 +988,9 @@ namespace BTCPayServer.Tests user.GrantAccess(true); var storeController = user.GetController(); Assert.IsType(storeController.UpdateStore()); - Assert.IsType(storeController.AddLightningNode(user.StoreId, "BTC")); + Assert.IsType(storeController.SetupLightningNode(user.StoreId, "BTC")); - var testResult = storeController.AddLightningNode(user.StoreId, new LightningNodeViewModel() + var testResult = storeController.SetupLightningNode(user.StoreId, new LightningNodeViewModel { ConnectionString = $"type=charge;server={tester.MerchantCharge.Client.Uri.AbsoluteUri};allowinsecure=true", SkipPortTest = true // We can't test this as the IP can't be resolved by the test host :( @@ -999,19 +999,19 @@ namespace BTCPayServer.Tests storeController.TempData.Clear(); Assert.True(storeController.ModelState.IsValid); - Assert.IsType(storeController.AddLightningNode(user.StoreId, - new LightningNodeViewModel() + Assert.IsType(storeController.SetupLightningNode(user.StoreId, + new LightningNodeViewModel { ConnectionString = $"type=charge;server={tester.MerchantCharge.Client.Uri.AbsoluteUri};allowinsecure=true" }, "save", "BTC").GetAwaiter().GetResult()); // Make sure old connection string format does not work - Assert.IsType(storeController.AddLightningNode(user.StoreId, - new LightningNodeViewModel() { ConnectionString = tester.MerchantCharge.Client.Uri.AbsoluteUri }, + Assert.IsType(storeController.SetupLightningNode(user.StoreId, + new LightningNodeViewModel { ConnectionString = tester.MerchantCharge.Client.Uri.AbsoluteUri }, "save", "BTC").GetAwaiter().GetResult()); var storeVm = - Assert.IsType(Assert + Assert.IsType(Assert .IsType(storeController.UpdateStore()).Model); Assert.Single(storeVm.LightningNodes.Where(l => !string.IsNullOrEmpty(l.Address))); } diff --git a/BTCPayServer/Controllers/StoresController.LightningLike.cs b/BTCPayServer/Controllers/StoresController.LightningLike.cs index 80b0fde50..9586cb008 100644 --- a/BTCPayServer/Controllers/StoresController.LightningLike.cs +++ b/BTCPayServer/Controllers/StoresController.LightningLike.cs @@ -15,7 +15,7 @@ namespace BTCPayServer.Controllers public partial class StoresController { [HttpGet("{storeId}/lightning/{cryptoCode}")] - public IActionResult AddLightningNode(string storeId, string cryptoCode) + public IActionResult SetupLightningNode(string storeId, string cryptoCode) { var store = HttpContext.GetStoreData(); if (store == null) @@ -31,7 +31,7 @@ namespace BTCPayServer.Controllers } [HttpPost("{storeId}/lightning/{cryptoCode}")] - public async Task AddLightningNode(string storeId, LightningNodeViewModel vm, string command, string cryptoCode) + public async Task SetupLightningNode(string storeId, LightningNodeViewModel vm, string command, string cryptoCode) { vm.CryptoCode = cryptoCode; var store = HttpContext.GetStoreData(); @@ -161,13 +161,17 @@ namespace BTCPayServer.Controllers private void SetExistingValues(StoreData store, LightningNodeViewModel vm) { + vm.CanUseInternalNode = CanUseInternalLightning(); var lightning = GetExistingLightningSupportedPaymentMethod(vm.CryptoCode, store); if (lightning != null) { vm.LightningNodeType = lightning.IsInternalNode ? LightningNodeType.Internal : LightningNodeType.Custom; vm.ConnectionString = lightning.GetDisplayableConnectionString(); } - vm.CanUseInternalNode = CanUseInternalLightning(); + else + { + vm.LightningNodeType = vm.CanUseInternalNode ? LightningNodeType.Internal : LightningNodeType.Custom; + } } private LightningSupportedPaymentMethod GetExistingLightningSupportedPaymentMethod(string cryptoCode, StoreData store) diff --git a/BTCPayServer/Models/StoreViewModels/LightningNodeViewModel.cs b/BTCPayServer/Models/StoreViewModels/LightningNodeViewModel.cs index 10c94d023..b4b97d571 100644 --- a/BTCPayServer/Models/StoreViewModels/LightningNodeViewModel.cs +++ b/BTCPayServer/Models/StoreViewModels/LightningNodeViewModel.cs @@ -4,7 +4,6 @@ namespace BTCPayServer.Models.StoreViewModels { public enum LightningNodeType { - None, Internal, Custom } diff --git a/BTCPayServer/Views/Stores/AddLightningNode.cshtml b/BTCPayServer/Views/Stores/AddLightningNode.cshtml deleted file mode 100644 index b5b162056..000000000 --- a/BTCPayServer/Views/Stores/AddLightningNode.cshtml +++ /dev/null @@ -1,120 +0,0 @@ -@model LightningNodeViewModel -@{ - Layout = "../Shared/_NavLayout.cshtml"; - ViewData.SetActivePageAndTitle(StoreNavPages.Index, "Lightning node settings", Context.GetStoreData().StoreName); -} - -

@ViewData["PageTitle"]

- - - - - -
-
-
- - -
-
-
-
- - -
-
- - - -
-

BTCPay Server currently supports:

-
    -
  • - c-lightning via TCP or unix domain socket connection: -
      -
    • - type=clightning;server=unix://root/.lightning/lightning-rpc -
    • -
    • - type=clightning;server=tcp://1.1.1.1:27743/ -
    • -
    -
  • -
  • - Lightning Charge via HTTPS: -
      -
    • - type=charge;server=https://charge:8080/;api-token=myapitoken... -
    • -
    -
  • -
  • - Eclair via HTTPS: -
      -
    • - type=eclair;server=https://eclair:8080/;password=eclairpassword... -
    • -
    -
  • -
  • - LND via the REST proxy: -
      -
    • - type=lnd-rest;server=https://mylnd:8080/;macaroon=abef263adfe... -
    • -
    • - type=lnd-rest;server=https://mylnd:8080/;macaroon=abef263adfe...;certthumbprint=abef263adfe... -
    • -
    - -
    -
    -

    For the macaroon options you need to provide the admin.macaroon.

    -

    The path to the LND data directory may vary, the following example assume /root/.lnd.

    -

    The macaroon parameter expects the HEX value, it can be obtained using this command:

    -
    xxd -plain /root/.lnd/data/chain/bitcoin/mainnet/admin.macaroon | tr -d '\n'
    -

    You can omit certthumbprint if the certificate is trusted by your machine.

    -

    The certthumbprint can be obtained using this command:

    -
    openssl x509 -noout -fingerprint -sha256 -in /root/.lnd/tls.cert | sed -e 's/.*=//;s/://g'
    -

    If your LND REST server is using HTTP or HTTPS with an untrusted certificate, you can set allowinsecure=true as a fallback.

    -
    -
    -
  • -
-
-
-
- -
- - - - - - Open Public Node Info Page - -
-
- -@section Scripts { - -} diff --git a/BTCPayServer/Views/Stores/SetupLightningNode.cshtml b/BTCPayServer/Views/Stores/SetupLightningNode.cshtml new file mode 100644 index 000000000..3ac7314cd --- /dev/null +++ b/BTCPayServer/Views/Stores/SetupLightningNode.cshtml @@ -0,0 +1,201 @@ +@model LightningNodeViewModel +@{ + Layout = "_LayoutWalletSetup.cshtml"; + ViewData.SetActivePageAndTitle(StoreNavPages.Index, "Connect to a Lightning node", Context.GetStoreData().StoreName); +} + +@section Navbar { + + + +} + +
+

@ViewData["Title"]

+
+ +

+ 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. + More information +

+
+
+ + + +
+ + + + +
+ @if (Model.CanUseInternalNode) + { +

Using the BTCPay Server internal node for this store requires no further configuration. Click the save button below to start accepting Bitcoin through the Lightning Network.

+ } + else + { +

Your instance administrator has disabled the use of the Internal node for non-admin users.

+ } +
+
+ +
+ + +
+ +

BTCPay Server currently supports:

+
    +
  • + +
    +
      +
    • + type=clightning;server=unix://root/.lightning/lightning-rpc +
    • +
    • + type=clightning;server=tcp://1.1.1.1:27743/ +
    • +
    +
    +
  • +
  • + +
    +
      +
    • + type=charge;server=https://charge:8080/;api-token=myapitoken... +
    • +
    +
    +
  • +
  • + +
    +
      +
    • + type=eclair;server=https://eclair:8080/;password=eclairpassword... +
    • +
    +
    +
  • +
  • + +
    +
      +
    • + type=lnd-rest;server=https://mylnd:8080/;macaroon=abef263adfe... +
    • +
    • + type=lnd-rest;server=https://mylnd:8080/;macaroon=abef263adfe...;certthumbprint=abef263adfe... +
    • +
    +

    + For the macaroon options you need to provide the admin.macaroon.
    + The path to the LND data directory may vary, the following examples assume /root/.lnd. +

    +

    The macaroon parameter expects the HEX value, it can be obtained using this command:

    +
    xxd -plain /root/.lnd/data/chain/bitcoin/mainnet/admin.macaroon | tr -d '\n'
    +

    + You can omit certthumbprint if the certificate is trusted by your machine.
    + The certthumbprint can be obtained using this command: +

    +
    openssl x509 -noout -fingerprint -sha256 -in /root/.lnd/tls.cert | sed -e 's/.*=//;s/://g'
    +

    If your LND REST server is using HTTP or HTTPS with an untrusted certificate, you can set allowinsecure=true as a fallback.

    +
    +
  • +
+
+
+ +
+
+ +@section Scripts { + +} diff --git a/BTCPayServer/Views/Stores/UpdateStore.cshtml b/BTCPayServer/Views/Stores/UpdateStore.cshtml index b9a90ec7f..643cdae58 100644 --- a/BTCPayServer/Views/Stores/UpdateStore.cshtml +++ b/BTCPayServer/Views/Stores/UpdateStore.cshtml @@ -112,15 +112,15 @@ @if (isSetUp) { @scheme.Address + + Public Node Info + } - - Public Node Info -
| } - + @(isSetUp ? "Modify" : "Setup") diff --git a/BTCPayServer/wwwroot/img/icon-sprite.svg b/BTCPayServer/wwwroot/img/icon-sprite.svg index 84f7c1e03..df92cf7a6 100644 --- a/BTCPayServer/wwwroot/img/icon-sprite.svg +++ b/BTCPayServer/wwwroot/img/icon-sprite.svg @@ -12,4 +12,5 @@ + diff --git a/BTCPayServer/wwwroot/main/themes/default-dark.css b/BTCPayServer/wwwroot/main/themes/default-dark.css index 5f1900686..557873ff6 100644 --- a/BTCPayServer/wwwroot/main/themes/default-dark.css +++ b/BTCPayServer/wwwroot/main/themes/default-dark.css @@ -3,30 +3,9 @@ /* Dark theme overrides */ :root { --btcpay-color-neutral-950: #222222; + --btcpay-color-primary-text: var(--btcpay-color-white); --btcpay-color-primary-backdrop: #389725; - - --btcpay-bg-dark: var(--btcpay-color-neutral-950); - --btcpay-header-bg: var(--btcpay-bg-dark); - --btcpay-header-color-link-active: var(--btcpay-color-primary); - - --btcpay-body-bg: var(--btcpay-color-neutral-900); - --btcpay-body-color: var(--btcpay-color-white); - - --btcpay-wizard-bg: var(--btcpay-body-bg); - --btcpay-wizard-color: var(--btcpay-body-color); - - --btcpay-footer-bg: var(--btcpay-bg-dark); - --btcpay-footer-color: var(--btcpay-color-neutral-600); - - --btcpay-nav-color-link: var(--btcpay-color-neutral-500); - --btcpay-nav-color-link-accent: var(--btcpay-color-neutral-300); - --btcpay-nav-color-link-active: var(--btcpay-color-white); - - --btcpay-bg-tile: var(--btcpay-bg-dark); - - --btcpay-border-color-light: var(--btcpay-color-neutral-600); - --btcpay-border-color-medium: var(--btcpay-color-neutral-700); - + --btcpay-color-secondary-accent: var(--btcpay-color-neutral-300); --btcpay-color-light: var(--btcpay-color-neutral-800); --btcpay-color-light-backdrop: var(--btcpay-color-neutral-800); --btcpay-color-light-accent: var(--btcpay-color-black); @@ -35,6 +14,39 @@ --btcpay-color-dark-backdrop: var(--btcpay-color-neutral-200); --btcpay-color-dark-accent: var(--btcpay-color-neutral-400); --btcpay-color-dark-text: var(--btcpay-color-neutral-800); + + --btcpay-bg-dark: var(--btcpay-color-neutral-950); + --btcpay-bg-tile: var(--btcpay-bg-dark); + + --btcpay-body-bg: var(--btcpay-color-neutral-900); + --btcpay-body-color: var(--btcpay-color-white); + --btcpay-body-color-link: var(--btcpay-color-primary); + --btcpay-body-color-link-accent: var(--btcpay-color-primary); + + --btcpay-header-bg: var(--btcpay-bg-dark); + --btcpay-header-color: var(--btcpay-body-color); + --btcpay-header-color-link: var(--btcpay-header-color); + --btcpay-header-color-link-accent: var(--btcpay-header-color); + --btcpay-header-color-link-active: var(--btcpay-color-primary); + + --btcpay-wizard-bg: var(--btcpay-body-bg); + --btcpay-wizard-color: var(--btcpay-body-color); + + --btcpay-nav-color-link: var(--btcpay-color-neutral-500); + --btcpay-nav-color-link-accent: var(--btcpay-color-neutral-300); + --btcpay-nav-color-link-active: var(--btcpay-color-white); + + --btcpay-footer-bg: var(--btcpay-bg-dark); + --btcpay-footer-color: var(--btcpay-color-neutral-600); + --btcpay-footer-color-link: var(--btcpay-color-neutral-600); + --btcpay-footer-color-link-accent: var(--btcpay-color-neutral-300); + + --btcpay-code-bg: var(--btcpay-bg-dark); + + --btcpay-bg-color-light: var(--btcpay-color-neutral-800); + --btcpay-bg-color-medium: var(--btcpay-color-neutral-700); + --btcpay-border-color-light: var(--btcpay-color-neutral-600); + --btcpay-border-color-medium: var(--btcpay-color-neutral-700); } .social-logo { diff --git a/BTCPayServer/wwwroot/main/themes/default.css b/BTCPayServer/wwwroot/main/themes/default.css index 5a1f8063b..5c24ea1ba 100644 --- a/BTCPayServer/wwwroot/main/themes/default.css +++ b/BTCPayServer/wwwroot/main/themes/default.css @@ -53,13 +53,10 @@ --btcpay-color-dark-text: var(--btcpay-color-neutral-200); /* Color definitions for specific sections - try to reuse colors defined above */ - --btcpay-bg-dark: var(--btcpay-brand-dark); --btcpay-bg-tile: var(--btcpay-color-white); + --btcpay-bg-dark: var(--btcpay-brand-dark); --btcpay-bg-cta: var(--btcpay-brand-dark); - --btcpay-border-color-light: var(--btcpay-color-neutral-200); - --btcpay-border-color-medium: var(--btcpay-color-neutral-300); - --btcpay-body-bg: var(--btcpay-color-neutral-100); --btcpay-body-color: var(--btcpay-color-neutral-900); --btcpay-body-color-link: var(--btcpay-color-primary); @@ -67,15 +64,31 @@ --btcpay-header-bg: var(--btcpay-color-white); --btcpay-header-color: var(--btcpay-body-color); - --btcpay-header-color-link: var(--btcpay-body-color); - --btcpay-header-color-link-accent: var(--btcpay-color-primary); + --btcpay-header-color-link: var(--btcpay-header-color); + --btcpay-header-color-link-accent: var(--btcpay-header-color); --btcpay-header-color-link-active: var(--btcpay-color-primary-accent); + --btcpay-nav-color-link: var(--btcpay-color-neutral-600); + --btcpay-nav-color-link-accent: var(--btcpay-color-neutral-700); + --btcpay-nav-color-link-active: var(--btcpay-color-neutral-900); + --btcpay-wizard-bg: var(--btcpay-color-white); --btcpay-wizard-color: var(--btcpay-body-color); --btcpay-footer-bg: var(--btcpay-brand-dark); --btcpay-footer-color: var(--btcpay-color-neutral-400); + --btcpay-footer-color-link: var(--btcpay-color-neutral-400); + --btcpay-footer-color-link-accent: var(--btcpay-color-neutral-100); + + --btcpay-code-color: var(--btcpay-body-color); + --btcpay-code-bg: var(--btcpay-color-neutral-200); + --btcpay-pre-color: var(--btcpay-color-white); + --btcpay-pre-bg: var(--btcpay-color-neutral-950); + + --btcpay-bg-color-light: var(--btcpay-color-white); + --btcpay-bg-color-medium: var(--btcpay-color-neutral-300); + --btcpay-border-color-light: var(--btcpay-color-neutral-200); + --btcpay-border-color-medium: var(--btcpay-color-neutral-300); --btcpay-font-size-base: 14px; --btcpay-font-family-head: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;