Files
zeekayandHanzo Dev f434a701dc dex: show the AMM trades that are actually landing, next to an honest CLOB
The AMM subgraph has been indexed and at chain head the whole time; nothing
read it. /dex queried only the native CLOB at 0x9999, which has genuinely
never emitted an event, so the page reported MARKETS 0 / VOLUME 0 while ~1
swap per block was landing in the WLUX/LZOO pool.

Wire the amm subgraph in as a SECOND venue rather than folding it into the
first. The two are different exchanges and their figures are never summed —
each section reports only its own state, so "live" can never be borrowed by
the venue that is not trading.

Swaps were rendering as anonymous EVM traffic; they now read as trades:
pool-signed amounts resolved into sold/bought, scaled by each token's own
decimals, with symbols, pair, fee tier and links to sender, block and txn.

Status uses the words already in use elsewhere (useNetworkValidators,
useFeeSplit) — live/idle/empty/unavailable/unknown — defined once in
lib/api/venueStatus. There is deliberately no 'stale': separating a stalled
indexer from a quiet venue needs an indexer head this API does not serve.

Also decomplected while here: one fetcher for both subgraphs, and an
unreachable endpoint is no longer flattened into "empty" — an outage and a
venue that has never traded are different facts and now render differently.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-07 08:03:30 -07:00

40 lines
1.0 KiB
TypeScript

// One way to reach the chain subgraphs the explorer serves under
// `${config.apis.general.endpoint}/v1/graph/cchain/<name>/graphql`. The network
// is selected exactly like every other resource — by deployment, via
// NEXT_PUBLIC_API_HOST.
//
// `null` means the endpoint did not answer. That is NOT the same as an answer
// carrying no rows, and callers must keep the two apart: one is an outage, the
// other is a fact about the venue.
import config from 'configs/app';
export function getApiBase(): string | undefined {
return config.apis.general?.endpoint;
}
export async function fetchSubgraph<T>(path: string, query: string): Promise<T | null> {
const base = getApiBase();
if (!base) {
return null;
}
try {
const res = await fetch(base + path, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
});
if (!res.ok) {
return null;
}
const json = await res.json() as { data?: T } | null;
return json?.data ?? null;
} catch {
return null;
}
}