arlo
P2P-based RPC URL discovery for Ethereum and Base networks.
cargo install arloWhy?
Need an execution RPC or Beacon url for a network but don't have one?
Arlo's got you.
Want to use a stack of RPC urls to create a robust provider service?
Arlo's got you.
Demo
base-mainnet-demo.mov
Screen.Recording.2026-03-11.at.4.11.47.PM.mov
Usage
Scan for RPC endpoints on Ethereum mainnet and Base mainnet (the default):
arlo scanScan a specific network, or multiple networks at once:
arlo scan --chain eth-mainnet
arlo scan --chain eth-mainnet,base-mainnet,eth-sepoliaScan for a fixed duration (seconds) instead of running forever:
arlo scan --chain eth-mainnet --duration 60Only surface endpoints that expose specific namespaces:
arlo scan --chain eth-mainnet --namespace eth,debug,traceWrite discovered URLs to a file as well as stdout:
arlo scan --chain eth-mainnet --output urls.txtOnce you have a list of discovered endpoints stored in ~/.arlo/, start the proxy:
arlo proxyThe proxy walks you through selecting a network, an RPC type (execution, beacon, or rollup), and which specific backends to include. It then binds a local HTTP server you can point any JSON-RPC client at. You can also skip the interactive prompts:
arlo proxy --network eth-mainnet --port 8888
arlo proxy --network eth-mainnet --port 8888 --floodIn flood mode every request is fanned out to all selected backends simultaneously and the fastest successful response is returned to the caller. In the default sequential mode backends are tried one at a time in order, falling through to the next on any error or non-200 response.
Print every supported EVM chain and its chain ID:
arlo chainsHow it works
Ethereum mainnet and Ethereum Sepolia use the discv4 peer discovery protocol. Arlo runs up to 32 concurrent discv4 tasks, each with its own UDP socket, bonding with remote nodes by exchanging PING and PONG packets and then issuing FINDNODE to collect neighbor lists. Because discv4 requires mutual bonding before a node will answer FINDNODE, Arlo completes the full handshake (our PING, their PONG, their PING, our PONG) before requesting neighbors. This yields roughly 25 newly seen node addresses per second across the task pool.
Base mainnet and Base Sepolia are OP Stack chains and use discv5 instead of discv4. Arlo bootstraps into discv5 by converting each bootnode's secp256k1 public key into a libp2p PeerID, building a multiaddr, requesting the node's signed ENR, and then issuing FINDNODE queries from there.
Every IP address that surfaces from either discovery path is sent to the prober. The prober attempts an HTTP JSON-RPC connection on a set of common ports (8545, 8546, 9545, 8547 by default). If a port responds, Arlo calls eth_chainId to confirm the network, rpc_modules to enumerate exposed namespaces, eth_syncing to check sync status, and web3_clientVersion to fingerprint the client. Endpoints that pass all checks are printed to stdout in real time and appended to ~/.arlo/<network>/rpcs.json.
Alongside execution RPC probing, Arlo probes for beacon REST API endpoints on L1 chains and for OP Stack rollup node endpoints on L2 chains. Beacon nodes are identified by querying /eth/v1/config/spec and /eth/v1/node/version. Rollup nodes are identified by calling optimism_syncStatus and optimism_outputAtBlock.
Discovered peer IPs are also saved to ~/.arlo/<network>/bootstore.json and reloaded as seed peers on the next run, so each scan starts with a warm set of known-good addresses and reaches useful results faster over time.
The proxy subcommand reads whichever rpcs.json files you have accumulated and starts a local HTTP server using axum. Sequential mode forwards each incoming request to backends one at a time, returning the first HTTP 200 it receives and moving on to the next backend only if a connection fails or the response is not 200. Flood mode spawns one concurrent request per backend using a tokio JoinSet, returns the body from whichever backend responds first with 200, and cancels the remaining in-flight requests. Both modes forward the full request path so that beacon REST calls like GET /eth/v1/beacon/headers are routed correctly alongside ordinary JSON-RPC POST requests.
License
MIT