Nethereum.JsonRpc.Client
7.0.0
Prefix Reserved
dotnet add package Nethereum.JsonRpc.Client --version 7.0.0
NuGet\Install-Package Nethereum.JsonRpc.Client -Version 7.0.0
<PackageReference Include="Nethereum.JsonRpc.Client" Version="7.0.0" />
<PackageVersion Include="Nethereum.JsonRpc.Client" Version="7.0.0" />
<PackageReference Include="Nethereum.JsonRpc.Client" />
paket add Nethereum.JsonRpc.Client --version 7.0.0
#r "nuget: Nethereum.JsonRpc.Client, 7.0.0"
#:package Nethereum.JsonRpc.Client@7.0.0
#addin nuget:?package=Nethereum.JsonRpc.Client&version=7.0.0
#tool nuget:?package=Nethereum.JsonRpc.Client&version=7.0.0
Nethereum.JsonRpc.Client
Core JSON-RPC abstraction layer for Ethereum node communication.
Overview
Nethereum.JsonRpc.Client provides the fundamental abstraction layer for all JSON-RPC communication with Ethereum nodes. It defines the core interfaces and base classes that all RPC client implementations must implement, enabling pluggable transport mechanisms (HTTP, WebSocket, IPC) while maintaining consistent error handling, request interception, and batch processing.
Key Features:
- Transport-agnostic RPC abstraction (HTTP, WebSocket, IPC)
- Request/response message handling
- Batch request support
- Request interception for logging/monitoring
- Consistent error handling across transports
- Basic authentication support
- Streaming/subscription support
Use Cases:
- Building custom RPC client implementations
- Implementing request logging and monitoring
- Creating custom transport mechanisms
- Testing and mocking RPC communication
- Building middleware for RPC calls
Installation
dotnet add package Nethereum.JsonRpc.Client
Note: This is typically used as a dependency by concrete client implementations. Most users will use:
- Nethereum.JsonRpc.RpcClient - HTTP/HTTPS client
- Nethereum.JsonRpc.WebSocketClient - WebSocket client
- Nethereum.JsonRpc.IpcClient - IPC client
Dependencies
Nethereum:
- Nethereum.Hex - Hex encoding/decoding utilities
External:
- Microsoft.Extensions.Logging.Abstractions (v6.0.0+) - Logging support (conditional dependency for modern frameworks)
JSON Serialization:
- Newtonsoft.Json (
[11.0.2,14)) - real dependency, used for request/response message handling andRpcError.Data - System.Text.Json support is provided by the separate
Nethereum.JsonRpc.SystemTextJsonRpcClientpackage, not by this one
Quick Start
using Nethereum.JsonRpc.Client;
using Nethereum.RPC.Eth.Blocks;
// Use concrete implementation (RpcClient)
var client = new RpcClient(new Uri("http://localhost:8545"));
// Use through higher-level RPC services
var ethBlockNumber = new EthBlockNumber(client);
var blockNumber = await ethBlockNumber.SendRequestAsync();
Console.WriteLine($"Current block: {blockNumber.Value}");
Core Interfaces
IClient
Main interface for JSON-RPC communication:
public interface IClient : IBaseClient
{
// Send single request
Task<T> SendRequestAsync<T>(RpcRequest request, string route = null);
Task<T> SendRequestAsync<T>(string method, string route = null, params object[] paramList);
// Send batch request
Task<RpcRequestResponseBatch> SendBatchRequestAsync(RpcRequestResponseBatch rpcRequestResponseBatch);
// Low-level message sending
Task<RpcResponseMessage> SendAsync(RpcRequestMessage rpcRequestMessage, string route = null);
}
IBaseClient
Base interface with common properties (IBaseClient.cs:6-15). Note ConnectionTimeout is not part of this interface - it lives on the static ClientBase.ConnectionTimeout property instead:
public interface IBaseClient
{
RequestInterceptor OverridingRequestInterceptor { get; set; }
T DecodeResult<T>(RpcResponseMessage rpcResponseMessage);
Task SendRequestAsync(RpcRequest request, string route = null);
Task SendRequestAsync(string method, string route = null, params object[] paramList);
}
Usage Examples
Example 1: Basic RPC Requests
using Nethereum.JsonRpc.Client;
using Nethereum.RPC.Eth;
using Nethereum.Hex.HexTypes;
// Create HTTP client
var client = new RpcClient(new Uri("http://localhost:8545"));
// Use with RPC services
var ethChainId = new EthChainId(client);
HexBigInteger chainId = await ethChainId.SendRequestAsync();
var ethAccounts = new EthAccounts(client);
string[] accounts = await ethAccounts.SendRequestAsync();
Console.WriteLine($"Chain ID: {chainId.Value}");
Console.WriteLine($"Accounts: {string.Join(", ", accounts)}");
Example 2: Direct Method Calls
using Nethereum.JsonRpc.Client;
using Newtonsoft.Json.Linq;
var client = new RpcClient(new Uri("http://localhost:8545"));
// Direct JSON-RPC method call
var blockNumber = await client.SendRequestAsync<string>("eth_blockNumber");
Console.WriteLine($"Block: {blockNumber}");
// With parameters
var balance = await client.SendRequestAsync<string>(
"eth_getBalance",
null, // route
"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", // address
"latest" // block parameter
);
Console.WriteLine($"Balance: {balance}");
Example 3: Batch Requests
RpcRequestResponseBatchItem<TRequestHandler, TResponse> is constructed from a request handler and an RpcRequest (RpcRequestResponseBatchItem.cs:7-13), and its decoded result is read from .Response - there is no GetResponse<T>() method:
using Nethereum.JsonRpc.Client;
var client = new RpcClient(new Uri("http://localhost:8545"));
// Create batch request
var batch = new RpcRequestResponseBatch();
// Build one handler per method, then wrap each in a batch item
var blockNumberHandler = new RpcRequestResponseHandlerNoParam<string>(client, "eth_blockNumber");
var chainIdHandler = new RpcRequestResponseHandlerNoParam<string>(client, "eth_chainId");
var gasPriceHandler = new RpcRequestResponseHandlerNoParam<string>(client, "eth_gasPrice");
var blockNumberItem = new RpcRequestResponseBatchItem<RpcRequestResponseHandlerNoParam<string>, string>(
blockNumberHandler, blockNumberHandler.BuildRequest(1));
var chainIdItem = new RpcRequestResponseBatchItem<RpcRequestResponseHandlerNoParam<string>, string>(
chainIdHandler, chainIdHandler.BuildRequest(2));
var gasPriceItem = new RpcRequestResponseBatchItem<RpcRequestResponseHandlerNoParam<string>, string>(
gasPriceHandler, gasPriceHandler.BuildRequest(3));
batch.BatchItems.Add(blockNumberItem);
batch.BatchItems.Add(chainIdItem);
batch.BatchItems.Add(gasPriceItem);
// Send batch
await client.SendBatchRequestAsync(batch);
// Process results - each typed item exposes .Response directly
foreach (var item in new IRpcRequestResponseBatchItem[] { blockNumberItem, chainIdItem, gasPriceItem })
{
if (item.HasError)
Console.WriteLine($"Request {item.RpcRequestMessage.Id} failed: {item.RpcError.Message}");
else
Console.WriteLine($"Request {item.RpcRequestMessage.Id}: {item.RawResponse}");
}
// Or read the strongly-typed result directly from a known item:
Console.WriteLine($"Block number: {blockNumberItem.Response}");
Example 4: Request Interception for Logging
using Nethereum.JsonRpc.Client;
using System.Diagnostics;
// Custom request interceptor
public class LoggingInterceptor : RequestInterceptor
{
public override async Task<object> InterceptSendRequestAsync<T>(
Func<RpcRequest, string, Task<T>> interceptedSendRequestAsync,
RpcRequest request,
string route = null)
{
var sw = Stopwatch.StartNew();
Console.WriteLine($"[REQUEST] {request.Method} - Params: {string.Join(", ", request.RawParameters ?? Array.Empty<object>())}");
try
{
var result = await base.InterceptSendRequestAsync(interceptedSendRequestAsync, request, route);
sw.Stop();
Console.WriteLine($"[RESPONSE] {request.Method} - {sw.ElapsedMilliseconds}ms");
return result;
}
catch (Exception ex)
{
sw.Stop();
Console.WriteLine($"[ERROR] {request.Method} - {sw.ElapsedMilliseconds}ms - {ex.Message}");
throw;
}
}
}
// Usage
var client = new RpcClient(new Uri("http://localhost:8545"));
client.OverridingRequestInterceptor = new LoggingInterceptor();
var ethBlockNumber = new EthBlockNumber(client);
var blockNumber = await ethBlockNumber.SendRequestAsync();
// Output: [REQUEST] eth_blockNumber - Params:
// Output: [RESPONSE] eth_blockNumber - 45ms
Example 5: Error Handling
using Nethereum.JsonRpc.Client;
var client = new RpcClient(new Uri("http://localhost:8545"));
try
{
// Invalid method call
var result = await client.SendRequestAsync<string>("invalid_method");
}
catch (RpcResponseException ex)
{
// Standard RPC error
Console.WriteLine($"RPC Error {ex.RpcError.Code}: {ex.RpcError.Message}");
if (ex.RpcError.Data != null)
{
Console.WriteLine($"Error data: {ex.RpcError.Data}");
}
}
catch (RpcClientTimeoutException ex)
{
// Request timeout
Console.WriteLine($"Request timed out: {ex.Message}");
}
catch (RpcClientUnknownException ex)
{
// Network or other errors
Console.WriteLine($"Unknown error: {ex.Message}");
Console.WriteLine($"Inner exception: {ex.InnerException?.Message}");
}
Example 6: Authentication with Basic Auth
using Nethereum.JsonRpc.Client;
using System.Net.Http.Headers;
using System.Text;
// Option 1: URL-based authentication
var clientWithAuth = new RpcClient(
new Uri("http://username:password@localhost:8545")
);
// Option 2: Explicit AuthenticationHeaderValue
var credentials = Convert.ToBase64String(
Encoding.UTF8.GetBytes("username:password")
);
var authHeader = new AuthenticationHeaderValue("Basic", credentials);
var client = new RpcClient(
new Uri("http://localhost:8545"),
authHeaderValue: authHeader
);
var blockNumber = await client.SendRequestAsync<string>("eth_blockNumber");
Console.WriteLine($"Authenticated request successful: {blockNumber}");
Example 7: Custom Connection Timeout
ConnectionTimeout is static on ClientBase (ClientBase.cs:10) - it applies process-wide to every client instance, and its default is 20 seconds, not 120:
using Nethereum.JsonRpc.Client;
var client = new RpcClient(new Uri("http://localhost:8545"));
// Default timeout is 20 seconds, shared by every ClientBase-derived client in the process
Console.WriteLine($"Default timeout: {ClientBase.ConnectionTimeout.TotalSeconds}s");
// Set custom timeout - this changes it for ALL clients, not just this instance
ClientBase.ConnectionTimeout = TimeSpan.FromSeconds(10);
try
{
var ethBlockNumber = new EthBlockNumber(client);
var blockNumber = await ethBlockNumber.SendRequestAsync();
}
catch (RpcClientTimeoutException ex)
{
Console.WriteLine($"Request timed out after 10 seconds: {ex.Message}");
}
Example 8: Building RPC Requests
using Nethereum.JsonRpc.Client;
// Using RpcRequestBuilder
var builder = new RpcRequestBuilder("eth_getBlockByNumber");
// Build request with parameters
var request = builder.BuildRequest(
id: 1,
paramList: new object[] { "0x1b4", true }
);
Console.WriteLine($"Method: {request.Method}");
Console.WriteLine($"ID: {request.Id}");
Console.WriteLine($"Params: {string.Join(", ", request.RawParameters)}");
// Send using client
var client = new RpcClient(new Uri("http://localhost:8545"));
var result = await client.SendRequestAsync<object>(request);
Example 9: Partial Batch Success Handling
using Nethereum.JsonRpc.Client;
var client = new RpcClient(new Uri("http://localhost:8545"));
var batch = new RpcRequestResponseBatch();
// Add valid and invalid requests
var blockNumberHandler = new RpcRequestResponseHandlerNoParam<string>(client, "eth_blockNumber");
var invalidHandler = new RpcRequestResponseHandlerNoParam<string>(client, "invalid_method"); // This will fail
var chainIdHandler = new RpcRequestResponseHandlerNoParam<string>(client, "eth_chainId");
batch.BatchItems.Add(blockNumberHandler.CreateBatchItem(1));
batch.BatchItems.Add(invalidHandler.CreateBatchItem(2));
batch.BatchItems.Add(chainIdHandler.CreateBatchItem(3));
// Accept partial success
batch.AcceptPartiallySuccessful = true;
var result = await client.SendBatchRequestAsync(batch);
// Process mixed results
int successCount = 0;
int errorCount = 0;
foreach (var item in result.BatchItems)
{
if (item.HasError)
{
errorCount++;
Console.WriteLine($"Request {item.RpcRequestMessage.Id} failed: {item.RpcError.Message}");
}
else
{
successCount++;
Console.WriteLine($"Request {item.RpcRequestMessage.Id} succeeded: {item.RawResponse}");
}
}
Console.WriteLine($"Success: {successCount}, Errors: {errorCount}");
API Reference
ClientBase
Abstract base class for client implementations (ClientBase.cs:8-100). ConnectionTimeout is static - one value shared by every client instance in the process, defaulting to 20 seconds. SendAsync(RpcRequestMessage, string) is public abstract (implemented by each transport); only the batch overload is protected abstract:
public abstract class ClientBase : IClient
{
public static TimeSpan ConnectionTimeout { get; set; } = TimeSpan.FromSeconds(20.0);
public RequestInterceptor OverridingRequestInterceptor { get; set; }
public abstract Task<RpcResponseMessage> SendAsync(RpcRequestMessage rpcRequestMessage, string route = null);
protected abstract Task<RpcResponseMessage[]> SendAsync(RpcRequestMessage[] requests);
protected void HandleRpcError(RpcResponseMessage response, string reqMsg);
}
RpcRequest
Represents a JSON-RPC request:
public class RpcRequest
{
public object Id { get; set; }
public string Method { get; private set; }
public object[] RawParameters { get; private set; }
}
RpcError
Represents a JSON-RPC error. Properties are set only through the constructor (RpcError.cs):
public class RpcError
{
public RpcError(int code, string message, object data = null);
public int Code { get; private set; }
public string Message { get; private set; }
public object Data { get; private set; }
public string GetDataAsString();
}
Important Notes
Transport Implementations
This package provides abstractions only. Use concrete implementations:
| Package | Transport | Use Case |
|---|---|---|
| Nethereum.JsonRpc.RpcClient | HTTP/HTTPS | Standard node communication |
| Nethereum.JsonRpc.WebSocketClient | WebSocket | Real-time subscriptions |
| Nethereum.JsonRpc.IpcClient | IPC | Local node communication |
| Nethereum.JsonRpc.SystemTextJsonRpcClient | HTTP (System.Text.Json) | .NET 9 (net9.0 only) with System.Text.Json |
Error Types
| Exception | Description |
|---|---|
| RpcResponseException | Standard JSON-RPC error response |
| RpcClientTimeoutException | Request exceeded ConnectionTimeout |
| RpcClientUnknownException | Network or other unexpected errors |
Batch Requests
- Batch requests improve performance by reducing network round trips
- Partial success requires
AcceptPartiallySuccessful = true - Each item in the batch has independent error handling
- Request IDs must be unique within a batch
Request Interception
Use RequestInterceptor for:
- Logging all RPC requests/responses
- Performance monitoring
- Request/response transformation
- Caching layer implementation
- Authentication injection
Thread Safety
IClientimplementations should be thread-safe after initialization- Connection pooling is managed by concrete implementations (e.g., RpcClient)
- Request interceptors must be thread-safe if used concurrently
The Streaming Namespace and Custom Client Extension Points
Nethereum.JsonRpc.Client.Streaming provides the abstractions that streaming transports (e.g. Nethereum.JsonRpc.WebSocketClient) build on:
IStreamingClient-IsStarted,AddSubscription/RemoveSubscription,SendRequestAsync(RpcRequest, IRpcStreamingResponseHandler, string),StartAsync/StopAsyncIRpcStreamingResponseHandler- handles an incoming streamed response for a given request/subscription idIRpcStreamingSubscriptionHandler,IUnsubscribeSubscriptionRpcRequestBuilder- subscription lifecycle contractsSubscriptionState,StreamingEventArgs- subscription bookkeeping types
To build a custom RPC client, derive from ClientBase and implement SendAsync(RpcRequestMessage, string) and SendAsync(RpcRequestMessage[]). For custom typed RPC calls against any IClient, use the extension points this package already provides instead of writing a new handler from scratch:
// For a method that takes parameters
public class MyCustomMethod : RpcRequestResponseHandler<string>
{
public MyCustomMethod(IClient client) : base(client, "my_customMethod") { }
public Task<string> SendRequestAsync(object id, params object[] paramList)
=> base.SendRequestAsync(id, paramList);
}
// For a method that takes no parameters
public class MyCustomNoParamMethod : RpcRequestResponseHandlerNoParam<string>
{
public MyCustomNoParamMethod(IClient client) : base(client, "my_noParamMethod") { }
}
Both RpcRequestResponseHandler<TResponse> and RpcRequestResponseHandlerNoParam<TResponse> implement IRpcRequestHandler<TResponse>, decode responses via Client.DecodeResult<TResponse>, and (for the no-param case) expose CreateBatchItem(object id) to participate in batch requests.
Related Packages
Core Abstractions
- Nethereum.JsonRpc.Client - This package (abstraction layer)
Concrete Implementations
- Nethereum.JsonRpc.RpcClient - HTTP/HTTPS client (Newtonsoft.Json)
- Nethereum.JsonRpc.SystemTextJsonRpcClient - HTTP client (System.Text.Json)
- Nethereum.JsonRpc.WebSocketClient - WebSocket client
- Nethereum.JsonRpc.WebSocketStreamingClient - Streaming WebSocket client
- Nethereum.JsonRpc.IpcClient - IPC client
Used By
- Nethereum.RPC - High-level RPC services
- Nethereum.Web3 - Complete Web3 API
- All Nethereum client implementations
Additional Resources
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net451 is compatible. net452 was computed. net46 was computed. net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.5.1
- Nethereum.Hex (>= 7.0.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
.NETFramework 4.6.1
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Nethereum.Hex (>= 7.0.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
.NETStandard 2.0
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Nethereum.Hex (>= 7.0.0)
- NETStandard.Library (>= 2.0.3)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Nethereum.Hex (>= 7.0.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
net6.0
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Nethereum.Hex (>= 7.0.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Nethereum.Hex (>= 7.0.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
net9.0
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Nethereum.Hex (>= 7.0.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
NuGet packages (9)
Showing the top 5 NuGet packages that depend on Nethereum.JsonRpc.Client:
| Package | Downloads |
|---|---|
|
Nethereum.RPC
Nethereum.RPC Ethereum Core RPC Class Library to interact via RPC with an Ethereum client, for example geth. |
|
|
Nethereum.JsonRpc.RpcClient
JsonRpc Rpc Client Nethereum provider |
|
|
Nethereum.JsonRpc.WebSocketClient
Nethereum.JsonRpc WebSocketClient |
|
|
Nethereum.JsonRpc.IpcClient
Nethereum.JsonRpc IpcClient for NamedPipes and UnixSockets Class Library |
|
|
Nethereum.CoreChain
Nethereum CoreChain - Core blockchain infrastructure for state, transactions, and receipts root management |
GitHub repositories (3)
Showing the top 3 popular GitHub repositories that depend on Nethereum.JsonRpc.Client:
| Repository | Stars |
|---|---|
|
ChainSafe/web3.unity
🕹 Unity SDK for building games that interact with blockchains.
|
|
|
unoplatform/Uno.Samples
A collection of code samples for the Uno Platform
|
|
|
biheBlockChain/MyLinkToken
开源链克口袋,玩客币钱包
|
| Version | Downloads | Last Updated |
|---|---|---|
| 7.0.0 | 156 | 10/2/2026 |
| 6.1.0 | 179,104 | 3/25/2026 |
| 6.0.4 | 21,601 | 3/18/2026 |
| 6.0.3 | 2,137 | 3/18/2026 |
| 6.0.1 | 3,598 | 3/17/2026 |
| 6.0.0 | 6,414 | 3/16/2026 |
| 5.8.0 | 111,008 | 1/6/2026 |
| 5.0.0 | 483,471 | 5/28/2025 |
| 4.29.0 | 351,929 | 2/10/2025 |
| 4.28.0 | 97,678 | 1/7/2025 |
| 4.27.1 | 17,373 | 12/24/2024 |
| 4.27.0 | 10,932 | 12/24/2024 |
| 4.26.0 | 114,155 | 10/1/2024 |
| 4.25.0 | 54,972 | 9/19/2024 |
| 4.21.4 | 153,578 | 8/9/2024 |
| 4.21.3 | 14,094 | 7/22/2024 |
| 4.21.2 | 79,328 | 6/26/2024 |
| 4.21.1 | 4,659 | 6/26/2024 |
| 4.21.0 | 25,134 | 6/18/2024 |
| 4.20.0 | 414,826 | 3/28/2024 |