use light_token_interface::{
discriminator::{ADD_TOKEN_POOL, CREATE_TOKEN_POOL},
CPI_AUTHORITY, LIGHT_TOKEN_PROGRAM_ID,
};
pub use light_token_interface::{
find_spl_interface_pda, find_spl_interface_pda_with_index, get_spl_interface_pda,
has_restricted_extensions, is_valid_spl_interface_pda, NUM_MAX_POOL_ACCOUNTS,
};
use solana_instruction::{AccountMeta, Instruction};
use solana_pubkey::Pubkey;
use crate::{AnchorDeserialize, AnchorSerialize};
#[derive(Debug, Clone, AnchorDeserialize, AnchorSerialize, PartialEq)]
pub struct SplInterfacePda {
pub pubkey: Pubkey,
pub bump: u8,
pub index: u8,
}
pub fn derive_spl_interface_pda(mint: &Pubkey, index: u8, restricted: bool) -> SplInterfacePda {
let (pubkey, bump) = find_spl_interface_pda_with_index(mint, index, restricted);
SplInterfacePda {
pubkey,
bump,
index,
}
}
pub struct CreateSplInterfacePda {
pub fee_payer: Pubkey,
pub mint: Pubkey,
pub token_program: Pubkey,
pub spl_interface_pda: Pubkey,
pub existing_spl_interface_pda: Option<Pubkey>,
pub index: u8,
}
impl CreateSplInterfacePda {
pub fn new(fee_payer: Pubkey, mint: Pubkey, token_program: Pubkey, restricted: bool) -> Self {
Self::new_with_index(fee_payer, mint, token_program, 0, restricted)
}
pub fn new_with_index(
fee_payer: Pubkey,
mint: Pubkey,
token_program: Pubkey,
index: u8,
restricted: bool,
) -> Self {
let (spl_interface_pda, _) = find_spl_interface_pda_with_index(&mint, index, restricted);
let existing_spl_interface_pda = if index > 0 {
let (existing_pda, _) =
find_spl_interface_pda_with_index(&mint, index.saturating_sub(1), restricted);
Some(existing_pda)
} else {
None
};
Self {
fee_payer,
mint,
token_program,
spl_interface_pda,
existing_spl_interface_pda,
index,
}
}
pub fn instruction(self) -> Instruction {
let cpi_authority = Pubkey::from(CPI_AUTHORITY);
if self.index == 0 {
Instruction {
program_id: Pubkey::from(LIGHT_TOKEN_PROGRAM_ID),
accounts: vec![
AccountMeta::new(self.fee_payer, true),
AccountMeta::new(self.spl_interface_pda, false),
AccountMeta::new_readonly(Pubkey::default(), false), AccountMeta::new(self.mint, false),
AccountMeta::new_readonly(self.token_program, false),
AccountMeta::new_readonly(cpi_authority, false),
],
data: CREATE_TOKEN_POOL.to_vec(),
}
} else {
let mut data = ADD_TOKEN_POOL.to_vec();
data.push(self.index);
Instruction {
program_id: Pubkey::from(LIGHT_TOKEN_PROGRAM_ID),
accounts: vec![
AccountMeta::new(self.fee_payer, true),
AccountMeta::new(self.spl_interface_pda, false),
AccountMeta::new_readonly(self.existing_spl_interface_pda.unwrap(), false),
AccountMeta::new_readonly(Pubkey::default(), false), AccountMeta::new(self.mint, false),
AccountMeta::new_readonly(self.token_program, false),
AccountMeta::new_readonly(cpi_authority, false),
],
data,
}
}
}
}