Monitors Solana Mainnet and the Contra payment channel for deposits/withdrawals and writes to database.
1. Yellowstone gRPC
Real-time block streaming via gRPC (requires a gRPC endpoint). Handles both Escrow and Withdraw program types.
Location: indexer/src/indexer/datasource/yellowstone/
2. RPC Polling (Mainnet or Contra)
Polls getBlock RPC sequentially with higher latency (~1-5 seconds) and no special infrastructure required.
Location: indexer/src/indexer/datasource/rpc_polling/
3. Vixen
Alternative datasource using the Vixen parsing framework for instruction decoding.
Location: indexer/src/datasource/vixen/
Recovers missed slots on indexer restart or network issues:
- Read last processed slot from database (
indexer_statetable) - Query RPC for current slot
- If gap > threshold:
- Parallelize RPC batch fetching (configurable batch size)
- Process blocks in order
- Update checkpoint per slot via
CheckpointWriter(driven bySlotCompleteevents)
- Switch to real-time mode (Yellowstone or polling)
Location: indexer/src/indexer/backfill.rs
Processes pending deposits/withdrawals and executes transactions between Solana Mainnet and the Contra payment channel.
Location: indexer/src/operator/
Polls database for pending transactions with row-level locking to prevent duplicate processing. Uses PostgreSQL SELECT FOR UPDATE SKIP LOCKED to prevent duplicate processing.
Location: indexer/src/operator/fetcher.rs
Validates transactions and builds Solana instructions that are managed by the Contra instance's authorized operators/admins. The processor is responsible for three main tasks:
- Processing deposits (Mainnet → Contra) - handles building a
MintToinstruction for the user on the Contra payment channel. - Processing withdrawals (Contra → Mainnet) - handles building a
ReleaseFundsinstruction (using the Escrow Program's SMT proof) for the user on Mainnet. - Rotating the SMT root on the Mainnet escrow instance to prevent double spending of withdrawals.
Location: indexer/src/operator/processor.rs
Submits transactions to the respective cluster with:
- Exponential backoff retry (configurable max attempts)
- Transaction confirmation polling
- Status updates to database (processing → completed/failed)
- Just-in-time mint initialization (if mint is not yet initialized on the Contra payment channel, the Sender will include an
InitializeMintinstruction in the transaction prior to theMintToinstruction)
Location: indexer/src/operator/sender/
Runs alongside the three-stage pipeline to detect and resolve discrepancies between on-chain state and the indexer database.
Location: indexer/src/operator/reconciliation.rs, indexer/src/indexer/reconciliation.rs
Handles batched database writes for transaction status updates from the operator pipeline.
Location: indexer/src/operator/db_transaction_writer.rs
The indexer uses a ProgramType enum (Escrow | Withdraw) to determine which pipeline branch runs. This is why two parallel instances are deployed: one watching the Escrow program on Mainnet, and one watching the Withdraw program on the Contra payment channel.