diff --git a/src/components/ChatViewer.tsx b/src/components/ChatViewer.tsx index ef3b89b..f65019b 100644 --- a/src/components/ChatViewer.tsx +++ b/src/components/ChatViewer.tsx @@ -940,6 +940,28 @@ export function ChatViewer({ {conversation.metadata.description}

)} + {/* Participants for NIP-17 group DMs */} + {protocol === "nip-17" && + conversation.participants.length > 2 && ( +
+ + Participants: + +
+ {[ + ...new Set( + conversation.participants.map((p) => p.pubkey), + ), + ].map((participantPubkey) => ( + + ))} +
+
+ )} {/* Protocol Type - Clickable */}
{(conversation.type === "group" || diff --git a/src/lib/chat/adapters/nip-17-adapter.ts b/src/lib/chat/adapters/nip-17-adapter.ts index d7af0a5..711812f 100644 --- a/src/lib/chat/adapters/nip-17-adapter.ts +++ b/src/lib/chat/adapters/nip-17-adapter.ts @@ -462,8 +462,9 @@ export class Nip17Adapter extends ChatProtocolAdapter { * Helper: Get conversation key from conversation */ private getConversationKey(conversation: Conversation): string { - const pubkeys = conversation.participants.map((p) => p.pubkey).sort(); - return pubkeys.join(":"); + const pubkeys = conversation.participants.map((p) => p.pubkey); + // Deduplicate and sort for consistency with gift wrap storage + return [...new Set(pubkeys)].sort().join(":"); } /** diff --git a/src/services/gift-wrap.ts b/src/services/gift-wrap.ts index 5d93238..434dd36 100644 --- a/src/services/gift-wrap.ts +++ b/src/services/gift-wrap.ts @@ -775,9 +775,22 @@ class GiftWrapManager { throw new Error(`Failed to unlock gift wrap: ${error}`); } - // Use applesauce helper to get the conversation identifier - // This properly handles all participants including group DMs - const conversationKey = getConversationIdentifierFromMessage(rumor); + // Generate conversation key based on rumor kind + // For kind 14 (DMs), use applesauce helper which handles groups properly + // For other kinds (reactions, etc.), extract participants from p-tags + let conversationKey: string; + if (rumor.kind === 14) { + // Use applesauce helper for DMs - it properly handles group DMs + conversationKey = getConversationIdentifierFromMessage(rumor); + } else { + // For non-DM events (reactions, private relays, etc.), + // create conversation key from sender + all p-tags + const recipientPubkeys = rumor.tags + .filter((t: string[]) => t[0] === "p" && t[1]) + .map((t: string[]) => t[1]); + const allParticipants = [rumor.pubkey, ...recipientPubkeys]; + conversationKey = [...new Set(allParticipants)].sort().join(":"); + } // Get seal ID from gift wrap tags (applesauce stores it there) const sealId = rumor.id.split(":")[1] || giftWrap.id;