diff --git a/modules/bitcoin/btcpayserver.nix b/modules/bitcoin/btcpayserver.nix index 64ae6d9..1e157dc 100644 --- a/modules/bitcoin/btcpayserver.nix +++ b/modules/bitcoin/btcpayserver.nix @@ -105,7 +105,8 @@ let cfg = config.services; nbLib = config.nix-bitcoin.lib; - inherit (config.services) bitcoind liquidd; + inherit (config.services) bitcoind; + # liquidd removed - Sovran uses lbtc=false, not needed in { inherit options; @@ -132,10 +133,6 @@ in { }; }; # vendored fix: liquidd may not exist in nixpkgs with this name - services.liquidd = mkIf (cfg.btcpayserver.lbtc && config.services ? liquidd) { - enable = true; - listenWhitelisted = true; - }; services.postgresql = { enable = true; ensureDatabases = [ @@ -166,28 +163,17 @@ in { btcrpcurl=http://${nbLib.addressWithPort bitcoind.rpc.address cfg.bitcoind.rpc.port} btcnodeendpoint=${nbLib.addressWithPort bitcoind.address bitcoind.whitelistedPort} bind=${cfg.nbxplorer.address} - port=${toString cfg.nbxplorer.port} - ${optionalString cfg.btcpayserver.lbtc '' - chains=btc,lbtc - lbtcrpcuser=${liquidd.rpcuser} - lbtcrpcurl=http://${nbLib.addressWithPort liquidd.rpc.address liquidd.rpc.port} - lbtcnodeendpoint=${nbLib.addressWithPort liquidd.address liquidd.whitelistedPort} - ''} - postgres=User ID=${cfg.nbxplorer.user};Host=/run/postgresql;Database=nbxplorer + port=${toString cfg.nbxplorer.port} postgres=User ID=${cfg.nbxplorer.user};Host=/run/postgresql;Database=nbxplorer ''; in rec { wantedBy = [ "multi-user.target" ]; requires = [ "postgresql.target" ]; - wants = [ "bitcoind.service" ] ++ optional cfg.btcpayserver.lbtc "liquidd.service"; + wants = [ "bitcoind.service" ]; after = requires ++ wants ++ [ "nix-bitcoin-secrets.target" ]; preStart = '' install -m 600 ${configFile} '${cfg.nbxplorer.dataDir}/settings.config' { - echo "btcrpcpassword=$(cat ${config.nix-bitcoin.secretsDir}/bitcoin-rpcpassword-btcpayserver)" - ${optionalString cfg.btcpayserver.lbtc '' - echo "lbtcrpcpassword=$(cat ${config.nix-bitcoin.secretsDir}/liquid-rpcpassword)" - ''} - } >> '${cfg.nbxplorer.dataDir}/settings.config' + echo "btcrpcpassword=$(cat ${config.nix-bitcoin.secretsDir}/bitcoin-rpcpassword-btcpayserver)" } >> '${cfg.nbxplorer.dataDir}/settings.config' ''; serviceConfig = nbLib.defaultHardening // { ExecStart = '' @@ -258,7 +244,6 @@ in { isSystemUser = true; group = cfg.nbxplorer.group; extraGroups = [ "bitcoinrpc-public" ] - ++ optional cfg.btcpayserver.lbtc liquidd.group; home = cfg.nbxplorer.dataDir; }; users.groups.${cfg.nbxplorer.group} = {}; diff --git a/modules/bitcoin/default.nix b/modules/bitcoin/default.nix index 7da187e..be2035d 100644 --- a/modules/bitcoin/default.nix +++ b/modules/bitcoin/default.nix @@ -10,7 +10,6 @@ ./rtl.nix ./btcpayserver.nix ./mempool.nix - ./stubs.nix ]; disabledModules = [ "services/networking/bitcoind.nix" ]; diff --git a/modules/bitcoin/lndconnect.nix b/modules/bitcoin/lndconnect.nix index 234fd98..a65254a 100644 --- a/modules/bitcoin/lndconnect.nix +++ b/modules/bitcoin/lndconnect.nix @@ -2,281 +2,62 @@ with lib; let - options = { - services.lnd.lndconnect = { - enable = mkOption { - type = types.bool; - default = false; - description = '' - Add a `lndconnect` binary to the system environment which prints - connection info for lnd clients. - See: https://github.com/LN-Zap/lndconnect + cfg = config.services.lnd; + operatorName = config.nix-bitcoin.operator.name; + nbLib = config.nix-bitcoin.lib; - Usage: - ```bash - # Print QR code - lndconnect - - # Print URL - lndconnect --url - ``` - ''; - }; - onion = mkOption { - type = types.bool; - default = false; - description = '' - Create an onion service for the lnd REST server, - which is used by lndconnect. - ''; - }; + mkLndconnect = { name, isClightning ? false, enableOnion, onionService, port, certPath, authSecretPath }: + let + lnd = config.services.lnd; + getOnionAddress = "cat ${config.nix-bitcoin.secretsDir}/onion-address-${onionService} 2>/dev/null || echo ${onionService}.onion"; + in pkgs.writeScriptBin name '' + #!${pkgs.bash}/bin/bash + set -e + certPath="${certPath}" + authSecretPath="${authSecretPath}" + if [ "${toString enableOnion}" = "1" ]; then + host=$(cat /var/lib/tor/onion/${onionService}/hostname 2>/dev/null || echo "${onionService}.onion") + port="${toString port}" + else + host="${nbLib.address lnd.restAddress}" + port="${toString lnd.restPort}" + fi + # lndconnect is provided by pkgs.lndconnect + ${getExe pkgs.lndconnect} --host="$host" --port="$port" --cert="$certPath" --macaroon="$authSecretPath" "$@" + ''; +in { + options.services.lnd.lndconnect = { + enable = mkOption { + type = types.bool; + default = false; + description = "Enable lndconnect for LND"; }; - - services.clightning.plugins.clnrest.lnconnect = { - enable = mkOption { - type = types.bool; - default = false; - description = '' - Add a `lnconnect-clnrest` binary to the system environment which prints - connection info for clightning clients. - See: https://github.com/LN-Zap/lndconnect - - Usage: - ```bash - # Print QR code - lnconnect-clnrest - - # Print URL - lnconnect-clnrest --url - ``` - ''; - }; - onion = mkOption { - type = types.bool; - default = false; - description = '' - Create an onion service for the clnrest server, - which is used by lnconnect. - ''; - }; - }; - - services.clightning-rest.lndconnect = { - enable = mkOption { - type = types.bool; - default = false; - description = '' - Add a `lndconnect-clightning` binary to the system environment which prints - connection info for clightning clients. - See: https://github.com/LN-Zap/lndconnect - - Usage: - ```bash - # Print QR code - lndconnect-clightning - - # Print URL - lndconnect-clightning --url - ``` - ''; - }; - onion = mkOption { - type = types.bool; - default = false; - description = '' - Create an onion service for the clightning REST server, - which is used by lndconnect. - ''; - }; - }; - - nix-bitcoin.mkLndconnect = mkOption { - readOnly = true; - default = mkLndconnect; - description = '' - A function to create a lndconnect binary. - See the source for further details. - ''; + onion = mkOption { + type = types.bool; + default = false; + description = "Expose lndconnect via Tor onion service"; }; }; - nbLib = config.nix-bitcoin.lib; - runAsUser = config.nix-bitcoin.runAsUserCmd; - - inherit (config.services) - lnd - clightning - clightning-rest; - - inherit (clightning.plugins) clnrest; - - mkLndconnect = { - name, - shebang ? "#!${pkgs.stdenv.shell} -e", - isClightning ? false, - isClnrest ? false, - port, - authSecretPath, - enableOnion, - onionService ? null, - certPath ? null - }: - # TODO-EXTERNAL: - # lndconnect requires a --configfile argument, although it's unused - # https://github.com/LN-Zap/lndconnect/issues/25 - lib.hiPrio (pkgs.writeScriptBin name '' - ${shebang} - url=$( - ${getExe pkgs.lndconnect} --url \ - ${optionalString enableOnion "--host=$(cat ${config.nix-bitcoin.onionAddresses.dataDir}/${onionService})"} \ - --port=${toString port} \ - ${if enableOnion || certPath == null then "--nocert" else "--tlscertpath='${certPath}'"} \ - --adminmacaroonpath='${authSecretPath}' \ - --configfile=/dev/null "$@" - ) - - ${optionalString isClightning - # - Change URL procotcol to c-lightning-rest - # - Encode macaroon as hex (in uppercase) instead of base 64. - # Because `macaroon` is always the last URL fragment, the - # sed replacement below works correctly. - '' - macaroonHex=$(${getExe pkgs.xxd} -p -u -c 99999 '${authSecretPath}') - url=$( - echo "$url" | ${getExe pkgs.gnused} " - s|^lndconnect|c-lightning-rest| - s|macaroon=.*|macaroon=$macaroonHex| - "; - ) - '' - } - - ${optionalString isClnrest - # Change URL procotcol to clnrest - '' - url=$( - echo "$url" | ${getExe pkgs.gnused} " - s|^lndconnect|clnrest| - s|macaroon=.*|rune=$(cat '${authSecretPath}')| - "; - ) - '' - } - - # If --url is in args - if [[ " $* " =~ " --url " ]]; then - echo "$url" - else - # This UTF-8 encoding yields a smaller, more convenient output format - # compared to the native lndconnect output - echo -n "$url" | ${getExe pkgs.qrencode} -t UTF8 -o - - fi - ''); - - operatorName = config.nix-bitcoin.operator.name; -in { - inherit options; - - config = mkMerge [ - (mkIf (lnd.enable && lnd.lndconnect.enable) - (mkMerge [ - { - environment.systemPackages = [( - mkLndconnect { - name = "lndconnect"; - # Run as lnd user because the macaroon and cert are not group-readable - shebang = "#!/usr/bin/env -S ${runAsUser} ${lnd.user} ${pkgs.bash}/bin/bash"; - enableOnion = lnd.lndconnect.onion; - onionService = "${lnd.user}/lnd-rest"; - port = lnd.restPort; - certPath = lnd.certPath; - authSecretPath = "${lnd.networkDir}/admin.macaroon"; - } - )]; - - services.lnd.restAddress = mkIf (!lnd.lndconnect.onion) "0.0.0.0"; - } - - (mkIf lnd.lndconnect.onion { - services.tor = { - enable = true; - relay.onionServices.lnd-rest = nbLib.mkOnionService { - target.addr = nbLib.address lnd.restAddress; - target.port = lnd.restPort; - port = lnd.restPort; - }; - }; - nix-bitcoin.onionAddresses.access = { - ${lnd.user} = [ "lnd-rest" ]; - ${operatorName} = [ "lnd-rest" ]; - }; + config = mkIf cfg.enable (mkMerge [ + (mkIf cfg.lndconnect.enable { + environment.systemPackages = [ + (mkLndconnect { + name = "lndconnect"; + enableOnion = cfg.lndconnect.onion; + onionService = "${operatorName}/lnd"; + port = cfg.restPort; + certPath = cfg.certPath; + authSecretPath = "${cfg.networkDir}/admin.macaroon"; }) - ])) - - (mkIf (clnrest.enable && clnrest.lnconnect.enable) - (mkMerge [ - { - environment.systemPackages = [( - mkLndconnect { - name = "lnconnect-clnrest"; - isClnrest = true; - enableOnion = clnrest.lnconnect.onion; - onionService = "${operatorName}/clnrest"; - port = clnrest.port; - certPath = "${clightning.networkDir}/client.pem"; - authSecretPath = "${clightning.networkDir}/admin-rune"; - } - )]; - - services.clightning.plugins.clnrest.address = mkIf (!clnrest.lnconnect.onion) "0.0.0.0"; - } - - (mkIf clnrest.lnconnect.onion { - services.tor = { - enable = true; - relay.onionServices.clnrest = nbLib.mkOnionService { - target.addr = nbLib.address clnrest.address; - target.port = clnrest.port; - port = clnrest.port; - }; - }; - # This also allows nodeinfo to show the clnrest onion address - nix-bitcoin.onionAddresses.access.${operatorName} = [ "clnrest" ]; - }) - ]) - ) - - (mkIf (clightning-rest.enable && clightning-rest.lndconnect.enable) - (mkMerge [ - { - environment.systemPackages = [( - mkLndconnect { - name = "lndconnect-clightning"; - isClightning = true; - enableOnion = clightning-rest.lndconnect.onion; - onionService = "${operatorName}/clightning-rest"; - port = clightning-rest.port; - certPath = "${clightning-rest.dataDir}/certs/certificate.pem"; - authSecretPath = "${clightning-rest.dataDir}/certs/access.macaroon"; - } - )]; - - # clightning-rest always binds to all interfaces - } - - (mkIf clightning-rest.lndconnect.onion { - services.tor = { - enable = true; - relay.onionServices.clightning-rest = nbLib.mkOnionService { - target.addr = nbLib.address clightning-rest.address; - target.port = clightning-rest.port; - port = clightning-rest.port; - }; - }; - # This also allows nodeinfo to show the clightning-rest onion address - nix-bitcoin.onionAddresses.access.${operatorName} = [ "clightning-rest" ]; - }) - ]) - ) - ]; + ]; + }) + (mkIf (cfg.lndconnect.enable && cfg.lndconnect.onion) { + services.tor.relay.onionServices.lnd = nbLib.mkOnionService { + map = [{ port = cfg.restPort; target = { addr = nbLib.address cfg.restAddress; port = cfg.restPort; }; }]; + version = 3; + }; + nix-bitcoin.onionAddresses.access.${operatorName} = [ "lnd" ]; + }) + ]); } diff --git a/modules/bitcoin/mempool.nix b/modules/bitcoin/mempool.nix index 503dfd3..3d374d2 100644 --- a/modules/bitcoin/mempool.nix +++ b/modules/bitcoin/mempool.nix @@ -170,8 +170,7 @@ let inherit (config.services) bitcoind - electrs - fulcrum; + electrs; torSocket = config.services.tor.client.socksListenAddress; @@ -241,8 +240,7 @@ in { config = mkIf cfg.enable { services.bitcoind.txindex = true; services.electrs.enable = mkIf (cfg.electrumServer == "electrs" ) true; - # vendored fix: fulcrum may not exist - services.fulcrum.enable = mkIf (cfg.electrumServer == "fulcrum" && config.services ? fulcrum) true; + # vendored fix: fulcrum may not exist # fulcrum removed - Sovran uses electrs only services.mysql = { enable = true; package = pkgs.mariadb; diff --git a/modules/bitcoin/rtl.nix b/modules/bitcoin/rtl.nix index a2dd71b..48c1ade 100644 --- a/modules/bitcoin/rtl.nix +++ b/modules/bitcoin/rtl.nix @@ -116,7 +116,7 @@ let lnNode = "Node"; lnImplementation = if isLnd then "LND" else "CLT"; Authentication = { - ${optionalAttr (isLnd && lndLoopEnabled) "swapMacaroonPath"} = "${lightning-loop.dataDir}/${bitcoind.network}"; + ${optionalAttr (isLnd && lndLoopEnabled) "swapMacaroonPath"} = "${(lightning-loop.dataDir or "/var/lib/lightning-loop")}/${bitcoind.network}"; ${optionalAttr (isLnd) "macaroonPath"} = "${cfg.dataDir}/macaroons"; ${optionalAttr (!isLnd) "runePath"} = runePath; }; @@ -129,7 +129,7 @@ let fiatConversion = cfg.extraCurrency != null; ${optionalAttr (cfg.extraCurrency != null) "currencyUnit"} = cfg.extraCurrency; ${optionalAttr (isLnd && lndLoopEnabled) "swapServerUrl"} = - "https://${nbLib.addressWithPort lightning-loop.restAddress lightning-loop.restPort}"; + "https://${nbLib.addressWithPort (lightning-loop.restAddress or "127.0.0.1") (lightning-loop.restPort or 8081)}"; lnServerUrl = "https://${ if isLnd then nbLib.addressWithPort lnd.restAddress lnd.restPort @@ -175,8 +175,7 @@ in { } ]; - services.lnd.enable = mkIf cfg.nodes.lnd.enable true; - services.lightning-loop.enable = mkIf lndLoopEnabled true; + services.lnd.enable = mkIf cfg.nodes.lnd.enable true; # lightning-loop removed - not used # vendored fix: clightning may not exist in this nixpkgs # clightning removed - Sovran uses lnd only diff --git a/modules/bitcoin/stubs.nix b/modules/bitcoin/stubs.nix deleted file mode 100644 index b715617..0000000 --- a/modules/bitcoin/stubs.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ lib, ... }: -with lib; -{ - # Stubs for services referenced but not in nixpkgs - clightning not stubbed (exists in f13ff45, handled via guards) - options.services.liquidd.enable = mkOption { type = types.bool; default = false; }; - options.services.liquidd.dataDir = mkOption { type = types.path; default = "/var/lib/liquidd"; }; - options.services.liquidd.address = mkOption { type = types.str; default = "127.0.0.1"; }; - options.services.liquidd.port = mkOption { type = types.port; default = 7041; }; - options.services.liquidd.rpc.address = mkOption { type = types.str; default = "127.0.0.1"; }; - options.services.liquidd.rpc.port = mkOption { type = types.port; default = 7040; }; - options.services.liquidd.rpcuser = mkOption { type = types.str; default = "liquiddrpc"; }; - options.services.liquidd.whitelistedPort = mkOption { type = types.port; default = 7042; }; - options.services.liquidd.group = mkOption { type = types.str; default = "liquidd"; }; - - options.services.fulcrum.enable = mkOption { type = types.bool; default = false; }; - options.services.lightning-loop.enable = mkOption { type = types.bool; default = false; }; - options.services.lightning-pool.enable = mkOption { type = types.bool; default = false; }; - options.services.joinmarket.enable = mkOption { type = types.bool; default = false; }; - options.services.joinmarket-ob-watcher.enable = mkOption { type = types.bool; default = false; }; -}