# mrbeliaev/task-market-indexer architecture

> Architecture diagram of the GitHub repository mrbeliaev/task-market-indexer, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/mrbeliaev/task-market-indexer
- Repository: https://github.com/mrbeliaev/task-market-indexer

## Overview

TaskMarket Indexer is a Go service that polls TaskMarketplace events across configured EVM chains and persists indexed task and withdrawal state in PostgreSQL. The workflow starts with environment and database setup, reconciles enabled chain configurations, polls block ranges, decodes contract events, applies task lifecycle updates, and advances a per-chain cursor only after successful processing. The README documents all event categories; source excerpts show representative handlers and the polling orchestration, but not every handler implementation.

Main entry points: [`internal/indexer/events.go`](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go) (Event filters and decoders), [`cmd/main.go`](https://github.com/mrbeliaev/task-market-indexer/blob/main/cmd/main.go) (Service entrypoint), [`internal/indexer/indexer.go`](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/indexer.go) (Multi-chain manager), [`internal/db/db.go`](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go) (Task state)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_startup["Startup and config"]
  node_main["Service entrypoint<br/>[main.go]"]
  node_config["Global config<br/>[config.go]"]
end

subgraph group_orchestration["Chain orchestration"]
  node_multi["Multi-chain manager<br/>[indexer.go]"]
  node_chain["Per-chain indexer<br/>[indexer.go]"]
  node_poll["Block-range poller<br/>[indexer.go]"]
end

subgraph group_ingestion["Event ingestion"]
  node_abi["Contract ABI<br/>[taskmarket.json]"]
  node_events["Event filters and decoders<br/>[events.go]"]
  node_taskevents["Task lifecycle events<br/>[events.go]"]
  node_disputeevents["Dispute events<br/>[events.go]"]
  node_withdrawalevents["Withdrawal events<br/>[events.go]"]
  node_governanceevents["Fee configuration events<br/>[events.go]"]
end

subgraph group_persistence["Persistence"]
  node_gorm["GORM connection<br/>[db.go]"]
  node_chainconfig[("Enabled chain config<br/>[db.go]")]
  node_cursor[("Indexing cursor<br/>[db.go]")]
  node_taskstore[("Task state<br/>[db.go]")]
  node_withdrawalstore[("Withdrawal records<br/>[db.go]")]
end

node_operator(("Service operator"))
node_environment["Environment variables"]
node_postgres[("PostgreSQL")]
node_rpc["EVM chain RPC"]

node_operator -->|"starts"| node_main
node_environment -->|"configures"| node_config
node_main -->|"loads settings"| node_config
node_main -->|"connects database"| node_gorm
node_gorm -->|"opens connection"| node_postgres
node_main -->|"initializes and runs"| node_multi
node_multi -->|"loads enabled chains"| node_chainconfig
node_multi -->|"validates chains"| node_config
node_multi -->|"starts and reconciles"| node_chain
node_chain -->|"connects and retries"| node_rpc
node_chain -->|"runs polling"| node_poll
node_poll -->|"gets block height"| node_rpc
node_poll -->|"reads and advances"| node_cursor
node_poll -->|"dispatches handlers"| node_events
node_events -->|"fetches event logs"| node_rpc
node_events -->|"decodes with"| node_abi
node_events -->|"routes lifecycle logs"| node_taskevents
node_events -->|"routes dispute logs"| node_disputeevents
node_events -->|"routes withdrawal logs"| node_withdrawalevents
node_events -->|"routes fee logs"| node_governanceevents
node_taskevents -->|"upserts and updates"| node_taskstore
node_disputeevents -->|"updates dispute state"| node_taskstore
node_withdrawalevents -->|"records withdrawals"| node_withdrawalstore
node_taskstore -->|"persists task rows"| node_postgres
node_withdrawalstore -->|"persists records"| node_postgres
node_cursor -->|"persists progress"| node_postgres
node_chainconfig -->|"reads configuration"| node_postgres

click node_main "https://github.com/mrbeliaev/task-market-indexer/blob/main/cmd/main.go"
click node_config "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/config/config.go"
click node_gorm "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go"
click node_chainconfig "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go"
click node_multi "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/indexer.go"
click node_chain "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/indexer.go"
click node_cursor "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go"
click node_poll "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/indexer.go"
click node_abi "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/abi/taskmarket.json"
click node_events "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go"
click node_taskevents "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go"
click node_disputeevents "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go"
click node_withdrawalevents "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go"
click node_governanceevents "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go"
click node_taskstore "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go"
click node_withdrawalstore "https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_config toneBlue
class node_multi,node_chain,node_poll,node_postgres toneAmber
class node_abi,node_events,node_taskevents,node_disputeevents,node_withdrawalevents,node_governanceevents toneMint
class node_gorm,node_chainconfig,node_cursor,node_taskstore,node_withdrawalstore toneRose
class node_operator,node_environment,node_rpc toneIndigo
```

## Components

### Startup and config

- [Service entrypoint](https://github.com/mrbeliaev/task-market-indexer/blob/main/cmd/main.go): `cmd/main.go`
- [Global config](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/config/config.go): `internal/config/config.go`

### Chain orchestration

- [Multi-chain manager](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/indexer.go): `internal/indexer/indexer.go`
- [Per-chain indexer](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/indexer.go): `internal/indexer/indexer.go`
- [Block-range poller](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/indexer.go): `internal/indexer/indexer.go`

### Event ingestion

- [Contract ABI](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/abi/taskmarket.json): `internal/indexer/abi/taskmarket.json`
- [Event filters and decoders](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go): `internal/indexer/events.go`
- [Task lifecycle events](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go): `internal/indexer/events.go`
- [Dispute events](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go): `internal/indexer/events.go`
- [Withdrawal events](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go): `internal/indexer/events.go`
- [Fee configuration events](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/indexer/events.go): `internal/indexer/events.go`

### Persistence

- [GORM connection](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go): `internal/db/db.go`
- [Enabled chain config](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go): `internal/db/db.go`
- [Indexing cursor](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go): `internal/db/db.go`
- [Task state](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go): `internal/db/db.go`
- [Withdrawal records](https://github.com/mrbeliaev/task-market-indexer/blob/main/internal/db/db.go): `internal/db/db.go`

### Other components

- **Service operator**
- **Environment variables**
- **PostgreSQL**
- **EVM chain RPC**

## Connections

- Service operator → Service entrypoint: starts
- Environment variables → Global config: configures
- Service entrypoint → Global config: loads settings
- Service entrypoint → GORM connection: connects database
- GORM connection → PostgreSQL: opens connection
- Service entrypoint → Multi-chain manager: initializes and runs
- Multi-chain manager → Enabled chain config: loads enabled chains
- Multi-chain manager → Global config: validates chains
- Multi-chain manager → Per-chain indexer: starts and reconciles
- Per-chain indexer → EVM chain RPC: connects and retries
- Per-chain indexer → Block-range poller: runs polling
- Block-range poller → EVM chain RPC: gets block height
- Block-range poller → Indexing cursor: reads and advances
- Block-range poller → Event filters and decoders: dispatches handlers
- Event filters and decoders → EVM chain RPC: fetches event logs
- Event filters and decoders → Contract ABI: decodes with
- Event filters and decoders → Task lifecycle events: routes lifecycle logs
- Event filters and decoders → Dispute events: routes dispute logs
- Event filters and decoders → Withdrawal events: routes withdrawal logs
- Event filters and decoders → Fee configuration events: routes fee logs
- Task lifecycle events → Task state: upserts and updates
- Dispute events → Task state: updates dispute state
- Withdrawal events → Withdrawal records: records withdrawals
- Task state → PostgreSQL: persists task rows
- Withdrawal records → PostgreSQL: persists records
- Indexing cursor → PostgreSQL: persists progress
- Enabled chain config → PostgreSQL: reads configuration
