Exth.Rpc.Encoding (Exth v0.2.1)

View Source

Handles encoding and decoding of JSON-RPC requests and responses.

This module provides functionality to serialize and deserialize JSON-RPC 2.0 requests and responses, ensuring compliance with the protocol specification.

Features

  • Request encoding (single and batch)
  • Response decoding (single and batch)
  • Error handling with detailed messages
  • Protocol compliance validation
  • Automatic structure conversion

JSON-RPC 2.0 Format

Request format:

{
  "jsonrpc": "2.0",
  "method": "method_name",
  "params": [],
  "id": 1
}

Success response format:

{
  "jsonrpc": "2.0",
  "result": "0x1",
  "id": 1
}

Error response format:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32700,
    "message": "Parse error"
  },
  "id": 1
}

Usage

Encoding single requests:

request = %Request{
  jsonrpc: "2.0",
  method: "eth_blockNumber",
  params: [],
  id: 1
}

{:ok, json} = Encoding.encode_request(request)

Encoding batch requests:

requests = [
  %Request{method: "eth_blockNumber", id: 1},
  %Request{method: "eth_gasPrice", id: 2}
]

{:ok, json} = Encoding.encode_request(requests)

Decoding responses:

{:ok, response} = Encoding.decode_response(json)
# Returns {:ok, %Response{}} for single responses
# Returns {:ok, [%Response{}, ...]} for batch responses

Error Handling

The module returns tagged tuples for all operations:

  • {:ok, result} - Successful encoding/decoding
  • {:error, exception} - Operation failed with detailed error

Common error cases:

  • Invalid JSON syntax
  • Missing required fields
  • Invalid response format
  • Protocol version mismatch

Examples

# Encode a single request
request = %Request{
  method: "eth_blockNumber",
  params: [],
  id: 1
}
{:ok, json} = Encoding.encode_request(request)

# Decode a success response
{:ok, response} = Encoding.decode_response(~s({
  "jsonrpc": "2.0",
  "result": "0x1",
  "id": 1
}))

# Decode an error response
{:ok, response} = Encoding.decode_response(~s({
  "jsonrpc": "2.0",
  "error": {
    "code": -32700,
    "message": "Parse error"
  },
  "id": 1
}))

# Handle batch operations
requests = [
  %Request{method: "eth_blockNumber", id: 1},
  %Request{method: "eth_gasPrice", id: 2}
]
{:ok, json} = Encoding.encode_request(requests)
{:ok, responses} = Encoding.decode_response(json)

Implementation Notes

  • Uses elixir's JSON for JSON encoding/decoding
  • Automatically handles struct conversion
  • Preserves request IDs for correlation
  • Supports both single and batch operations
  • Validates protocol compliance

See Exth.Rpc.Request for request structure details and Exth.Rpc.Response for response handling.

Summary

Functions

decode_response(json)

@spec decode_response(String.t()) ::
  {:ok, Exth.Rpc.Response.t() | [Exth.Rpc.Response.t()]}
  | {:error, Exception.t()}

encode_request(request)

@spec encode_request(Exth.Rpc.Request.t() | [Exth.Rpc.Request.t()]) ::
  {:ok, String.t()} | {:error, Exception.t()}