Guardian Client
A minimal Rust client library for interacting with the Guardian gRPC service.
API Reference
Client Creation
use Arc;
use SecretKey;
use ;
// Without authentication (only for configure endpoint)
let client = connect.await?;
// With request signing (required for all other endpoints)
let secret_key = new;
let signer = new;
let client = connect
.await?
.with_signer;
Abandoning a Stuck Candidate
If an approved transaction dies client-side after guardian approval (RPC
submit failure, prover timeout, crash), its candidate delta keeps the
account locked — new proposals are answered 409 conflict_pending_delta —
until the server's grace period and retry budget run out. Only the client
knows the transaction will never land:
// Records an abandon intent; the guardian's worker confirms over a short
// quarantine that the tx did not land, then releases the account.
let response = client.abandon_candidate.await?;
assert_eq!;
// Poll the delta for the resolution: still `candidate` -> waiting,
// `canonical` -> the tx landed after all, `discarded` with reason
// `client_abandoned` -> the account is released.
let delta = client.get_delta.await?;
Rate Limits and Retries
The server rate-limits both its gRPC and HTTP surfaces. The sustained
per-minute limit is keyed per IP alone, so gRPC and HTTP calls from one
client draw on the same allowance; the burst limit is keyed per IP and
method. An over-budget call fails with ResourceExhausted, code
rate_limit_exceeded, and a backoff hint. ClientError classifies it:
is_retryable() reads the error envelope (falling back to the status-code
class), and retry_after() returns the server's hint, preferring the
retry-after status metadata over the envelope value.
Rate-limit rejections happen before the server touches any state, so retrying them is always safe. The client does not retry automatically (automatic backoff is tracked in #360); a bounded loop over the exposed hint is a few lines:
let max_attempts = 3;
let mut attempts = 0;
let state = loop ;
Retries are idempotent (the original request timestamp is preserved). The
server refuses with GUARDIAN_CANDIDATE_LANDED when the transaction
demonstrably landed.
Authentication
The client uses Falcon Poseidon2 signatures for authenticated requests. Here is how to set it up:
1. Create a Signer
use Arc;
use SecretKey;
use FalconKeyStore;
// Generate a new secret key
let secret_key = new;
let signer = new;
// Get the public key for authorization
let pubkey_hex = signer.public_key_hex;
2. Configure Client with Signer
let client = connect
.await?
.with_signer;
3. Set Up Account Authorization
use auth;
// Add the public key to the account's authorized cosigners
let auth_config = miden_falcon_rpo_auth;
Server Signature Verification
After pushing a delta, the server returns an Acknowledgment signature that signs the new commitment. You should verify this signature to ensure the server is signing with the expected public key.
use verify_commitment_signature;
let push_response = client.push_delta.await?;
if let Some = &push_response.delta
The server signs the new_commitment (the resulting commitment after applying the delta) to provide cryptographic proof that it processed the delta correctly.
Example