Nostr Compass #32

IndieSats opens music infrastructure, Nostrord implements NIP-29 upgrades, Divine hardens delivery, and Armada brings Buzz workspaces to an independent Nostr client.

Nostr Compass

22. Juli 2026July 22, 2026 · 24 Min. Lesezeit24 min read

Welcome back to Nostr Compass, your weekly guide to Nostr.

This week: IndieSats (⁠Gunnar Stødle) retires key custody, its whitelist, and its mandatory revenue cut, relaunching as an open relay, player, and discovery layer where artists publish under their own keys. Nostrord v2.3.0 ⁠Nostrord lands group moderation, mute lists, and onion relays the same week five NIP-29 spec PRs merge. Zapstore 1.1.0 ⁠Zapstore introduces a portable encrypted device key with Amber backup and opt-in background auto-updates. The favorite-follow-sets list kind merges and opens a renumbering PR within days. And the Iris projects ship nostr-pubsub, the fips-ts browser runtime, and nostr-social-graph 2.0.0 in a single week.

Tagged releases bring Amber v6.3.0 (⁠greenart7c3) with grouped bunker-signing approvals, Armada v0.37.0 with a second client for Buzz workspaces, Divine Mobile 1.0.17 with durable NIP-17 delivery and strict TLS validation, and nak v0.20.2 (⁠fiatjaf) with NIP-34 pull-request commands.

On the unreleased side, Snort (⁠Kieran) records EOSE-proven cache coverage, Shopstr ⁠Shopstr Markets closes two payment-integrity gaps, Mostr bridges ActivityPub private chats to Nostr DMs, nostream (⁠Cameri 🦦) merges the access-control stack this week's Deep Dive covers, and Amethyst ⁠Amethyst reaches 88 merged PRs with full NIP-88 polls on Desktop.

The NIPs repository merges five PRs this week, including the NIP-29 cluster and kind:10011 favorite follow sets, and opens debates on NIP-47 simplification and trusted relay assertions. The Deep Dive covers NIP-42 and NIP-43, the relay access-control pair.


Lead stories#

IndieSats drops its publisher role and relaunches as open Nostr music infrastructure#

IndieSats is a Nostr-based music platform that until this week acted as a publisher: it held keys for artists, ran a whitelist, and took a mandatory 2% cut of revenue. In a pivot announcement published on July 20, the project retired all three of those roles at once. The relaunched platform is three pieces of open infrastructure: an open relay, a player, and a discovery layer. Artists now publish music under their own Nostr profiles. The 2% track-level platform share is optional but selected by default when an artist publishes, and artists can clear it to retain the full payment; the platform also honors NIP-09 kind:5 deletion requests so artists can remove their work. A v1.1.5 update published July 21 changed track publication to the event format expected by Amethyst and other Nostr music clients and made relay delivery explicit. For a space that usually talks about protocols replacing platforms, this is a live case of a platform voluntarily disassembling itself into protocol pieces.

Nostrord v2.3.0 ships group moderation, mute lists, and onion relays#

Nostrord, the group-chat client for Android, iOS, web, and desktop, shipped v2.3.0 with wired-up group moderation actions on all UIs (PR #192), consent-gated group invites with cross-relay detection (PR #195), cross-platform NIP-51 mute lists (PR #188), and Tor .onion relay support. Its release lands the same week the underlying NIP-29 spec merged five PRs covering subgroups, message pinning, banners, and invite codes (details in this week's protocol section), so group chat on Nostr now has both a deeper spec and a client exercising most of it, which shortens the feedback loop for everyone else building on relay groups.

Zapstore 1.1.0 makes the device key portable and adds background auto-updates#

Zapstore is a Nostr-native app store where releases are signed by developer keys and no central operator vouches for them. Version 1.1.0, the first release covered here since early March, closes the two biggest gaps with conventional app stores. For updates, opt-in background downloads now run over Wi-Fi and install silently or staged, so apps stay current without manual trips through the store. Identity continuity comes from a portable encrypted device key that users can back up through Amber over NIP-55, the Android signer interface, so a phone migration preserves the device identity. Version 1.1.0 also moves the app catalog onto relays as device-signed kind:10067 events, adds NIP-56 verified reporting from the overflow menu so users can flag problematic apps in a way other clients can consume, and verifies the C1 proof attached to a release before any install proceeds, tightening the link between what a developer signed and what a device runs.

The favorite-follow-sets list kind merges and immediately moves house#

A spec-coordination story played out inside a single week. PR #2413 merged on July 15, standardizing a replaceable list kind for favorite follow sets under NIP-51 (lists): a dedicated kind for a user's curated sets of followed accounts. Within days it turned out the assigned kind:10011 was already in use elsewhere, so a follow-up PR #2417 is now open to renumber the list to kind:10021. Nothing has shipped against the merged kind yet, which makes this the cheap moment to renumber; once clients start publishing kind:10011 events, the collision would get expensive to unwind. Developers building list-consuming features should track the renumbering PR, not the merged text, until it resolves.

The Iris projects ship a pubsub library, a browser FIPS runtime, and a social-graph 2.0 in one week#

Three releases from the Iris orbit landed together, and they interlock. nostr-pubsub is a transport-neutral publish/subscribe library for Nostr events; its first tracked releases, v0.1.3 through v0.5.2, deliver a browser relay carrier built on nostr-tools' SimplePool, event verification at the transport boundary so invalid signatures never reach subscribers, and bounded historical queries. fips-ts (⁠Johnathan Corgan) brings FIPS, the Noise-over-secp256k1 peer transport previously available as a Rust stack, into the browser as a TypeScript runtime: releases 0.0.24 through 0.0.30 added a WebRTC datachannel carrier, Nostr-based signaling for peer discovery, a recent-peer cache, and an IndexedDB adapter for browser storage, and the runtime is wire-compatible with the reference Rust implementation. The third piece, nostr-social-graph v2.0.0, is a major version of the social-graph library: signed roster operations for Nostr identity graphs, device-approval flows bootstrapped from a canonical three-field URI, and FIPS transport identity facets with shared Rust and TypeScript test vectors. The connective framing is the Iris Stack, the project's integration lab tying these libraries together with Blossom, Hashtree, and encrypted messaging. Taken together, a web app can now discover peers over Nostr, open an encrypted FIPS channel to them, and maintain a signed social graph, all in TypeScript.


Tagged releases#

Amber v6.3.0 groups bunker signing approvals and adds Expert List support#

Amber is an Android NIP-46 remote signer. v6.3.0 adds grouped multi-request approval so users can review and approve a batch of bunker signatures at once. The release also adds support for Expert List (kind 12022) and Expert Pack (kind 32022) events, a privacy mode that hides sensitive content on screen, and a change to fetch an account's NIP-65 relay list before its profile metadata so signer flows start from the user's actual relay set. This follows the v6.2.x line covered in the 2026-07-08 issue.

Nostrord v2.2.0 follow-up#

With v2.3.0 leading this week's News section, the tagged-release slot notes only what the lead does not: v2.3.0 follows v2.2.0's DM controls covered in #31, making this the client's second consecutive weekly release.

Armada v0.37.0 opens Buzz workspaces from a second client#

Armada, a Discord-style Nostr client, released v0.37.0 with support for Buzz relays as an enhanced NIP-29 workspace mode, detected through the relay's NIP-11 metadata. The client renders Buzz forum posts and comments as kinds 45001 and 45003, folds edits and deletions into stream timelines, and adds presence, workflow, job, huddle, and shared-canvas surfaces. Its Projects workspace reads NIP-34 repository announcements, patches, pull requests, issues, and status events directly from the relay (implementation commit), giving Buzz workspaces a second client for both conversation and repository work.

Wisp v1.2.0 adds a multi-account switcher and collapsible reply threads#

Wisp (⁠utxo the webmaster 🧑‍💻🍁) is a privacy-oriented Nostr client with built-in wallet support. v1.2.0 adds a multi-account switcher for moving between profiles without re-login, collapsible reply threads for long conversations, stripping of tracking parameters from note links before they open, and a wallet transaction-history view. The release follows the Wisp update covered in the 2026-07-08 issue.

Divine Mobile 1.0.17 hardens relay security and DM delivery#

Divine Mobile, a Nostr short-video client, released 1.0.17 with a persistent stop-motion editor and tighter Nostr paths. Direct messages now wait for relay OK responses, retry through a durable queue, and route through recipients' kind 10050 inbox-relay lists (PR #6046); NIP-46 pairing preserves auth_url challenges as recoverable signer steps (PR #6151). PR #6278 removes permissive certificate acceptance from production relay WebSockets and HTTP requests used for NIP-96 uploads, LNURL, and zaps, restoring platform TLS validation outside debug loopback connections. Interrupted uploads can also resume from the server's last confirmed offset, so a backgrounded publish no longer restarts from zero.

ClipRelay v0.1.2 (new project) syncs clipboards across devices over Nostr relays#

ClipRelay (⁠hoppe2) is a newly launched cross-platform app (Android, macOS, Windows, Linux) that syncs your clipboard across your own devices: copy on one machine, paste on another. All traffic moves through Nostr relays as NIP-44 encrypted events addressed to yourself, so there is no server to run and no account to create; the private key stays outside the app. v0.1.2 fixes a subtle sync failure where a machine waking from sleep kept publishing but silently stopped receiving, and tightens the relay-status indicators that previously reported dead subscriptions as healthy. This is ClipRelay's first appearance in the newsletter.

Sonar v0.1-alpha.11 continues the alpha line#

Sonar ⁠Vincenzo Palazzo, last week's lead story, cut v0.1-alpha.11 with work on the Rust mesh link engine, BLE and mesh fixes, and relay diagnostics; an incremental follow-up to the alpha line covered in #31.

nak v0.20.2 adds NIP-34 pull-request workflows#

nak, the Nostr command-line tool, released v0.20.2 with commands to create, pull, and merge NIP-34 pull requests and to pull individual patches, and it allows pushes without rewriting a repository announcement. The 11-commit release range also adds parent-group handling for NIP-29, queries more outbox relays, makes relay connection timeouts configurable, and fixes bunker selection when only the default --sec value exists.

The week's smaller launches#

Four smaller releases deserve one line each: noscall v0.6.0, the Nostr calling app, migrated its push notifications to UnifiedPush, keeping call signaling off Google's push infrastructure; nostr-vpn v4.1.3, a mesh VPN that uses Nostr for signaling, unified its exit-DNS policy across platforms and now restores the original route and DNS state after WireGuard or private-exit sessions; StableKraft v1.3.0, the Nostr-plus-Lightning music and podcast aggregator covered in April, added native Android lock-screen and headset controls plus a playback-scoped wake lock so audio survives Doze; and new Zapstore app Hakari backs up a weight logger over encrypted Nostr events.

Amethyst lands v1.13.0 pre-release QA on napplet isolation and Concord authority#

Amethyst merged 88 PRs this week ahead of its v1.13.0 release. PR #3650 is a pre-release QA pass covering napplet account isolation, Concord authority fixes, and around 30 other fixes. The late-window work adds full Desktop NIP-88 poll rendering, creation, voting, declared-relay tallying, and kind 1068 search (PR #3664); NIP-50 search now ranks results by BM25 relevance while large tag watchers use bounded merging (PR #3663). A separate relay-store pass selects query indexes by measured cost, adds tag-author-kind indexes, and serializes each live event once per fanout (PR #3660), with reported benchmark reductions from 149 to 4 milliseconds for one query shape and from 14.2 to 0.66 milliseconds for a common DM-room query.


Unreleased changes#

Snort rewrites query synchronization around EOSE-proven coverage#

Snort, a web Nostr client, rewrote its query and cache-synchronization path in commit 8a62770. The client now records which query windows reached EOSE, uses those watermarks to skip covered cache ranges, centralizes event dispatch behind one relay-pool listener, and sends search filters only to relays whose NIP-11 documents advertise NIP-50. Follow-up fixes serialize concurrent watermark updates and correct inclusive timeline boundaries, while commit 9d1721b restores a live subscription to the chunked follows feed so events arriving after page load do not freeze outside its cached windows.

Shopstr binds payment validation to signed receipts and server-side prices#

Shopstr, a Nostr marketplace client, closed two payment-integrity gaps. PR #552 makes Zapsnag verify each kind 9735 receipt's signature, signer, embedded zap request, recipient and product tags, BOLT11 amount, and optional preimage against the invoice payment hash before treating it as a purchase. PR #449 moves Cashu quote creation behind a Shopstr API route that resolves the listing and recomputes its price server-side, so a browser-modified amount cannot determine the mint invoice.

Mostr bridges ActivityPub private chats and Nostr DMs#

Mostr, an ActivityPub-to-Nostr bridge, now carries one-to-one Pleroma ChatMessage objects and encrypted Nostr DMs in both directions (commit 36ee547). ActivityPub private chats become kind 4 events addressed to the Nostr recipient, while kind 4 messages sent to bridged Fediverse users are decrypted and federated as ChatMessage objects. The bridge limits these events to configured DM relays gated by NIP-42 and authenticates with a separate relay key. This interoperability path uses legacy NIP-04 encryption. NIP-17 gift wrapping remains outside this implementation.

nostream merges eight PRs without cutting a release#

nostream, the TypeScript relay implementation, merged eight PRs this week without cutting a release. The headline pair is PR #702 and PR #676, which together give relay operators a working authentication-plus-membership access-control stack; this week's NIP Deep Dive walks through exactly that handshake. PR #694 fixes generic #e, #p, #g, and similar tag filters that could return one copy of an event for every matching tag row, reducing duplicate protocol traffic within a subscription.

FIPS v0.4.1 tightens the Iris transport layer#

jmcorgan/fips shipped v0.4.1, a maintenance release capping antipoison state, fixing convergence and MTU handling, and cutting CPU use. The browser TypeScript runtime fips-ts from the Iris project cluster is wire-compatible with this Rust transport, so fixes here propagate directly to browser interoperability.


Protocol work and NIP updates#

Recent changes to the NIPs repository:

Merged:

Open PRs and Discussions:


NIP Deep Dive: NIP-42 and NIP-43#

Running a relay that is not open to everyone used to mean inventing everything yourself. A paid or invite-only relay operator had to maintain a whitelist out of band, usually a text file of pubkeys collected over DMs, with no standard way to tell a connected client "prove who you are" and no standard way for a user to ask for admission or know whether they were a member. Every relay that wanted gated reads or gated writes built its own private mechanism, and clients could not interoperate with any of them. NIP-42 standardizes the proof-of-identity half of that problem, and NIP-43 standardizes the membership half. This week nostream, the TypeScript relay, merged the pair end to end: PR #702 restricts reads of encrypted kinds to authenticated recipients, and PR #676 adds join and leave request event strategies, both merged on July 20.

NIP-42: Authentication of clients to relays#

NIP-42 answers one question: who is on this connection? A relay that wants to gate reads or writes sends an AUTH message carrying a challenge string, at connect time or on demand when a request needs authentication. A client replies with its own AUTH message containing a signed ephemeral event, kind 22242, and the relay answers with an OK message exactly as if the auth event were an ordinary write. Authentication then holds for the duration of the connection. A sequence of AUTH messages can authenticate several pubkeys on one connection.

Here is the signed auth event:

{
  "id": "4ef6f2c0b1a84c9a3d0f9c58e2a1b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0",
  "pubkey": "c308e1f882c1f1dff2a43d4294239ddeec04e575f2d1aad1fa21ea7684e61fb5",
  "created_at": 1753195800,
  "kind": 22242,
  "tags": [
    ["relay", "wss://relay.example.com/"],
    ["challenge", "challengestringhere"]
  ],
  "content": "",
  "sig": "8b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1"
}

The pubkey is the identity being proved, since the relay verifies the sig over the event id against it. Kind 22242 sits in the ephemeral range: the event is a connection-level credential, and relays must never store it or broadcast it to other clients. A relay tag binds the signature to one relay URL so a captured auth event cannot be replayed against a different relay, while the challenge tag binds it to the specific challenge string issued on this connection and blocks later replay. Its created_at must be close to the current time, within roughly a ten-minute window, so a stale auth event expires on its own. An empty content field confirms that nothing is being published.

The spec also defines two machine-readable prefixes that make gating visible to clients. A relay that rejects a subscription because the client has not authenticated yet answers with a CLOSED message starting with auth-required:, and a rejected write gets an OK with the same prefix. A client that authenticated but still lacks permission for the action gets restricted: instead. That distinction is what nostream's PR #702 builds on: reads of encrypted kinds can now be closed with auth-required: until the requesting pubkey proves it is the recipient.

NIP-43: Relay Access Metadata and Requests#

NIP-43 answers the follow-up question: now that the relay knows who you are, what are you allowed to do? Where NIP-42 is a handshake on a live connection, NIP-43 is a set of published events that describe membership state and let users ask to change it. On the relay side, a kind 13534 event, signed by the pubkey in the relay's NIP-11 self field, lists one member tag per pubkey, with optional role arguments pointing at role definitions published as kind 33534. Kind 8000 announces a member being added and kind 8001 announces a removal, both signed by the same relay key with a p tag for the affected member. On the user side, kind 28934 is a join request carrying an invite code in a claim tag, kind 28935 is an ephemeral invite-code event the relay generates on the fly when a user requests a claim, and kind 28936 is a leave request.

A join request looks like this:

{
  "id": "9f0e1d2c3b4a59687a6b5c4d3e2f1098a7b6c5d4e3f2019a8b7c6d5e4f3021a9b8",
  "pubkey": "ee1d336e13779e4d4c527b988429d96de16088f958cbf6c074676ac9cfd9c958",
  "created_at": 1753195900,
  "kind": 28934,
  "tags": [
    ["-"],
    ["claim", "invite-code-from-operator"]
  ],
  "content": "",
  "sig": "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2"
}

The pubkey is the user asking for admission, and kind 28934 marks the event as a join request. Its - tag is the NIP-70 protected-event marker, telling relays to accept the event only from its author. A claim tag carries the invite code obtained out of band, and created_at must be now, plus or minus a few minutes, so an old request cannot be replayed. Relays answer the claim with an OK message, reuse the NIP-42 restricted: prefix for failures such as an expired or invalid code, update the kind 13534 list, and may publish a kind 8000 add-member event. Membership is deliberately not derived from a single event: the spec treats the relay-signed list as one input, and a client deciding whether someone is currently a member should consult both the relay's kind 13534 and the member's own events. Clients must only send join, invite, or leave requests to relays that advertise this NIP in the supported_nips section of their NIP-11 document, and nostream's PR #676 is the relay-side machinery that turns those request kinds into actual membership changes.

History#

NIP-42 is the older of the two by a wide margin. It entered the NIPs repository on January 2, 2023, in commit c80be21c, where fiatjaf drastically simplified an earlier relay-auth NIP drafted by semisol, collapsing a more complex challenge scheme into the single signed ephemeral event the spec still uses today. NIP-43 arrived much later, on October 30, 2025, when hodlbod's PR #1079 merged, adding relay access metadata and requests built directly on top of NIP-42's restricted: prefix. The two-and-a-half-year gap reflects how long paid and private relay operators used ad-hoc whitelists before the membership layer got a standard.

Implementations#

On the relay side, nostream now ships both halves after this week's merges. strfry (⁠Doug Hoyte) implements NIP-42, validating kind 22242 auth events in its ingester and issuing challenges from its config. nostr-rs-relay handles the AUTH handshake in its connection layer with tests covering the challenge and timestamp window. khatru, the Go relay framework, tracks the authenticated pubkey per connection so policies can gate reads and writes on it. On the client side, Amethyst signs kind 22242 responses to relay challenges, including per-stream auth for its Concord encrypted communities. The two NIPs split access control along a clean line: NIP-42 is proof of identity, scoped to one connection, one challenge, and a few minutes of validity, and it says nothing about policy. NIP-43 is policy, expressed as ordinary relay events: who is a member, who was added or removed, and how a user requests those transitions. The gap implementers should keep in mind is that nothing yet standardizes finer-grained permissions beyond NIP-43's optional role metadata, so any relay doing more than a binary member/non-member split is designing that layer on its own.


That's it for this week. Building something or have news to share? Reach out via NIP-17 DM or find us on Nostr.

#clients#nips#nostr#privacy#relays

Written by

Comments

No comments yet. Start the conversation.

Contents

5 sections

  1. Lead stories
  2. Tagged releases
  3. Unreleased changes
  4. Protocol work and NIP updates
  5. NIP Deep Dive: NIP-42 and NIP-43