1{ config, lib, pkgs, ... }:
2
3with lib;
4let
5 cfg = config.services.bee;
6 format = pkgs.formats.yaml {};
7 configFile = format.generate "bee.yaml" cfg.settings;
8in {
9 meta = {
10 # doc = ./bee.xml;
11 maintainers = with maintainers; [ attila-lendvai ];
12 };
13
14 ### interface
15
16 options = {
17 services.bee = {
18 enable = mkEnableOption (lib.mdDoc "Ethereum Swarm Bee");
19
20 package = mkOption {
21 type = types.package;
22 default = pkgs.bee;
23 defaultText = literalExpression "pkgs.bee";
24 example = literalExpression "pkgs.bee-unstable";
25 description = lib.mdDoc "The package providing the bee binary for the service.";
26 };
27
28 settings = mkOption {
29 type = format.type;
30 description = lib.mdDoc ''
31 Ethereum Swarm Bee configuration. Refer to
32 <https://gateway.ethswarm.org/bzz/docs.swarm.eth/docs/installation/configuration/>
33 for details on supported values.
34 '';
35 };
36
37 daemonNiceLevel = mkOption {
38 type = types.int;
39 default = 0;
40 description = lib.mdDoc ''
41 Daemon process priority for bee.
42 0 is the default Unix process priority, 19 is the lowest.
43 '';
44 };
45
46 user = mkOption {
47 type = types.str;
48 default = "bee";
49 description = lib.mdDoc ''
50 User the bee binary should execute under.
51 '';
52 };
53
54 group = mkOption {
55 type = types.str;
56 default = "bee";
57 description = lib.mdDoc ''
58 Group the bee binary should execute under.
59 '';
60 };
61 };
62 };
63
64 ### implementation
65
66 config = mkIf cfg.enable {
67 assertions = [
68 { assertion = (hasAttr "password" cfg.settings) != true;
69 message = ''
70 `services.bee.settings.password` is insecure. Use `services.bee.settings.password-file` or `systemd.services.bee.serviceConfig.EnvironmentFile` instead.
71 '';
72 }
73 { assertion = (hasAttr "swap-endpoint" cfg.settings) || (cfg.settings.swap-enable or true == false);
74 message = ''
75 In a swap-enabled network a working Ethereum blockchain node is required. You must specify one using `services.bee.settings.swap-endpoint`, or disable `services.bee.settings.swap-enable` = false.
76 '';
77 }
78 ];
79
80 warnings = optional (! config.services.bee-clef.enable) "The bee service requires an external signer. Consider setting `config.services.bee-clef.enable` = true";
81
82 services.bee.settings = {
83 data-dir = lib.mkDefault "/var/lib/bee";
84 password-file = lib.mkDefault "/var/lib/bee/password";
85 clef-signer-enable = lib.mkDefault true;
86 clef-signer-endpoint = lib.mkDefault "/var/lib/bee-clef/clef.ipc";
87 swap-endpoint = lib.mkDefault "https://rpc.slock.it/goerli";
88 };
89
90 systemd.packages = [ cfg.package ]; # include the upstream bee.service file
91
92 systemd.tmpfiles.rules = [
93 "d '${cfg.settings.data-dir}' 0750 ${cfg.user} ${cfg.group}"
94 ];
95
96 systemd.services.bee = {
97 requires = optional config.services.bee-clef.enable
98 "bee-clef.service";
99
100 wantedBy = [ "multi-user.target" ];
101
102 serviceConfig = {
103 Nice = cfg.daemonNiceLevel;
104 User = cfg.user;
105 Group = cfg.group;
106 ExecStart = [
107 "" # this hides/overrides what's in the original entry
108 "${cfg.package}/bin/bee --config=${configFile} start"
109 ];
110 };
111
112 preStart = with cfg.settings; ''
113 if ! test -f ${password-file}; then
114 < /dev/urandom tr -dc _A-Z-a-z-0-9 2> /dev/null | head -c32 > ${password-file}
115 chmod 0600 ${password-file}
116 echo "Initialized ${password-file} from /dev/urandom"
117 fi
118 if [ ! -f ${data-dir}/keys/libp2p.key ]; then
119 ${cfg.package}/bin/bee init --config=${configFile} >/dev/null
120 echo "
121Logs: journalctl -f -u bee.service
122
123Bee has SWAP enabled by default and it needs ethereum endpoint to operate.
124It is recommended to use external signer with bee.
125Check documentation for more info:
126- SWAP https://docs.ethswarm.org/docs/installation/manual#swap-bandwidth-incentives
127- External signer https://docs.ethswarm.org/docs/installation/bee-clef
128
129After you finish configuration run 'sudo bee-get-addr'."
130 fi
131 '';
132 };
133
134 users.users = optionalAttrs (cfg.user == "bee") {
135 bee = {
136 group = cfg.group;
137 home = cfg.settings.data-dir;
138 isSystemUser = true;
139 description = "Daemon user for Ethereum Swarm Bee";
140 extraGroups = optional config.services.bee-clef.enable
141 config.services.bee-clef.group;
142 };
143 };
144
145 users.groups = optionalAttrs (cfg.group == "bee") {
146 bee = {};
147 };
148 };
149}