1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.bee;
9 format = pkgs.formats.yaml { };
10 configFile = format.generate "bee.yaml" cfg.settings;
11in
12{
13 meta = {
14 # doc = ./bee.xml;
15 maintainers = [ ];
16 };
17
18 ### interface
19
20 options = {
21 services.bee = {
22 enable = lib.mkEnableOption "Ethereum Swarm Bee";
23
24 package = lib.mkPackageOption pkgs "bee" {
25 example = "bee-unstable";
26 };
27
28 settings = lib.mkOption {
29 type = format.type;
30 description = ''
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 = lib.mkOption {
38 type = lib.types.int;
39 default = 0;
40 description = ''
41 Daemon process priority for bee.
42 0 is the default Unix process priority, 19 is the lowest.
43 '';
44 };
45
46 user = lib.mkOption {
47 type = lib.types.str;
48 default = "bee";
49 description = ''
50 User the bee binary should execute under.
51 '';
52 };
53
54 group = lib.mkOption {
55 type = lib.types.str;
56 default = "bee";
57 description = ''
58 Group the bee binary should execute under.
59 '';
60 };
61 };
62 };
63
64 ### implementation
65
66 config = lib.mkIf cfg.enable {
67 assertions = [
68 {
69 assertion = (lib.hasAttr "password" cfg.settings) != true;
70 message = ''
71 `services.bee.settings.password` is insecure. Use `services.bee.settings.password-file` or `systemd.services.bee.serviceConfig.EnvironmentFile` instead.
72 '';
73 }
74 {
75 assertion =
76 (lib.hasAttr "swap-endpoint" cfg.settings) || (cfg.settings.swap-enable or true == false);
77 message = ''
78 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.
79 '';
80 }
81 ];
82
83 services.bee.settings = {
84 data-dir = lib.mkDefault "/var/lib/bee";
85 password-file = lib.mkDefault "/var/lib/bee/password";
86 clef-signer-enable = lib.mkDefault true;
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 wantedBy = [ "multi-user.target" ];
98
99 serviceConfig = {
100 Nice = cfg.daemonNiceLevel;
101 User = cfg.user;
102 Group = cfg.group;
103 ExecStart = [
104 "" # this hides/overrides what's in the original entry
105 "${cfg.package}/bin/bee --config=${configFile} start"
106 ];
107 };
108
109 preStart = with cfg.settings; ''
110 if ! test -f ${password-file}; then
111 < /dev/urandom tr -dc _A-Z-a-z-0-9 2> /dev/null | head -c32 | install -m 600 /dev/stdin ${password-file}
112 echo "Initialized ${password-file} from /dev/urandom"
113 fi
114 if [ ! -f ${data-dir}/keys/libp2p.key ]; then
115 ${cfg.package}/bin/bee init --config=${configFile} >/dev/null
116 echo "
117 Logs: journalctl -f -u bee.service
118
119 Bee has SWAP enabled by default and it needs ethereum endpoint to operate.
120 It is recommended to use external signer with bee.
121 Check documentation for more info:
122 - SWAP https://docs.ethswarm.org/docs/installation/manual#swap-bandwidth-incentives
123
124 After you finish configuration run 'sudo bee-get-addr'."
125 fi
126 '';
127 };
128
129 users.users = lib.optionalAttrs (cfg.user == "bee") {
130 bee = {
131 group = cfg.group;
132 home = cfg.settings.data-dir;
133 isSystemUser = true;
134 description = "Daemon user for Ethereum Swarm Bee";
135 };
136 };
137
138 users.groups = lib.optionalAttrs (cfg.group == "bee") {
139 bee = { };
140 };
141 };
142}