A native remote signer for Nostr. Not a web app in a window: Zig throughout, drawn by the toolkit itself, with no Electron and no WebView anywhere. Notary keeps your secret key on a machine you control and signs for your apps over NIP-46. The key never leaves the signer, and nothing gets signed quietly: you see what a client is asking for before it happens.
Built on zig-nostr/nostr.
Status: early / work in progress. The signer works end-to-end over public relays, including those that require NIP-42 authentication. Downloads are ad-hoc signed (not notarized). See Install.
![]() |
![]() |
![]() |
Real windows, photographed from the running app. Every pixel inside the
window is the app's own, so nothing here shows a screen the app cannot draw. The
signer pubkey and bunker:// URL come from a stub daemon; no real key appears in
any of them.
macOS (Apple Silicon):
curl -fsSL https://raw.githubusercontent.com/zig-nostr/notary/main/scripts/install-macos.sh | bashThat downloads the latest release, verifies its SHA-256, installs Notary.app
to /Applications, and opens it, ready to use.
Notary is ad-hoc signed, not notarized, on purpose. It holds your keys, so
the trust anchor is a build you can reproduce, not an Apple signature: every
release is built by CI from a tagged commit
(.github/workflows/release.yml). Prefer to
trust nothing you didn't run? Read the
installer and build from source.
Notary is split into two processes on purpose, so the secret key stays isolated from the user interface:
daemon/: the headless NIP-46 signer ("bunker"). It holds the encrypted key, connects to your relays, and in GUI mode serves a loopback-only approval API. It runs standalone as a CLI for advanced users, or supervised by the GUI.gui/: the native desktop approver, built with the Native SDK (declarative markup plus Zig, rendered natively: no WebView, no Electron). It shows each pending request and sends back your approve/deny decision. The key never enters it.
Packaged together, one download brings up both as a single macOS .app.
Each component builds independently. See its own README for details:
# daemon (Zig 0.16)
cd daemon && zig build -Doptimize=ReleaseFast
# gui (Native SDK CLI: npm install -g @native-sdk/cli)
cd gui && native builddaemon/README.md: running the signer, key management, relays, and the approval API.gui/README.md: the approval app and how it connects to (or supervises) the daemon.
MIT © Sepehr Safari



