Indexer
The indexer lives in nuvex-services , under indexer/. It copies accounts the three programs already store. It does not submit transactions and it is not chain authority.
What it decodes
start calls getProgramAccounts for each configured program id and decodes layouts it recognises:
OracleRequest— requester, job type, status,max_fee, expiry, callback, and the assigned node, stake, and heartbeatNodeAccount— authority, operator, VRF key, stake, status, heartbeat, cooldownNodeRegistry— node count, minimum stake, cooldown, heartbeat windowProtocolConfig— authority and the pause flagVrfResult— the request, the node, and the 64-byte output as hex
Unknown account data is ignored. A poll replaces the previous snapshot, so a closed account disappears from the copy.
What it needs
start exits 2 unless all of these are set:
NUVEX_RPC_URL(orNUVEX_SOLANA_RPC_URL)- at least one of
NUVEX_ORACLE_CORE_PROGRAM_ID,NUVEX_ORACLE_REGISTRY_PROGRAM_ID,NUVEX_VERIFICATION_PROGRAM_ID DATABASE_URLorNUVEX_READ_MODEL_PATH
--health only checks the process. It does not prove a slot was indexed.
Apply indexer/prisma/migrations/ before the API reads PostgreSQL. An empty database is a valid result: the API returns an empty list, not invented rows.
What it does not do
It does not replay transactions, charge max_fee, or store price observations. Jobs and models stay 501. A price median is computed when /v1/prices is called, and it is not an indexed row. Challenge accounts are not allocated.