Class MirrorGrpcClient
Hedera Network Mirror Streaming Client
Implements
Inherited Members
Namespace: Hiero
Assembly: Hiero.dll
Syntax
public sealed class MirrorGrpcClient : IAsyncDisposable
Remarks
This client facilitates access to the Hedera Mirror Network HCS streaming service. It is used to subscribe to a topic and forward the messages returned by the mirror node in near real-time to a .NET channel for processing.
Thread safety. An instance is safe for concurrent use and is intended to be shared — a singleton registered with dependency injection is the expected pattern. Each operation builds its own child context, so concurrent calls share no mutable state, and the underlying gRPC channels are pooled in a thread-safe cache.
Configure(Action<IMirrorGrpcContext>) is the exception. It mutates this instance's own
context in place, which every in-flight operation reads through, and is
meant for setup before the client is used or while it is otherwise idle.
To vary settings on a live client, pass the per-call configure
argument — it applies only to that one call — or take a separately
configured instance with Clone(Action<IMirrorGrpcContext>?).
Constructors
| Edit this page View SourceMirrorGrpcClient(Action<IMirrorGrpcContext>?)
Creates a new instance of a Hedera Mirror Network MirrorGrpcClient.
Declaration
public MirrorGrpcClient(Action<IMirrorGrpcContext>? configure = null)
Parameters
| Type | Name | Description |
|---|---|---|
| Action<IMirrorGrpcContext> | configure | Optional configuration method that can set the location of the network node accessing the network. |
Remarks
Creating a new instance of a
MirrorGrpcClient
initializes a new instance of a client. It will have a separate cache of GRPC channels to the network and will maintain a separate configuration from other clients. The constructor takes an optional callback method that configures the details on how the client should connect to the network configurable details. See the IMirrorGrpcContext documentation for configuration details.
MirrorGrpcClient(Func<Uri, GrpcChannel>, Action<IMirrorGrpcContext>?)
Creates a new instance of a Hedera Mirror Network MirrorGrpcClient with a custom gRPC channel factory.
Declaration
public MirrorGrpcClient(Func<Uri, GrpcChannel> channelFactory, Action<IMirrorGrpcContext>? configure = null)
Parameters
| Type | Name | Description |
|---|---|---|
| Func<Uri, GrpcChannel> | channelFactory | A custom callback method returning a new channel given the target mirror node URI. Note, this method is only called once for each unique URI requested by the mirror grpc client (which is a function of the current context's URI parameter) |
| Action<IMirrorGrpcContext> | configure | Optional configuration method that can set the location of the network node accessing the network. |
Remarks
Creating a new instance of a
MirrorGrpcClient
initializes a new instance of a client. It will have a separate cache of GRPC channels to the network and will maintain a separate configuration from other clients. The constructor takes an optional callback method that configures the details on how the client should connect to the network configurable details. See the IMirrorGrpcContext documentation for configuration details.
Methods
| Edit this page View SourceClone(Action<IMirrorGrpcContext>?)
Creates a new instance of the mirror client having a shared base configuration with its parent. Changes to the parent’s configuration will reflect in this instances configuration while changes in this instances configuration will not be reflected in the parent configuration.
Declaration
public MirrorGrpcClient Clone(Action<IMirrorGrpcContext>? configure = null)
Parameters
| Type | Name | Description |
|---|---|---|
| Action<IMirrorGrpcContext> | configure | The callback method receiving the IMirrorGrpcContext object providing the configuration details of this client instance. Values can be retrieved and set within the context of the method invocation. |
Returns
| Type | Description |
|---|---|
| MirrorGrpcClient | A new instance of a client object. |
Configure(Action<IMirrorGrpcContext>)
Updates the configuration of this instance of a mirror client through implementation of the supplied IMirrorGrpcContext callback method.
Declaration
public void Configure(Action<IMirrorGrpcContext> configure)
Parameters
| Type | Name | Description |
|---|---|---|
| Action<IMirrorGrpcContext> | configure | The callback method receiving the IMirrorGrpcContext object providing the configuration details of this client instance. Values can be retrieved and set within the context of the method invocation. |
Remarks
Mutates this client's own context in place. Every operation already in
flight reads its inherited settings through that context, so calling
this concurrently with active work can let a call observe a partially
applied configuration. Configure before use, or while the client is
idle. For a live client, prefer the per-call configure argument
(scoped to that call alone) or Clone(Action<IMirrorGrpcContext>?) for a separately
configured instance.
DisposeAsync()
.NET Asynchronous dispose method.
Declaration
public ValueTask DisposeAsync()
Returns
| Type | Description |
|---|---|
| ValueTask | An Async Task. |
Remarks
Closes any GRPC channels solely owned by this
MirrorGrpcClient
instance.
SubscribeTopicAsync(SubscribeTopicParams, Action<IMirrorGrpcContext>?)
Subscribes to a Topics Stream from a mirror node, placing the topic messages returned meeting the query criteria into the provided .net Channel.
Declaration
public Task SubscribeTopicAsync(SubscribeTopicParams subscribeParameters, Action<IMirrorGrpcContext>? configure = null)
Parameters
| Type | Name | Description |
|---|---|---|
| SubscribeTopicParams | subscribeParameters | The details of the query, including the id of the topic, time constraint filters and the .net channel receiving the messages as they are returned from the server. |
| Action<IMirrorGrpcContext> | configure | Optional callback method providing an opportunity to modify the execution configuration for just this method call. It is executed prior to submitting the request to the mirror node. |
Returns
| Type | Description |
|---|---|
| Task | Returns only after one of the four conditions occur: the output channel is completed by calling code; the cancellation token provided in the params is signaled; the maximum number of topic messages was returned as configured in the params; or if the mirror stream faults during streaming, in which case a MirrorGrpcException is thrown. |
Examples
Live stream from the current time forward — reads keep pace with the
incoming mirror messages via a Channel:
await using var stream = new MirrorGrpcClient(ctx =>
{
ctx.Uri = new Uri(mirrorEndpoint);
});
var channel = Channel.CreateUnbounded<TopicMessage>();
var topic = new EntityId(0, 0, topicNum);
Console.WriteLine($"Subscribing to topic 0.0.{topicNum}...");
Console.WriteLine("Waiting for messages (Ctrl+C to stop)...");
// Start subscription in the background. Messages arrive via channel.Writer
// so this task runs independently of the consumer loop below.
var subscribeTask = stream.SubscribeTopicAsync(new SubscribeTopicParams
{
Topic = topic,
MessageWriter = channel.Writer,
Starting = ConsensusTimeStamp.MinValue,
MaxCount = maxMessages,
CancellationToken = cts.Token
});
// Read messages as they arrive
try
{
await foreach (var msg in channel.Reader.ReadAllAsync(cts.Token))
{
var text = Encoding.UTF8.GetString(msg.Message.Span);
Console.WriteLine($"[Seq {msg.SequenceNumber}] {msg.Consensus}: {text}");
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Subscription cancelled.");
}
await subscribeTask;
Replay a bounded historical time range instead of tailing:
// Subscribe to a bounded time range of messages — the subscription
// call returns as soon as `Ending` is reached. Useful for backfilling
// historical messages without streaming indefinitely.
var channel = Channel.CreateUnbounded<TopicMessage>();
var subscribe = mirror.SubscribeTopicAsync(new SubscribeTopicParams
{
Topic = topic,
Starting = startInclusive,
Ending = endExclusive,
MessageWriter = channel.Writer
});
await foreach (var msg in channel.Reader.ReadAllAsync())
{
Console.WriteLine(
$"[{msg.SequenceNumber}] {msg.Consensus}: " +
Encoding.UTF8.GetString(msg.Message.Span));
}
await subscribe;
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | If required arguments are missing. |
| ArgumentOutOfRangeException | If the ending time is before the starting time. |
| InvalidOperationException | If required context configuration is missing. |
| MirrorGrpcException | If the mirror node stream faulted during request processing or upon submission. |