at 23.11-pre 5.4 kB view raw
1{ config, lib, options, pkgs, ... }: 2 3let 4 cfg = config.services.wasabibackend; 5 opt = options.services.wasabibackend; 6 7 inherit (lib) literalExpression mkEnableOption mkIf mkOption optionalAttrs optionalString types; 8 9 confOptions = { 10 BitcoinRpcConnectionString = "${cfg.rpc.user}:${cfg.rpc.password}"; 11 } // optionalAttrs (cfg.network == "mainnet") { 12 Network = "Main"; 13 MainNetBitcoinP2pEndPoint = "${cfg.endpoint.ip}:${toString cfg.endpoint.port}"; 14 MainNetBitcoinCoreRpcEndPoint = "${cfg.rpc.ip}:${toString cfg.rpc.port}"; 15 } // optionalAttrs (cfg.network == "testnet") { 16 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") { 20 Network = "RegTest"; 21 RegTestBitcoinP2pEndPoint = "${cfg.endpoint.ip}:${toString cfg.endpoint.port}"; 22 RegTestBitcoinCoreRpcEndPoint = "${cfg.rpc.ip}:${toString cfg.rpc.port}"; 23 }; 24 25 configFile = pkgs.writeText "wasabibackend.conf" (builtins.toJSON confOptions); 26 27in { 28 29 options = { 30 31 services.wasabibackend = { 32 enable = mkEnableOption (lib.mdDoc "Wasabi backend service"); 33 34 dataDir = mkOption { 35 type = types.path; 36 default = "/var/lib/wasabibackend"; 37 description = lib.mdDoc "The data directory for the Wasabi backend node."; 38 }; 39 40 customConfigFile = mkOption { 41 type = types.nullOr types.path; 42 default = null; 43 description = lib.mdDoc "Defines the path to a custom configuration file that is copied to the user's directory. Overrides any config options."; 44 }; 45 46 network = mkOption { 47 type = types.enum [ "mainnet" "testnet" "regtest" ]; 48 default = "mainnet"; 49 description = lib.mdDoc "The network to use for the Wasabi backend service."; 50 }; 51 52 endpoint = { 53 ip = mkOption { 54 type = types.str; 55 default = "127.0.0.1"; 56 description = lib.mdDoc "IP address for P2P connection to bitcoind."; 57 }; 58 59 port = mkOption { 60 type = types.port; 61 default = 8333; 62 description = lib.mdDoc "Port for P2P connection to bitcoind."; 63 }; 64 }; 65 66 rpc = { 67 ip = mkOption { 68 type = types.str; 69 default = "127.0.0.1"; 70 description = lib.mdDoc "IP address for RPC connection to bitcoind."; 71 }; 72 73 port = mkOption { 74 type = types.port; 75 default = 8332; 76 description = lib.mdDoc "Port for RPC connection to bitcoind."; 77 }; 78 79 user = mkOption { 80 type = types.str; 81 default = "bitcoin"; 82 description = lib.mdDoc "RPC user for the bitcoin endpoint."; 83 }; 84 85 password = mkOption { 86 type = types.str; 87 default = "password"; 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."; 89 }; 90 91 passwordFile = mkOption { 92 type = types.nullOr types.path; 93 default = null; 94 description = lib.mdDoc "File that contains the password of the RPC user."; 95 }; 96 }; 97 98 user = mkOption { 99 type = types.str; 100 default = "wasabibackend"; 101 description = lib.mdDoc "The user as which to run the wasabibackend node."; 102 }; 103 104 group = mkOption { 105 type = types.str; 106 default = cfg.user; 107 defaultText = literalExpression "config.${opt.user}"; 108 description = lib.mdDoc "The group as which to run the wasabibackend node."; 109 }; 110 }; 111 }; 112 113 config = mkIf cfg.enable { 114 115 systemd.tmpfiles.rules = [ 116 "d '${cfg.dataDir}' 0770 '${cfg.user}' '${cfg.group}' - -" 117 ]; 118 119 systemd.services.wasabibackend = { 120 description = "wasabibackend server"; 121 wantedBy = [ "multi-user.target" ]; 122 after = [ "network-online.target" ]; 123 environment = { 124 DOTNET_PRINT_TELEMETRY_MESSAGE = "false"; 125 DOTNET_CLI_TELEMETRY_OPTOUT = "true"; 126 }; 127 preStart = '' 128 mkdir -p ${cfg.dataDir}/.walletwasabi/backend 129 ${if cfg.customConfigFile != null then '' 130 cp -v ${cfg.customConfigFile} ${cfg.dataDir}/.walletwasabi/backend/Config.json 131 '' else '' 132 cp -v ${configFile} ${cfg.dataDir}/.walletwasabi/backend/Config.json 133 ${optionalString (cfg.rpc.passwordFile != null) '' 134 CONFIGTMP=$(mktemp) 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 137 ''} 138 ''} 139 chmod ug+w ${cfg.dataDir}/.walletwasabi/backend/Config.json 140 ''; 141 serviceConfig = { 142 User = cfg.user; 143 Group = cfg.group; 144 ExecStart = "${pkgs.wasabibackend}/bin/WasabiBackend"; 145 ProtectSystem = "full"; 146 }; 147 }; 148 149 users.users.${cfg.user} = { 150 name = cfg.user; 151 group = cfg.group; 152 description = "wasabibackend daemon user"; 153 home = cfg.dataDir; 154 isSystemUser = true; 155 }; 156 157 users.groups.${cfg.group} = {}; 158 159 }; 160}