92 lines
3.3 KiB
Rust
92 lines
3.3 KiB
Rust
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::program_pack::Pack;
|
|
use solana_program::pubkey::Pubkey;
|
|
use solana_sdk::account::Account;
|
|
use solana_sdk::signature::Signature;
|
|
use solana_transaction_status_client_types::{EncodedConfirmedTransactionWithStatusMeta, UiTransactionEncoding};
|
|
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))),
|
|
}
|
|
} |