Join Nostr
2026-05-28 12:17:46 UTC

Innis on Nostr: And also shipping jsr:@innis/nostr-nip07 today. The first adapter to be released ...

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

And shipping jsr:@innis/nostr-core today. The TypeScript port of the PHP library. Same architecture, same discipline. Branded primitives at the boundary, immutable domain objects, pure functions, ports where the protocol meets the world. The protocol layer separated from everything else, organised around domain concepts rather than NIP numbers, strict enough that a client, a relay, and an application can share the same core.

It is a contracts library and not a batteries-included toolkit. nostr-tools is excellent at the latter and the two are not feature-for-feature competitors. What this exposes that nostr-tools does not is a hex-typed boundary the compiler can check, with PublicKey, EventId, RelayUrl, and Sig all branded, one Signer port that NIP-07 and NIP-46 and a local signer all satisfy, crypto failures returned as Results rather than thrown, and an HttpClient port so libraries that touch the network never reach for fetch directly. If you are building an app and do not need any of that, use nostr-tools. If you are working inside the innis stack or want swappable boundaries you can test against in memory, this is where the contracts live.

The standalone relay-selection library released earlier this month was the first piece of the TypeScript stack to go public. This is the foundation of everything else. The pool, the event store, the NIP-07 and NIP-46 signers, and the work built on top of all of it, all to follow as each layer is cleaned for release. The discipline I am working on is not letting that cleanup become the delay. The lesson keeps coming back around.

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-core
https://github.com/johninnis/nostr-core-ts

MIT.

#nostr #typescript #opensource #nostrdev