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 approvals can be once, for an hour or day, or indefinite, with operation and signing-kind limits. Review and edit existing choices, test or reconnect a signer, and review a redacted diagnostic report before sharing it. Native Android apps can use Cambium silently while approved. 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, 9 total releases.

Most recent release: Oct 30, 2026.

Website Repo

Appears in 3 app stacks.

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

  • Oct 30, 2026 0.9.1
    - A request approved late in Heartwood's 30-second on-device window now reaches the app that asked. A visible request waits 45 seconds instead of 20, so the board's own answer, a signature or its own timeout, arrives before the phone gives up while the board is still asking. Silent, already-approved requests keep their 15-second bound, and an unreachable signer is still reported within 20 seconds.
  • Oct 13, 2026 0.9.0
    - Native approval can be once, hourly, daily or indefinite, with optional method and event-kind restrictions. Existing approvals keep their previous meaning; websites remain one-shot. - Approval sheets explain common requests and offer bounded, temporary request details. - Paired identities show connection health and last contact, with authenticated connection tests and a reconnect action. Supported signers can update NIP-46 transport relays securely. - Rename an existing identity and edit an app's scope, expiry or confirmed identity binding. Atomic checks prevent stale approval and management dialogs overwriting a newer choice. - Activity logs include safe failure categories and timings, filters and explicitly reviewed diagnostic reports that exclude payloads, secrets and identifying app/identity names. - Native NIP-55 batches return ordered results. Additional requests without reliable Android
    More…
    caller attribution require visible one-shot consent rather than borrowing a remembered grant.
  • Oct 12, 2026 0.8.0
    - Refresh the pairing, connected-apps, activity-log and phone-unlock screens with clearer sections, labelled inputs, larger controls and colours that follow the system light/dark theme. - Approval panels name the identity and scroll with enlarged text. Identity labels wrap and decision buttons stack on narrow screens or with larger system text. Native requests explain remembered approval and website requests remain visibly one-shot. Signing, pairing, permission and unlock rules are unchanged.
  • 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.