{"id":29015469,"url":"https://github.com/chainstacklabs/compare-dashboard-functions","last_synced_at":"2025-07-18T06:35:53.801Z","repository":{"id":274182521,"uuid":"906386413","full_name":"chainstacklabs/compare-dashboard-functions","owner":"chainstacklabs","description":"Serverless solution for monitoring RPC nodes response time across different blockchains and regions using Vercel Functions","archived":false,"fork":false,"pushed_at":"2025-06-18T08:10:38.000Z","size":234,"stargazers_count":13,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-25T21:07:31.902Z","etag":null,"topics":["blockchain","web3"],"latest_commit_sha":null,"homepage":"https://compare.chainstack.com/dashboard","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chainstacklabs.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-20T19:36:29.000Z","updated_at":"2025-06-18T08:10:41.000Z","dependencies_parsed_at":"2025-04-07T08:22:02.111Z","dependency_job_id":"1e78d6fe-3cc8-44a8-8c78-5d921aa8bcaa","html_url":"https://github.com/chainstacklabs/compare-dashboard-functions","commit_stats":null,"previous_names":["chainstacklabs/chainstack-rpc-dashboard-functions","chainstacklabs/compare-dashboard-functions"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/chainstacklabs/compare-dashboard-functions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainstacklabs%2Fcompare-dashboard-functions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainstacklabs%2Fcompare-dashboard-functions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainstacklabs%2Fcompare-dashboard-functions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainstacklabs%2Fcompare-dashboard-functions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chainstacklabs","download_url":"https://codeload.github.com/chainstacklabs/compare-dashboard-functions/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainstacklabs%2Fcompare-dashboard-functions/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265711091,"owners_count":23815471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","web3"],"created_at":"2025-06-25T21:07:29.882Z","updated_at":"2025-07-18T06:35:53.773Z","avatar_url":"https://github.com/chainstacklabs.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chainstack Compare Dashboard\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fchainstacklabs%2Fchainstack-rpc-dashboard-functions\u0026env=GRAFANA_URL,GRAFANA_USER,GRAFANA_API_KEY,CRON_SECRET,SKIP_AUTH,SOLANA_PRIVATE_KEY,ENDPOINTS,STORE_ID,VERCEL_BLOB_TOKEN)\n\nA 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.\n\n📊 [Live Dashboard](https://chainstack.grafana.net/public-dashboards/65c0fcb02f994faf845d4ec095771bd0?orgId=1) | 📚 [Documentation](https://docs.chainstack.com/docs/chainstack-compare-dashboard)\n\n## Table of Contents\n- [Features](#features)\n- [System Overview](#solution-overview)\n- [Quick Start](#quick-start)\n- [Detailed Setup](#detailed-setup)\n- [Configuration](#configuration)\n- [Development Guide](#development-guide)\n- [Technical Reference](#technical-reference)\n- [Contributing](#contributing)\n\n## Features\n\n- :chains: Supported blockchains: Ethereum, Arbitrum, Base, BNB Smart Chain, Solana, TON\n- :globe_with_meridians: Multi-region deployment (US, EU, Asia)\n- :zap: Real-time metrics collection\n\n## Solution Overview\n\n```mermaid\nflowchart TB\n    subgraph Vercel[\"Vercel Platform\"]\n        subgraph Functions[\"Serverless Functions\"]\n            subgraph Global[\"Global Functions\"]\n                Collectors[\"Measure Response Times\n                            [1 min]\"]\n            end\n            subgraph Services[\"EU Only Functions\"]\n                STATE[\"Update Recent Data\n                      [30 min]\"]\n                TX[\"Measure Tx Landing\n                    [15 min]\"]\n            end\n        end\n        BLOB[(\"Blob Storage\")]\n    end\n    subgraph RPC[\"RPC Nodes\"]\n        API[\"JSON-RPC API\"]\n    end\n    subgraph Grafana[\"Grafana Cloud\"]\n        METRICS[\"Default Prometheus Instance\"]\n    end\n    %% Data Flows\n    BLOB --\u003e Collectors\n    Collectors \u003c--\u003e API\n    Collectors --\u003e METRICS\n    API \u003c--\u003e STATE\n    STATE --\u003e BLOB\n    TX \u003c--\u003e API\n    TX --\u003e METRICS\n    %% Basic Styling\n    classDef default fill:#f9f9f9,stroke:#333,stroke-width:2px,color:#000\n    classDef vercel fill:#f0f0f0,stroke:#333,color:#000\n    classDef grafana fill:#d4eaf7,stroke:#333,color:#000\n    classDef rpc fill:#eafaf1,stroke:#333,color:#000\n    \n    class BLOB,Collectors,STATE,TX vercel\n    class METRICS grafana\n    class API rpc\n```\n\n## Quick Start\n\n### 1. Prerequisites\n- Grafana Cloud account\n- Vercel account\n- GitHub account\n- RPC node endpoints\n\n### 2. One-Click Deploy\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fchainstacklabs%2Fchainstack-rpc-dashboard-functions\u0026env=GRAFANA_URL,GRAFANA_USER,GRAFANA_API_KEY,CRON_SECRET,SKIP_AUTH,SOLANA_PRIVATE_KEY,ENDPOINTS,STORE_ID,VERCEL_BLOB_TOKEN)\n\nConfigure required environment variables:\n   ```env\n   GRAFANA_URL=Grafana Cloud URL for pushing metrics\n   GRAFANA_USER=Grafana Cloud user ID\n   GRAFANA_API_KEY=Grafana Cloud API key\n\n   CRON_SECRET=Generate secret to protect API, it's used by CRON jobs\n   SKIP_AUTH=Set False for non-production deployments\n\n   SOLANA_PRIVATE_KEY=Set it if you'd like to measure transaction landing\n   ENDPOINTS=Read below\n\n   STORE_ID=Vercel Blob Storage ID\n   VERCEL_BLOB_TOKEN=Vercel Blob Storage token for reading/writing data to the storage\n   ```\n\nUpdate the `ENDPOINTS` environment variable with your RPC configuration:\n```json\n{\n    \"providers\": [\n        {\n            \"blockchain\": \"Ethereum\",\n            \"name\": \"Provider-Name\",\n            \"region\": \"Global\",\n            \"websocket_endpoint\": \"wss://...\",\n            \"http_endpoint\": \"https://...\",\n            \"data\": {}\n        }\n    ]\n}\n```\nYou 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`.\n\n## Detailed Setup\n\n### Multi-Region Deployment\n1. Create three Vercel projects:\n   - `your-project-sin1` (Singapore)\n   - `your-project-fra1` (EU)\n   - `your-project-sfo1` (US West)\n\n2. Configure each project:\n   ```bash\n   # Project Settings → Functions\n   Function Regions: [Select corresponding region]\n   ```\n\n3. Link environment variables:\n   ```bash\n   # Team Settings → Environment Variables\n   Link to all three projects\n   ```\n\n   It is recommended to have separate environment variables for production and preview for at least `ENDPOINTS`, `SOLANA_PRIVATE_KEY` and `SKIP_AUTH`. You can create two environment variables with the same name, but linked to different environments.\n\n### Blob Storage Setup\n1. Create a Vercel Blob store\n2. Configure storage variables:\n   ```env\n   VERCEL_BLOB_TOKEN=your_blob_token\n   STORE_ID=your_store_id\n   ```\n\n### Security Configuration\n1. Generate a strong CRON_SECRET\n2. Configure authentication:\n   ```env\n   SKIP_AUTH=FALSE  # Production\n   SKIP_AUTH=TRUE   # Development\n   ```\n\n## Configuration\n\n### Environment Variables\n\n#### Required Variables\n```env\n# Grafana Settings\nGRAFANA_URL=https://influx-...grafana.net/api/v1/push/influx/write\nGRAFANA_USER=your_user_id\nGRAFANA_API_KEY=your_api_key\n\n# Security\nCRON_SECRET=your_secret\nSKIP_AUTH=FALSE\n\n# Storage\nVERCEL_BLOB_TOKEN=your_blob_token\nSTORE_ID=your_store_id\n```\n\n#### Optional Variables\n```env\n# Development\nVERCEL_ENV=development  # Adds 'dev_' prefix to metrics\nSOLANA_PRIVATE_KEY=...  # For Solana write metrics\n```\n\n### RPC Provider Configuration\nFull configuration options in `endpoints.json`:\n```json\n{\n    \"providers\": [\n        {\n            \"blockchain\": \"Ethereum\",\n            \"name\": \"Provider1\",\n            \"region\": \"Global\",\n            \"websocket_endpoint\": \"wss://...\",\n            \"http_endpoint\": \"https://...\",\n            \"tx_endpoint\": \"\",\n            \"data\": {}\n        }\n    ]\n}\n```\nYou 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`.\n\n## Development Guide\n\n### Local Setup\n1. Clone and setup environment:\n   ```bash\n   git clone https://github.com/chainstacklabs/chainstack-rpc-dashboard-functions.git\n   cd chainstack-rpc-dashboard-functions\n   python -m venv venv\n   source venv/bin/activate  # or venv\\Scripts\\activate on Windows\n   ```\n\n2. Install dependencies:\n   ```bash\n   pip install -r requirements.txt\n   ```\n\n3. Configure local environment:\n   ```bash\n   cp .env.local.example .env.local\n   cp endpoints.json.example endpoints.json\n   # Update with your values\n   ```\n\n4. Run development server:\n   ```bash\n   python tests/test_api_read.py  # For read metrics\n   python tests/test_api_write.py  # For write metrics\n   python tests/test_update_state.py  # For state updates\n   ```\n\n### Adding New Metrics\n1. Create metric class:\n   ```python\n   from common.metric_types import HttpCallLatencyMetricBase\n\n   class YourMetric(HttpCallLatencyMetricBase):\n       @property\n       def method(self) -\u003e str:\n           return \"your_rpc_method\"\n\n       @staticmethod\n       def get_params_from_state(state_data: dict) -\u003e dict:\n           return {\"your\": \"params\"}\n   ```\n\n2. Register in appropriate handler:\n   ```python\n   METRICS = [\n       (YourMetric, metric_name),\n       # ... other metrics\n   ]\n   ```\n\n## Technical Reference\n\n### Project Structure\n```plaintext\n├── api/                      # Vercel Functions\n│   ├── read/                 # Read metrics\n│   ├── write/                # Write metrics\n│   └── support/             # Support functions\n├── common/                   # Shared utilities\n│   ├── base_metric.py       # Base framework\n│   ├── factory.py           # Metrics creation\n│   ├── metric_*.py          # Configuration\n│   └── state/              # State management\n├── metrics/                 # Implementations\n└── config/                  # Configuration\n```\n\n### Metric Types\n- **HTTP Metrics**: RPC endpoint response times\n- **WebSocket Metrics**: real-time block monitoring\n- **Transaction Metrics**: tx processing times\n\n## Contributing\n\n### Getting Started\n1. Fork the repository\n2. Create feature branch:\n   ```bash\n   git checkout -b feature/YourFeature\n   ```\n3. Make changes\n4. Run local servers\n5. Submit PR\n\n### Code Style\n- Follow PEP 8\n- Use type hints\n- Add docstrings\n- Include tests\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainstacklabs%2Fcompare-dashboard-functions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchainstacklabs%2Fcompare-dashboard-functions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainstacklabs%2Fcompare-dashboard-functions/lists"}