Fetch balance
Usually we will use Solana SDK but we doing vanilla here so...
How to fetch account balance in Javascript
vanilla.
const get_balance = async (pubkey, options) =>
new Promise(async (resolve, reject) => {
const { rpc_url, id, maximumFractionDigits } = {
id: parseInt(100 * Math.random()),
maximumFractionDigits: 2,
...options
}
const result = await fetch(rpc_url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
jsonrpc: '2.0',
id,
method: 'getBalance',
params: [pubkey]
})
}).catch(reject)
const json = await result?.json().catch(reject)
if (isNaN(json?.result?.value)) {
reject(new Error('No result.'))
}
resolve(
(json?.result?.value / Math.pow(10, 9) || 0).toLocaleString('en-US', {
maximumFractionDigits
})
)
})
// Consider donate some SOL to this 👇 account to see some number show up 😆
get_balance('gistmeAhMG7AcKSPCHis8JikGmKT9tRRyZpyMLNNULq', {
rpc_url: 'https://rpc.ankr.com/solana'
})
.then(console.log)
.catch(console.error)
Now let's try Rust
version.
How to fetch account balance in Rust
vanilla.
use currency_rs::{Currency, CurrencyOpts}; use rand::Rng; use serde::{Deserialize, Serialize}; // We need this lifetime 👇. struct GetBalanceOptions<'a> { rpc_url: &'static str, id: u32, // Because of this options 👇 required it. currency_opts: Option<CurrencyOpts<'a>>, } #[derive(Debug, Serialize, Deserialize)] struct RpcPayload { jsonrpc: String, id: u32, method: String, params: Vec<String>, } #[derive(Debug, Serialize, Deserialize)] struct GetBalanceResponse { jsonrpc: String, id: u32, result: GetBalanceResponseResult, } #[derive(Debug, Serialize, Deserialize)] struct GetBalanceResponseResult { value: u64, } #[derive(Debug)] #[allow(dead_code)] struct UiBalance { lamports: f64, ui_lamports: String, } // We need this 'a 👇 async fn get_balance<'a>( pubkey: String, // But this can be elided 'a👇 options: GetBalanceOptions<'_>, ) -> anyhow::Result<UiBalance> { let client = reqwest::Client::new(); let json_payload = RpcPayload { jsonrpc: "2.0".to_owned(), id: options.id, method: "getBalance".to_owned(), params: vec![pubkey], }; // We can deserialize json by 👇 specify type let balance_response: GetBalanceResponse = client .post(options.rpc_url) .json(&json_payload) .send() .await? .json() .await?; let lamports = balance_response.result.value as f64 / 10u64.pow(9) as f64; let ui_lamports = Currency::new_float(lamports, options.currency_opts).format(); Ok(UiBalance { lamports, ui_lamports, }) } // We need tokio main here due to async. #[tokio::main] async fn main() { let ui_balance_result = get_balance( // Consider donate some SOL to this 👇 account to see some number show up 😆 "gistmeAhMG7AcKSPCHis8JikGmKT9tRRyZpyMLNNULq".to_owned(), GetBalanceOptions { rpc_url: "https://rpc.ankr.com/solana", id: rand::thread_rng().gen_range(0u32..u32::MAX), currency_opts: Some( CurrencyOpts::new() .set_precision(2) .set_symbol("") .set_separator(",") .set_decimal("."), ), }, ) .await; // Consider use match to handle this 👇 as a homework. println!("ui_balance_result: {:?}", ui_balance_result); }
[package]
name = "fetch-balance"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0"
currency_rs = { version = "1.1", default-features = false }
rand = "0.8"
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version ="1.22", features = ["full"] }
[profile.release]
opt-level = "z" # Optimize for size.
strip = true # Automatically strip symbols from the binary.
lto = true # Enable Link Time Optimization (LTO)
codegen-units = 1 # Reduce Parallel Code Generation Units to Increase Optimization
panic = "abort"