From 975acc2bf48ddbd98d58864ba04f95b2fcca6803 Mon Sep 17 00:00:00 2001 From: Clawd Date: Sun, 8 Mar 2026 09:58:35 -0700 Subject: Add ephemeral event support (kinds 20000-29999) Per NIP-01, ephemeral events are broadcast to subscribers but not persisted to storage. This enables real-time features like typing indicators without bloating the database. Also adds typing-indicators.md spec for kind 20001. --- internal/handler/websocket/handler.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'internal') diff --git a/internal/handler/websocket/handler.go b/internal/handler/websocket/handler.go index c64f3f9..b591f61 100644 --- a/internal/handler/websocket/handler.go +++ b/internal/handler/websocket/handler.go @@ -359,6 +359,14 @@ func (h *Handler) handleEvent(ctx context.Context, conn *websocket.Conn, raw []j return nil } + // Handle ephemeral events (kinds 20000-29999) - broadcast but don't store + if isEphemeralKind(pbEvent.Kind) { + h.subs.MatchAndFan(pbEvent) + status = "ok" + h.sendOK(ctx, conn, event.ID, true, "") + return nil + } + eventData := &storage.EventData{ Event: pbEvent, CanonicalJSON: canonicalJSON, @@ -643,3 +651,10 @@ func (h *Handler) isAllowedKind(kind int32) bool { } return h.allowedKinds[kind] } + +// isEphemeralKind returns true if the event kind is ephemeral (20000-29999). +// Ephemeral events are broadcast to subscribers but not stored. +// See NIP-01: https://github.com/nostr-protocol/nips/blob/master/01.md +func isEphemeralKind(kind int32) bool { + return kind >= 20000 && kind < 30000 +} -- cgit v1.2.3