1 { config, lib, options, pkgs, ... }:
4 cfg = config.services.wasabibackend;
5 opt = options.services.wasabibackend;
7 inherit (lib) literalExpression mkEnableOption mkIf mkOption optionalAttrs optionalString types;
10 BitcoinRpcConnectionString = "${cfg.rpc.user}:${cfg.rpc.password}";
11 } // optionalAttrs (cfg.network == "mainnet") {
13 MainNetBitcoinP2pEndPoint = "${cfg.endpoint.ip}:${toString cfg.endpoint.port}";
14 MainNetBitcoinCoreRpcEndPoint = "${cfg.rpc.ip}:${toString cfg.rpc.port}";
15 } // optionalAttrs (cfg.network == "testnet") {
17 TestNetBitcoinP2pEndPoint = "${cfg.endpoint.ip}:${toString cfg.endpoint.port}";
18 TestNetBitcoinCoreRpcEndPoint = "${cfg.rpc.ip}:${toString cfg.rpc.port}";
19 } // optionalAttrs (cfg.network == "regtest") {
21 RegTestBitcoinP2pEndPoint = "${cfg.endpoint.ip}:${toString cfg.endpoint.port}";
22 RegTestBitcoinCoreRpcEndPoint = "${cfg.rpc.ip}:${toString cfg.rpc.port}";
25 configFile = pkgs.writeText "wasabibackend.conf" (builtins.toJSON confOptions);
31 services.wasabibackend = {
32 enable = mkEnableOption (lib.mdDoc "Wasabi backend service");
36 default = "/var/lib/wasabibackend";
37 description = lib.mdDoc "The data directory for the Wasabi backend node.";
40 customConfigFile = mkOption {
41 type = types.nullOr types.path;
43 description = lib.mdDoc "Defines the path to a custom configuration file that is copied to the user's directory. Overrides any config options.";
47 type = types.enum [ "mainnet" "testnet" "regtest" ];
49 description = lib.mdDoc "The network to use for the Wasabi backend service.";
55 default = "127.0.0.1";
56 description = lib.mdDoc "IP address for P2P connection to bitcoind.";
62 description = lib.mdDoc "Port for P2P connection to bitcoind.";
69 default = "127.0.0.1";
70 description = lib.mdDoc "IP address for RPC connection to bitcoind.";
76 description = lib.mdDoc "Port for RPC connection to bitcoind.";
82 description = lib.mdDoc "RPC user for the bitcoin endpoint.";
88 description = lib.mdDoc "RPC password for the bitcoin endpoint. Warning: this is stored in cleartext in the Nix store! Use `configFile` or `passwordFile` if needed.";
91 passwordFile = mkOption {
92 type = types.nullOr types.path;
94 description = lib.mdDoc "File that contains the password of the RPC user.";
100 default = "wasabibackend";
101 description = lib.mdDoc "The user as which to run the wasabibackend node.";
107 defaultText = literalExpression "config.${opt.user}";
108 description = lib.mdDoc "The group as which to run the wasabibackend node.";
113 config = mkIf cfg.enable {
115 systemd.tmpfiles.rules = [
116 "d '${cfg.dataDir}' 0770 '${cfg.user}' '${cfg.group}' - -"
119 systemd.services.wasabibackend = {
120 description = "wasabibackend server";
121 wantedBy = [ "multi-user.target" ];
122 after = [ "network-online.target" ];
124 DOTNET_PRINT_TELEMETRY_MESSAGE = "false";
125 DOTNET_CLI_TELEMETRY_OPTOUT = "true";
128 mkdir -p ${cfg.dataDir}/.walletwasabi/backend
129 ${if cfg.customConfigFile != null then ''
130 cp -v ${cfg.customConfigFile} ${cfg.dataDir}/.walletwasabi/backend/Config.json
132 cp -v ${configFile} ${cfg.dataDir}/.walletwasabi/backend/Config.json
133 ${optionalString (cfg.rpc.passwordFile != null) ''
135 cat ${cfg.dataDir}/.walletwasabi/backend/Config.json | ${pkgs.jq}/bin/jq --arg rpconnection "${cfg.rpc.user}:$(cat "${cfg.rpc.passwordFile}")" '. + { BitcoinRpcConnectionString: $rpconnection }' > $CONFIGTMP
136 mv $CONFIGTMP ${cfg.dataDir}/.walletwasabi/backend/Config.json
139 chmod ug+w ${cfg.dataDir}/.walletwasabi/backend/Config.json
144 ExecStart = "${pkgs.wasabibackend}/bin/WasabiBackend";
145 ProtectSystem = "full";
149 users.users.${cfg.user} = {
152 description = "wasabibackend daemon user";
157 users.groups.${cfg.group} = {};