Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.generalmarket.io/llms.txt

Use this file to discover all available pages before exploring further.

Data Node

Ninety-one sources. One database. The world reduced to rows. 76,000 lines of Rust that watch earthquakes, train delays, crypto prices, Congressional stock trades, and McDonald’s ice cream machine outages — then store the results in PostgreSQL and serve them through 50+ endpoints. Every price the protocol touches passes through this service. It is the single data backbone for frontend, oracles, Vision, and the explorer. If it stops, everything stops.
 ╔══════════════════════════════════════════════════════════════════════════════╗
 ║                              DATA NODE                                      ║
 ║               91 Sources  •  REST  •  WebSocket  •  SSE                     ║
 ╠══════════════════════════════════════════════════════════════════════════════╣
 ║                                                                              ║
 ║  EXTERNAL DATA               COLLECTORS              STORAGE                ║
 ║  ┌─────────────┐         ┌────────────────┐      ┌────────────────────┐     ║
 ║  │ Earthquakes │────┐    │ Market Data    │─────►│ market_prices      │     ║
 ║  │ Weather     │────┤    │ (91 sources)   │      │ market_prices_     │     ║
 ║  │ Trains      │────┤    ├────────────────┤      │   latest           │     ║
 ║  │ Flights     │────┤    │ CoinGecko      │─────►│ coingecko_mcaps    │     ║
 ║  │ Crypto      │────┤    │ (mcap/cats)    │      │ coingecko_cats     │     ║
 ║  │ Stocks      │────┼───►├────────────────┤      ├────────────────────┤     ║
 ║  │ DeFi        │────┤    │ DeFi Llama     │─────►│ dl_protocols       │     ║
 ║  │ Esports     │────┤    │ (TVL/fees)     │      │ dl_metrics         │     ║
 ║  │ Reddit      │────┤    ├────────────────┤      ├────────────────────┤     ║
 ║  │ Steam       │────┤    │ Kline/OHLCV    │─────►│ klines             │     ║
 ║  │ Twitch      │────┤    ├────────────────┤      ├────────────────────┤     ║
 ║  │ Nuclear     │────┤    │ Trade          │─────►│ trades             │     ║
 ║  │ Volcanoes   │────┤    ├────────────────┤      ├────────────────────┤     ║
 ║  │ Space       │────┤    │ Liquidity      │─────►│ liquidity          │     ║
 ║  │ Animals     │────┤    ├────────────────┤      ├────────────────────┤     ║
 ║  │ ...87 more  │────┘    │ Chain Pollers  │─────►│ itp_snapshots      │     ║
 ║  └─────────────┘         │ (L3 + Settl.)  │      │ oracle_health      │     ║
 ║                          ├────────────────┤      ├────────────────────┤     ║
 ║                          │ FNG / Oracle   │─────►│ fng_index          │     ║
 ║                          │ Health / GitHub │      │ github_metrics     │     ║
 ║                          └────────────────┘      └─────────┬──────────┘     ║
 ║                                                            │                ║
 ║                                                            ▼                ║
 ║  CONSUMERS                                        ┌────────────────────┐    ║
 ║  ┌─────────────┐     ┌──────────────────┐         │     REST API       │    ║
 ║  │  Frontend   │◄────│  /price /prices   │◄────────│   50+ endpoints    │    ║
 ║  │  (Next.js)  │     │  /itp-price /nav  │         │   Axum + Tower     │    ║
 ║  ├─────────────┤     │  /portfolio       │         └────────────────────┘    ║
 ║  │  Oracles    │◄────│  /sim/run-stream  │                  │               ║
 ║  │  (Rust)     │     │  /vision/ws       │                  ▼               ║
 ║  ├─────────────┤     │  /market/prices   │         ┌────────────────────┐   ║
 ║  │  Explorer   │◄────│  /explorer/*      │         │  WebSocket + SSE   │   ║
 ║  │  Dashboard  │     │  /batches/*       │         │  Real-time streams │   ║
 ║  └─────────────┘     └──────────────────┘         └────────────────────┘   ║
 ║                                                                              ║
 ╚══════════════════════════════════════════════════════════════════════════════╝

Configuration

PropertyDetail
LanguageRust (76K lines) with Tokio async runtime
DatabasePostgreSQL — 25 migrations, 15+ tables
Default Port8200
TransportREST + WebSocket + SSE
Concurrency91 source engines + 8 internal collectors, all concurrent Tokio tasks
Connection Pool80 max connections, 10s acquire timeout

Collector Architecture

Every source is an independent Tokio task. When one panics, spawn_resilient restarts it. The source does not know it died. All writes flow through a shared BatchWriter channel that coalesces inserts — because PostgreSQL has limits, even if the world does not.
     Source APIs          spawn_resilient           BatchWriter          PostgreSQL
    ┌───────────┐       ┌───────────────┐       ┌──────────────┐     ┌──────────┐
    │ finnhub   │──────►│  SyncEngine   │──┐    │              │     │          │
    │ earthquake│──────►│  SyncEngine   │──┤    │   Batched    │     │ market_  │
    │ twitch    │──────►│  SyncEngine   │──┤    │   INSERT     │     │ prices   │
    │ volcano   │──────►│  SyncEngine   │──┼───►│   Channel    │────►│          │
    │ reddit    │──────►│  SyncEngine   │──┤    │              │     │ market_  │
    │ steam     │──────►│  SyncEngine   │──┤    │  (mpsc +     │     │ prices_  │
    │ ...       │──────►│  SyncEngine   │──┘    │   coalesce)  │     │ latest   │
    └───────────┘       └───────┬───────┘       └──────┬───────┘     └──────────┘
                                │                      │
                                │                      ▼
                                │               ┌──────────────┐
                                │               │  Broadcast   │
                                └──────────────►│  Hub (WS)    │
                                                └──────────────┘
Each SyncEngine owns:
  • A source-specific client (HTTP, WebSocket, or gRPC)
  • A config JSON defining assets, poll interval, and schedules
  • Rate limiting per source API
  • Error tracking via global ErrorTracker
  • Registration in the SyncRegistry for health monitoring

Internal Collectors

Beyond the 91 external sources, the data node runs its own collectors — polling chains, computing NAV, tracking oracle health. The system watches itself.
CollectorModuleResponsibilityPoll Interval
Price Collectorcollector.rsBitget spot prices for DTF-eligible assets30s
DTF Collectoritp_collector.rsOn-chain DTF state (NAV, supply, inventory) from L330s
Trade Collectortrade_collector.rsOn-chain order fills and trade events from L330s
Kline Collectorkline_collector.rsOHLCV candles from Bitget for chart displayContinuous
Liquidity Collectorliquidity_collector.rsOrder book depth snapshots per trading pair1h
CoinGecko Collectorcg_collector.rsMarket caps, categories, coin logos24h
DeFi Llama Collectordl_collector.rsProtocol TVL, fees, volume, raises24h
FNG Collectorfng_collector.rsFear & Greed Index readings6h
Oracle Healthoracle_health_collector.rsOracle node status, latency, consensus health5m
Listing Synclisting_sync.rsBitget listing/delisting dates24h
Chain Pollerschain_pollers.rsL3 + Settlement chain state (balances, orders, Morpho)30s
Chain Event Scannerchain_event_scanner.rsHistorical event scanning (fills, deposits)On-demand
Batch Enginebatch_engine.rsVision batch lifecycle managementContinuous

Chain Pollers Detail

Two chains, polled simultaneously. The results are cached in memory and served by the API. The chain is the source of truth; the cache is the speed.
    L3 Orbit Chain (111222333)              Settlement Chain
    ┌──────────────────────────┐           ┌──────────────────┐
    │  Index.sol               │           │  USDC balances   │
    │  ├─ getITPState()        │           │  Allowances      │
    │  ├─ getUserShares()      │           │  Morpho positions│
    │  ├─ getOrder()           │           │  Bridge proxy    │
    │  ├─ nextOrderId()        │           └──────────────────┘
    │  ├─ FillConfirmed events │                    │
    │  Oracle.sol              │                    │
    │  ├─ currentPrice()       │                    │
    │  ├─ lastCycleNumber()    │                    │
    │  OracleRegistry          │                    │
    │  ├─ oracle status        │                    │
    └────────────┬─────────────┘                    │
                 │                                  │
                 ▼                                  ▼
         ┌─────────────────────────────────────────────┐
         │              ChainCache (in-memory)          │
         │  NavSnapshot, UserBalances, UserOrders,      │
         │  MorphoPositions, FillRecords, Oracles       │
         └──────────────────────┬──────────────────────┘


                          REST API serves
                          cached chain state

The 91 Market Data Sources

Every source has its own Rust client, config JSON, and SyncEngine. Sixteen categories. From the Federal Reserve to Chaturbate. The protocol does not judge what is tradeable.

Finance & Markets

SourceConfigWhat It Tracks
finnhubstocks.jsonUS/EU stock prices, earnings, splits
fredrates.jsonFederal Reserve economic indicators
blsbls.jsonBureau of Labor Statistics (CPI, employment)
treasurybonds.jsonUS Treasury yields (2Y, 10Y, 30Y)
ecbecb.jsonEuropean Central Bank rates, EUR/USD
finrafinra.jsonFINRA margin debt, credit balances
finra_short_volfinra.jsonShort volume by ticker
twsetwse.jsonTaiwan Stock Exchange index
nasdaqNASDAQ composite data
zillowzillow.jsonUS housing market (Zillow Home Value Index)
cftccftc.jsonCFTC Commitments of Traders
imfimf.jsonIMF global economic indicators
opecopec.jsonOPEC oil production, basket price
eiaeia.jsonEnergy Information Administration (oil, gas, coal)

Crypto & DeFi

SourceConfigWhat It Tracks
coingeckocrypto.json2000+ crypto prices, market caps
defillama_marketdefi.jsonDeFi protocol TVL, fees, volume
pumpfunpumpfun.jsonPump.fun memecoin launches/metrics
polymarketpolymarket.jsonPolymarket prediction market odds
bchainbchain.jsonBitcoin on-chain metrics (hashrate, tx count)

Government & Regulation

SourceConfigWhat It Tracks
sec_edgarSEC EDGAR filings (10-K, 10-Q)
sec_eftsSEC EFTS full-text search
sec_insidersec_13f.jsonSEC insider trading (Form 4)
congresscongress.jsonUS Congress stock trades
usa_spendingusa_spending.jsonFederal contract awards
courtlistenercourtlistener.jsonFederal court opinions

Weather & Environment

SourceConfigWhat It Tracks
openmeteoweather.jsonGlobal weather forecasts (temp, wind, precip)
weather_alertsweather_alerts.jsonNWS severe weather alerts
noaa_metnoaa_met.jsonNOAA meteorological observations
noaa_tidesnoaa_tides.jsonNOAA tide levels and predictions
ndbcndbc.jsonNOAA ocean buoy data (waves, SST)
nwpsnwps.jsonNational Water Prediction Service
airnowairnow.jsonEPA air quality index (AQI)
usgs_waterusgs_water.jsonUSGS river/stream flow gauges

Natural Disasters

SourceConfigWhat It Tracks
earthquakeearthquake.jsonUSGS earthquake feed (magnitude, location)
volcanovolcano.jsonSmithsonian GVP volcano alerts
wildfirewildfire.jsonNIFC active wildfire incidents
epidemicepidemic.jsonWHO/CDC disease outbreak reports
spaceweatherspaceweather.jsonNOAA solar flares, geomagnetic storms

Transportation

SourceConfigWhat It Tracks
flightsflights.jsonLive flight delays (FlightAware)
faa_delaysfaa_delays.jsonFAA airport delay programs
ryanairryanair.jsonRyanair route prices
db_trainsdb_trains.jsonDeutsche Bahn train delays (IRIS-TTS)
tfl_tubetfl_tube.jsonLondon Underground line status
paris_metroparis_metro.jsonParis Metro / RATP disruptions
mta_subwaymta_subway.jsonNYC MTA subway delays
gtfs_rtgtfs_rt.jsonGTFS Realtime transit feeds
maritimemaritime.jsonAIS vessel tracking
aisstreamaisstream.jsonReal-time AIS ship positions
mil_aircraftmil_aircraft.jsonMilitary aircraft transponders
tomtom_traffictomtom_traffic.jsonTomTom traffic congestion index
citybikescitybikes.jsonBike-share station availability
parkingparking.jsonReal-time parking garage occupancy

Technology & Developer

SourceConfigWhat It Tracks
githubgithub.jsonGitHub repo stars, commits, contributors
npmnpm.jsonNPM package weekly downloads
pypipypi.jsonPyPI package downloads
crates_iocrates_io.jsonCrates.io Rust package downloads
cloudflarecloudflare.jsonCloudflare Radar internet traffic
hackernewshackernews.jsonHacker News top story scores
stackexchangestackexchange.jsonStack Overflow question activity

Entertainment & Media

SourceConfigWhat It Tracks
twitchtwitch.jsonTwitch streamer viewer counts
tmdbtmdb.jsonMovie/TV popularity (TMDB)
anilistanilist.jsonAnime/manga popularity (AniList)
lastfmlastfm.jsonLast.fm artist play counts
steamsteam.jsonSteam concurrent player counts
bggbgg.jsonBoardGameGeek game rankings

Gaming & Virtual Economies

SourceConfigWhat It Tracks
backpacktfbackpacktf.jsonTF2 item prices (Backpack.tf)
pandascorepandascore.jsonEsports match results and odds
queue_timesqueue_times.jsonTheme park ride wait times

Social & Community

SourceConfigWhat It Tracks
redditreddit.jsonSubreddit subscriber/activity metrics
fourchanfourchan.json4chan board post velocity
chaturbatechaturbate.jsonChaturbate streamer viewer counts

Science & Research

SourceConfigWhat It Tracks
openalexopenalex.jsonAcademic paper citation counts
crossrefcrossref.jsonDOI registration velocity
pubmedpubmed.jsonPubMed publication counts by topic

Wildlife & Nature

SourceConfigWhat It Tracks
animalsanimals.jsonZoo/wildlife population counts
movebankmovebank.jsonAnimal migration GPS tracking
ebirdebird.jsoneBird species observation hotspots

Infrastructure & Energy

SourceConfigWhat It Tracks
nrc_nuclearnrc_nuclear.jsonUS nuclear reactor status (NRC)
power_outagespower_outages.jsonUS power outage counts by utility
iodaioda.jsonInternet outage detection (IODA)
ississ.jsonISS position and crew count
tomtom_evchargetomtom_evcharge.jsonEV charging station availability

Commerce & Consumer

SourceConfigWhat It Tracks
bestbuybestbuy.jsonBest Buy product pricing
yahoo_drinksyahoo_drinks.jsonBeverage commodity prices
mcbrokenmcbroken.jsonMcDonald’s ice cream machine status
sheltershelter.jsonAnimal shelter intake/adoption rates
adzunaadzuna.jsonJob listing counts by category
cbp_bordercbp_border.jsonUS border crossing wait times
nyc311nyc311.jsonNYC 311 complaint volume

Database Schema

Twenty-five migrations. Fifteen tables. Five groups. The schema is a fossil record of every feature that survived.
    ┌─────────────────────────────────────────────────────────────────────┐
    │                        PostgreSQL Schema                            │
    ├─────────────────────────────────────────────────────────────────────┤
    │                                                                     │
    │  MARKET DATA (Vision sources)           ITP / PORTFOLIO             │
    │  ┌──────────────────────┐              ┌──────────────────────┐    │
    │  │ market_prices        │              │ itp_snapshots        │    │
    │  │   source, asset_id,  │              │   itp_id, nav,       │    │
    │  │   value, change_pct, │              │   supply, weights    │    │
    │  │   volume, fetched_at │              ├──────────────────────┤    │
    │  ├──────────────────────┤              │ trades               │    │
    │  │ market_prices_latest │              │   order fills,       │    │
    │  │   (materialized      │              │   prices, amounts    │    │
    │  │    latest per asset) │              ├──────────────────────┤    │
    │  ├──────────────────────┤              │ klines               │    │
    │  │ market_assets        │              │   OHLCV candles      │    │
    │  │   (source registry)  │              ├──────────────────────┤    │
    │  └──────────────────────┘              │ liquidity            │    │
    │                                        │   orderbook depth    │    │
    │  COINGECKO                             └──────────────────────┘    │
    │  ┌──────────────────────┐                                          │
    │  │ coingecko_market_caps│              DEFI LLAMA                  │
    │  │ coingecko_categories │              ┌──────────────────────┐    │
    │  │ bitget_listings      │              │ defillama_protocols  │    │
    │  └──────────────────────┘              │ defillama_metrics    │    │
    │                                        │ defillama_raises     │    │
    │  SIMULATION & MISC                     └──────────────────────┘    │
    │  ┌──────────────────────┐                                          │
    │  │ simulations          │              SYSTEM                      │
    │  │ fng_index             │              ┌──────────────────────┐    │
    │  │ github_metrics       │              │ collector_cursors    │    │
    │  │ batch_tables         │              │ oracle_health_snaps  │    │
    │  └──────────────────────┘              └──────────────────────┘    │
    │                                                                     │
    └─────────────────────────────────────────────────────────────────────┘

Key Tables

TableMigrationPurpose
market_prices001Full price history for all 91 sources, partitioned by source
market_prices_latest025Materialized “latest price per asset” for fast reads
market_assets021Source registry (which assets each source tracks)
itp_snapshots002DTF NAV/supply/weight snapshots from chain poller
trades004On-chain trade fills (orderId, price, amount)
klines005OHLCV candle data from Bitget
liquidity006Order book depth snapshots
coingecko_market_caps007Monthly market cap snapshots per coin
coingecko_categories008CoinGecko category membership
bitget_listings009Bitget listing/delisting dates
simulations010Cached backtester simulation results
defillama_protocols015DeFi Llama protocol metadata
defillama_metrics016TVL, fees, volume time series
defillama_raises017Fundraising rounds
fng_index019Fear & Greed Index history
github_metrics020GitHub repo star/commit counts
collector_cursors023Last processed block per chain collector
batch_tables024Vision batch state and lifecycle

REST API

Axum. 50+ endpoints. Six groups. CORS and gzip via Tower middleware. The API returns data. What you do with it is your problem.

Pricing & NAV

EndpointMethodDescription
/healthGETService health check
/priceGETSingle asset price
/pricesGETMulti-asset prices
/fast-pricesGETIn-memory cached prices (2s refresh)
/fast-prices-by-addressGETSame, keyed by contract address
/latest-pricesGETLatest prices from market_prices_latest
/prices-by-addressGETPrices keyed by on-chain address
/itp-priceGETDTF NAV (inventory-based computation)
/verify-navGETCross-check NAV against on-chain
/nav-seriesGETHistorical NAV time series
/itp-bid-askGETDTF bid/ask spread from orderbook
/itp-orderbookGETFull aggregated DTF orderbook

Portfolio & User State

EndpointMethodDescription
/portfolioGETUser holdings, P&L, cost basis
/portfolio/historyGETHistorical portfolio value
/portfolio/tradesGETUser trade history
/user-stateGETCombined balance + order + position state
/orderGETSingle order status
/vault-balancesGETProtocol vault TVL breakdown
/morpho-positionGETUser’s Morpho lending position
/morpho-historyGETMorpho position history
/fill-speedGETAverage order fill latency
/aum-rankingGETDTF ranking by AUM
/liquidityGETLiquidity depth per pair
/liquidity/alertsGETLow liquidity warnings

Market Data (Vision Sources)

EndpointMethodDescription
/market/prices/:sourceGETAll asset prices for a source
/market/prices/:source/:asset_idGETSingle asset price
/market/prices/:source/:asset_id/historyGETPrice history for an asset
/market/assets/:sourceGETAll tracked assets for a source
/market/statsGETBulk health stats across all sources
/market/stats/:sourceGETHealth stats for one source
/market/batch-historyGETBatch-level price history

Simulation (Backtester)

EndpointMethodDescription
/sim/categoriesGETAvailable backtest categories
/sim/runGETRun simulation, return JSON result
/sim/run-streamGETRun simulation, stream results via SSE
/sim/sweep-streamGETParameter sweep, stream via SSE
/sim/resultsGETRetrieve cached simulation results
/sim/compareGETCompare multiple simulation runs
/sim/holdingsGETSimulated portfolio holdings over time
/sim/invalidateGETInvalidate cached simulation
/sim/benchmarksGETBenchmark indices (BTC, ETH, S&P 500)
/sim/reload-cacheGETForce reload simulation data cache

Vision

EndpointMethodDescription
/vision/snapshotGETCurrent Vision system state
/vision/markets/activeGETActive Vision markets with prices
/vision/batch/:batch_id/historyGETPrice history for a batch
/vision/wsGETWebSocket upgrade for live prices
/batches/recommendedGETRecommended batches for new users
/batches/config/:hashGETBatch configuration by content hash
/batches/signedGETSigned batch attestations

CoinGecko & DeFi Llama

EndpointMethodDescription
/cg/categoriesGETCoinGecko category list
/cg/category-coins/:category_idGETCoins in a CoinGecko category
/cg/coin-categories/:coin_idGETCategories for a specific coin
/coin-mapGETCoinGecko ID to symbol mapping
/logo/:coin_idGETServe cached CoinGecko logo
/listingsGETBitget-listed coins
/listings/unsafeGETAll coins including unlisted
/listingGETSingle coin listing data
/dl/investorsGETDeFi Llama investor/raise data
/fng/latestGETLatest Fear & Greed reading

Explorer (Authenticated)

EndpointMethodDescription
/explorer/healthGETAggregated source health (token-gated)
/explorer/historyGETHistorical health data (token-gated)
Explorer endpoints require a x-explorer-token header. Authentication uses SHA-256 hash comparison with constant-time equality to prevent timing attacks.

Snapshots

EndpointMethodDescription
/snapshotGETFull system state snapshot
/snapshot/metaGETSnapshot metadata only

WebSocket Support

Subscribe to batch IDs. Receive prices as they arrive. Unsubscribe when you have had enough.
    Client                    Data Node                     Source Engines
    ┌──────┐                 ┌──────────┐                  ┌──────────┐
    │      │── subscribe ───►│          │                  │          │
    │      │   [42, 77]      │  WS      │◄── broadcast ───│ SyncEng  │
    │      │                 │  Handler  │    PriceBatch    │ (91x)   │
    │      │◄── prices ─────│          │                  │          │
    │      │   {batchId:42,  │          │                  │          │
    │      │    markets:[..]}│          │                  │          │
    │      │── unsubscribe ─►│          │                  │          │
    │      │   [42]          │          │                  │          │
    └──────┘                 └──────────┘                  └──────────┘
Protocol:
  • Client sends {"subscribe": [42, 77]} to start receiving prices for batch IDs 42 and 77
  • Client sends {"unsubscribe": [42]} to stop receiving prices for batch 42
  • Server pushes {"type": "prices", "batchId": 42, "ts": "...", "markets": [...]} on each source tick

Simulation Engine

2,759 lines that answer the question every investor asks after the fact: “What if I had done it differently?”
  • Category-based selection — pick from CoinGecko or DeFi Llama categories
  • Market cap weighting — equal weight, cap-weighted, or inverse-cap
  • Rebalance schedules — daily, weekly, monthly, or custom
  • Benchmark comparison — BTC, ETH, S&P 500 overlays
  • Parameter sweeps — grid search over rebalance frequency and weighting schemes
  • SSE streaming — results stream to the frontend as they compute
The SimDataCache loads into memory at startup and reloads every 24 hours. Everything the backtester needs, always warm:
    SimDataCache (in-memory)
    ┌──────────────────────────────────────────┐
    │  all_dates:        Vec<NaiveDate>        │
    │  category_coins:   HashMap<cat, coins>   │
    │  coin_symbol_map:  HashMap<id, symbol>   │
    │  bitget_lookup:    HashMap<symbol, pair>  │
    │  prices:           HashMap<(coin,date),f> │
    │  mcap_rankings:    HashMap<date, ranks>   │
    │  categories:       Vec<Category>          │
    │  defi_metrics:     HashMap<proto, tvl>    │
    │  defi_history:     HashMap<proto, ts>     │
    │  fng_index:        HashMap<date, score>   │
    │  btc_dominance:    HashMap<date, pct>     │
    │  eth_dominance:    HashMap<date, pct>     │
    └──────────────────────────────────────────┘

The same formula as Index.sol._getCurrentPrice(). The Data Node reads _itpInventory directly from L3. One formula. Two implementations. They must agree.
For each DTF:
NAV = sum(qty[i] * price[i]) / 1e18
Where qty[i] is the per-share quantity from _itpInventory[itpId] on-chain, and price[i] is the latest validated price from the data pipeline. The chain poller reads inventory via getITPState(), multiplies by prices, caches in ChainCache. The API serves it. Sub-second latency.

CLI Reference

Six subcommands. One binary. Most of the time you only need serve.
    data-node
    ├── serve           Run HTTP server + all collectors
    ├── backfill        Backfill historical Bitget prices + ITP snapshots
    ├── cg-backfill     Backfill CoinGecko monthly market caps
    ├── sync-logos      Download missing CoinGecko coin logos
    ├── sync-listings   Fetch Bitget listing/delisting dates
    └── dl-backfill     Backfill DeFi Llama TVL/fees/volume history

serve

The only command that matters in production. Starts the HTTP server and all collectors.
FlagEnv VarDefaultDescription
--portDATA_NODE_PORT8200HTTP server port
--database-urlDATABASE_URLPostgreSQL connection string
--assets-fileDATA_NODE_ASSETS_FILEassets.jsonDTF-eligible asset definitions
--poll-intervalDATA_NODE_POLL_INTERVAL_SECS30Price collector interval
--rpc-urlINDEX_RPC_URLhttps://rpc.generalmarket.io/L3 chain RPC
--index-addressINDEX_ADDRESSIndex.sol contract address
--settlement-rpc-urlSETTLEMENT_RPC_URLhttp://localhost:8546Settlement chain RPC
--fast-poll-secsDATA_NODE_FAST_POLL_SECS2In-memory ticker cache interval
--coingecko-api-keyCOINGECKO_API_KEYCoinGecko Pro key (optional)
--reset-sessionfalseTruncate session tables on startup
--log-levelDATA_NODE_LOG_LEVELinfoTracing filter

backfill

Backfills historical OHLCV data from Bitget for all assets in assets.json. Used to seed the database before first serve run.

cg-backfill

Backfills monthly market cap snapshots from CoinGecko for all tracked coins. Required for the backtester to have historical weighting data.

dl-backfill

Backfills DeFi Llama protocol metrics (TVL, fees, volume) for all tracked protocols.

sync-logos

Downloads CoinGecko coin logo images to the local data/logos/ directory. The /logo/:coin_id endpoint serves these cached images.

sync-listings

Fetches Bitget spot listing and delisting dates and stores them in the bitget_listings table. Used by the backtester to avoid survivorship bias.

Deployment

One binary. One VPS. Behind nginx. The simplicity is earned.
PropertyDetail
Binary~/index-data-node
Working directory~/index-dn-work/
DatabasePostgreSQL on Docker
Port8200 (behind nginx)
Logs~/index-data-node.log
# Start the data node
cd ~/index-dn-work && ~/index-data-node serve

# Check health
curl http://localhost:8200/health

# Backfill historical data
~/index-data-node backfill --database-url $DATABASE_URL

# Tail logs
tail -f ~/index-data-node.log