Use app relays for loser's race instead of separate profile relays
- Removed hardcoded PROFILE_RELAYS list - Loser's race now queries the same relays as the pool - Gets effective relays from app config (user relays + app relays) - Queries each relay individually with 5000ms timeout (vs 500ms EOSE in pool) - Solves issue where profiles exist on app relays (like nos.lol) but not on hardcoded profile relays - Now covers all relays user has configured instead of arbitrary subset Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
+14
-12
@@ -1,15 +1,8 @@
|
||||
import { type NostrEvent, type NostrMetadata, NSchema as n } from '@nostrify/nostrify';
|
||||
import { useNostr } from '@nostrify/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
/** Profile relay URLs used as fallback when the pool's EOSE timeout returns empty. */
|
||||
export const PROFILE_RELAYS = [
|
||||
'wss://relay.primal.net',
|
||||
'wss://relay.damus.io',
|
||||
'wss://relay.ditto.pub',
|
||||
'wss://ditto.pub/relay',
|
||||
'wss://purplepag.es',
|
||||
];
|
||||
import { useAppContext } from '@/hooks/useAppContext';
|
||||
import { getEffectiveRelays } from '@/lib/appRelays';
|
||||
|
||||
/** Parse a kind-0 event into metadata + event, or return just the event on parse failure. */
|
||||
export function parseAuthorEvent(event: NostrEvent): { event: NostrEvent; metadata?: NostrMetadata } {
|
||||
@@ -23,6 +16,11 @@ export function parseAuthorEvent(event: NostrEvent): { event: NostrEvent; metada
|
||||
|
||||
export function useAuthor(pubkey: string | undefined) {
|
||||
const { nostr } = useNostr();
|
||||
const { config } = useAppContext();
|
||||
|
||||
// Get the effective relays (same ones used by the pool)
|
||||
const effectiveRelays = getEffectiveRelays(config.relayMetadata, config.useAppRelays);
|
||||
const readRelayUrls = effectiveRelays.relays.filter(r => r.read).map(r => r.url);
|
||||
|
||||
return useQuery<{ event?: NostrEvent; metadata?: NostrMetadata }>({
|
||||
queryKey: ['author', pubkey ?? ''],
|
||||
@@ -44,12 +42,16 @@ export function useAuthor(pubkey: string | undefined) {
|
||||
}
|
||||
|
||||
// Slow path: pool returned empty (EOSE timeout may have cut off slower relays).
|
||||
// Query each relay individually and resolve on first hit.
|
||||
// Query each relay individually (same relays as pool, but with more time).
|
||||
if (readRelayUrls.length === 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return new Promise<{ event?: NostrEvent; metadata?: NostrMetadata }>((resolve) => {
|
||||
let settled = false;
|
||||
let pending = PROFILE_RELAYS.length;
|
||||
let pending = readRelayUrls.length;
|
||||
|
||||
for (const url of PROFILE_RELAYS) {
|
||||
for (const url of readRelayUrls) {
|
||||
nostr.relay(url).query(
|
||||
[{ kinds: [0], authors: [pubkey!], limit: 1 }],
|
||||
{ signal: combinedSignal },
|
||||
|
||||
+14
-7
@@ -1,7 +1,9 @@
|
||||
import { type NostrEvent, type NostrMetadata } from '@nostrify/nostrify';
|
||||
import { useNostr } from '@nostrify/react';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { parseAuthorEvent, PROFILE_RELAYS } from '@/hooks/useAuthor';
|
||||
import { parseAuthorEvent } from '@/hooks/useAuthor';
|
||||
import { useAppContext } from '@/hooks/useAppContext';
|
||||
import { getEffectiveRelays } from '@/lib/appRelays';
|
||||
|
||||
export interface AuthorData {
|
||||
pubkey: string;
|
||||
@@ -21,6 +23,11 @@ export interface AuthorData {
|
||||
export function useAuthors(pubkeys: string[]) {
|
||||
const { nostr } = useNostr();
|
||||
const queryClient = useQueryClient();
|
||||
const { config } = useAppContext();
|
||||
|
||||
// Get the effective relays (same ones used by the pool)
|
||||
const effectiveRelays = getEffectiveRelays(config.relayMetadata, config.useAppRelays);
|
||||
const readRelayUrls = effectiveRelays.relays.filter(r => r.read).map(r => r.url);
|
||||
|
||||
// Deduplicate and sort for a stable query key
|
||||
const uniquePubkeys = [...new Set(pubkeys)].sort();
|
||||
@@ -56,16 +63,16 @@ export function useAuthors(pubkeys: string[]) {
|
||||
found.add(event.pubkey);
|
||||
}
|
||||
|
||||
// Slow path: for any pubkeys not found by the pool, query relays individually.
|
||||
// This is the "loser's race" - we query specific profile relays that may have
|
||||
// been cut off by the pool's EOSE timeout.
|
||||
// Slow path: for any pubkeys not found by the pool, query each relay individually.
|
||||
// This is the "loser's race" - we query the same relays from the pool, but
|
||||
// individually with more time (5000ms vs 500ms EOSE timeout).
|
||||
const missing = uniquePubkeys.filter(pk => !found.has(pk));
|
||||
if (missing.length > 0) {
|
||||
if (missing.length > 0 && readRelayUrls.length > 0) {
|
||||
await new Promise<void>((resolve) => {
|
||||
const needed = new Set(missing);
|
||||
let pending = PROFILE_RELAYS.length;
|
||||
let pending = readRelayUrls.length;
|
||||
|
||||
for (const url of PROFILE_RELAYS) {
|
||||
for (const url of readRelayUrls) {
|
||||
nostr.relay(url).query(
|
||||
[{ kinds: [0], authors: missing, limit: missing.length }],
|
||||
{ signal: combinedSignal },
|
||||
|
||||
Reference in New Issue
Block a user