Clients
What this teaches: when to use HttpClient and when to use WsClient, and what each one is wired to under the hood.
Mental model
The SDK ships two transports:
HttpClient— one-shot queries and transaction broadcast over GraphQL and REST. Cloneable, no live connection.WsClient— GraphQL subscriptions overgraphql-transport-ws. Cheap factory value; the actual socket lives in aSession.
There is no shared "Client" abstraction. Pick the one that matches the call pattern.
HttpClient
HttpClient wraps a reqwest::Client. It is Debug + Clone; cloning shares the underlying connection pool — pass it around freely.
It implements four upstream query traits, which is where the queries live:
QueryClient—query_app,query_store,simulate.BlockClient—query_block,query_block_outcome(REST, not GraphQL).BroadcastClient—broadcast_tx.SearchTxClient—search_tx.
Bringing the traits into scope is what unlocks the methods:
use {
anyhow::Result,
dango_sdk::HttpClient,
grug::{BlockClient, BroadcastClient, QueryClient, SearchTxClient},
};
#[tokio::main]
async fn main() -> Result<()> {
let client = HttpClient::new("https://api-mainnet.dango.zone")?;
let block = client.query_block(None).await?;
println!("height: {}", block.info.height);
Ok(())
}Extension methods on HttpClient
Because HttpClient implements QueryClient, the QueryClientExt blanket trait lights up a suite of convenience methods:
| Method | What it does |
|---|---|
query_app_config | Fetch the typed AppConfig. |
query_balance | Fetch a single denom balance for an address. |
query_balances | Fetch all balances for an address. |
query_supply | Fetch total supply for one denom. |
query_supplies | Fetch total supplies. |
query_wasm_smart | Run a typed smart query on a contract. |
query_wasm_raw | Read a raw storage slot from a contract. |
query_code | Fetch a Wasm bytecode by hash. |
query_codes | List uploaded code hashes. |
query_contract | Fetch a contract's info. |
query_contracts | List contracts. |
See the QueryClientExt reference for full signatures.
Pagination
HttpClient ships own pagination helpers on top of the GraphQL connection types:
paginate_all— generic forward/backward loop driven by closures.paginate_accounts,paginate_transfers,paginate_transactions,paginate_blocks,paginate_events,paginate_messages— typed wrappers for each indexer connection.
Use the typed wrappers when the query type matches; use paginate_all when shaping a custom traversal.
WsClient
WsClient holds nothing but a parsed Url. Cloning is free.
Two ways to consume it:
WsClient::connect→Session. Open one socket and multiplex multiple subscriptions over it. Drop theSessionand every derived stream to close the connection.WsClient::subscribe. Open a dedicated socket for one subscription. Drop the stream to close.
Subscription items are Result<Response<T>, WsError>. The first error variant WsError::Closed ends the stream. See Subscriptions for which entry point to pick.
Lifecycle
HttpClienthas noDrophook. Reuse one instance for the lifetime of the program.WsClientis a config object; copy it freely.Sessionruns a backgroundtokiotask spawned byconnect. The lastSessionclone drops it via aClosecommand. See Session.
Next
- Signers and authentication — sign transactions before broadcasting.
- Subscriptions — when to use
Session::subscribevsWsClient::subscribe.