Skip to main content

Client

Struct Client 

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

HTTP client for communicating with the Real Markets matching engine.

The Client provides a simple interface for sending transactions and querying the matching engine via JSON-RPC over HTTP. It handles serialization, network communication, and response parsing automatically.

§Examples

use sdk::Client;

// Create a new client
let client = Client::new("https://matching.api.testnet.real.xyz")?;

// Read the engine's health snapshot: heights and unix-ms timestamps
let health = client.healthcheck().await?;

// Get the service version
let version = client.get_version().await?;

Implementations§

Source§

impl Client

Source

pub fn new(url: impl AsRef<str>) -> Result<Client>

Creates a new client instance for the Real Markets matching engine.

This method establishes a connection to the matching engine’s JSON-RPC API endpoint. The client uses HTTP transport and handles connection pooling and request/response serialization automatically.

§Arguments
§Returns
  • Ok(Client) - Successfully created client instance
  • Err(_) - Failed to create HTTP client (usually due to invalid URL format)
§Examples
use sdk::Client;

// Create a client for testnet
let client = Client::new("https://matching.api.testnet.real.xyz")?;

// Create a client for local development
let local_client = Client::new("http://localhost:1789")?;
§Errors

This method will return an error if:

  • The URL format is invalid
  • The HTTP client cannot be initialized
Source

pub async fn send_transaction( &self, tx: Transaction, ) -> Result<TransactionReport>

Sends a signed transaction to the matching engine for processing.

This is the primary method for submitting orders, cancellations, and other operations to the matching engine. The transaction must be properly signed before submission.

§Arguments
  • tx - A signed Transaction containing one or more commands (orders, cancellations, etc.)
§Returns
  • Ok(TransactionReport) - The engine returned a verdict. That includes rejection: an admission failure (bad signature, stale or reused nonce, chain-id mismatch, rate limit, per-command validation) arrives from the node as a JSON-RPC error carrying a TransactionReport in its data, and this method unwraps it into Ok. Always check report.success — an Ok here is not an acceptance.
  • Err(_) - No verdict at all: transport failure, or a node-level error with no report attached (sequencer not ready, ingress disabled, internal error, or an admitted transaction whose outcome execution never reported)
§Examples
use sdk::{
    Client,
    crypto::Signer,
    types::{SubmitOrderRequest, Transaction, TransactionPayload},
};

let client = Client::new("https://matching.api.testnet.real.xyz")?;
let signer: Signer =
    "iotaprivkey1qrsd2u9ztqr6z2y78sp2ch8kcyak9cx3ezphkpp4acqaqruajxr6qye2645".into();

// `chain_id` must be the one the endpoint reports (`real-t-0001` on
// testnet) and `nonce` microseconds since the Unix epoch — admission
// rejects a mismatched chain id and a nonce outside its replay window
let payload = TransactionPayload::builder()
    .nonce(1_757_000_000_000_000)
    .chain_id("real-t-0001")
    .command(
        SubmitOrderRequest::builder()
            .market("0x5efc5ad00c209baf4c5d77dfd1be18e8b50916e53adbe2142ae1b47af445303c")
            .account("0xcc6ebf909253ea35314bb28d91321f6415827c01790fba84aaf570c87372850a")
            .buy()
            .limit_order("50000.00")
            .quantity("0.1")
            .good_till_cancel()
            .build()?,
    )
    .build()?;

let transaction = Transaction::builder()
    .client_request_id("unique-id")
    .payload(payload)
    .sign_and_build(signer)?;

// a rejected transaction also arrives as `Ok`; check `report.success`
let report = client.send_transaction(transaction).await?;
println!("Transaction result: {:?}", report);
§Errors

This method will return an error if:

  • Network connection fails
  • Request times out
  • Response cannot be parsed
  • The node answered with an error that carried no TransactionReport

A transaction the engine rejects is not an error here: it comes back as Ok(report) with report.success == false.

Source

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

Retrieves the version information of the matching engine.

This method queries the matching engine to get its current version string, which is useful for compatibility checking and debugging.

§Returns
  • Ok(String) - The version string of the matching engine
  • Err(_) - Network error or failed to parse response
§Examples
use sdk::Client;

let client = Client::new("https://matching.api.testnet.real.xyz")?;
let version = client.get_version().await?;
println!("Matching engine version: {}", version);
§Errors

This method will return an error if:

  • Network connection fails
  • The matching engine is unreachable
  • Response format is unexpected
  • Request times out
Source

pub async fn get_chain_id(&self) -> Result<&str>

Retrieves the chain_id this endpoint expects in signed transaction payloads.

The value is fixed for the life of a network, so it is fetched from the node once on the first call and cached for the life of the client. The cache is shared by every clone of this client, so many crate::SigningClients built on one Client cost a single round-trip between them.

Prefer letting crate::SigningClient resolve this for you — build it without a chain_id and it will call this on first submission.

§Examples
use sdk::Client;

let client = Client::new("https://matching.api.testnet.real.xyz")?;
let chain_id = client.get_chain_id().await?;
println!("signing against: {}", chain_id);
§Errors

This method will return an error if the node is unreachable or the response cannot be parsed. A failed lookup is not cached — the next call retries.

Source

pub async fn verify_chain_id(&self, expected: &str) -> Result<()>

Asserts this endpoint is the network expected names.

Pointing a client at the wrong URL is otherwise silent: transactions get signed for whatever network the caller believes it is on. Call this once at startup to turn that into a boot failure.

§Errors

Fails if the endpoint reports a different chain id, or is unreachable.

Source

pub async fn healthcheck(&self) -> Result<HealthCheck>

Performs a health check on the matching engine.

This method pings the matching engine to verify it’s running and responsive. It’s useful for monitoring, load balancer health checks, and ensuring connectivity before attempting to send transactions.

§Returns
  • Ok(HealthCheck) - The node answered. status is a constant true on any node that answers at all, so the liveness signal is the other four fields: sequencer_height / sequencer_ts (the last block the engine opened and its unix-millisecond timestamp) and settlement_chain_height / settlement_chain_ts (the last settlement-chain checkpoint ingested). A node that has not produced a block yet reports zeros.
  • Err(_) - Network error or failed to reach the matching engine
§Examples
use sdk::Client;

let client = Client::new("https://matching.api.testnet.real.xyz")?;

// Check health before sending important transactions
let health = client.healthcheck().await?;
println!(
    "sequencer {}@{} ms, settlement chain {}@{} ms",
    health.sequencer_height,
    health.sequencer_ts,
    health.settlement_chain_height,
    health.settlement_chain_ts,
);
§Use Cases
  • Monitoring: Regular health checks for system monitoring
  • Load Balancing: Health checks for load balancer configuration
  • Pre-flight Checks: Verify connectivity before critical operations
  • Circuit Breaker: Implement circuit breaker patterns in client code
§Errors

This method will return an error if:

  • Network connection fails
  • The matching engine is completely unreachable
  • Response cannot be parsed
  • Request times out

Trait Implementations§

Source§

impl Clone for Client

Source§

fn clone(&self) -> Client

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 Client

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
§

impl<U> As for U

§

fn as_<T>(self) -> T
where T: CastFrom<U>, U: Sized,

Casts self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read more
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

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
§

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

§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

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

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

fn from_ref(input: &T) -> T

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

impl<T> Instrument for T

§

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

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

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

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

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a Request
§

impl<L> LayerExt<L> for L

§

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].
§

impl<T> MaybeSend for T
where T: Send,

§

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

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

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

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. 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.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

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