feat: nip05 feeds

This commit is contained in:
codytseng 2025-06-26 23:21:12 +08:00
parent e08172f4a7
commit 5619905ae0
28 changed files with 395 additions and 165 deletions

View file

@ -11,17 +11,20 @@ export const toNote = (eventOrId: Pick<Event, 'id' | 'pubkey'> | string) => {
export const toNoteList = ({
hashtag,
search,
externalContentId
externalContentId,
domain
}: {
hashtag?: string
search?: string
externalContentId?: string
domain?: string
}) => {
const path = '/notes'
const query = new URLSearchParams()
if (hashtag) query.set('t', hashtag.toLowerCase())
if (search) query.set('s', search)
if (externalContentId) query.set('i', externalContentId)
if (domain) query.set('d', domain)
return `${path}?${query.toString()}`
}
export const toProfile = (userId: string) => {
@ -29,10 +32,11 @@ export const toProfile = (userId: string) => {
const npub = nip19.npubEncode(userId)
return `/users/${npub}`
}
export const toProfileList = ({ search }: { search?: string }) => {
export const toProfileList = ({ search, domain }: { search?: string; domain?: string }) => {
const path = '/users'
const query = new URLSearchParams()
if (search) query.set('s', search)
if (domain) query.set('d', domain)
return `${path}?${query.toString()}`
}
export const toFollowingList = (pubkey: string) => {

View file

@ -1,4 +1,5 @@
import { LRUCache } from 'lru-cache'
import { isValidPubkey } from './pubkey'
type TVerifyNip05Result = {
isVerified: boolean
@ -20,7 +21,7 @@ async function _verifyNip05(nip05: string, pubkey: string): Promise<TVerifyNip05
if (!nip05Name || !nip05Domain || !pubkey) return result
try {
const res = await fetch(`https://${nip05Domain}/.well-known/nostr.json?name=${nip05Name}`)
const res = await fetch(getWellKnownNip05Url(nip05Domain, nip05Name))
const json = await res.json()
if (json.names?.[nip05Name] === pubkey) {
return { ...result, isVerified: true }
@ -39,3 +40,32 @@ export async function verifyNip05(nip05: string, pubkey: string): Promise<TVerif
const [nip05Name, nip05Domain] = nip05?.split('@') || [undefined, undefined]
return { isVerified: false, nip05Name, nip05Domain }
}
export function getWellKnownNip05Url(domain: string, name?: string): string {
const url = new URL('/.well-known/nostr.json', `https://${domain}`)
if (name) {
url.searchParams.set('name', name)
}
return url.toString()
}
export async function fetchPubkeysFromDomain(domain: string): Promise<string[]> {
try {
const res = await fetch(getWellKnownNip05Url(domain))
const json = await res.json()
const pubkeySet = new Set<string>()
return Object.values(json.names || {}).filter((pubkey) => {
if (typeof pubkey !== 'string' || !isValidPubkey(pubkey)) {
return false
}
if (pubkeySet.has(pubkey)) {
return false
}
pubkeySet.add(pubkey)
return true
}) as string[]
} catch (error) {
console.error('Error fetching pubkeys from domain:', error)
return []
}
}