Files
solace-bg-dubai/frontend/lib/prices.ts
defiQUG a03417be98
All checks were successful
CI / lint-and-test (push) Successful in 9m52s
chore: consolidate local WIP (repo cleanup 20260707)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:41:38 -07:00

69 lines
1.7 KiB
TypeScript

import { useQuery } from "@tanstack/react-query";
const STABLE_USD = 1;
async function fetchEthUsd(): Promise<number> {
const res = await fetch(
"https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd"
);
if (!res.ok) {
throw new Error(`Price feed HTTP ${res.status}`);
}
const json = (await res.json()) as { ethereum?: { usd?: number } };
const usd = json.ethereum?.usd;
if (typeof usd !== "number" || !Number.isFinite(usd)) {
throw new Error("Invalid ETH price payload");
}
return usd;
}
export function useUsdPrices() {
const query = useQuery({
queryKey: ["usd-prices", "eth"],
queryFn: fetchEthUsd,
staleTime: 60_000,
retry: 2,
});
return {
ethUsd: query.data ?? null,
stableUsd: STABLE_USD,
isLoading: query.isLoading,
error: query.error,
};
}
export function rawToDecimal(raw: bigint, decimals: number): number {
const divisor = 10 ** decimals;
return Number(raw) / divisor;
}
export function formatUsd(value: number | null | undefined): string {
if (value == null || !Number.isFinite(value)) {
return "—";
}
return new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(value);
}
export function tokenUsdValue(
raw: bigint | undefined,
decimals: number,
symbol: string,
ethUsd: number | null
): number | null {
if (raw === undefined) return null;
const amount = rawToDecimal(raw, decimals);
if (symbol === "ETH") {
return ethUsd != null ? amount * ethUsd : null;
}
if (symbol === "cUSDT" || symbol === "cUSDC") {
return amount * STABLE_USD;
}
return null;
}