Cambium

dev.forgesworn.cambium
by TheCryptoDonkey darren@600.wtf

NIP-55 signer that holds no keys — signing is proxied to a NIP-46 hardware bunker

Cambium is an Android NIP-55 signer that holds no user keys. Cryptographic results come from a paired Heartwood hardware signer over NIP-46 (Nostr relays), with only safe, exact repeats answered from bounded per-identity caches. Amethyst, Primal and most other Amber-compatible clients cannot log in to a remote NIP-46 bunker directly, but they all support NIP-55 external signers. Cambium fills that gap: it registers as a signer, but it is not one. No user identity keys ever touch the phone. Compromising the phone exposes only the ability to request signatures, which the hardware signer's policy engine and physical confirmation button still gate, never the identity key itself. Phone unlock (opt-in): a Heartwood that restarts locked after a power cut asks this phone to unlock it. One tap and your screen lock send the board's unlock secret, which signs nothing and is useless without the board's own flash. Native Android apps can use Cambium silently after approval. Websites can use NIP-55 nostrsigner: links with an explicit one-shot approval and a validated HTTPS callback or clipboard result. Per-identity bounded priority queues keep user work available during relay-authentication bursts. No Google Play services, no Firebase, no analytics. Runs on any Android 8.1+ device, including GrapheneOS.

First release: Aug 13, 2026, 6 total releases.

Most recent release: Sep 26, 2026.

Website Repo

Appears in 1 app stack.

0 sats / 0 zaps received in the past year.

Sats Received

Underlying data available via MCP: app_zaps, app_releases.

Zap Count

Underlying data available via MCP: app_zaps, app_releases.

Releases

  • Sep 26, 2026 0.7.1
    - The check code stays on screen once enrolment finishes, labelled and with a reminder that it should match the board and Sapwood, instead of disappearing as soon as the board's answer is confirmed. It clears when the owner leaves the screen. - Release builds no longer embed git metadata, so the APK built by F-Droid matches the one published here whatever checkout it was built from.
  • Sep 24, 2026 0.5.0
    - Phone unlock. A Heartwood (0.18.0-beta.17 or later) that restarts locked after a power cut can ask this phone to unlock it: a notification with the board's restart reason, network and restart count, then one tap and the phone's screen lock (PIN, password or strong biometric). The unlock secret sits under a Keystore key that needs that authentication for every use; lock messages are read unfiltered and matched locally; each unlock goes out from a throwaway key, to that board's own relays. Enrolment shows a six-character check code to compare with Sapwood. Set up from a paired signer's row; Sapwood's enrolment panel is not released yet (`scripts/phone-unlock.mjs enrol-for` in heartwood-esp32 stands in for it). - The keep-warm service now says when a paired signer has gone quiet (two failed scheduled checks in a row), and runs whenever a board is set up for phone unlock. It also restarts itself after
    More…
    an app update instead of waiting for the next reboot. - Screens no longer start under the status bar on Android 15 and later. - The store description now says 64-bit Android 8.1+ devices: the APK ships arm64-v8a and x86_64 only, so 32-bit ARM phones were never able to install it despite the old wording.
  • Aug 14, 2026 0.4.3
    - Relay AUTH is now idle-only best effort: Cambium admits at most one distinct NIP-42 challenge per identity, never retries it internally, and opens a 60-second per-identity circuit after a transport failure. New challenges fail fast during the cooldown while posts, reactions, encryption, and exact cached AUTH duplicates remain available. - Repetitive AUTH-unavailable warnings are aggregated per calling app instead of flooding logcat during an Amethyst relay burst.
  • Aug 13, 2026 0.4.0
    - Websites can now use Cambium through NIP-55 `nostrsigner:` links. Cambium parses the browser request parameters, asks for an explicit one-shot approval, and returns a signature, signed event, or `Signer1` gzip envelope through a validated HTTPS callback. When there is no callback, it copies the result to the clipboard. - Browser requests never inherit or create a remembered permission for Chrome (or any other browser). The approval sheet identifies the callback host and makes the one-shot boundary clear. Native Android intent and content-provider permissions are unchanged. - Minimal NIP-55 web events now sign correctly when they omit `pubkey`, `created_at`, or `tags`, as the specification's own example does. Cambium fills the pubkey from the exact paired identity proved by the NIP-46 handshake before passing the event to rust-nostr.
  • Aug 13, 2026 0.3.6
    Pairing fix. Cambium could not pair with a signer that answers `connect` by echoing the bunker URI's secret, which is what current NIP-46 specifies and what Heartwood's firmware does. - The rust-nostr dependency moves from 0.44.2 to 0.44.8. The older build accepted only the literal `ack` as a `connect` result and refused the secret echo, so pairing ended in "Unexpected response" against a spec-following signer. Both forms are accepted now, so signers on either convention pair. Verified against live hardware and against `nak bunker`, which still answers `ack`.
  • Aug 13, 2026 0.3.5
    Review hygiene from F-Droid inclusion feedback. No behaviour changes. - The `ACCESS_NETWORK_STATE` permission is no longer requested. It was scaffold boilerplate: nothing in Cambium or its dependencies reads network state, so the app now asks only for what it uses. - The Gradle wrapper now pins the distribution's SHA-256 (`distributionSha256Sum`), so a fresh build verifies the Gradle download before running it. Requested in F-Droid review.