diff --git a/.github/workflows/auto-update.yml b/.github/workflows/auto-update.yml index c35748e..eaa3932 100644 --- a/.github/workflows/auto-update.yml +++ b/.github/workflows/auto-update.yml @@ -53,7 +53,7 @@ jobs: # Only packages with an upstream to track. vcrunch and zelda-oot # are local-only (src = ./. / writeShellScriptBin) — no version # concept beyond what Chief stamps manually. - for pkg in brush-shell brave-origin antigravity-cli proton-drive-cli; do + for pkg in brave-origin antigravity-cli proton-drive-cli; do echo "::group::update $pkg" def="pkgs/$pkg/default.nix" before=$(grep -oE "version = \"[^\"]+\"" "$def" | head -n1 | sed "s/version = \"//; s/\"\$//") @@ -62,13 +62,6 @@ jobs: "pkgs/$pkg/update.sh" rc=$? tool="update.sh" - elif [[ "$pkg" == "brush-shell" ]]; then - # brush-shell tracks the upstream default branch (nightly), - # not tagged releases. --version=branch grabs the newest - # commit and stamps a "-unstable-" version. - nix-update --flake "$pkg" --version=branch --build - rc=$? - tool="nix-update (branch)" else nix-update --flake "$pkg" --build rc=$? diff --git a/README.md b/README.md index b3082cc..8c8910f 100644 --- a/README.md +++ b/README.md @@ -2,26 +2,41 @@ Personal Nix package collection. -## How to Update +## Packages -### Rust Packages (brush-shell) -These use `buildRustPackage` and need a `cargoHash`. +| Package | Platforms | Auto-update | +|--------------------|-------------------------------|-------------| +| `proton-drive-cli` | linux, darwin (x64 + arm64) | `update.sh` | +| `pd` | linux, darwin | manual | +| `sparrow` | linux (x64 + arm64) | planned | +| `antigravity-cli` | linux, darwin | nix-update | +| `brave-origin` | linux | nix-update | +| `vcrunch` | linux | manual | +| `zelda-oot` | linux | manual | +| `flashgbx` | linux | manual | +| `opengigabyte` | linux | manual | -1. Update `rev` and `shortRev` (if used) to latest commit. -2. Update `hash` (source hash): - - Run: `nix shell nixpkgs#nix-prefetch-github -c nix-prefetch-github --rev ` -3. Update `cargoHash`: - - Set `cargoHash = lib.fakeHash;` (or many zeros). - - Run: `nix-build -E 'with import {}; callPackage ./pkgs//default.nix {}'` - - Copy "got" hash from error message into `default.nix`. -4. Verify build: `nix-build -E 'with import {}; callPackage ./pkgs//default.nix {}'` +## Usage -### Other Packages (vcrunch, brave-origin) -Usually just need `rev` and `hash` updates. +```bash +# Try a package without installing +nix run github:izaac/nix-packages#pd -1. Update `rev`. -2. Update source `hash` using `nix-prefetch-url` or `nix-prefetch-github`. -3. Verify build same as above. +# Use as flake input +inputs.nix-packages.url = "github:izaac/nix-packages"; +``` + +## Updating Packages + +Packages with `update.sh` scripts auto-update via the weekly GitHub Actions workflow. +For others, use `nix-update`: + +```bash +nix-update --flake --build +``` ## Verification -Always run `nix-build` before committing. + +```bash +nix flake check +``` diff --git a/flake.nix b/flake.nix index cef4c9c..8f1ba29 100644 --- a/flake.nix +++ b/flake.nix @@ -41,10 +41,10 @@ linuxOnly = lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { vcrunch = pkgs.callPackage ./pkgs/vcrunch {}; zelda-oot = pkgs.callPackage ./pkgs/zelda-oot {}; - brush-shell = pkgs.callPackage ./pkgs/brush-shell {}; brave-origin = pkgs.callPackage ./pkgs/brave-origin {}; flashgbx = pkgs.callPackage ./pkgs/flashgbx {}; opengigabyte = pkgs.linuxPackages_latest.callPackage ./pkgs/opengigabyte {}; + sparrow = pkgs.callPackage ./pkgs/sparrow {}; }; in linuxOnly @@ -68,10 +68,10 @@ linuxOnly = lib.optionalAttrs final.stdenv.hostPlatform.isLinux { izaac-vcrunch = final.callPackage ./pkgs/vcrunch {}; izaac-zelda-oot = final.callPackage ./pkgs/zelda-oot {}; - izaac-brush-shell = final.callPackage ./pkgs/brush-shell {}; izaac-brave-origin = final.callPackage ./pkgs/brave-origin {}; izaac-flashgbx = final.callPackage ./pkgs/flashgbx {}; izaac-opengigabyte = final.linuxPackages_latest.callPackage ./pkgs/opengigabyte {}; + izaac-sparrow = final.callPackage ./pkgs/sparrow {}; }; in linuxOnly diff --git a/pkgs/brush-shell/default.nix b/pkgs/brush-shell/default.nix deleted file mode 100644 index 7e2d6e4..0000000 --- a/pkgs/brush-shell/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - pkgs, - lib, - ... -}: let - version = "brush-core-v0.5.0-unstable-2026-07-11"; -in - pkgs.rustPlatform.buildRustPackage { - pname = "brush-shell"; - inherit version; - - src = pkgs.fetchFromGitHub { - owner = "reubeno"; - repo = "brush"; - rev = "7521022efcd3c857f3829c1f9d69b67b0a262922"; - hash = "sha256-0UeeI/Gszj8KG1PL8yFz8jqc2jo4WP4r+gyeixWGhpQ="; - }; - - cargoHash = "sha256-QV8NSTtUX/DqXLmw1CkKJ2k4nxh6xLPG1cnjEwQqTxE="; - - cargoBuildFlags = ["-p" "brush-shell"]; - - # Tests require bash as oracle and network access - doCheck = false; - - meta = with lib; { - description = "Bash/POSIX-compatible shell written in Rust"; - homepage = "https://github.com/reubeno/brush"; - license = licenses.mit; - mainProgram = "brush"; - platforms = ["x86_64-linux"]; - }; - } diff --git a/pkgs/sparrow/default.nix b/pkgs/sparrow/default.nix new file mode 100644 index 0000000..fb9aacc --- /dev/null +++ b/pkgs/sparrow/default.nix @@ -0,0 +1,290 @@ +{ + stdenv, + stdenvNoCC, + lib, + makeWrapper, + fetchurl, + makeDesktopItem, + copyDesktopItems, + autoPatchelfHook, + zulu25, + gtk3, + gsettings-desktop-schemas, + writeScript, + bash, + gnugrep, + tor, + zlib, + imagemagick, + gzip, + gnupg, + libusb1, + pcsclite, +}: let + pname = "sparrow"; + version = "2.5.2"; + + openjdk = zulu25.override {enableJavaFX = true;}; + + sparrowArch = + { + x86_64-linux = "x86_64"; + aarch64-linux = "aarch64"; + } + .${ + stdenvNoCC.hostPlatform.system + }; + + src = fetchurl { + url = "https://github.com/sparrowwallet/${pname}/releases/download/${version}/sparrowwallet-${version}-${sparrowArch}.tar.gz"; + hash = + { + x86_64-linux = "sha256-jDvUNaA/g/iyzdbbetlydBz9fFeHmvL8IQNVOi0JGMA="; + aarch64-linux = "sha256-fa+g7OsNAHm1335f5bfzEW80OpqBy8U8GyVx7v8ET10="; + } + .${ + stdenvNoCC.hostPlatform.system + }; + + nativeBuildInputs = [gnupg]; + downloadToTemp = true; + + postFetch = '' + pushd $(mktemp -d) + export GNUPGHOME=$PWD/gnupg + mkdir -m 700 -p $GNUPGHOME + ln -s ${manifest} ./manifest.txt + ln -s ${manifestSignature} ./manifest.txt.asc + ln -s $downloadedFile ./sparrowwallet-${version}-${sparrowArch}.tar.gz + gpg --import ${publicKey} + gpg --verify manifest.txt.asc manifest.txt + sha256sum -c --ignore-missing manifest.txt + popd + mv $downloadedFile $out + ''; + }; + + manifest = fetchurl { + url = "https://github.com/sparrowwallet/${pname}/releases/download/${version}/${pname}-${version}-manifest.txt"; + hash = "sha256-g9y41Cuk4g8qy9TV0VyDwISzWZa9F8zyRpjvopHXYLM="; + }; + + manifestSignature = fetchurl { + url = "https://github.com/sparrowwallet/${pname}/releases/download/${version}/${pname}-${version}-manifest.txt.asc"; + hash = "sha256-PNuyEGkHj3lIoLmw6egXt9/sqO/21WqkbyCZLKx/2qQ="; + }; + + publicKey = ./publickey.asc; + + launcher = writeScript "sparrow" '' + #! ${bash}/bin/bash + params=( + -Dsun.security.smartcardio.library=${pcsclite.lib}/lib/libpcsclite.so.1 + --module-path @out@/lib:@jdkModules@/modules + --add-opens=javafx.graphics/com.sun.javafx.css=org.controlsfx.controls + --add-opens=javafx.graphics/javafx.scene=org.controlsfx.controls + --add-opens=javafx.controls/com.sun.javafx.scene.control.behavior=org.controlsfx.controls + --add-opens=javafx.controls/com.sun.javafx.scene.control.inputmap=org.controlsfx.controls + --add-opens=javafx.graphics/com.sun.javafx.scene.traversal=org.controlsfx.controls + --add-opens=javafx.base/com.sun.javafx.event=org.controlsfx.controls + --add-opens=javafx.controls/javafx.scene.control.cell=com.sparrowwallet.sparrow + --add-opens=org.controlsfx.controls/impl.org.controlsfx.skin=com.sparrowwallet.sparrow + --add-opens=org.controlsfx.controls/impl.org.controlsfx.skin=javafx.fxml + --add-opens=javafx.graphics/com.sun.javafx.tk=centerdevice.nsmenufx + --add-opens=javafx.graphics/com.sun.javafx.tk.quantum=centerdevice.nsmenufx + --add-opens=javafx.graphics/com.sun.glass.ui=centerdevice.nsmenufx + --add-opens=javafx.controls/com.sun.javafx.scene.control=centerdevice.nsmenufx + --add-opens=javafx.graphics/com.sun.javafx.menu=centerdevice.nsmenufx + --add-opens=javafx.graphics/com.sun.glass.ui=com.sparrowwallet.sparrow + --add-opens=javafx.graphics/javafx.scene.input=com.sparrowwallet.sparrow + --add-opens=javafx.graphics/com.sun.javafx.application=com.sparrowwallet.sparrow + --add-opens=java.base/java.net=com.sparrowwallet.sparrow + --add-opens=java.base/java.io=com.google.gson + --add-opens=java.smartcardio/sun.security.smartcardio=com.sparrowwallet.sparrow + --add-reads=com.sparrowwallet.merged.module=java.desktop + --add-reads=com.sparrowwallet.merged.module=java.sql + --add-reads=com.sparrowwallet.merged.module=com.sparrowwallet.sparrow + --add-reads=com.sparrowwallet.merged.module=ch.qos.logback.classic + --add-reads=com.sparrowwallet.merged.module=org.slf4j + --add-reads=com.sparrowwallet.merged.module=com.fasterxml.jackson.databind + --add-reads=com.sparrowwallet.merged.module=com.fasterxml.jackson.annotation + --add-reads=com.sparrowwallet.merged.module=com.fasterxml.jackson.core + --add-reads=com.sparrowwallet.merged.module=co.nstant.in.cbor + --add-reads=kotlin.stdlib=kotlinx.coroutines.core + -m com.sparrowwallet.sparrow + ) + + XDG_DATA_DIRS=${gsettings-desktop-schemas}/share/gsettings-schemas/${gsettings-desktop-schemas.name}:${gtk3}/share/gsettings-schemas/${gtk3.name}:$XDG_DATA_DIRS ${openjdk}/bin/java ''${params[@]} $@ + ''; + + torWrapper = writeScript "tor-wrapper" '' + #! ${bash}/bin/bash + + exec ${tor}/bin/tor "$@" + ''; + + jdk-modules = stdenvNoCC.mkDerivation { + name = "jdk-modules"; + nativeBuildInputs = [openjdk]; + dontUnpack = true; + + buildPhase = '' + mkdir modules + pushd modules + jimage extract ${openjdk}/lib/modules + ls | xargs -d " " -- echo > ../manifest.txt + popd + ''; + + installPhase = '' + mkdir -p $out + cp manifest.txt $out/ + cp -r modules/ $out/ + ''; + }; + + sparrow-modules = stdenvNoCC.mkDerivation { + pname = "sparrow-modules"; + inherit version src; + nativeBuildInputs = [ + makeWrapper + gzip + gnugrep + openjdk + autoPatchelfHook + (lib.getLib stdenv.cc.cc) + zlib + libusb1 + ]; + + buildPhase = '' + mkdir modules + pushd modules + jimage extract ../lib/runtime/lib/modules + + cat ${jdk-modules}/manifest.txt | xargs -I {} -- rm -fR {} + + rm -fR com.sparrowwallet.merged.module/com/sun/jna/freebsd-x86-64 + rm -fR com.sparrowwallet.merged.module/com/sun/jna/dragonflybsd-x86-64 + rm -fR com.sparrowwallet.merged.module/com/sun/jna/freebsd-aarch64 + rm -fR com.sparrowwallet.merged.module/com/sun/jna/freebsd-x86 + rm -fR com.sparrowwallet.merged.module/com/sun/jna/linux-arm + rm -fR com.sparrowwallet.merged.module/com/sun/jna/linux-armel + rm -fR com.sparrowwallet.merged.module/com/sun/jna/linux-mips64el + rm -fR com.sparrowwallet.merged.module/com/sun/jna/linux-ppc + rm -fR com.sparrowwallet.merged.module/com/sun/jna/linux-ppc64le + rm -fR com.sparrowwallet.merged.module/com/sun/jna/linux-s390x + rm -fR com.sparrowwallet.merged.module/com/sun/jna/linux-x86 + rm -fR com.sparrowwallet.merged.module/com/sun/jna/openbsd-x86-64 + rm -fR com.sparrowwallet.merged.module/com/sun/jna/openbsd-x86 + rm -fR com.sparrowwallet.merged.module/com/sun/jna/sunos-sparc + rm -fR com.sparrowwallet.merged.module/com/sun/jna/sunos-sparcv9 + rm -fR com.sparrowwallet.merged.module/com/sun/jna/sunos-x86-64 + rm -fR com.sparrowwallet.merged.module/com/sun/jna/sunos-x86 + rm -fR com.github.sarxos.webcam.capture/com/github/sarxos/webcam/ds/buildin/lib/linux_armel + rm -fR com.github.sarxos.webcam.capture/com/github/sarxos/webcam/ds/buildin/lib/linux_armhf + rm -fR com.github.sarxos.webcam.capture/com/github/sarxos/webcam/ds/buildin/lib/linux_x86 + rm -fR openpnp.capture.java/darwin-aarch64 + rm -fR openpnp.capture.java/darwin-x86-64 + rm -fR openpnp.capture.java/win32-x86-64 + rm -fR com.nativelibs4java.bridj/org/bridj/lib/linux_arm32_armel + rm -fR com.nativelibs4java.bridj/org/bridj/lib/linux_armel + rm -fR com.nativelibs4java.bridj/org/bridj/lib/linux_armhf + rm -fR com.nativelibs4java.bridj/org/bridj/lib/linux_x86 + rm -fR com.nativelibs4java.bridj/org/bridj/lib/sunos_x64 + rm -fR com.nativelibs4java.bridj/org/bridj/lib/sunos_x86 + rm -fR com.sparrowwallet.merged.module/linux-arm + rm -fR com.sparrowwallet.merged.module/linux-x86 + rm -fR com.fazecast.jSerialComm/FreeBSD + rm -fR com.fazecast.jSerialComm/OpenBSD + rm -fR com.fazecast.jSerialComm/Android + rm -fR com.fazecast.jSerialComm/Solaris + + ls | xargs -d " " -- echo > ../manifest.txt + find . | grep "\.so$" | xargs -- chmod ugo+x + popd + + gzip -c ${torWrapper} > tor.gz + cp tor.gz modules/io.matthewnelson.kmp.tor.resource.exec.tor/io/matthewnelson/kmp/tor/resource/exec/tor/native/linux-libc/${sparrowArch}/tor.gz + ''; + + installPhase = '' + mkdir -p $out + cp manifest.txt $out/ + cp -r modules/ $out/ + ''; + }; + sparrow-icons = stdenvNoCC.mkDerivation { + inherit version src; + pname = "sparrow-icons"; + nativeBuildInputs = [imagemagick]; + + installPhase = '' + for n in 16 24 32 48 64 96 128 256; do + size=$n"x"$n + mkdir -p $out/hicolor/$size/apps + convert lib/Sparrow.png -resize $size $out/hicolor/$size/apps/sparrow-desktop.png + done; + ''; + }; +in + stdenvNoCC.mkDerivation { + inherit version src; + pname = "sparrow"; + nativeBuildInputs = [ + makeWrapper + copyDesktopItems + ]; + + desktopItems = [ + (makeDesktopItem { + name = "sparrow-desktop"; + exec = "sparrow-desktop"; + icon = "sparrow-desktop"; + desktopName = "Sparrow Bitcoin Wallet"; + genericName = "Bitcoin Wallet"; + categories = [ + "Finance" + "Network" + ]; + mimeTypes = [ + "application/psbt" + "application/bitcoin-transaction" + "x-scheme-handler/bitcoin" + "x-scheme-handler/auth47" + "x-scheme-handler/lightning" + ]; + startupWMClass = "Sparrow"; + }) + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin $out + ln -s ${sparrow-modules}/modules $out/lib + install -D -m 777 ${launcher} $out/bin/sparrow-desktop + substituteAllInPlace $out/bin/sparrow-desktop + substituteInPlace $out/bin/sparrow-desktop --subst-var-by jdkModules ${jdk-modules} + + mkdir -p $out/share/icons + ln -s ${sparrow-icons}/hicolor $out/share/icons + + mkdir -p $out/etc/udev/ + ln -s ${sparrow-modules}/modules/com.sparrowwallet.lark/udev $out/etc/udev/rules.d + + runHook postInstall + ''; + + meta = with lib; { + description = "Modern desktop Bitcoin wallet with hardware wallet support, built on common standards such as PSBT"; + homepage = "https://sparrowwallet.com"; + sourceProvenance = with sourceTypes; [ + binaryBytecode + binaryNativeCode + ]; + license = licenses.asl20; + platforms = ["x86_64-linux" "aarch64-linux"]; + mainProgram = "sparrow-desktop"; + }; + } diff --git a/pkgs/sparrow/publickey.asc b/pkgs/sparrow/publickey.asc new file mode 100644 index 0000000..c053995 --- /dev/null +++ b/pkgs/sparrow/publickey.asc @@ -0,0 +1,90 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: GPGTools - http://gpgtools.org + +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 +EmR2yA== +=t5JY +-----END PGP PUBLIC KEY BLOCK-----