mirror of
https://github.com/Such-Software/wowcheckout.git
synced 2026-10-17 05:51:45 +02:00
Minimal changes from upstream xmrcheckout to support Wownero: - Rate provider: Nonlogs WOW-BTC via Kraken BTC/USD - Subaddress derivation: Wownero network byte overrides (53/63/54) - Payment URI scheme: wownero: - Dockerfile: Wownero binaries from Codeberg - Display text: Monero→Wownero, XMR→WOW throughout UI - Default daemon: 192.168.88.235:34568 - Added wownero-logo.svg File and folder structure kept identical to upstream for easy sync.
71 lines
1.6 KiB
TypeScript
71 lines
1.6 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
|
|
const RATE_TTL_MS = 5 * 60 * 1000;
|
|
const RATE_URL =
|
|
"https://api.coingecko.com/api/v3/simple/price?ids=wownero&vs_currencies=usd";
|
|
|
|
let cachedRate: number | null = null;
|
|
let cachedAt: number | null = null;
|
|
let inflight: Promise<number | null> | null = null;
|
|
|
|
const fetchRate = async (): Promise<number | null> => {
|
|
try {
|
|
const response = await fetch(RATE_URL, { cache: "no-store" });
|
|
if (!response.ok) {
|
|
return null;
|
|
}
|
|
const data = (await response.json()) as {
|
|
wownero?: { usd?: number };
|
|
};
|
|
const rate = data?.wownero?.usd;
|
|
if (typeof rate !== "number" || !Number.isFinite(rate)) {
|
|
return null;
|
|
}
|
|
cachedRate = rate;
|
|
cachedAt = Date.now();
|
|
return rate;
|
|
} catch {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
export const useXmrUsdRate = () => {
|
|
const [rate, setRate] = useState<number | null>(cachedRate);
|
|
const [updatedAt, setUpdatedAt] = useState<number | null>(cachedAt);
|
|
|
|
useEffect(() => {
|
|
let active = true;
|
|
const now = Date.now();
|
|
const hasFreshRate =
|
|
cachedRate !== null && cachedAt !== null && now - cachedAt < RATE_TTL_MS;
|
|
|
|
if (hasFreshRate) {
|
|
setRate(cachedRate);
|
|
setUpdatedAt(cachedAt);
|
|
return;
|
|
}
|
|
|
|
const request =
|
|
inflight ??
|
|
(inflight = fetchRate().finally(() => {
|
|
inflight = null;
|
|
}));
|
|
|
|
request.then((nextRate) => {
|
|
if (!active) {
|
|
return;
|
|
}
|
|
if (nextRate !== null) {
|
|
setRate(nextRate);
|
|
setUpdatedAt(cachedAt);
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
active = false;
|
|
};
|
|
}, []);
|
|
|
|
return { rate, updatedAt, source: "coingecko" as const };
|
|
};
|