HyperIndex for Neverland Protocol. This indexer tracks lending, rewards, NFT partnerships, leaderboards, and protocol configuration events to power analytics and product surfaces.
The Neverland indexer provides real-time data aggregation for the Neverland DeFi protocol, including:
- Lending Protocol: Track supplies, borrows, interest rates, and reserve dynamics
- Tokenomics: Monitor DUST token emissions, veDUST voting escrow locks, and governance power
- Rewards System: Monitor reward distributions, emission schedules, and configuration history
- NFT Partnerships: Index partnership NFTs with static boost and geometric decay multipliers
- Leaderboard: Track user points, rankings, and competitive metrics
- Protocol Configuration: Capture parameter updates and governance changes
Built with Envio HyperIndex, this indexer leverages:
- HyperSync: Up to 2000x faster blockchain data access
- PostgreSQL: Reliable data storage with full query capabilities
- GraphQL API: Real-time querying interface for frontend applications
- TypeScript: Type-safe handlers and generated bindings
- Node.js 22 or newer
- pnpm 10 or newer
- Docker Desktop (for local development only)
# Install dependencies
pnpm install
# Start local dependencies (Postgres)
pnpm run local:docker:up
# Generate types and bindings
pnpm run codegen
# Start the indexer in development mode
pnpm run devCreate a .env file in the project root (see .env.example):
# Required for HyperSync access (self-hosted only)
ENVIO_API_TOKEN=your-envio-api-token
# Optional: Custom RPC endpoint(s)
# RPC_URL_143=https://rpc-mainnet.monadinfra.com
# Optional: Logging
# LOG_LEVEL=debug
# METRICS_PORT=9090
# Optional: External read controls
# ENVIO_DISABLE_EXTERNAL_CALLS=true
# ENVIO_DISABLE_ETH_CALLS=true
# Optional: One-time chain baselines during settlement
# ENVIO_ENABLE_NFT_CHAIN_SYNC=true
# ENVIO_ENABLE_LP_CHAIN_SYNC=true
# Optional: LP debug logging
# DEBUG_LP_POINTS=trueNote: For production deployments to Envio's hosted service, environment variables are configured through the Envio dashboard instead of a
.envfile.
pnpm run codegen: Generate Envio bindings and types from schema and configpnpm run dev: Run the local indexer with hot reloadpnpm run start: Start the indexer in production modepnpm run stop: Stop the running indexerpnpm run local:docker:up: Start local Postgres for developmentpnpm run local:docker:down: Stop local Postgres
pnpm run format: Format code with Prettierpnpm run format:check: Check code formattingpnpm run lint: Run ESLint checkspnpm run lint:fix: Fix ESLint issuespnpm run type-check: Perform TypeScript type checking
pnpm run test:build: Compile tests todist-testpnpm run test: Compile and run unit testspnpm run test:coverage: Generate coverage reportpnpm run test:coverage:check: Enforce 100% test coverage
neverland-hyperindex/
├── .github/ # GitHub workflows and templates
├── .husky/ # Git hooks
├── abis/ # Contract ABIs
│ ├── helpers/ # Utility contract ABIs
│ ├── leaderboard/ # Leaderboard contract ABIs
│ └── lending/ # Lending protocol ABIs
├── src/
│ ├── __tests__/ # Test suite (unit/integration/e2e)
│ ├── handlers/ # Event handlers
│ │ ├── config.ts # Protocol configuration events
│ │ ├── dustlock.ts # Dust lock events
│ │ ├── leaderboard.ts # Leaderboard and points events
│ │ ├── leaderboardKeeper.ts # Leaderboard keeper/settlement events
│ │ ├── lp.ts # LP position tracking (Uniswap V3)
│ │ ├── nft.ts # NFT partnership events
│ │ ├── pool.ts # Lending protocol events
│ │ ├── rewards.ts # Rewards distribution events
│ │ ├── shared.ts # Shared handler utilities
│ │ └── tokenization.ts # Tokenization events
│ ├── helpers/ # Shared utilities
│ │ ├── constants.ts # Constant values
│ │ ├── entityHelpers.ts # Database entity helpers
│ │ ├── leaderboard.ts # Leaderboard calculation logic
│ │ ├── math.ts # Mathematical operations (ray/wad)
│ │ ├── points.ts # Points calculation logic
│ │ ├── protocolAggregation.ts # Protocol-level aggregations
│ │ ├── uniswapV3.ts # Uniswap V3 math helpers
│ │ └── viem.ts # Viem utilities
│ └── types/ # TypeScript type definitions
│ └── shims.d.ts # Type shims
├── .env.example # Environment variables template
├── .gitignore # Git ignore file
├── LICENSE # License file
├── README.md # Project documentation
├── config.yaml # Indexer configuration
├── package.json # Project dependencies and scripts
├── pnpm-workspace.yaml # pnpm workspace configuration
├── schema.graphql # GraphQL schema definition
└── tsconfig.json # TypeScript configuration
The indexer is configured to track Neverland Protocol on Monad. Update config.yaml to:
- Add new contracts or events
- Adjust start blocks, batch sizes, and reorg depth
- Configure multiple networks (for multichain support)
- Override RPC URLs with
RPC_URL_<CHAIN_ID>in.env
When modifying schema.graphql:
- Run
pnpm run codegento regenerate types - Update handlers to use new entities
- Run tests to ensure compatibility
-
Connect GitHub Repository
- Install the Envio Deployments GitHub App
- Select your repository and configure deployment branch
-
Configure Environment Variables
- Navigate to the Envio dashboard
- Add required environment variables (prefixed with
ENVIO_) - Optional performance flags live outside the
ENVIO_namespace - No need for
ENVIO_API_TOKEN- provided automatically
-
Deploy
git push origin main # Triggers automatic deployment -
Monitor
- View deployment status in the Envio Explorer
- Check logs and sync status in real-time
The project includes production-ready Docker Compose configurations for self-hosted deployments.
The self-hosted stack includes:
- PostgreSQL 16: Data storage with persistent volumes
- Hasura GraphQL Engine: Auto-generated GraphQL API layer
- Envio Indexer: Event processing and data aggregation
- Cloudflare Tunnel (optional): Secure external access without exposing ports
- Create environment file (
.env):
# Required
ENVIO_API_TOKEN=your-envio-api-token
# Database credentials
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your-secure-password
POSTGRES_DB=envio
# Hasura admin secret
HASURA_ADMIN_SECRET=your-admin-secret
# RPC endpoint (optional, defaults to public Monad RPC)
RPC_URL_143=https://rpc-mainnet.monadinfra.com
# Cloudflare Tunnel token (optional, for external access)
CLOUDFLARE_TUNNEL_TOKEN=your-tunnel-token
# Optional: Feature flags
ENVIO_ENABLE_NFT_CHAIN_SYNC=false
ENVIO_ENABLE_LP_CHAIN_SYNC=false
DEBUG_LP_POINTS=false
# Optional: Logging
LOG_LEVEL=info
METRICS_PORT=9090- Deploy production stack:
docker compose -f docker-compose.prod.yml up -d- Verify deployment:
# Check service health
docker compose -f docker-compose.prod.yml ps
# View logs
docker compose -f docker-compose.prod.yml logs -f indexer
# Access Hasura console (local only)
open http://localhost:8080/consoleFor testing before production deployment:
# Deploy staging (uses separate database and ports)
docker compose -f docker-compose.staging.yml up -d
# Staging runs on:
# - PostgreSQL: port 5433
# - Hasura: port 8081
# - Metrics: port 9091Production:
- GraphQL API:
http://localhost:8080/v1/graphql - Hasura Console:
http://localhost:8080/console - Metrics:
http://localhost:9090 - PostgreSQL:
localhost:5432
Staging:
- GraphQL API:
http://localhost:8081/v1/graphql - Hasura Console:
http://localhost:8081/console - Metrics:
http://localhost:9091 - PostgreSQL:
localhost:5433
For secure public access without exposing ports:
- Create a Cloudflare Tunnel in your Cloudflare dashboard
- Configure tunnel to route to
http://hasura:8080 - Add
CLOUDFLARE_TUNNEL_TOKENto.env - Tunnel automatically starts with the stack
Data is stored in Docker volumes:
postgres_data: Database filesnode_modules: Cached dependenciespnpm_store: pnpm package cache
To backup database:
docker exec neverland-postgres pg_dump -U postgres envio > backup.sqlTo restore:
cat backup.sql | docker exec -i neverland-postgres psql -U postgres envio# Pull latest code
git pull origin main
# Rebuild and restart (preserves data)
docker compose -f docker-compose.prod.yml up -d --build
# View startup logs
docker compose -f docker-compose.prod.yml logs -f indexerTo resync from genesis:
# Stop services
docker compose -f docker-compose.prod.yml down
# Remove database volume (WARNING: deletes all indexed data)
docker volume rm neverland-envio_postgres_data
# Restart
docker compose -f docker-compose.prod.yml up -dIndexer not starting:
# Check logs
docker compose -f docker-compose.prod.yml logs indexer
# Verify Hasura is healthy
docker compose -f docker-compose.prod.yml ps hasura
# Check database connection
docker exec neverland-postgres psql -U postgres -d envio -c "SELECT 1"Slow sync performance:
- Verify
ENVIO_API_TOKENis set correctly - Check RPC endpoint latency
- Monitor system resources (CPU, RAM, disk I/O)
- Review
LOG_LEVEL=debugfor bottlenecks
Out of memory:
- Increase Docker memory limit (Settings → Resources)
- Adjust
ENVIO_THROTTLE_*environment variables to reduce concurrency
Once deployed, query your indexed data using GraphQL:
query {
ProtocolStats(where: { id: { _eq: "current" } }) {
tvlUsd
suppliesUsd
borrowsUsd
totalRevenueUsd
updatedAt
}
}
query {
LeaderboardState {
currentEpochNumber
isActive
}
UserEpochStats(
where: { epochNumber: { _eq: "1" } }
orderBy: totalPoints
orderDirection: desc
first: 10
) {
user_id
totalPoints
lpPoints
depositPoints
borrowPoints
rank
lastUpdatedAt
}
LeaderboardBlacklist(where: { isBlacklisted: { _eq: true } }) {
user_id
lastUpdate
}
}
query {
LPPoolConfig(where: { pool: { _eq: "0x..." } }) {
pool
token0
token1
fee
lpRateBps
isActive
}
LPPoolState(where: { pool: { _eq: "0x..." } }) {
currentTick
token0Price
token1Price
lastUpdate
}
LPPoolFeeStats(where: { pool: { _eq: "0x..." } }) {
volumeUsd24h
feesUsd24h
feeAprBps
lastUpdate
}
UserLPPosition(where: { user_id: { _eq: "0x..." } }) {
tokenId
pool
isInRange
valueUsd
lastSettledAt
}
}
query {
# Get all active NFT partnerships with multiplier configuration
NFTPartnership(where: { active: { _eq: true } }) {
id
collection
name
active
staticBoostBps # null = decay, 0 = decay, >0 = static boost (e.g., 2000 = 20%)
startTimestamp
endTimestamp
}
# Get decay configuration for collections without static boost
NFTMultiplierConfig(where: { id: { _eq: "current" } }) {
firstBonus # First NFT bonus (e.g., 1000 = 10%)
decayRatio # Decay ratio (e.g., 9000 = 90% of previous)
lastUpdate
}
# Get user's NFT holdings and calculated multiplier
UserLeaderboardState(where: { id: { _eq: "0x..." } }) {
nftCount
nftMultiplier # Combined static + decay multiplier
vpMultiplier
combinedMultiplier # (nftMultiplier * vpMultiplier) / 10000, capped at 100000
votingPower
lifetimePoints
}
# Get user's specific NFT ownership
UserNFTOwnership(
where: {
user_id: { _eq: "0x..." }
hasNFT: { _eq: true }
}
) {
partnership_id
balance
hasNFT
lastCheckedAt
}
}- Access the GraphQL Playground at
http://localhost:4000/graphql - View database logs in the console
- Use
context.log()in handlers for custom logging - Enable
DEBUG_LP_POINTS=truefor verbose LP point tracing
- Monitor deployment health in the Envio dashboard
- Set up alerts for failures or performance issues
- Use IP whitelisting for additional security
- Fork the repository
- Create a feature branch
- Make your changes
- Ensure all tests pass and coverage is at 100%
- Submit a pull request
This project maintains high code quality standards:
- Pre-commit hooks: Enforce formatting, linting, and type checks
- CI/CD: Automated testing and deployment validation
- Test Coverage: 100% coverage requirement for all new code
- Type Safety: Strict TypeScript configuration
Indexer not starting:
- Check Node.js and pnpm versions
- Verify Docker is running (for local development)
- Ensure
.envfile is properly configured
Missing data after deployment:
- Verify the starting block number
- Check if contracts are correctly configured
- Review handler logic for data processing
Performance issues:
- Adjust
full_batch_sizein config.yaml - Optimize handler logic
- Consider using unordered multichain mode
- Join the Envio Discord for community support
- Check the Envio Documentation
- Review existing issues in the repository
See LICENSE for licensing information.