Read Operations Proxy
Relevant source files
The following files were used as context for generating this wiki page:
The Read Operations Proxy is a core functional pattern within the walletless provider that facilitates the separation of blockchain state queries from cryptographic signing operations. In this architecture, the provider acts as a "Man-in-the-Middle," identifying JSON-RPC methods that only require data retrieval (reads) and transparently forwarding them to an external RPC endpoint, typically an Anvil instance.
This mechanism ensures "chain realism" by fetching actual state data (like balances, contract code, or block information) from a real or forked blockchain while bypassing the need for a browser extension or manual user confirmation for read-only requests.
Sources: src/provider.ts:110-117, README.md:16-24
Architecture and Request Routing
The proxy logic is integrated into the provider's main request handler. When a request is received, the system categorizes the method using predefined constants to determine if it should be handled locally (wallet/write methods) or proxied to the RPC URL (read methods).
Request Flow Diagram
The following diagram illustrates how the provider differentiates between request types and routes read operations to the external RPC.
Sources: src/provider.ts:443-463, README.md:12-22
Read Method Classification
Read operations are defined as RPC methods that retrieve data from the blockchain without altering state or requiring private key access. The proxy maintains a comprehensive list of these methods to ensure correct routing.
| Category | Supported RPC Methods |
|---|---|
| Block Data | eth_blockNumber, eth_getBlockByHash, eth_getBlockByNumber, eth_getBlockTransactionCountByHash, eth_getBlockTransactionCountByNumber, eth_getUncleByBlockHashAndIndex, eth_getUncleByBlockNumberAndIndex, eth_getUncleCountByBlockHash, eth_getUncleCountByBlockNumber |
| State/Account | eth_getBalance, eth_getCode, eth_getStorageAt, eth_call |
| Transactions | eth_getTransactionByHash, eth_getTransactionByBlockHashAndIndex, eth_getTransactionByBlockNumberAndIndex, eth_getTransactionReceipt, eth_getTransactionCount |
| Filters/Logs | eth_newFilter, eth_newBlockFilter, eth_newPendingTransactionFilter, eth_uninstallFilter, eth_getFilterChanges, eth_getFilterLogs, eth_getLogs |
| Network/Gas | eth_gasPrice, eth_estimateGas, eth_feeHistory, eth_maxPriorityFeePerGas, eth_chainId, net_version, net_listening, net_peerCount |
Sources: src/constants.ts:74-131
Implementation Details
Proxy Execution Logic
The proxying is handled by two primary internal functions: handleReadMethod and sendJsonRpc. The sendJsonRpc function encapsulates the fetch logic, constructing a standard JSON-RPC 2.0 request and sending it to the currently configured rpcUrl.
async function sendJsonRpc<T>(method: string, params?: unknown[]): Promise<T> {
const rpcRequest: JsonRpcRequest = {
jsonrpc: "2.0",
method,
params,
id: requestId,
};
const response = await fetch(internal.rpcUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(rpcRequest),
});
const data: JsonRpcResponse<T> = (await response.json()) as JsonRpcResponse<T>;
// Error handling and result return logic...
}
Sources: src/provider.ts:203-233
RPC URL Resolution
The proxy dynamically resolves the target RPC endpoint based on the provider's current chain state. If a specific URL is provided in the rpcUrls configuration for the active chainId, it is used; otherwise, it defaults to the standard Anvil URL.
- Default URL:
http://127.0.0.1:8545 - Fallback Logic: If a chain is not explicitly mapped in
rpcUrls, the proxy falls back to the default Anvil RPC.
Sources: src/constants.ts:5, src/provider.ts:139-143, src/types.ts:27-32
Sequence of a Read Operation
The following sequence diagram shows the interaction between the DApp, the Walletless Provider, and the remote RPC during a balance check.
Error Handling
The proxy includes a mechanism to pass through errors from the remote RPC. If the fetched JsonRpcResponse contains an error object, the proxy extracts the message and error code, throwing a local error that the DApp can catch. This ensures that network-level or node-level issues (e.g., "Invalid Request" or "Contract Execution Reverted") are correctly reported to the testing environment.
Sources: src/provider.ts:222-228, src/types.ts:62-66, test/provider.spec.ts:233-247
Summary
The Read Operations Proxy is the mechanism that allows walletless to remain lightweight while providing full access to blockchain data. By routing all non-signing and non-wallet-state methods directly to an external RPC like Anvil, the system ensures that tests operate against high-fidelity blockchain state without the overhead of browser-based wallet interactions.