# Chain Indexer

Source: https://docs.settlemint.com/docs/architecture/data-availability/chain-indexer
The Chain Indexer reads EVM logs, decodes DALP events, and writes queryable
read models. It explains how checkpoints, finality, reorg handling, and
reindexing affect the state shown by APIs and dashboards.




The Chain Indexer turns supported EVM events into read models for DALP APIs, dashboards, reports, and operational review.

It reads chain logs, decodes them with known contract ABIs, routes each event to a domain handler, and stores the resulting state in PostgreSQL.

This page is an architecture explanation. It describes how indexed state is produced and what consistency boundary readers should expect.

It does not document a public API contract or replace deployment-specific monitoring runbooks.

## Indexing flow [#indexing-flow]

<Mermaid
  chart="`flowchart TB
  subgraph EVM[&#x22;EVM network&#x22;]
    HEAD(Chain head)
    LOGS(Event logs)
    FINALITY(Finality signal)
  end

  subgraph IDX[&#x22;Chain Indexer&#x22;]
    WATCHER(Live watcher)
    SYNC(syncChain)
    PROCESS(processBlockRange)
    DECODE(Event decoder)
    HANDLERS(Domain handlers)
  end

  subgraph STORE[&#x22;PostgreSQL&#x22;]
    CONTRACTS(Registered contracts)
    CHECKPOINT(Sync checkpoint)
    READMODELS(Read models)
    REORG(Reorg window data)
  end

  subgraph READS[&#x22;Read surfaces&#x22;]
    API(DALP APIs)
    UI(Asset Console)
    REPORTS(Reports and review)
  end

  HEAD --> WATCHER
  FINALITY --> WATCHER
  WATCHER --> SYNC
  SYNC --> CONTRACTS
  CONTRACTS --> PROCESS
  PROCESS --> LOGS
  LOGS --> DECODE
  DECODE --> HANDLERS
  HANDLERS --> READMODELS
  PROCESS --> CHECKPOINT
  PROCESS --> REORG
  WATCHER --> CHECKPOINT
  READMODELS --> API
  READMODELS --> UI
  READMODELS --> REPORTS

  style HEAD fill:#b661d9,stroke:#8a3fb3,stroke-width:2px,color:#fff
  style LOGS fill:#b661d9,stroke:#8a3fb3,stroke-width:2px,color:#fff
  style FINALITY fill:#b661d9,stroke:#8a3fb3,stroke-width:2px,color:#fff
  style WATCHER fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style SYNC fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style PROCESS fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style DECODE fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style HANDLERS fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style CONTRACTS fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style CHECKPOINT fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style READMODELS fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style REORG fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style API fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style UI fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style REPORTS fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff`"
/>

## What the indexer owns [#what-the-indexer-owns]

| Area               | Current behaviour                                                                                                                                                                                  | Consistency effect                                                                                                                        |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Chain progress     | A live watcher checks the chain head and calls the sync path when the head advances. WebSocket block subscriptions can trigger the same sync path, with polling as the steady fallback.            | API and UI reads follow the latest processed checkpoint, not the raw chain head.                                                          |
| Contract discovery | Genesis and event handlers register known DALP contracts in PostgreSQL. Forward range processing is single-pass; newly discovered contracts are queued for backfill and cascade work.              | Events from newly created DALP contracts can appear after follow-up backfill work, even when the parent block range has already advanced. |
| Event ordering     | The log fetch path address-filters `eth_getLogs`, chunks block ranges, decodes ABI events, and sorts results by block number and log index before handlers run.                                    | Replaying the same block range produces the same handler order.                                                                           |
| Checkpointing      | The sync path stores per-chain progress in PostgreSQL after processing ranges. It can resume from the stored checkpoint after downtime.                                                            | Reads can lag during catch-up, then converge as checkpoints advance.                                                                      |
| Finality tracking  | The watcher maintains a finalized-block watermark. PoS chains can use the RPC `finalized` tag. Private or test chains use configured confirmation depth where the network configuration allows it. | Pruning and reorg cleanup are tied to the finalized watermark rather than only to the latest observed head.                               |
| Reorg recovery     | The sync path checks stored block hashes for reorganisations, rolls back affected indexed state, and reprocesses the canonical chain.                                                              | Recent indexed data can be corrected when the chain reorganises. Finalized data is treated as the safer boundary for cleanup.             |
| Reindexing         | A new indexer deployment schema can be built while the old schema continues serving reads. When the new deployment catches up across chains, public views can swap to the new schema.              | Long reindex work does not need to remove the currently served read model while the replacement is being built.                           |

## Read-model consistency boundary [#read-model-consistency-boundary]

Indexed state is current to the indexer's processed checkpoint.

A transaction can be mined on-chain before it appears in DALP read surfaces. This can happen when the indexer has not processed that block yet, when the service is catching up after downtime, or when a reindex deployment is still building.

Applications should treat on-chain transaction finality and indexed read visibility as related but separate facts:

1. The EVM transaction decides whether the on-chain operation succeeded.
2. The indexer observes the emitted events and writes the DALP read model.
3. APIs, dashboards, and reports read the indexed model.
4. Monitoring shows whether the indexer is caught up, lagging, backfilling, or recovering.

That boundary matters for support and operations. If a transaction is visible in an explorer but missing from a DALP dashboard, the first question is whether the indexer checkpoint has reached the transaction block and whether the relevant contract was registered for indexing.

## Failure and recovery model [#failure-and-recovery-model]

| Condition                 | What happens                                                                                                                                    | Operator check                                                                   |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Indexer downtime          | The service resumes from the stored checkpoint and processes missed ranges.                                                                     | Check the per-chain processed block and block lag.                               |
| RPC interruption          | The watcher keeps its loop alive and retries on later ticks. Finality advancement can pause when the configured finality signal is unavailable. | Check RPC health, latest chain head, finality lag, and indexer errors.           |
| Newly discovered contract | The discovered contract is registered, then queued for backfill and cascade processing.                                                         | Check contract registration and whether backfill work remains for that contract. |
| Chain reorganisation      | The indexer rolls back affected rows within the supported reorg window and reprocesses canonical blocks.                                        | Check reorg metrics and whether the finalized watermark has advanced.            |
| Reindex requested         | A building deployment schema is created. The serving schema continues to back current reads until the replacement is ready to swap.             | Check deployment registry state and pending backfill progress.                   |

## Monitoring and troubleshooting signals [#monitoring-and-troubleshooting-signals]

Use [Blockchain monitoring](/docs/developer-guides/operations/blockchain-monitoring) for live chain and indexer health. The most useful signals are block lag, block age, finality lag, sync failures, handler errors, pending backfill state, and reindex deployment state.

Use the [indexer troubleshooting checks](/docs/developer-guides/operations/blockchain-monitoring#troubleshoot-indexed-data-lag) before starting a reindex. They help operators distinguish normal read-model lag from RPC failure, missing contract discovery, reorg recovery, or active reindex work.

Use [Observability](/docs/architecture/operability/observability) for deployment-level metrics, logs, and traces when the observability chart is enabled. Observability helps explain why the indexer is lagging; the indexed database and blockchain monitoring surfaces show what state DALP is currently serving.

## Boundaries [#boundaries]

The Chain Indexer does not change EVM finality, provide an external proof of reserve, or guarantee an RPC provider's availability.

It turns supported chain events into DALP read models. Operators use those models and related signals to understand freshness, lag, reorg recovery, and reindex progress.

The indexer does not index arbitrary contracts by default. DALP handlers process known contract types and events registered through the platform's discovery and handler registry.

External bridges, non-EVM networks, custody-provider records, and off-chain reserve evidence need their own integration or evidence source.

## See also [#see-also]

* [Blockchain monitoring](/docs/developer-guides/operations/blockchain-monitoring) for operational health checks
* [Observability](/docs/architecture/operability/observability) for deployment telemetry
* [Database](/docs/architecture/operability/database) for storage architecture
* [Contract Runtime](/docs/architecture/components/infrastructure/contract-runtime) for contract calls and event decoding boundaries
