1use light_token_interface::{
6 discriminator::{ADD_TOKEN_POOL, CREATE_TOKEN_POOL},
7 CPI_AUTHORITY, LIGHT_TOKEN_PROGRAM_ID,
8};
9pub use light_token_interface::{
11 find_spl_interface_pda, find_spl_interface_pda_with_index, get_spl_interface_pda,
12 has_restricted_extensions, is_valid_spl_interface_pda, NUM_MAX_POOL_ACCOUNTS,
13};
14use solana_instruction::{AccountMeta, Instruction};
15use solana_pubkey::Pubkey;
16
17use crate::{AnchorDeserialize, AnchorSerialize};
18
19#[derive(Debug, Clone, AnchorDeserialize, AnchorSerialize, PartialEq)]
20pub struct SplInterfacePda {
21 pub pubkey: Pubkey,
22 pub bump: u8,
23 pub index: u8,
24}
25
26pub fn derive_spl_interface_pda(mint: &Pubkey, index: u8, restricted: bool) -> SplInterfacePda {
28 let (pubkey, bump) = find_spl_interface_pda_with_index(mint, index, restricted);
29 SplInterfacePda {
30 pubkey,
31 bump,
32 index,
33 }
34}
35
36pub struct CreateSplInterfacePda {
56 pub fee_payer: Pubkey,
57 pub mint: Pubkey,
58 pub token_program: Pubkey,
59 pub spl_interface_pda: Pubkey,
60 pub existing_spl_interface_pda: Option<Pubkey>,
61 pub index: u8,
62}
63
64impl CreateSplInterfacePda {
65 pub fn new(fee_payer: Pubkey, mint: Pubkey, token_program: Pubkey, restricted: bool) -> Self {
67 Self::new_with_index(fee_payer, mint, token_program, 0, restricted)
68 }
69
70 pub fn new_with_index(
73 fee_payer: Pubkey,
74 mint: Pubkey,
75 token_program: Pubkey,
76 index: u8,
77 restricted: bool,
78 ) -> Self {
79 let (spl_interface_pda, _) = find_spl_interface_pda_with_index(&mint, index, restricted);
80 let existing_spl_interface_pda = if index > 0 {
81 let (existing_pda, _) =
82 find_spl_interface_pda_with_index(&mint, index.saturating_sub(1), restricted);
83 Some(existing_pda)
84 } else {
85 None
86 };
87 Self {
88 fee_payer,
89 mint,
90 token_program,
91 spl_interface_pda,
92 existing_spl_interface_pda,
93 index,
94 }
95 }
96
97 pub fn instruction(self) -> Instruction {
98 let cpi_authority = Pubkey::from(CPI_AUTHORITY);
99
100 if self.index == 0 {
101 Instruction {
103 program_id: Pubkey::from(LIGHT_TOKEN_PROGRAM_ID),
104 accounts: vec![
105 AccountMeta::new(self.fee_payer, true),
106 AccountMeta::new(self.spl_interface_pda, false),
107 AccountMeta::new_readonly(Pubkey::default(), false), AccountMeta::new(self.mint, false),
109 AccountMeta::new_readonly(self.token_program, false),
110 AccountMeta::new_readonly(cpi_authority, false),
111 ],
112 data: CREATE_TOKEN_POOL.to_vec(),
113 }
114 } else {
115 let mut data = ADD_TOKEN_POOL.to_vec();
117 data.push(self.index);
118 Instruction {
119 program_id: Pubkey::from(LIGHT_TOKEN_PROGRAM_ID),
120 accounts: vec![
121 AccountMeta::new(self.fee_payer, true),
122 AccountMeta::new(self.spl_interface_pda, false),
123 AccountMeta::new_readonly(self.existing_spl_interface_pda.unwrap(), false),
124 AccountMeta::new_readonly(Pubkey::default(), false), AccountMeta::new(self.mint, false),
126 AccountMeta::new_readonly(self.token_program, false),
127 AccountMeta::new_readonly(cpi_authority, false),
128 ],
129 data,
130 }
131 }
132 }
133}