Skip to content

Simplify RPC layer by leaning on near-openrpc-client #133

@r-near

Description

@r-near

Context

With the migration from near-openapi-client to near-openrpc-client (in progress on feat/migrate-openrpc), there's an opportunity to further simplify the RPC layer by using more of what the openrpc crate already provides instead of reimplementing it.

Current state

  • api/src/rpc_client.rs is a hand-rolled JSON-RPC 2.0 client that reimplements what NearRpcClient in near-openrpc-client already does. It exists because the retry loop in config.rs needs to construct a fresh client per endpoint.
  • api/src/common/query/query_request.rs manually builds serde_json::Value objects for each query type (view_account, call_function, etc.), but the openrpc crate already has typed request structs (RpcViewAccountRequest, RpcCallFunctionRequest, etc.) with proper serde.
  • types/src/lib.rs re-exports ~10 openrpc types verbatim (RpcViewStateResponse, RpcViewCodeResponse, RpcBlockResponse, etc.) — these could be imported directly from near-openrpc-client.

Proposed simplifications (in order of impact)

1. Use NearRpcClient directly, delete rpc_client.rs

Enable the client feature on near-openrpc-client and make NearRpcClient accept an external reqwest::Client + URL (small upstream change). Then retry() constructs NearRpcClient instances, and RPC types like SimpleBlockRpc call typed methods (client.block(request)) instead of client.call::<_, RpcBlockResponse>("block", request).

SimpleQueryRpc would still need the generic call() for the polymorphic query endpoint, but everything else gets typed methods for free.

2. Replace QueryRequest JSON construction with typed openrpc request structs

Delete the manual serde_json::json!({...}) construction in query_request.rs and use the openrpc crate's RpcViewAccountRequest, RpcCallFunctionRequest, etc. directly. The polymorphic response still deserializes to Value first, but typed requests + untyped responses is still a win over untyped everything.

3. Reduce types crate re-exports

Stop re-exporting openrpc types that don't add value beyond the original. The types crate should focus on what it genuinely adds: CryptoHash([u8; 32]), Account, crypto types, borsh-serializable transaction types, and execution result ergonomics. Users would import RPC response types from near-openrpc-client directly.

Related

The ContractExecutionError special case (checking value.get("error") on query success responses) might also be eliminable if NEAR returns these as proper RPC errors through the typed query path — worth investigating.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    NEW❗

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions