modules: move options to the top

This greatly improves readability and makes it easier to discover options.

This commit was genereated by running the following script inside the
repo root dir:

#!/usr/bin/env ruby

def transform(src)
  return false if src.include?('inherit options;')

  success = false

  options = nil
  src.sub!(/^  options.*?^  }.*?;/m) do |match|
    options = match
    "  inherit options;"
  end
  return false if !options

  src.sub!(/^with lib;\s*let\n+/m) do |match|
    success = true
    <<~EOF
      with lib;
      let
      #{options}

    EOF
  end

  success
end

Dir['modules/**/*.nix'].each do |f|
  src = File.read(f)
  if transform(src)
    puts "Changed file #{f}"
    File.write(f, src)
  end
end
This commit is contained in:
Erik Arvstedt 2021-09-13 13:40:47 +02:00
parent 731cf647ff
commit 27c45b82cc
No known key found for this signature in database
GPG Key ID: 33312B944DD97846
24 changed files with 609 additions and 578 deletions

View File

@ -1,40 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
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 = {
enable = mkEnableOption "Backups service";
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 {
environment.systemPackages = [ pkgs.duplicity ];

View File

@ -1,63 +1,7 @@
{ config, pkgs, lib, ... }:
with lib;
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 = {
services.bitcoind = {
enable = mkEnableOption "Bitcoin daemon";
@ -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 {
environment.systemPackages = [ cfg.package (hiPrio cfg.cli) ];

View File

@ -1,12 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
in {
options.services = {
nbxplorer = {
package = mkOption {
@ -102,6 +97,12 @@ in {
};
};
cfg = config.services;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
in {
inherit options;
config = mkIf cfg.btcpayserver.enable {
services.bitcoind.enable = true;
services.clightning.enable = mkIf (cfg.btcpayserver.lightningBackend == "clightning") true;

View File

@ -1,26 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
let
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
{
options.services.charge-lnd = with types; {
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 {
services.lnd = {
enable = true;

View File

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

View File

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

View File

@ -1,25 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
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 = {
enable = mkEnableOption "clightning";
address = mkOption {
@ -91,6 +73,25 @@ in {
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 {
services.bitcoind = {
enable = true;

View File

@ -2,11 +2,6 @@
with lib;
let
cfg = config.services.electrs;
nbLib = config.nix-bitcoin.lib;
secretsDir = config.nix-bitcoin.secretsDir;
bitcoind = config.services.bitcoind;
in {
options.services.electrs = {
enable = mkEnableOption "electrs";
address = mkOption {
@ -54,6 +49,13 @@ in {
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 {
assertions = [
{ assertion = bitcoind.prune == 0;

View File

@ -1,12 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.hardware-wallets;
dataDir = "/var/lib/hardware-wallets/";
enabled = cfg.ledger || cfg.trezor;
in {
options.services.hardware-wallets = {
ledger = mkOption {
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 [
(mkIf (cfg.ledger || cfg.trezor) {
assertions = [

View File

@ -2,6 +2,40 @@
with lib;
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;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
@ -39,39 +73,7 @@ let
${socks5Settings}
'';
in {
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;
};
};
inherit options;
config = mkIf cfg.enable {
services.bitcoind.rpc.users.joinmarket-ob-watcher = {

View File

@ -1,8 +1,102 @@
{ config, lib, pkgs, ... }:
with lib;
let
options.services.joinmarket = {
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
'';
};
};
};
cfg = config.services.joinmarket;
nbLib = config.nix-bitcoin.lib;
nbPkgs = config.nix-bitcoin.pkgs;
@ -114,100 +208,7 @@ let
chmod -R +x $out/bin
'';
in {
options.services.joinmarket = {
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
'';
};
};
};
inherit options;
config = mkIf cfg.enable (mkMerge [{
services.bitcoind = {

View File

@ -1,34 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
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 = {
enable = mkEnableOption "lightning-loop";
rpcAddress = mkOption {
@ -86,6 +59,34 @@ in {
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 {
services.lnd.enable = true;

View File

@ -1,27 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
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 = {
enable = mkEnableOption "lightning-pool";
rpcAddress = mkOption {
@ -79,6 +59,27 @@ in {
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 {
services.lnd.enable = true;

View File

@ -1,73 +1,7 @@
{ config, pkgs, lib, ... }:
with lib;
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 = {
services.liquidd = {
@ -203,6 +137,73 @@ in {
};
};
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 {
inherit options;
config = mkIf cfg.enable {
services.bitcoind.enable = true;

View File

@ -1,24 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
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 = {
enable = mkOption {
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 {
services.tor = {
enable = true;

View File

@ -1,42 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
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 = {
enable = mkEnableOption "Lightning Network Daemon";
dataDir = mkOption {
@ -157,6 +122,42 @@ in {
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.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 {
inherit options;
config = mkIf cfg.enable {
assertions = [
{ assertion = bitcoind.prune == 0;

View File

@ -1,50 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
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 = {
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 [
# Base infrastructure

View File

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

View File

@ -7,11 +7,7 @@
{ config, lib, ... }:
with lib;
let
cfg = config.nix-bitcoin.onionAddresses;
nbLib = config.nix-bitcoin.lib;
in {
options.nix-bitcoin.onionAddresses = {
access = mkOption {
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 != []) {
systemd.services.onion-addresses = {
wantedBy = [ "tor.service" ];

View File

@ -7,19 +7,7 @@
{ config, lib, pkgs, ... }:
with lib;
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 {
default = {};
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 [
(mkIf (cfg != {}) {
# Define hidden services

View File

@ -8,8 +8,6 @@
with lib;
let
cfg = config.nix-bitcoin.operator;
in {
options.nix-bitcoin.operator = {
enable = mkEnableOption "operator user";
name = mkOption {
@ -29,6 +27,10 @@ in {
};
};
cfg = config.nix-bitcoin.operator;
in {
inherit options;
config = mkIf cfg.enable {
users.users.${cfg.name} = {
isNormalUser = true;

View File

@ -1,8 +1,39 @@
{ config, lib, pkgs, ... }:
with lib;
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;
nbLib = config.nix-bitcoin.lib;
recurring-donations-script = pkgs.writeScript "recurring-donations.sh" ''
@ -40,37 +71,7 @@ let
}
'';
in {
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;
};
inherit options;
config = mkIf cfg.enable {
services.clightning.enable = true;

View File

@ -1,27 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
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 = {
enable = mkEnableOption "spark-wallet";
address = mkOption {
@ -61,6 +41,27 @@ in {
inherit (nbLib) enforceTor;
};
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 {
inherit options;
config = mkIf cfg.enable {
services.clightning.enable = true;

View File

@ -7,6 +7,21 @@
with lib;
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;
# Sorted by increasing version numbers
@ -161,20 +176,7 @@ in
./obsolete-options.nix
];
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.
'';
};
};
inherit options;
config = {
# Force evaluation. An actual option value is never assigned