A serverless solution for monitoring RPC nodes response time across different blockchains and regions using Vercel Functions and Grafana Cloud. The project collects metrics from HTTP/WS endpoints for multiple blockchains and pushes them to Grafana Cloud.
📊 Live Dashboard | 📚 Documentation
- Features
- System Overview
- Quick Start
- Detailed Setup
- Configuration
- Development Guide
- Technical Reference
- Contributing
- ⛓️ Supported blockchains: Ethereum, Arbitrum, Base, BNB Smart Chain, Solana, TON
- 🌐 Multi-region deployment (US, EU, Asia)
- ⚡ Real-time metrics collection
flowchart TB
    subgraph Vercel["Vercel Platform"]
        subgraph Functions["Serverless Functions"]
            subgraph Global["Global Functions"]
                Collectors["Measure Response Times
                            [1 min]"]
            end
            subgraph Services["EU Only Functions"]
                STATE["Update Recent Data
                      [30 min]"]
                TX["Measure Tx Landing
                    [15 min]"]
            end
        end
        BLOB[("Blob Storage")]
    end
    subgraph RPC["RPC Nodes"]
        API["JSON-RPC API"]
    end
    subgraph Grafana["Grafana Cloud"]
        METRICS["Default Prometheus Instance"]
    end
    %% Data Flows
    BLOB --> Collectors
    Collectors <--> API
    Collectors --> METRICS
    API <--> STATE
    STATE --> BLOB
    TX <--> API
    TX --> METRICS
    %% Basic Styling
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:2px,color:#000
    classDef vercel fill:#f0f0f0,stroke:#333,color:#000
    classDef grafana fill:#d4eaf7,stroke:#333,color:#000
    classDef rpc fill:#eafaf1,stroke:#333,color:#000
    
    class BLOB,Collectors,STATE,TX vercel
    class METRICS grafana
    class API rpc
    - Grafana Cloud account
- Vercel account
- GitHub account
- RPC node endpoints
Configure required environment variables:
GRAFANA_URL=Grafana Cloud URL for pushing metrics
GRAFANA_USER=Grafana Cloud user ID
GRAFANA_API_KEY=Grafana Cloud API key
CRON_SECRET=Generate secret to protect API, it's used by CRON jobs
SKIP_AUTH=Set False for non-production deployments
SOLANA_PRIVATE_KEY=Set it if you'd like to measure transaction landing
ENDPOINTS=Read below
STORE_ID=Vercel Blob Storage ID
VERCEL_BLOB_TOKEN=Vercel Blob Storage token for reading/writing data to the storageUpdate the ENDPOINTS environment variable with your RPC configuration:
{
    "providers": [
        {
            "blockchain": "Ethereum",
            "name": "Provider-Name",
            "region": "Global",
            "websocket_endpoint": "wss://...",
            "http_endpoint": "https://...",
            "data": {}
        }
    ]
}You can leave data empty. If a provider has a separate endpoint for sending transactions, use tx_endpoint field for that in addition to http_endpoint.
- 
Create three Vercel projects: - your-project-sin1(Singapore)
- your-project-fra1(EU)
- your-project-sfo1(US West)
 
- 
Configure each project: # Project Settings → Functions Function Regions: [Select corresponding region]
- 
Link environment variables: # Team Settings → Environment Variables Link to all three projectsIt is recommended to have separate environment variables for production and preview for at least ENDPOINTS,SOLANA_PRIVATE_KEYandSKIP_AUTH. You can create two environment variables with the same name, but linked to different environments.
- Create a Vercel Blob store
- Configure storage variables:
VERCEL_BLOB_TOKEN=your_blob_token STORE_ID=your_store_id 
- Generate a strong CRON_SECRET
- Configure authentication:
SKIP_AUTH=FALSE # Production SKIP_AUTH=TRUE # Development 
# Grafana Settings
GRAFANA_URL=https://influx-...grafana.net/api/v1/push/influx/write
GRAFANA_USER=your_user_id
GRAFANA_API_KEY=your_api_key
# Security
CRON_SECRET=your_secret
SKIP_AUTH=FALSE
# Storage
VERCEL_BLOB_TOKEN=your_blob_token
STORE_ID=your_store_id# Development
VERCEL_ENV=development  # Adds 'dev_' prefix to metrics
SOLANA_PRIVATE_KEY=...  # For Solana write metricsFull configuration options in endpoints.json:
{
    "providers": [
        {
            "blockchain": "Ethereum",
            "name": "Provider1",
            "region": "Global",
            "websocket_endpoint": "wss://...",
            "http_endpoint": "https://...",
            "tx_endpoint": "",
            "data": {}
        }
    ]
}You can leave data empty. If a provider has a separate endpoint for sending transactions, use tx_endpoint field for that in addition to http_endpoint.
- 
Clone and setup environment: git clone https://github.com/chainstacklabs/chainstack-rpc-dashboard-functions.git cd chainstack-rpc-dashboard-functions python -m venv venv source venv/bin/activate # or venv\Scripts\activate on Windows 
- 
Install dependencies: pip install -r requirements.txt 
- 
Configure local environment: cp .env.local.example .env.local cp endpoints.json.example endpoints.json # Update with your values
- 
Run development server: python tests/test_api_read.py # For read metrics python tests/test_api_write.py # For write metrics python tests/test_update_state.py # For state updates 
- 
Create metric class: from common.metric_types import HttpCallLatencyMetricBase class YourMetric(HttpCallLatencyMetricBase): @property def method(self) -> str: return "your_rpc_method" @staticmethod def get_params_from_state(state_data: dict) -> dict: return {"your": "params"} 
- 
Register in appropriate handler: METRICS = [ (YourMetric, metric_name), # ... other metrics ] 
├── api/                      # Vercel Functions
│   ├── read/                 # Read metrics
│   ├── write/                # Write metrics
│   └── support/             # Support functions
├── common/                   # Shared utilities
│   ├── base_metric.py       # Base framework
│   ├── factory.py           # Metrics creation
│   ├── metric_*.py          # Configuration
│   └── state/              # State management
├── metrics/                 # Implementations
└── config/                  # Configuration
- HTTP Metrics: RPC endpoint response times
- WebSocket Metrics: real-time block monitoring
- Transaction Metrics: tx processing times
- Fork the repository
- Create feature branch:
git checkout -b feature/YourFeature 
- Make changes
- Run local servers
- Submit PR
- Follow PEP 8
- Use type hints
- Add docstrings
- Include tests