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
Adds 6 preview functions covering:
- PictureCardCompose with title, without title, and multi-image
- PictureCardCaption with title, without title, and long content
- Uses ThemeComparisonColumn for light/dark theme comparison
- Uses mock PictureEvent JSON data consumed via LocalCache
https://claude.ai/code/session_01KtuzFmDZXk67tW8QxPqmMy