Skip to main content

GET /price/0g

curl https://api.signalium.site/price/0g
Response:
{
  "symbol": "0g",
  "priceUsd": 0.557,
  "change24h": 0.182,
  "source": "coingecko",
  "fetchedAt": 1777454139365
}

How it works

  • Upstream: CoinGecko /simple/price?ids=zero-gravity&vs_currencies=usd&include_24hr_change=true.
  • Cache: SQLite row keyed by 0g, refreshed when older than 6 hours.
  • Stale fallback: if CoinGecko is unreachable but a cached row exists, the cached value is served and a warning is logged. Total upstream failures (cold cache + outage) return 502.
The web app uses this for the ≈ $X.XX display in the bet panel via the use0gPrice hook.

GET /price/og-yield

curl 'https://api.signalium.site/price/og-yield?windowDays=7'
Response:
{
  "apyBps": 487,
  "sampleCount": 168,
  "windowFromUnix": 1777022139,
  "latestRateWei": "1281640000000000000",
  "latestSampledAt": 1777626739,
  "fallbackApyBps": 500
}
FieldMeaning
apyBpsAnnualized return in basis points, derived from the slope between the oldest and newest samples in the window. Null until ≥2 samples spanning ≥1 hour exist (~2h after a fresh deploy).
sampleCountHow many samples fell inside the window.
windowFromUnixWindow start (unix seconds) — now − windowDays.
latestRateWeiMost recent getRate() reading (1e18-scaled), useful for sanity-checking.
latestSampledAtUnix timestamp of that latest sample.
fallbackApyBpsDefault to use when apyBps is null (currently 500 = 5%).

How it works

  • An hourly sampler (gimo-sampler.ts) reads StakePool.getRate() from 0G mainnet via viem and persists (sampledAt, rateWei) rows into the gimo_rate_sample table.
  • On startup, if the previous process died more than one interval ago, the sampler immediately backfills a sample so the series stays continuous.
  • estimateYield computes APR = (r1/r0 − 1) × (yearSeconds / dt) between the first and last sample in the window. A negative or absurd (>100%) result is treated as noise and returned as null.
The web app consumes this in useMarketYield so the “projected additional yield” line in the bet panel reflects the real Gimo rate trajectory rather than a hardcoded guess. When apyBps is null the projection silently falls back to fallbackApyBps.

Choosing windowDays

st0G’s rate moves slowly, so a wider window smooths sampler jitter at the cost of reacting to recent rate changes more slowly. The default 7 days is a good balance for a UI projection; pass windowDays=1 for a more reactive (but noisier) reading.