Skip to main content

CantonClient

Struct CantonClient 

Source
pub struct CantonClient { /* private fields */ }
Expand description

An async client for the Canton Ledger API over gRPC.

The client owns a lazily-connected Channel; cloning it is cheap and clones share the underlying connection pool, so it is safe to hand a clone to each task.

Implementations§

Source§

impl CantonClient

Source

pub fn connect_lazy(config: Config) -> Result<Self>

Build a lazily-connected client. Returns immediately; the TCP/TLS handshake happens on the first RPC.

§Errors

Returns Error::InvalidRequest if the endpoint is not a valid URI.

Source

pub async fn version(&self) -> Result<String>

Return the participant’s Ledger API version string (e.g. "3.5.7").

§Errors

Returns an Error if the RPC fails.

Source

pub async fn health_check(&self) -> Result<ServingStatus>

Probe the participant’s overall serving status via the standard grpc.health.v1.Health service (served on the Ledger API port).

Poll this to react to intermittent or permanent node failure: a healthy participant answers ServingStatus::Serving; an unreachable one surfaces a transport Error (see Error::is_retriable).

§Errors

Returns an Error if the health RPC fails (e.g. the node is down).

Source

pub async fn submit(&self, submit: Submit) -> Result<String>

Submit commands fire-and-forget (CommandSubmissionService.Submit): hand the commands to the participant and return promptly without waiting for the transaction. Returns the change-ID command_id used, so the caller can recover the outcome later with Self::await_completion (or the Self::completions stream).

A fresh UUID command_id is generated when the caller did not set one, so ledger-side de-duplication behaves correctly across retries.

§Errors

Returns an Error if authentication fails or the participant rejects the submission synchronously (e.g. a preprocessing error).

Source

pub fn submission(&self, submit: Submit) -> Submission

Fix a submission’s identity before sending it, returning a Submission that carries its ChangeId.

This is the handle to reach for when losing the outcome is not an option. A submission whose response is lost — a dropped connection, a timeout, a retry the participant de-duplicated — may well have committed, and the only way back to the answer is the change ID. If the SDK generated the command id inside the call that failed, there is no change ID to go back with.

use std::time::Duration;

// Where to start reading completions from, taken before submitting.
let offset = client.ledger_end().await?;
let submission = client.submission(submit);

if submission.submit_and_wait().await.is_err() {
    // Ambiguous: ask the ledger what actually happened.
    let completion = submission.recover(offset, Duration::from_secs(30)).await?;
    println!("committed after all: {}", completion.update_id);
}
Source

pub async fn submit_and_wait( &self, submit: Submit, ) -> Result<SubmitAndWaitResponse>

Submit commands and wait for the result without fetching the transaction (CommandService.SubmitAndWait): blocks until the command commits (or is rejected) and returns the update_id and completion offset. Lighter than Self::submit_and_wait_for_transaction when the caller does not need the event payload.

§Errors

Returns an Error if authentication fails or the command is rejected. The retry caveat on Self::submit_and_wait_for_transaction applies.

Source

pub async fn submit_and_wait_for_transaction( &self, submit: Submit, ) -> Result<Transaction>

Submit commands and wait for the resulting transaction.

Fills the change ID’s command_id with a fresh UUID when the caller did not set one, so ledger-side de-duplication behaves correctly. The returned transaction is shaped as LEDGER_EFFECTS and filtered to the acting party (wildcard), so created events are visible in the response.

§Errors

Returns an Error if authentication fails, the command is rejected, or the response contains no transaction.

§Example
use canton_ledger::{Submit, create, identifier, record};

let tx = client
    .submit_and_wait_for_transaction(
        Submit::new(party)
            .add_command(create(identifier(pkg, "M", "T"), record(vec![]))),
    )
    .await?;
println!("committed {} at offset {}", tx.update_id, tx.offset);
§Retry caveat (exactly-once)

With retry enabled (Config::with_retry), a submission that commits on the ledger but whose response is lost to a retriable error is re-sent with the same command_id and de-duplicated by the participant.

Self::submit can answer that on its own: a duplicate rejection of a retry it made itself means its earlier attempt was accepted, which is success, so it reports success. This method cannot. Its result is the committed transaction, and a de-duplicated retry does not carry one — so the duplicate rejection reaches the caller, and the transaction has to be read back rather than invented.

Take a Submission from Self::submission before submitting, and on any error recover the outcome with Submission::recover — it knows the change ID, which is the only way back to a command whose response was lost. See the recover_a_submission example.

Source

pub async fn completions( &self, parties: Vec<String>, begin_offset: i64, ) -> Result<impl Stream<Item = Result<Completion>> + Send + use<>>

Subscribe to the command-completion stream for parties, starting after begin_offset (exclusive). Offset checkpoints are filtered out, so the stream yields only pb::Completions.

§Errors

Returns an Error if authentication or opening the stream fails.

Source

pub async fn completions_with( &self, request: CompletionsRequest, ) -> Result<impl Stream<Item = Result<Completion>> + Send + use<>>

Like Self::completions, with the full request surface: a CompletionsRequest additionally selects the user_id whose command completions to stream (pair it with Submit::with_user_id).

§Errors

Returns an Error if authentication or opening the stream fails.

Source

pub async fn await_completion( &self, change_id: &ChangeId, begin_offset: i64, timeout: Duration, ) -> Result<Completion>

Recover the completion for a specific command by scanning the completion stream from begin_offset, up to timeout.

This is the command-recovery path: after a crash, lost connection, or timeout, the outcome of a pending command is read back from the completion endpoint instead of blindly re-submitting. If the command’s completion reports a non-OK status, this returns Error::CommandRejected.

Matching is on the whole ChangeId — user, acting parties and command id — because that is what identifies a command to Canton. A command id on its own is not unique across the users of a participant, and answering with somebody else’s completion is worse than answering with none.

The completion stream is a live subscription that does not self-terminate, so timeout bounds how long to wait for the target completion.

§Errors

Returns Error::Timeout if the completion is not seen within timeout, Error::CommandRejected if the ledger rejected the command, or another Error if the stream fails.

Source

pub async fn ledger_end(&self) -> Result<i64>

Return the current ledger end offset as seen by the participant.

A value of 0 means the participant’s view of the ledger is empty. This is an authenticated endpoint.

§Errors

Returns an Error if authentication or the RPC fails.

Source

pub async fn events_by_contract_id( &self, contract_id: impl Into<String>, parties: Vec<String>, ) -> Result<GetEventsByContractIdResponse>

Fetch the created and/or archived events for a contract by id (EventQueryService.GetEventsByContractId), with verbose records and no created-event blob. To obtain a contract’s created_event_blob (for disclosure), use a template-filtered Self::active_contracts_with read with ActiveContractsRequest::with_created_event_blobs.

§Errors

Returns an Error if authentication or the RPC fails.

Source

pub async fn active_contracts_page( &self, parties: Vec<String>, active_at_offset: i64, max_page_size: i32, page_token: Option<Vec<u8>>, ) -> Result<(Vec<ActiveContract>, Option<Vec<u8>>)>

Fetch one page of the Active Contract Set for parties as of active_at_offset. Returns the page’s active contracts and the next page token (None once the last page has been read); pass the token back in to fetch the following page.

§Errors

Returns an Error if authentication or the RPC fails.

Source

pub async fn active_contracts_page_with( &self, request: &ActiveContractsRequest, max_page_size: i32, page_token: Option<Vec<u8>>, ) -> Result<(Vec<ActiveContract>, Option<Vec<u8>>)>

Like Self::active_contracts_page, with the full request surface of an ActiveContractsRequest (template/interface filters, created-event blobs, non-verbose records).

§Errors

Returns an Error if authentication or the RPC fails.

Source

pub async fn acs_page( &self, parties: Vec<String>, active_at_offset: i64, max_page_size: i32, page_token: Option<Vec<u8>>, ) -> Result<(Vec<AcsEntry>, Option<Vec<u8>>)>

One page of the Active Contract Set for parties, losslessly: every entry the participant sent, active or incomplete (see AcsEntry).

§Errors

Returns an Error if authentication or the RPC fails.

Source

pub async fn acs_page_with( &self, request: &ActiveContractsRequest, max_page_size: i32, page_token: Option<Vec<u8>>, ) -> Result<(Vec<AcsEntry>, Option<Vec<u8>>)>

Like Self::acs_page, with the full request surface of an ActiveContractsRequest.

§Errors

Returns an Error if authentication or the RPC fails.

Source

pub async fn updates_page( &self, parties: Vec<String>, begin_offset_exclusive: i64, end_offset_inclusive: i64, max_page_size: i32, descending: bool, page_token: Option<Vec<u8>>, ) -> Result<(Vec<GetUpdateResponse>, Option<Vec<u8>>)>

Fetch one page of updates in the offset range (begin_offset_exclusive, end_offset_inclusive], optionally in reverse (descending) order. Returns the page items and the next page token (None once the last page has been read).

§Errors

Returns an Error if authentication or the RPC fails.

Source

pub async fn updates_page_with( &self, request: &UpdatesRequest, max_page_size: i32, page_token: Option<Vec<u8>>, ) -> Result<(Vec<GetUpdateResponse>, Option<Vec<u8>>)>

Like Self::updates_page, with the full request surface of an UpdatesRequest (template/interface filters, transaction shape, descending order, created-event blobs, topology events, non-verbose records). The request’s bounds supply the page range, so UpdatesRequest::until is required here — the paged read is inherently bounded.

§Errors

Returns Error::InvalidRequest if the request has no end offset, or another Error if authentication or the RPC fails.

Source

pub async fn active_contracts( &self, parties: Vec<String>, active_at_offset: i64, ) -> Result<impl Stream<Item = Result<ActiveContract>> + Send + use<>>

Stream the Active Contract Set for parties as of active_at_offset (typically the current ledger end). Yields the active contracts, wildcard-filtered to the given parties.

§Errors

Returns an Error if authentication or opening the stream fails.

Source

pub async fn active_contracts_with( &self, request: ActiveContractsRequest, ) -> Result<impl Stream<Item = Result<ActiveContract>> + Send + use<>>

Like Self::active_contracts, with the full request surface: an ActiveContractsRequest additionally filters by template or interface, includes created-event blobs, and drops record labels.

§Errors

Returns an Error if authentication or opening the stream fails.

Source

pub async fn acs_entries( &self, parties: Vec<String>, active_at_offset: i64, ) -> Result<impl Stream<Item = Result<AcsEntry>> + Send + use<>>

Stream the Active Contract Set for parties losslessly: every entry the participant sends, active or incomplete (see AcsEntry).

§Errors

Returns an Error if authentication or opening the stream fails.

Source

pub async fn acs_entries_with( &self, request: ActiveContractsRequest, ) -> Result<impl Stream<Item = Result<AcsEntry>> + Send + use<>>

Like Self::acs_entries, with the full request surface of an ActiveContractsRequest.

§Errors

Returns an Error if authentication or opening the stream fails.

Source

pub fn active_contracts_resumable( &self, parties: Vec<String>, active_at_offset: i64, max_page_size: i32, ) -> impl Stream<Item = Result<ActiveContract>> + Send + use<>

Like Self::active_contracts, but resumable: reads the ACS snapshot page-by-page (continuation tokens), retrying a failed page on retriable errors from the last token instead of restarting the snapshot from zero. max_page_size bounds each page RPC.

Source

pub fn active_contracts_resumable_with( &self, request: ActiveContractsRequest, max_page_size: i32, ) -> impl Stream<Item = Result<ActiveContract>> + Send + use<>

Like Self::active_contracts_resumable, with the full request surface of an ActiveContractsRequest.

Source

pub fn acs_entries_resumable( &self, parties: Vec<String>, active_at_offset: i64, max_page_size: i32, ) -> impl Stream<Item = Result<AcsEntry>> + Send + use<>

Like Self::acs_entries, but resumable and page-based: reads the snapshot page by page and retries a failed page from the last continuation token instead of restarting from zero. Every entry the participant sent is yielded (see AcsEntry).

Source

pub fn acs_entries_resumable_with( &self, request: ActiveContractsRequest, max_page_size: i32, ) -> impl Stream<Item = Result<AcsEntry>> + Send + use<>

Like Self::acs_entries_resumable, with the full request surface of an ActiveContractsRequest.

Source

pub async fn updates( &self, parties: Vec<String>, begin_offset: i64, ) -> Result<impl Stream<Item = Result<Update>> + Send + use<>>

Stream ledger updates — transactions and reassignments — for parties, starting after begin_offset (exclusive). Offset checkpoints are filtered out. Reassignments are surfaced as their own case (each carrying the distinct Unassigned/Assigned events). Topology events are not included; ask for them with UpdatesRequest::with_topology_events on Self::updates_with.

§Errors

Returns an Error if authentication or opening the stream fails.

Source

pub async fn updates_with( &self, request: UpdatesRequest, ) -> Result<impl Stream<Item = Result<Update>> + Send + use<>>

Like Self::updates, with the full request surface: an UpdatesRequest additionally bounds the stream at an end offset (until — the catch-up/sync form, after which the stream terminates), filters by template or interface, selects the ACS-delta shape, includes created-event blobs or topology events, and drops reassignments or record labels.

§Errors

Returns an Error if authentication or opening the stream fails.

Source

pub fn updates_resumable( &self, parties: Vec<String>, begin_offset: i64, ) -> impl Stream<Item = Result<Update>> + Send + use<>

Like Self::updates, but resumable: on a retriable stream error it reconnects from the last offset it observed (rather than restarting from begin_offset or losing position), with a short backoff and a bounded number of consecutive reconnects (see the client’s RetryConfig).

Observed includes the participant’s OffsetCheckpoint frames, which are filtered out of what this yields but are the only thing that advances the resume point on a stream where nothing is happening. Once the reconnect budget is spent the stream yields the failure that caused it — the participant’s status, details and retriable classification intact — rather than an error of the SDK’s own.

§Example
use tokio_stream::StreamExt as _;

let stream = client.updates_resumable(vec![party], 0);
tokio::pin!(stream);
while let Some(update) = stream.next().await {
    println!("update: {:?}", update?);
}
Source

pub fn updates_resumable_with( &self, request: UpdatesRequest, ) -> impl Stream<Item = Result<Update>> + Send + use<>

Like Self::updates_resumable, with the full request surface of an UpdatesRequest. A bounded request (until) makes this a resilient catch-up read: reconnects resume from the last observed offset, and the stream ends once the participant closes it at the end offset.

Trait Implementations§

Source§

impl Clone for CantonClient

Source§

fn clone(&self) -> CantonClient

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CantonClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more