First call
A five-minute hello-world that queries chain status with HttpClient.
The program
use {
anyhow::Result,
dango_sdk::HttpClient,
grug::BlockClient,
};
#[tokio::main]
async fn main() -> Result<()> {
let client = HttpClient::new("https://api-mainnet.dango.zone")?;
let block = client.query_block(None).await?;
println!("latest height: {}", block.info.height);
println!("chain id: {}", block.info.chain_id);
println!("timestamp: {}", block.info.timestamp);
Ok(())
}BlockClient supplies query_block. HttpClient implements it, so the method is reachable once the trait is in scope.
What just happened
HttpClient::newwraps areqwest::Clientaround the Dango HTTP endpoint. No network call is made.query_block(None)hits the REST endpointGET /block/infoand parses the response into aBlock.- Errors propagate as
anyhow::Errorvia?.
Querying contract state
Most "what's my balance" calls go through the QueryClientExt blanket trait, which is automatically reachable on HttpClient:
use {
anyhow::Result,
dango_sdk::HttpClient,
grug::{Addr, Denom, QueryClientExt},
std::str::FromStr,
};
#[tokio::main]
async fn main() -> Result<()> {
let client = HttpClient::new("https://api-mainnet.dango.zone")?;
let address = Addr::from_str("0x0000000000000000000000000000000000000000")?;
let denom = Denom::from_str("bridge/usdc")?;
let balance = client.query_balance(address, denom, None).await?;
println!("balance: {balance}");
Ok(())
}query_balance, query_app_config, query_wasm_smart, and the other QueryClientExt methods. See Clients for the full list reachable on HttpClient.
Next
- Project setup — wiring endpoints, keys, and env vars.
- Concepts: Clients —
HttpClientvsWsClient.