A comprehensive blockchain event monitoring system that captures, standardizes, and stores protocol events in real-time using ClickHouse (local cluster or cloud) for analytics and data persistence.
Example of the table structure -
- π Features
- ποΈ Architecture
- β‘ Quick Start
- π¦ Installation
- π§ Configuration
- π» Commands Reference
- π Data Schema
- π Monitoring & Analytics
- π οΈ Troubleshooting
- π Project Structure
- π€ Contributing
- β‘ Real-time Event Listening: WebSocket-based event listening for instant blockchain event detection
- π Dynamic Market Discovery: Automatically detects new pools/markets and starts tracking them
- π Multi-Protocol Support:
- Uniswap V2 (Ethereum)
- Uniswap V3 (Ethereum)
- PancakeSwap V2 (BSC)
- π― Standardized Schema: Unified data structure across all protocols
- π Event Normalization: Converts protocol-specific events to standard format
- ποΈ ClickHouse Integration: Real-time data storage and analytics
- ποΈ Local Cluster Support: 3-replica ClickHouse cluster with ClickHouse Keeper
- βοΈ Cloud-Ready: ClickHouse Cloud support for scalable data processing
- π Real-time Analytics: Materialized views for instant insights
- π Advanced Querying: SQL-based analytics and reporting
- π Data Visualization: Built-in dashboard and monitoring tools
- π Data Replication: Automatic data replication across cluster nodes
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Blockchain β β Event Listener β β ClickHouse β
β Networks βββββΆβ & Processor βββββΆβ Cluster/Cloud β
β β β β β β
β β’ Ethereum β β β’ Multi-Protocol β β β’ Real-time β
β β’ BSC β β β’ Standardizationβ β β’ Analytics β
β β’ WebSocket β β β’ BigInt Handlingβ β β’ Replication β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
Factory Contract β New Pool Created β Start Pool Listening β Pool Events β Standardized Events β ClickHouse Storage
# 1. Install dependencies
yarn install
# 2. Setup environment
cp env.example .env
# Edit .env with your credentials
# 3. Start monitoring
yarn data:ingestion# Check what's been captured
yarn db:view
# Reset if needed
yarn db:reset- Node.js 18+
- Yarn package manager
- Docker and Docker Compose (for local cluster)
- ClickHouse Cloud account (optional, for cloud setup)
- RPC Endpoints for Ethereum and BSC
yarn installcp env.example .envOption A: Local ClickHouse Cluster (Recommended)
# Setup local ClickHouse cluster
yarn clickhouse:setupOption B: ClickHouse Cloud
# Setup ClickHouse Cloud (requires cloud account)
yarn clickhouse:cloud-setupyarn data:ingestionCreate a .env file with your credentials:
# ===========================================
# BLOCKCHAIN RPC ENDPOINTS
# ===========================================
# Ethereum Mainnet
ETHEREUM_RPC_URL=https://eth.llamarpc.com
ETHEREUM_WS_URL=wss://eth.llamarpc.com
# BSC Mainnet
BSC_RPC_URL=https://bsc-dataseed.binance.org/
BSC_WS_URL=wss://bsc-ws-node.nariox.org:443/ws
# ===========================================
# CLICKHOUSE CONFIGURATION
# ===========================================
# For Local ClickHouse Cluster (Default)
CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=8123
CLICKHOUSE_USERNAME=default
CLICKHOUSE_PASSWORD=
CLICKHOUSE_DATABASE=default
CLICKHOUSE_SECURE=false
CLICKHOUSE_CLUSTER_NAME=protocol_cluster
CLICKHOUSE_IS_CLUSTER=false
# For ClickHouse Cloud (Alternative)
# CLICKHOUSE_HOST=abcdef.azure.clickhouse.cloud
# CLICKHOUSE_PORT=8443
# CLICKHOUSE_USERNAME=default
# CLICKHOUSE_PASSWORD=your_password_here
# CLICKHOUSE_DATABASE=default
# CLICKHOUSE_SECURE=true
# CLICKHOUSE_IS_CLUSTER=falseimport { ProtocolListenerApp } from './src/app/protocol-listener';
const config = {
rpcUrl: 'https://your-rpc-url',
wsUrl: 'wss://your-ws-url',
chainId: 1, // Ethereum Mainnet
protocols: ['uniswap-v2', 'uniswap-v3']
};
const listener = new ProtocolListenerApp(config);| Command | Description | Usage |
|---|---|---|
yarn data:ingestion |
Main command - Start blockchain monitoring | yarn data:ingestion |
yarn db:view |
View database contents and statistics | yarn db:view |
yarn db:reset |
Clear all data from database | yarn db:reset |
| Command | Description | Usage |
|---|---|---|
yarn clickhouse:setup |
Setup local ClickHouse cluster | yarn clickhouse:setup |
yarn cluster:start |
Start ClickHouse cluster | yarn cluster:start |
yarn cluster:stop |
Stop ClickHouse cluster | yarn cluster:stop |
yarn cluster:logs |
View cluster logs | yarn cluster:logs |
yarn cluster:status |
Check cluster status | yarn cluster:status |
yarn cluster:verify |
Verify cluster health and replication | yarn cluster:verify |
| Command | Description | Usage |
|---|---|---|
yarn listener:ethereum |
Start Ethereum event listener | yarn listener:ethereum |
yarn listener:bsc |
Start BSC event listener | yarn listener:bsc |
yarn listener:all |
Start all blockchain listeners | yarn listener:all |
| Command | Description | Usage |
|---|---|---|
yarn dev |
Start Next.js development server | yarn dev |
yarn build |
Build the application | yarn build |
yarn start |
Start production server | yarn start |
yarn lint |
Run ESLint | yarn lint |
| Command | Description | Usage |
|---|---|---|
yarn db:view |
View all events and statistics | yarn db:view |
yarn db:reset |
Clear all data (use with caution) | yarn db:reset |
# 1. Setup environment
cp env.example .env
# 2. Setup ClickHouse cluster
yarn clickhouse:setup
# 3. Start monitoring
yarn data:ingestion
# 4. View data
yarn db:view
# 5. Start web interface
yarn dev# Start cluster
yarn cluster:start
# Check cluster status
yarn cluster:status
# View cluster logs
yarn cluster:logs
# Verify cluster health
yarn cluster:verify
# Stop cluster
yarn cluster:stop# View recent events
yarn db:view
# Check specific protocol
# (Use ClickHouse console for advanced queries)| Command | Description | Usage |
|---|---|---|
yarn db:view |
Quick database viewer - Shows events, stats, and analytics | yarn db:view |
yarn dev |
Web interface - Start Next.js dashboard at localhost:3000 | yarn dev |
# Connect to ClickHouse directly
docker exec -it clickhouse-single clickhouse-client
# Then run SQL queries:
SHOW TABLES;
SELECT count() FROM protocol_events;
SELECT * FROM protocol_events ORDER BY timestamp DESC LIMIT 10;
SELECT protocol, count() as event_count FROM protocol_events GROUP BY protocol;
EXIT;# Test connection
curl http://localhost:8123
# Run queries via HTTP
curl -X POST 'http://localhost:8123' -d 'SELECT count() FROM protocol_events'
curl -X POST 'http://localhost:8123' -d 'SELECT * FROM protocol_events LIMIT 5'1. Quick Overview (Recommended)
yarn db:view2. Web Dashboard
yarn dev
# Open http://localhost:3000 in your browser3. Direct SQL Access
docker exec -it clickhouse-single clickhouse-client4. HTTP API Queries
curl -X POST 'http://localhost:8123' -d 'YOUR_SQL_QUERY'When you run yarn db:view, you'll see output like this:
π ClickHouse Database Viewer
β
Connected to ClickHouse
π Tables in database:
=====================
- protocol_events
π Event Statistics:
===================
Total events: 100
π Recent Events (last 10):
==========================
1. uniswap-v2 swap
Pool: 0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852
Tokens: WETH/USDT
Block: 23581685 | Time: 2025-10-15 07:45:54
2. uniswap-v2 sync
Pool: 0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc
Tokens: USDC/WETH
Block: 23581685 | Time: 2025-10-15 07:45:54
π Event Statistics by Protocol:
================================
uniswap-v2 sync: 59 events
uniswap-v2 swap: 41 events
π Real-time Analytics:
======================
uniswap-v2 swap at 2025-10-15 07:00:00:
Events: 41, Pools: 3, Transactions: 40
uniswap-v2 sync at 2025-10-15 07:00:00:
Events: 59, Pools: 3, Transactions: 56
β
Database view completed
# 1. View database overview
yarn db:view
# 2. Start web dashboard
yarn dev
# Then open http://localhost:3000
# 3. Direct SQL access
docker exec -it clickhouse-single clickhouse-client
# 4. Test connection
curl http://localhost:8123Swap: Token swaps in liquidity poolsMint: Liquidity provision eventsBurn: Liquidity removal eventsSync: Reserve updatesPairCreated: New pair creation (factory events)
Swap: Token swaps with concentrated liquidityMint: Liquidity provision in price rangesBurn: Liquidity removal from price rangesInitialize: Pool initialization with starting pricePoolCreated: New pool creation (factory events)
All events are normalized to this structure:
interface StandardizedEvent {
// Core identification
id: string; // Unique event identifier
protocol: ProtocolType; // 'uniswap-v2' | 'uniswap-v3' | 'pancakeswap-v2'
version: string; // Protocol version
eventType: EventType; // 'swap' | 'mint' | 'burn' | 'sync' | 'initialize'
timestamp: number; // Unix timestamp
blockNumber: number; // Blockchain block number
transactionHash: string; // Transaction hash
logIndex: number; // Log index in transaction
// Pool/Pair information
poolAddress: string; // Pool/pair contract address
token0: TokenInfo; // First token information
token1: TokenInfo; // Second token information
// Event-specific data
data: SwapEventData | LiquidityEventData | SyncEventData | InitializeEventData;
// Additional metadata
gasUsed?: string;
gasPrice?: string;
fee?: string;
}
interface TokenInfo {
address: string;
symbol: string;
decimals: number;
name?: string;
}CREATE TABLE protocol_events (
id String,
protocol String,
version String,
event_type String,
timestamp UInt64,
block_number UInt64,
transaction_hash String,
log_index UInt64,
pool_address String,
token0_address String,
token0_symbol String,
token0_decimals UInt8,
token0_name String,
token1_address String,
token1_symbol String,
token1_decimals UInt8,
token1_name String,
event_data String,
gas_used String,
gas_price String,
fee String,
created_at DateTime DEFAULT now()
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(toDateTime(timestamp / 1000))
ORDER BY (protocol, event_type, block_number, transaction_hash, log_index)The system provides comprehensive monitoring:
- π Event Statistics: Real-time event counts and protocol breakdown
- π Pool Discovery: Automatic detection of new pools and markets
- π Data Consistency: Replication status and data integrity checks
- β‘ Performance Metrics: Event processing rates and system health
- π Materialized Views: Pre-computed analytics for fast queries
- π Advanced Filtering: Filter by protocol, event type, time range
- π Real-time Dashboards: Live event monitoring and statistics
- ποΈ Data Export: Export data for external analysis
- ποΈ Local Cluster: 3-replica cluster with ClickHouse Keeper for coordination
- βοΈ Cloud Scalability: Handles high-volume event processing
- π Real-time Analytics: Materialized views for instant insights
- π Advanced Querying: SQL-based analytics and reporting
- π Data Visualization: Built-in dashboard and monitoring tools
- π Data Replication: Automatic replication across cluster nodes
protocol-adapters/
βββ π src/
β βββ π core/
β β βββ EventListener.ts # Main event listening engine
β β βββ ClickHouseService.ts # ClickHouse database operations
β β βββ DataIngestionService.ts # Data ingestion orchestration
β βββ π types/
β β βββ schemas.ts # Standardized event schemas
β β βββ contracts.ts # Contract addresses and ABIs
β βββ π app/
β β βββ protocol-listener.ts # Application wrapper
β β βββ page.tsx # Next.js UI for event display
β βββ π scripts/
β βββ run-data-ingestion.ts # Main data ingestion script
β βββ view-database.ts # Database viewer script
β βββ reset-database.ts # Database reset script
β βββ setup-clickhouse-cluster.ts # ClickHouse cluster setup script
β βββ verify-cluster.ts # Cluster verification script
βββ π package.json # Dependencies and scripts
βββ π env.example # Environment variables template
βββ π README.md # This documentation
βββ π docker-compose.cluster.yml # ClickHouse cluster configuration
βββ π CLUSTER_SETUP.md # ClickHouse cluster setup guide
βββ π clickhouse-configs/ # ClickHouse configuration files
| Component | Purpose | Key Features |
|---|---|---|
| EventListener | Core event processing | Multi-protocol support, real-time listening |
| ClickHouseService | Database operations | Cloud integration, BigInt handling |
| DataIngestionService | Data orchestration | Event buffering, batch processing |
| Protocol Adapters | Protocol-specific logic | Uniswap V2/V3, PancakeSwap V2 |
| UI Components | Event visualization | Real-time display, statistics |
# Check if ClickHouse is running
docker ps | grep clickhouse
# Check ClickHouse logs
docker logs clickhouse-single
# Restart ClickHouse
docker restart clickhouse-single# Ensure .env file has correct settings
cat .env
# Restart ClickHouse with proper environment
docker stop clickhouse-single
docker rm clickhouse-single
docker run -d --name clickhouse-single -p 8123:8123 -p 9000:9000 -e CLICKHOUSE_USER=default -e CLICKHOUSE_PASSWORD= clickhouse/clickhouse-server:latest# Check cluster status
yarn cluster:status
# View cluster logs
yarn cluster:logs
# Restart cluster
yarn cluster:stop
yarn cluster:start# Start the full cluster
yarn clickhouse:setup
# Or start manually
yarn cluster:start# Check cluster status
yarn cluster:status
# Verify replication
yarn cluster:verify
# View cluster logs
yarn cluster:logs# Stop cluster
yarn cluster:stop
# Stop and remove volumes
docker-compose -f docker-compose.cluster.yml down -v# Test ClickHouse connection
curl http://localhost:8123
# View database contents
yarn db:view
# Check environment variables
cat .env
# View application logs
yarn data:ingestion