Minimal Ethereum JSON-RPC client over Finch.
Provides exactly the read-only RPC surface local payment verification needs:
eth_call, eth_getCode, eth_chainId, and ordered batch requests. It is
not a general-purpose Ethereum client — there is no transaction signing, no
filter/subscription support, and no ABI layer.
Requires the optional :finch dependency at runtime; every request returns
{:error, :missing_dependency} when Finch is unavailable. Users bring their
own Finch pool, exactly as with X402.Facilitator.HTTP:
{:ok, rpc} =
X402.RPC.new(
rpc_url: "https://sepolia.base.org",
finch: MyApp.Finch
)
{:ok, "0x14a34"} = X402.RPC.chain_id(rpc)TLS Verification
rpc_url must use https:// (plain http:// is allowed only for
localhost), and TLS peer verification must be configured on the Finch
pool — see X402.Facilitator.HTTP.secure_pool_opts/0 for a ready-made
configuration.
Telemetry
Every request emits [:x402, :rpc, :request] with :status (:ok or
:error) and :method metadata (the string method name, or :batch).
Summary
Types
One request in a batch: a JSON-RPC method name and its params.
Per-request outcome inside a successful batch response.
Structured request errors.
A Finch pool identifier, as accepted by Finch.request/3.
A JSON-RPC error object returned by the node.
Functions
Performs an ordered JSON-RPC batch request in one HTTP round-trip.
Performs an eth_call against the given block (default "latest").
Returns the chain id via eth_chainId, as the node's hex string
(for example "0x14a34" for Base Sepolia).
Returns the bytecode at address via eth_getCode (default block
"latest").
Builds a validated RPC configuration.
Performs a single JSON-RPC request.
Validates that a value is an %X402.RPC{} configuration.
Types
One request in a batch: a JSON-RPC method name and its params.
@type batch_result() :: {:ok, term()} | {:error, {:jsonrpc_error, jsonrpc_error()}}
Per-request outcome inside a successful batch response.
@type error() :: :missing_dependency | :insecure_rpc_url | {:transport_error, term()} | {:http_error, non_neg_integer()} | {:invalid_response, term()} | {:jsonrpc_error, jsonrpc_error()}
Structured request errors.
A Finch pool identifier, as accepted by Finch.request/3.
A JSON-RPC error object returned by the node.
@type t() :: %X402.RPC{ finch: finch_name(), rpc_url: String.t(), timeout: pos_integer() }
Validated JSON-RPC endpoint configuration built by new/1.
Functions
@spec batch(t(), [batch_request()]) :: {:ok, [batch_result()]} | {:error, error()}
Performs an ordered JSON-RPC batch request in one HTTP round-trip.
Takes a list of {method, params} tuples and returns {:ok, results}
where results has one entry per request, in request order (responses
are re-ordered by id): each entry is {:ok, result} or
{:error, {:jsonrpc_error, error}}. Transport-level failures fail the
whole batch with {:error, reason}.
An empty request list returns {:ok, []} without any HTTP call.
Performs an eth_call against the given block (default "latest").
The call object accepts :to, :data, and optionally :from (atom or
string keys). Returns the raw 0x-prefixed return data.
Returns the chain id via eth_chainId, as the node's hex string
(for example "0x14a34" for Base Sepolia).
Returns the bytecode at address via eth_getCode (default block
"latest").
A plain externally-owned account returns {:ok, "0x"}.
Builds a validated RPC configuration.
Options are validated with NimbleOptions:
:rpc_url(String.t/0) - Required. The JSON-RPC endpoint URL. Must usehttps://; plainhttp://is accepted only forlocalhost(local development nodes and tests).:finch- Required. The Finch pool name (atom, pid, or{:via, module, term}).:timeout(pos_integer/0) - Receive timeout per HTTP request, in milliseconds. The default value is5000.
Returns {:error, :insecure_rpc_url} when rpc_url does not use
https:// (with a localhost exemption for development nodes).
Examples
iex> {:ok, rpc} = X402.RPC.new(rpc_url: "https://sepolia.base.org", finch: MyFinch)
iex> rpc.timeout
5000
iex> X402.RPC.new(rpc_url: "http://rpc.example.com", finch: MyFinch)
{:error, :insecure_rpc_url}
Performs a single JSON-RPC request.
Returns the decoded "result" value on success, or a structured error —
node-side failures come back as {:error, {:jsonrpc_error, %{code: _, message: _, data: _}}} and transport failures as
{:error, {:transport_error, reason}}.
Validates that a value is an %X402.RPC{} configuration.
Designed for NimbleOptions custom validation (used by
X402.Verify.EVM).