I see there have been a number of issues around the current set of active RPC providers, particularly for Paseo.
As I’ve been playing around with pallet_revive I’ve been finding that I occasionally was being throttled by the RPC providers (no fault on them for managing spam). Based on my understanding of how smoldot was intended to bypass the need for RPC’s entirely, I thought it would be viable to use a compatibility layer to translate the eth-rpc calls.
Pine-RPC handles nearly everything I’ve tested with it. It is a self-contained smoldot node server you can setup in your network and point other devices to, or using the PineProvider you can import the node directly into you app or web page with EVM translation compatibility. I’m actively using it in my hacking and learning.
There are some limitation of using a light client, but I think it comes down to the trade off between convenience and resilience, mostly. Hopefully someone finds this useful for their own purposes.
Install
npm install -g pine-rpc
or run without installing:
npx pine-rpc --chain paseo-asset-hub
Requires Node.js ≥ 18. Or skip Node entirely and use Docker:
docker run -p 8545:8545 ghcr.io/baronvonbonbon/pine-rpc --chain polkadot-asset-hub
Run the node
Paseo Asset Hub testnet on http://127.0.0.1:8545 (+ ws://127.0.0.1:8545)
pine
Polkadot Asset Hub mainnet on a custom port
pine --chain polkadot-asset-hub --port 9944
Expose on the LAN (no auth — only behind a trusted network)
pine --host 0.0.0.0
First sync takes ~10–60 s (WASM init + P2P peer discovery + first finalized block). When ready you’ll see:
HTTP http://127.0.0.1:8545
WS ws://127.0.0.1:8545
ready — press Ctrl+C to stop
GET /health returns 200 {"status":"ok"}
once the light client is following finalized blocks (503 while starting) — use it for Docker HEALTHCHECK, systemd readiness, or load-balancer probes.
Point any Ethereum tool at it:
cast block-number --rpc-url http://127.0.0.1:8545
import { JsonRpcProvider } from "ethers";
const provider = new JsonRpcProvider("http://127.0.0.1:8545");
console.log(await provider.getBlockNumber());