Whitelist Indexer
Comprehensive real-time indexing for the Whitelist contract, providing complete audit trails, section lifecycle management, and analytics for Merkle tree-based whitelisting operations.
Overview
The Whitelist indexer processes all whitelist management events from the Whitelist contract, transforming raw blockchain events into structured, queryable data. It provides real-time tracking of section management, administrative changes, and comprehensive analytics for governance transparency and operational monitoring.
Features
🔍 Event Processing
- MerkleRootUpdated: Section lifecycle management with creation/update detection
- RoleHelperUpdated: Security-critical role helper contract changes
- Initialized: Contract deployment and initialization tracking
- Upgraded: UUPS proxy upgrade monitoring
📊 Data Analytics
- Section creation and activity metrics
- Manager attribution and contribution tracking
- Administrative operation history
- Real-time global statistics
🛡️ Data Integrity
- Duplicate event prevention
- Transaction-level consistency
- Type-safe data validation
- Comprehensive error handling
Database Schema
whitelistSections Table
Track current state and metadata for each whitelist section.
{
id: number, // Section ID (composite primary key with chainId)
chainId: number, // Chain ID for multi-chain support
currentRoot: Hash, // Current Merkle root hash
isActive: boolean, // Whether section has valid root
createdAt: bigint, // Section creation timestamp
lastUpdated: bigint, // Most recent update timestamp
updateCount: number, // Total number of updates
createdBy: Address, // Manager who created section
lastUpdatedBy: Address // Manager who last updated
}- Section lifecycle monitoring
- Manager activity tracking
- Update frequency analysis
- Active section counting
whitelistRootActivities Table
Complete history of all Merkle root updates.
{
id: Hash, // Event ID (composite primary key with chainId)
chainId: number, // Chain ID for multi-chain support
section: number, // Section ID being updated
oldRoot: Hash | null, // Previous root (null for new)
newRoot: Hash, // New Merkle root hash
updatedBy: Address, // Manager performing update
timestamp: bigint, // Block timestamp
blockNumber: bigint // Block number
}- Complete audit trail
- Root change history
- Manager attribution
- Compliance reporting
whitelistAdminActivities Table
Track administrative operations like role helper updates and upgrades.
{
id: Hash, // Event ID (composite primary key with chainId)
chainId: number, // Chain ID for multi-chain support
type: number, // Activity category (WhitelistAdminActivityType enum as integer)
oldValue: Hash | null, // Previous value (nullable)
newValue: Hash, // New value being set
initiatedBy: Address, // Admin who initiated
timestamp: bigint, // Block timestamp
blockNumber: bigint // Block number
}ROLE_HELPER_UPDATED- Role helper contract changesUPGRADED- UUPS implementation upgradesINITIALIZED- Contract initialization events
- Administrative oversight
- Security monitoring
- Governance transparency
- Change tracking
whitelistStats Table
Maintain system-wide statistics and activity metrics.
{
id: "global", // Single row identifier (composite primary key with chainId)
chainId: number, // Chain ID for multi-chain support
totalSections: number, // Total sections ever created
activeSections: number, // Sections with non-zero roots
totalUpdates: number, // Total root updates performed
lastActivity: bigint // Most recent activity timestamp
}- Dashboard metrics
- Performance monitoring
- System health indicators
- Activity timeline
API Usage
GraphQL Queries
Get All Active Sections
query ActiveSections {
whitelistSections(where: { isActive: true }) {
id
currentRoot
createdAt
lastUpdated
updateCount
createdBy
lastUpdatedBy
}
}Section Activity History
query SectionHistory($sectionId: Int!) {
whitelistRootActivities(
where: { section: $sectionId }
orderBy: { timestamp: "desc" }
) {
id
oldRoot
newRoot
updatedBy
timestamp
blockNumber
}
}Administrative Activities
query AdminActivities {
whitelistAdminActivities(
orderBy: { timestamp: "desc" }
limit: 10
) {
id
type
oldValue
newValue
initiatedBy
timestamp
}
}Global Statistics
query GlobalStats {
whitelistStats(where: { id: "global" }) {
totalSections
activeSections
totalUpdates
lastActivity
}
}REST API Examples
Section Information
# Get specific section details
GET /api/whitelistSections/1
# Get all sections with filtering
GET /api/whitelistSections?isActive=true&limit=50Activity Monitoring
# Recent root update activities
GET /api/whitelistRootActivities?orderBy=timestamp:desc&limit=20
# Administrative activities
GET /api/whitelistAdminActivities?type=1&limit=10Performance Features
Optimization Strategies
- Event ID Deduplication: Prevents duplicate processing using unique event identifiers
- Atomic Operations: All database updates wrapped in transaction-safe operations
- Efficient Queries: Targeted database operations with minimal overhead
- Batch-Safe Design: Handlers designed for concurrent event processing
High-Volume Handling
- Memory Management: Minimal object allocation in event processing loops
- Conditional Logic: Existence checks before insertions to prevent conflicts
- Index Optimization: Strategic database indexing for query performance
Integration Examples
Dashboard Analytics
// Get section management overview
const sectionOverview = await ponder.findMany(whitelistSections, {
select: {
id: true,
isActive: true,
updateCount: true,
lastUpdated: true,
lastUpdatedBy: true
},
orderBy: { lastUpdated: 'desc' },
take: 10
});
// Calculate manager activity metrics
const managerStats = await ponder.findMany(whitelistRootActivities, {
select: {
updatedBy: true,
_count: { updatedBy: true }
},
groupBy: ['updatedBy']
});Security Monitoring
// Monitor role helper changes
const roleHelperChanges = await ponder.findMany(whitelistAdminActivities, {
where: { type: WhitelistAdminActivityType.ROLE_HELPER_UPDATED },
orderBy: { timestamp: 'desc' },
take: 5
});
// Track recent upgrades
const upgrades = await ponder.findMany(whitelistAdminActivities, {
where: { type: WhitelistAdminActivityType.UPGRADED },
include: {
// Additional details about the upgrade
}
});Cross-Contract Analytics
// Correlate with Roles indexer data
const adminRoles = await ponder.findMany(users, {
where: {
roles: { has: ADMIN_ROLE },
id: { in: recentAdminActivities.map(a => a.initiatedBy) }
}
});Monitoring & Health
Indexer Health Checks
- Event processing latency monitoring
- Database connection health
- Error rate tracking
- Memory usage optimization
Performance Metrics
- Events processed per second
- Database query performance
- API response times
- Resource utilization
Alert Conditions
- Unusual administrative activity patterns
- High-frequency section updates
- Failed event processing
- Database connection issues
Deployment Configuration
Environment Setup
// ponder.config.ts
export default createConfig({
contracts: {
Whitelist: {
chain: "mainnet", // or your target chain
abi: whitelistAbi,
address: "0x...", // deployed contract address
startBlock: 0, // deployment block number
},
},
});Production Considerations
- Database Scaling: Configure appropriate connection pools
- Monitoring: Set up comprehensive logging and alerting
- Backup Strategy: Regular database backups and recovery procedures
- Performance Tuning: Index optimization and query performance monitoring
Security Considerations
Data Integrity
- Immutable Audit Trail: All events stored with block-level precision
- Transaction Context: Full transaction hash and block number recording
- Manager Attribution: Complete tracking of who performed each action
Access Control
- Read-Only API: Indexer provides read-only access to processed data
- Input Validation: Comprehensive validation of all event data
- Error Handling: Graceful handling of malformed or missing events
Compliance Features
- Complete History: Permanent record of all administrative actions
- Governance Transparency: Full audit trail for role helper and upgrade operations
- Time-Based Queries: Historical analysis with precise timestamp filtering