Getting Started
First read
A chain read. No wallet required. Ten lines.
import { create_reader } from "@ethernauta/transport";
import { eth_block_number, eth_get_balance } from "@ethernauta/eth";
import { eip155_1, eip155_11155111 } from "@ethernauta/chain";
const reader = create_reader([eip155_1, eip155_11155111]);
const number = await eth_block_number()(
reader({ chain_id: eip155_1.chain_id }),
);
const balance = await eth_get_balance({
address: "0xd8dA6BF26964aF9D7eED9e03E53415D37aA96045",
block: "latest",
})(reader({ chain_id: eip155_1.chain_id })); What just happened
create_reader([chains]) — built a Reader factory that knows how to dial public RPC endpoints for any chain you pass in. The chain objects carry their own RPC URL list.
eth_block_number() — first call. Binds the method’s parameters (none, in this case). Returns a curried function with the shape (_resolved: ResolvedReader) => Promise<Uint>.
reader({ chain_id: eip155_1.chain_id }) — built a ResolvedReader for mainnet by picking the chain out of the registry.
The outer call — passes the resolved reader into the curried method. The HTTP request happens here.
The two-call shape — method(args)(resolver(...)) — is never collapsed. The first call binds parameters; the second binds the transport. That separation is what lets the same eth_block_number run against a public RPC reader, an EIP-1193 provider, or a test mock with zero changes at the call site.
Different chains, same call shape
const mainnet_block = await eth_block_number()(
reader({ chain_id: eip155_1.chain_id }),
);
const sepolia_block = await eth_block_number()(
reader({ chain_id: eip155_11155111.chain_id }),
); One reader, many chains. The chain_id argument picks the RPC at call time.
Where the URLs come from
The reader doesn’t hard-code endpoints. Each chain definition in @ethernauta/chain carries an rpc array of public endpoints. The HTTP transport rotates through them on failure. You can pass your own list if you want to point at a private RPC.
Next
- First signature — sign and broadcast.
- Reading from the chain — the full
eth_*read surface. - Concepts → resolver shapes — why
Readerexists at all.