3.01.08 (crate / Tauri semver 3.1.8). Same product line as the Android and iOS apps. Cyberpunk is the default theme on a light or dark system, with the Void wallpaper anchored at the top left. Body text uses DejaVu Sans Mono. Send waits until the wallet is spend-ready, the sync label is green only while lightwalletd is live, and Paper uses the same graphite and grey accent scale as Android and iOS Light. Type is the Android scale (Source Sans 3, Outfit, IBM Plex Mono). Cross-platform DarkFi wallet for desktop (nighthawk-apps/nighthawk-desktop):
- Lit UI (Chat · Wallet · Transfer · DAO · Mine · Settings). Wallet actions are Request · Receive · Send.
- Tauri 2 Rust host
- Same
darkfi-mobile-ffiUniFFI crate as Android (upstreamdrktransfer, trial-decrypt sync, DarkIRC, send/receive). Sent-tx session cache is FIFO-capped (10,000; updates do not refresh eviction). Reorg UItxs_affectedis the wallet history row count (block_height > rewind), not CLI log-line length. - Instant sync & checkpoints: authenticated
TreeStaterestore, real birthday clamping, UnifOMR pipelining, and ZKAS caching (see docs/instant-sync-strategy.md) - Proto version lockstep: the shared Android FFI expects lightwalletd proto 2.1.0. A major mismatch sets
protoVersionMismatchand the wallet screen shows a warning banner. DarkFi pin44ec78b6epays fees from tx-local change when that output covers the fee - Local vault (
vault.datAES-256-GCM; master key in the OS keychain — macOS Keychain / Windows Credential Manager / Linux Secret Service). Legacy v2 vaults used a static PBKDF2 constant. No app PIN; the wallet opens automatically. Treat the data directory as sensitive. - Separate data dirs per testnet / mainnet, plus optional multi-wallet profiles
- Product surface: tokens, memos, DAO, Arti Tor, DarkIRC E2E DM, address book
- Bundled xmrig only. The Mine tab refuses a binary whose SHA-256 is not a shipped Nighthawk build, and it no longer falls back to a system
xmrig. Stratum and other remote endpoints reject private and link-local hosts; loopback stays allowed for a local darkfid - Wallet, chat, and vault commands run against the wallet that is open in the app, not a process-global handle
- Tor on by default for remote lightwalletd / chat (embedded Arti). Default testnet LWD is loopback
http://127.0.0.1:9067; switch URL in Settings for a remote pin. - Trial decryption is the default. Money notes, token mints, and compact DAO calls sync without a clue. Experimental UnifOMR is off in Settings. Turn it on only when both wallets are registered on the same lightwalletd. It is not maintained until DarkFi mainnet contracts are live. Embedded Tor is Arti 0.48.
- Localnet (2026-10-21): 100/100 UnifOMR sends each way with Moonshine and with Android. Ten Moonshine
--no-omrpayments trial-decrypted (E2E_FORCE_TRIAL=1); the balance stayed put across eight further syncs. iOS was not in that run. Desktop finished at 2.5958 DRK, which is not enough for another 100-send pair (6.42 DRK if change is recovered). - UnifOMR Param2 limits:
docs/unifomr_mvp_limits.md
- Rust toolchain, Node 20+,
pnpm - macOS: Xcode CLT (for local macOS builds)
- Reachable darkfi-lightwalletd (default testnet:
http://127.0.0.1:9067; remote HTTPS still needs a TLS pin) - Sibling directory literally named
nighthawk-android-wallet(Cargo path-depends on../../nighthawk-android-wallet/rust/darkfi-mobile-ffi). - For mining: darkfid with stratum (
:18347testnet /:8347mainnet)
Path dependencies use sibling directory names (see src-tauri/Cargo.toml):
parent/
darkfi/ # do not clone git.dark.fi (HTTP 504). FFI uses Android third_party
darkfi-nighthawk-testnet/ # symlink to nighthawk-android-wallet/third_party/darkfi
darkfi-lightwalletd/ # lightwalletd + UnifOMR reference
nighthawk-android-wallet/ # provides rust/darkfi-mobile-ffi (required)
nighthawk-desktop/ # this repo
# optional:
nighthawk-ios-wallet/
moonshine/
src-tauri/Cargo.toml path-depends on:
../../nighthawk-android-wallet/rust/darkfi-mobile-ffi
Do not point at a darkfi-mobile-ffi symlink at the GitHub root — Cargo resolves the FFI crate’s relative third_party/darkfi from the real Android tree path.
src-tauri/Cargo.lock is committed so release builds stay reproducible.
cd nighthawk-desktop
pnpm install
# Optional if the default cargo git cache is not writable:
# export CARGO_HOME=$HOME/.cargo-nh
pnpm tauri devsrc-tauri/Cargo.toml requires a sibling nighthawk-android-wallet.
Cargo git deps inside that tree are not fetched from git.dark.fi (HTTP 504):
| Crate | URL |
|---|---|
kvdb-overlay accd2689 |
https://gitlab.com/nighthawk24/kvdb-overlay |
RandomX 0e31d5a |
https://codeberg.org/darkrenaissance/RandomX |
rust-url branch v258 |
https://github.com/darkrenaissance/rust-url |
# Dev / compile the .app only (skips Finder/AppleScript DMG layout):
CI=true pnpm tauri build
# Or skip the DMG bundle:
pnpm tauri build --bundles appWithout CI=true, bundle_dmg.sh fails in non-GUI / agent shells (it drives Finder via AppleScript). The binary and .app still compile; only the DMG step needs a real Finder session or CI=true.
Host checks after Android FFI changes (this app path-depends on nighthawk-android-wallet/rust/darkfi-mobile-ffi):
cd src-tauri
cargo test --release
cargo build --releasePlace platform binaries under src-tauri/binaries/ named for Tauri externals:
xmrig-aarch64-apple-darwinxmrig-x86_64-apple-darwinxmrig-x86_64-unknown-linux-gnuxmrig-x86_64-pc-windows-msvc.exe
The app checks the file against the SHA-256 allowlist in src-tauri/src/commands.rs before it starts. A Homebrew or other system xmrig is not used.
./scripts/fetch-xmrig.sh~/Library/Application Support/nighthawk-app-desktop/
prefs.json{testnet,mainnet}/wallet.db(turso + experimental aegis256; wipe after DarkFi pin bumps that change wallet format){testnet,mainnet}/cache/{testnet,mainnet}/darkirc_db/- Local vault:
vault.meta.json+vault.dat(AES-256-GCM; master key in OS keychain, not a user PIN)
use_tor defaults to true. Remote lightwalletd and DarkIRC exit via Arti SOCKS. Disable Tor in Settings only for loopback/dev testing.
Changing LWD URL, TLS pin, Tor, or network closes the open wallet handle — reopen the wallet after Save.
Unlock wallet → Mine → set threads → Start. Payouts go to primary_deposit_address. Stratum URL is editable in Settings.
- Strict UnifOMR is the default. Clue-less payments (Moonshine
--no-omr, upstreamdrk) stay invisible until strict mode is turned off. Forcing trial while strict mode is still on used to idle the scan cursor; trial now clears strict mode first, and aGetBlockRangehole does not mark missing blocks scanned. - The 2026-10-21 localnet did not include iOS. This desktop build shares the Android UniFFI crate, so the trial-cursor fixes apply here after that crate is rebuilt.
git.dark.fireturns HTTP 504. Do not clone DarkFi or its git deps from there. Use the Androidthird_party/darkfipin and the GitLab / Codeberg / GitHub mirrors listed under Build.
