service/sol: Implement function for fetching SPL Token balance.

It can be used as follows:

fn main() {
    let main_pk = Pubkey::from_str("mainWallet").unwrap();
    let mint_pk = Pubkey::from_str("usdcMint").unwrap();
    let (tokn_pk, _) = get_associated_token_account(&main_pk, &mint_pk);
    let (bal, dec) = get_account_token_balance(
        "https://api.mainnet-beta.solana.com".to_string(),
        &tokn_pk,
        &mint_pk
    ).unwrap();

    println!("Balance:  {}", bal);
    println!("Decimals: {}", dec);
    println!("UI representation: {}", bal / u64::pow(10, dec as u32));
}
This commit is contained in:
parazyd
2021-09-28 15:46:14 +02:00
parent 3ac9d7edbe
commit c6e4e3f3b4

View File

@@ -11,8 +11,8 @@ use serde::Serialize;
use serde_json::{json, Value};
use solana_client::{blockhash_query::BlockhashQuery, rpc_client::RpcClient};
use solana_sdk::{
native_token::lamports_to_sol, pubkey::Pubkey, signature::Signer, signer::keypair::Keypair,
system_instruction, transaction::Transaction,
native_token::lamports_to_sol, program_pack::Pack, pubkey::Pubkey, signature::Signer,
signer::keypair::Keypair, system_instruction, transaction::Transaction,
};
use tungstenite::Message;
@@ -326,6 +326,23 @@ pub fn get_associated_token_account(owner: &Pubkey, mint: &Pubkey) -> (Pubkey, u
)
}
/// Gets account token balance for given mint.
/// Returns: (amount, decimals)
pub fn get_account_token_balance(
rpc_server: String,
address: &Pubkey,
mint: &Pubkey,
) -> SolResult<(u64, u64)> {
let rpc = RpcClient::new(rpc_server);
let mint_account = rpc.get_account(mint)?;
let token_account = rpc.get_account(address)?;
let mint_data = spl_token::state::Mint::unpack_from_slice(&mint_account.data)?;
let token_data = spl_token::state::Account::unpack_from_slice(&token_account.data)?;
Ok((token_data.amount, mint_data.decimals as u64))
}
/// Check if given account is a valid token mint
pub fn account_is_initialized_mint(rpc_server: String, mint: &Pubkey) -> bool {
let rpc = RpcClient::new(rpc_server);
@@ -434,6 +451,12 @@ impl From<solana_client::client_error::ClientError> for SolFailed {
}
}
impl From<solana_sdk::program_error::ProgramError> for SolFailed {
fn from(err: solana_sdk::program_error::ProgramError) -> SolFailed {
SolFailed::SolError(err.to_string())
}
}
impl From<crate::error::Error> for SolFailed {
fn from(err: crate::error::Error) -> SolFailed {
SolFailed::SolError(err.to_string())