Seshat

Documentation

Market Data

Market-Data Enrichment

Dexscreener is Seshat's primary market feed, but a single source can be thin or wrong for new tokens. CoinGecko and DeFiLlama add cross-source context — categories, all-time-high data, an independent price with a confidence score, and protocol TVL — so the picture isn't built on one provider alone.

Cadence: every 2 hoursCoinGecko + DeFiLlamaKV-cached · fail-soft

Design principles

Cross-source, not authoritative

These feeds add context on top of Dexscreener. They are enrichment — most clanker/meme tokens won't be listed on CoinGecko or map to a DeFiLlama protocol, and that's expected.

Fail-soft everywhere

404 (not listed), 429 (rate limited), or any network error → null. A missing feed never breaks enrichment.

Hard-cached in KV

Every response is cached in the CACHE KV namespace (default ~1h TTL) to respect free-tier rate limits — CoinGecko's keyless tier is ~30 req/min.

CoinGecko

Looked up by on-chain contract address on the base asset platform. When COINGECKO_API_KEY is set, the demo header x-cg-demo-api-key is sent; otherwise the keyless free tier is used. It returns category tags, market cap, total volume, all-time-high data, 24h change, and links (Twitter handle, homepage, description).

// providers/coingecko.ts — getByContract(address, platform = 'base')
// GET /coins/{platform}/contract/{address}   (cache key: cg:contract:{addr})
interface CoinGeckoData {
  coingecko_id:        string | null;
  categories:          string[];        // e.g. ["AI", "Base Ecosystem"]
  market_cap_usd:      number | null;
  total_volume_usd:    number | null;
  ath_usd:             number | null;
  ath_change_pct:      number | null;
  price_change_24h_pct: number | null;
  twitter:             string | null;   // handle without @
  homepage:            string | null;
  description:         string | null;
}
// !res.ok (404/429/etc.) → null. Cached on success.

DeFiLlama

No API key required. Two endpoints: an independent spot price with a confidence value (how much Llama trusts that price — a useful cross-check against Dexscreener), and protocol TVL by slug.

// providers/defillama.ts
// 1. getCurrentPrice(address, chain = 'base')
//    GET coins.llama.fi/prices/current/{chain}:{address}
interface LlamaPrice {
  price_usd:  number | null;
  confidence: number | null;   // 0-1 — how trustworthy Llama considers the price
  symbol:     string | null;
}

// 2. getProtocolTvl(slug)
//    GET api.llama.fi/tvl/{slug}  → bare JSON number (USD)
//    Most meme/clanker tokens don't map to a protocol → null (expected).

Why the confidence field matters

A low DeFiLlama price confidence on a token that Dexscreener reports as liquid is a quiet warning — the two sources disagree on how real the price is. It's exactly the kind of cross-source context a single feed can't give you.

How it runs

The external enrich step runs on the 2-hour cron as qualitative context and can be triggered manually via POST /api/admin/enrich-external. Like the other context layers, this data informs the picture (categories feed narrative and research context; cross-source prices sanity-check the market read) but is not itself a weighted dimension in the composite score.

Lineage

Both providers are native re-implementations of the most useful data sources from web3-research-mcp — an MCP stdio server that can't run inside a Worker — rebuilt to match Seshat's provider idioms (KV cache, fail-soft return shapes) so they run edge-native with no external process.