Skip to content

Indexer

Real-time blockchain data indexing powered by Ponder, providing efficient event processing and GraphQL APIs for the ifif ecosystem.

Overview

Our indexing infrastructure captures and processes blockchain events in real-time, transforming raw event data into structured, queryable datasets. Built on Ponder's robust framework, the indexers provide comprehensive analytics and audit trails for smart contract interactions.

Current Implementation: 4 production-ready indexers covering comprehensive project lifecycle tracking, factory operations, role management, and whitelist operations, with 27 specialized database tables providing complete audit trails and real-time analytics.

Available Indexers

🏗️ IFIF Indexer

Comprehensive project lifecycle tracking with investment analytics, NFT management, and asset distribution.

Key Features:
  • Project stage transitions and configuration tracking
  • Investment and refund processing with bonus calculations
  • Complete NFT lifecycle management (claim, split, merge, convert)
  • Asset distribution and token claim tracking
  • Cross-project user analytics and daily metrics
  • Signature nonce tracking for replay attack prevention
Data Tables:
  • project - Core project state and configuration
  • projectStageHistory - Stage transition audit trail
  • projectConfigUpdate - Configuration change tracking
  • deploymentDetailsUpdate - Project metadata updates
  • contractUpgrade - Contract upgrade tracking
  • userPurchase - Individual investment transactions
  • userRefund - Refund processing and tracking
  • userInvestmentSummary - Aggregated user investments
  • nftAllocation - NFT ownership and weight tracking
  • nftOperation - Complete NFT operation history
  • nftTransfer - NFT transfer event tracking
  • assetDeposit - Asset distribution tracking
  • tokenClaim - Token claim event tracking
  • dexPair - DEX integration monitoring
  • userProfile - Cross-project user analytics
  • dailyMetric - Platform-wide daily analytics
  • nonceConsumption - Signature nonce audit trail
  • nonceState - Current nonce state tracking

🧬 IFIFv2 Indexer

Advanced IFIFv2 event tracking with explicit v2 configuration, fund claim, distributor, and sweep event support. Fully multi-chain compatible and version-aware.

Key Features:
  • v2-specific event processing (ConfigV2Updated, FundClaimConfigUpdated, DistributorConfigUpdated, ClaimConfigUpdated, FundClaimed, Sweept)
  • Multi-chain support via chainId in all tables and queries
  • Composite primary keys for cross-chain event deduplication
  • Version-aware event handling and state management
Data Tables:
  • projectV2Config - v2 configuration tracking
  • fundClaimConfig - Fund claim configuration
  • distributorConfig - Distributor and fee configuration
  • claimConfig - Claim configuration
  • fundClaim - Fund claim events
  • sweep - Project sweep events

🏭 IFIF Factory Indexer

Factory operations and system administration tracking with deployment analytics.

Key Features:
  • Project and token deployment monitoring
  • System configuration and upgrade tracking
  • Administrative operation history
  • Infrastructure component updates
  • Factory performance analytics
Data Tables:
  • factoryDeployment - Project deployment tracking
  • tokenDeployment - Token deployment linking
  • factorySystemUpdate - System configuration tracking
  • deploymentDetailsUpdate - Project metadata updates

🔐 Roles Indexer

Comprehensive role-based access control event tracking with real-time analytics.

Key Features:
  • Role grant/revoke event processing
  • User role state management
  • Ownership history tracking
  • Statistical analytics and metrics
Data Tables:
  • roleActivities - Complete audit trail
  • users - Current role assignments
  • roleStats - Role holder statistics
  • rolesOwnershipHistory - Governance transparency

📋 Whitelist Indexer

Advanced Merkle tree-based whitelisting system with section lifecycle management.

Key Features:
  • Section creation and root update tracking
  • Administrative activity monitoring
  • Real-time analytics and metrics
  • UUPS upgrade and initialization tracking
Data Tables:
  • whitelistSections - Section lifecycle management
  • whitelistRootActivities - Complete audit trail
  • whitelistAdminActivities - Administrative operations
  • whitelistStats - Global analytics

Architecture

Technology Stack

  • Framework: Ponder v0.12+ with TypeScript integration
  • Database: PostgreSQL with Drizzle ORM for type-safe operations
  • API: Auto-generated GraphQL and SQL endpoints
  • Type Safety: Full TypeScript integration with contract ABI generation

Core Features

  • Real-time Processing: Events indexed as they occur with duplicate prevention
  • Data Integrity: Transaction-safe operations with comprehensive validation
  • Scalable Design: Optimized for high-volume event processing across multiple contracts
  • Developer Experience: Type-safe queries, comprehensive documentation, and performance monitoring
  • Cross-Contract Analytics: Coordinated indexing across IFIF, Factory, Roles, and Whitelist contracts

Getting Started

Development Setup

# Start local blockchain (choose based on your architecture)
pnpm anvil-arm   # For ARM-based systems (M1/M2 Macs)
pnpm anvil-amd   # For AMD/Intel systems
 
# Run indexer in development mode
pnpm indexer:dev
 
# Access GraphQL playground
open http://localhost:42069

Production Deployment

# Start production server
pnpm indexer:start

GraphQL API

Each indexer exposes a comprehensive GraphQL endpoint for querying processed data with full schema introspection:

  • Development: http://localhost:42069
  • Production: Configured per deployment environment

Query Examples

IFIF Indexer Queries

# Get project details with investment summary
query ProjectOverview($address: String!) {
  project(id: $address) {
    id
    projectId
    stage
    totalPurchase
    fundingTarget
    token
    dexPair
  }
  userInvestmentSummaries(where: { projectAddress: $address }) {
    items {
      user
      totalPurchased
      totalWeight
      bonusEarned
    }
  }
}
 
# Get user investment portfolio
query UserPortfolio($user: String!) {
  userProfile(id: $user) {
    totalProjectsInvested
    totalAmountInvested
    totalTokensClaimed
    totalNftsClaimed
  }
  userInvestmentSummaries(where: { user: $user }) {
    items {
      projectAddress
      totalPurchased
      isRefunded
    }
  }
}

Factory Indexer Queries

# Get recent project deployments
query RecentDeployments($limit: Int = 10) {
  factoryDeployments(
    limit: $limit
    orderBy: "timestamp"
    orderDirection: "desc"
  ) {
    items {
      projectId
      projectAddress
      projectName
      projectSymbol
      timestamp
    }
  }
}
 
# Get system updates
query SystemUpdates {
  factorySystemUpdates(
    orderBy: "timestamp"
    orderDirection: "desc"
    limit: 20
  ) {
    items {
      updateType
      newValue
      timestamp
    }
  }
}

Roles Indexer Queries

# Get recent role activities
query RecentActivities {
  roleActivities(limit: 10, orderBy: "timestamp", orderDirection: "desc") {
    items {
      id
      type
      role
      account
      sender
      timestamp
    }
  }
}
 
# Get user roles
query UserRoles($address: String!) {
  user(id: $address) {
    id
    roles
  }
}
 
#### Whitelist Indexer Queries
```graphql
# Get active whitelist sections
query ActiveSections {
  whitelistSections(where: { isActive: true }) {
    id
    currentRoot
    updateCount
    lastUpdated
    lastUpdatedBy
  }
}
 
# Get section activity history
query SectionHistory($sectionId: Int!) {
  whitelistRootActivities(
    where: { section: $sectionId }
    orderBy: { timestamp: "desc" }
  ) {
    id
    oldRoot
    newRoot
    updatedBy
    timestamp
  }
}

Integration

Frontend Integration

import { GraphQLClient } from 'graphql-request'
 
const client = new GraphQLClient('http://localhost:42069')
 
// Query user roles
const getUserRoles = async (address: string) => {
  const query = `
    query GetUser($id: String!) {
      user(id: $id) {
        id
        roles
      }
    }
  `
  return client.request(query, { id: address })
}
 
// Query whitelist section status
const getSectionStatus = async (sectionId: number) => {
  const query = `
    query GetSection($id: Int!) {
      whitelistSection(id: $id) {
        id
        currentRoot
        isActive
        updateCount
        lastUpdatedBy
      }
    }
  `
  return client.request(query, { id: sectionId })
}

Cross-Contract Analytics

// Correlate role assignments with whitelist management
const getManagerActivity = async (managerAddress: string) => {
  const query = `
    query ManagerAnalytics($address: String!) {
      # Check manager roles
      user(id: $address) {
        roles
      }
      
      # Get their whitelist activities
      whitelistRootActivities(
        where: { updatedBy: $address }
        orderBy: { timestamp: "desc" }
        limit: 10
      ) {
        section
        newRoot
        timestamp
      }
    }
  `
  return client.request(query, { address: managerAddress })
}

Real-time Updates

// Subscribe to role changes
const roleSubscription = `
  subscription RoleUpdates {
    roleActivities(orderBy: "timestamp", orderDirection: "desc") {
      id
      type
      account
      role
    }
  }
`
 
// Subscribe to whitelist section updates
const whitelistSubscription = `
  subscription WhitelistUpdates {
    whitelistRootActivities(orderBy: "timestamp", orderDirection: "desc") {
      id
      section
      newRoot
      updatedBy
    }
  }
`

Performance & Monitoring

Metrics

  • Event Processing: Latency and throughput for all indexers
  • Database Performance: Query optimization across 27 specialized tables
  • API Response Times: GraphQL and SQL endpoint performance
  • Data Consistency: Cross-table integrity and audit trail validation
  • Resource Usage: Memory and CPU optimization for concurrent processing

Optimization Strategies

  • Efficient Indexing: Strategic database indexes for complex queries
  • Query Caching: Result caching for frequently accessed data
  • Batch Processing: Optimized handling of high-volume events
  • Memory Management: Minimal allocation in event processing loops
  • Duplicate Prevention: Event ID-based deduplication across all handlers

Contributing

Adding New Indexers

  1. Schema Design: Create tables in indexer/ponder.schema.ts with proper relationships
  2. Event Handlers: Implement handlers in indexer/src/ with duplicate prevention
  3. Contract Configuration: Add contract to ponder.config.ts with correct ABI
  4. Handler Registration: Import handlers in indexer/src/index.ts
  5. Documentation: Create comprehensive API docs following existing patterns
  6. Testing: Validate event processing and data integrity

Best Practices

  • Type Safety: Use TypeScript with full Viem integration for contract types
  • Error Handling: Implement comprehensive error recovery and logging
  • Documentation: Add detailed JSDoc and user documentation (see /indexer/roles and /indexer/whitelist)
  • Performance: Include duplicate prevention and batch-safe design patterns
  • Consistency: Follow established naming conventions and schema patterns
  • Security: Validate all inputs and maintain complete audit trails