Sign in with a bunker code (NIP-46) #4
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/nip46-bunker"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Asked for on Zapstore against v0.11.0 by "the axiom": "this is great but it would be even better if it had a way to login with a bunker code!" — and answered "will do".
Stash signed only over NIP-55 until now: an Android intent to a signer app on the same phone. Anyone without one reached
No Nostr signer found on this device.and stopped. A bunker code is a remote signer over a relay — nothing installed locally, works with a desktop or hardware key.Shape
NostrConnectSigneris a thirdNostrSignerimplementation. No caller changes — the repository does not know which signer it was handed.Tested against a real bunker, not a fake
scripts/e2e-direct.shnow runsnak bunkerwith a fixed key on its own relay (a fourth service beside the plain/auth/silent relays). The emulator pairs over a websocket and the event that comes back is signed by a key the app process has never seen — the entire point of NIP-46, and the one thing a fake signer could not demonstrate.A defect the tests caught
The
Durationhanded toNostrConnectdoes not bound the attempt. Configured at 20s, a dead relay still took 30093ms to give up. The bound is now enforced at our own boundary withwithTimeoutOrNull, and the test asserts 25s rather than 30 — a 30s assertion would have passed on the binding's own behaviour and never noticed ours had stopped being enforced.The two questions from the plan
Built to my stated recommendations, since the go-ahead did not pick:
1. Where the client key lives. Sealed with AES-GCM under an
AndroidKeyStorekey (SecretBox), not plain SharedPreferences. Notandroidx.security:security-crypto— a new dependency, deprecated, and what it buys here is sixty lines of platform API. The key is deliberately not user-authentication-bound: the app signs in the background for relay AUTH, and a key demanding a screen unlock would fail those with nothing to ask.To be precise about what is stored: this is the client key, which identifies the app to the bunker. The user's identity key never enters the app, so the description's claim still holds.
2. One signer at a time. Amber or a bunker; switch by logging out.
Judgement calls worth your eye
Failed, neverRejected. NIP-46 returns an error string, so a user declining and a relay dropping arrive identically — andRejecteddrives UI that says the user declined.Also here
UnsignedEvent.fromJsonexists at SDK 0.44.6, so the stale comment inLocalKeysSignerclaiming otherwise is wrong; that hand-rolled JSON parse can go in a follow-up.Plan:
PLANS/STASH_NIP46_BUNKER_LOGIN.md.Closed because it has landed, not because it was dropped:
feat/nip46-bunkeris an ancestor ofmain(ff39aee) via #6. Verified withgit merge-base --is-ancestor, not by eye.The branch itself is untouched, so nothing here is lost.
Pull request closed