From 7b508603830337d4b90b75339517ab265056f310 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Wed, 20 Jul 2022 17:59:21 +0200 Subject: [PATCH] lndhub-go: integrate LndHub.go --- README.md | 1 + examples/configuration.nix | 5 ++ modules/lndhub-go.nix | 131 +++++++++++++++++++++++++++++++++ modules/modules.nix | 1 + modules/netns-isolation.nix | 6 ++ modules/nodeinfo.nix | 1 + modules/presets/enable-tor.nix | 2 + pkgs/pinned.nix | 1 + test/tests.nix | 4 + test/tests.py | 6 ++ 10 files changed, 158 insertions(+) create mode 100644 modules/lndhub-go.nix diff --git a/README.md b/README.md index 75147e30b..0f2e64e4a 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ NixOS modules ([src](modules/modules.nix)) * [Lightning Loop](https://github.com/lightninglabs/loop) * [Lightning Pool](https://github.com/lightninglabs/pool) * [charge-lnd](https://github.com/accumulator/charge-lnd): policy-based channel fee manager + * [LndHub.go](https://github.com/getAlby/lndhub.go): accounting wrapper for lnd * [lndconnect](https://github.com/LN-Zap/lndconnect): connect your wallet to lnd or clightning via a REST onion service * [Ride The Lightning](https://github.com/Ride-The-Lightning/RTL): web interface for `lnd` and `clightning` * [spark-wallet](https://github.com/shesek/spark-wallet) diff --git a/examples/configuration.nix b/examples/configuration.nix index 9ec5837f8..0137bb787 100644 --- a/examples/configuration.nix +++ b/examples/configuration.nix @@ -136,6 +136,11 @@ # # services.fulcrum.enable = true; + ### LNDHUB.GO + # Set this to enable LndHub.go, an accounting wrapper for the Lightning Network. + # + # services.lndhub-go.enable = true; + ### BTCPayServer # Set this to enable BTCPayServer, a self-hosted, open-source # cryptocurrency payment processor. diff --git a/modules/lndhub-go.nix b/modules/lndhub-go.nix new file mode 100644 index 000000000..d1d32e2f4 --- /dev/null +++ b/modules/lndhub-go.nix @@ -0,0 +1,131 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + options.services = { + lndhub-go = { + enable = mkEnableOption "LndHub.go, an accounting wrapper for lnd"; + address = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "Address to listen on."; + }; + port = mkOption { + type = types.port; + default = 8082; + description = "Port to listen on."; + }; + settings = mkOption { + type = with types; attrsOf (oneOf [ str int bool ]); + example = { + ALLOW_ACCOUNT_CREATION = false; + FEE_RESERVE = true; + MAX_SEND_AMOUNT = 1000000; + }; + description = '' + LndHub.go settings. + See here for possible options: + https://github.com/getAlby/lndhub.go#available-configuration + ''; + }; + package = mkOption { + type = types.package; + default = config.nix-bitcoin.pkgs.lndhub-go; + defaultText = "config.nix-bitcoin.pkgs.lndhub-go"; + description = "The package providing LndHub.go binaries."; + }; + user = mkOption { + type = types.str; + default = "lndhub-go"; + description = "The user as which to run LndHub.go."; + }; + group = mkOption { + type = types.str; + default = cfg.user; + description = "The group as which to run LndHub.go."; + }; + tor.enforce = nbLib.tor.enforce; + }; + }; + + cfg = config.services.lndhub-go; + nbLib = config.nix-bitcoin.lib; + + inherit (config.services) + lnd + postgresql; + + configFile = builtins.toFile "lndhub-go-conf" (lib.generators.toKeyValue {} cfg.settings); + + dbName = "lndhub-go"; +in { + inherit options; + + config = mkIf cfg.enable { + services.lnd = { + enable = true; + macaroons.lndhub-go = { + inherit (cfg) user; + permissions = ''{"entity":"info","action":"read"},{"entity":"invoices","action":"read"},{"entity":"invoices","action":"write"},{"entity":"offchain","action":"read"},{"entity":"offchain","action":"write"}''; + }; + }; + services.postgresql = { + enable = true; + ensureDatabases = [ dbName ]; + ensureUsers = [ + { + name = cfg.user; + ensurePermissions."DATABASE \"${dbName}\"" = "ALL PRIVILEGES"; + } + ]; + }; + + services.lndhub-go.settings = { + HOST = cfg.address; + PORT = cfg.port; + DATABASE_URI = "unix://${cfg.user}@${dbName}/run/postgresql/.s.PGSQL.${toString postgresql.port}?sslmode=disable"; + LND_ADDRESS = "${nbLib.addressWithPort lnd.address lnd.rpcPort}"; + LND_MACAROON_FILE = "/run/lnd/lndhub-go.macaroon"; + LND_CERT_FILE = lnd.certPath; + BRANDING_TITLE = "LndHub.go - Nix-Bitcoin"; + BRANDING_DESC = "Accounting wrapper for the Lightning Network"; + BRANDING_URL = "https://nixbitcoin.org"; + BRANDING_LOGO = "https://nixbitcoin.org/files/nix-bitcoin-logo-text.png"; + BRANDING_FAVICON = "https://nixbitcoin.org/files/nix-bitcoin-logo.png"; + BRANDING_FOOTER = "about=https://nixbitcoin.org;github=https://github.com/fort-nix/nix-bitcoin"; + }; + + systemd.services.lndhub-go = rec { + wantedBy = [ "multi-user.target" ]; + requires = [ "lnd.service" "postgresql.service" ]; + after = requires; + preStart = '' + { + cat ${configFile} + echo "JWT_SECRET=$(cat '${config.nix-bitcoin.secretsDir}/lndhub.go-jwt-secret')" + } > .env + ''; + serviceConfig = nbLib.defaultHardening // { + StateDirectory = "lndhub-go"; + StateDirectoryMode = "770"; + # lndhub-go reads file `.env` from the working directory + WorkingDirectory = "/var/lib/lndhub-go"; + ExecStart = "${config.nix-bitcoin.pkgs.lndhub-go}/bin/lndhub.go"; + User = cfg.user; + Restart = "on-failure"; + RestartSec = "10s"; + } // nbLib.allowedIPAddresses cfg.tor.enforce; + }; + + users.users.${cfg.user} = { + isSystemUser = true; + group = cfg.group; + }; + users.groups.${cfg.group} = {}; + + nix-bitcoin.secrets."lndhub.go-jwt-secret".user = cfg.user; + nix-bitcoin.generateSecretsCmds.lndhub-go = '' + makePasswordSecret lndhub.go-jwt-secret + ''; + }; +} diff --git a/modules/modules.nix b/modules/modules.nix index fd3907769..297c3b634 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -16,6 +16,7 @@ ./clightning-replication.nix ./spark-wallet.nix ./lnd.nix + ./lndhub-go.nix ./lightning-loop.nix ./lightning-pool.nix ./charge-lnd.nix diff --git a/modules/netns-isolation.nix b/modules/netns-isolation.nix index 940a8c682..226bbb783 100644 --- a/modules/netns-isolation.nix +++ b/modules/netns-isolation.nix @@ -297,6 +297,10 @@ in { id = 31; connections = [ "bitcoind" ]; }; + lndhub-go = { + id = 32; + connections = [ "lnd" ]; + }; }; services.bitcoind = { @@ -355,6 +359,8 @@ in { services.rtl.address = netns.rtl.address; services.clightning-rest.address = netns.clightning-rest.address; + + services.lndhub-go.address = netns.lndhub-go.address; } ]); } diff --git a/modules/nodeinfo.nix b/modules/nodeinfo.nix index 5c0cd1419..c9affcebe 100644 --- a/modules/nodeinfo.nix +++ b/modules/nodeinfo.nix @@ -138,6 +138,7 @@ in { liquidd = mkInfo ""; joinmarket-ob-watcher = mkInfo ""; rtl = mkInfo ""; + lndhub-go = mkInfo ""; # Only add sshd when it has an onion service sshd = name: cfg: mkIfOnionPort "sshd" (onionPort: '' add_service("sshd", """set_onion_address(info, "sshd", ${onionPort})""") diff --git a/modules/presets/enable-tor.nix b/modules/presets/enable-tor.nix index 709c01e6b..108dc937b 100644 --- a/modules/presets/enable-tor.nix +++ b/modules/presets/enable-tor.nix @@ -40,6 +40,7 @@ in { joinmarket = defaultEnforceTor; joinmarket-ob-watcher = defaultEnforceTor; clightning-rest = defaultEnforceTor; + lndhub-go = defaultEnforceTor; }; # Add onion services for incoming connections @@ -51,5 +52,6 @@ in { spark-wallet.enable = defaultTrue; joinmarket-ob-watcher.enable = defaultTrue; rtl.enable = defaultTrue; + lndhub-go.enable = defaultTrue; }; } diff --git a/pkgs/pinned.nix b/pkgs/pinned.nix index 1d61bd0b7..d0dd3443d 100644 --- a/pkgs/pinned.nix +++ b/pkgs/pinned.nix @@ -18,6 +18,7 @@ pkgs: pkgsUnstable: hwi lightning-loop lnd + lndhub-go nbxplorer; inherit pkgs pkgsUnstable; diff --git a/test/tests.nix b/test/tests.nix index b0f9c697e..eeffd99a9 100644 --- a/test/tests.nix +++ b/test/tests.nix @@ -109,6 +109,8 @@ let tests.liquidd = cfg.liquidd.enable; services.liquidd.extraConfig = mkIf config.test.noConnections "connect=0"; + tests.lndhub-go = cfg.lndhub-go.enable; + tests.btcpayserver = cfg.btcpayserver.enable; services.btcpayserver = { lightningBackend = mkDefault "lnd"; @@ -191,6 +193,7 @@ let services.lightning-loop.enable = true; services.lightning-pool.enable = true; services.charge-lnd.enable = true; + services.lndhub-go.enable = true; services.electrs.enable = true; services.fulcrum.enable = true; services.liquidd.enable = true; @@ -238,6 +241,7 @@ let services.lightning-loop.enable = true; services.lightning-pool.enable = true; services.charge-lnd.enable = true; + services.lndhub-go.enable = true; services.electrs.enable = true; services.fulcrum.enable = true; services.btcpayserver.enable = true; diff --git a/test/tests.py b/test/tests.py index 1fb98e24d..ebde7d96d 100644 --- a/test/tests.py +++ b/test/tests.py @@ -123,6 +123,12 @@ def _(): def _(): succeed("systemctl stop electrs") +@test("lndhub-go") +def _(): + assert_running("lndhub-go") + wait_for_open_port(ip("lndhub-go"), 8082) + machine.wait_until_succeeds(log_has_string("lndhub-go", "Connected to LND")) + @test("liquidd") def _(): assert_running("liquidd")