From c6e4e3f3b44aa835ba34b2e866ccd055f23cd8c9 Mon Sep 17 00:00:00 2001 From: parazyd Date: Tue, 28 Sep 2021 15:46:14 +0200 Subject: [PATCH] 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)); } --- src/service/sol.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/service/sol.rs b/src/service/sol.rs index fc3b1fefb..ee086c36e 100644 --- a/src/service/sol.rs +++ b/src/service/sol.rs @@ -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 for SolFailed { } } +impl From for SolFailed { + fn from(err: solana_sdk::program_error::ProgramError) -> SolFailed { + SolFailed::SolError(err.to_string()) + } +} + impl From for SolFailed { fn from(err: crate::error::Error) -> SolFailed { SolFailed::SolError(err.to_string())