You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
2.7 KiB
107 lines
2.7 KiB
import { error } from '@sveltejs/kit'; |
|
import type { Load } from '@sveltejs/kit'; |
|
import type { NDKEvent } from '@nostr-dev-kit/ndk'; |
|
import { nip19 } from 'nostr-tools'; |
|
import { getActiveRelays } from '$lib/ndk.ts'; |
|
|
|
/** |
|
* Decodes an naddr identifier and returns a filter object |
|
*/ |
|
function decodeNaddr(id: string) { |
|
try { |
|
if (!id.startsWith('naddr')) return {}; |
|
|
|
const decoded = nip19.decode(id); |
|
if (decoded.type !== 'naddr') return {}; |
|
|
|
const data = decoded.data; |
|
return { |
|
kinds: [data.kind], |
|
authors: [data.pubkey], |
|
'#d': [data.identifier] |
|
}; |
|
} catch (e) { |
|
console.error('Failed to decode naddr:', e); |
|
return null; |
|
} |
|
} |
|
|
|
/** |
|
* Fetches an event by ID or filter |
|
*/ |
|
async function fetchEventById(ndk: any, id: string): Promise<NDKEvent> { |
|
const filter = decodeNaddr(id); |
|
|
|
// Handle the case where filter is null (decoding error) |
|
if (filter === null) { |
|
// If we can't decode the naddr, try using the raw ID |
|
try { |
|
const event = await ndk.fetchEvent(id); |
|
if (!event) { |
|
throw new Error(`Event not found for ID: ${id}`); |
|
} |
|
return event; |
|
} catch (err) { |
|
throw error(404, `Failed to fetch publication root event.\n${err}`); |
|
} |
|
} |
|
|
|
const hasFilter = Object.keys(filter).length > 0; |
|
|
|
try { |
|
const event = await (hasFilter ? |
|
ndk.fetchEvent(filter) : |
|
ndk.fetchEvent(id)); |
|
|
|
if (!event) { |
|
throw new Error(`Event not found for ID: ${id}`); |
|
} |
|
return event; |
|
} catch (err) { |
|
throw error(404, `Failed to fetch publication root event.\n${err}`); |
|
} |
|
} |
|
|
|
/** |
|
* Fetches an event by d tag |
|
*/ |
|
async function fetchEventByDTag(ndk: any, dTag: string): Promise<NDKEvent> { |
|
try { |
|
const event = await ndk.fetchEvent( |
|
{ '#d': [dTag] }, |
|
{ closeOnEose: false }, |
|
getActiveRelays(ndk) |
|
); |
|
|
|
if (!event) { |
|
throw new Error(`Event not found for d tag: ${dTag}`); |
|
} |
|
return event; |
|
} catch (err) { |
|
throw error(404, `Failed to fetch publication root event.\n${err}`); |
|
} |
|
} |
|
|
|
export const load: Load = async ({ url, parent }: { url: URL; parent: () => Promise<any> }) => { |
|
const id = url.searchParams.get('id'); |
|
const dTag = url.searchParams.get('d'); |
|
const { ndk, parser } = await parent(); |
|
|
|
if (!id && !dTag) { |
|
throw error(400, 'No publication root event ID or d tag provided.'); |
|
} |
|
|
|
// Fetch the event based on available parameters |
|
const indexEvent = id |
|
? await fetchEventById(ndk, id) |
|
: await fetchEventByDTag(ndk, dTag!); |
|
|
|
const publicationType = indexEvent?.getMatchingTags('type')[0]?.[1]; |
|
const fetchPromise = parser.fetch(indexEvent); |
|
|
|
return { |
|
waitable: fetchPromise, |
|
publicationType, |
|
indexEvent, |
|
}; |
|
};
|
|
|