From ffaf86429ad799fd70235c6e9e5cfacb06ea21c1 Mon Sep 17 00:00:00 2001 From: Maurice Poirrier Chuden Date: Mon, 14 Apr 2025 14:58:32 -0400 Subject: [PATCH] chore: add simple nix flake adds a simple flake.nix file for nix users to use LNDK in their nix setup and also help with dependencies in development --- .github/workflows/main.yml | 33 ++++++-- .gitignore | 4 + README.md | 24 ++++++ flake.lock | 150 ++++++++++++++++++++++++++++++++++++ flake.nix | 70 +++++++++++++++++ nix/bitcoin.nix | 11 +++ nix/checks/flake-module.nix | 31 ++++++++ nix/pkgs/flake-module.nix | 20 +++++ nix/pkgs/rust.nix | 51 ++++++++++++ nix/shells.nix | 41 ++++++++++ nix/treefmt.nix | 12 +++ 11 files changed, 442 insertions(+), 5 deletions(-) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix/bitcoin.nix create mode 100644 nix/checks/flake-module.nix create mode 100644 nix/pkgs/flake-module.nix create mode 100644 nix/pkgs/rust.nix create mode 100644 nix/shells.nix create mode 100644 nix/treefmt.nix diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1943fa9..f0a8d84 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: ['master'] + branches: ["master"] pull_request: - branches: ['*'] + branches: ["*"] env: GO_VERSION: 1.21.0 @@ -30,15 +30,15 @@ jobs: steps: - uses: actions/checkout@v4 with: - submodules: 'true' + submodules: "true" - uses: dtolnay/rust-toolchain@stable - run: sudo apt-get install protobuf-compiler - name: setup go ${{ env.GO_VERSION }} uses: lightningnetwork/lnd/.github/actions/setup-go@v0-16-4-branch with: - go-version: '${{ env.GO_VERSION }}' + go-version: "${{ env.GO_VERSION }}" - name: run unit tests - run: cargo test --bin lndk + run: cargo test --bin lndk - name: run cli unit tests run: cargo test --bin lndk-cli - name: run integration tests @@ -63,3 +63,26 @@ jobs: files: lcov.info fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} + + check-flake: + name: Check Nix Flake + runs-on: ubuntu-latest + env: + FNAME: bitcoin-22.1-x86_64-linux-gnu.tar.gz + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: "recursive" + + - name: Check Nix flake inputs + uses: DeterminateSystems/flake-checker-action@v8 + + - name: Install Nix + uses: cachix/install-nix-action@V27 + with: + nix_path: nixpkgs=channel:nixos-24.05 + - run: echo "BITCOIND_TARBALL_FILE=./${FNAME}" >> $GITHUB_ENV + - run: wget -q https://bitcoincore.org/bin/bitcoin-core-22.1/${FNAME} + - name: Check flake (excluding integration tests) + run: BITCOIND_TARBALL_FILE=./${FNAME} nix flake check --impure diff --git a/.gitignore b/.gitignore index 6b20d96..0363bc1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ /target lndk.conf* /.vscode + +# Ignore nix outputs +result +result-[0-9]* diff --git a/README.md b/README.md index 41771f0..202cb23 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,30 @@ Rather than use the admin.macaroon with unrestricted permission to an `LND` node lncli bakemacaroon --save_to=/lndk.macaroon uri:/lnrpc.Lightning/GetInfo uri:/lnrpc.Lightning/ListPeers uri:/lnrpc.Lightning/SubscribePeerEvents uri:/lnrpc.Lightning/SendCustomMessage uri:/lnrpc.Lightning/SubscribeCustomMessages uri:/peersrpc.Peers/UpdateNodeAnnouncement uri:/signrpc.Signer/DeriveSharedKey uri:/verrpc.Versioner/GetVersion ``` +### Using Nix + +Nix is a package manager for Unix systems that makes package management reliable and reproducible. + +To use LNDK on Nix you first need to install [Nix](https://nixos.org/download/). + +Then you have few options to run or develop LNDK: + +`nix develop` will open a shell with all the dependencies needed to run LNDK and itests. +`nix flake check` will run all the checks defined in the flake. Also runs cargo audit and formatting checks. + + +#### Running Integration Tests + +Integration tests require building an LND binary. You can use Nix to provide a complete environment with all dependencies needed for the tests: + +``` +nix develop +make itest +``` + +The integration tests must be run from within the Git repository. The script will handle building LND from source and running the tests with the correct environment variables. + + ## Security NOTE: It is recommended to always use [cargo-crev](https://github.com/crev-dev/cargo-crev) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..7f89359 --- /dev/null +++ b/flake.lock @@ -0,0 +1,150 @@ +{ + "nodes": { + "advisory-db": { + "flake": false, + "locked": { + "lastModified": 1744288177, + "narHash": "sha256-HxYhdWc6YJ8Q8gOZtv7+teCucmDf6+Ntickvb62Au58=", + "owner": "rustsec", + "repo": "advisory-db", + "rev": "1273f0099ce6882659ff64b852c8fdb5f8cdd5b9", + "type": "github" + }, + "original": { + "owner": "rustsec", + "repo": "advisory-db", + "type": "github" + } + }, + "crane": { + "locked": { + "lastModified": 1744386647, + "narHash": "sha256-DXwQEJllxpYeVOiSlBhQuGjfvkoGHTtILLYO2FvcyzQ=", + "owner": "ipetkov", + "repo": "crane", + "rev": "d02c1cdd7ec539699aa44e6ff912e15535969803", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1744440957, + "narHash": "sha256-FHlSkNqFmPxPJvy+6fNLaNeWnF1lZSgqVCl/eWaJRc4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "26d499fc9f1d567283d5d56fcf367edd815dba1d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1743296961, + "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1735554305, + "narHash": "sha256-zExSA1i/b+1NMRhGGLtNfFGXgLtgo+dcuzHzaWA6w3Q=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "0e82ab234249d8eee3e8c91437802b32c74bb3fd", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "advisory-db": "advisory-db", + "crane": "crane", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay", + "treefmt-nix": "treefmt-nix" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744684506, + "narHash": "sha256-pDPDMT1rdkTWi8MIoZ67gT3L817R7P0Jo+PP+BrnyJI=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "47beae969336c05e892e1e4a9dbaac9593de34ab", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1743748085, + "narHash": "sha256-uhjnlaVTWo5iD3LXics1rp9gaKgDRQj6660+gbUU3cE=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "815e4121d6a5d504c0f96e5be2dd7f871e4fd99d", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..4c54f7d --- /dev/null +++ b/flake.nix @@ -0,0 +1,70 @@ +{ + description = "LNDK: Standalone deamon that connects to LND that implements bolt12 funtionallities"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; + + flake-parts.url = "github:hercules-ci/flake-parts"; + + crane.url = "github:ipetkov/crane"; + + treefmt-nix.url = "github:numtide/treefmt-nix"; + + advisory-db = { + url = "github:rustsec/advisory-db"; + flake = false; + }; + + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + inputs@{ + self, + nixpkgs, + flake-parts, + rust-overlay, + crane, + ... + }: + flake-parts.lib.mkFlake + { + inherit inputs; + specialArgs = { inherit crane; }; + } + { + systems = nixpkgs.lib.systems.flakeExposed; + imports = [ + inputs.treefmt-nix.flakeModule + ./nix/pkgs/flake-module.nix + ./nix/checks/flake-module.nix + ./nix/shells.nix + ./nix/treefmt.nix + ]; + perSystem = + { + config, + pkgs, + self', + system, + ... + }: + { + _module.args.pkgs = import inputs.nixpkgs { + inherit system; + overlays = [ (import rust-overlay) ]; + }; + apps = { + lndk = { + program = "${self'.packages.lndk}/bin/lndk"; + }; + lndk-cli = { + program = "${self'.packages.lndk}/bin/lndk-cli"; + }; + }; + }; + }; +} diff --git a/nix/bitcoin.nix b/nix/bitcoin.nix new file mode 100644 index 0000000..d9084a2 --- /dev/null +++ b/nix/bitcoin.nix @@ -0,0 +1,11 @@ +{ system, pkgs }: +let + pkgs_bitcoind = import (builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/21808d22b1cda1898b71cf1a1beb524a97add2c4.tar.gz"; + # Bitcoin Core 28.1 + sha256 = "0v2z6jphhbk1ik7fqhlfnihcyff5np9wb3pv19j9qb9mpildx0cg"; + }) { inherit system; }; +in +{ + bitcoind = pkgs_bitcoind.bitcoind; +} diff --git a/nix/checks/flake-module.nix b/nix/checks/flake-module.nix new file mode 100644 index 0000000..55a3c77 --- /dev/null +++ b/nix/checks/flake-module.nix @@ -0,0 +1,31 @@ +{ + inputs, + self, + crane, + ... +}: +{ + perSystem = + { + pkgs, + config, + system, + ... + }: + let + rustToolchainFile = builtins.fromTOML (builtins.readFile ../../rust-toolchain.toml); + rustChannel = rustToolchainFile.toolchain.channel; + craneLib = (crane.mkLib pkgs).overrideToolchain (pkgs.rust-bin.stable.${rustChannel}.default); + advisory-db = inputs.advisory-db; + in + { + checks = { + lndk = config.packages.rust; + cargo-audit = craneLib.cargoAudit { + src = ../../.; + inherit advisory-db; + }; + formatting = config.treefmt.build.check self; + }; + }; +} diff --git a/nix/pkgs/flake-module.nix b/nix/pkgs/flake-module.nix new file mode 100644 index 0000000..28cbcda --- /dev/null +++ b/nix/pkgs/flake-module.nix @@ -0,0 +1,20 @@ +{ + self, + inputs, + crane, + ... +}: +{ + perSystem = + { system, pkgs, ... }: + let + rustPackages = import ./rust.nix { inherit pkgs inputs crane; }; + in + { + packages = { + inherit (rustPackages) rust; + lndk = rustPackages.rust; # Alias for consistency + default = rustPackages.rust; + }; + }; +} diff --git a/nix/pkgs/rust.nix b/nix/pkgs/rust.nix new file mode 100644 index 0000000..cd23a8a --- /dev/null +++ b/nix/pkgs/rust.nix @@ -0,0 +1,51 @@ +{ + pkgs, + inputs, + crane, + ... +}: + +let + inherit (pkgs) lib stdenv; + src = ../../.; + rustToolchainFile = builtins.fromTOML (builtins.readFile ../../rust-toolchain.toml); + rustChannel = rustToolchainFile.toolchain.channel; + craneLib = (crane.mkLib pkgs).overrideToolchain (pkgs.rust-bin.stable.${rustChannel}.default); + commonDeps = { + nativeBuildInputs = with pkgs; [ + pkg-config + protobuf + ]; + + buildInputs = with pkgs; [ + openssl + ]; + }; + + cargoArtifacts = craneLib.buildDepsOnly { + inherit src; + pname = "lndk-deps"; + inherit (commonDeps) nativeBuildInputs buildInputs; + }; + + basePkg = { + inherit src cargoArtifacts; + inherit (commonDeps) nativeBuildInputs buildInputs; + + meta = with lib; { + description = "Standalone daemon that connects to LND to implement bolt12 functionalities"; + homepage = "https://github.com/lndk-org/lndk"; + license = licenses.mit; + platforms = platforms.linux ++ platforms.darwin; + }; + }; + + lndkPkg = craneLib.buildPackage ( + basePkg + // { + pname = "lndk"; + +in +{ + rust = lndkPkg; +} diff --git a/nix/shells.nix b/nix/shells.nix new file mode 100644 index 0000000..c776a41 --- /dev/null +++ b/nix/shells.nix @@ -0,0 +1,41 @@ +{ self, crane, ... }: +{ + perSystem = + { + config, + pkgs, + system, + ... + }: + let + rustToolchainFile = builtins.fromTOML (builtins.readFile ../rust-toolchain.toml); + rustChannel = rustToolchainFile.toolchain.channel; + bitcoinPkgs = import ./bitcoin.nix { inherit system pkgs; }; + in + { + devShells = { + default = pkgs.mkShell { + packages = [ + pkgs.rust-bin.stable.${rustChannel}.rust-analyzer + bitcoinPkgs.bitcoind + ]; + + nativeBuildInputs = with pkgs; [ + pkg-config + protobuf + openssl + openssl.dev + rust-bin.stable.${rustChannel}.default + go + git + ]; + + shellHook = '' + echo "LNDK development environment loaded with Rust toolchain $(rustc --version)" + export BITCOIND_EXE="${bitcoinPkgs.bitcoind}/bin/bitcoind" + export BITCOIND_SKIP_DOWNLOAD="TRUE" + ''; + }; + }; + }; +} diff --git a/nix/treefmt.nix b/nix/treefmt.nix new file mode 100644 index 0000000..a45cdd3 --- /dev/null +++ b/nix/treefmt.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + perSystem = + { pkgs, lib, ... }: + { + treefmt = { + projectRootFile = "flake.nix"; + programs.nixfmt.enable = true; + programs.rustfmt.enable = true; + }; + }; +}