diff --git a/src/app.css b/src/app.css
index 4988e6a..507dbf8 100644
--- a/src/app.css
+++ b/src/app.css
@@ -265,6 +265,9 @@
@apply bg-primary-50 text-primary-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-sm dark:bg-primary-900 dark:text-primary-200;
}
+ .npub-badge {
+ @apply inline-flex items-center text-primary-600 dark:text-primary-500 hover:underline me-2 px-2.5 py-0.5 rounded-sm border border-primary-600 dark:border-primary-500;
+ }
}
@layer components {
diff --git a/src/lib/snippets/UserSnippets.svelte b/src/lib/snippets/UserSnippets.svelte
new file mode 100644
index 0000000..62f9f60
--- /dev/null
+++ b/src/lib/snippets/UserSnippets.svelte
@@ -0,0 +1,13 @@
+
+
+{#snippet userBadge(identifier: string, displayText: string | undefined)}
+ {#await createProfileLinkWithVerification(identifier, displayText)}
+ {@html createProfileLink(identifier, displayText)}
+ {:then html}
+ {@html html}
+ {:catch}
+ {@html createProfileLink(identifier, displayText)}
+ {/await}
+{/snippet}
diff --git a/src/lib/utils/nostrUtils.ts b/src/lib/utils/nostrUtils.ts
index f702d24..48f593a 100644
--- a/src/lib/utils/nostrUtils.ts
+++ b/src/lib/utils/nostrUtils.ts
@@ -2,6 +2,11 @@ import { get } from 'svelte/store';
import { nip19 } from 'nostr-tools';
import { ndkInstance } from '$lib/ndk';
import { npubCache } from './npubCache';
+import { NDKUser } from "@nostr-dev-kit/ndk";
+
+const badgeCheckSvg = ''
+
+const graduationCapSvg = '';
// Regular expressions for Nostr identifiers - match the entire identifier including any prefix
export const NOSTR_PROFILE_REGEX = /(?@${escapedText}`;
+ return `@${escapedText}`;
}
+/**
+ * Create a profile link element with a NIP-05 verification indicator.
+ */
+export async function createProfileLinkWithVerification(identifier: string, displayText: string | undefined): Promise {
+ const ndk = get(ndkInstance) as NDK;
+ if (!ndk) {
+ return createProfileLink(identifier, displayText);
+ }
+
+ const cleanId = identifier.replace(/^nostr:/, '');
+ const isNpub = cleanId.startsWith('npub');
+
+ let user: NDKUser;
+ if (isNpub) {
+ user = ndk.getUser({ npub: cleanId });
+ } else {
+ user = ndk.getUser({ pubkey: cleanId });
+ }
+
+ const profile = await user.fetchProfile();
+ const nip05 = profile?.nip05;
+
+ if (!nip05) {
+ return createProfileLink(identifier, displayText);
+ }
+
+ const defaultText = `${cleanId.slice(0, 8)}...${cleanId.slice(-4)}`;
+ const escapedText = escapeHtml(displayText || defaultText);
+ const displayIdentifier = profile?.displayName ?? profile?.name ?? escapedText;
+
+ const isVerified = await user.validateNip05(nip05);
+
+ if (!isVerified) {
+ return createProfileLink(identifier, displayText);
+ }
+
+ // TODO: Make this work with an enum in case we add more types.
+ const type = nip05.endsWith('edu') ? 'edu' : 'standard';
+ switch (type) {
+ case 'edu':
+ return `${graduationCapSvg}@${displayIdentifier}`;
+ case 'standard':
+ return `${badgeCheckSvg}@${displayIdentifier}`;
+ }
+}
/**
* Create a note link element
*/