A robust, scalable blockchain token indexer built with NestJS, designed for indexing ERC-20 token events on Polygon (and easily extensible to other EVM-compatible chains).
This indexer follows the principles outlined in building custom indexers as an alternative to The Graph:
- π Queued ingestion with Redis - Fault-tolerant event processing
- ποΈ Batch writes + upserts to PostgreSQL - Efficient database operations
- π Fault-tolerant logic with retries - Automatic error recovery
- π Cross-chain support - Easily configurable for multiple blockchains
- π Real-time insights - Performance metrics and monitoring
- Multi-contract indexing - Configure multiple token contracts
- Event-driven architecture - Process Transfer and Approval events
- Fault tolerance - Automatic retries and error handling
- Batch processing - Efficient blockchain data retrieval
- Real-time monitoring - Track indexing progress and performance
- RESTful API - Easy integration and data access
- Docker support - Containerized development environment
- Node.js 18+
- Docker & Docker Compose
- Git
git clone <repository-url>
cd token-indexer
npm install# Start PostgreSQL and Redis
./scripts/dev-setup.sh
# Copy environment configuration
cp .env.example .env
# Edit .env with your configurationUpdate .env with your settings:
# Polygon RPC (you can use Alchemy, Infura, or public RPC)
POLYGON_RPC_URL=https://polygon-rpc.com
# Contract to index (example: USDC on Polygon)
USDC_CONTRACT_ADDRESS=0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174
INDEX_USDC=truenpm run start:devPOST /indexing/start/:contractAddressStart indexing a specific contract.
Example:
curl -X POST http://localhost:3000/indexing/start/0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174GET /indexing/status/:contractAddress?chainId=137Get current indexing progress for a contract.
Example:
curl http://localhost:3000/indexing/status/0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174GET /indexing/transfers/:contractAddress?address=0x...&limit=100Retrieve token transfer history.
Example:
curl "http://localhost:3000/indexing/transfers/0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174?limit=50"GET /indexing/healthThe indexer is configured through environment variables and the src/config/configuration.ts file.
To index additional contracts, add them to the configuration:
// src/config/configuration.ts
contracts: {
usdc: {
address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
chainId: 137,
events: ['Transfer', 'Approval'],
enabled: true,
},
weth: {
address: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
chainId: 137,
events: ['Transfer'],
enabled: true,
},
}To support additional blockchains:
- Add chain configuration:
blockchain: {
polygon: { /* existing config */ },
ethereum: {
rpcUrl: process.env.ETHEREUM_RPC_URL,
chainId: 1,
batchSize: 100,
},
}- Update environment variables
- Configure contracts for the new chain
src/
βββ config/ # Configuration management
βββ entities/ # TypeORM database entities
βββ database/ # Database module and setup
βββ queue/ # Redis queue configuration
βββ blockchain/ # Blockchain interaction services
βββ indexing/ # Core indexing logic
β βββ indexing.service.ts # Main indexing service
β βββ indexing.processor.ts # Queue processors
β βββ indexing.controller.ts # REST API endpoints
β βββ indexing.module.ts # Module configuration
βββ main.ts # Application entry point
- Configuration: Define contracts and events to index
- Queue Setup: Redis queues manage processing workflows
- Block Processing: Retrieve events in configurable batches
- Event Processing: Parse and store individual events
- Fault Tolerance: Automatic retries and error logging
- Progress Tracking: Monitor indexing status and performance
- Stores all indexed Transfer events
- Indexed by contract, block number, and addresses
- Supports efficient querying and analytics
- Tracks indexing status per contract
- Monitors last processed block and sync status
- Enables resumable indexing
- Stores events that failed processing
- Enables manual review and retry
- Tracks error patterns for debugging
The project includes a complete Docker Compose setup:
# Start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose downServices included:
- PostgreSQL 15
- Redis 7
- Redis Commander (web UI at http://localhost:8081)
Access Redis Commander at http://localhost:8081 to monitor job queues.
Connect to PostgreSQL to analyze indexed data:
docker-compose exec postgres psql -U postgres -d token_indexerThe application provides detailed logging for debugging:
- Blockchain connection status
- Event processing progress
- Error details and retry attempts
- Configure production database and Redis
- Set appropriate batch sizes for your RPC limits
- Configure monitoring and alerting
- Set up proper logging aggregation
- Increase queue concurrency for higher throughput
- Use read replicas for API queries
- Implement rate limiting for RPC calls
- Consider sharding by contract or chain
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the MIT License.
For issues and questions:
- Check the logs for error details
- Verify your RPC endpoint is working
- Ensure PostgreSQL and Redis are running
- Check the GitHub issues for similar problems
Built with β€οΈ for the blockchain development community.