Full build: Vite/React acid-terminal frontend (BEARER design system, Panchang/Sentient/Fragment Mono, neon layer, palette audit script), HoodquidityVaults Foundry contracts (single+dual deposits via Chainlink-style feeds, hybrid exit, 10% platform fee, boost, Genesis LP), Reown AppKit wallet connect with Robinhood Chain testnet (46630), live data from Dexscreener and onchain reads, partner portal, design-sync setup for claude.ai/design. Deploy: static via Forgejo Actions platform, BUILD_DIR=apps/web/dist (.env). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
import { useQuery } from "@tanstack/react-query";
|
|
import { fetchPair, fetchBasket, type PairData } from "@/lib/dexscreener";
|
|
import type { MarketMeta } from "@/lib/contracts";
|
|
|
|
async function fetchMarket(meta: MarketMeta): Promise<PairData | null> {
|
|
if (meta.dexscreenerQuery.startsWith("basket:")) {
|
|
return fetchBasket(meta.dexscreenerQuery.slice("basket:".length).split(","));
|
|
}
|
|
return fetchPair(meta.dexscreenerQuery);
|
|
}
|
|
|
|
/** Live price / volume / liquidity for one market, refreshed every 30s. */
|
|
export function useMarketData(meta: MarketMeta) {
|
|
return useQuery({
|
|
queryKey: ["dexscreener", meta.dexscreenerQuery],
|
|
queryFn: () => fetchMarket(meta),
|
|
refetchInterval: 30_000,
|
|
staleTime: 25_000,
|
|
});
|
|
}
|
|
|
|
export function useAllMarketData(markets: MarketMeta[]) {
|
|
return useQuery({
|
|
queryKey: ["dexscreener-all", markets.map((m) => m.dexscreenerQuery).join()],
|
|
queryFn: async () => {
|
|
const results = await Promise.all(
|
|
markets.map((m) => fetchMarket(m).catch(() => null)),
|
|
);
|
|
return Object.fromEntries(
|
|
markets.map((m, i) => [m.symbol, results[i]]),
|
|
) as Record<string, PairData | null>;
|
|
},
|
|
refetchInterval: 30_000,
|
|
staleTime: 25_000,
|
|
});
|
|
}
|