Join Nostr
2026-06-01 12:02:16 UTC

Innis on Nostr: And shipping jsr:@innis/nostr-nip46 today. NIP-46, the remote signer the spec calls ...

And shipping jsr:@innis/nostr-nip46 today. NIP-46, the remote signer the spec calls Nostr Connect and everyone else calls the bunker.

Two roles in this one. The client implements the Signer interface that @innis/nostr-core defines, the same one the NIP-07 adapter does. So applications call signEvent and never learns if the key is in a browser extension or a popup on a phone in the next room.

The bunker is the other end of the contract. It takes one of those same signers, your ordinary logged-in key, and lends it out to another device, queuing each request for you to approve.

Built on @innis/nostr-core, alongside @innis/nostr-nip07. Two adapters now, one signing contract, the rest of the stack to follow as each layer is cleaned.

AI was involved, same terms as before. The architecture is mine. The decisions are mine. The machine occasionally did what I asked it to.

deno add jsr:@innis/nostr-nip46
https://github.com/johninnis/nostr-nip46-ts

MIT.

#nostr #typescript #opensource #nostrdev
And also shipping jsr:@innis/nostr-nip07 today. The first adapter to be released that's built on top of @innis/nostr-core. It wraps the window.nostr surface that browser extensions inject, Alby and nos2x and Flamingo and anything else that puts a key holder behind a popup, into the same Signer interface every other signer in the stack implements. Application code never branches on what kind of identity is on the other end of the call.

One factory function in, a frozen Signer out. getPublicKey memoises after the first resolve. Encryption methods return a Result instead of throwing, because a missing NIP-44 implementation is information about the extension, not an exception to recover from. User rejection still throws. Clicking deny is a control-flow signal and belongs in the same channel as signEvent's other rejections.

The piece I care about most is the pubkey-mismatch check. If the user logs in as one identity and the extension later signs an event as another, the signer fires a callback and refuses to return the event. Extensions can switch accounts under you. Most code never notices. This one checks every signature against the pubkey the application thinks it has.

Built on @innis/nostr-core. AI was involved, same terms as before. The architecture is mine. The decisions are mine. The machine held the other end of the board.

deno add jsr:@innis/nostr-nip07
https://github.com/johninnis/nostr-nip07-ts

MIT.

#nostr #typescript #opensource #nostrdev