Skip to content

Agusrodri/json-proxy-exp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

JSON-RPC HTTP Reverse Proxy

A lightweight Go reverse proxy for JSON-RPC endpoints with authentication, method allowlisting, rate limiting, and structured JSON logging.

Architecture

Client ──POST──▶ :8080
                  │
                  ├─ POST guard (405 if not POST)
                  ├─ Rate limiter (429 if over 10 req/s, burst 20)
                  ├─ Auth check (401 if missing/wrong Bearer token)
                  ├─ Method allowlist (403 if method not allowed)
                  │
                  ▼
            TARGET_RPC_URL

Quick Start

go build -o json-proxy-exp .
TARGET_RPC_URL=https://eth.llamarpc.com ./json-proxy-exp

Or without building:

TARGET_RPC_URL=https://eth.llamarpc.com go run main.go

The server listens on :8080 and forwards allowed JSON-RPC requests to the target.

Configuration

Variable Required Description
TARGET_RPC_URL Yes Upstream JSON-RPC endpoint to proxy

E2E Test Scenarios

Start the proxy in one terminal:

TARGET_RPC_URL=https://eth.llamarpc.com go run main.go

Then run each test in a second terminal.

1. POST Guard — Wrong HTTP Method

Verifies that non-POST requests are rejected before reaching any middleware.

curl -i http://localhost:8080/

Expected: 405 Method Not Allowed Server logs: "msg":"method_not_allowed","client_ip":"127.0.0.1","http_method":"GET".

2. Rate Limiter — Burst Exceeded

Fires 25 rapid requests to exceed the burst capacity of 20.

for i in $(seq 1 25); do
  curl -s -o /dev/null -w "$i: %{http_code}\n" -X POST http://localhost:8080/ \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
done

Expected: First ~20 return 401 (pass rate limiter, fail auth). Remaining return 429 Too Many Requests. Server logs: "msg":"rate_limit_exceeded" entries for the 429 responses.

3. Auth — Missing Authorization Header

curl -i -X POST http://localhost:8080/ \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

Expected: 401 Unauthorized with body {"error":"unauthorized"}. Server logs: "auth":"failed","policy":"deny".

4. Auth — Wrong API Key

curl -i -X POST http://localhost:8080/ \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wrong-key" \
  -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

Expected: 401 Unauthorized. Server logs: "auth":"failed","policy":"deny".

5. Method Allowlist — Blocked Method

Sends a valid auth but a method not in the allowlist.

curl -i -X POST http://localhost:8080/ \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer test-key-123" \
  -d '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[],"id":1}'

Expected: 403 Forbidden with a JSON-RPC error:

{"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"method not allowed: eth_sendTransaction"}}

Server logs: "auth":"success","policy":"deny".

6. Full Proxy — eth_chainId

curl -s -X POST http://localhost:8080/ \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer test-key-123" \
  -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

Expected: 200 OK with response:

{"jsonrpc":"2.0","id":1,"result":"0x1"}

Server logs: "auth":"success","policy":"allow".

7. Full Proxy — eth_blockNumber

curl -s -X POST http://localhost:8080/ \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer test-key-123" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":2}'

Expected: 200 OK with a hex block number in the result, e.g.:

{"jsonrpc":"2.0","id":2,"result":"0x134a1c0"}

Server logs: "auth":"success","policy":"allow".

Log Reference

Every request that reaches the gateway produces a structured JSON log line:

{"time":"2026-03-03T12:00:00Z","level":"INFO","msg":"rpc_request","client_ip":"127.0.0.1","method":"eth_chainId","auth":"success","policy":"allow"}
Field Values Description
client_ip IP address From X-Forwarded-For or direct
method JSON-RPC method string e.g. eth_chainId
auth success / failed Authorization header check result
policy allow / deny Final access control decision

Allowed Methods

Method
eth_chainId
eth_blockNumber
eth_call

All other methods are denied by default.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages