1use borsh::BorshDeserialize;
9use borsh::BorshSerialize;
10use solana_pubkey::Pubkey;
11
12pub const CREATE_CONFIG_DISCRIMINATOR: u8 = 0;
13
14#[derive(Debug)]
16pub struct CreateConfig {
17 pub payer: solana_pubkey::Pubkey,
18
19 pub authority: solana_pubkey::Pubkey,
20
21 pub mint: solana_pubkey::Pubkey,
22
23 pub mint_config: solana_pubkey::Pubkey,
24
25 pub system_program: solana_pubkey::Pubkey,
26
27 pub token_program: solana_pubkey::Pubkey,
28}
29
30impl CreateConfig {
31 pub fn instruction(
32 &self,
33 args: CreateConfigInstructionArgs,
34 ) -> solana_instruction::Instruction {
35 self.instruction_with_remaining_accounts(args, &[])
36 }
37 #[allow(clippy::arithmetic_side_effects)]
38 #[allow(clippy::vec_init_then_push)]
39 pub fn instruction_with_remaining_accounts(
40 &self,
41 args: CreateConfigInstructionArgs,
42 remaining_accounts: &[solana_instruction::AccountMeta],
43 ) -> solana_instruction::Instruction {
44 let mut accounts = Vec::with_capacity(6 + remaining_accounts.len());
45 accounts.push(solana_instruction::AccountMeta::new(self.payer, false));
46 accounts.push(solana_instruction::AccountMeta::new_readonly(
47 self.authority,
48 true,
49 ));
50 accounts.push(solana_instruction::AccountMeta::new(self.mint, false));
51 accounts.push(solana_instruction::AccountMeta::new(
52 self.mint_config,
53 false,
54 ));
55 accounts.push(solana_instruction::AccountMeta::new_readonly(
56 self.system_program,
57 false,
58 ));
59 accounts.push(solana_instruction::AccountMeta::new_readonly(
60 self.token_program,
61 false,
62 ));
63 accounts.extend_from_slice(remaining_accounts);
64 let mut data = CreateConfigInstructionData::new().try_to_vec().unwrap();
65 let mut args = args.try_to_vec().unwrap();
66 data.append(&mut args);
67
68 solana_instruction::Instruction {
69 program_id: crate::TOKEN_ACL_ID,
70 accounts,
71 data,
72 }
73 }
74}
75
76#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
77#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
78pub struct CreateConfigInstructionData {
79 discriminator: u8,
80}
81
82impl CreateConfigInstructionData {
83 pub fn new() -> Self {
84 Self { discriminator: 0 }
85 }
86
87 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
88 borsh::to_vec(self)
89 }
90}
91
92impl Default for CreateConfigInstructionData {
93 fn default() -> Self {
94 Self::new()
95 }
96}
97
98#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
99#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
100pub struct CreateConfigInstructionArgs {
101 pub gating_program: Pubkey,
102}
103
104impl CreateConfigInstructionArgs {
105 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
106 borsh::to_vec(self)
107 }
108}
109
110#[derive(Clone, Debug, Default)]
121pub struct CreateConfigBuilder {
122 payer: Option<solana_pubkey::Pubkey>,
123 authority: Option<solana_pubkey::Pubkey>,
124 mint: Option<solana_pubkey::Pubkey>,
125 mint_config: Option<solana_pubkey::Pubkey>,
126 system_program: Option<solana_pubkey::Pubkey>,
127 token_program: Option<solana_pubkey::Pubkey>,
128 gating_program: Option<Pubkey>,
129 __remaining_accounts: Vec<solana_instruction::AccountMeta>,
130}
131
132impl CreateConfigBuilder {
133 pub fn new() -> Self {
134 Self::default()
135 }
136 #[inline(always)]
137 pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self {
138 self.payer = Some(payer);
139 self
140 }
141 #[inline(always)]
142 pub fn authority(&mut self, authority: solana_pubkey::Pubkey) -> &mut Self {
143 self.authority = Some(authority);
144 self
145 }
146 #[inline(always)]
147 pub fn mint(&mut self, mint: solana_pubkey::Pubkey) -> &mut Self {
148 self.mint = Some(mint);
149 self
150 }
151 #[inline(always)]
152 pub fn mint_config(&mut self, mint_config: solana_pubkey::Pubkey) -> &mut Self {
153 self.mint_config = Some(mint_config);
154 self
155 }
156 #[inline(always)]
158 pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self {
159 self.system_program = Some(system_program);
160 self
161 }
162 #[inline(always)]
164 pub fn token_program(&mut self, token_program: solana_pubkey::Pubkey) -> &mut Self {
165 self.token_program = Some(token_program);
166 self
167 }
168 #[inline(always)]
169 pub fn gating_program(&mut self, gating_program: Pubkey) -> &mut Self {
170 self.gating_program = Some(gating_program);
171 self
172 }
173 #[inline(always)]
175 pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self {
176 self.__remaining_accounts.push(account);
177 self
178 }
179 #[inline(always)]
181 pub fn add_remaining_accounts(
182 &mut self,
183 accounts: &[solana_instruction::AccountMeta],
184 ) -> &mut Self {
185 self.__remaining_accounts.extend_from_slice(accounts);
186 self
187 }
188 #[allow(clippy::clone_on_copy)]
189 pub fn instruction(&self) -> solana_instruction::Instruction {
190 let accounts = CreateConfig {
191 payer: self.payer.expect("payer is not set"),
192 authority: self.authority.expect("authority is not set"),
193 mint: self.mint.expect("mint is not set"),
194 mint_config: self.mint_config.expect("mint_config is not set"),
195 system_program: self
196 .system_program
197 .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")),
198 token_program: self.token_program.unwrap_or(solana_pubkey::pubkey!(
199 "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
200 )),
201 };
202 let args = CreateConfigInstructionArgs {
203 gating_program: self
204 .gating_program
205 .clone()
206 .expect("gating_program is not set"),
207 };
208
209 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
210 }
211}
212
213pub struct CreateConfigCpiAccounts<'a, 'b> {
215 pub payer: &'b solana_account_info::AccountInfo<'a>,
216
217 pub authority: &'b solana_account_info::AccountInfo<'a>,
218
219 pub mint: &'b solana_account_info::AccountInfo<'a>,
220
221 pub mint_config: &'b solana_account_info::AccountInfo<'a>,
222
223 pub system_program: &'b solana_account_info::AccountInfo<'a>,
224
225 pub token_program: &'b solana_account_info::AccountInfo<'a>,
226}
227
228pub struct CreateConfigCpi<'a, 'b> {
230 pub __program: &'b solana_account_info::AccountInfo<'a>,
232
233 pub payer: &'b solana_account_info::AccountInfo<'a>,
234
235 pub authority: &'b solana_account_info::AccountInfo<'a>,
236
237 pub mint: &'b solana_account_info::AccountInfo<'a>,
238
239 pub mint_config: &'b solana_account_info::AccountInfo<'a>,
240
241 pub system_program: &'b solana_account_info::AccountInfo<'a>,
242
243 pub token_program: &'b solana_account_info::AccountInfo<'a>,
244 pub __args: CreateConfigInstructionArgs,
246}
247
248impl<'a, 'b> CreateConfigCpi<'a, 'b> {
249 pub fn new(
250 program: &'b solana_account_info::AccountInfo<'a>,
251 accounts: CreateConfigCpiAccounts<'a, 'b>,
252 args: CreateConfigInstructionArgs,
253 ) -> Self {
254 Self {
255 __program: program,
256 payer: accounts.payer,
257 authority: accounts.authority,
258 mint: accounts.mint,
259 mint_config: accounts.mint_config,
260 system_program: accounts.system_program,
261 token_program: accounts.token_program,
262 __args: args,
263 }
264 }
265 #[inline(always)]
266 pub fn invoke(&self) -> solana_program_error::ProgramResult {
267 self.invoke_signed_with_remaining_accounts(&[], &[])
268 }
269 #[inline(always)]
270 pub fn invoke_with_remaining_accounts(
271 &self,
272 remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)],
273 ) -> solana_program_error::ProgramResult {
274 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
275 }
276 #[inline(always)]
277 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult {
278 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
279 }
280 #[allow(clippy::arithmetic_side_effects)]
281 #[allow(clippy::clone_on_copy)]
282 #[allow(clippy::vec_init_then_push)]
283 pub fn invoke_signed_with_remaining_accounts(
284 &self,
285 signers_seeds: &[&[&[u8]]],
286 remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)],
287 ) -> solana_program_error::ProgramResult {
288 let mut accounts = Vec::with_capacity(6 + remaining_accounts.len());
289 accounts.push(solana_instruction::AccountMeta::new(*self.payer.key, false));
290 accounts.push(solana_instruction::AccountMeta::new_readonly(
291 *self.authority.key,
292 true,
293 ));
294 accounts.push(solana_instruction::AccountMeta::new(*self.mint.key, false));
295 accounts.push(solana_instruction::AccountMeta::new(
296 *self.mint_config.key,
297 false,
298 ));
299 accounts.push(solana_instruction::AccountMeta::new_readonly(
300 *self.system_program.key,
301 false,
302 ));
303 accounts.push(solana_instruction::AccountMeta::new_readonly(
304 *self.token_program.key,
305 false,
306 ));
307 remaining_accounts.iter().for_each(|remaining_account| {
308 accounts.push(solana_instruction::AccountMeta {
309 pubkey: *remaining_account.0.key,
310 is_signer: remaining_account.1,
311 is_writable: remaining_account.2,
312 })
313 });
314 let mut data = CreateConfigInstructionData::new().try_to_vec().unwrap();
315 let mut args = self.__args.try_to_vec().unwrap();
316 data.append(&mut args);
317
318 let instruction = solana_instruction::Instruction {
319 program_id: crate::TOKEN_ACL_ID,
320 accounts,
321 data,
322 };
323 let mut account_infos = Vec::with_capacity(7 + remaining_accounts.len());
324 account_infos.push(self.__program.clone());
325 account_infos.push(self.payer.clone());
326 account_infos.push(self.authority.clone());
327 account_infos.push(self.mint.clone());
328 account_infos.push(self.mint_config.clone());
329 account_infos.push(self.system_program.clone());
330 account_infos.push(self.token_program.clone());
331 remaining_accounts
332 .iter()
333 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
334
335 if signers_seeds.is_empty() {
336 solana_cpi::invoke(&instruction, &account_infos)
337 } else {
338 solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds)
339 }
340 }
341}
342
343#[derive(Clone, Debug)]
354pub struct CreateConfigCpiBuilder<'a, 'b> {
355 instruction: Box<CreateConfigCpiBuilderInstruction<'a, 'b>>,
356}
357
358impl<'a, 'b> CreateConfigCpiBuilder<'a, 'b> {
359 pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self {
360 let instruction = Box::new(CreateConfigCpiBuilderInstruction {
361 __program: program,
362 payer: None,
363 authority: None,
364 mint: None,
365 mint_config: None,
366 system_program: None,
367 token_program: None,
368 gating_program: None,
369 __remaining_accounts: Vec::new(),
370 });
371 Self { instruction }
372 }
373 #[inline(always)]
374 pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
375 self.instruction.payer = Some(payer);
376 self
377 }
378 #[inline(always)]
379 pub fn authority(&mut self, authority: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
380 self.instruction.authority = Some(authority);
381 self
382 }
383 #[inline(always)]
384 pub fn mint(&mut self, mint: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
385 self.instruction.mint = Some(mint);
386 self
387 }
388 #[inline(always)]
389 pub fn mint_config(
390 &mut self,
391 mint_config: &'b solana_account_info::AccountInfo<'a>,
392 ) -> &mut Self {
393 self.instruction.mint_config = Some(mint_config);
394 self
395 }
396 #[inline(always)]
397 pub fn system_program(
398 &mut self,
399 system_program: &'b solana_account_info::AccountInfo<'a>,
400 ) -> &mut Self {
401 self.instruction.system_program = Some(system_program);
402 self
403 }
404 #[inline(always)]
405 pub fn token_program(
406 &mut self,
407 token_program: &'b solana_account_info::AccountInfo<'a>,
408 ) -> &mut Self {
409 self.instruction.token_program = Some(token_program);
410 self
411 }
412 #[inline(always)]
413 pub fn gating_program(&mut self, gating_program: Pubkey) -> &mut Self {
414 self.instruction.gating_program = Some(gating_program);
415 self
416 }
417 #[inline(always)]
419 pub fn add_remaining_account(
420 &mut self,
421 account: &'b solana_account_info::AccountInfo<'a>,
422 is_writable: bool,
423 is_signer: bool,
424 ) -> &mut Self {
425 self.instruction
426 .__remaining_accounts
427 .push((account, is_writable, is_signer));
428 self
429 }
430 #[inline(always)]
435 pub fn add_remaining_accounts(
436 &mut self,
437 accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)],
438 ) -> &mut Self {
439 self.instruction
440 .__remaining_accounts
441 .extend_from_slice(accounts);
442 self
443 }
444 #[inline(always)]
445 pub fn invoke(&self) -> solana_program_error::ProgramResult {
446 self.invoke_signed(&[])
447 }
448 #[allow(clippy::clone_on_copy)]
449 #[allow(clippy::vec_init_then_push)]
450 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult {
451 let args = CreateConfigInstructionArgs {
452 gating_program: self
453 .instruction
454 .gating_program
455 .clone()
456 .expect("gating_program is not set"),
457 };
458 let instruction = CreateConfigCpi {
459 __program: self.instruction.__program,
460
461 payer: self.instruction.payer.expect("payer is not set"),
462
463 authority: self.instruction.authority.expect("authority is not set"),
464
465 mint: self.instruction.mint.expect("mint is not set"),
466
467 mint_config: self
468 .instruction
469 .mint_config
470 .expect("mint_config is not set"),
471
472 system_program: self
473 .instruction
474 .system_program
475 .expect("system_program is not set"),
476
477 token_program: self
478 .instruction
479 .token_program
480 .expect("token_program is not set"),
481 __args: args,
482 };
483 instruction.invoke_signed_with_remaining_accounts(
484 signers_seeds,
485 &self.instruction.__remaining_accounts,
486 )
487 }
488}
489
490#[derive(Clone, Debug)]
491struct CreateConfigCpiBuilderInstruction<'a, 'b> {
492 __program: &'b solana_account_info::AccountInfo<'a>,
493 payer: Option<&'b solana_account_info::AccountInfo<'a>>,
494 authority: Option<&'b solana_account_info::AccountInfo<'a>>,
495 mint: Option<&'b solana_account_info::AccountInfo<'a>>,
496 mint_config: Option<&'b solana_account_info::AccountInfo<'a>>,
497 system_program: Option<&'b solana_account_info::AccountInfo<'a>>,
498 token_program: Option<&'b solana_account_info::AccountInfo<'a>>,
499 gating_program: Option<Pubkey>,
500 __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>,
502}