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