JSON-RPC
Overview
For an Application to communicate with the Ethereum network, it needs to establish a connection to an Ethereum Node, and be able to send and receive messages in a standardized format.
All Ethereum Nodes implement the JSON-RPC specification, which is a stateless & lightweight remote procedure call (RPC) protocol.
Ox provides type-safe primitives for working with the JSON-RPC specification.
Examples
Sending a Request
The example below demonstrates sending a strongly-typed JSON-RPC request to an Ethereum Node using an auto-incrementing JSON-RPC id
store via RpcRequest.createStore
.
import { RpcRequest } from 'ox'
// 1. Create a request store.
const store = RpcRequest.createStore()
// 2. Prepare a request.
const request = store.prepare({
method: 'eth_getBlockByNumber',
params: ['latest', false],
})
{ id: 0, jsonrpc: '2.0', method: 'eth_getBlockByNumber', params: ['latest', false] } // 3. Send the request to an Ethereum Node.
const response = await fetch('https://1.rpc.thirdweb.com', {
body: JSON.stringify(request),
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
}).then((res) => res.json())
Parsing a Response
The example below demonstrates parsing a JSON-RPC response using the RpcResponse.parse
function. This will extract the JSON-RPC result
and and strongly type the response based on the request
used.
import { RpcRequest, RpcResponse } from 'ox'
// 1. Create a request store.
const store = RpcRequest.createStore()
// 2. Prepare a request.
const request = store.prepare({
method: 'eth_getBlockByNumber',
params: ['latest', false],
})
// 3. Send the request to an Ethereum Node.
const response = await fetch('https://1.rpc.thirdweb.com', {
body: JSON.stringify(request),
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
// 4. Parse the response.
.then((res) => RpcResponse.parse(res, { request }))
const response: {
baseFeePerGas?: `0x${string}` | undefined;
blobGasUsed?: `0x${string}` | undefined;
difficulty?: `0x${string}` | undefined;
excessBlobGas?: `0x${string}` | undefined;
extraData?: Hex | undefined;
... 21 more ...;
withdrawalsRoot?: Hex | undefined;
} | nullresponse
Handling Requests
If you need to handle incoming JSON-RPC requests and return a respective response (for example, if you are building an JSON-RPC API handler or an EIP-1193 Provider request
handler in a Wallet), you can utilize the RpcResponse.from
function.
import { RpcRequest, RpcResponse, RpcSchema } from 'ox'
const accounts = ['0x...', '0x...'] as const
async function handleRequest(request: RpcRequest.RpcRequest<RpcSchema.Eth>) {
if (request.method === 'eth_accounts')
return RpcResponse.from({ result: accounts }, { request })
if (request.method === 'eth_chainId')
return RpcResponse.from({ result: '0x1' }, { request })
if (request.method === 'eth_getBlocketh_getBlockByHasheth_getBlockByNumbereth_getBlockTransactionCountByHasheth_getBlockTransactionCountByNumber')
return await fetch('https://1.rpc.thirdweb.com', {
body: JSON.stringify(request),
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
.then((res) => RpcResponse.from(res))
}
Related Modules
Module | Description |
---|---|
RpcRequest | Utility types & functions for working with JSON-RPC 2.0 Requests and Ethereum JSON-RPC methods as defined on the Ethereum API specification |
RpcResponse | Utility types & functions for working with JSON-RPC 2.0 Responses |
RpcSchema | Utility types for working with Ethereum JSON-RPC namespaces & schemas. |
RpcTransport | Utility functions for working with JSON-RPC Transports. |