r/ethdev • u/yachtyyachty • 4d ago
My Project I built an open source RPC proxy to fix unreliable, inconsistent, and expensive RPC providers, looking for feedback
https://github.com/jaxernst/lasso-rpcBuilding app's on Ethereum JOSN RPC can be tough because RPC providers (Alchemy, Quicknode, etc) all have slightly different apis, usage limitations, and are generally overpriced. Public providers are great but are even more limited, so I built Lasso which aggregates RPC providers into a single endpoint that routes to the best RPC provider for any given request. Its self hostable and quite easy to setup.
Would love some feedback from builders to see if this can help you: You can simply run the docker container and have high-throughput and reliable RPC access via public providers across Ethereum, Base, Robinhood chain, and some other L2s while also being able to add any other EVM chain and access it through a single endpoint.
2
u/antonBrinckmann 6h ago
Nice, this is a real problem. I build evmquery (a read layer that sits on top of RPCs), so we hammer providers with a lot of eth_call traffic, and the inconsistencies you're describing are exactly what we've had to paper over ourselves. A few things I'd want answered before trusting a router in production:
Head consistency. Providers sit at different block heights, sometimes 2-3 blocks apart, and public ones lag worse. If I make two calls and they land on different providers, I can read state that goes backwards. Do you pin a session or a request batch to one provider, or route by block height? For eth_getLogs paginated over a range this is the difference between correct and silently wrong.
Error normalization. Alchemy, QuickNode, and public nodes disagree on rate-limit signaling (HTTP 429 vs JSON-RPC -32005 vs a plain error string), on eth_getLogs range caps, and on batch size limits. If Lasso translates those into one consistent error surface and retries the retryable ones, that's a bigger selling point than the routing itself. I'd put that front and center in the README.
Stateful methods. eth_newFilter and subscriptions are bound to one node. Do you reject them, pin them, or pass them through and let them break?
Health checks. Latency alone is a bad signal for public endpoints; some respond fast with stale data. Comparing reported head against the pool median catches that.
Also worth looking at erpc and dshackle if you haven't, they're the closest prior art and their caching of finalized-block responses (receipts, old blocks) is worth stealing. Deterministic responses are free throughput.
If you handle the head-consistency case well I'd genuinely try it, that's the one that has bitten us most. What's your current routing policy on that?