Skip to main content

Crate blokli_client

Crate blokli_client 

Source
Expand description

Rust client for the Blokli GraphQL API and transaction endpoints.

blokli-client provides a typed, async interface to a Blokli service. It wraps Blokli’s GraphQL API with ergonomic Rust traits for:

  • querying accounts, balances, channels, safes, ticket statistics, chain metadata, and transaction state;
  • subscribing to server-sent event streams for accounts, channels, health, graph changes, safe deployments, ticket redemptions, and tracked transactions;
  • submitting signed transactions and optionally waiting for tracking or confirmation.

The main entry point is BlokliClient. Most operations are trait methods, so bring the trait for the operation family into scope:

§API concepts

A BlokliClient is configured with the Blokli service base URL, not the GraphQL endpoint itself. For example, https://blokli.example.org becomes https://blokli.example.org/graphql for GraphQL requests and SSE subscriptions.

Queries and subscriptions use typed selectors instead of generic filter maps. Address-like values such as ChainAddress, ChannelId, PacketKey, and TxReceipt are byte arrays at the public boundary and are encoded as hex strings for GraphQL. Blokli-specific identifiers such as KeyId and TxId are kept distinct: a TxId is a Blokli tracking id, while a TxReceipt is the on-chain transaction hash returned by submission endpoints.

Subscriptions are GraphQL operations delivered over server-sent events. They yield streams of Result<T, E> so callers can decide how to handle item-level errors. Transaction helpers operate on already-signed raw transaction bytes; this crate does not sign transactions.

§Quick start

Create a client with a Blokli base URL. The client derives the GraphQL endpoint by appending /graphql to that base URL.

use blokli_client::{BlokliClient, BlokliClientConfig, BlokliQueryClient};

async fn example() -> Result<(), Box<dyn std::error::Error>> {
    let client = BlokliClient::new("https://blokli.example.org".parse()?, BlokliClientConfig::default());

    let version = client.query_version().await?;
    let chain = client.query_chain_info().await?;

    println!("Blokli {version} indexes chain {}", chain.chain_id);
    Ok(())
}

§Querying

Selectors are strongly typed. For example, channel queries use ChannelSelector plus an optional ChannelFilter and status.

use blokli_client::{BlokliClient, BlokliClientConfig, BlokliQueryClient, ChannelFilter, ChannelSelector};

async fn example(source: u32) -> Result<(), Box<dyn std::error::Error>> {
    let client = BlokliClient::new("https://blokli.example.org".parse()?, BlokliClientConfig::default());
    let selector = ChannelSelector {
        filter: Some(ChannelFilter::SourceKeyId(source)),
        ..Default::default()
    };

    let channels = client.query_channels(selector).await?;
    println!("{} channels found", channels.channels.len());
    Ok(())
}

§Subscriptions

Subscription methods return futures::Stream values. Streams use Blokli’s SSE endpoint and yield Result items so callers can decide how to handle transient transport, parsing, or GraphQL errors.

use blokli_client::{AccountSelector, BlokliClient, BlokliClientConfig, BlokliSubscriptionClient};
use futures::TryStreamExt;

async fn example() -> Result<(), Box<dyn std::error::Error>> {
    let client = BlokliClient::new("https://blokli.example.org".parse()?, BlokliClientConfig::default());
    let mut accounts = Box::pin(client.subscribe_accounts(AccountSelector::Any)?);

    while let Some(account) = accounts.try_next().await? {
        println!("account key id: {}", account.keyid);
    }

    Ok(())
}

§Transactions

Transaction methods expect already-signed raw transactions. submit_transaction returns immediately after submission, submit_and_track_transaction returns a Blokli tracking id, and submit_and_confirm_transaction waits for the requested number of confirmations.

use std::time::Duration;

use blokli_client::{BlokliClient, BlokliClientConfig, BlokliTransactionClient};

async fn example(signed_transaction: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
    let client = BlokliClient::new("https://blokli.example.org".parse()?, BlokliClientConfig::default());

    let tx_id = client.submit_and_track_transaction(signed_transaction).await?;
    let transaction = client.track_transaction(tx_id, Duration::from_secs(120)).await?;

    println!("transaction status: {:?}", transaction.status);
    Ok(())
}

§Public API layout

Common selectors, traits, and address aliases are re-exported at the crate root. The versioned API remains available under api::v1, and GraphQL response models are grouped under types.

§Errors

Fallible operations return BlokliClientError. Use BlokliClientError::kind when matching on stable client error categories such as invalid input, GraphQL errors, timeouts, or transaction tracking failures.

§DNS override

By default, BlokliClient uses the system DNS resolver through reqwest. Callers that need to keep Blokli communication working while DNS is unreliable can configure BlokliClientConfig::dns_override to pin the Blokli URL hostname to a fixed IP address.

The request hostname is not rewritten. For example, a client configured with https://blokli.example.org and a DNS override still sends requests for blokli.example.org, preserving TLS SNI and certificate validation while bypassing system DNS for that hostname. When BlokliDnsOverride::port is set, it becomes the request port; otherwise the original URL port or scheme default is used.

use std::net::IpAddr;

use blokli_client::{BlokliClient, BlokliClientConfig, BlokliDnsOverride};

let client = BlokliClient::new(
    "https://blokli.example.org".parse()?,
    BlokliClientConfig {
        dns_override: Some(BlokliDnsOverride {
            ip: IpAddr::from([203, 0, 113, 10]),
            port: None,
        }),
        ..Default::default()
    },
);

Leave dns_override as None to use normal system DNS resolution.

Re-exports§

pub use api::AccountSelector;
pub use api::BlokliQueryClient;
pub use api::BlokliSubscriptionClient;
pub use api::BlokliTransactionClient;
pub use api::ChainAddress;
pub use api::ChannelFilter;
pub use api::ChannelId;
pub use api::ChannelSelector;
pub use api::KeyId;
pub use api::ModulePredictionInput;
pub use api::PacketKey;
pub use api::RedeemedStatsSelector;
pub use api::SafeSelector;
pub use api::ServiceSelector;
pub use api::ServiceTypeId;
pub use api::TicketSelector;
pub use api::TxId;
pub use api::TxReceipt;
pub use api::types;
pub use errors::BlokliClientError;
pub use errors::ErrorKind;
pub use errors::TrackingErrorKind;

Modules§

api
Current Blokli client API. Versioned Blokli API traits, selectors, aliases, and response models.
errors
Errors returned by the Blokli client.
internal

Structs§

BlokliClient
Client implementation of the Blokli API.
BlokliClientConfig
Configuration for the BlokliClient.
BlokliDnsOverride
DNS resolution override for the Blokli base URL host.
BlokliTestClient
In-memory Blokli client for tests.
BlokliTestState
In-memory state served by BlokliTestClient.
BlokliTestStateSnapshot
Snapshot of the BlokliTestState inside a BlokliTestClient.
GraphQlQueries
Contains all GraphQL queries used by the Blokli client.
NopStateMutator
No-op state mutator.
ReqwestTransport

Constants§

CLIENT_VERSION
Version of the blokli-client crate.

Traits§

BlokliTestStateMutator
Applies signed-transaction effects to a BlokliTestState.