TrustBadge called useTrustScore per card, which fetched the viewer's follow list plus up to 100 friends' follow lists for EVERY card. The graph does not depend on the target, so useViewerGraph computes it once per viewer (one shared React Query) and deriveLocalScore returns the same 100/90/60/0 ladder (the NIP-05 30 tier classified as unknown anyway). TrustBadge now costs no per-card network work on top of the batched assertion read. Behaviour preserved; logged-out users still use the house graph. Also records the ANALYZE=1 bundle findings in AGENTS.md.
46 lines
1.8 KiB
TypeScript
46 lines
1.8 KiB
TypeScript
import { useCurrentUser } from './useCurrentUser';
|
|
import { useViewerGraph, deriveLocalScore } from './useViewerGraph';
|
|
import { useTrustAssertions } from './useTrustAssertions';
|
|
import { bucketFromAssertion, bucketFromLocalScore, type TrustBucket } from '@/lib/trustLadder';
|
|
import type { UserTrustAssertion } from '@/lib/nip85';
|
|
|
|
export interface TrustBucketResult {
|
|
bucket: TrustBucket;
|
|
/** Provider assertion backing the bucket, when one exists. */
|
|
assertion?: UserTrustAssertion;
|
|
/** Local web-of-trust score (0-100), when available. */
|
|
localScore?: number;
|
|
/** The viewer directly follows this account (or it is the viewer). */
|
|
directFollow: boolean;
|
|
isLoading: boolean;
|
|
}
|
|
|
|
/**
|
|
* Resolve a viewer-facing trust bucket for one pubkey. Prefers a NIP-85
|
|
* assertion (it can both verify and flag); otherwise falls back to the local
|
|
* web-of-trust ladder (verify only — it has no negative signal).
|
|
*
|
|
* Both inputs are batched/shared: the assertion read is a shared per-viewer
|
|
* batch, and the local graph is computed once per viewer — so a grid of badges
|
|
* costs no per-card network work.
|
|
*/
|
|
export function useTrustBucket(pubkey: string | undefined): TrustBucketResult {
|
|
const { user } = useCurrentUser();
|
|
const { data: graph, isLoading: graphLoading } = useViewerGraph();
|
|
const { data: assertions, isLoading: assertionsLoading } = useTrustAssertions(
|
|
pubkey ? [pubkey] : [],
|
|
);
|
|
|
|
const assertion = pubkey ? assertions?.get(pubkey) : undefined;
|
|
const localScore = deriveLocalScore(graph, pubkey, user?.pubkey);
|
|
const bucket = assertion ? bucketFromAssertion(assertion) : bucketFromLocalScore(localScore);
|
|
const directFollow = localScore !== undefined && localScore >= 90;
|
|
|
|
return {
|
|
bucket,
|
|
assertion,
|
|
localScore,
|
|
directFollow,
|
|
isLoading: graphLoading || assertionsLoading,
|
|
};
|
|
}
|