Remove callManager injection from EventProcessor — let the existing
gift wrap pipeline consume and index call events normally. Instead,
observe new notes from LocalCache.live.newEventBundles in
AccountViewModel and route call signaling events to CallManager
from there. This keeps the EventProcessor clean and follows the
existing pattern for UI-layer event observation.
https://claude.ai/code/session_017hZm7yu7CzmcQgZGSaqSXS
Add CallOfferEvent, CallAnswerEvent, CallIceCandidateEvent,
CallHangupEvent, CallRejectEvent, and CallRenegotiateEvent to
LocalCache.justConsumeInnerInner() so they are properly consumed
and indexed when received from relays.
https://claude.ai/code/session_017hZm7yu7CzmcQgZGSaqSXS
Connects all call infrastructure so calls flow through the system:
- EventProcessor routes unwrapped call events (offer/answer/ICE/
hangup/reject) from gift wraps to CallManager
- CallController orchestrates WebRTC session lifecycle: creates
PeerConnection, generates SDP offers/answers, exchanges ICE
candidates via gift-wrapped events, and manages foreground service
- AccountViewModel initializes CallManager + CallController and
wires answer/ICE callbacks between them
- Account.publishCallSignaling() publishes gift-wrapped events
- DM chat top bar gets a call button (1-on-1 rooms only) that
initiates a voice call and navigates to ActiveCall screen
- ActiveCall route registered in AppNavigation with CallScreen
https://claude.ai/code/session_017hZm7yu7CzmcQgZGSaqSXS
Specifies the signaling protocol for P2P voice/video calls:
- 6 event kinds (25050-25055) for offer/answer/ICE/hangup/reject/renegotiate
- NIP-59 gift wrap delivery (no seal layer)
- Follow-gated spam prevention
- Short expiration for ephemeral signaling data
https://claude.ai/code/session_017hZm7yu7CzmcQgZGSaqSXS
Implements P2P calling over Nostr relays using WebRTC for media
transport and NIP-59 Gift Wraps for encrypted signaling. No custom
server required — only public STUN servers for NAT traversal.
Protocol layer (quartz/nip100WebRtcCalls):
- 6 new event kinds (25050-25055): offer, answer, ICE candidate,
hangup, reject, renegotiate
- WebRtcCallFactory for creating and gift-wrapping signaling events
- CallIdTag and CallTypeTag for event metadata
- Events registered in EventFactory
Call state machine (commons/call):
- CallState sealed interface with full lifecycle states
- CallManager orchestrating signaling and state transitions
- Follow-gate spam prevention: only followed users can ring,
non-follows are silently ignored
Android WebRTC integration (amethyst/service/call):
- WebRtcCallSession wrapping Google WebRTC PeerConnection
- CallForegroundService for keeping calls alive in background
- IceServerConfig with default public STUN servers
- User-configurable TURN server support
Android UI (amethyst/ui/call):
- CallScreen with offering, connecting, connected, and ended states
- IncomingCallUI with accept/reject buttons
- ConnectedCallUI with mute, video toggle, speaker, and timer
- Call button added to 1-on-1 DM chat header
- ActiveCall route added to navigation
https://claude.ai/code/session_017hZm7yu7CzmcQgZGSaqSXS
Instead of replacing the new bookmark list, the migration now checks for
an existing kind 10003 event and merges old bookmarks into it, skipping
duplicates that already exist.
https://claude.ai/code/session_01U9sjQHQMVVHxYiesoXjqop
Rename the existing BookmarkListEvent (kind 30001) to OldBookmarkListEvent
and create a new BookmarkListEvent with kind 10003 as per the updated spec.
- OldBookmarkListEvent (kind 30001): Kept as-is for backward compatibility,
displayed as "Old Bookmarks" in the Bookmark Lists screen
- BookmarkListEvent (kind 10003): New replaceable event, all new bookmark
operations (save/check/remove) use this kind
- Both kinds are displayed as separate items in the Bookmark Lists screen
- Old Bookmarks screen includes a "Move All to New Bookmarks" button that
migrates public bookmarks to public and private to private
- Created PrivateReplaceableTagArrayEvent base class for replaceable events
with encrypted private tags (kind 10003 is in the 10000-19999 range)
- Updated all relay filters, search queries, and profile views to fetch
both kinds
- Updated Android and Desktop modules
https://claude.ai/code/session_01U9sjQHQMVVHxYiesoXjqop