diff --git a/configuration.nix b/configuration.nix index 1893db4..14adfbd 100644 --- a/configuration.nix +++ b/configuration.nix @@ -78,6 +78,15 @@ # "djbooth007" = 1000; # }; + ### Hardware wallets + # Enable this module to allow using hardware wallets. See https://github.com/bitcoin-core/HWI + # for more information. + # Ledger must be initialized through the official ledger live app and the Bitcoin app must + # be installed and running on the device. + # services.hardware-wallets.ledger = true; + # Trezor can be initialized with the trezorctl command in nix-bitcoin. + # services.hardware-wallets.trezor = true; + # FIXME: Define your hostname. networking.hostName = "nix-bitcoin"; time.timeZone = "UTC"; @@ -96,7 +105,6 @@ # FIXME: Add custom options (like boot options, output of # nixos-generate-config, etc.): - # If the hardened profile is imported above, we need to explicitly allow # user namespaces to enable sanboxed builds and services. security.allowUserNamespaces = true; diff --git a/default.nix b/default.nix index 518bd34..5f9a46b 100644 --- a/default.nix +++ b/default.nix @@ -11,4 +11,5 @@ spark-wallet = pkgs.callPackage ./pkgs/spark-wallet { }; electrs = pkgs.callPackage ./pkgs/electrs { }; liquidd = pkgs.callPackage ./pkgs/liquidd { }; + hwi = pkgs.callPackage ./pkgs/hwi { }; } diff --git a/modules/hardware-wallets.nix b/modules/hardware-wallets.nix new file mode 100644 index 0000000..738804a --- /dev/null +++ b/modules/hardware-wallets.nix @@ -0,0 +1,69 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.hardware-wallets; + dataDir = "/var/lib/hardware-wallets/"; + enabled = cfg.ledger || cfg.trezor; +in { + options.services.hardware-wallets = { + ledger = mkOption { + type = types.bool; + default = false; + description = '' + If enabled, the ledger udev rules will be installed. + ''; + }; + trezor = mkOption { + type = types.bool; + default = false; + description = '' + If enabled, the trezor udev rules will be installed. + ''; + }; + group = mkOption { + type = types.string; + default = "hardware-wallets"; + description = '' + Group the hardware wallet udev rules apply to. + ''; + }; + }; + + config = mkMerge [ + { + # Create group + users.groups."${cfg.group}" = {}; + } + (mkIf cfg.ledger { + # Ledger Nano S according to https://github.com/LedgerHQ/udev-rules/blob/master/add_udev_rules.sh + # Don't use rules from nixpkgs because we want to use our own group. + services.udev.packages = lib.singleton (pkgs.writeTextFile { + name = "ledger-udev-rules"; + destination = "/etc/udev/rules.d/20-ledger.rules"; + text = '' + SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0001", MODE="0660", GROUP="${cfg.group}" + ''; + }); + }) + (mkIf cfg.trezor { + # Don't use rules from nixpkgs because we want to use our own group. + services.udev.packages = lib.singleton (pkgs.writeTextFile { + name = "trezord-udev-rules"; + destination = "/etc/udev/rules.d/52-trezor.rules"; + text = '' + # TREZOR v1 (One) + SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0660", GROUP="${cfg.group}", TAG+="uaccess", SYMLINK+="trezor%n" + KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0660", GROUP="${cfg.group}", TAG+="uaccess" + + # TREZOR v2 (T) + SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c0", MODE="0660", GROUP="${cfg.group}", TAG+="uaccess", SYMLINK+="trezor%n" + SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c1", MODE="0660", GROUP="${cfg.group}", TAG+="uaccess", SYMLINK+="trezor%n" + KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", MODE="0660", GROUP="${cfg.group}", TAG+="uaccess" + ''; + }); + services.trezord.enable = true; + }) + ]; +} diff --git a/modules/nix-bitcoin.nix b/modules/nix-bitcoin.nix index a4779c4..58eeb6a 100644 --- a/modules/nix-bitcoin.nix +++ b/modules/nix-bitcoin.nix @@ -27,6 +27,7 @@ in { ./electrs.nix ./onion-chef.nix ./recurring-donations.nix + ./hardware-wallets.nix ]; options.services.nix-bitcoin = { @@ -98,7 +99,9 @@ in { isNormalUser = true; extraGroups = [ config.services.bitcoind.group ] ++ (if config.services.clightning.enable then [ "clightning" ] else [ ]) - ++ (if config.services.liquidd.enable then [ config.services.liquidd.group ] else [ ]); + ++ (if config.services.liquidd.enable then [ config.services.liquidd.group ] else [ ]) + ++ (if (config.services.hardware-wallets.ledger || config.services.hardware-wallets.trezor) + then [ config.services.hardware-wallets.group ] else [ ]); }; # Give operator access to onion hostnames services.onion-chef.enable = true; @@ -174,7 +177,15 @@ in { ++ optionals config.services.nix-bitcoin-webindex.enable [nginx] ++ optionals config.services.liquidd.enable [liquidd] ++ optionals config.services.spark-wallet.enable [spark-wallet] - ++ optionals config.services.electrs.enable [electrs]; + ++ optionals config.services.electrs.enable [electrs] + ++ optionals (config.services.hardware-wallets.ledger || config.services.hardware-wallets.trezor) [ + hwi + # To allow debugging issues with lsusb: + usbutils + ] + ++ optionals config.services.hardware-wallets.trezor [ + python35.pkgs.trezor + ]; }; } diff --git a/pkgs/hwi/default.nix b/pkgs/hwi/default.nix new file mode 100644 index 0000000..11d9d00 --- /dev/null +++ b/pkgs/hwi/default.nix @@ -0,0 +1,29 @@ +{ stdenv, fetchurl, fetchFromGitHub, python35 }: + +with stdenv.lib; +with python35.pkgs; + +let + buildInputs = [ mnemonic ecdsa typing-extensions hidapi libusb1 pyaes ]; +in +buildPythonPackage rec { + pname = "hwi"; + version = "1.0.0"; + + src = fetchFromGitHub { + owner = "bitcoin-core"; + repo = "HWI"; + rev = "4dd56fda3cd9cade8abc482e43e7733ddc8360a9"; + sha256 = "1xy2iq95b8a4cm9k5yzsi8lx1ha0dral3lhshbl1mfm1fi9ch3nk"; + }; + + # TODO: enable tests + doCheck = false; + + inherit buildInputs; + propagatedBuildInputs = buildInputs; + + meta = with lib; { + homepage = https://github.com/bitcoin-core/hwi; + }; +}