New :desktop Gradle module turns a computer into a NIP-46 signer with the same accounts, permission model and bunker flows as the Android app, built on the quartz-jvm artifact and Compose Multiplatform. - BunkerEngine ports NotificationSubscription + EventNotificationConsumer + BunkerRequestUtils: per-connection localKey subscriptions (kind 24133), auto-accept/auto-reject via the rememberType/acceptUntil rules, approval queue for everything else, and relay responses with retry/backoff - All NIP-46 methods supported: connect, sign_event, get_public_key, ping, nip04/nip44 encrypt/decrypt, nip44v3 encrypt/decrypt, decrypt_zap_event, sign_psbt, switch_relays, logout (NIP-55 is Android-only IPC and is intentionally out of scope) - Keys are AES-256-GCM encrypted at rest with the key held in a PKCS12 Java KeyStore; keystore + password files are owner-only permissions - Connections via pasted nostrconnect:// URIs or generated bunker:// URIs with QR code; per-app permissions, activity history and logs persisted as JSON per account - UI mirrors mobile: same theme/colors, bottom navigation (Incoming request / Applications / Relays / Settings), login/create-key with NIP-06 seed words, ncryptsec backup, multi-account switching - Packaging via compose nativeDistributions: dmg, msi, exe, deb, rpm - Tests: unit tests plus an opt-in (AMBER_E2E=1) end-to-end NIP-46 round-trip against a public relay Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YQTVwy8RBj7spdEK3aEc3i
2.9 KiB
Amber Desktop (Windows, macOS, Linux)
A Compose for Desktop port of Amber that turns your computer into a NIP-46 remote signer ("bunker"). It shares the same Nostr stack as the Android app (the Quartz library, published for the JVM) and mirrors the mobile UI and permission model.
Features
- Multiple accounts: create a new key (NIP-06 seed words) or import an
nsec,ncryptsec(NIP-49), raw hex key, or mnemonic - NIP-46 signing over relays:
connect,sign_event,get_public_key,ping,nip04_encrypt/decrypt,nip44_encrypt/decrypt,nip44v3_encrypt/decrypt,decrypt_zap_event,sign_psbt,switch_relays,logout - Connect applications with a
nostrconnect://URI or by generating abunker://URI (with QR code) — each connection gets its own local key - The same permission model as mobile: auto-accept / auto-reject rules per request type and event kind, time-bound grants (5 minutes … always), and per-application sign policies (basic / manual / sign everything)
- Per-application activity history and relay logs
- Default bunker relays management
- Light/dark theme following the mobile look
Not included: NIP-55 (nostrsigner: intents and the content provider) —
that is Android IPC and does not exist on desktop. Web apps and other
clients connect through NIP-46 instead.
Key storage
Private keys are encrypted at rest with AES-256-GCM. The AES key is held in a Java KeyStore (PKCS12) file under the application data directory:
- Windows:
%APPDATA%\Amber - macOS:
~/Library/Application Support/Amber - Linux:
$XDG_DATA_HOME/amber(or~/.local/share/amber)
Desktop platforms have no universal hardware-backed keystore, so the keystore password is a per-install random secret stored next to the keystore with owner-only permissions. Anyone with access to your OS user account can read your keys — use full-disk encryption and OS login protection.
Run and build
./gradlew :desktop:run # run from source
./gradlew :desktop:createDistributable # runnable app image
./gradlew :desktop:packageDeb # Linux .deb
./gradlew :desktop:packageRpm # Linux .rpm
./gradlew :desktop:packageMsi # Windows .msi (build on Windows)
./gradlew :desktop:packageExe # Windows .exe (build on Windows)
./gradlew :desktop:packageDmg # macOS .dmg (build on macOS)
./gradlew :desktop:packageDistributionForCurrentOs # whatever fits the host
jpackage can only produce installers for the OS it runs on, so release
builds are made per-platform. Linux packaging needs fakeroot (deb) or
rpm-build (rpm) installed.
Tests
./gradlew :desktop:test # unit tests
AMBER_E2E=1 ./gradlew :desktop:test # + a NIP-46 round-trip over a public relay