pub struct JsonClient { /* private fields */ }Expand description
A client for the Canton JSON Ledger API over HTTP.
Implementations§
Source§impl JsonClient
impl JsonClient
Sourcepub fn new(base_url: impl Into<String>) -> Self
pub fn new(base_url: impl Into<String>) -> Self
Create a JSON client for base_url (e.g. http://localhost:3975), with
no authentication. A trailing slash on base_url is tolerated.
Sourcepub fn from_env() -> Result<Self>
pub fn from_env() -> Result<Self>
Build a client from a local development network exported into the
environment — the JSON counterpart to Config::from_env.
eval "$(canton-devkit localnet env demo)"reads CANTON_JSON_LEDGER_API_URL and the default participant’s JWT.
See canton_core::localnet for the full contract.
§Errors
Returns Error::InvalidRequest when no JSON endpoint is exported,
naming the variable and the command that produces it. A missing token is
not an error: an unauthenticated LocalNet is a normal target.
Sourcepub fn from_env_for(role: &str) -> Result<Self>
pub fn from_env_for(role: &str) -> Result<Self>
The same, for a participant other than the default: "app-user",
"sv", or any role the exporter knows.
§Errors
As Self::from_env, naming that role’s variable.
Sourcepub fn with_timeout(self, timeout: Duration) -> Self
pub fn with_timeout(self, timeout: Duration) -> Self
How long one HTTP attempt may take (default 30s), the JSON lane’s
counterpart to Config::with_timeout.
reqwest imposes no timeout of its own, so without this a request to a
participant that accepts the connection and then goes quiet never
returns. Applied per attempt: under Self::with_retry each try gets
the full budget, matching how the gRPC channel’s timeout composes with
its retries.
The clock covers the whole exchange — connecting, sending, and reading the response body — so it is a real bound rather than a bound on the first byte.
Sourcepub fn with_max_decoding_message_size(self, bytes: usize) -> Self
pub fn with_max_decoding_message_size(self, bytes: usize) -> Self
The largest WebSocket message this client will accept, in bytes —
the JSON lane’s counterpart to Config::with_max_decoding_message_size,
and the same default.
A WS stream carries the same payloads the gRPC one does, so it needs the
same ceiling. Left alone, tungstenite applies its own: 64 MiB per
message and 16 MiB per frame, the second of which is the one a large
update meets first. Both are set from this value, so a frame is capped
only by what the caller asked for.
Does not affect the HTTP (POST) lane, which has no ceiling to raise.
Sourcepub fn with_retry(self, retry: RetryConfig) -> Self
pub fn with_retry(self, retry: RetryConfig) -> Self
Retry requests on retriable errors (category-first classification of the participant’s error body, transient HTTP statuses, connection failures) with exponential backoff, honouring a server-recommended retry delay — the same policy as the gRPC client’s unary retries. Off by default. Safe for command submission too: the command id in the body stays fixed across attempts, so the participant de-duplicates. Streaming (the WS lane) resumes via its own reconnect policy instead.
Sourcepub fn with_tls(self, tls: &TlsConfig) -> Result<Self>
pub fn with_tls(self, tls: &TlsConfig) -> Result<Self>
Use TLS for the HTTP connection: a custom CA (server-side TLS against a
private/self-signed server) and/or a client identity (mutual TLS). This
is a terminal builder step — call it last, after Self::with_token /
Self::with_oidc.
An http:// base URL is normalised to https:// so TLS is never
silently downgraded: reqwest selects TLS from the URL scheme (not from
the configured certificates), and the WebSocket lane maps http→ws /
https→wss the same way, so an http:// base URL with with_tls
would otherwise send plaintext HTTP and open a ws:// socket with the
certificates unused. Detection is case-insensitive, mirroring the gRPC
channel builder (canton-core’s resolve_endpoint).
TlsConfig::domain_name is not applied here: reqwest derives SNI
from the request URL (it is a gRPC/tonic knob).
§Errors
Returns Error::InvalidRequest if a certificate/identity PEM is
invalid or the HTTPS client cannot be built.
Sourcepub fn with_token(self, token: impl Into<String>) -> Self
pub fn with_token(self, token: impl Into<String>) -> Self
Authenticate with a fixed bearer token.
Sourcepub fn with_oidc(self, provider: TokenProvider) -> Self
pub fn with_oidc(self, provider: TokenProvider) -> Self
Authenticate with an OIDC token provider (client-credentials, auto-refresh).
Sourcepub async fn ledger_end(&self) -> Result<i64>
pub async fn ledger_end(&self) -> Result<i64>
Sourcepub async fn submit_and_wait_for_transaction(
&self,
commands: &JsonCommands,
) -> Result<JsonSubmitResponse>
pub async fn submit_and_wait_for_transaction( &self, commands: &JsonCommands, ) -> Result<JsonSubmitResponse>
Submit commands and wait for the resulting transaction
(POST /v2/commands/submit-and-wait-for-transaction).
§Errors
Returns an Error if authentication fails, the command is rejected
(surfaced as Error::Http carrying the participant’s error body), or
the response is malformed.
Sourcepub async fn submit(&self, commands: &JsonCommands) -> Result<()>
pub async fn submit(&self, commands: &JsonCommands) -> Result<()>
Submit without waiting (POST /v2/commands/async/submit): the
participant accepts the command and the outcome arrives on the
completion stream.
The gRPC lane has had this since M1. Note what a failure here means: the
command may still have committed, so reach for
Self::submission rather than this method when losing the outcome is
not acceptable.
§Errors
Returns an Error if authentication fails or the participant rejects
the submission (Error::Http with its error body).
Sourcepub async fn submit_and_wait(
&self,
commands: &JsonCommands,
) -> Result<JsonSubmitAndWaitResponse>
pub async fn submit_and_wait( &self, commands: &JsonCommands, ) -> Result<JsonSubmitAndWaitResponse>
Sourcepub async fn events_by_contract_id(
&self,
contract_id: impl Into<String>,
parties: Vec<String>,
) -> Result<Value>
pub async fn events_by_contract_id( &self, contract_id: impl Into<String>, parties: Vec<String>, ) -> Result<Value>
The create and consuming-exercise events of one contract
(POST /v2/events/events-by-contract-id), as seen by parties.
Returns the raw response object; a contract that has been pruned or is
invisible to parties comes back as a CONTRACT_EVENTS_NOT_FOUND
error rather than an empty result.
§Errors
Returns an Error if authentication or the request fails, or the
contract has no events visible to parties.
Sourcepub fn submission(&self, commands: JsonCommands) -> JsonSubmission
pub fn submission(&self, commands: JsonCommands) -> JsonSubmission
Fix a submission’s identity before sending it, returning a
JsonSubmission that carries its
ChangeId — the JSON lane’s
CantonClient::submission.
Sourcepub async fn active_contracts(
&self,
parties: Vec<String>,
active_at_offset: i64,
limit: Option<i64>,
) -> Result<Vec<Value>>
pub async fn active_contracts( &self, parties: Vec<String>, active_at_offset: i64, limit: Option<i64>, ) -> Result<Vec<Value>>
The active contract set snapshot at active_at_offset, wildcard-filtered
to parties (POST /v2/state/active-contracts).
This is a bounded read: the node caps results at
http-list-max-elements-limit and returns Error::Http 413 past it,
so pass a limit for large sets (or use the streaming transport).
Each element is raw JSON ({"workflowId": …, "contractEntry": …}).
§Errors
Returns an Error if authentication or the request fails, or the
result set exceeds the node limit (413).
Sourcepub async fn active_contracts_with(
&self,
request: &ActiveContractsRequest,
limit: Option<i64>,
) -> Result<Vec<Value>>
pub async fn active_contracts_with( &self, request: &ActiveContractsRequest, limit: Option<i64>, ) -> Result<Vec<Value>>
Like Self::active_contracts, with the full request surface of an
ActiveContractsRequest
(template/interface filters, created-event blobs, non-verbose records)
— the same builder the gRPC lane takes.
§Errors
Returns an Error if authentication or the request fails, or the
result set exceeds the node limit (413).
Sourcepub async fn updates(
&self,
parties: Vec<String>,
begin_exclusive: i64,
end_inclusive: Option<i64>,
limit: Option<i64>,
) -> Result<Vec<Value>>
pub async fn updates( &self, parties: Vec<String>, begin_exclusive: i64, end_inclusive: Option<i64>, limit: Option<i64>, ) -> Result<Vec<Value>>
Updates (transactions/reassignments) for parties in the offset range
(begin_exclusive, end_inclusive] (POST /v2/updates).
A bounded read like Self::active_contracts: bound it with
end_inclusive and/or limit, or the node returns Error::Http
413. Each element is raw JSON ({"update": …}), including
OffsetCheckpoint heartbeats.
§Errors
Returns an Error if authentication or the request fails, or the
result set exceeds the node limit (413).
Sourcepub async fn updates_with(
&self,
request: &UpdatesRequest,
limit: Option<i64>,
) -> Result<Vec<Value>>
pub async fn updates_with( &self, request: &UpdatesRequest, limit: Option<i64>, ) -> Result<Vec<Value>>
Like Self::updates, with the full request surface of an
UpdatesRequest (bounds, template/
interface filters, transaction shape, created-event blobs, topology
events, non-verbose records) — the same builder the gRPC lane takes.
§Errors
Returns an Error if authentication or the request fails, or the
result set exceeds the node limit (413).
Source§impl JsonClient
impl JsonClient
Sourcepub async fn ws_updates(
&self,
parties: Vec<String>,
begin_exclusive: i64,
end_inclusive: Option<i64>,
) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
Available on crate feature ws only.
pub async fn ws_updates( &self, parties: Vec<String>, begin_exclusive: i64, end_inclusive: Option<i64>, ) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
ws only.Stream updates over WebSocket (feature ws) for parties, starting after
begin_exclusive. With end_inclusive the stream is bounded and closes
once the range is exhausted; without it the stream tails live. Each item
is a raw JSON update ({"update": …}); OffsetCheckpoint heartbeats are
filtered out (as in the gRPC CantonClient::updates).
Unlike Self::updates, this is not capped by the node’s list limit. For
automatic reconnection use Self::ws_updates_resumable.
§Errors
Returns an Error if the handshake fails; the stream yields Err on a
participant error frame or a transport failure.
Sourcepub async fn ws_updates_with(
&self,
request: &UpdatesRequest,
) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
Available on crate feature ws only.
pub async fn ws_updates_with( &self, request: &UpdatesRequest, ) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
ws only.Like Self::ws_updates, with the full request surface of an
UpdatesRequest — the same builder
the gRPC lane takes (bounds, filters, shape, blobs, topology events,
non-verbose records).
§Errors
Returns an Error if the handshake fails; the stream yields Err on
a participant error frame or a transport failure.
Sourcepub async fn ws_active_contracts(
&self,
parties: Vec<String>,
active_at_offset: i64,
) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
Available on crate feature ws only.
pub async fn ws_active_contracts( &self, parties: Vec<String>, active_at_offset: i64, ) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
ws only.Stream the active contract set snapshot at active_at_offset over
WebSocket (feature ws), wildcard-filtered to parties. The stream
closes when the snapshot is fully delivered. Each item is raw JSON
({"workflowId": …, "contractEntry": …}).
Unlike Self::active_contracts, this is not capped by the node’s list
limit.
§Errors
Returns an Error if the handshake fails; the stream yields Err on a
participant error frame or a transport failure.
Sourcepub async fn ws_active_contracts_with(
&self,
request: &ActiveContractsRequest,
) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
Available on crate feature ws only.
pub async fn ws_active_contracts_with( &self, request: &ActiveContractsRequest, ) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
ws only.Like Self::ws_active_contracts, with the full request surface of an
ActiveContractsRequest —
the same builder the gRPC lane takes.
§Errors
Returns an Error if the handshake fails; the stream yields Err on
a participant error frame or a transport failure.
Sourcepub async fn ws_completions(
&self,
parties: Vec<String>,
begin_exclusive: i64,
) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
Available on crate feature ws only.
pub async fn ws_completions( &self, parties: Vec<String>, begin_exclusive: i64, ) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
ws only.Stream command completions over WebSocket (feature ws) for parties,
starting after begin_exclusive. Each item is a raw JSON completion;
OffsetCheckpoint heartbeats are filtered out.
§Errors
Returns an Error if the handshake fails; the stream yields Err on a
participant error frame or a transport failure.
Sourcepub async fn ws_completions_with(
&self,
request: &CompletionsRequest,
) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
Available on crate feature ws only.
pub async fn ws_completions_with( &self, request: &CompletionsRequest, ) -> Result<impl Stream<Item = Result<Value>> + Send + use<>>
ws only.Like Self::ws_completions, with the full request surface of a
CompletionsRequest — including
the submitting user_id to scope the stream to (the same builder the
gRPC lane takes).
§Errors
Returns an Error if the handshake fails; the stream yields Err on
a participant error frame or a transport failure.
Sourcepub fn ws_active_contracts_resumable(
&self,
parties: Vec<String>,
active_at_offset: i64,
) -> impl Stream<Item = Result<Value>> + Send + use<>
Available on crate feature ws only.
pub fn ws_active_contracts_resumable( &self, parties: Vec<String>, active_at_offset: i64, ) -> impl Stream<Item = Result<Value>> + Send + use<>
ws only.Like Self::ws_active_contracts, but resumable: on a retriable
disconnect it resubscribes from the last continuation token the
participant sent, rather than starting the snapshot again.
An ACS snapshot has no offsets to resume from — it is a position in a
stream of entries, which is what streamContinuationToken names. The
gRPC lane has had a resumable ACS read since M1; this is its counterpart,
and without it a WebSocket consumer of a large snapshot had to start over
on any blip.
The token is only valid against the same participant, the same
active_at_offset and the same filters — all of which are fixed for the
life of this stream — and while the snapshot’s offset has not been
pruned.
Sourcepub fn ws_updates_resumable(
&self,
parties: Vec<String>,
begin_exclusive: i64,
) -> impl Stream<Item = Result<Value>> + Send + use<>
Available on crate feature ws only.
pub fn ws_updates_resumable( &self, parties: Vec<String>, begin_exclusive: i64, ) -> impl Stream<Item = Result<Value>> + Send + use<>
ws only.Like Self::ws_updates (unbounded tail), but resumable: on a
retriable disconnect it reconnects from the last offset it observed
(tracked via OffsetCheckpoint heartbeats and update offsets), with a
short backoff and a bounded number of consecutive reconnects. Mirrors the
gRPC CantonClient::updates_resumable. Checkpoints are consumed for
position tracking and not yielded.
Trait Implementations§
Source§impl Clone for JsonClient
impl Clone for JsonClient
Source§fn clone(&self) -> JsonClient
fn clone(&self) -> JsonClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for JsonClient
Hand-written for the same reason Config’s is: a base URL can carry
credentials in its userinfo (https://user:secret@host), and the derived
Debug printed them verbatim — one tracing field holding a client, or one
{:?} in a log line, was enough.
impl Debug for JsonClient
Hand-written for the same reason Config’s is: a base URL can carry
credentials in its userinfo (https://user:secret@host), and the derived
Debug printed them verbatim — one tracing field holding a client, or one
{:?} in a log line, was enough.
The reqwest client is left out entirely — finish_non_exhaustive says so
rather than pretending otherwise — because its internals describe a
connection pool, not this client.
Auto Trait Implementations§
impl !RefUnwindSafe for JsonClient
impl !UnwindSafe for JsonClient
impl Freeze for JsonClient
impl Send for JsonClient
impl Sync for JsonClient
impl Unpin for JsonClient
impl UnsafeUnpin for JsonClient
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request