aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix')
-rw-r--r--nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix275
1 files changed, 275 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix b/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix
new file mode 100644
index 00000000000..dde24522756
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix
@@ -0,0 +1,275 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ eachBlockbook = config.services.blockbook-frontend;
+
+ blockbookOpts = { config, lib, name, ...}: {
+
+ options = {
+
+ enable = mkEnableOption "blockbook-frontend application.";
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.blockbook;
+ description = "Which blockbook package to use.";
+ };
+
+ user = mkOption {
+ type = types.str;
+ default = "blockbook-frontend-${name}";
+ description = "The user as which to run blockbook-frontend-${name}.";
+ };
+
+ group = mkOption {
+ type = types.str;
+ default = "${config.user}";
+ description = "The group as which to run blockbook-frontend-${name}.";
+ };
+
+ certFile = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ example = "/etc/secrets/blockbook-frontend-${name}/certFile";
+ description = ''
+ To enable SSL, specify path to the name of certificate files without extension.
+ Expecting <filename>certFile.crt</filename> and <filename>certFile.key</filename>.
+ '';
+ };
+
+ configFile = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ example = "${config.dataDir}/config.json";
+ description = "Location of the blockbook configuration file.";
+ };
+
+ coinName = mkOption {
+ type = types.str;
+ default = "Bitcoin";
+ example = "Bitcoin";
+ description = ''
+ See <link xlink:href="https://github.com/trezor/blockbook/blob/master/bchain/coins/blockchain.go#L61"/>
+ for current of coins supported in master (Note: may differ from release).
+ '';
+ };
+
+ cssDir = mkOption {
+ type = types.path;
+ default = "${config.package}/share/css/";
+ example = "${config.dataDir}/static/css/";
+ description = ''
+ Location of the dir with <filename>main.css</filename> CSS file.
+ By default, the one shipped with the package is used.
+ '';
+ };
+
+ dataDir = mkOption {
+ type = types.path;
+ default = "/var/lib/blockbook-frontend-${name}";
+ description = "Location of blockbook-frontend-${name} data directory.";
+ };
+
+ debug = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Debug mode, return more verbose errors, reload templates on each request.";
+ };
+
+ internal = mkOption {
+ type = types.nullOr types.str;
+ default = ":9030";
+ example = ":9030";
+ description = "Internal http server binding <literal>[address]:port</literal>.";
+ };
+
+ messageQueueBinding = mkOption {
+ type = types.str;
+ default = "tcp://127.0.0.1:38330";
+ example = "tcp://127.0.0.1:38330";
+ description = "Message Queue Binding <literal>address:port</literal>.";
+ };
+
+ public = mkOption {
+ type = types.nullOr types.str;
+ default = ":9130";
+ example = ":9130";
+ description = "Public http server binding <literal>[address]:port</literal>.";
+ };
+
+ rpc = {
+ url = mkOption {
+ type = types.str;
+ default = "http://127.0.0.1";
+ description = "URL for JSON-RPC connections.";
+ };
+
+ port = mkOption {
+ type = types.port;
+ default = 8030;
+ description = "Port for JSON-RPC connections.";
+ };
+
+ user = mkOption {
+ type = types.str;
+ default = "rpc";
+ example = "rpc";
+ description = "Username for JSON-RPC connections.";
+ };
+
+ password = mkOption {
+ type = types.str;
+ default = "rpc";
+ example = "rpc";
+ description = ''
+ RPC password for JSON-RPC connections.
+ Warning: this is stored in cleartext in the Nix store!!!
+ Use <literal>configFile</literal> or <literal>passwordFile</literal> if needed.
+ '';
+ };
+
+ passwordFile = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ File containing password of the RPC user.
+ Note: This options is ignored when <literal>configFile</literal> is used.
+ '';
+ };
+ };
+
+ sync = mkOption {
+ type = types.bool;
+ default = true;
+ description = "Synchronizes until tip, if together with zeromq, keeps index synchronized.";
+ };
+
+ templateDir = mkOption {
+ type = types.path;
+ default = "${config.package}/share/templates/";
+ example = "${config.dataDir}/templates/static/";
+ description = "Location of the HTML templates. By default, ones shipped with the package are used.";
+ };
+
+ extraConfig = mkOption {
+ type = types.attrs;
+ default = {};
+ example = literalExample '' {
+ alternative_estimate_fee = "whatthefee-disabled";
+ alternative_estimate_fee_params = "{\"url\": \"https://whatthefee.io/data.json\", \"periodSeconds\": 60}";
+ fiat_rates = "coingecko";
+ fiat_rates_params = "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"bitcoin\", \"periodSeconds\": 60}";
+ coin_shortcut = "BTC";
+ coin_label = "Bitcoin";
+ xpub_magic = 76067358;
+ xpub_magic_segwit_p2sh = 77429938;
+ xpub_magic_segwit_native = 78792518;
+ }'';
+ description = ''
+ Additional configurations to be appended to <filename>coin.conf</filename>.
+ Overrides any already defined configuration options.
+ See <link xlink:href="https://github.com/trezor/blockbook/tree/master/configs/coins"/>
+ for current configuration options supported in master (Note: may differ from release).
+ '';
+ };
+
+ extraCmdLineOptions = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [ "-workers=1" "-dbcache=0" "-logtosderr" ];
+ description = ''
+ Extra command line options to pass to Blockbook.
+ Run blockbook --help to list all available options.
+ '';
+ };
+ };
+ };
+in
+{
+ # interface
+
+ options = {
+ services.blockbook-frontend = mkOption {
+ type = types.attrsOf (types.submodule blockbookOpts);
+ default = {};
+ description = "Specification of one or more blockbook-frontend instances.";
+ };
+ };
+
+ # implementation
+
+ config = mkIf (eachBlockbook != {}) {
+
+ systemd.services = mapAttrs' (blockbookName: cfg: (
+ nameValuePair "blockbook-frontend-${blockbookName}" (
+ let
+ configFile = if cfg.configFile != null then cfg.configFile else
+ pkgs.writeText "config.conf" (builtins.toJSON ( {
+ coin_name = "${cfg.coinName}";
+ rpc_user = "${cfg.rpc.user}";
+ rpc_pass = "${cfg.rpc.password}";
+ rpc_url = "${cfg.rpc.url}:${toString cfg.rpc.port}";
+ message_queue_binding = "${cfg.messageQueueBinding}";
+ } // cfg.extraConfig)
+ );
+ in {
+ description = "blockbook-frontend-${blockbookName} daemon";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ preStart = ''
+ ln -sf ${cfg.templateDir} ${cfg.dataDir}/static/
+ ln -sf ${cfg.cssDir} ${cfg.dataDir}/static/
+ ${optionalString (cfg.rpc.passwordFile != null && cfg.configFile == null) ''
+ CONFIGTMP=$(mktemp)
+ ${pkgs.jq}/bin/jq ".rpc_pass = \"$(cat ${cfg.rpc.passwordFile})\"" ${configFile} > $CONFIGTMP
+ mv $CONFIGTMP ${cfg.dataDir}/${blockbookName}-config.json
+ ''}
+ '';
+ serviceConfig = {
+ User = cfg.user;
+ Group = cfg.group;
+ ExecStart = ''
+ ${cfg.package}/bin/blockbook \
+ ${if (cfg.rpc.passwordFile != null && cfg.configFile == null) then
+ "-blockchaincfg=${cfg.dataDir}/${blockbookName}-config.json"
+ else
+ "-blockchaincfg=${configFile}"
+ } \
+ -datadir=${cfg.dataDir} \
+ ${optionalString (cfg.sync != false) "-sync"} \
+ ${optionalString (cfg.certFile != null) "-certfile=${toString cfg.certFile}"} \
+ ${optionalString (cfg.debug != false) "-debug"} \
+ ${optionalString (cfg.internal != null) "-internal=${toString cfg.internal}"} \
+ ${optionalString (cfg.public != null) "-public=${toString cfg.public}"} \
+ ${toString cfg.extraCmdLineOptions}
+ '';
+ Restart = "on-failure";
+ WorkingDirectory = cfg.dataDir;
+ LimitNOFILE = 65536;
+ };
+ }
+ ) )) eachBlockbook;
+
+ systemd.tmpfiles.rules = flatten (mapAttrsToList (blockbookName: cfg: [
+ "d ${cfg.dataDir} 0750 ${cfg.user} ${cfg.group} - -"
+ "d ${cfg.dataDir}/static 0750 ${cfg.user} ${cfg.group} - -"
+ ]) eachBlockbook);
+
+ users.users = mapAttrs' (blockbookName: cfg: (
+ nameValuePair "blockbook-frontend-${blockbookName}" {
+ name = cfg.user;
+ group = cfg.group;
+ home = cfg.dataDir;
+ isSystemUser = true;
+ })) eachBlockbook;
+
+ users.groups = mapAttrs' (instanceName: cfg: (
+ nameValuePair "${cfg.group}" { })) eachBlockbook;
+ };
+
+ meta.maintainers = with maintainers; [ _1000101 ];
+
+}