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

39 lines
1.4 KiB
TypeScript

// How much we actually know about a trading venue. Every word already carries
// this meaning elsewhere in the codebase (lib/api/pchain/useNetworkValidators,
// lib/api/cchain/useFeeSplit) and keeps it here:
//
// 'unavailable' — the indexer never answered, so we learned nothing at all.
// 'unknown' — it answered, but the chain head is unreadable, so we cannot
// judge how recent its newest trade is.
// 'empty' — it answered and has never recorded a single trade.
// 'idle' — it has history, but nothing inside the recent window.
// 'live' — its newest trade is inside the recent window.
//
// There is deliberately no 'stale'. Telling a stalled indexer apart from a
// quiet venue needs the indexer's own head block, which this API does not
// serve, so claiming that distinction would be a guess.
export type VenueStatus = 'live' | 'idle' | 'empty' | 'unavailable' | 'unknown';
// ~30 minutes at the ~9s cadence C-Chain actually runs.
export const RECENT_WINDOW_BLOCKS = 200;
export function deriveVenueStatus(
latestBlock: number | null,
headBlock: number | null,
reachable: boolean,
): VenueStatus {
if (!reachable) {
return 'unavailable';
}
if (latestBlock === null) {
return 'empty';
}
if (headBlock === null) {
return 'unknown';
}
return headBlock - latestBlock <= RECENT_WINDOW_BLOCKS ? 'live' : 'idle';
}