From dfa19ff0776be0850ad7b86ca579601431349593 Mon Sep 17 00:00:00 2001 From: bndw Date: Fri, 13 Feb 2026 20:38:59 -0800 Subject: feat: implement NIP-09 with hard delete Implement event deletion (NIP-09) using hard delete approach: - Kind 5 events trigger deletion but are not stored themselves - ProcessDeletion hard deletes referenced events (DELETE FROM events) - Only authors can delete their own events (pubkey verification) - Support multiple event IDs in single deletion request - No deletions table needed (simpler schema) - Added 4 deletion tests covering various scenarios - All 45 tests passing --- internal/handler/websocket/handler.go | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'internal/handler/websocket/handler.go') diff --git a/internal/handler/websocket/handler.go b/internal/handler/websocket/handler.go index 38d4fa6..224a2f8 100644 --- a/internal/handler/websocket/handler.go +++ b/internal/handler/websocket/handler.go @@ -17,6 +17,7 @@ import ( type EventStore interface { StoreEvent(context.Context, *storage.EventData) error QueryEvents(context.Context, []*pb.Filter, *storage.QueryOptions) ([]*pb.Event, error) + ProcessDeletion(context.Context, *pb.Event) error } type Handler struct { @@ -115,6 +116,16 @@ func (h *Handler) handleEvent(ctx context.Context, conn *websocket.Conn, raw []j pbEvent := NostrToPB(&event) canonicalJSON := event.Serialize() + // Handle deletion events (kind 5) - process but don't store + if pbEvent.Kind == 5 { + if err := h.store.ProcessDeletion(ctx, pbEvent); err != nil { + h.sendOK(ctx, conn, event.ID, false, fmt.Sprintf("deletion failed: %v", err)) + return nil + } + h.sendOK(ctx, conn, event.ID, true, "deleted") + return nil + } + eventData := &storage.EventData{ Event: pbEvent, CanonicalJSON: canonicalJSON, -- cgit v1.2.3