use solana_pubkey::Pubkey;
use spl_token_2022::{
extension::{BaseStateWithExtensions, PodStateWithExtensions},
pod::PodMint,
};
use crate::{
constants::{LIGHT_TOKEN_PROGRAM_ID, POOL_SEED, RESTRICTED_POOL_SEED},
is_restricted_extension,
};
pub const NUM_MAX_POOL_ACCOUNTS: u8 = 5;
pub fn find_spl_interface_pda(mint: &Pubkey, restricted: bool) -> (Pubkey, u8) {
find_spl_interface_pda_with_index(mint, 0, restricted)
}
pub fn find_spl_interface_pda_with_index(
mint: &Pubkey,
index: u8,
restricted: bool,
) -> (Pubkey, u8) {
let program_id = Pubkey::from(LIGHT_TOKEN_PROGRAM_ID);
let index_bytes = [index];
let seeds: &[&[u8]] = if restricted {
if index == 0 {
&[POOL_SEED, mint.as_ref(), RESTRICTED_POOL_SEED]
} else {
&[POOL_SEED, mint.as_ref(), RESTRICTED_POOL_SEED, &index_bytes]
}
} else if index == 0 {
&[POOL_SEED, mint.as_ref()]
} else {
&[POOL_SEED, mint.as_ref(), &index_bytes]
};
Pubkey::find_program_address(seeds, &program_id)
}
pub fn get_spl_interface_pda(mint: &Pubkey, restricted: bool) -> Pubkey {
find_spl_interface_pda(mint, restricted).0
}
#[inline(always)]
pub fn is_valid_spl_interface_pda(
mint_bytes: &[u8],
spl_interface_pubkey: &Pubkey,
pool_index: u8,
bump: Option<u8>,
restricted: bool,
) -> bool {
let program_id = Pubkey::from(LIGHT_TOKEN_PROGRAM_ID);
let index_bytes = [pool_index];
let pda = if let Some(bump) = bump {
let bump_bytes = [bump];
let seeds: &[&[u8]] = if restricted {
if pool_index == 0 {
&[POOL_SEED, mint_bytes, RESTRICTED_POOL_SEED, &bump_bytes]
} else {
&[
POOL_SEED,
mint_bytes,
RESTRICTED_POOL_SEED,
&index_bytes,
&bump_bytes,
]
}
} else if pool_index == 0 {
&[POOL_SEED, mint_bytes, &bump_bytes]
} else {
&[POOL_SEED, mint_bytes, &index_bytes, &bump_bytes]
};
match Pubkey::create_program_address(seeds, &program_id) {
Ok(pda) => pda,
Err(_) => return false,
}
} else {
let seeds: &[&[u8]] = if restricted {
if pool_index == 0 {
&[POOL_SEED, mint_bytes, RESTRICTED_POOL_SEED]
} else {
&[POOL_SEED, mint_bytes, RESTRICTED_POOL_SEED, &index_bytes]
}
} else if pool_index == 0 {
&[POOL_SEED, mint_bytes]
} else {
&[POOL_SEED, mint_bytes, &index_bytes]
};
Pubkey::find_program_address(seeds, &program_id).0
};
pda == *spl_interface_pubkey
}
pub fn has_restricted_extensions(mint_data: &[u8]) -> bool {
let mint = match PodStateWithExtensions::<PodMint>::unpack(mint_data) {
Ok(mint) => mint,
Err(_) => return false,
};
let extensions = match mint.get_extension_types() {
Ok(exts) => exts,
Err(_) => return false,
};
extensions.iter().any(is_restricted_extension)
}