Original release notes
Minor Changes
- #756
570a7ccThanks @Priyanshubhartistm! - feat: add relay-load-aware adaptive PoW difficulty (NIP-13)
Adds limits.event.pow settings that scale the required proof-of-work difficulty between a configured floor and ceiling based on the observed event rate, in place of the existing static eventId.minLeadingZeroBits value (the static pubkey.minLeadingZeroBits check is unaffected and still enforced independently). The event rate is tracked per worker process with the same EWMA shape already used by the relay's rate limiter. Disabled by default (limits.event.pow.enabled: false), so existing static PoW configuration is unaffected unless explicitly opted in.
- #641
837540bThanks @Ferryx349! - feat: add disabled-by-default admin API with password auth, session, and health endpoints
- #666
44f3bb4Thanks @Ferryx349! - feat: add admin observability dashboard with Grafana embed and provisioned metrics panels
- #653
8ab4825Thanks @Ferryx349! - feat: add OpenTelemetry metrics bootstrap with OTLP export for Prometheus
- #661
237b1a4Thanks @Ferryx349! - feat: instrument event and websocket handlers with OpenTelemetry metrics
- #662
36d95ccThanks @Ferryx349! - feat: add Prometheus-backed admin metrics SSE endpoint
- #753
7c2875eThanks @Ferryx349! - feat(admin): add GET /admin/network-health endpoint
- #764
ff43cd3Thanks @Ferryx349! - feat(admin): add Network Health panel to observability dashboard
Adds a dashboard section that renders the latest NIP-66 probe snapshot with per-target DNS, TLS, WebSocket RTT, and NIP-11 status.
- #784
c6c4c4fThanks @Ferryx349! - feat(admin): add GET/PATCH /admin/notifications API for operator alert config
Closes #760.
- #787
de7c9dfThanks @Ferryx349! - feat(admin): add notifications console page for operator alerts
Adds a Notifications view to the admin dashboard for configuring targets and event toggles, testing delivery, and browsing the delivery log via the admin API.
Closes #761
- #690
f70adf2Thanks @Ferryx349! - feat: add authenticated admin settings API endpoints
- #706
841833fThanks @Ferryx349! - feat: add settings editor tab to admin dashboard UI
- #770
07524ebThanks @Priyanshubhartistm! - feat: add WoT-weighted NIP-56 content reporting
Accepts and stores kind-1984 report events, weighting each report by the reporter's WoT distance from wot.seedPubkey (full weight for a direct follow, halving each additional hop, zero for a pubkey outside the trust graph). Reports from a nip56.trustedModerators pubkey always get maximum weight and are flagged actionable, ready for a future management-API surface to act on; every other report is stored for manual review only. Disabled by default (nip56.enabled: false).
- #734
fd7f56aThanks @Priyanshubhartistm! - feat(dvm): dispatch pending DVM jobs to worker processes and publish kind 6000-6999 results back
- #729
275c30cThanks @Priyanshubhartistm! - feat(dvm): trap NIP-90 job request events (kind 5000-5999) and record them via the job repository
- #727
d00eb42Thanks @Priyanshubhartistm! - feat(dvm): add job persistence migration and repository for DVM job state
- #737
9f36191Thanks @Priyanshubhartistm! - feat(dvm): add NIP-89 handler recommendation/information kinds and verify passive accept-and-serve
- #721
11ec673Thanks @Priyanshubhartistm! - feat(dvm): add worker registry settings and dvm-orchestrator process topology
- #587
30fa252Thanks @Anshumancanrock! - Add NIP-50 full-text search support with PostgreSQLtsvector/GINindexing.
Clients can now include a search field in REQ filter objects to perform full-text queries against event content. Results are ranked by relevance (ts_rank) instead of the usual created_at ordering, per the NIP-50 specification.
Features:
- New
searchfilter field accepted in REQ messages - PostgreSQL GIN index on
to_tsvector('simple', event_content)for fast full-text lookups - Configurable text-search language (defaults to
simple, supportsenglish,spanish, etc.) - Configurable max search query length for abuse prevention
- NIP-50 listed in NIP-11 relay information document
- Search can be combined with all existing filter fields (kinds, authors, tags, etc.)
- #702
e172cceThanks @Anshumancanrock! - feat(nip42): enforce authentication on reads for restricted event kinds (encrypted DMs, gift wraps) across REQ, live broadcasts and COUNT
- #716
2f5a1c0Thanks @Anshumancanrock! - feat(nip42): add session tracking with optional TTL and publish-time authRequired (NIP-11 restricted_writes)
- #732
d413bd6Thanks @Anshumancanrock! - Add a CLI to mint NIP-43 invite codes (nostream invite create) so operators can issue a claim without SQL. New codes honornip43.defaultMaxUsesandnip43.inviteCodeExpirySeconds.
- #650
3461dfeThanks @Anshumancanrock! - Add NIP-43 invite code foundation: InviteCodeRepository with atomic claimCode, invite_codes migration, and event kind/tag constants.
- #738
a0853dbThanks @Anshumancanrock! - feat(nip43): issue kind 28935 invite codes on request
NIP-43 kind 28935 is not an event clients publish - it is a REQ the relay answers by minting an invite code on the fly and returning a relay-signed ephemeral event. Nostream now serves those subscriptions, completing the membership flow: request a claim, join with kind 28934, publish.
Off by default. It requires nip43.enabled and the new nip43.allowInviteRequests, a NIP-42 authenticated requester, an info.self consistent with the relay signing key, and a per-pubkey budget under the new limits.invite.rateLimits (5/hour by default). This also makes the previously inert nip43.inviteRequestWhitelist setting take effect. The minted event is never persisted and never broadcast: the claim tag is a bearer secret and is sent only to the socket that asked for it.
Two fixes the flow depended on. The relay signs its own events with a key derived from SECRET, but info.self was a hand-edited string that nothing validated - by default it was a placeholder that is not a pubkey at all, so any NIP-43 client verifying a relay-signed event against self would reject it. info.self is now optional: when unset or unparseable, NIP-11 advertises the derived signing pubkey instead, and nostream info prints that pubkey so operators can pin it.
Kind 28935 also sits in the ephemeral range, so a client-published one fell through to EphemeralEventStrategy and was broadcast to every subscriber - including everyone subscribed to kind 28935 waiting for a real invite. Anyone could inject a forged claim tag into that subscription. It is now rejected with an OK false and never broadcast, and bypasses the NIP-43 admission gate so that rejection actually reaches non-members, who are the ones most likely to publish it by mistake while trying to obtain a code.
CLI.md and README.md now describe the request flow. CLI.md previously claimed the relay "does not yet generate kind 28935 on REQ", and never mentioned that nostream info prints the signing pubkey that CONFIGURATION.md tells operators to pin.
- #676
0bfa0b5Thanks @Anshumancanrock! - Add NIP-43 join/leave request event strategies (kinds 28934/28936) with NIP-42 auth enforcement, created_at freshness validation, invite code claiming, and admission management. Whennip43.enabledis set, publishing is restricted to admitted members even without payments enabled, and NIP-43 is advertised in the NIP-11 document (hidden when disabled). Join/leave update the admission cache so membership changes take effect immediately.
- #675
5a70839Thanks @Ferryx349! - feat(nip66): add shared relay probe engine for DNS, TLS, WebSocket RTT, and NIP-11 checks
- #741
afa8999Thanks @Ferryx349! - feat(nip66): publish kind 30166 and 10166 relay health events after probe runs
After each relay monitor probe run, sign and store NIP-66 relay discovery and monitor announcement events using the configured monitor identity, bootstrap kind 0/10002 on first run, and persist via the existing parameterized replaceable event path.
Fixes #696
- #724
d14b1e9Thanks @Ferryx349! - feat(nip66): add RelayMonitorWorker cluster worker and probe scheduler
- #689
e294a71Thanks @Ferryx349! - Add NIP-66 relay monitor settings foundation with defaults for probe interval, timeouts, targets, monitor identity, and DNS cache TTL.
- #644
2f6d773Thanks @Anshumancanrock! - feat: reject NIP-70 protected events and reposts embedding them
- #730
ef4123eThanks @Anshumancanrock! - feat(admin): accept NIP-98 Authorization on protected admin API routes

