SkateSpots/GROUP_MESSAGING.md

2.9 KiB

Group Messaging

What ships today (NIP-17 group DMs)

SkateSpots group chat uses the NIP-17 fan-out primitive — the same encryption path as 1:1 DMs, just addressed to more than one person:

  • The sender builds one kind-14 rumor with a p tag per recipient, then encrypts that same rumor to each recipient separately inside a kind-13 seal, wrapped in a kind-1059 gift wrap addressed only to them.
  • Anyone receiving a rumor with more than one p tag is in a group.
  • A group is identified by getGroupId(participants) — the sorted, joined participant pubkeys — so every client derives the same id.

Implementation:

Piece File
Send (1:1 or group) useDirectMessages.ts → useSendDirectMessage (createRumor)
List groups (inbox) useDirectMessages.ts → useGroupConversations
Group thread useDirectMessages.ts → useGroupConversation(participants)
Thread UI pages/GroupConversationPage.tsx → /messages/group/:participants
Create a group components/NewMessageDialog.tsx (multi-select → Start group)

Honest limitations

This primitive is simple and interoperable, but it is not a modern group protocol:

  • No forward secrecy / post-compromise security. One leaked message key can expose that message (and, with a leaked identity key, the whole history).
  • No membership ratchet or roster. "Membership" is just whoever is in the p tags; there is no cryptographic join/leave, and no automatic rekey when someone is removed.
  • Fan-out cost is O(n) per message (one sealed copy per recipient).
  • Metadata (timing, group size) is visible to relays.

Good enough for casual crew/community chats. Not appropriate for high-stakes or large public rooms.

Upgrade paths (when the guarantees matter)

From Encrypted Group Chat on Nostr: Marmot, Concord, and Cordn Compared (https://nostrdev.com/blog/nostr-group-chat-protocols/):

Protocol Crypto Use when
Marmot MLS (RFC 9420), no privileged server Small, high-stakes groups needing forward secrecy + post-compromise security; the most mature spec and a flagship Rust implementation (MDK)
Concord Shared key + NIP-59 giftwrap, signed roster Large, public, Discord-style communities (channels/roles/moderation). Trades forward secrecy for scale
Cordn MLS via a per-group coordinator (ContextVM) MLS guarantees where running/finding a small self-hostable coordinator is acceptable; best public-metadata story

Migration would be additive: keep the NIP-17 threads for casual DMs and adopt one of the above for rooms that need ratcheting, rosters and moderation. Revisit when the target protocol's spec has stabilised.

Decision

Ship NIP-17 group DMs now (zero new protocols, reuses the DM stack); adopt Marmot if/when teams need Signal-grade guarantees, and Concord if the goal becomes large public communities. See the article above for the trade-offs.