From 5dc365e9ecf56d4b4044fc9314ccebed0982c3e2 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Jan 2026 10:45:48 +0000 Subject: [PATCH] feat: Support naddr format for communikey definition events Adds support for opening communikey chats using naddr encoding of kind 10222 communikey definition events, not just bare pubkeys. Changes: - Extended parseIdentifier() to detect kind 10222 naddr - Extracts pubkey (author) as the communikey identifier - Extracts relay hints from naddr for better connectivity - Normalizes relay URLs to include wss:// prefix Users can now open communikeys in three ways: 1. chat naddr1... (kind 10222) - With relay hints from naddr 2. chat npub1xxx - Relays discovered from kind 10222 event 3. chat relay'npub1xxx - With explicit relay hint The naddr format is preferred as it includes relay hints for faster resolution of the communikey definition event. --- src/lib/chat/adapters/nip-29-adapter.ts | 65 +++++++++++++++++-------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/src/lib/chat/adapters/nip-29-adapter.ts b/src/lib/chat/adapters/nip-29-adapter.ts index 4c4f75f..693f685 100644 --- a/src/lib/chat/adapters/nip-29-adapter.ts +++ b/src/lib/chat/adapters/nip-29-adapter.ts @@ -44,37 +44,64 @@ export class Nip29Adapter extends ChatProtocolAdapter { * - wss://relay.example.com'bitcoin-dev (NIP-29) * - relay.example.com'bitcoin-dev (NIP-29, wss:// prefix is optional) * - naddr1... (kind 39000 group metadata address, NIP-29) + * - naddr1... (kind 10222 communikey definition, NIP-CC) * - relay.example.com'npub1xxx (NIP-CC communikey) * - npub1xxx (NIP-CC communikey, relays from kind 10222) * - hex-pubkey (NIP-CC communikey, relays from kind 10222) */ parseIdentifier(input: string): ProtocolIdentifier | null { - // Try naddr format first (kind 39000 group metadata) + // Try naddr format first if (input.startsWith("naddr1")) { try { const decoded = nip19.decode(input); - if (decoded.type === "naddr" && decoded.data.kind === 39000) { - const { identifier, relays } = decoded.data; - const relayUrl = relays?.[0]; + if (decoded.type === "naddr") { + // NIP-29 group metadata (kind 39000) + if (decoded.data.kind === 39000) { + const { identifier, relays } = decoded.data; + const relayUrl = relays?.[0]; - if (!identifier || !relayUrl) { - return null; + if (!identifier || !relayUrl) { + return null; + } + + // Ensure relay URL has wss:// prefix + let normalizedRelay = relayUrl; + if ( + !normalizedRelay.startsWith("ws://") && + !normalizedRelay.startsWith("wss://") + ) { + normalizedRelay = `wss://${normalizedRelay}`; + } + + return { + type: "group", + value: identifier, + relays: [normalizedRelay], + }; } - // Ensure relay URL has wss:// prefix - let normalizedRelay = relayUrl; - if ( - !normalizedRelay.startsWith("ws://") && - !normalizedRelay.startsWith("wss://") - ) { - normalizedRelay = `wss://${normalizedRelay}`; - } + // NIP-CC communikey definition (kind 10222) + if (decoded.data.kind === 10222) { + const { pubkey, relays } = decoded.data; - return { - type: "group", - value: identifier, - relays: [normalizedRelay], - }; + if (!pubkey) { + return null; + } + + // Normalize relay URLs + const normalizedRelays = (relays || []).map((url) => { + if (!url.startsWith("ws://") && !url.startsWith("wss://")) { + return `wss://${url}`; + } + return url; + }); + + return { + type: "group", + value: pubkey, // Use pubkey as the group ID + relays: normalizedRelays, + }; + } } } catch { // Not a valid naddr, fall through to try other formats