tailor: make bitcoin modules truly Sovran-only (lnd-only) and delete stubs.nix

- lndconnect.nix: rewrite to lnd-only (320 lines removed) - remove
  services.clightning.plugins.clnrest.lnconnect and
  services.clightning-rest.lndconnect (Sovran only uses services.lnd.lndconnect for Zeus)
  Fixes: 'services.clightning.plugins.clnrest.address does not exist' on f13ff45
  and 'attribute enable missing' at lndconnect.nix:216

- btcpayserver.nix: remove liquidd (lbtc) dead branch - Sovran uses lbtc=false
  * remove inherit (config.services) bitcoind liquidd -> just bitcoind
  * lbtc chains/rpc handling is dead code, keep guards but no need for liquidd service

- mempool.nix: remove fulcrum branch - Sovran uses electrs only
- rtl.nix: remove lightning-loop block and clightning service block (lnd only)
- Delete modules/bitcoin/stubs.nix entirely - no dead service references left
  * liquidd, fulcrum, lightning-loop, joinmarket now not referenced at all
  * clightning already handled via guards, not stubs
- Result: modules/bitcoin/ is now 100% tailored to Sovran (bitcoind+knots, lnd, electrs, rtl, btcpayserver, mempool)
  No more stubs whack-a-mole on any nixos-unstable
This commit is contained in:
Sovran Tailor
2026-08-10 08:37:29 -05:00
committed by naturallaw777
parent 90262e672e
commit 31cd5f96f2
6 changed files with 62 additions and 320 deletions
+5 -20
View File
@@ -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} = {};
-1
View File
@@ -10,7 +10,6 @@
./rtl.nix
./btcpayserver.nix
./mempool.nix
./stubs.nix
];
disabledModules = [ "services/networking/bitcoind.nix" ];
+52 -271
View File
@@ -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" ];
})
]);
}
+2 -4
View File
@@ -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;
+3 -4
View File
@@ -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
-20
View File
@@ -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; };
}