use {
crate::{
token::{self, GenericTokenAccount, GenericTokenMint},
token_2022,
},
solana_pubkey::Pubkey,
};
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Account {
pub mint: Pubkey,
pub owner: Pubkey,
pub amount: u64,
}
impl Account {
pub fn unpack(account_data: &[u8], program_id: &Pubkey) -> Option<Self> {
let (mint, owner, amount) = if *program_id == token::id() {
token::Account::valid_account_data(account_data).then_some(())?;
let mint = token::Account::unpack_account_mint_unchecked(account_data);
let owner = token::Account::unpack_account_owner_unchecked(account_data);
let amount = token::Account::unpack_account_amount_unchecked(account_data);
(*mint, *owner, amount)
} else if *program_id == token_2022::id() {
token_2022::Account::valid_account_data(account_data).then_some(())?;
let mint = token_2022::Account::unpack_account_mint_unchecked(account_data);
let owner = token_2022::Account::unpack_account_owner_unchecked(account_data);
let amount = token_2022::Account::unpack_account_amount_unchecked(account_data);
(*mint, *owner, amount)
} else {
return None;
};
Some(Self {
mint,
owner,
amount,
})
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Mint {
pub supply: u64,
pub decimals: u8,
}
impl Mint {
pub fn unpack(account_data: &[u8], program_id: &Pubkey) -> Option<Self> {
let (supply, decimals) = if *program_id == token::id() {
token::Mint::valid_account_data(account_data).then_some(())?;
let supply = token::Mint::unpack_mint_supply_unchecked(account_data);
let decimals = token::Mint::unpack_mint_decimals_unchecked(account_data);
(supply, decimals)
} else if *program_id == token_2022::id() {
token_2022::Mint::valid_account_data(account_data).then_some(())?;
let supply = token_2022::Mint::unpack_mint_supply_unchecked(account_data);
let decimals = token_2022::Mint::unpack_mint_decimals_unchecked(account_data);
(supply, decimals)
} else {
return None;
};
Some(Self { supply, decimals })
}
}