use anchor_lang::{AccountDeserialize, Discriminator}; use mango_v4::state::{Bank, MangoAccount, MangoAccountValue, MintInfo, PerpMarket, Serum3Market}; use solana_account_decoder::UiAccountEncoding; use solana_client::nonblocking::rpc_client::RpcClient as RpcClientAsync; use solana_client::rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}; use solana_client::rpc_filter::{Memcmp, RpcFilterType}; use solana_sdk::pubkey::Pubkey; pub async fn fetch_mango_accounts( rpc: &RpcClientAsync, program: Pubkey, group: Pubkey, owner: Pubkey, ) -> anyhow::Result> { let config = RpcProgramAccountsConfig { filters: Some(vec![ RpcFilterType::Memcmp(Memcmp::new_base58_encoded( 0, &MangoAccount::discriminator(), )), RpcFilterType::Memcmp(Memcmp::new_base58_encoded(8, &group.to_bytes())), RpcFilterType::Memcmp(Memcmp::new_base58_encoded(40, &owner.to_bytes())), ]), account_config: RpcAccountInfoConfig { encoding: Some(UiAccountEncoding::Base64), ..RpcAccountInfoConfig::default() }, ..RpcProgramAccountsConfig::default() }; rpc.get_program_accounts_with_config(&program, config) .await? .into_iter() .map(|(key, account)| Ok((key, MangoAccountValue::from_bytes(&account.data[8..])?))) .collect::, _>>() } pub async fn fetch_anchor_account( rpc: &RpcClientAsync, address: &Pubkey, ) -> anyhow::Result { let account = rpc.get_account(address).await?; Ok(T::try_deserialize(&mut (&account.data as &[u8]))?) } async fn fetch_anchor_accounts( rpc: &RpcClientAsync, program: Pubkey, filters: Vec, ) -> anyhow::Result> { let account_type_filter = RpcFilterType::Memcmp(Memcmp::new_base58_encoded(0, &T::discriminator())); let config = RpcProgramAccountsConfig { filters: Some([vec![account_type_filter], filters].concat()), account_config: RpcAccountInfoConfig { encoding: Some(UiAccountEncoding::Base64), ..RpcAccountInfoConfig::default() }, ..RpcProgramAccountsConfig::default() }; rpc.get_program_accounts_with_config(&program, config) .await? .into_iter() .map(|(key, account)| Ok((key, T::try_deserialize(&mut (&account.data as &[u8]))?))) .collect() } pub async fn fetch_banks( rpc: &RpcClientAsync, program: Pubkey, group: Pubkey, ) -> anyhow::Result> { fetch_anchor_accounts::( rpc, program, vec![RpcFilterType::Memcmp(Memcmp::new_base58_encoded( 8, &group.to_bytes(), ))], ) .await } pub async fn fetch_mint_infos( rpc: &RpcClientAsync, program: Pubkey, group: Pubkey, ) -> anyhow::Result> { fetch_anchor_accounts::( rpc, program, vec![RpcFilterType::Memcmp(Memcmp::new_base58_encoded( 8, &group.to_bytes(), ))], ) .await } pub async fn fetch_serum3_markets( rpc: &RpcClientAsync, program: Pubkey, group: Pubkey, ) -> anyhow::Result> { fetch_anchor_accounts::( rpc, program, vec![RpcFilterType::Memcmp(Memcmp::new_base58_encoded( 8, &group.to_bytes(), ))], ) .await } pub async fn fetch_perp_markets( rpc: &RpcClientAsync, program: Pubkey, group: Pubkey, ) -> anyhow::Result> { fetch_anchor_accounts::( rpc, program, vec![RpcFilterType::Memcmp(Memcmp::new_base58_encoded( 8, &group.to_bytes(), ))], ) .await }