A JSON-RPC server that returns token unit prices in USD for snapshot strategies at specified block timestamps across multiple blockchain networks.
Overlord is an Express-based JSON-RPC server application that fetches token unit prices in USD for snapshot strategies at specific block timestamps. The service retrieves historical token prices from CoinGecko across 200+ blockchain networks with robust input validation and caching.
- Token Unit Pricing: Fetches USD price per token unit at specific timestamps
- Multi-Network Support: Compatible with 200+ blockchain networks via CoinGecko platform mappings
- JSON-RPC API: Express-based server with standardized JSON-RPC 2.0 interface
- TypeScript: Full TypeScript support with comprehensive type definitions
- Input Validation: Robust input validation using Zod schemas
- Caching: Built-in in-memory caching for improved performance
- Testing: Comprehensive test suite with snapshot testing
Clone the repository and install dependencies:
git clone https://github.com/snapshot-labs/overlord.git
cd overlord
bun installCreate a .env file in your project root:
COINGECKO_API_KEY=your_coingecko_pro_api_keyStart the server:
# Development mode with watch
bun run dev
# Production mode
bun start
# Build and run
bun run build
bun run startThe server will be available at http://localhost:3000 (or your
configured PORT).
Send POST requests to / with the following format:
{
"method": "get_value_by_strategy",
"params": {
"network": 1,
"snapshot": 1640998800,
"strategies": [
{
"name": "erc20-balance-of",
"network": "1",
"params": {
"address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
"decimals": 18
}
}
]
},
"id": 1
}Response:
{
"jsonrpc": "2.0",
"result": [1234.56],
"id": 1
}The result array contains the USD unit prices corresponding to each token
in the snapshot strategies. The array is the same size and order as the
input params.strategies array, and returns 0 for unsupported strategies.
For strategies with inner strategies, it returns the lowest value among the
inner strategies.
curl -X POST http://localhost:3000 \
-H "Content-Type: application/json" \
-d '{
"method": "get_value_by_strategy",
"params": {
"network": 1,
"snapshot": 1640998800,
"strategies": [
{
"name": "erc20-balance-of",
"network": "1",
"params": {
"address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
"decimals": 18
}
}
]
},
"id": 1
}'| Strategy Name | Description |
|---|---|
erc20-balance-of |
Standard ERC20 token balance |
erc20-balance-of-delegation |
ERC20 balance with delegation support |
erc20-balance-of-with-delegation |
ERC20 balance with delegation |
erc20-votes |
ERC20 votes implementation |
erc20-votes-with-override |
ERC20 votes with override capability |
comp-like-votes |
Compound-like voting mechanism |
uni |
Uniswap-specific strategy |
multichain |
Multi-chain aggregation strategy |
delegation |
Delegation strategy |
with-delegation |
Generic delegation support |
The server supports 200+ blockchain networks including:
- Ethereum (1) -
ethereum - Polygon (137) -
polygon-pos - BSC (56) -
binance-smart-chain - Arbitrum One (42161) -
arbitrum-one - Optimism (10) -
optimistic-ethereum - Avalanche (43114) -
avalanche - Base (8453) -
base - And many more...
See the full list in src/helpers/coingecko.ts:PLATFORM_IDS.
The server follows a modular architecture:
- Express Server (
src/index.ts): Main entry point with CORS, JSON middleware, and route setup - JSON-RPC Router (
src/rpc.ts): Handlesget_value_by_strategymethod with async error handling - Middleware System:
- Validation (
src/middleware/validation.ts): Zod-based input validation and sanitization - Error Handler (
src/middleware/errorHandler.ts): Centralized error handling for consistent JSON-RPC responses
- Validation (
- Strategy System (
src/strategies/): Pluggable pricing strategies with unified interface - CoinGecko Integration (
src/helpers/coingecko.ts): API client with platform ID mappings for 200+ networks - Token Helpers (
src/helpers/token.ts): ERC20 token utilities for decimal conversion - Cache System (
src/helpers/cache.ts): In-memory caching for API responses
Strategies implement the signature: (params: any, network: number, snapshot: number) => Promise<number>
- Core Strategy:
erc20-balance-of- Fetches token prices and handles decimal conversion - Composite Strategies:
multichain,uni- Handle complex scenarios with multiple tokens/networks - Strategy Aliases: Multiple strategy names map to the same implementation
- Bun (recommended) or Node.js 22+
- CoinGecko Pro API key
# Install dependencies
bun install
# Build the project
bun run build
# Run tests
bun test
# Start development server with watch mode
bun run dev
# Lint code
bun run lint
# Auto-fix lint issues
bun run lint:fix
# Type checking
bun run typecheckThe project uses Bun's built-in test runner with snapshot testing:
# Run all tests
bun test
# Run specific test
bun test test/strategies.test.ts
# Update snapshots
bun test --update-snapshotsFetch USD unit prices for tokens specified in snapshot strategies at a given block timestamp.
Parameters:
network(number): Blockchain network IDsnapshot(number): Unix timestamp in seconds for the snapshot blockstrategies(array): Array of strategy configurations
Strategy Configuration:
name(string): Strategy name from supported strategies (e.g.,erc20-balance-of)network(string): Network ID as string (e.g.,"1")params(object): Strategy-specific parametersaddress(string): EVM token contract address (e.g.,0x1f9840a85d5af5bf1d1762f925bdaddc4201f984)decimals(number): Token decimals (e.g.,18)
Returns: Array of numbers representing USD unit prices for each token
The server uses centralized error handling middleware that automatically catches and formats errors into standardized JSON-RPC 2.0 responses. All errors are processed through a single error handler that distinguishes between validation errors (400) and internal server errors (500).
For validation errors, the data field contains an array of specific field errors:
{
"jsonrpc": "2.0",
"error": {
"code": 400,
"message": "Bad Request",
"data": [
{
"path": [
"params",
"strategies",
0,
"network"
],
"code": "invalid_format",
"message": "Network must be a valid positive integer string"
},
{
"path": [
"params",
"strategies",
1,
"params",
"address"
],
"code": "invalid_format",
"message": "Address must be a valid EVM address"
}
]
},
"id": 2
}For other errors, the data field may contain a simple error message:
{
"jsonrpc": "2.0",
"error": {
"code": 500,
"message": "Internal Server Error",
"data": "Failed to fetch token price"
},
"id": 1
}Common error codes:
400: Bad Request (missing or invalid parameters)500: Internal Server Error
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes
- Run tests:
bun test - Run linting:
bun run lint:fix - Commit changes:
git commit -am 'Add my feature' - Push to branch:
git push origin feature/my-feature - Create a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ by Snapshot Labs