5

I am trying to use Rust (not Typescript) to query Solana and retrieve the SOL balance of a given account.

But I can't seem to be able to do this. What I have thus far. As dependencies I have the following:

[dependencies]
borsh = "0.9.3"
solana-client = "1.14.1"
solana-sdk = "1.14.1"
solana-program = "1.14.1"

Then in code I have the following:

use solana_sdk::commitment_config::CommitmentConfig;
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;

#[test]
fn get_price() {
    let rpc = RpcClient::new("https://api.devnet.solana.com".to_string());
    let balance = rpc.get_account(&Pubkey::new(b"BQeizWYD2dHmQq1b6HQqwBPrLWKitnhv5K82ZnRNPL8z")).unwrap().lamports;
    dbg!(balance);
}

But this fails with thread 'get_price' panicked at 'Slice must be the same length as a Pubkey: TryFromSliceError(())'

What am I doing wrong? And how do I get the SOL balance given that I have the public key (i.e. the address) using Rust?

1 Answer 1

3

The error message Slice must be the same length as a Pubkey: TryFromSliceError(()) is a clue to what the problem is.

Solana addresses are in base58 format, while the Pubkey::new function expects &[u8]. Converting the str directly to bytes won't work. To make it work, you need to use a utility that can convert base58 into bytes array.

Solana_sdk uses the bs58 crate and it exposes this too. So to make it work, I updated your code to below:

use solana_sdk::commitment_config::CommitmentConfig;
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use solana_sdk::{bs58}; // <- bring bs58 into scope

#[test]
fn get_price() {
 let rpc = RpcClient::new("https://api.devnet.solana.com".to_string());

 // first decode the base58 string
 let decoded_addrs = &bs58::decode("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU")
     .into_vec().unwrap()[..];

 let balance = rpc.get_account(&Pubkey::new(decoded_addrs)).unwrap().lamports;
    dbg!(balance);
}

By the way the address BQeizWYD2dHmQq1b6HQqwBPrLWKitnhv5K82ZnRNPL8z you used in your example does not seem to exist on devnet, so I used this USDC account instead

Edit

Going through the documentation for Pubkey again, I noticed it implements the FromStr trait. Meaning the solution can be simplified by bringing use std::str::FromStr; into scope and then creating an instance of Pubkey directly from the address string. The solution will then look like this:

use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;

use std::str::FromStr; // <- needs to be in scope

#[test]
fn get_price() {
    let rpc = RpcClient::new("https://api.devnet.solana.com".to_string());

    let balance = rpc.get_account(
        &Pubkey::from_str("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU").unwrap()
    ).unwrap().lamports;

    dbg!(balance);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.