fix: query all 3 Nostr relays in parallel, pick latest profile (BUG-F8)
fetchNostrProfile now uses Promise.allSettled to query all relays concurrently. Aggregates results with latest-created_at-wins strategy instead of stopping at the first relay that responds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
c288b23c13
commit
8b72bef22e
@@ -581,26 +581,33 @@ async function fetchNostrProfilePic(pk: string): Promise<string | null> {
|
||||
return profile?.picture || null
|
||||
}
|
||||
|
||||
/** Fetch full Nostr profile (kind:0 metadata) with caching */
|
||||
/** Fetch full Nostr profile (kind:0 metadata) with caching.
|
||||
* Queries all relays in parallel, picks result with latest created_at. */
|
||||
async function fetchNostrProfile(pk: string): Promise<NostrProfile | null> {
|
||||
const cached = profileCache.get(pk)
|
||||
if (cached && Date.now() - cached.ts < PROFILE_TTL) return cached.data
|
||||
|
||||
for (const relay of RELAYS) {
|
||||
try {
|
||||
const profile = await queryRelayProfile(relay, pk)
|
||||
if (profile) {
|
||||
profileCache.set(pk, { data: profile, ts: Date.now() })
|
||||
return profile
|
||||
}
|
||||
} catch {
|
||||
continue
|
||||
const results = await Promise.allSettled(
|
||||
RELAYS.map(relay => queryRelayProfile(relay, pk))
|
||||
)
|
||||
|
||||
// Pick the profile with the latest created_at (newest wins)
|
||||
let best: { profile: NostrProfile; createdAt: number } | null = null
|
||||
for (const r of results) {
|
||||
if (r.status !== 'fulfilled' || !r.value) continue
|
||||
if (!best || r.value.createdAt > best.createdAt) {
|
||||
best = r.value
|
||||
}
|
||||
}
|
||||
|
||||
if (best) {
|
||||
profileCache.set(pk, { data: best.profile, ts: Date.now() })
|
||||
return best.profile
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function queryRelayProfile(url: string, pk: string): Promise<NostrProfile | null> {
|
||||
function queryRelayProfile(url: string, pk: string): Promise<{ profile: NostrProfile; createdAt: number } | null> {
|
||||
return new Promise((resolve) => {
|
||||
let timedOut = false
|
||||
const timeout = setTimeout(() => {
|
||||
@@ -625,11 +632,14 @@ function queryRelayProfile(url: string, pk: string): Promise<NostrProfile | null
|
||||
clearTimeout(timeout)
|
||||
ws.close()
|
||||
resolve({
|
||||
displayName: meta.display_name || meta.name || null,
|
||||
about: meta.about || null,
|
||||
picture: meta.picture || null,
|
||||
banner: meta.banner || null,
|
||||
nip05: meta.nip05 || null,
|
||||
profile: {
|
||||
displayName: meta.display_name || meta.name || null,
|
||||
about: meta.about || null,
|
||||
picture: meta.picture || null,
|
||||
banner: meta.banner || null,
|
||||
nip05: meta.nip05 || null,
|
||||
},
|
||||
createdAt: data[2].created_at || 0,
|
||||
})
|
||||
} else if (data[0] === 'EOSE') {
|
||||
clearTimeout(timeout)
|
||||
|
||||
Reference in New Issue
Block a user