diff --git a/src/lib/utils/notification_utils.ts b/src/lib/utils/notification_utils.ts index d90e7f4..b0f15c9 100644 --- a/src/lib/utils/notification_utils.ts +++ b/src/lib/utils/notification_utils.ts @@ -4,9 +4,11 @@ import { getUserMetadata, NDKRelaySetFromNDK, toNpub } from "$lib/utils/nostrUti import { get } from "svelte/store"; import { ndkInstance } from "$lib/ndk"; import { searchRelays } from "$lib/consts"; -import { userStore } from "$lib/stores/userStore"; +import { userStore, type UserState } from "$lib/stores/userStore"; import { buildCompleteRelaySet } from "$lib/utils/relay_management"; import { neventEncode } from "$lib/utils"; +import { nip19 } from "nostr-tools"; +import type NDK from "@nostr-dev-kit/ndk"; // AI-NOTE: Notification-specific utility functions that don't exist elsewhere @@ -82,19 +84,22 @@ export async function renderQuotedContent(message: NDKEvent, publicMessages: NDK const eventId = qTag[1]; if (eventId) { + // Validate eventId format (should be 64 character hex string) + const isValidEventId = /^[a-fA-F0-9]{64}$/.test(eventId); + // First try to find in local messages let quotedMessage = publicMessages.find(msg => msg.id === eventId); // If not found locally, fetch from relays if (!quotedMessage) { try { - const ndk = get(ndkInstance); + const ndk: NDK | undefined = get(ndkInstance); if (ndk) { - const userStoreValue = get(userStore); - const user = userStoreValue.signedIn && userStoreValue.pubkey ? ndk.getUser({ pubkey: userStoreValue.pubkey }) : null; - const relaySet = await buildCompleteRelaySet(ndk, user); - const allRelays = [...relaySet.inboxRelays, ...relaySet.outboxRelays, ...searchRelays]; - + const userStoreValue: UserState = get(userStore); + const user = userStoreValue.signedIn && userStoreValue.pubkey ? ndk.getUser({ pubkey: userStoreValue.pubkey }) : null; + const relaySet = await buildCompleteRelaySet(ndk, user); + const allRelays = [...relaySet.inboxRelays, ...relaySet.outboxRelays, ...searchRelays]; + if (allRelays.length > 0) { const ndkRelaySet = NDKRelaySetFromNDK.fromRelayUrls(allRelays, ndk); const fetchedEvent = await ndk.fetchEvent({ ids: [eventId], limit: 1 }, undefined, ndkRelaySet); @@ -111,9 +116,20 @@ export async function renderQuotedContent(message: NDKEvent, publicMessages: NDK const parsedContent = await parseBasicmarkup(quotedContent); return `
${parsedContent}
`; } else { - // Fallback to nevent link - const nevent = neventEncode({ id: eventId } as any, []); - return `
Quoted message not found. Click to view event ${eventId.slice(0, 8)}...
`; + // Fallback to nevent link - only if eventId is valid + if (isValidEventId) { + try { + const nevent = nip19.neventEncode({ id: eventId }); + return `
Quoted message not found. Click to view event ${eventId.slice(0, 8)}...
`; + } catch (error) { + console.warn(`[renderQuotedContent] Failed to encode nevent for ${eventId}:`, error); + // Fall back to just showing the event ID without a link + return `
Quoted message not found. Event ID: ${eventId.slice(0, 8)}...
`; + } + } else { + // Invalid event ID format + return `
Invalid quoted message reference
`; + } } } @@ -161,7 +177,7 @@ export async function fetchAuthorProfiles(events: NDKEvent[]): Promise