feat(buzz): WebSocket inbound transport — NIP-42 auth, live DM discovery, poll fallback

Consolidates the native-transport half of PR #73636 by @ScaleLeanChris
onto the merged adapter: persistent NIP-42-authenticated Nostr WebSocket
subscription as the default inbound path (transport=auto|websocket|poll),
kind-44100 membership events for live DM discovery, since-timestamp
resume on reconnect with bounded exponential backoff, and automatic
fallback to CLI polling when the WS can't be established. Events route
through the same _handle_event() pipeline as the poll loop, so de-dupe,
mention gating, p-tag DM latching, and allow-lists behave identically on
both transports. Outbound stays on the CLI (one-shot sends never race a
WS auth handshake — his design).

E2E verified against a real in-process websockets relay: NIP-42
challenge -> signed kind-22242 AUTH (event id re-derived server-side) ->
REQ subscription -> EVENT dispatch -> clean disconnect.

Co-authored-by: ScaleLeanChris <chris@scalelean.com>
This commit is contained in:
Teknium 2026-07-28 18:22:28 -07:00
parent 21c7b806a3
commit 07e931fcb4
5 changed files with 509 additions and 5 deletions

View file

@ -21,6 +21,14 @@ requires_env:
prompt: "Nostr private key (nsec or hex)"
password: true
optional_env:
- name: BUZZ_TRANSPORT
description: "Inbound transport: auto (WebSocket w/ poll fallback, default), websocket, or poll"
prompt: "Transport (auto/websocket/poll)"
password: false
- name: BUZZ_AUTH_TAG
description: "Optional NIP-OA owner-attestation auth tag JSON for NIP-42 WebSocket auth"
prompt: "NIP-OA auth tag JSON (or empty)"
password: false
- name: BUZZ_CHANNELS
description: "Comma-separated channel UUIDs to watch (default: all joined channels)"
prompt: "Channel UUIDs (comma-separated)"