Rust SDK for interacting with Mina Protocol nodes via GraphQL.
- Async GraphQL client — query node status, accounts, blocks; send payments and delegations
- Typed response structs with
Currencyarithmetic - Automatic retry with configurable backoff
- Public
execute_query()for custom GraphQL queries tracinginstrumentation
- Rust 1.70+ (edition 2021)
- A running Mina daemon with GraphQL enabled
[dependencies]
mina-sdk = "0.1"use mina_sdk::{MinaClient, Payment, Currency};
#[tokio::main]
async fn main() -> mina_sdk::Result<()> {
let client = MinaClient::new("http://127.0.0.1:3085/graphql");
// Check sync status
let status = client.get_sync_status().await?;
println!("Sync status: {status}");
// Query an account
let account = client.get_account("B62q...", None).await?;
println!("Balance: {} MINA", account.balance.total);
// Send a payment
let result = client.send_payment(
Payment::sender("B62qsender...")
.to("B62qreceiver...")
.amount(Currency::from_mina("1.5")?)
.fee(Currency::from_mina("0.01")?)
.memo("hello from SDK"),
).await?;
println!("Tx hash: {}", result.hash);
Ok(())
}use mina_sdk::{MinaClient, ClientConfig};
use std::time::Duration;
let client = MinaClient::with_config(ClientConfig {
graphql_uri: "http://127.0.0.1:3085/graphql".to_string(),
retries: 3,
retry_delay: Duration::from_secs(5),
timeout: Duration::from_secs(30),
});Full API documentation is available on docs.rs.
| Method | Description |
|---|---|
get_sync_status() |
Node sync status (Synced, Bootstrap, etc.) |
get_daemon_status() |
Comprehensive daemon status |
get_network_id() |
Network identifier |
get_account(public_key, token_id) |
Account balance, nonce, delegate |
get_best_chain(max_length) |
Recent blocks from best chain |
get_peers() |
Connected peers |
get_pooled_user_commands(public_key) |
Pending transactions |
execute_query(query, variables, name) |
Run a custom GraphQL query |
| Method | Description |
|---|---|
send_payment(Payment) |
Send a payment |
send_delegation(Delegation) |
Delegate stake |
set_snark_worker(public_key) |
Set/unset SNARK worker |
set_snark_work_fee(fee) |
Set SNARK work fee |
use mina_sdk::Currency;
let a = Currency::from_mina("10")?; // 10 MINA
let b = Currency::from_mina("1.5")?; // 1.5 MINA
let c = Currency::from_nanomina(1_000_000_000); // 1 MINA
let d = Currency::from_graphql("1500000000")?; // from GraphQL response
println!("{}", (a + b)); // 11.500000000
println!("{}", a.nanomina()); // 10000000000
assert!(a > b);Runnable programs live in examples/:
| Example | Command | Needs a node |
|---|---|---|
basic_usage |
cargo run --example basic_usage |
yes |
send_payment |
cargo run --example send_payment |
yes |
stake_delegation |
cargo run --example stake_delegation |
yes |
node_monitoring |
cargo run --example node_monitoring |
yes |
custom_query |
cargo run --example custom_query |
yes |
error_handling |
cargo run --example error_handling |
yes |
currency_operations |
cargo run --example currency_operations |
no |
git clone https://github.com/MinaProtocol/mina-sdk-rust.git
cd mina-sdk-rust
cargo test
cargo clippyIntegration tests run against a live Mina node and are skipped by default. To run them locally with a lightnet Docker container:
docker run --rm -d -p 8080:8080 -p 8181:8181 -p 3085:3085 \
-e NETWORK_TYPE=single-node -e PROOF_LEVEL=none \
o1labs/mina-local-network:compatible-latest-lightnet
# Wait for the network to sync, then:
MINA_GRAPHQL_URI=http://127.0.0.1:8080/graphql \
cargo test --test integration_tests -- --test-threads=1Connection refused — Make sure the Mina daemon is running and the GraphQL endpoint is accessible. The default URI is http://127.0.0.1:3085/graphql.
Account not found — The account may not exist on the network, or the public key format is incorrect. Mina public keys start with B62q.
Schema drift — If queries fail with unexpected GraphQL errors, the daemon version may have changed its schema. Run the schema drift check: python3 scripts/check_schema_drift.py --endpoint http://your-node:3085/graphql
Timeout errors — Increase the timeout and retry settings via ClientConfig. Some queries (like get_best_chain) can be slow on nodes that are still syncing.
Contributions are welcome. Please open an issue first to discuss what you'd like to change.