Backend API service that fetches and exposes restaking data from EigenLayer using Official EigenExplorer APIs
A Node.js backend API that aggregates and exposes EigenLayer restaking data, including details of users who restaked their stETH, validator metadata, and reward information. Built with MongoDB caching for improved performance and real-time data from official EigenExplorer APIs.
- Endpoint:
GET /api/restakers - Returns: List of users who restaked their stETH
- User address
- Amount restaked (in stETH)
- Target AVS validator/operator address
- Endpoint:
GET /api/validators - Returns: List of validators with comprehensive stats
- Operator address/ID
- Total delegated stake
- Slash history (when, how much, reason if available)
- Validator status (active, jailed, slashed, etc.)
- Endpoint:
GET /api/rewards/:address - Returns: Reward info for a specific wallet
- Total restaking rewards received
- Breakdown per validator
- Optional timestamps if available
- Node.js + Express - API server
- GraphQL + REST - two API interfaces
- MongoDB + Mongoose - Database for temporary caching
- EigenExplorer APIs - Official data source
- Axios - HTTP requests for API calls
- Winston - Structured logging
- Helmet + CORS - Security middleware
The API fetches data from Official EigenExplorer APIs:
- Stakers API:
https://api.eigenexplorer.com/stakers - Operators API:
https://api.eigenexplorer.com/operators - AVS Rewards API:
https://api.eigenexplorer.com/avs/{address}/rewards - Reward Events API:
https://api.eigenexplorer.com/avs/{address}/events/rewards
Smart Contract Integration:
- stETH Strategy:
0x93c4b944D05dfe6df7645A86cd2206016c51564D - EigenLayer contracts via official APIs
node --version # v16.0.0 or higher
npm --version # v8.0.0 or highergit clone https://github.com/Agrim-Sharma174/restaking-info-api
cd restaking-info-api
npm installCreate .env file:
PORT=3000
NODE_ENV=development
EIGENEXPLORER_API_TOKEN=<api-token-here>
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
MONGODB_URI=<connection-string here>setup a database in either mongodb atlas or compass.
# Optional: Fetch real data from EigenExplorer APIs and cache in MongoDB, this is just using the script to fetch initial data, you can directly call APIs to get real time data.
npm run fetch-data# Development with auto-reload
npm run dev
# Production
npm startServer will be running at:
- REST API: http://localhost:3000/api
- GraphQL: http://localhost:3000/graphql
- Health Check: http://localhost:3000/health
Returns paginated list of stETH restakers
curl "http://localhost:3000/api/restakers"Response:
{
"success": true,
"data": {
"restakers": [
{
"userAddress": "0x742d35cc...",
"amountRestaked": 32.5,
"stETHBalance": 32.5,
"targetValidators": [
{
"operatorAddress": "0x123abc...",
"stakedAmount": 32.5
}
],
"totalRewards": 1.625,
"lastActivity": "2024-01-15T10:30:00.000Z",
"mainOperator": "0x123abc...",
"stakingStatus": "active",
"dataSource": "live_api"
}
],
"pagination": {
"total": 250,
"limit": 10,
"offset": 0,
"hasMore": true
},
"dataSource": "live_api_with_cache"
}
}Returns list of validators with metadata
curl "http://localhost:3000/api/validators"Response:
{
"success": true,
"data": {
"validators": [
{
"operatorAddress": "0x456def...",
"operatorId": "validator_1",
"name": "Validator Name",
"totalDelegatedStake": 1250.75,
"delegatorCount": 45,
"avsCount": 3,
"slashHistory": [
{
"when": "2023-12-01T14:20:00.000Z",
"howMuch": { "amountETH": 2.5, "currency": "ETH" },
"reason": "downtime",
"penaltyType": "stake_slash"
}
],
"validatorStatus": "active",
"uptime": 0.98,
"attestationRate": 0.99
}
],
"summary": {
"totalStake": 6253.75,
"totalDelegators": 225,
"statusBreakdown": { "active": 8, "jailed": 1, "slashed": 1 }
}
}
}Returns reward breakdown for specific wallet
curl "http://localhost:3000/api/rewards/0x742d35cc..."Response:
{
"success": true,
"data": {
"userAddress": "0x742d35cc...",
"totalRewards": "1625000000000000000",
"totalRewardsETH": 1.625,
"rewardsByValidator": [
{
"operatorAddress": "0x456def...",
"validatorName": "Validator Name",
"totalRewardsETH": 1.625,
"rewardCount": 12,
"lastReward": "2024-01-15T10:30:00.000Z"
}
],
"estimatedAnnualRewards": 3.25,
"rewardHistory": [
{
"amount": 0.135,
"operatorAddress": "0x456def...",
"timestamp": "2024-01-15T10:30:00.000Z",
"rewardType": "restaking_reward",
"transactionHash": "0x789ghi...",
"blockNumber": 19123456
}
]
}
}GraphQL Playground: http://localhost:3000/graphql
Example Query:
query GetRestakingData {
restakers(limit: 5, sortBy: TOTAL_STAKE) {
userAddress
totalStakedETH
activeValidators {
operatorAddress
stakedAmountETH
}
}
validators(limit: 3, status: ACTIVE) {
operatorAddress
totalDelegatedStakeETH
slashingHistory {
when
reason
howMuch {
amountETH
}
}
}
}restaking-info-api/
├── scripts/
│ ├── fetchOnchainData.js # EigenExplorer API integration
│ └── setup-database.js # Database initialization
├── src/
│ ├── config/
│ │ └── database.js # MongoDB connection
│ ├── controllers/ # Request handlers
│ │ ├── restakerController.js
│ │ ├── validatorController.js
│ │ └── rewardController.js
│ ├── graphql/ # GraphQL interface
│ │ ├── typeDefs.js # Schema definitions
│ │ └── resolvers.js # Query resolvers
│ ├── middleware/
│ │ └── errorHandler.js # Error handling
│ ├── models/ # Data models
│ │ ├── Restaker.js # User restaking data
│ │ └── Validator.js # Validator metadata
│ ├── routes/ # API endpoints
│ │ ├── index.js
│ │ ├── restakers.js
│ │ ├── validators.js
│ │ └── rewards.js
│ ├── services/ # Business logic
│ │ ├── restakerService.js
│ │ ├── validatorService.js
│ │ └── rewardService.js
│ └── server.js # Express server
├── package.json
└── README.md
-
Live Data Fetching: APIs fetch real-time data from EigenLayer
- Primary: Each API call fetches live data from EigenExplorer APIs
- Fallback: MongoDB cache used when live APIs are unavailable
- Smart Caching: Live data is cached to MongoDB for performance
-
API Architecture: Express routes → Controllers → Services (Live API calls) → EigenLayer
- REST endpoints:
/api/restakers,/api/validators,/api/rewards/:address - GraphQL endpoint:
/graphql - All endpoints fetch live onchain data first, fallback to cache
- REST endpoints:
-
Data Sources:
- Live: EigenExplorer APIs (https://api.eigenexplorer.com)
- Cache: MongoDB (temporary caching for performance)
- Response includes:
dataSourcefield showing "live_api" or "cached_fallback"
-
Script Usage:
# First, setup the database with proper indexes and configuration npm run setup-db # Then fetch and cache initial data from EigenExplorer APIs npm run fetch-data
The scripts will:
setup-database.js: Create MongoDB collections, indexes, and initial configurationfetchOnchainData.js: Fetch live data from EigenExplorer APIs and cache in MongoDB:- Staker data from
/stakersendpoint - Validator data from
/operatorsendpoint - Reward data from
/avs/{address}/rewardsendpoint - Event data from
/avs/{address}/events/rewardsendpoint
- Staker data from
# Optional: Populate initial cache data, in case you want to load an initial data in database, otherwise to get real time data just go to next command.
npm run fetch-data
# Start development server (APIs will fetch live data)
npm run dev
# Test endpoints - These now fetch LIVE data from EigenLayer APIs
curl http://localhost:3000/api/restakers
curl http://localhost:3000/api/validators
curl http://localhost:3000/api/rewards/0x742d35cc6ef7c72e2f3a7f5cd8e9bc3c7a8e5f12
# Health check
curl http://localhost:3000/health
# GraphQL with live data
curl -X POST http://localhost:3000/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ restakers(limit: 5) { restakers { userAddress amountRestaked dataSource } dataSource } }"}'- Set
NODE_ENV=production - Configure production MongoDB URI
- Set up EigenExplorer API token (
EIGENEXPLORER_API_TOKEN) - Configure rate limiting and CORS for your domain
- Set up process manager (PM2) or containerization
Node.js backend - Express server with professional architecture
GraphQL + REST APIs - Dual interface support
MongoDB integration - Mongoose ODM with temporary caching (as specified)
EigenLayer data fetching - Official EigenExplorer API integration
3 Core endpoints - Exactly as specified in requirements
Clean code structure - Modular, maintainable, professional
Error handling - Comprehensive validation and error responses
Security - Helmet, CORS, rate limiting
Logging - Winston structured logging
- Real-time data from official APIs
- Accurate stETH strategy filtering
- Complete operator metadata (names, descriptions, social links)
- TVL calculations with strategy breakdowns
- AVS registrations and reward tracking
- Proper pagination and rate limiting
- Error handling for API failures
- MongoDB caching for improved performance
This implementation demonstrates:
- Backend Development: Node.js, Express, MongoDB
- Blockchain Integration: EigenExplorer APIs, smart contract data
- API Design: REST + GraphQL, proper validation, pagination
- Code Quality: Clean architecture, error handling, documentation
- Real Data Integration: Official APIs, accurate information
- Performance Optimization: Database caching, rate limiting