Overview

@ethernauta/transport

The transport layer. Four resolver factories, HTTP and WebSocket transports, multicall batching, contract address binding, and 1193-provider adaptation.

pnpm add @ethernauta/transport

This package defines the shapes that every method binding in the monorepo speaks: Readable<T>, Writable<T>, Signable<T>, Callable<T>. See Concepts → resolver shapes for the philosophy.

The four factories

import {
  create_reader,
  create_writer,
  create_signer,
  create_contract,
} from "@ethernauta/transport";

const reader = create_reader([eip155_1, eip155_8453]);
const writer = create_writer([eip155_1]);
const signer = create_signer([eip155_1]);
const contract = create_contract([eip155_1]);

Each factory accepts a Chain[] and returns a function ({ chain_id, ... }) => ResolvedX. Pass the resolved object as the second curried argument to any method.

HTTP transport

import { http } from "@ethernauta/transport";

const transport = http({
  urls: ["https://eth.llamarpc.com", "https://cloudflare-eth.com"],
  retry: { attempts: 3, backoff: "exponential" },
  batch: { window_ms: 50, max_size: 100 },
});

Used internally by create_reader / create_writer / create_contract. Exposed if you want to construct a transport directly without going through the resolver factories.

Options:

  • urls — list of RPC endpoints. The transport rotates on failure.
  • retry: HttpRetryOptions{ attempts: number, backoff: "linear" | "exponential" }.
  • batch: HttpBatchOptions — enable JSON-RPC batch requests within a time window.

WebSocket transport

import { websocket } from "@ethernauta/transport";

const transport = websocket({
  url: "wss://eth.llamarpc.com/ws",
});

For subscription-based methods (eth_newHeads, eth_newPendingTransactions). HTTP can’t carry subscriptions; switch to WebSocket when you need long-lived push updates.

Multicall

import { create_multicall } from "@ethernauta/transport";
import { eth_get_balance, eth_block_number } from "@ethernauta/eth";

const multicall = create_multicall([eip155_1]);

const [block, balance] = await multicall({ chain_id: eip155_1.chain_id }).all([
  eth_block_number(),
  eth_get_balance({ address, block: "latest" }),
]);

Aggregates multiple reads into a single JSON-RPC batch. Backed by the same HTTP transport; the batching is at the JSON-RPC layer ([{ id: 1, ... }, { id: 2, ... }]).

For on-chain Multicall3-style aggregation (where the contract aggregates calls), use the matching ERC binding in @ethernauta/erc.

Contract binding

import { create_contract, contract } from "@ethernauta/transport";
import { balance_of } from "@ethernauta/erc/20";

const c = create_contract([eip155_1]);

const balance = await balance_of({ owner: holder })(
  c({ chain_id: eip155_1.chain_id, contract: token_address }),
);

create_contract produces a Callable-shaped resolver. The contract address is bound at resolver-construction time; ERC method bindings consume it implicitly via eth_call.

contract (lowercase) is the lower-level primitive that binds a callable to an address; create_contract is the factory.

EIP-1193 provider adapter

import { create_provider, create_injected_transport, create_injected_signer } from "@ethernauta/transport";

const provider = create_provider(window.ethereum);

// reads through the provider
const block = await eth_block_number()(provider.reader({ chain_id: 1 }));

// signing through the provider
const hash = await eth_send_transaction({ to, value })(
  provider.signer({ chain_id: 1 }),
);

create_provider(provider) adapts any 1193-compliant source into Ethernauta’s resolver shapes. create_injected_transport and create_injected_signer are the lower-level building blocks.

JSON-RPC schemas

The wire schemas for JSON-RPC requests and responses:

SchemaType
methodSchemathe method name
parametersSchemathe params array
requestSchemafull { jsonrpc, id, method, params }
responseSchemafull { jsonrpc, id, result } \| { ..., error }
idSchemarequest ID

Use these if you’re building a custom transport (e.g. an in-memory mock for tests) and need to validate the wire shape.

Types

TypeDescription
Readable<T>(_resolved: ResolvedReader) => Promise<T>
Writable<T>(_resolved: ResolvedWriter) => Promise<T>
Callable<T>composable read against a contract
Http, HttpOptions, HttpRetryOptions, HttpBatchOptionsHTTP transport types
Reader, Writer, Multicallfactory return shapes
Call, ContractContextfor Callable<T> builders
RequestArguments, Request, ResponseJSON-RPC wire types
ProviderRpcErrorEIP-1193 error type

See also