Skip to content

omnipair/omnipair-indexer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

70 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Omnipair Indexer

A comprehensive blockchain indexer for the Omnipair protocol on Solana, built with a modern hybrid architecture combining Rust performance with TypeScript flexibility.

πŸ—οΈ Architecture Overview

This project uses a hybrid Rust/TypeScript architecture that leverages the strengths of both languages:

  • Rust Indexer Daemon: High-performance data ingestion and processing using the Carbon framework
  • TypeScript API Server: Flexible REST API for client applications using modern web technologies
  • Shared Database Layer: PostgreSQL with TimescaleDB for optimal time-series data storage

System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Solana RPC    β”‚    β”‚   WebSocket     β”‚    β”‚   Client Apps   β”‚
β”‚   & WebSocket   β”‚    β”‚   Real-time     β”‚    β”‚   & Frontends   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                      β”‚                      β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚                      β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
    β”‚                                                          β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
    β”‚  β”‚   Rust Indexer      β”‚    β”‚   TypeScript API        β”‚  β”‚
    β”‚  β”‚   (Carbon-based)    β”‚    β”‚   (Bun + Drizzle)      β”‚  β”‚
    β”‚  β”‚                     β”‚    β”‚                         β”‚  β”‚
    β”‚  β”‚ β€’ Event Processing  β”‚    β”‚ β€’ REST Endpoints       β”‚  β”‚
    β”‚  β”‚ β€’ Account Decoding  β”‚    β”‚ β€’ Query Optimization   β”‚  β”‚
    β”‚  β”‚ β€’ Real-time Sync    β”‚    β”‚ β€’ Response Caching     β”‚  β”‚
    β”‚  β”‚ β€’ Backfilling       β”‚    β”‚ β€’ Rate Limiting        β”‚  β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
    β”‚                     β”‚                      β”‚             β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚                      β”‚
                          β–Ό                      β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚             PostgreSQL + TimescaleDB                    β”‚
    β”‚                                                         β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
    β”‚  β”‚   Pairs     β”‚ β”‚ Positions   β”‚ β”‚  Transactions   β”‚   β”‚
    β”‚  β”‚   Config    β”‚ β”‚ & Health    β”‚ β”‚  (Hypertable)   β”‚   β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
    β”‚                                                         β”‚
    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
    β”‚  β”‚ Aggregates  β”‚ β”‚ Price Feeds β”‚ β”‚   Analytics     β”‚   β”‚
    β”‚  β”‚ (1m, 1h)    β”‚ β”‚ & Charts    β”‚ β”‚   & Metrics     β”‚   β”‚
    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Key Features

Indexer Daemon (Rust)

  • Real-time Transaction Monitoring: Live processing of Omnipair protocol events
  • Historical Backfilling: Complete historical data processing with gap detection
  • High Performance: Built with Rust and the Carbon framework for maximum throughput
  • Account Tracking: Real-time monitoring of pairs, positions, and protocol state
  • Robust Error Handling: Automatic retry logic and comprehensive error recovery

API Server (TypeScript)

  • RESTful API: Clean, well-documented REST endpoints for all data access
  • Type Safety: Full TypeScript types with Drizzle ORM integration
  • Performance Optimized: Efficient database queries with caching strategies
  • Rate Limiting: Built-in protection against API abuse
  • Health Monitoring: Comprehensive health checks and system status endpoints

Database Layer

  • TimescaleDB Integration: Optimized for time-series queries and analytics
  • Automatic Aggregation: Continuous aggregates for price feeds and analytics
  • Data Retention: Intelligent data lifecycle management with compression
  • Migration System: Version-controlled schema evolution with Drizzle

πŸ“ Project Structure

omnipair-indexer/
β”œβ”€β”€ indexer/                  # πŸ¦€ Rust indexer daemon
β”‚   β”œβ”€β”€ src/main.rs          # Main indexer application
β”‚   β”œβ”€β”€ crates/              # Carbon framework components
β”‚   β”œβ”€β”€ decoders/            # Omnipair protocol decoders
β”‚   β”œβ”€β”€ datasources/         # RPC and WebSocket data sources
β”‚   β”œβ”€β”€ metrics/             # Performance monitoring
β”‚   └── README.md            # Indexer-specific documentation
β”‚
β”œβ”€β”€ api/                     # πŸ“‘ TypeScript API server
β”‚   β”œβ”€β”€ src/                 # API server source code
β”‚   β”‚   β”œβ”€β”€ routes/          # REST endpoint handlers
β”‚   β”‚   β”œβ”€β”€ services/        # Business logic layer
β”‚   β”‚   └── middleware/      # Express middleware
β”‚   └── README.md            # API-specific documentation
β”‚
β”œβ”€β”€ database/                # πŸ—„οΈ Shared database layer
β”‚   β”œβ”€β”€ lib/schema.ts        # Database schema definitions
β”‚   β”œβ”€β”€ migrations/          # Database migration files
β”‚   β”œβ”€β”€ sql/                 # Custom SQL scripts
β”‚   └── README.md            # Database documentation
β”‚
β”œβ”€β”€ docs/                    # πŸ“š Additional documentation
β”œβ”€β”€ Cargo.toml               # Rust workspace configuration
β”œβ”€β”€ package.json             # Node.js workspace configuration
└── README.md                # This file

πŸš€ Quick Start

Prerequisites

1. Clone and Setup

# Clone the repository
git clone <repository-url>
cd omnipair-indexer

# Install dependencies
bun install  # For TypeScript components

2. Database Setup

# Create database
createdb omnipair_indexer

# Enable TimescaleDB extension
psql omnipair_indexer -c "CREATE EXTENSION IF NOT EXISTS timescaledb;"

# Run database migrations
cd database
bun run migrate
psql omnipair_indexer -f sql/setup-timescaledb.sql
cd ..

3. Environment Configuration

Create .env files in the appropriate directories:

# Root .env (shared configuration)
DATABASE_URL=postgresql://username:password@localhost:5432/omnipair_indexer
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
SOLANA_WS_URL=wss://api.mainnet-beta.solana.com

# Indexer-specific (indexer/.env)
RPC_URL=https://api.mainnet-beta.solana.com
RPC_WS_URL=wss://api.mainnet-beta.solana.com
RUST_LOG=info

# API-specific (api/.env)
PORT=3000
NODE_ENV=development
LOG_LEVEL=info

4. Start Services

# Terminal 1: Start the indexer daemon
cd indexer
cargo run --release

# Terminal 2: Start the API server
cd api
bun run dev

# Or use workspace commands from root
cargo run -p omnipair-carbon-indexer  # Indexer
bun run api:dev                       # API Server

5. Verify Installation

# Check API health
curl http://localhost:3000/health

# Check indexer logs
tail -f indexer/logs/indexer.log

πŸ› οΈ Development

Indexer Development (Rust)

# Build indexer
cargo build -p omnipair-carbon-indexer

# Run with debug logging
RUST_LOG=debug cargo run -p omnipair-carbon-indexer

# Run tests
cargo test

# Watch for changes
cargo install cargo-watch
cargo watch -x "run -p omnipair-carbon-indexer"

API Development (TypeScript)

# Start development server
cd api
bun run dev

# Run tests
bun test

# Type checking
bun run type-check

# Linting
bun run lint

Database Development

# Generate new migration
cd database
bun run migrate:create

# Apply migrations
bun run migrate

# Run custom SQL
bun run sql path/to/script.sql

πŸš€ Deployment

Railway Deployment

This project is optimized for Railway deployment with multi-service configuration:

  1. Database Service: PostgreSQL with TimescaleDB
  2. Indexer Service: Rust daemon (points to indexer/)
  3. API Service: TypeScript server (points to api/)

Each service has its own railway.toml configuration file.

Environment Variables

# Shared across services
DATABASE_URL=${{Postgres.DATABASE_URL}}
SOLANA_RPC_URL=https://your-premium-rpc.com
SOLANA_WS_URL=wss://your-premium-ws.com

# Indexer-specific
RUST_LOG=info

# API-specific
NODE_ENV=production
PORT=3000

Docker Deployment (Planned)

# Build all services
docker-compose build

# Start all services
docker-compose up -d

# View logs
docker-compose logs -f

πŸ“Š Monitoring and Observability

Health Checks

  • Indexer Health: Internal health monitoring with structured logging
  • API Health: GET /health endpoint with database connectivity checks
  • Database Health: TimescaleDB-specific monitoring queries

Metrics Collection

  • Indexer Metrics: Transaction processing rate, RPC call frequency, error rates
  • API Metrics: Request rate, response times, error rates
  • Database Metrics: Query performance, storage utilization, compression ratios

Logging

  • Structured Logging: JSON-formatted logs across all services
  • Log Levels: Configurable log levels for development and production
  • Log Aggregation: Ready for centralized logging systems

πŸ”§ Configuration

Indexer Configuration

# Environment variables
RPC_URL=https://api.mainnet-beta.solana.com
RPC_WS_URL=wss://api.mainnet-beta.solana.com
DATABASE_URL=postgresql://user:pass@host/db
RUST_LOG=info

API Configuration

# Server settings
PORT=3000
NODE_ENV=production

# Database
DATABASE_URL=postgresql://user:pass@host/db

# Rate limiting
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100

# CORS
ALLOWED_ORIGINS=https://yourdomain.com

πŸ“š Documentation

πŸ” API Reference

Core Endpoints

  • GET /health - System health check
  • GET /pairs - List all trading pairs
  • GET /pairs/:address - Get pair details
  • GET /users/:address/positions - Get user positions
  • GET /transactions - Query transaction history
  • GET /analytics/overview - Protocol analytics

Planned Features

  • WebSocket API: Real-time data streaming
  • GraphQL API: Flexible query interface
  • Authentication: API key and JWT-based auth
  • Advanced Analytics: Custom metrics and reporting
  • Alerting System: Real-time notifications

🚨 Troubleshooting

Common Issues

Database Connection

# Test database connectivity
psql $DATABASE_URL -c "SELECT version();"

# Check TimescaleDB extension
psql $DATABASE_URL -c "SELECT * FROM pg_extension WHERE extname = 'timescaledb';"

RPC Connectivity

# Test Solana RPC
curl -X POST -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}' \
  $SOLANA_RPC_URL

Service Health

# Check indexer logs
tail -f indexer/logs/indexer.log

# Check API health
curl http://localhost:3000/health

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Update documentation
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

Development Guidelines

  • Rust Code: Follow Rust best practices, use cargo fmt and cargo clippy
  • TypeScript Code: Use strict TypeScript, follow ESLint rules
  • Database Changes: Always create migrations for schema changes
  • Documentation: Update relevant documentation for any changes
  • Testing: Add tests for new features and bug fixes

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ†˜ Support

For support and questions:

  • Issues: Create an issue in the GitHub repository
  • Documentation: Check the component-specific README files
  • Logs: Review application logs for error details
  • Community: Join our Discord/Telegram for community support

Note: This indexer is specifically designed for the Omnipair protocol on Solana. Ensure you're using the correct program ID and connecting to the appropriate Solana network.

About

Indexes on-chain data to Postgres/TimescaleDB for real-time lookup and historical information.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages