Rust SDK
The official Rust SDK for MoltChain. Built on reqwest and tokio with strong typing and Result<T> error handling.
Installation
# Cargo.toml
[dependencies]
moltchain-sdk = "0.1"
tokio = { version = "1", features = ["full"] }
Or via the command line:
cargo add moltchain-sdk
Re-exports: moltchain_sdk::{Client, ClientBuilder, Keypair, TransactionBuilder, Balance, Block, NetworkInfo}
Quick Start
use moltchain_sdk::{Client, Keypair, TransactionBuilder, Balance};
#[tokio::main]
async fn main() -> Result<(), Box> {
// Connect to local validator
let client = Client::new("http://localhost:8899");
// Generate a keypair
let kp = Keypair::new();
println!("Address: {}", kp.pubkey());
// Check balance
let balance = client.get_balance(&kp.pubkey().to_string()).await?;
println!("Balance: {} shells", balance.shells());
// Build and send a transfer
let blockhash = client.get_recent_blockhash().await?;
let tx = TransactionBuilder::new()
.add_instruction(/* transfer instruction */)
.recent_blockhash(&blockhash)
.build_and_sign(&kp)?;
let sig = client.send_transaction(&tx).await?;
println!("Signature: {sig}");
Ok(())
}
Client
Client::new(rpc_url: &str) -> Client
Create a client pointing at the given JSON-RPC endpoint.
let client = Client::new("http://localhost:8899");
Client::builder() -> ClientBuilder
Create a client with advanced options via the builder pattern.
let client = Client::builder()
.rpc_url("http://localhost:8899")
.timeout(std::time::Duration::from_secs(30))
.build()?;
| Builder Method | Type | Description |
|---|---|---|
| rpc_url(url) | &str | Set RPC endpoint URL (required) |
| timeout(duration) | Duration | Set per-request timeout |
| build() | Result<Client> | Construct the client |
Chain Queries
async get_slot(&self) -> Result<u64>
Get the current slot number.
let slot = client.get_slot().await?;
println!("Slot: {slot}");
async get_latest_block(&self) -> Result<Block>
Get the most recently produced block.
async get_block(&self, slot: u64) -> Result<Block>
Get a block by slot number.
async get_recent_blockhash(&self) -> Result<String>
Get a recent blockhash for signing transactions.
async get_metrics(&self) -> Result<Value>
Get chain performance metrics (TPS, total transactions/blocks, average block time).
async get_chain_status(&self) -> Result<Value>
Get comprehensive chain status.
async health(&self) -> Result<Value>
Liveness probe. Returns {"status": "ok"}.
async get_network_info(&self) -> Result<NetworkInfo>
Get network information — chain ID, network ID, version, slot.
let info = client.get_network_info().await?;
println!("Chain: {} v{}", info.chain_id, info.version);
async get_peers(&self) -> Result<Value>
Get connected P2P peers.
async get_total_burned(&self) -> Result<Value>
Get total burned MOLT — {"shells": ..., "molt": ...}.
Account Methods
async get_balance(&self, pubkey: &str) -> Result<Balance>
Get account balance. Returns a strongly-typed Balance.
let bal = client.get_balance("7xKXtg2CW87d...").await?;
println!("{} shells ({} MOLT)", bal.shells(), bal.molt());
async get_account_info(&self, pubkey: &str) -> Result<Value>
Get enhanced account information with metadata.
async get_transaction_history(&self, pubkey: &str, limit: u64) -> Result<Value>
Get paginated transaction history for an account.
Transaction Methods
async send_transaction(&self, tx_json: &Value) -> Result<String>
Submit a signed transaction JSON. Returns the signature string.
let blockhash = client.get_recent_blockhash().await?;
let tx = TransactionBuilder::new()
.add_instruction(serde_json::json!({
"type": 0,
"from": kp.pubkey(),
"to": "RecipientAddress...",
"amount": 1_000_000_000_u64
}))
.recent_blockhash(&blockhash)
.build_and_sign(&kp)?;
let sig = client.send_transaction(&tx).await?;
async send_raw_transaction(&self, raw_tx: &str) -> Result<String>
Submit a pre-serialized transaction string.
async get_transaction(&self, signature: &str) -> Result<Value>
Look up a transaction by its signature hash.
Validator & Staking
async get_validators(&self) -> Result<Value>
Get all registered validators.
async get_validator_info(&self, pubkey: &str) -> Result<Value>
Get detailed validator information.
async get_validator_performance(&self, pubkey: &str) -> Result<Value>
Get validator performance metrics.
async stake(&self, from: &str, validator: &str, amount: u64) -> Result<String>
Stake MOLT to a validator. Amount in shells.
let sig = client.stake(
&kp.pubkey(),
"ValidatorPubkey...",
10_000_000_000 // 10 MOLT
).await?;
async unstake(&self, from: &str, validator: &str, amount: u64) -> Result<String>
Unstake MOLT from a validator.
async get_staking_status(&self, pubkey: &str) -> Result<Value>
Get staking status for an account.
async get_staking_rewards(&self, pubkey: &str) -> Result<Value>
Get accumulated staking rewards.
Contract Methods
async get_contract_info(&self, contract_id: &str) -> Result<Value>
Get information about a deployed smart contract.
async get_contract_logs(&self, contract_id: &str) -> Result<Value>
Get execution logs emitted by a contract.
async get_all_contracts(&self) -> Result<Value>
List all deployed contracts.
Program Methods
async get_program(&self, program_id: &str) -> Result<Value>
Get program information.
async get_programs(&self) -> Result<Value>
List all deployed programs.
async get_program_stats(&self, program_id: &str) -> Result<Value>
Get execution statistics for a program.
async get_program_calls(&self, program_id: &str) -> Result<Value>
Get recent call history for a program.
async get_program_storage(&self, program_id: &str) -> Result<Value>
Get on-chain storage summary for a program.
NFT Methods
async get_collection(&self, collection_id: &str) -> Result<Value>
Get NFT collection metadata.
async get_nft(&self, collection_id: &str, token_id: u64) -> Result<Value>
Get a specific NFT by collection and token ID.
async get_nfts_by_owner(&self, owner: &str) -> Result<Value>
Get all NFTs owned by an address.
async get_nfts_by_collection(&self, collection_id: &str) -> Result<Value>
Get all NFTs in a collection.
async get_nft_activity(&self, collection_id: &str, token_id: u64) -> Result<Value>
Get activity history for a specific NFT.
Keypair
Ed25519 keypair wrapper around ed25519_dalek. Thread-safe and Clone-able.
Keypair::new() -> Keypair
Generate a new random keypair.
let kp = Keypair::new();
println!("Pubkey: {}", kp.pubkey());
Keypair::from_seed(seed: &[u8; 32]) -> Keypair
Derive a deterministic keypair from a 32-byte seed.
let seed = [0u8; 32];
let kp = Keypair::from_seed(&seed);
keypair.sign(message: &[u8]) -> Vec<u8>
Sign an arbitrary message. Returns the 64-byte detached signature.
keypair.pubkey() -> String
Get the base58-encoded public key string.
keypair.to_seed() -> [u8; 32]
Extract the 32-byte seed.
keypair.inner() -> &ed25519_dalek::SigningKey
Access the underlying ed25519_dalek::SigningKey for advanced use cases.
TransactionBuilder
Builder pattern for constructing and signing transactions. All methods consume and return self for chaining.
TransactionBuilder::new() -> TransactionBuilder
Create an empty builder.
.add_instruction(value: Value) -> Self
Append an instruction JSON value. Can be called multiple times.
.recent_blockhash(hash: &str) -> Self
Set the recent blockhash.
.build_and_sign(keypair: &Keypair) -> Result<Value>
Sign the instructions and return a transaction JSON object ready to submit.
use serde_json::json;
let blockhash = client.get_recent_blockhash().await?;
let tx = TransactionBuilder::new()
.add_instruction(json!({
"type": 0,
"from": kp.pubkey(),
"to": recipient,
"amount": 5_000_000_000_u64
}))
.recent_blockhash(&blockhash)
.build_and_sign(&kp)?;
let sig = client.send_transaction(&tx).await?;
println!("Transfer complete: {sig}");
Types
Balance
Strongly-typed balance with unit conversions.
| Method / Constructor | Returns | Description |
|---|---|---|
| Balance::from_shells(n: u64) | Balance | Create from raw shell count |
| Balance::from_molt(n: f64) | Balance | Create from MOLT (1 MOLT = 109 shells) |
| balance.shells() | u64 | Get balance in shells |
| balance.molt() | f64 | Get balance in MOLT |
let b = Balance::from_molt(25.0);
assert_eq!(b.shells(), 25_000_000_000);
assert_eq!(b.molt(), 25.0);
Block
Deserialized block data.
#[derive(Debug, Deserialize)]
pub struct Block {
pub slot: u64,
pub hash: String,
pub parent_hash: String,
pub timestamp: u64,
pub transactions: Vec,
}
NetworkInfo
Deserialized network information.
#[derive(Debug, Deserialize)]
pub struct NetworkInfo {
pub chain_id: String,
pub network_id: String,
pub version: String,
pub slot: u64,
pub validator_count: u64,
pub peer_count: u64,
}
Error Handling
All client methods return Result<T, Box<dyn std::error::Error>>. RPC errors surface with their JSON-RPC error code and message.
match client.get_balance("7xKXtg2CW87d...").await {
Ok(balance) => println!("{} MOLT", balance.molt()),
Err(e) => {
let msg = e.to_string();
if msg.contains("Account not found") {
println!("Account does not exist yet");
} else {
eprintln!("RPC error: {e}");
}
}
}
Common error codes:
-32601— Method not found-32602— Invalid params-32003— Admin auth required-32005— Rate limit exceeded
Tip: For production services, use the ClientBuilder with a custom timeout and wrap calls in a retry loop with exponential backoff for transient network errors.
WebSocket Subscriptions
The Rust SDK supports real-time event streaming via WebSocket. Create a WsClient and subscribe to on-chain events with typed callbacks.
use moltchain_sdk::{WsClient, Pubkey};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let ws = WsClient::connect("ws://localhost:8900").await?;
// Subscribe to slot updates
let slot_sub = ws.on_slot(|slot| {
println!("New slot: {}", slot);
}).await?;
// Subscribe to account changes
let acct = Pubkey::from_base58("YourAccountBase58Here")?;
let acct_sub = ws.on_account_change(&acct, |account| {
println!("Balance changed: {} shells", account.shells);
}).await?;
// Unsubscribe when done
ws.off_slot(slot_sub).await?;
ws.off_account_change(acct_sub).await?;
// Close all subscriptions
ws.close().await;
Ok(())
}
WsClient::connect(url: &str) -> Result<WsClient>
Open a WebSocket connection to the given endpoint.
on_slot(callback) / off_slot(sub_id)
Subscribe to slot updates. Returns a subscription ID for unsubscribing.
on_block(callback) / off_block(sub_id)
Subscribe to new blocks.
on_account_change(pubkey, callback) / off_account_change(sub_id)
Watch a specific account for balance or data changes.
on_logs(callback, contract_id?) / off_logs(sub_id)
Stream contract logs. Optionally filter by contract ID.
close()
Close the WebSocket connection and clear all active subscriptions.