solana_scanner/src/solana_rpc_calls.rs
Alexandre RAY-BERNAT 9bd88aeb03
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Retrieves social infos + post on Telegram
2025-05-23 16:13:36 +02:00

98 lines
3.6 KiB
Rust

use anyhow::anyhow;
use base64::Engine;
use base64::prelude::BASE64_STANDARD;
use log::error;
use mpl_token_metadata::accounts::Metadata;
use solana_account_decoder::{UiAccountData, UiAccountEncoding};
use solana_client::rpc_client::RpcClient;
use solana_client::rpc_config::RpcAccountInfoConfig;
use solana_client::rpc_request::TokenAccountsFilter;
use solana_program::message::{Message, VersionedMessage};
use solana_program::program_pack::Pack;
use solana_program::pubkey::Pubkey;
use solana_sdk::account::Account;
use solana_sdk::signature::Signature;
use solana_sdk::transaction::VersionedTransaction;
use solana_transaction_status_client_types::{EncodedConfirmedTransactionWithStatusMeta, UiTransactionEncoding};
use solana_transaction_status_client_types::EncodedTransaction::Binary;
use spl_token::state::Mint;
use crate::dto::{ParsedAccount, TokenInfo};
use crate::{ find_metadata_account};
pub fn get_token_info(client: &RpcClient, mint_pubkey: &Pubkey) -> anyhow::Result<TokenInfo> {
let account = fetch_account(client, mint_pubkey);
let mint = Mint::unpack(&*account?.data);
match mint {
Ok(mint) => Ok(TokenInfo {
mint_address: mint_pubkey.to_string(),
decimals: mint.decimals,
mint_authority: mint.mint_authority.is_some(),
freeze_authority: mint.freeze_authority.is_some(),
supply: mint.supply,
}),
Err(e) => Err(anyhow::Error::msg(format!("ProgramError: {:?}", e))),
}
}
pub fn get_transactions(
client: &RpcClient,
signature: &Signature,
) -> solana_client::client_error::Result<EncodedConfirmedTransactionWithStatusMeta> {
let config = solana_client::rpc_config::RpcTransactionConfig {
encoding: Some(UiTransactionEncoding::Base64),
commitment: Some(solana_sdk::commitment_config::CommitmentConfig::confirmed()),
max_supported_transaction_version: Some(0),
};
client.get_transaction_with_config(&signature, config)
}
pub fn get_token_metadata(client: &RpcClient, mint: &Pubkey) -> anyhow::Result<Metadata> {
let (metadata_pubkey, _) = find_metadata_account(mint);
let account = client.get_account(&metadata_pubkey)?;
let metadata = Metadata::safe_deserialize(&mut account.data.as_ref())?;
Ok(metadata)
}
pub fn get_dev_balance_for_token(rpc: &RpcClient, dev_pubkey: &Pubkey, mint: &Pubkey) -> anyhow::Result<f64> {
let token_accounts =
rpc.get_token_accounts_by_owner(dev_pubkey, TokenAccountsFilter::Mint(*mint))?;
let mut total_balance: f64 = 0.0;
for account_info in token_accounts {
let amount_option = match account_info.account.data.clone() {
UiAccountData::Json(test) => {
let json = serde_json::to_value(&test.parsed)?;
let token: ParsedAccount = serde_json::from_value(json)?;
token.info.tokenAmount.uiAmount
}
_ => {
error!("Cannot parse account_data");
None
}
};
total_balance += amount_option.unwrap_or_else(|| 0.0);
}
Ok(total_balance)
}
fn fetch_account(rpc_client: &RpcClient, mint_pubkey: &Pubkey) -> anyhow::Result<Account> {
let config = RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Base64),
..RpcAccountInfoConfig::default()
};
match rpc_client.get_account_with_config(&mint_pubkey, config) {
Ok(response) => match response.value {
Some(account) => Ok(account),
None => Err(anyhow::Error::msg(format!("Account not found"))),
},
Err(e) => Err(anyhow::Error::msg(format!("RPC error {}", e))),
}
}