diff --git a/src/lib/components/PublicationHeader.svelte b/src/lib/components/PublicationHeader.svelte
index f9ded78..c7f9e15 100644
--- a/src/lib/components/PublicationHeader.svelte
+++ b/src/lib/components/PublicationHeader.svelte
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
+
diff --git a/src/lib/components/util/Profile.svelte b/src/lib/components/util/Profile.svelte
index fd23c9f..6918677 100644
--- a/src/lib/components/util/Profile.svelte
+++ b/src/lib/components/util/Profile.svelte
@@ -70,25 +70,21 @@ function shortenNpub(long: string|undefined) {
{#if isNav}
-
Sign out
-
+
{:else}
{/if}
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
index 021c979..35d6e03 100644
--- a/src/lib/utils.ts
+++ b/src/lib/utils.ts
@@ -10,6 +10,20 @@ export function neventEncode(event: NDKEvent, relays: string[]) {
});
}
+export function naddrEncode(event: NDKEvent, relays: string[]) {
+ const dTag = event.getMatchingTags('d')[0]?.[1];
+ if (!dTag) {
+ throw new Error('Event does not have a d tag');
+ }
+
+ return nip19.naddrEncode({
+ identifier: dTag,
+ pubkey: event.pubkey,
+ kind: event.kind || 0,
+ relays,
+ });
+}
+
export function formatDate(unixtimestamp: number) {
const months = [
"Jan",
diff --git a/src/routes/publication/+page.ts b/src/routes/publication/+page.ts
index 7fddcdc..052cc75 100644
--- a/src/routes/publication/+page.ts
+++ b/src/routes/publication/+page.ts
@@ -1,43 +1,90 @@
import { error } from '@sveltejs/kit';
import type { NDKEvent } from '@nostr-dev-kit/ndk';
import type { PageLoad } from './$types';
+import { nip19 } from 'nostr-tools';
import { getActiveRelays } from '$lib/ndk.ts';
import { setContext } from 'svelte';
import { PublicationTree } from '$lib/data_structures/publication_tree.ts';
+/**
+ * Decodes an naddr identifier and returns a filter object
+ */
+function decodeNaddr(id: string) {
+ try {
+ if (!id.startsWith('naddr1')) 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 {};
+ }
+}
+
+/**
+ * Fetches an event by ID or filter
+ */
+async function fetchEventById(ndk: any, id: string): Promise {
+ const filter = decodeNaddr(id);
+ 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 for ID: ${id}\n${err}`);
+ }
+}
+
+/**
+ * Fetches an event by d tag
+ */
+async function fetchEventByDTag(ndk: any, dTag: string): Promise {
+ 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 for d tag: ${dTag}\n${err}`);
+ }
+}
+
export const load: PageLoad = async ({ url, parent }: { url: URL; parent: () => Promise }) => {
const id = url.searchParams.get('id');
const dTag = url.searchParams.get('d');
-
const { ndk, parser } = await parent();
-
- let eventPromise: Promise;
- let indexEvent: NDKEvent | null;
-
- if (id) {
- eventPromise = ndk.fetchEvent(id)
- .then((ev: NDKEvent | null) => {
- return ev;
- })
- .catch((err: any) => {
- error(404, `Failed to fetch publication root event for ID: ${id}\n${err}`);
- });
- } else if (dTag) {
- eventPromise = new Promise(resolve => {
- ndk
- .fetchEvent({ '#d': [dTag] }, { closeOnEose: false }, getActiveRelays(ndk))
- .then((event: NDKEvent | null) => {
- resolve(event);
- })
- .catch((err: any) => {
- error(404, `Failed to fetch publication root event for d tag: ${dTag}\n${err}`);
- });
- });
- } else {
- error(400, 'No publication root event ID or d tag provided.');
+
+ if (!id && !dTag) {
+ throw error(400, 'No publication root event ID or d tag provided.');
}
-
- indexEvent = await eventPromise as NDKEvent;
+
+ // 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);