Documentation for querying wallet balances and account information from the Bittensor network.
Wallet queries provide access to account balances, transaction history, and staking information. These queries are essential for monitoring account state and managing funds.
use bittensor_rs::queries::wallets;
use bittensor_rs::format_rao_as_tao;
// Get total balance
let balance = wallets::get_balance(&client, &account_id).await?;
println!("Balance: {} TAO", format_rao_as_tao(balance));
// Get detailed balance info
let account_info = wallets::get_account_info(&client, &account_id).await?;
if let Some(info) = account_info {
println!("Free: {} TAO", format_rao_as_tao(info.data.free));
println!("Reserved: {} TAO", format_rao_as_tao(info.data.reserved));
println!("Frozen: {} TAO", format_rao_as_tao(info.data.frozen));
}// Query multiple accounts
let addresses = vec![account1, account2, account3];
let balances = wallets::get_balances(&client, &addresses).await?;
for (account, balance) in addresses.iter().zip(balances.iter()) {
println!("{}: {} TAO",
account.to_ss58check(),
balance.as_ref().map(|b| format_rao_as_tao(*b)).unwrap_or_else(|| "0.000000000".to_string())
);
}use sp_core::crypto::AccountId32;
// From SS58 string
let ss58 = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
let account_id = AccountId32::from_ss58check(ss58)?;
// With custom format
let account_id = AccountId32::from_ss58check_with_version(ss58)?;use sp_core::crypto::Ss58Codec;
use bittensor_rs::core::SS58_FORMAT;
// To Bittensor SS58 format
let ss58 = account_id.to_ss58check_with_version(
sp_core::crypto::Ss58AddressFormat::custom(SS58_FORMAT)
);
// To default format
let ss58 = account_id.to_ss58check();use bittensor_rs::queries::stakes;
// Get total stake for a hotkey
let total_stake = stakes::get_total_stake(&client, &hotkey).await?;
println!("Total stake: {} TAO", format_rao_as_tao(total_stake));
// Get stake for specific subnet
let stake = stakes::get_stake(&client, netuid, &hotkey).await?;// Get all stakes for a hotkey
let all_stakes = stakes::get_all_stakes_for_hotkey(&client, &hotkey).await?;
for (subnet, stake) in all_stakes {
println!("Subnet {}: {} TAO", subnet, format_rao_as_tao(stake));
}
// Get delegators for a hotkey
let delegators = stakes::get_delegators(&client, &hotkey).await?;
for (delegator, amount) in delegators {
println!("Delegator {}: {} TAO",
delegator.to_ss58check(),
format_rao_as_tao(amount)
);
}async fn monitor_account(client: &BittensorClient, account: &AccountId32) -> Result<()> {
let mut last_balance = 0u128;
loop {
let balance = wallets::get_balance(client, account).await?
.unwrap_or(0);
if balance != last_balance {
let change = if balance > last_balance {
format!("+{} TAO", format_rao_as_tao(balance - last_balance))
} else {
format!("-{} TAO", format_rao_as_tao(last_balance - balance))
};
println!("Balance changed: {} (new total: {} TAO)",
change, format_rao_as_tao(balance)
);
last_balance = balance;
}
tokio::time::sleep(Duration::from_secs(12)).await;
}
}async fn find_wealthy_accounts(
client: &BittensorClient,
accounts: &[AccountId32],
min_balance: u128
) -> Result<Vec<(AccountId32, u128)>> {
let mut wealthy = Vec::new();
for account in accounts {
if let Some(balance) = wallets::get_balance(client, account).await? {
if balance >= min_balance {
wealthy.push((account.clone(), balance));
}
}
}
wealthy.sort_by(|a, b| b.1.cmp(&a.1));
Ok(wealthy)
}async fn calculate_portfolio(
client: &BittensorClient,
accounts: &[(AccountId32, String)] // (account, name)
) -> Result<()> {
let mut total = 0u128;
println!("Portfolio Summary");
println!("{:-<50}", "");
for (account, name) in accounts {
let balance = wallets::get_balance(client, account).await?
.unwrap_or(0);
let stake = stakes::get_total_stake(client, account).await?
.unwrap_or(0);
let account_total = balance + stake;
total += account_total;
println!("{:<20} {:>15} TAO (Balance: {}, Stake: {})",
name,
format_rao_as_tao(account_total),
format_rao_as_tao(balance),
format_rao_as_tao(stake)
);
}
println!("{:-<50}", "");
println!("{:<20} {:>15} TAO", "Total", format_rao_as_tao(total));
Ok(())
}use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct AccountExport {
address: String,
balance: u128,
stake: u128,
delegations: Vec<(String, u128)>,
timestamp: u64,
}
async fn export_account_data(
client: &BittensorClient,
account: &AccountId32
) -> Result<AccountExport> {
let balance = wallets::get_balance(client, account).await?
.unwrap_or(0);
let stake = stakes::get_total_stake(client, account).await?
.unwrap_or(0);
let delegators = stakes::get_delegators(client, account).await?
.unwrap_or_default();
let delegations: Vec<_> = delegators
.into_iter()
.map(|(d, a)| (d.to_ss58check(), a))
.collect();
let block = client.get_block_number().await?;
Ok(AccountExport {
address: account.to_ss58check(),
balance,
stake,
delegations,
timestamp: block,
})
}- Batch balance queries when checking multiple accounts
- Cache balance information for frequently accessed accounts
- Use event subscriptions for real-time balance monitoring
- Consider rate limiting for continuous monitoring
use bittensor_rs::Error;
match wallets::get_balance(&client, &account).await {
Ok(Some(balance)) => println!("Balance: {} TAO", format_rao_as_tao(balance)),
Ok(None) => println!("Account not found or zero balance"),
Err(Error::DecodingError(e)) => println!("Failed to decode balance: {}", e),
Err(e) => println!("Query failed: {}", e),
}- Never log or display private keys
- Use secure storage for sensitive account information
- Validate SS58 addresses before processing
- Consider using hardware wallets for high-value accounts
- Staking Queries - Detailed staking information
- Delegate Queries - Delegation management
- Chain Operations - Transaction submission
- Runtime Queries - Hotkey ownership helper
- Staking Queries - Detailed staking information
- Delegate Queries - Delegation management
- Chain Operations - Transaction submission