██████╗ ██████╗ ██████╗███████╗ ██████╗ ██████╗ ██████╗ ███████╗
██╔══██╗██╔══██╗██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
██████╔╝██████╔╝██║ █████╗ ██║ ██║██████╔╝██║ ███╗█████╗
██╔══██╗██╔═══╝ ██║ ██╔══╝ ██║ ██║██╔══██╗██║ ██║██╔══╝
██║ ██║██║ ╚██████╗██║ ╚██████╔╝██║ ██║╚██████╔╝███████╗
╚═╝ ╚═╝╚═╝ ╚═════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
The Problem:
- Infura/Alchemy charge per request and lock you into their platform
- No visibility into your RPC traffic
- Rate limits kill your dApp during peak usage
- Compliance issues with data residency
The Solution: RPCForge gives you enterprise-grade RPC infrastructure you can self-host in 5 minutes. Full control, zero vendor lock-in, unlimited requests.
✅ dApp developers tired of paying per API call
✅ Projects requiring data sovereignty/compliance
✅ Teams building on multiple chains
✅ Anyone wanting full visibility into blockchain requests
✅ Developers who need unlimited rate limits
Live Instance: rpc-forge.vercel.app
Dashboard: rpc-forge.vercel.app/dashboard
Test Endpoint:
curl -X POST https://rpcforge-production.up.railway.app/eth \
-H "x-api-key: demo_key_12345" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'If RPCForge saves you money or helps your project, give us a star! It helps others discover this tool.
RPCForge is a self-hostable, production-ready RPC gateway that sits in front of your Ethereum nodes. It gives you a single, reliable endpoint with API key auth, per-tier rate limiting, method blacklisting, response caching, multi-node failover, and a real-time WebSocket dashboard — all in one.
Built for developers who want Infura/Alchemy-level features without the vendor lock-in.
| Feature | Description |
|---|---|
| Multi-chain Support | Ethereum, Polygon, BSC, Arbitrum, Sepolia out of the box |
| Multi-node Failover | Shuffles across your configured nodes, retries on failure |
| Per-key Rate Limiting | Free tier: 20 req/min · Pro tier: 100 req/min |
| Response Caching | 10s TTL cache for eth_blockNumber, eth_chainId, eth_gasPrice |
| Method Blacklist | Blocks eth_sendRawTransaction, eth_sign, personal_sign by default |
| Real-time Dashboard | WebSocket-powered live feed, charts, and stats |
| API Key Manager | Create, revoke, and upgrade keys via UI or CLI |
| Auth via Supabase | Email/password + Google OAuth, per-user API key provisioning |
| CLI Tool | Full-featured terminal interface for power users |
| Docker Ready | One command to spin up the full stack |
┌─────────────────────────────────────────────────────────────┐
│ Client / dApp │
└──────────────────────────┬──────────────────────────────────┘
│ POST /{chain}
│ x-api-key: <your_key>
▼
┌─────────────────────────────────────────────────────────────┐
│ RPCForge Server │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
│ │ API Key │ │ Rate │ │ Method │ │ Cache │ │
│ │ Auth │→ │ Limiter │→ │Blacklist │→ │ (10s TTL)│ │
│ └──────────┘ └──────────┘ └──────────┘ └─────┬─────┘ │
│ │ │
│ ┌────────────────────────────────────────────────▼──────┐ │
│ │ Multi-node Failover Router │ │
│ │ Node 1 ──┐ │ │
│ │ Node 2 ──┼──► Shuffle & Retry on failure │ │
│ │ Node N ──┘ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ WebSocket Broadcast (live logs) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
Ethereum Polygon BSC
Mainnet Mainnet Mainnet
Sepolia ... Arbitrum
mini-rpc-provider/
├── server.js # Express + WebSocket backend
├── Dockerfile # Production Docker image
├── docker-compose.yml # Full stack (backend + frontend)
├── .env # Node URLs, API keys, secrets
├── package.json
│
├── frontend/ # React + Vite + Tailwind dashboard
│ └── src/
│ ├── App.jsx # Router (/, /signup, /dashboard)
│ ├── LandingPage.jsx
│ ├── SignupPage.jsx # Supabase auth (email + Google)
│ ├── Dashboard.jsx # Live stats, logs, key manager
│ └── supabase.js
│
└── cli/ # Node.js CLI tool
├── index.js # Commands: init, test, keys, stats
└── bin/rpcforge.js
git clone https://github.com/your-username/mini-rpc-provider.git
cd mini-rpc-provider
npm installPORT=3000
ADMIN_SECRET=your_admin_secret
# Add your node URLs (Infura, Alchemy, or public nodes)
ETH_NODE_1=https://mainnet.infura.io/v3/<YOUR_KEY>
ETH_NODE_2=https://eth-mainnet.g.alchemy.com/v2/<YOUR_KEY>
SEPOLIA_NODE_1=https://eth-sepolia.g.alchemy.com/v2/<YOUR_KEY>
POLYGON_NODE_1=https://polygon-rpc.com
POLYGON_NODE_2=https://rpc-mainnet.matic.quiknode.pro
BSC_NODE_1=https://bsc-dataseed.binance.org
BSC_NODE_2=https://bsc-dataseed1.defibit.io
ARBITRUM_NODE_1=https://arb1.arbitrum.io/rpc
ARBITRUM_NODE_2=https://arbitrum-one.publicnode.com
# Format: key:tier,key:tier
API_KEYS=mykey123:free,prokey456:pronode server.js
# RPCForge 🚀 running on port 3000cd frontend
npm install
npm run dev
# http://localhost:5173docker-compose up --build- Fork this repository
- Click:
- Set environment variables:
VITE_SUPABASE_URLVITE_SUPABASE_ANON_KEYVITE_API_BASE_URL(your Railway backend URL)
# Pull from Docker Hub
docker pull yourusername/rpcforge:latest
# Run with environment file
docker run -p 3000:3000 --env-file .env yourusername/rpcforge:latest
# Or use docker-compose
docker-compose up -dimport { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider(
"https://rpcforge-production.up.railway.app/eth",
undefined,
{
fetchOptions: {
headers: { "x-api-key": "YOUR_API_KEY" }
}
}
);
// Use it like any provider
const blockNumber = await provider.getBlockNumber();
const balance = await provider.getBalance("0x...");import { createPublicClient, http } from 'viem';
import { mainnet } from 'viem/chains';
const client = createPublicClient({
chain: mainnet,
transport: http("https://rpcforge-production.up.railway.app/eth", {
fetchOptions: {
headers: { "x-api-key": "YOUR_API_KEY" }
}
})
});
const blockNumber = await client.getBlockNumber();import { createConfig, http } from 'wagmi';
import { mainnet, polygon, arbitrum } from 'wagmi/chains';
export const config = createConfig({
chains: [mainnet, polygon, arbitrum],
transports: {
[mainnet.id]: http("https://rpcforge-production.up.railway.app/eth", {
fetchOptions: { headers: { "x-api-key": "YOUR_KEY" }}
}),
[polygon.id]: http("https://rpcforge-production.up.railway.app/polygon", {
fetchOptions: { headers: { "x-api-key": "YOUR_KEY" }}
}),
[arbitrum.id]: http("https://rpcforge-production.up.railway.app/arbitrum", {
fetchOptions: { headers: { "x-api-key": "YOUR_KEY" }}
}),
},
});// hardhat.config.js
require("@nomiclabs/hardhat-ethers");
module.exports = {
networks: {
mainnet: {
url: "https://rpcforge-production.up.railway.app/eth",
headers: { "x-api-key": process.env.RPCFORGE_API_KEY },
accounts: [process.env.PRIVATE_KEY]
},
polygon: {
url: "https://rpcforge-production.up.railway.app/polygon",
headers: { "x-api-key": process.env.RPCFORGE_API_KEY },
accounts: [process.env.PRIVATE_KEY]
}
}
};We love contributions! Check out our CONTRIBUTING.md for guidelines.
- Fork the repo
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
Good First Issues: Check issues tagged with good-first-issue
Found a bug? Want a feature? Open an issue
- Discord: Join our server (coming soon)
- GitHub Discussions: Ask questions
- Twitter: @RPCForge (coming soon)
- WebSocket support for
eth_subscribe - Prometheus metrics export
- GraphQL query layer
- Load balancing across regions
- Custom caching rules per method
- Webhook alerts for downtime
- Multi-tenant isolation
Vote on features in GitHub Discussions!
(Add benchmarks showing RPCForge vs Infura/Alchemy in terms of latency, uptime, cost)
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ for the Ethereum community
Special thanks to:
If RPCForge helps you save money on RPC costs:
- ⭐ Star this repo
- 🐦 Tweet about it
- 💬 Share in your Discord/Telegram
- ☕ Buy me a coffee (optional)
Every star helps more developers discover this tool!
Made with ⚡ by Mayur
All RPC requests go to POST /{chain} with your API key in the header.
| Chain | Endpoint |
|---|---|
| Ethereum Mainnet | POST /eth |
| Ethereum Sepolia | POST /sepolia |
| Polygon | POST /polygon |
| BSC | POST /bsc |
| Arbitrum | POST /arbitrum |
curl -X POST https://rpcforge-production.up.railway.app/eth \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'const provider = new ethers.JsonRpcProvider(
"https://rpcforge-production.up.railway.app/eth",
undefined,
{ headers: { "x-api-key": "YOUR_API_KEY" } }
);const transport = http("https://rpcforge-production.up.railway.app/eth", {
fetchOptions: { headers: { "x-api-key": "YOUR_API_KEY" } }
});// hardhat.config.js
networks: {
mainnet: {
url: "https://rpcforge-production.up.railway.app/eth",
headers: { "x-api-key": "YOUR_API_KEY" }
}
}All admin routes require the x-admin-secret header.
| Method | Route | Description |
|---|---|---|
GET |
/stats |
Total requests, errors, top methods |
GET |
/logs |
Last 500 request logs |
GET |
/keys |
List all API keys |
POST |
/keys |
Create a key { tier: "free" | "pro" } |
DELETE |
/keys/:key |
Revoke a key |
PATCH |
/keys/:key |
Upgrade/downgrade tier { tier: "pro" } |
GET |
/chains |
List supported chains and node counts |
The easiest way to use RPCForge is via the official CLI — no cloning required.
npm install -g rpcforge-clirpcforge initThat's it. The CLI will walk you through picking a chain, generating or validating your API key, and print ready-to-use code snippets for ethers.js, curl, and Hardhat.
| Command | Description |
|---|---|
rpcforge init |
Setup your endpoint & get usage examples |
rpcforge test |
Send a live eth_blockNumber test request |
rpcforge keys |
List all API keys |
rpcforge keys create |
Create a new API key (free or pro) |
rpcforge keys revoke |
Revoke an API key |
rpcforge stats |
Show total requests, errors, top methods |
After installing, if you see 'rpcforge' is not recognized, npm's global bin folder isn't in your PATH. Fix it by running this in cmd as Administrator:
setx PATH "%PATH%;%APPDATA%\npm" /MThen close and reopen your terminal. Alternatively, use npx without any install:
npx rpcforge-cli initSo you're not prompted every time you run keys or stats:
# macOS / Linux — add to ~/.bashrc or ~/.zshrc
export RPCFORGE_ADMIN_SECRET=your_secret_here
# Windows cmd
setx RPCFORGE_ADMIN_SECRET your_secret_here| Tier | Requests / min |
|---|---|
| Free | 20 |
| Pro | 100 |
Exceeding the limit returns:
{ "error": "Rate limit exceeded. Too many requests." }The following methods are blocked by default to prevent abuse:
eth_sendRawTransactioneth_signpersonal_sign
- Push to GitHub
- Create a new Railway project → Deploy from GitHub
- Add all
.envvariables in Railway's environment settings - Railway auto-detects the
Dockerfileand deploys
cd frontend
vercel --prodSet VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY in Vercel's environment variables.
Backend
- Node.js + Express 5
- WebSocket (
ws) express-rate-limitfor per-key throttlingaxiosfor upstream node forwardinguuidfor log IDs
Frontend
- React 18 + Vite
- Tailwind CSS
- Chart.js + react-chartjs-2
- Supabase (auth + user DB)
- React Router v7
CLI
chalk,inquirer,ora,axios
Infrastructure
- Docker + Docker Compose
- Railway (backend)
- Vercel (frontend)
- Supabase (auth + database)
| Variable | Description |
|---|---|
PORT |
Server port (default: 3000) |
ADMIN_SECRET |
Secret for admin API routes |
ETH_NODE_1 / ETH_NODE_2 |
Ethereum mainnet node URLs |
SEPOLIA_NODE_1 |
Sepolia testnet node URL |
POLYGON_NODE_1 / POLYGON_NODE_2 |
Polygon node URLs |
BSC_NODE_1 / BSC_NODE_2 |
BSC node URLs |
ARBITRUM_NODE_1 / ARBITRUM_NODE_2 |
Arbitrum node URLs |
API_KEYS |
Comma-separated key:tier pairs |
MIT © 2025 RPCForge