SkateSpots/src/hooks/useLoggedInAccounts.ts
shakespeare.diy aea66d11e2 Fix 78 pre-existing TypeScript errors surfaced by npm test
- useDirectMessages: correct nip44 getConversationKey (Uint8Array) + finalizeEvent EventTemplate (remove pubkey/unused ephemeralPubkey/bytesToHex)
- Access current-user metadata via useCurrentUser() spread instead of user.metadata across ~10 files (rename to userMetadata where author metadata already bound)
- useCrewGoal: explicit UseQueryResult<CrewGoal|null> return type (fixes CrewForm/CrewTreasuryCard {} inference)
- New useCommentCounts hook; fix EventsPage/MapPage misuse of useComments(string[])
- CoachDetailPage: typed pget/pbool accessors for craft-specific union fields
- MapPage: shop entries include tags/category to satisfy SkateSpot
- SkateGlobe: read event.tags; LabPage: remove duplicate serviceType; LabCrewsStrip: add 'judging'
- Icon prop widened to accept style; ReportDialog subtype guard; SecuritySettings/TourCard/EventsPage comparisons; CashuWallet onClick; ConversationPage recipients; useLoggedInAccounts NLoginType import; LicensePage icon; TourDetailPage ZapButton target + real npub link; TestApp useSkateRelay

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-03 21:18:02 +07:00

101 lines
No EOL
3.3 KiB
TypeScript

import { useNostr } from '@nostrify/react';
import { useNostrLogin, type NLoginType } from '@nostrify/react/login';
import { useQuery } from '@tanstack/react-query';
import { NSchema as n, NostrEvent, NostrMetadata } from '@nostrify/nostrify';
export interface Account {
id: string;
pubkey: string;
event?: NostrEvent;
metadata: NostrMetadata;
}
// Fallback relays for fetching profile data
const FALLBACK_RELAYS = [
'wss://relay.damus.io',
'wss://nos.lol',
'wss://purplepag.es',
];
export function useLoggedInAccounts() {
const { nostr } = useNostr();
const { logins, setLogin, removeLogin } = useNostrLogin();
// Extract pubkey safely — works for both standard NLoginType and custom AmberLoginType
const getPubkey = (login: NLoginType): string | undefined => {
return (login as unknown as { pubkey?: string }).pubkey;
};
const loginPubkeys = logins.map(getPubkey).filter((p): p is string => !!p);
const { data: authors = [] } = useQuery({
queryKey: ['nostr', 'logins', logins.map((l) => l.id).join(';')],
queryFn: async ({ signal }) => {
if (logins.length === 0) return [];
if (loginPubkeys.length === 0) return [];
// Try primary relays first with longer timeout
let events: NostrEvent[] = [];
try {
events = await nostr.query(
[{ kinds: [0], authors: loginPubkeys }],
{ signal: AbortSignal.any([signal, AbortSignal.timeout(5000)]) },
);
} catch (error) {
console.warn('[useLoggedInAccounts] Primary relay query failed, trying fallback relays...');
}
// If no events found, try fallback relays
if (events.length === 0) {
try {
const fallbackGroup = nostr.group(FALLBACK_RELAYS);
events = await fallbackGroup.query(
[{ kinds: [0], authors: loginPubkeys }],
{ signal: AbortSignal.any([signal, AbortSignal.timeout(8000)]) },
);
if (events.length > 0) {
console.log('[useLoggedInAccounts] Found profile on fallback relays');
}
} catch (error) {
console.warn('[useLoggedInAccounts] Fallback relay query also failed:', error);
}
}
return logins.map((login): Account => {
const id = login.id;
const pubkey = getPubkey(login) ?? '';
const event = events.find((e) => e.pubkey === pubkey);
try {
const metadata = n.json().pipe(n.metadata()).parse(event?.content);
return { id, pubkey, metadata, event };
} catch {
return { id, pubkey, metadata: {}, event };
}
});
},
retry: 3,
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 10000),
staleTime: 30000, // Consider data fresh for 30 seconds
});
// Current user is the first login
const currentUser: Account | undefined = (() => {
const login = logins[0];
if (!login) return undefined;
const pubkey = getPubkey(login) ?? '';
const author = authors.find((a) => a.id === login.id);
return { metadata: {}, ...author, id: login.id, pubkey };
})();
// Other users are all logins except the current one
const otherUsers = (authors || []).slice(1) as Account[];
return {
authors,
currentUser,
otherUsers,
setLogin,
removeLogin,
};
}