1 { config, lib, pkgs, ... }:
4 cfg = config.services.monero;
6 listToConf = option: list:
7 lib.concatMapStrings (value: "${option}=${value}\n") list;
9 login = (cfg.rpc.user != null && cfg.rpc.password != null);
11 configFile = with cfg; pkgs.writeText "monero.conf" ''
15 ${lib.optionalString mining.enable ''
16 start-mining=${mining.address}
17 mining-threads=${toString mining.threads}
20 rpc-bind-ip=${rpc.address}
21 rpc-bind-port=${toString rpc.port}
22 ${lib.optionalString login ''
23 rpc-login=${rpc.user}:${rpc.password}
25 ${lib.optionalString rpc.restricted ''
29 limit-rate-up=${toString limits.upload}
30 limit-rate-down=${toString limits.download}
31 max-concurrency=${toString limits.threads}
32 block-sync-size=${toString limits.syncSize}
34 ${listToConf "add-peer" extraNodes}
35 ${listToConf "add-priority-node" priorityNodes}
36 ${listToConf "add-exclusive-node" exclusiveNodes}
51 enable = lib.mkEnableOption "Monero node daemon";
53 dataDir = lib.mkOption {
55 default = "/var/lib/monero";
57 The directory where Monero stores its data files.
61 mining.enable = lib.mkOption {
62 type = lib.types.bool;
65 Whether to mine monero.
69 mining.address = lib.mkOption {
73 Monero address where to send mining rewards.
77 mining.threads = lib.mkOption {
78 type = lib.types.addCheck lib.types.int (x: x>=0);
81 Number of threads used for mining.
82 Set to `0` to use all available.
86 rpc.user = lib.mkOption {
87 type = lib.types.nullOr lib.types.str;
90 User name for RPC connections.
94 rpc.password = lib.mkOption {
95 type = lib.types.nullOr lib.types.str;
98 Password for RPC connections.
102 rpc.address = lib.mkOption {
103 type = lib.types.str;
104 default = "127.0.0.1";
106 IP address the RPC server will bind to.
110 rpc.port = lib.mkOption {
111 type = lib.types.port;
114 Port the RPC server will bind to.
118 rpc.restricted = lib.mkOption {
119 type = lib.types.bool;
122 Whether to restrict RPC to view only commands.
126 limits.upload = lib.mkOption {
127 type = lib.types.addCheck lib.types.int (x: x>=-1);
130 Limit of the upload rate in kB/s.
131 Set to `-1` to leave unlimited.
135 limits.download = lib.mkOption {
136 type = lib.types.addCheck lib.types.int (x: x>=-1);
139 Limit of the download rate in kB/s.
140 Set to `-1` to leave unlimited.
144 limits.threads = lib.mkOption {
145 type = lib.types.addCheck lib.types.int (x: x>=0);
148 Maximum number of threads used for a parallel job.
149 Set to `0` to leave unlimited.
153 limits.syncSize = lib.mkOption {
154 type = lib.types.addCheck lib.types.int (x: x>=0);
157 Maximum number of blocks to sync at once.
158 Set to `0` for adaptive.
162 extraNodes = lib.mkOption {
163 type = lib.types.listOf lib.types.str;
166 List of additional peer IP addresses to add to the local list.
170 priorityNodes = lib.mkOption {
171 type = lib.types.listOf lib.types.str;
174 List of peer IP addresses to connect to and
175 attempt to keep the connection open.
179 exclusiveNodes = lib.mkOption {
180 type = lib.types.listOf lib.types.str;
183 List of peer IP addresses to connect to *only*.
184 If given the other peer options will be ignored.
188 extraConfig = lib.mkOption {
189 type = lib.types.lines;
192 Extra lines to be added verbatim to monerod configuration.
201 ###### implementation
203 config = lib.mkIf cfg.enable {
205 users.users.monero = {
208 description = "Monero daemon user";
213 users.groups.monero = { };
215 systemd.services.monero = {
216 description = "monero daemon";
217 after = [ "network.target" ];
218 wantedBy = [ "multi-user.target" ];
223 ExecStart = "${pkgs.monero-cli}/bin/monerod --config-file=${configFile} --non-interactive";
225 SuccessExitStatus = [ 0 1 ];
229 assertions = lib.singleton {
230 assertion = cfg.mining.enable -> cfg.mining.address != "";
232 You need a Monero address to receive mining rewards:
233 specify one using option monero.mining.address.
239 meta.maintainers = with lib.maintainers; [ rnhmjoj ];