Exth.Rpc.Client (Exth v0.4.2)

View Source

Core client module for making JSON-RPC requests to EVM nodes.

This module provides the main client interface for interacting with EVM nodes, handling request creation, response parsing, and client lifecycle management.

Features

  • Atomic request ID generation
  • Transport abstraction
  • Request/response lifecycle management
  • Batch request support
  • Error handling
  • Fluent API for chaining requests

Usage

Basic Usage

# Create a new client
client = Client.new(:http,
  rpc_url: "https://eth-mainnet.example.com",
  timeout: 30_000
)

# Create a raw request
rpc_call = Client.request(client, "eth_blockNumber", [])

# Send the request
{:ok, response} = Client.send(rpc_call)

# Send batch requests
{:ok, responses} =
  client
  |> Client.request("eth_blockNumber", [])
  |> Client.request("eth_getBalance", [address, block])
  |> Client.send()

Using Raw Requests

# Create a raw request
request = Request.new("eth_blockNumber", [], 1)

# Send the request
{:ok, response} = Client.send(request, client)
# or
{:ok, response} = Client.send(client, request)

# Send batch requests
{:ok, responses} = Client.send([request1, request2], client)
# or
{:ok, responses} = Client.send(client, [request1, request2])

Client Configuration

The client accepts the following options:

  • :rpc_url - (Required) The endpoint URL
  • other options that are specific to the transport type

Request ID Generation

The client uses Erlang's :atomics for thread-safe, monotonic request ID generation. This ensures:

  • Unique IDs across concurrent requests
  • No ID collisions in batch requests
  • Efficient ID allocation
  • Process-independent ID tracking

Transport Layer

The client supports different transport mechanisms through the Exth.Transport.Transportable protocol:

  • Built-in HTTP transport using Tesla/Mint
  • Custom transport implementations
  • Future support for WebSocket and IPC

Error Handling

The client provides consistent error handling:

  • {:ok, response} - Successful request
  • {:error, reason} - Request failed

Best Practices

  • Reuse client instances when possible
  • Use batch requests for multiple calls
  • Implement appropriate timeouts
  • Handle errors gracefully
  • Monitor client health
  • Clean up resources when done

See Exth.Transport for transport details.

Summary

Types

send_argument_type()

@type send_argument_type() ::
  t() | Exth.Rpc.Call.t() | Exth.Rpc.Request.t() | [Exth.Rpc.Request.t()] | []

send_response_type()

@type send_response_type() ::
  Exth.Transport.call_response() | {:error, :duplicate_ids}

t()

@type t() :: %Exth.Rpc.Client{
  counter: :atomics.atomics_ref(),
  handler: Exth.Rpc.MessageHandler.handler() | nil,
  transport: Exth.Transport.Transportable.t()
}

Functions

generate_id(client)

@spec generate_id(t()) :: non_neg_integer()

new(type, opts)

@spec new(
  Exth.Transport.type(),
  keyword()
) :: t()

request(client, method, params)

send(call)

@spec send(Exth.Rpc.Call.t()) :: send_response_type()

send(client, request)