use crate::accounts::{
OneBtcVaultEntry, PublicDeployment, ONE_BTC_VAULT_ENTRY_DISCRIMINATOR, PUBLIC_DEPLOYMENT_DISCRIMINATOR,
};
use crate::shared::DecodedAccount;
use crate::SATRUSH_ID;
use solana_account_decoder::UiAccountEncoding;
use solana_pubkey::Pubkey;
use solana_rpc_client::rpc_client::RpcClient;
use solana_rpc_client_api::config::{RpcAccountInfoConfig, RpcProgramAccountsConfig};
use solana_rpc_client_api::filter::{Memcmp, RpcFilterType};
const PUBLIC_DEPLOYMENT_AUTHORITY_OFFSET: usize = 8 + 2 + 1;
pub fn fetch_public_deployments_by_authority(
rpc: &RpcClient,
authority: &Pubkey,
) -> Result<Vec<DecodedAccount<PublicDeployment>>, std::io::Error> {
let config = RpcProgramAccountsConfig {
filters: Some(vec![
RpcFilterType::Memcmp(Memcmp::new_base58_encoded(0, &PUBLIC_DEPLOYMENT_DISCRIMINATOR)),
RpcFilterType::Memcmp(Memcmp::new_base58_encoded(PUBLIC_DEPLOYMENT_AUTHORITY_OFFSET, authority.as_ref())),
]),
account_config: RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Base64),
..Default::default()
},
..Default::default()
};
let accounts = rpc
.get_program_ui_accounts_with_config(&SATRUSH_ID, config)
.map_err(|e| std::io::Error::other(e.to_string()))?;
accounts
.into_iter()
.map(|(address, ui_account)| {
let account: solana_account::Account = ui_account
.decode()
.ok_or_else(|| std::io::Error::other(format!("failed to decode account {address}")))?;
let data = PublicDeployment::from_bytes(&account.data)?;
Ok(DecodedAccount { address, account, data })
})
.collect()
}
const ONE_BTC_ENTRY_ITERATION_OFFSET: usize = 8 + 2;
const ONE_BTC_ENTRY_AUTHORITY_OFFSET: usize = ONE_BTC_ENTRY_ITERATION_OFFSET + 4;
pub fn fetch_one_btc_vault_entries_by_authority(
rpc: &RpcClient,
authority: &Pubkey,
iteration_id: u32,
) -> Result<Vec<DecodedAccount<OneBtcVaultEntry>>, std::io::Error> {
let config = RpcProgramAccountsConfig {
filters: Some(vec![
RpcFilterType::Memcmp(Memcmp::new_base58_encoded(0, &ONE_BTC_VAULT_ENTRY_DISCRIMINATOR)),
RpcFilterType::Memcmp(Memcmp::new_base58_encoded(
ONE_BTC_ENTRY_ITERATION_OFFSET,
&iteration_id.to_le_bytes(),
)),
RpcFilterType::Memcmp(Memcmp::new_base58_encoded(ONE_BTC_ENTRY_AUTHORITY_OFFSET, authority.as_ref())),
]),
account_config: RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Base64),
..Default::default()
},
..Default::default()
};
let accounts = rpc
.get_program_ui_accounts_with_config(&SATRUSH_ID, config)
.map_err(|e| std::io::Error::other(e.to_string()))?;
accounts
.into_iter()
.map(|(address, ui_account)| {
let account: solana_account::Account = ui_account
.decode()
.ok_or_else(|| std::io::Error::other(format!("failed to decode account {address}")))?;
let data = OneBtcVaultEntry::from_bytes(&account.data)?;
Ok(DecodedAccount { address, account, data })
})
.collect()
}