A TypeScript/Node.js indexer for Starknet events, supporting PostgreSQL, SQLite, and real-time event handling via WebSocket and RPC.
Read our documentation
- 🔄 Real-time Event Indexing: Listen to Starknet events from specified contracts
- 💾 Data Persistence: Store events and block data in PostgreSQL
- 🔄 Chain Reorg Handling: Detect and handle blockchain reorganizations gracefully
- 🔌 Extensible Architecture: Register custom event handlers for any contract
- 🛡️ Type Safety: Full TypeScript support with type-safe event handling
- 🔄 Retry Logic: Automatic retry mechanisms with exponential backoff
- 📊 Historical Processing: Process historical blocks with seamless real-time transition
- 🔌 Multiple DB Support: Supports PostgreSQL, SQLite, and MySQL out of the box.
- ⚡ High Performance: Optimized for speed with parallel processing and efficient data handling
npm install aucogit clone https://github.com/Quantum3-Labs/auco.git
cd auco
npm install
npm run build- Node.js: Version 18 or higher
- PostgreSQL: Version 12 or higher (can be switched with SQLite or MySQL)
- WebSocket endpoint: Starknet node with WebSocket support (e.g., Infura, local node with WS enabled)
- Starknet node spec version 0.8 or above: Compatible with Starknet nodes running spec version 0.8+
- How to install a Starknet node? See the quick guide in CONTRIBUTING.md.
See example/index.ts for a PostgreSQL-based example.
import { StarknetIndexer, LogLevel } from 'auco';
import { abi as myContractAbi } from './myContractAbi'; // Provide your contract ABI
const indexer = new StarknetIndexer({
rpcNodeUrl: 'https://starknet-mainnet.infura.io/v3/YOUR_KEY',
wsNodeUrl: 'wss://starknet-mainnet.infura.io/ws/v3/YOUR_KEY',
database: {
type: 'postgres',
config: {
connectionString: 'postgresql://user:password@localhost:5432/mydb',
},
},
logLevel: LogLevel.INFO,
});
indexer.onEvent({
contractAddress: '0x...',
abi: myContractAbi,
eventName: 'Transfer',
handler: async (event, client, indexer) => {
console.log('Received event:', event);
// Custom logic here
},
});
indexer.start();-
Configure your environment:
- Edit
example/sqlite.tswith your node URLs and contract address - Update your database config to SQLite
import Database from 'better-sqlite3'; const indexer = new StarknetIndexer({ rpcNodeUrl: 'https://starknet-sepolia-rpc.publicnode.com', wsNodeUrl: 'wss://starknet-sepolia-rpc.publicnode.com', database: { type: 'sqlite', config: { dbInstance: new Database('starknet_indexer.db'), }, }, logLevel: LogLevel.INFO, startingBlockNumber: 'latest', });
- Edit
-
Run the example:
npx ts-node example/sqlite.ts
-
Configure your environment:
- Edit
example/mysql.tswith your node URLs and contract address - Update your database config to MySQL
const indexer = new StarknetIndexer({ rpcNodeUrl: 'https://starknet-sepolia-rpc.publicnode.com', wsNodeUrl: 'wss://starknet-sepolia-rpc.publicnode.com', database: { type: 'mysql', config: { connectionString: 'mysql://root:root@localhost:3306/starknet_indexer', }, }, logLevel: LogLevel.INFO, startingBlockNumber: 'latest', });
- Edit
-
Run the example:
npx ts-node example/mysql.ts
You can download contract ABIs directly from Starknet nodes using the built-in CLI script. This is useful for generating TypeScript ABI files for your project.
Run the script with npx (recommended) or directly with ts-node/node:
Download the ABI for a single contract:
npx ts-node src/scripts/download-abi.ts single \
--rpc-url <STARKNET_RPC_URL> \
--address <CONTRACT_ADDRESS> \
--name <CONTRACT_NAME> \
[--output <OUTPUT_DIR>]--rpc-url(required): Starknet RPC endpoint URL--address(required): Contract address--name(required): Name for the generated ABI file (no extension)--output(optional): Output directory (default:generated/abis)
Example:
npx ts-node src/scripts/download-abi.ts single \
--rpc-url https://starknet-mainnet.infura.io/v3/YOUR_KEY \
--address 0x123...abc \
--name MyContractDownload ABIs for multiple contracts defined in a JSON file:
-
Create a JSON file (e.g.,
contracts.json) with the following format:{ "MyContract": "0x123...abc", "AnotherContract": "0x456...def" } -
Run:
npx ts-node src/scripts/download-abi.ts batch \ --rpc-url <STARKNET_RPC_URL> \ --file contracts.json \ [--output <OUTPUT_DIR>]
--file(required): Path to the JSON file mapping contract names to addresses- Other options as above
Example:
npx ts-node src/scripts/download-abi.ts batch \
--rpc-url https://starknet-mainnet.infura.io/v3/YOUR_KEY \
--file contracts.jsonThe script will generate TypeScript ABI files in the specified output directory and create an index.ts exporting all ABIs.
AUCO is designed for high-performance event indexing with optimized parallel processing and efficient data handling. Our benchmarks demonstrate significant performance advantages:
| Metric | AUCO | APIBARA | Improvement |
|---|---|---|---|
| Sync Time | 147.63s | 270.50s | 83% faster |
| Events Processed | 159,885 | 152,604 | 4.8% more events |
Benchmark Parameters:
- Block Range: 1,500,000 to 1,505,000 (5,000 blocks)
- Event Type: Starknet Transfer events
- Total Events: ~150,000 events processed
- Device: MacBook M1 Pro (16GB RAM)
| Option | Type | Required | Description |
|---|---|---|---|
rpcNodeUrl |
string |
✅ | Starknet RPC endpoint |
wsNodeUrl |
string |
✅ | Starknet WebSocket endpoint |
database |
object |
✅ | Database configuration object with type and config properties |
logLevel |
LogLevel |
❌ | Log verbosity (DEBUG, INFO, WARN, ERROR) |
startingBlockNumber |
number | 'latest' |
❌ | Starting block number for indexing |
The indexer automatically detects and handles chain reorganizations:
indexer.onReorg({
handler: async (forkedBlock) => {
console.log(`Reorg detected at block ${forkedBlock.block_number}`);
// Implement your reorg handling logic
// The indexer automatically rolls back non-canonical data
},
});Important: You must implement your own business logic for handling reorgs. The indexer provides the hook and basic database cleanup.
npm testnpm run lint # Check code style
npm run lint:fix # Fix code style issues
npm run format # Format code with Prettiernpm run build # Compile TypeScript- Additional database (MongoDB, MySQL, etc.) ✅
- Built-in monitoring and health checks
- Advanced caching layer
- Docker containerization
- Event filtering by multiple criteria
- Instant event processing via WebSocket
We welcome contributions! Please see our Contributing Guide for details.
-
Fork and clone the repository
-
Install dependencies:
npm install
-
Setup development environment:
# Start local PostgreSQL (if using Docker) docker run --name postgres-dev -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres:13 # Start local Starknet devnet npm run chain
-
Run tests:
npm test -
Submit a pull request with your changes
- Use TypeScript for all new code
- Follow the existing code style (enforced by ESLint and Prettier)
- Write tests for new functionality
- Update documentation as needed
| Issue | Solution |
|---|---|
| PostgreSQL connection failed | Ensure PostgreSQL is running and accessible |
| WebSocket connection failed | Verify your node supports WebSocket connections |
| ABI parsing errors | Check your ABI file and event names |
| Memory usage high | Consider processing events in smaller batches |
- 📖 Documentation: Check the API Reference
- 🐛 Issues: Report bugs on GitHub Issues
- 💬 Discussions: Join our GitHub Discussions
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Starknet.js
- Type-safe ABI parsing with abi-wan-kanabi
- Database operations with node-postgres, mysql2, and better-sqlite3