Merge fort-nix/nix-bitcoin#388: Modules formatting

9114ec669a lnd: improve options formatting (Erik Arvstedt)
c8774375d3 modules: use consistent service variables (Erik Arvstedt)
ad97c268c6 modules: move user/group options to bottom (Erik Arvstedt)
27c45b82cc modules: move options to the top (Erik Arvstedt)
731cf647ff modules: remove unneeded use of `options` module arg (Erik Arvstedt)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 9114ec669a

Tree-SHA512: 7817b33d00459b31cacedc365ec067c8162200d46d13a3c2a405eba61e014373d6be8de4cb3c270886da8b1555f86bc7909023ce20d33d3f7ec5429f5eae9d8b
This commit is contained in:
Jonas Nick 2021-09-19 11:28:11 +00:00
commit 020d9486dd
No known key found for this signature in database
GPG Key ID: 4861DBF262123605
24 changed files with 690 additions and 653 deletions

View File

@ -1,40 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.backups;
filelist = pkgs.writeText "filelist.txt" ''
${optionalString (!cfg.with-bulk-data) "- ${config.services.bitcoind.dataDir}/blocks"}
${optionalString (!cfg.with-bulk-data) "- ${config.services.bitcoind.dataDir}/chainstate"}
${config.services.bitcoind.dataDir}
${config.services.clightning.dataDir}
${config.services.lnd.dataDir}
${optionalString (!cfg.with-bulk-data) "- ${config.services.liquidd.dataDir}/*/blocks"}
${optionalString (!cfg.with-bulk-data) "- ${config.services.liquidd.dataDir}/*/chainstate"}
${config.services.liquidd.dataDir}
${optionalString cfg.with-bulk-data "${config.services.electrs.dataDir}"}
${config.services.nbxplorer.dataDir}
${config.services.btcpayserver.dataDir}
${config.services.joinmarket.dataDir}
${optionalString config.nix-bitcoin.generateSecrets "${config.nix-bitcoin.secretsDir}"}
/var/lib/tor
/var/lib/nixos
${builtins.concatStringsSep "\n" postgresqlBackupPaths}
# Extra files
${cfg.extraFiles}
# Exclude all unspecified files and directories
- /
'';
postgresqlBackupDir = config.services.postgresqlBackup.location;
postgresqlBackupPaths = map (db: "${postgresqlBackupDir}/${db}.sql.gz") cfg.postgresqlDatabases;
postgresqlBackupServices = map (db: "postgresqlBackup-${db}.service") cfg.postgresqlDatabases;
in {
options.services.backups = { options.services.backups = {
enable = mkEnableOption "Backups service"; enable = mkEnableOption "Backups service";
with-bulk-data = mkOption { with-bulk-data = mkOption {
@ -73,6 +40,40 @@ in {
}; };
}; };
cfg = config.services.backups;
filelist = pkgs.writeText "filelist.txt" ''
${optionalString (!cfg.with-bulk-data) "- ${config.services.bitcoind.dataDir}/blocks"}
${optionalString (!cfg.with-bulk-data) "- ${config.services.bitcoind.dataDir}/chainstate"}
${config.services.bitcoind.dataDir}
${config.services.clightning.dataDir}
${config.services.lnd.dataDir}
${optionalString (!cfg.with-bulk-data) "- ${config.services.liquidd.dataDir}/*/blocks"}
${optionalString (!cfg.with-bulk-data) "- ${config.services.liquidd.dataDir}/*/chainstate"}
${config.services.liquidd.dataDir}
${optionalString cfg.with-bulk-data "${config.services.electrs.dataDir}"}
${config.services.nbxplorer.dataDir}
${config.services.btcpayserver.dataDir}
${config.services.joinmarket.dataDir}
${optionalString config.nix-bitcoin.generateSecrets "${config.nix-bitcoin.secretsDir}"}
/var/lib/tor
/var/lib/nixos
${builtins.concatStringsSep "\n" postgresqlBackupPaths}
# Extra files
${cfg.extraFiles}
# Exclude all unspecified files and directories
- /
'';
postgresqlBackupDir = config.services.postgresqlBackup.location;
postgresqlBackupPaths = map (db: "${postgresqlBackupDir}/${db}.sql.gz") cfg.postgresqlDatabases;
postgresqlBackupServices = map (db: "postgresqlBackup-${db}.service") cfg.postgresqlDatabases;
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.duplicity ]; environment.systemPackages = [ pkgs.duplicity ];

View File

@ -1,63 +1,7 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
with lib; with lib;
let let
cfg = config.services.bitcoind;
nbLib = config.nix-bitcoin.lib;
secretsDir = config.nix-bitcoin.secretsDir;
configFile = builtins.toFile "bitcoin.conf" ''
# We're already logging via journald
nodebuglogfile=1
startupnotify=/run/current-system/systemd/bin/systemd-notify --ready
${optionalString cfg.regtest ''
regtest=1
[regtest]
''}
${optionalString (cfg.dbCache != null) "dbcache=${toString cfg.dbCache}"}
prune=${toString cfg.prune}
${optionalString (cfg.sysperms != null) "sysperms=${if cfg.sysperms then "1" else "0"}"}
${optionalString (cfg.disablewallet != null) "disablewallet=${if cfg.disablewallet then "1" else "0"}"}
${optionalString (cfg.assumevalid != null) "assumevalid=${cfg.assumevalid}"}
# Connection options
${optionalString cfg.listen "bind=${cfg.address}${optionalString cfg.enforceTor "=onion"}"}
port=${toString cfg.port}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
listen=${if cfg.listen then "1" else "0"}
${optionalString (cfg.discover != null) "discover=${if cfg.discover then "1" else "0"}"}
${lib.concatMapStrings (node: "addnode=${node}\n") cfg.addnodes}
# RPC server options
rpcbind=${cfg.rpc.address}
rpcport=${toString cfg.rpc.port}
rpcconnect=${cfg.rpc.address}
${optionalString (cfg.rpc.threads != null) "rpcthreads=${toString cfg.rpc.threads}"}
rpcwhitelistdefault=0
${concatMapStrings (user: ''
${optionalString (!user.passwordHMACFromFile) "rpcauth=${user.name}:${passwordHMAC}"}
${optionalString (user.rpcwhitelist != [])
"rpcwhitelist=${user.name}:${lib.strings.concatStringsSep "," user.rpcwhitelist}"}
'') (builtins.attrValues cfg.rpc.users)
}
${lib.concatMapStrings (rpcallowip: "rpcallowip=${rpcallowip}\n") cfg.rpc.allowip}
# Wallet options
${optionalString (cfg.addresstype != null) "addresstype=${cfg.addresstype}"}
# ZMQ options
${optionalString (cfg.zmqpubrawblock != null) "zmqpubrawblock=${cfg.zmqpubrawblock}"}
${optionalString (cfg.zmqpubrawtx != null) "zmqpubrawtx=${cfg.zmqpubrawtx}"}
# Extra options
${cfg.extraConfig}
'';
zmqServerEnabled = (cfg.zmqpubrawblock != null) || (cfg.zmqpubrawtx != null);
in {
options = { options = {
services.bitcoind = { services.bitcoind = {
enable = mkEnableOption "Bitcoin daemon"; enable = mkEnableOption "Bitcoin daemon";
@ -99,16 +43,6 @@ in {
default = "/var/lib/bitcoind"; default = "/var/lib/bitcoind";
description = "The data directory for bitcoind."; description = "The data directory for bitcoind.";
}; };
user = mkOption {
type = types.str;
default = "bitcoin";
description = "The user as which to run bitcoind.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run bitcoind.";
};
rpc = { rpc = {
address = mkOption { address = mkOption {
type = types.str; type = types.str;
@ -277,6 +211,16 @@ in {
example = "bech32"; example = "bech32";
description = "The type of addresses to use"; description = "The type of addresses to use";
}; };
user = mkOption {
type = types.str;
default = "bitcoin";
description = "The user as which to run bitcoind.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run bitcoind.";
};
cli = mkOption { cli = mkOption {
readOnly = true; readOnly = true;
type = types.package; type = types.package;
@ -289,6 +233,63 @@ in {
}; };
}; };
cfg = config.services.bitcoind;
nbLib = config.nix-bitcoin.lib;
secretsDir = config.nix-bitcoin.secretsDir;
configFile = builtins.toFile "bitcoin.conf" ''
# We're already logging via journald
nodebuglogfile=1
startupnotify=/run/current-system/systemd/bin/systemd-notify --ready
${optionalString cfg.regtest ''
regtest=1
[regtest]
''}
${optionalString (cfg.dbCache != null) "dbcache=${toString cfg.dbCache}"}
prune=${toString cfg.prune}
${optionalString (cfg.sysperms != null) "sysperms=${if cfg.sysperms then "1" else "0"}"}
${optionalString (cfg.disablewallet != null) "disablewallet=${if cfg.disablewallet then "1" else "0"}"}
${optionalString (cfg.assumevalid != null) "assumevalid=${cfg.assumevalid}"}
# Connection options
${optionalString cfg.listen "bind=${cfg.address}${optionalString cfg.enforceTor "=onion"}"}
port=${toString cfg.port}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
listen=${if cfg.listen then "1" else "0"}
${optionalString (cfg.discover != null) "discover=${if cfg.discover then "1" else "0"}"}
${lib.concatMapStrings (node: "addnode=${node}\n") cfg.addnodes}
# RPC server options
rpcbind=${cfg.rpc.address}
rpcport=${toString cfg.rpc.port}
rpcconnect=${cfg.rpc.address}
${optionalString (cfg.rpc.threads != null) "rpcthreads=${toString cfg.rpc.threads}"}
rpcwhitelistdefault=0
${concatMapStrings (user: ''
${optionalString (!user.passwordHMACFromFile) "rpcauth=${user.name}:${passwordHMAC}"}
${optionalString (user.rpcwhitelist != [])
"rpcwhitelist=${user.name}:${lib.strings.concatStringsSep "," user.rpcwhitelist}"}
'') (builtins.attrValues cfg.rpc.users)
}
${lib.concatMapStrings (rpcallowip: "rpcallowip=${rpcallowip}\n") cfg.rpc.allowip}
# Wallet options
${optionalString (cfg.addresstype != null) "addresstype=${cfg.addresstype}"}
# ZMQ options
${optionalString (cfg.zmqpubrawblock != null) "zmqpubrawblock=${cfg.zmqpubrawblock}"}
${optionalString (cfg.zmqpubrawtx != null) "zmqpubrawtx=${cfg.zmqpubrawtx}"}
# Extra options
${cfg.extraConfig}
'';
zmqServerEnabled = (cfg.zmqpubrawblock != null) || (cfg.zmqpubrawtx != null);
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package (hiPrio cfg.cli) ]; environment.systemPackages = [ cfg.package (hiPrio cfg.cli) ];

View File

@ -1,12 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
in {
options.services = { options.services = {
nbxplorer = { nbxplorer = {
package = mkOption { package = mkOption {
@ -72,16 +67,6 @@ in {
default = "/var/lib/btcpayserver"; default = "/var/lib/btcpayserver";
description = "The data directory for btcpayserver."; description = "The data directory for btcpayserver.";
}; };
user = mkOption {
type = types.str;
default = "btcpayserver";
description = "The user as which to run btcpayserver.";
};
group = mkOption {
type = types.str;
default = cfg.btcpayserver.user;
description = "The group as which to run btcpayserver.";
};
lightningBackend = mkOption { lightningBackend = mkOption {
type = types.nullOr (types.enum [ "clightning" "lnd" ]); type = types.nullOr (types.enum [ "clightning" "lnd" ]);
default = null; default = null;
@ -98,10 +83,28 @@ in {
example = "btcpayserver"; example = "btcpayserver";
description = "The prefix for root-relative btcpayserver URLs."; description = "The prefix for root-relative btcpayserver URLs.";
}; };
user = mkOption {
type = types.str;
default = "btcpayserver";
description = "The user as which to run btcpayserver.";
};
group = mkOption {
type = types.str;
default = cfg.btcpayserver.user;
description = "The group as which to run btcpayserver.";
};
enforceTor = nbLib.enforceTor; enforceTor = nbLib.enforceTor;
}; };
}; };
cfg = config.services;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
bitcoind = config.services.bitcoind;
in {
inherit options;
config = mkIf cfg.btcpayserver.enable { config = mkIf cfg.btcpayserver.enable {
services.bitcoind.enable = true; services.bitcoind.enable = true;
services.clightning.enable = mkIf (cfg.btcpayserver.lightningBackend == "clightning") true; services.clightning.enable = mkIf (cfg.btcpayserver.lightningBackend == "clightning") true;
@ -138,10 +141,10 @@ in {
systemd.services.nbxplorer = let systemd.services.nbxplorer = let
configFile = builtins.toFile "config" '' configFile = builtins.toFile "config" ''
network=${config.services.bitcoind.network} network=${bitcoind.network}
btcrpcuser=${cfg.bitcoind.rpc.users.btcpayserver.name} btcrpcuser=${cfg.bitcoind.rpc.users.btcpayserver.name}
btcrpcurl=http://${config.services.bitcoind.rpc.address}:${toString cfg.bitcoind.rpc.port} btcrpcurl=http://${bitcoind.rpc.address}:${toString cfg.bitcoind.rpc.port}
btcnodeendpoint=${config.services.bitcoind.address}:${toString config.services.bitcoind.port} btcnodeendpoint=${bitcoind.address}:${toString bitcoind.port}
bind=${cfg.nbxplorer.address} bind=${cfg.nbxplorer.address}
port=${toString cfg.nbxplorer.port} port=${toString cfg.nbxplorer.port}
${optionalString cfg.btcpayserver.lbtc '' ${optionalString cfg.btcpayserver.lbtc ''
@ -179,9 +182,9 @@ in {
systemd.services.btcpayserver = let systemd.services.btcpayserver = let
nbExplorerUrl = "http://${cfg.nbxplorer.address}:${toString cfg.nbxplorer.port}/"; nbExplorerUrl = "http://${cfg.nbxplorer.address}:${toString cfg.nbxplorer.port}/";
nbExplorerCookie = "${cfg.nbxplorer.dataDir}/${config.services.bitcoind.makeNetworkName "Main" "RegTest"}/.cookie"; nbExplorerCookie = "${cfg.nbxplorer.dataDir}/${bitcoind.makeNetworkName "Main" "RegTest"}/.cookie";
configFile = builtins.toFile "config" ('' configFile = builtins.toFile "config" (''
network=${config.services.bitcoind.network} network=${bitcoind.network}
bind=${cfg.btcpayserver.address} bind=${cfg.btcpayserver.address}
port=${toString cfg.btcpayserver.port} port=${toString cfg.btcpayserver.port}
socksendpoint=${config.nix-bitcoin.torClientAddressWithPort} socksendpoint=${config.nix-bitcoin.torClientAddressWithPort}

View File

@ -1,26 +1,7 @@
{ config, options, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.charge-lnd;
nbLib = config.nix-bitcoin.lib;
lnd = config.services.lnd;
electrs = if (options ? services.electrs) && config.services.electrs.enable
then config.services.electrs
else null;
user = "charge-lnd";
group = user;
dataDir = "/var/lib/charge-lnd";
configFile = builtins.toFile "charge-lnd.config" cfg.policies;
checkedConfig = pkgs.runCommandNoCC "charge-lnd-checked.config" { } ''
${config.nix-bitcoin.pkgs.charge-lnd}/bin/charge-lnd --check --config ${configFile}
cp ${configFile} $out
'';
in
{
options.services.charge-lnd = with types; { options.services.charge-lnd = with types; {
enable = mkEnableOption "charge-lnd, policy-based fee manager"; enable = mkEnableOption "charge-lnd, policy-based fee manager";
@ -86,6 +67,26 @@ in
}; };
}; };
cfg = config.services.charge-lnd;
nbLib = config.nix-bitcoin.lib;
lnd = config.services.lnd;
electrs = if (config.services ? electrs) && config.services.electrs.enable
then config.services.electrs
else null;
user = "charge-lnd";
group = user;
dataDir = "/var/lib/charge-lnd";
configFile = builtins.toFile "charge-lnd.config" cfg.policies;
checkedConfig = pkgs.runCommandNoCC "charge-lnd-checked.config" { } ''
${config.nix-bitcoin.pkgs.charge-lnd}/bin/charge-lnd --check --config ${configFile}
cp ${configFile} $out
'';
in
{
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.lnd = { services.lnd = {
enable = true; enable = true;

View File

@ -2,6 +2,12 @@
with lib; with lib;
let let
options.services.clightning.plugins = {
helpme.enable = mkEnableOption "Help me (clightning plugin)";
monitor.enable = mkEnableOption "Monitor (clightning plugin)";
rebalance.enable = mkEnableOption "Rebalance (clightning plugin)";
};
cfg = config.services.clightning.plugins; cfg = config.services.clightning.plugins;
pluginPkgs = config.nix-bitcoin.pkgs.clightning-plugins; pluginPkgs = config.nix-bitcoin.pkgs.clightning-plugins;
in { in {
@ -12,11 +18,7 @@ in {
./zmq.nix ./zmq.nix
]; ];
options.services.clightning.plugins = { inherit options;
helpme.enable = mkEnableOption "Help me (clightning plugin)";
monitor.enable = mkEnableOption "Monitor (clightning plugin)";
rebalance.enable = mkEnableOption "Rebalance (clightning plugin)";
};
config = { config = {
services.clightning.extraConfig = mkMerge [ services.clightning.extraConfig = mkMerge [

View File

@ -2,6 +2,10 @@
with lib; with lib;
let let
options.services.clightning.plugins.zmq = {
enable = mkEnableOption "ZMQ (clightning plugin)";
} // lib.genAttrs endpoints mkEndpointOption;
cfg = config.services.clightning.plugins.zmq; cfg = config.services.clightning.plugins.zmq;
nbLib = config.nix-bitcoin.lib; nbLib = config.nix-bitcoin.lib;
@ -31,9 +35,7 @@ let
''; '';
in in
{ {
options.services.clightning.plugins.zmq = { inherit options;
enable = mkEnableOption "ZMQ (clightning plugin)";
} // lib.genAttrs endpoints mkEndpointOption;
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.clightning.extraConfig = '' services.clightning.extraConfig = ''

View File

@ -1,25 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.clightning;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
network = config.services.bitcoind.makeNetworkName "bitcoin" "regtest";
configFile = pkgs.writeText "config" ''
network=${network}
bitcoin-datadir=${config.services.bitcoind.dataDir}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
always-use-proxy=${boolToString cfg.always-use-proxy}
bind-addr=${cfg.address}:${toString cfg.port}
bitcoin-rpcconnect=${config.services.bitcoind.rpc.address}
bitcoin-rpcport=${toString config.services.bitcoind.rpc.port}
bitcoin-rpcuser=${config.services.bitcoind.rpc.users.public.name}
rpc-file-mode=0660
${cfg.extraConfig}
'';
in {
options.services.clightning = { options.services.clightning = {
enable = mkEnableOption "clightning"; enable = mkEnableOption "clightning";
address = mkOption { address = mkOption {
@ -91,6 +73,26 @@ in {
inherit (nbLib) enforceTor; inherit (nbLib) enforceTor;
}; };
cfg = config.services.clightning;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
network = config.services.bitcoind.makeNetworkName "bitcoin" "regtest";
configFile = pkgs.writeText "config" ''
network=${network}
bitcoin-datadir=${config.services.bitcoind.dataDir}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
always-use-proxy=${boolToString cfg.always-use-proxy}
bind-addr=${cfg.address}:${toString cfg.port}
bitcoin-rpcconnect=${config.services.bitcoind.rpc.address}
bitcoin-rpcport=${toString config.services.bitcoind.rpc.port}
bitcoin-rpcuser=${config.services.bitcoind.rpc.users.public.name}
rpc-file-mode=0660
${cfg.extraConfig}
'';
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.bitcoind = { services.bitcoind = {
enable = true; enable = true;

View File

@ -2,11 +2,6 @@
with lib; with lib;
let let
cfg = config.services.electrs;
nbLib = config.nix-bitcoin.lib;
secretsDir = config.nix-bitcoin.secretsDir;
bitcoind = config.services.bitcoind;
in {
options.services.electrs = { options.services.electrs = {
enable = mkEnableOption "electrs"; enable = mkEnableOption "electrs";
address = mkOption { address = mkOption {
@ -24,16 +19,6 @@ in {
default = "/var/lib/electrs"; default = "/var/lib/electrs";
description = "The data directory for electrs."; description = "The data directory for electrs.";
}; };
user = mkOption {
type = types.str;
default = "electrs";
description = "The user as which to run electrs.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run electrs.";
};
high-memory = mkOption { high-memory = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
@ -51,9 +36,26 @@ in {
default = ""; default = "";
description = "Extra command line arguments passed to electrs."; description = "Extra command line arguments passed to electrs.";
}; };
user = mkOption {
type = types.str;
default = "electrs";
description = "The user as which to run electrs.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run electrs.";
};
enforceTor = nbLib.enforceTor; enforceTor = nbLib.enforceTor;
}; };
cfg = config.services.electrs;
nbLib = config.nix-bitcoin.lib;
secretsDir = config.nix-bitcoin.secretsDir;
bitcoind = config.services.bitcoind;
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [
{ assertion = bitcoind.prune == 0; { assertion = bitcoind.prune == 0;

View File

@ -1,12 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.hardware-wallets;
dataDir = "/var/lib/hardware-wallets/";
enabled = cfg.ledger || cfg.trezor;
in {
options.services.hardware-wallets = { options.services.hardware-wallets = {
ledger = mkOption { ledger = mkOption {
type = types.bool; type = types.bool;
@ -31,6 +26,12 @@ in {
}; };
}; };
cfg = config.services.hardware-wallets;
dataDir = "/var/lib/hardware-wallets/";
enabled = cfg.ledger || cfg.trezor;
in {
inherit options;
config = mkMerge [ config = mkMerge [
(mkIf (cfg.ledger || cfg.trezor) { (mkIf (cfg.ledger || cfg.trezor) {
assertions = [ assertions = [

View File

@ -2,6 +2,40 @@
with lib; with lib;
let let
options.services.joinmarket-ob-watcher = {
enable = mkEnableOption "JoinMarket orderbook watcher";
address = mkOption {
type = types.str;
default = "127.0.0.1";
description = "HTTP server address.";
};
port = mkOption {
type = types.port;
default = 62601;
description = "HTTP server port.";
};
dataDir = mkOption {
readOnly = true;
default = "/var/lib/joinmarket-ob-watcher";
description = "The data directory for JoinMarket orderbook watcher.";
};
user = mkOption {
type = types.str;
default = "joinmarket-ob-watcher";
description = "The user as which to run JoinMarket.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run JoinMarket.";
};
# This option is only used by netns-isolation
enforceTor = mkOption {
readOnly = true;
default = true;
};
};
cfg = config.services.joinmarket-ob-watcher; cfg = config.services.joinmarket-ob-watcher;
nbLib = config.nix-bitcoin.lib; nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs; nbPkgs = config.nix-bitcoin.pkgs;
@ -39,39 +73,7 @@ let
${socks5Settings} ${socks5Settings}
''; '';
in { in {
options.services.joinmarket-ob-watcher = { inherit options;
enable = mkEnableOption "JoinMarket orderbook watcher";
address = mkOption {
type = types.str;
default = "127.0.0.1";
description = "HTTP server address.";
};
port = mkOption {
type = types.port;
default = 62601;
description = "HTTP server port.";
};
dataDir = mkOption {
readOnly = true;
default = "/var/lib/joinmarket-ob-watcher";
description = "The data directory for JoinMarket orderbook watcher.";
};
user = mkOption {
type = types.str;
default = "joinmarket-ob-watcher";
description = "The user as which to run JoinMarket.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run JoinMarket.";
};
# This option is only used by netns-isolation
enforceTor = mkOption {
readOnly = true;
default = true;
};
};
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.bitcoind.rpc.users.joinmarket-ob-watcher = { services.bitcoind.rpc.users.joinmarket-ob-watcher = {

View File

@ -1,8 +1,102 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
options.services.joinmarket = {
enable = mkEnableOption "JoinMarket";
dataDir = mkOption {
type = types.path;
default = "/var/lib/joinmarket";
description = "The data directory for JoinMarket.";
};
rpcWalletFile = mkOption {
type = types.nullOr types.str;
default = "jm_wallet";
description = ''
Name of the watch-only bitcoind wallet the JoinMarket addresses are imported to.
'';
};
user = mkOption {
type = types.str;
default = "joinmarket";
description = "The user as which to run JoinMarket.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run JoinMarket.";
};
cli = mkOption {
default = cli;
};
# This option is only used by netns-isolation
enforceTor = mkOption {
readOnly = true;
default = true;
};
inherit (nbLib) cliExec;
yieldgenerator = {
enable = mkEnableOption "yield generator bot";
ordertype = mkOption {
type = types.enum [ "reloffer" "absoffer" ];
default = "reloffer";
description = ''
Which fee type to actually use
'';
};
cjfee_a = mkOption {
type = types.ints.unsigned;
default = 500;
description = ''
Absolute offer fee you wish to receive for coinjoins (cj) in Satoshis
'';
};
cjfee_r = mkOption {
type = types.float;
default = 0.00002;
description = ''
Relative offer fee you wish to receive based on a cj's amount
'';
};
cjfee_factor = mkOption {
type = types.float;
default = 0.1;
description = ''
Variance around the average cj fee
'';
};
txfee = mkOption {
type = types.ints.unsigned;
default = 100;
description = ''
The average transaction fee you're adding to coinjoin transactions
'';
};
txfee_factor = mkOption {
type = types.float;
default = 0.3;
description = ''
Variance around the average tx fee
'';
};
minsize = mkOption {
type = types.ints.unsigned;
default = 100000;
description = ''
Minimum size of your cj offer in Satoshis. Lower cj amounts will be disregarded.
'';
};
size_factor = mkOption {
type = types.float;
default = 0.1;
description = ''
Variance around all offer sizes
'';
};
};
};
cfg = config.services.joinmarket; cfg = config.services.joinmarket;
nbLib = config.nix-bitcoin.lib; nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs; nbPkgs = config.nix-bitcoin.pkgs;
@ -114,100 +208,7 @@ let
chmod -R +x $out/bin chmod -R +x $out/bin
''; '';
in { in {
options.services.joinmarket = { inherit options;
enable = mkEnableOption "JoinMarket";
dataDir = mkOption {
type = types.path;
default = "/var/lib/joinmarket";
description = "The data directory for JoinMarket.";
};
user = mkOption {
type = types.str;
default = "joinmarket";
description = "The user as which to run JoinMarket.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run JoinMarket.";
};
rpcWalletFile = mkOption {
type = types.nullOr types.str;
default = "jm_wallet";
description = ''
Name of the watch-only bitcoind wallet the JoinMarket addresses are imported to.
'';
};
cli = mkOption {
default = cli;
};
# This option is only used by netns-isolation
enforceTor = mkOption {
readOnly = true;
default = true;
};
inherit (nbLib) cliExec;
yieldgenerator = {
enable = mkEnableOption "yield generator bot";
ordertype = mkOption {
type = types.enum [ "reloffer" "absoffer" ];
default = "reloffer";
description = ''
Which fee type to actually use
'';
};
cjfee_a = mkOption {
type = types.ints.unsigned;
default = 500;
description = ''
Absolute offer fee you wish to receive for coinjoins (cj) in Satoshis
'';
};
cjfee_r = mkOption {
type = types.float;
default = 0.00002;
description = ''
Relative offer fee you wish to receive based on a cj's amount
'';
};
cjfee_factor = mkOption {
type = types.float;
default = 0.1;
description = ''
Variance around the average cj fee
'';
};
txfee = mkOption {
type = types.ints.unsigned;
default = 100;
description = ''
The average transaction fee you're adding to coinjoin transactions
'';
};
txfee_factor = mkOption {
type = types.float;
default = 0.3;
description = ''
Variance around the average tx fee
'';
};
minsize = mkOption {
type = types.ints.unsigned;
default = 100000;
description = ''
Minimum size of your cj offer in Satoshis. Lower cj amounts will be disregarded.
'';
};
size_factor = mkOption {
type = types.float;
default = 0.1;
description = ''
Variance around all offer sizes
'';
};
};
};
config = mkIf cfg.enable (mkMerge [{ config = mkIf cfg.enable (mkMerge [{
services.bitcoind = { services.bitcoind = {

View File

@ -1,34 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.lightning-loop;
nbLib = config.nix-bitcoin.lib;
secretsDir = config.nix-bitcoin.secretsDir;
lnd = config.services.lnd;
network = config.services.bitcoind.network;
rpclisten = "${cfg.rpcAddress}:${toString cfg.rpcPort}";
configFile = builtins.toFile "loop.conf" ''
datadir=${cfg.dataDir}
network=${network}
rpclisten=${rpclisten}
restlisten=${cfg.restAddress}:${toString cfg.restPort}
logdir=${cfg.dataDir}/logs
tlscertpath=${secretsDir}/loop-cert
tlskeypath=${secretsDir}/loop-key
lnd.host=${lnd.rpcAddress}:${toString lnd.rpcPort}
lnd.macaroonpath=${lnd.networkDir}/admin.macaroon
lnd.tlspath=${lnd.certPath}
${optionalString (cfg.proxy != null) "server.proxy=${cfg.proxy}"}
${cfg.extraConfig}
'';
in {
options.services.lightning-loop = { options.services.lightning-loop = {
enable = mkEnableOption "lightning-loop"; enable = mkEnableOption "lightning-loop";
rpcAddress = mkOption { rpcAddress = mkOption {
@ -86,6 +59,34 @@ in {
enforceTor = nbLib.enforceTor; enforceTor = nbLib.enforceTor;
}; };
cfg = config.services.lightning-loop;
nbLib = config.nix-bitcoin.lib;
secretsDir = config.nix-bitcoin.secretsDir;
lnd = config.services.lnd;
network = config.services.bitcoind.network;
rpclisten = "${cfg.rpcAddress}:${toString cfg.rpcPort}";
configFile = builtins.toFile "loop.conf" ''
datadir=${cfg.dataDir}
network=${network}
rpclisten=${rpclisten}
restlisten=${cfg.restAddress}:${toString cfg.restPort}
logdir=${cfg.dataDir}/logs
tlscertpath=${secretsDir}/loop-cert
tlskeypath=${secretsDir}/loop-key
lnd.host=${lnd.rpcAddress}:${toString lnd.rpcPort}
lnd.macaroonpath=${lnd.networkDir}/admin.macaroon
lnd.tlspath=${lnd.certPath}
${optionalString (cfg.proxy != null) "server.proxy=${cfg.proxy}"}
${cfg.extraConfig}
'';
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.lnd.enable = true; services.lnd.enable = true;

View File

@ -1,27 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.lightning-pool;
nbLib = config.nix-bitcoin.lib;
lnd = config.services.lnd;
network = config.services.bitcoind.network;
rpclisten = "${cfg.rpcAddress}:${toString cfg.rpcPort}";
configFile = builtins.toFile "pool.conf" ''
rpclisten=${rpclisten}
restlisten=${cfg.restAddress}:${toString cfg.restPort}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
lnd.host=${lnd.rpcAddress}:${toString lnd.rpcPort}
lnd.macaroondir=${lnd.networkDir}
lnd.tlspath=${lnd.certPath}
${cfg.extraConfig}
'';
in {
options.services.lightning-pool = { options.services.lightning-pool = {
enable = mkEnableOption "lightning-pool"; enable = mkEnableOption "lightning-pool";
rpcAddress = mkOption { rpcAddress = mkOption {
@ -79,6 +59,27 @@ in {
enforceTor = nbLib.enforceTor; enforceTor = nbLib.enforceTor;
}; };
cfg = config.services.lightning-pool;
nbLib = config.nix-bitcoin.lib;
lnd = config.services.lnd;
network = config.services.bitcoind.network;
rpclisten = "${cfg.rpcAddress}:${toString cfg.rpcPort}";
configFile = builtins.toFile "pool.conf" ''
rpclisten=${rpclisten}
restlisten=${cfg.restAddress}:${toString cfg.restPort}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
lnd.host=${lnd.rpcAddress}:${toString lnd.rpcPort}
lnd.macaroondir=${lnd.networkDir}
lnd.tlspath=${lnd.certPath}
${cfg.extraConfig}
'';
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.lnd.enable = true; services.lnd.enable = true;

View File

@ -1,75 +1,8 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
with lib; with lib;
let let
cfg = config.services.liquidd;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
secretsDir = config.nix-bitcoin.secretsDir;
pidFile = "${cfg.dataDir}/liquidd.pid";
configFile = pkgs.writeText "elements.conf" ''
chain=${config.services.bitcoind.makeNetworkName "liquidv1" ''
regtest
[regtest]'' # Add [regtest] config section
}
${optionalString (cfg.dbCache != null) "dbcache=${toString cfg.dbCache}"}
${optionalString (cfg.prune != null) "prune=${toString cfg.prune}"}
${optionalString (cfg.validatepegin != null) "validatepegin=${if cfg.validatepegin then "1" else "0"}"}
# Connection options
${optionalString cfg.listen "bind=${cfg.address}"}
port=${toString cfg.port}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
listen=${if cfg.listen then "1" else "0"}
# RPC server options
rpcport=${toString cfg.rpc.port}
${concatMapStringsSep "\n"
(rpcUser: "rpcauth=${rpcUser.name}:${rpcUser.passwordHMAC}")
(attrValues cfg.rpc.users)
}
rpcbind=${cfg.rpc.address}
rpcconnect=${cfg.rpc.address}
${lib.concatMapStrings (rpcallowip: "rpcallowip=${rpcallowip}\n") cfg.rpcallowip}
rpcuser=${cfg.rpcuser}
mainchainrpchost=${config.services.bitcoind.rpc.address}
mainchainrpcport=${toString config.services.bitcoind.rpc.port}
mainchainrpcuser=${config.services.bitcoind.rpc.users.public.name}
# Extra config options (from liquidd nixos service)
${cfg.extraConfig}
'';
cmdlineOptions = concatMapStringsSep " " (arg: "'${arg}'") [
"-datadir=${cfg.dataDir}"
"-pid=${pidFile}"
];
hexStr = types.strMatching "[0-9a-f]+";
rpcUserOpts = { name, ... }: {
options = {
name = mkOption {
type = types.str;
example = "alice";
description = ''
Username for JSON-RPC connections.
'';
};
passwordHMAC = mkOption {
type = with types; uniq (strMatching "[0-9a-f]+\\$[0-9a-f]{64}");
example = "f7efda5c189b999524f151318c0c86$d5b51b3beffbc02b724e5d095828e0bc8b2456e9ac8757ae3211a5d9b16a22ae";
description = ''
Password HMAC-SHA-256 for JSON-RPC connections. Must be a string of the
format <SALT-HEX>$<HMAC-HEX>.
'';
};
};
config = {
name = mkDefault name;
};
};
in {
options = { options = {
services.liquidd = { services.liquidd = {
enable = mkEnableOption "Liquid sidechain"; enable = mkEnableOption "Liquid sidechain";
address = mkOption { address = mkOption {
@ -97,16 +30,6 @@ in {
default = "/var/lib/liquidd"; default = "/var/lib/liquidd";
description = "The data directory for liquidd."; description = "The data directory for liquidd.";
}; };
user = mkOption {
type = types.str;
default = "liquid";
description = "The user as which to run liquidd.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run liquidd.";
};
rpc = { rpc = {
address = mkOption { address = mkOption {
type = types.str; type = types.str;
@ -186,6 +109,16 @@ in {
Validate pegin claims. All functionaries must run this. Validate pegin claims. All functionaries must run this.
''; '';
}; };
user = mkOption {
type = types.str;
default = "liquid";
description = "The user as which to run liquidd.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run liquidd.";
};
cli = mkOption { cli = mkOption {
readOnly = true; readOnly = true;
default = pkgs.writeScriptBin "elements-cli" '' default = pkgs.writeScriptBin "elements-cli" ''
@ -203,6 +136,76 @@ in {
}; };
}; };
cfg = config.services.liquidd;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
secretsDir = config.nix-bitcoin.secretsDir;
bitcoind = config.services.bitcoind;
pidFile = "${cfg.dataDir}/liquidd.pid";
configFile = pkgs.writeText "elements.conf" ''
chain=${bitcoind.makeNetworkName "liquidv1" ''
regtest
[regtest]'' # Add [regtest] config section
}
${optionalString (cfg.dbCache != null) "dbcache=${toString cfg.dbCache}"}
${optionalString (cfg.prune != null) "prune=${toString cfg.prune}"}
${optionalString (cfg.validatepegin != null) "validatepegin=${if cfg.validatepegin then "1" else "0"}"}
# Connection options
${optionalString cfg.listen "bind=${cfg.address}"}
port=${toString cfg.port}
${optionalString (cfg.proxy != null) "proxy=${cfg.proxy}"}
listen=${if cfg.listen then "1" else "0"}
# RPC server options
rpcport=${toString cfg.rpc.port}
${concatMapStringsSep "\n"
(rpcUser: "rpcauth=${rpcUser.name}:${rpcUser.passwordHMAC}")
(attrValues cfg.rpc.users)
}
rpcbind=${cfg.rpc.address}
rpcconnect=${cfg.rpc.address}
${lib.concatMapStrings (rpcallowip: "rpcallowip=${rpcallowip}\n") cfg.rpcallowip}
rpcuser=${cfg.rpcuser}
mainchainrpchost=${bitcoind.rpc.address}
mainchainrpcport=${toString bitcoind.rpc.port}
mainchainrpcuser=${bitcoind.rpc.users.public.name}
# Extra config options (from liquidd nixos service)
${cfg.extraConfig}
'';
cmdlineOptions = concatMapStringsSep " " (arg: "'${arg}'") [
"-datadir=${cfg.dataDir}"
"-pid=${pidFile}"
];
hexStr = types.strMatching "[0-9a-f]+";
rpcUserOpts = { name, ... }: {
options = {
name = mkOption {
type = types.str;
example = "alice";
description = ''
Username for JSON-RPC connections.
'';
};
passwordHMAC = mkOption {
type = with types; uniq (strMatching "[0-9a-f]+\\$[0-9a-f]{64}");
example = "f7efda5c189b999524f151318c0c86$d5b51b3beffbc02b724e5d095828e0bc8b2456e9ac8757ae3211a5d9b16a22ae";
description = ''
Password HMAC-SHA-256 for JSON-RPC connections. Must be a string of the
format <SALT-HEX>$<HMAC-HEX>.
'';
};
};
config = {
name = mkDefault name;
};
};
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.bitcoind.enable = true; services.bitcoind.enable = true;

View File

@ -1,24 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.lnd.restOnionService;
nbLib = config.nix-bitcoin.lib;
runAsUser = config.nix-bitcoin.runAsUserCmd;
lnd = config.services.lnd;
bin = pkgs.writeScriptBin "lndconnect-rest-onion" ''
#!/usr/bin/env -S ${runAsUser} ${lnd.user} ${pkgs.bash}/bin/bash
exec ${cfg.package}/bin/lndconnect \
--host=$(cat ${config.nix-bitcoin.onionAddresses.dataDir}/lnd/lnd-rest) \
--port=${toString lnd.restPort} \
--lnddir=${lnd.dataDir} \
--tlscertpath=${lnd.certPath} "$@"
'';
in {
options.services.lnd.restOnionService = { options.services.lnd.restOnionService = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -36,6 +19,24 @@ in {
}; };
}; };
cfg = config.services.lnd.restOnionService;
nbLib = config.nix-bitcoin.lib;
runAsUser = config.nix-bitcoin.runAsUserCmd;
lnd = config.services.lnd;
bin = pkgs.writeScriptBin "lndconnect-rest-onion" ''
#!/usr/bin/env -S ${runAsUser} ${lnd.user} ${pkgs.bash}/bin/bash
exec ${cfg.package}/bin/lndconnect \
--host=$(cat ${config.nix-bitcoin.onionAddresses.dataDir}/lnd/lnd-rest) \
--port=${toString lnd.restPort} \
--lnddir=${lnd.dataDir} \
--tlscertpath=${lnd.certPath} "$@"
'';
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.tor = { services.tor = {
enable = true; enable = true;

View File

@ -1,54 +1,9 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.lnd;
nbLib = config.nix-bitcoin.lib;
secretsDir = config.nix-bitcoin.secretsDir;
runAsUser = config.nix-bitcoin.runAsUserCmd;
bitcoind = config.services.bitcoind;
bitcoindRpcAddress = bitcoind.rpc.address;
networkDir = "${cfg.dataDir}/chain/bitcoin/${bitcoind.network}";
configFile = pkgs.writeText "lnd.conf" ''
datadir=${cfg.dataDir}
logdir=${cfg.dataDir}/logs
tlscertpath=${cfg.certPath}
tlskeypath=${secretsDir}/lnd-key
listen=${toString cfg.address}:${toString cfg.port}
rpclisten=${cfg.rpcAddress}:${toString cfg.rpcPort}
restlisten=${cfg.restAddress}:${toString cfg.restPort}
bitcoin.${bitcoind.network}=1
bitcoin.active=1
bitcoin.node=bitcoind
${optionalString (cfg.enforceTor) "tor.active=true"}
${optionalString (cfg.tor-socks != null) "tor.socks=${cfg.tor-socks}"}
bitcoind.rpchost=${bitcoindRpcAddress}:${toString bitcoind.rpc.port}
bitcoind.rpcuser=${bitcoind.rpc.users.public.name}
bitcoind.zmqpubrawblock=${bitcoind.zmqpubrawblock}
bitcoind.zmqpubrawtx=${bitcoind.zmqpubrawtx}
${cfg.extraConfig}
'';
in {
options.services.lnd = { options.services.lnd = {
enable = mkEnableOption "Lightning Network Daemon"; enable = mkEnableOption "Lightning Network Daemon";
dataDir = mkOption {
type = types.path;
default = "/var/lib/lnd";
description = "The data directory for LND.";
};
networkDir = mkOption {
readOnly = true;
default = networkDir;
description = "The network data directory.";
};
address = mkOption { address = mkOption {
type = types.str; type = types.str;
default = "localhost"; default = "localhost";
@ -72,15 +27,23 @@ in {
restAddress = mkOption { restAddress = mkOption {
type = types.str; type = types.str;
default = "localhost"; default = "localhost";
description = '' description = "Address to listen for REST connections.";
Address to listen for REST connections.
'';
}; };
restPort = mkOption { restPort = mkOption {
type = types.port; type = types.port;
default = 8080; default = 8080;
description = "Port to listen for REST connections."; description = "Port to listen for REST connections.";
}; };
dataDir = mkOption {
type = types.path;
default = "/var/lib/lnd";
description = "The data directory for LND.";
};
networkDir = mkOption {
readOnly = true;
default = "${cfg.dataDir}/chain/bitcoin/${bitcoind.network}";
description = "The network data directory.";
};
tor-socks = mkOption { tor-socks = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null; default = if cfg.enforceTor then config.nix-bitcoin.torClientAddressWithPort else null;
@ -122,13 +85,13 @@ in {
}; };
cli = mkOption { cli = mkOption {
default = pkgs.writeScriptBin "lncli" default = pkgs.writeScriptBin "lncli"
# Switch user because lnd makes datadir contents readable by user only # Switch user because lnd makes datadir contents readable by user only
'' ''
${runAsUser} ${cfg.user} ${cfg.package}/bin/lncli \ ${runAsUser} ${cfg.user} ${cfg.package}/bin/lncli \
--rpcserver ${cfg.rpcAddress}:${toString cfg.rpcPort} \ --rpcserver ${cfg.rpcAddress}:${toString cfg.rpcPort} \
--tlscertpath '${cfg.certPath}' \ --tlscertpath '${cfg.certPath}' \
--macaroonpath '${networkDir}/admin.macaroon' "$@" --macaroonpath '${networkDir}/admin.macaroon' "$@"
''; '';
description = "Binary to connect with the lnd instance."; description = "Binary to connect with the lnd instance.";
}; };
getPublicAddressCmd = mkOption { getPublicAddressCmd = mkOption {
@ -157,6 +120,43 @@ in {
inherit (nbLib) enforceTor; inherit (nbLib) enforceTor;
}; };
cfg = config.services.lnd;
nbLib = config.nix-bitcoin.lib;
secretsDir = config.nix-bitcoin.secretsDir;
runAsUser = config.nix-bitcoin.runAsUserCmd;
bitcoind = config.services.bitcoind;
bitcoindRpcAddress = bitcoind.rpc.address;
networkDir = cfg.networkDir;
configFile = pkgs.writeText "lnd.conf" ''
datadir=${cfg.dataDir}
logdir=${cfg.dataDir}/logs
tlscertpath=${cfg.certPath}
tlskeypath=${secretsDir}/lnd-key
listen=${toString cfg.address}:${toString cfg.port}
rpclisten=${cfg.rpcAddress}:${toString cfg.rpcPort}
restlisten=${cfg.restAddress}:${toString cfg.restPort}
bitcoin.${bitcoind.network}=1
bitcoin.active=1
bitcoin.node=bitcoind
${optionalString (cfg.enforceTor) "tor.active=true"}
${optionalString (cfg.tor-socks != null) "tor.socks=${cfg.tor-socks}"}
bitcoind.rpchost=${bitcoindRpcAddress}:${toString bitcoind.rpc.port}
bitcoind.rpcuser=${bitcoind.rpc.users.public.name}
bitcoind.zmqpubrawblock=${bitcoind.zmqpubrawblock}
bitcoind.zmqpubrawtx=${bitcoind.zmqpubrawtx}
${cfg.extraConfig}
'';
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [
{ assertion = bitcoind.prune == 0; { assertion = bitcoind.prune == 0;

View File

@ -1,50 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.nix-bitcoin.netns-isolation;
netns = builtins.mapAttrs (n: v: {
inherit (v) id;
address = "169.254.${toString cfg.addressblock}.${toString v.id}";
availableNetns = availableNetns.${n};
netnsName = "nb-${n}";
}) enabledServices;
# Symmetric netns connection matrix
# if clightning.connections = [ "bitcoind" ]; then
# availableNetns.bitcoind = [ "clighting" ];
# and
# availableNetns.clighting = [ "bitcoind" ];
#
# FIXME: Although negligible for our purposes, this calculation's runtime
# is in the order of (number of connections * number of services),
# because attrsets and lists are fully copied on each update with '//' or '++'.
# This can only be improved with an update in the nix language.
#
availableNetns = let
# base = { clightning = [ "bitcoind" ]; ... }
base = builtins.mapAttrs (n: v:
builtins.filter isEnabled v.connections
) enabledServices;
in
foldl (xs: s1:
foldl (xs: s2:
xs // { "${s2}" = xs.${s2} ++ [ s1 ]; }
) xs cfg.services.${s1}.connections
) base (builtins.attrNames base);
enabledServices = filterAttrs (n: v: isEnabled n) cfg.services;
isEnabled = x: config.services.${x}.enable;
ip = "${pkgs.iproute}/bin/ip";
iptables = "${config.networking.firewall.package}/bin/iptables";
bridgeIp = "169.254.${toString cfg.addressblock}.10";
mkCliExec = service: "exec netns-exec ${netns.${service}.netnsName}";
in {
options.nix-bitcoin.netns-isolation = { options.nix-bitcoin.netns-isolation = {
enable = mkEnableOption "netns isolation"; enable = mkEnableOption "netns isolation";
@ -92,6 +49,50 @@ in {
}; };
}; };
cfg = config.nix-bitcoin.netns-isolation;
netns = builtins.mapAttrs (n: v: {
inherit (v) id;
address = "169.254.${toString cfg.addressblock}.${toString v.id}";
availableNetns = availableNetns.${n};
netnsName = "nb-${n}";
}) enabledServices;
# Symmetric netns connection matrix
# if clightning.connections = [ "bitcoind" ]; then
# availableNetns.bitcoind = [ "clighting" ];
# and
# availableNetns.clighting = [ "bitcoind" ];
#
# FIXME: Although negligible for our purposes, this calculation's runtime
# is in the order of (number of connections * number of services),
# because attrsets and lists are fully copied on each update with '//' or '++'.
# This can only be improved with an update in the nix language.
#
availableNetns = let
# base = { clightning = [ "bitcoind" ]; ... }
base = builtins.mapAttrs (n: v:
builtins.filter isEnabled v.connections
) enabledServices;
in
foldl (xs: s1:
foldl (xs: s2:
xs // { "${s2}" = xs.${s2} ++ [ s1 ]; }
) xs cfg.services.${s1}.connections
) base (builtins.attrNames base);
enabledServices = filterAttrs (n: v: isEnabled n) cfg.services;
isEnabled = x: config.services.${x}.enable;
ip = "${pkgs.iproute}/bin/ip";
iptables = "${config.networking.firewall.package}/bin/iptables";
bridgeIp = "169.254.${toString cfg.addressblock}.10";
mkCliExec = service: "exec netns-exec ${netns.${service}.netnsName}";
in {
inherit options;
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
# Base infrastructure # Base infrastructure

View File

@ -2,6 +2,16 @@
with lib; with lib;
let let
options = {
nix-bitcoin.nodeinfo = {
enable = mkEnableOption "nodeinfo";
program = mkOption {
readOnly = true;
default = script;
};
};
};
cfg = config.nix-bitcoin.nodeinfo; cfg = config.nix-bitcoin.nodeinfo;
# Services included in the output # Services included in the output
@ -102,15 +112,7 @@ let
inherit (config.services.tor.relay) onionServices; inherit (config.services.tor.relay) onionServices;
in { in {
options = { inherit options;
nix-bitcoin.nodeinfo = {
enable = mkEnableOption "nodeinfo";
program = mkOption {
readOnly = true;
default = script;
};
};
};
config = { config = {
environment.systemPackages = optional cfg.enable script; environment.systemPackages = optional cfg.enable script;

View File

@ -7,11 +7,7 @@
{ config, lib, ... }: { config, lib, ... }:
with lib; with lib;
let let
cfg = config.nix-bitcoin.onionAddresses;
nbLib = config.nix-bitcoin.lib;
in {
options.nix-bitcoin.onionAddresses = { options.nix-bitcoin.onionAddresses = {
access = mkOption { access = mkOption {
type = with types; attrsOf (listOf str); type = with types; attrsOf (listOf str);
@ -42,6 +38,11 @@ in {
}; };
}; };
cfg = config.nix-bitcoin.onionAddresses;
nbLib = config.nix-bitcoin.lib;
in {
inherit options;
config = mkIf (cfg.access != {} || cfg.services != []) { config = mkIf (cfg.access != {} || cfg.services != []) {
systemd.services.onion-addresses = { systemd.services.onion-addresses = {
wantedBy = [ "tor.service" ]; wantedBy = [ "tor.service" ];

View File

@ -7,19 +7,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.nix-bitcoin.onionServices;
nbLib = config.nix-bitcoin.lib;
services = builtins.attrNames cfg;
activeServices = builtins.filter (service:
config.services.${service}.enable && cfg.${service}.enable
) services;
publicServices = builtins.filter (service: cfg.${service}.public) activeServices;
in {
options.nix-bitcoin.onionServices = mkOption { options.nix-bitcoin.onionServices = mkOption {
default = {}; default = {};
type = with types; attrsOf (submodule ( type = with types; attrsOf (submodule (
@ -52,6 +40,19 @@ in {
)); ));
}; };
cfg = config.nix-bitcoin.onionServices;
nbLib = config.nix-bitcoin.lib;
services = builtins.attrNames cfg;
activeServices = builtins.filter (service:
config.services.${service}.enable && cfg.${service}.enable
) services;
publicServices = builtins.filter (service: cfg.${service}.public) activeServices;
in {
inherit options;
config = mkMerge [ config = mkMerge [
(mkIf (cfg != {}) { (mkIf (cfg != {}) {
# Define hidden services # Define hidden services

View File

@ -4,12 +4,10 @@
# When using nix-bitcoin as part of a larger system config, set # When using nix-bitcoin as part of a larger system config, set
# `nix-bitcoin.operator.name` to your main user name. # `nix-bitcoin.operator.name` to your main user name.
{ config, lib, pkgs, options, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.nix-bitcoin.operator;
in {
options.nix-bitcoin.operator = { options.nix-bitcoin.operator = {
enable = mkEnableOption "operator user"; enable = mkEnableOption "operator user";
name = mkOption { name = mkOption {
@ -29,6 +27,10 @@ in {
}; };
}; };
cfg = config.nix-bitcoin.operator;
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
users.users.${cfg.name} = { users.users.${cfg.name} = {
isNormalUser = true; isNormalUser = true;

View File

@ -1,8 +1,39 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
options.services.recurring-donations = {
enable = mkEnableOption "recurring-donations";
tallycoin = mkOption {
type = types.attrs;
default = {};
description = ''
This option is used to specify tallycoin donation receivers using an
attribute set. For example the following setting instructs the module
to repeatedly send 1000 satoshis to djbooth007.
{
"djbooth007" = 1000;
}
'';
};
interval = mkOption {
type = types.str;
default = "Mon *-*-* 00:00:00";
description = ''
Schedules the donations. Default is weekly on Mon 00:00:00. See `man
systemd.time` for further options.
'';
};
randomizedDelaySec = mkOption {
type = types.int;
default = 86400;
description = ''
Random delay to add to scheduled time for donation. Default is one day.
'';
};
enforceTor = nbLib.enforceTor;
};
cfg = config.services.recurring-donations; cfg = config.services.recurring-donations;
nbLib = config.nix-bitcoin.lib; nbLib = config.nix-bitcoin.lib;
recurring-donations-script = pkgs.writeScript "recurring-donations.sh" '' recurring-donations-script = pkgs.writeScript "recurring-donations.sh" ''
@ -40,37 +71,7 @@ let
} }
''; '';
in { in {
options.services.recurring-donations = { inherit options;
enable = mkEnableOption "recurring-donations";
tallycoin = mkOption {
type = types.attrs;
default = {};
description = ''
This option is used to specify tallycoin donation receivers using an
attribute set. For example the following setting instructs the module
to repeatedly send 1000 satoshis to djbooth007.
{
"djbooth007" = 1000;
}
'';
};
interval = mkOption {
type = types.str;
default = "Mon *-*-* 00:00:00";
description = ''
Schedules the donations. Default is weekly on Mon 00:00:00. See `man
systemd.time` for further options.
'';
};
randomizedDelaySec = mkOption {
type = types.int;
default = 86400;
description = ''
Random delay to add to scheduled time for donation. Default is one day.
'';
};
enforceTor = nbLib.enforceTor;
};
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.clightning.enable = true; services.clightning.enable = true;

View File

@ -1,27 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
let let
cfg = config.services.spark-wallet;
nbLib = config.nix-bitcoin.lib;
# Use wasabi rate provider because the default (bitstamp) doesn't accept
# connections through Tor
torRateProvider = "--rate-provider wasabi --proxy socks5h://${config.nix-bitcoin.torClientAddressWithPort}";
startScript = ''
${optionalString (cfg.getPublicAddressCmd != "") ''
publicURL="--public-url http://$(${cfg.getPublicAddressCmd})"
''}
exec ${config.nix-bitcoin.pkgs.spark-wallet}/bin/spark-wallet \
--ln-path '${config.services.clightning.networkDir}' \
--host ${cfg.address} --port ${toString cfg.port} \
--config '${config.nix-bitcoin.secretsDir}/spark-wallet-login' \
${optionalString cfg.enforceTor torRateProvider} \
$publicURL \
--pairing-qr --print-key ${cfg.extraArgs}
'';
in {
options.services.spark-wallet = { options.services.spark-wallet = {
enable = mkEnableOption "spark-wallet"; enable = mkEnableOption "spark-wallet";
address = mkOption { address = mkOption {
@ -61,16 +41,32 @@ in {
inherit (nbLib) enforceTor; inherit (nbLib) enforceTor;
}; };
cfg = config.services.spark-wallet;
nbLib = config.nix-bitcoin.lib;
clightning = config.services.clightning;
# Use wasabi rate provider because the default (bitstamp) doesn't accept
# connections through Tor
torRateProvider = "--rate-provider wasabi --proxy socks5h://${config.nix-bitcoin.torClientAddressWithPort}";
startScript = ''
${optionalString (cfg.getPublicAddressCmd != "") ''
publicURL="--public-url http://$(${cfg.getPublicAddressCmd})"
''}
exec ${config.nix-bitcoin.pkgs.spark-wallet}/bin/spark-wallet \
--ln-path '${clightning.networkDir}' \
--host ${cfg.address} --port ${toString cfg.port} \
--config '${config.nix-bitcoin.secretsDir}/spark-wallet-login' \
${optionalString cfg.enforceTor torRateProvider} \
$publicURL \
--pairing-qr --print-key ${cfg.extraArgs}
'';
in {
inherit options;
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.clightning.enable = true; services.clightning.enable = true;
users.users.${cfg.user} = {
isSystemUser = true;
group = cfg.group;
extraGroups = [ config.services.clightning.group ];
};
users.groups.${cfg.group} = {};
systemd.services.spark-wallet = { systemd.services.spark-wallet = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
requires = [ "clightning.service" ]; requires = [ "clightning.service" ];
@ -84,6 +80,13 @@ in {
// nbLib.nodejs; // nbLib.nodejs;
}; };
users.users.${cfg.user} = {
isSystemUser = true;
group = cfg.group;
extraGroups = [ clightning.group ];
};
users.groups.${cfg.group} = {};
nix-bitcoin.secrets.spark-wallet-login.user = cfg.user; nix-bitcoin.secrets.spark-wallet-login.user = cfg.user;
nix-bitcoin.generateSecretsCmds.spark-wallet = '' nix-bitcoin.generateSecretsCmds.spark-wallet = ''
makePasswordSecret spark-wallet-password makePasswordSecret spark-wallet-password

View File

@ -7,6 +7,21 @@
with lib; with lib;
let let
options = {
nix-bitcoin.configVersion = mkOption {
type = with types; nullOr str;
default = null;
description = ''
Set this option to the nix-bitcoin release version that your config is
compatible with.
When upgrading to a backwards-incompatible release, nix-bitcoin will throw an
error during evaluation and provide hints for migrating your config to the
new release.
'';
};
};
version = config.nix-bitcoin.configVersion; version = config.nix-bitcoin.configVersion;
# Sorted by increasing version numbers # Sorted by increasing version numbers
@ -161,20 +176,7 @@ in
./obsolete-options.nix ./obsolete-options.nix
]; ];
options = { inherit options;
nix-bitcoin.configVersion = mkOption {
type = with types; nullOr str;
default = null;
description = ''
Set this option to the nix-bitcoin release version that your config is
compatible with.
When upgrading to a backwards-incompatible release, nix-bitcoin will throw an
error during evaluation and provide hints for migrating your config to the
new release.
'';
};
};
config = { config = {
# Force evaluation. An actual option value is never assigned # Force evaluation. An actual option value is never assigned