1use borsh::BorshDeserialize;
9use borsh::BorshSerialize;
10
11pub struct Utilize {
13 pub metadata: solana_program::pubkey::Pubkey,
15 pub token_account: solana_program::pubkey::Pubkey,
17 pub mint: solana_program::pubkey::Pubkey,
19 pub use_authority: solana_program::pubkey::Pubkey,
21 pub owner: solana_program::pubkey::Pubkey,
23 pub token_program: solana_program::pubkey::Pubkey,
25 pub ata_program: solana_program::pubkey::Pubkey,
27 pub system_program: solana_program::pubkey::Pubkey,
29 pub rent: solana_program::pubkey::Pubkey,
31 pub use_authority_record: Option<solana_program::pubkey::Pubkey>,
33 pub burner: Option<solana_program::pubkey::Pubkey>,
35}
36
37impl Utilize {
38 pub fn instruction(
39 &self,
40 args: UtilizeInstructionArgs,
41 ) -> solana_program::instruction::Instruction {
42 self.instruction_with_remaining_accounts(args, &[])
43 }
44 #[allow(clippy::vec_init_then_push)]
45 pub fn instruction_with_remaining_accounts(
46 &self,
47 args: UtilizeInstructionArgs,
48 remaining_accounts: &[solana_program::instruction::AccountMeta],
49 ) -> solana_program::instruction::Instruction {
50 let mut accounts = Vec::with_capacity(11 + remaining_accounts.len());
51 accounts.push(solana_program::instruction::AccountMeta::new(
52 self.metadata,
53 false,
54 ));
55 accounts.push(solana_program::instruction::AccountMeta::new(
56 self.token_account,
57 false,
58 ));
59 accounts.push(solana_program::instruction::AccountMeta::new(
60 self.mint, false,
61 ));
62 accounts.push(solana_program::instruction::AccountMeta::new(
63 self.use_authority,
64 true,
65 ));
66 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
67 self.owner, false,
68 ));
69 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
70 self.token_program,
71 false,
72 ));
73 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
74 self.ata_program,
75 false,
76 ));
77 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
78 self.system_program,
79 false,
80 ));
81 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
82 self.rent, false,
83 ));
84 if let Some(use_authority_record) = self.use_authority_record {
85 accounts.push(solana_program::instruction::AccountMeta::new(
86 use_authority_record,
87 false,
88 ));
89 }
90 if let Some(burner) = self.burner {
91 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
92 burner, false,
93 ));
94 }
95 accounts.extend_from_slice(remaining_accounts);
96 let mut data = UtilizeInstructionData::new().try_to_vec().unwrap();
97 let mut args = args.try_to_vec().unwrap();
98 data.append(&mut args);
99
100 solana_program::instruction::Instruction {
101 program_id: crate::MPL_TOKEN_METADATA_ID,
102 accounts,
103 data,
104 }
105 }
106}
107
108#[derive(BorshDeserialize, BorshSerialize)]
109struct UtilizeInstructionData {
110 discriminator: u8,
111}
112
113impl UtilizeInstructionData {
114 fn new() -> Self {
115 Self { discriminator: 19 }
116 }
117}
118
119#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
120#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
121pub struct UtilizeInstructionArgs {
122 pub number_of_uses: u64,
123}
124
125#[derive(Default)]
141pub struct UtilizeBuilder {
142 metadata: Option<solana_program::pubkey::Pubkey>,
143 token_account: Option<solana_program::pubkey::Pubkey>,
144 mint: Option<solana_program::pubkey::Pubkey>,
145 use_authority: Option<solana_program::pubkey::Pubkey>,
146 owner: Option<solana_program::pubkey::Pubkey>,
147 token_program: Option<solana_program::pubkey::Pubkey>,
148 ata_program: Option<solana_program::pubkey::Pubkey>,
149 system_program: Option<solana_program::pubkey::Pubkey>,
150 rent: Option<solana_program::pubkey::Pubkey>,
151 use_authority_record: Option<solana_program::pubkey::Pubkey>,
152 burner: Option<solana_program::pubkey::Pubkey>,
153 number_of_uses: Option<u64>,
154 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
155}
156
157impl UtilizeBuilder {
158 pub fn new() -> Self {
159 Self::default()
160 }
161 #[inline(always)]
163 pub fn metadata(&mut self, metadata: solana_program::pubkey::Pubkey) -> &mut Self {
164 self.metadata = Some(metadata);
165 self
166 }
167 #[inline(always)]
169 pub fn token_account(&mut self, token_account: solana_program::pubkey::Pubkey) -> &mut Self {
170 self.token_account = Some(token_account);
171 self
172 }
173 #[inline(always)]
175 pub fn mint(&mut self, mint: solana_program::pubkey::Pubkey) -> &mut Self {
176 self.mint = Some(mint);
177 self
178 }
179 #[inline(always)]
181 pub fn use_authority(&mut self, use_authority: solana_program::pubkey::Pubkey) -> &mut Self {
182 self.use_authority = Some(use_authority);
183 self
184 }
185 #[inline(always)]
187 pub fn owner(&mut self, owner: solana_program::pubkey::Pubkey) -> &mut Self {
188 self.owner = Some(owner);
189 self
190 }
191 #[inline(always)]
194 pub fn token_program(&mut self, token_program: solana_program::pubkey::Pubkey) -> &mut Self {
195 self.token_program = Some(token_program);
196 self
197 }
198 #[inline(always)]
201 pub fn ata_program(&mut self, ata_program: solana_program::pubkey::Pubkey) -> &mut Self {
202 self.ata_program = Some(ata_program);
203 self
204 }
205 #[inline(always)]
208 pub fn system_program(&mut self, system_program: solana_program::pubkey::Pubkey) -> &mut Self {
209 self.system_program = Some(system_program);
210 self
211 }
212 #[inline(always)]
215 pub fn rent(&mut self, rent: solana_program::pubkey::Pubkey) -> &mut Self {
216 self.rent = Some(rent);
217 self
218 }
219 #[inline(always)]
222 pub fn use_authority_record(
223 &mut self,
224 use_authority_record: Option<solana_program::pubkey::Pubkey>,
225 ) -> &mut Self {
226 self.use_authority_record = use_authority_record;
227 self
228 }
229 #[inline(always)]
232 pub fn burner(&mut self, burner: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
233 self.burner = burner;
234 self
235 }
236 #[inline(always)]
237 pub fn number_of_uses(&mut self, number_of_uses: u64) -> &mut Self {
238 self.number_of_uses = Some(number_of_uses);
239 self
240 }
241 #[inline(always)]
243 pub fn add_remaining_account(
244 &mut self,
245 account: solana_program::instruction::AccountMeta,
246 ) -> &mut Self {
247 self.__remaining_accounts.push(account);
248 self
249 }
250 #[inline(always)]
252 pub fn add_remaining_accounts(
253 &mut self,
254 accounts: &[solana_program::instruction::AccountMeta],
255 ) -> &mut Self {
256 self.__remaining_accounts.extend_from_slice(accounts);
257 self
258 }
259 #[allow(clippy::clone_on_copy)]
260 pub fn instruction(&self) -> solana_program::instruction::Instruction {
261 let accounts = Utilize {
262 metadata: self.metadata.expect("metadata is not set"),
263 token_account: self.token_account.expect("token_account is not set"),
264 mint: self.mint.expect("mint is not set"),
265 use_authority: self.use_authority.expect("use_authority is not set"),
266 owner: self.owner.expect("owner is not set"),
267 token_program: self.token_program.unwrap_or(solana_program::pubkey!(
268 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
269 )),
270 ata_program: self.ata_program.unwrap_or(solana_program::pubkey!(
271 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
272 )),
273 system_program: self
274 .system_program
275 .unwrap_or(solana_program::pubkey!("11111111111111111111111111111111")),
276 rent: self.rent.unwrap_or(solana_program::pubkey!(
277 "SysvarRent111111111111111111111111111111111"
278 )),
279 use_authority_record: self.use_authority_record,
280 burner: self.burner,
281 };
282 let args = UtilizeInstructionArgs {
283 number_of_uses: self
284 .number_of_uses
285 .clone()
286 .expect("number_of_uses is not set"),
287 };
288
289 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
290 }
291}
292
293pub struct UtilizeCpiAccounts<'a, 'b> {
295 pub metadata: &'b solana_program::account_info::AccountInfo<'a>,
297 pub token_account: &'b solana_program::account_info::AccountInfo<'a>,
299 pub mint: &'b solana_program::account_info::AccountInfo<'a>,
301 pub use_authority: &'b solana_program::account_info::AccountInfo<'a>,
303 pub owner: &'b solana_program::account_info::AccountInfo<'a>,
305 pub token_program: &'b solana_program::account_info::AccountInfo<'a>,
307 pub ata_program: &'b solana_program::account_info::AccountInfo<'a>,
309 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
311 pub rent: &'b solana_program::account_info::AccountInfo<'a>,
313 pub use_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
315 pub burner: Option<&'b solana_program::account_info::AccountInfo<'a>>,
317}
318
319pub struct UtilizeCpi<'a, 'b> {
321 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
323 pub metadata: &'b solana_program::account_info::AccountInfo<'a>,
325 pub token_account: &'b solana_program::account_info::AccountInfo<'a>,
327 pub mint: &'b solana_program::account_info::AccountInfo<'a>,
329 pub use_authority: &'b solana_program::account_info::AccountInfo<'a>,
331 pub owner: &'b solana_program::account_info::AccountInfo<'a>,
333 pub token_program: &'b solana_program::account_info::AccountInfo<'a>,
335 pub ata_program: &'b solana_program::account_info::AccountInfo<'a>,
337 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
339 pub rent: &'b solana_program::account_info::AccountInfo<'a>,
341 pub use_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
343 pub burner: Option<&'b solana_program::account_info::AccountInfo<'a>>,
345 pub __args: UtilizeInstructionArgs,
347}
348
349impl<'a, 'b> UtilizeCpi<'a, 'b> {
350 pub fn new(
351 program: &'b solana_program::account_info::AccountInfo<'a>,
352 accounts: UtilizeCpiAccounts<'a, 'b>,
353 args: UtilizeInstructionArgs,
354 ) -> Self {
355 Self {
356 __program: program,
357 metadata: accounts.metadata,
358 token_account: accounts.token_account,
359 mint: accounts.mint,
360 use_authority: accounts.use_authority,
361 owner: accounts.owner,
362 token_program: accounts.token_program,
363 ata_program: accounts.ata_program,
364 system_program: accounts.system_program,
365 rent: accounts.rent,
366 use_authority_record: accounts.use_authority_record,
367 burner: accounts.burner,
368 __args: args,
369 }
370 }
371 #[inline(always)]
372 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
373 self.invoke_signed_with_remaining_accounts(&[], &[])
374 }
375 #[inline(always)]
376 pub fn invoke_with_remaining_accounts(
377 &self,
378 remaining_accounts: &[(
379 &'b solana_program::account_info::AccountInfo<'a>,
380 bool,
381 bool,
382 )],
383 ) -> solana_program::entrypoint::ProgramResult {
384 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
385 }
386 #[inline(always)]
387 pub fn invoke_signed(
388 &self,
389 signers_seeds: &[&[&[u8]]],
390 ) -> solana_program::entrypoint::ProgramResult {
391 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
392 }
393 #[allow(clippy::clone_on_copy)]
394 #[allow(clippy::vec_init_then_push)]
395 pub fn invoke_signed_with_remaining_accounts(
396 &self,
397 signers_seeds: &[&[&[u8]]],
398 remaining_accounts: &[(
399 &'b solana_program::account_info::AccountInfo<'a>,
400 bool,
401 bool,
402 )],
403 ) -> solana_program::entrypoint::ProgramResult {
404 let mut accounts = Vec::with_capacity(11 + remaining_accounts.len());
405 accounts.push(solana_program::instruction::AccountMeta::new(
406 *self.metadata.key,
407 false,
408 ));
409 accounts.push(solana_program::instruction::AccountMeta::new(
410 *self.token_account.key,
411 false,
412 ));
413 accounts.push(solana_program::instruction::AccountMeta::new(
414 *self.mint.key,
415 false,
416 ));
417 accounts.push(solana_program::instruction::AccountMeta::new(
418 *self.use_authority.key,
419 true,
420 ));
421 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
422 *self.owner.key,
423 false,
424 ));
425 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
426 *self.token_program.key,
427 false,
428 ));
429 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
430 *self.ata_program.key,
431 false,
432 ));
433 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
434 *self.system_program.key,
435 false,
436 ));
437 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
438 *self.rent.key,
439 false,
440 ));
441 if let Some(use_authority_record) = self.use_authority_record {
442 accounts.push(solana_program::instruction::AccountMeta::new(
443 *use_authority_record.key,
444 false,
445 ));
446 }
447 if let Some(burner) = self.burner {
448 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
449 *burner.key,
450 false,
451 ));
452 }
453 remaining_accounts.iter().for_each(|remaining_account| {
454 accounts.push(solana_program::instruction::AccountMeta {
455 pubkey: *remaining_account.0.key,
456 is_signer: remaining_account.1,
457 is_writable: remaining_account.2,
458 })
459 });
460 let mut data = UtilizeInstructionData::new().try_to_vec().unwrap();
461 let mut args = self.__args.try_to_vec().unwrap();
462 data.append(&mut args);
463
464 let instruction = solana_program::instruction::Instruction {
465 program_id: crate::MPL_TOKEN_METADATA_ID,
466 accounts,
467 data,
468 };
469 let mut account_infos = Vec::with_capacity(11 + 1 + remaining_accounts.len());
470 account_infos.push(self.__program.clone());
471 account_infos.push(self.metadata.clone());
472 account_infos.push(self.token_account.clone());
473 account_infos.push(self.mint.clone());
474 account_infos.push(self.use_authority.clone());
475 account_infos.push(self.owner.clone());
476 account_infos.push(self.token_program.clone());
477 account_infos.push(self.ata_program.clone());
478 account_infos.push(self.system_program.clone());
479 account_infos.push(self.rent.clone());
480 if let Some(use_authority_record) = self.use_authority_record {
481 account_infos.push(use_authority_record.clone());
482 }
483 if let Some(burner) = self.burner {
484 account_infos.push(burner.clone());
485 }
486 remaining_accounts
487 .iter()
488 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
489
490 if signers_seeds.is_empty() {
491 solana_program::program::invoke(&instruction, &account_infos)
492 } else {
493 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
494 }
495 }
496}
497
498pub struct UtilizeCpiBuilder<'a, 'b> {
514 instruction: Box<UtilizeCpiBuilderInstruction<'a, 'b>>,
515}
516
517impl<'a, 'b> UtilizeCpiBuilder<'a, 'b> {
518 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
519 let instruction = Box::new(UtilizeCpiBuilderInstruction {
520 __program: program,
521 metadata: None,
522 token_account: None,
523 mint: None,
524 use_authority: None,
525 owner: None,
526 token_program: None,
527 ata_program: None,
528 system_program: None,
529 rent: None,
530 use_authority_record: None,
531 burner: None,
532 number_of_uses: None,
533 __remaining_accounts: Vec::new(),
534 });
535 Self { instruction }
536 }
537 #[inline(always)]
539 pub fn metadata(
540 &mut self,
541 metadata: &'b solana_program::account_info::AccountInfo<'a>,
542 ) -> &mut Self {
543 self.instruction.metadata = Some(metadata);
544 self
545 }
546 #[inline(always)]
548 pub fn token_account(
549 &mut self,
550 token_account: &'b solana_program::account_info::AccountInfo<'a>,
551 ) -> &mut Self {
552 self.instruction.token_account = Some(token_account);
553 self
554 }
555 #[inline(always)]
557 pub fn mint(&mut self, mint: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
558 self.instruction.mint = Some(mint);
559 self
560 }
561 #[inline(always)]
563 pub fn use_authority(
564 &mut self,
565 use_authority: &'b solana_program::account_info::AccountInfo<'a>,
566 ) -> &mut Self {
567 self.instruction.use_authority = Some(use_authority);
568 self
569 }
570 #[inline(always)]
572 pub fn owner(&mut self, owner: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
573 self.instruction.owner = Some(owner);
574 self
575 }
576 #[inline(always)]
578 pub fn token_program(
579 &mut self,
580 token_program: &'b solana_program::account_info::AccountInfo<'a>,
581 ) -> &mut Self {
582 self.instruction.token_program = Some(token_program);
583 self
584 }
585 #[inline(always)]
587 pub fn ata_program(
588 &mut self,
589 ata_program: &'b solana_program::account_info::AccountInfo<'a>,
590 ) -> &mut Self {
591 self.instruction.ata_program = Some(ata_program);
592 self
593 }
594 #[inline(always)]
596 pub fn system_program(
597 &mut self,
598 system_program: &'b solana_program::account_info::AccountInfo<'a>,
599 ) -> &mut Self {
600 self.instruction.system_program = Some(system_program);
601 self
602 }
603 #[inline(always)]
605 pub fn rent(&mut self, rent: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
606 self.instruction.rent = Some(rent);
607 self
608 }
609 #[inline(always)]
612 pub fn use_authority_record(
613 &mut self,
614 use_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
615 ) -> &mut Self {
616 self.instruction.use_authority_record = use_authority_record;
617 self
618 }
619 #[inline(always)]
622 pub fn burner(
623 &mut self,
624 burner: Option<&'b solana_program::account_info::AccountInfo<'a>>,
625 ) -> &mut Self {
626 self.instruction.burner = burner;
627 self
628 }
629 #[inline(always)]
630 pub fn number_of_uses(&mut self, number_of_uses: u64) -> &mut Self {
631 self.instruction.number_of_uses = Some(number_of_uses);
632 self
633 }
634 #[inline(always)]
636 pub fn add_remaining_account(
637 &mut self,
638 account: &'b solana_program::account_info::AccountInfo<'a>,
639 is_writable: bool,
640 is_signer: bool,
641 ) -> &mut Self {
642 self.instruction
643 .__remaining_accounts
644 .push((account, is_writable, is_signer));
645 self
646 }
647 #[inline(always)]
652 pub fn add_remaining_accounts(
653 &mut self,
654 accounts: &[(
655 &'b solana_program::account_info::AccountInfo<'a>,
656 bool,
657 bool,
658 )],
659 ) -> &mut Self {
660 self.instruction
661 .__remaining_accounts
662 .extend_from_slice(accounts);
663 self
664 }
665 #[inline(always)]
666 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
667 self.invoke_signed(&[])
668 }
669 #[allow(clippy::clone_on_copy)]
670 #[allow(clippy::vec_init_then_push)]
671 pub fn invoke_signed(
672 &self,
673 signers_seeds: &[&[&[u8]]],
674 ) -> solana_program::entrypoint::ProgramResult {
675 let args = UtilizeInstructionArgs {
676 number_of_uses: self
677 .instruction
678 .number_of_uses
679 .clone()
680 .expect("number_of_uses is not set"),
681 };
682 let instruction = UtilizeCpi {
683 __program: self.instruction.__program,
684
685 metadata: self.instruction.metadata.expect("metadata is not set"),
686
687 token_account: self
688 .instruction
689 .token_account
690 .expect("token_account is not set"),
691
692 mint: self.instruction.mint.expect("mint is not set"),
693
694 use_authority: self
695 .instruction
696 .use_authority
697 .expect("use_authority is not set"),
698
699 owner: self.instruction.owner.expect("owner is not set"),
700
701 token_program: self
702 .instruction
703 .token_program
704 .expect("token_program is not set"),
705
706 ata_program: self
707 .instruction
708 .ata_program
709 .expect("ata_program is not set"),
710
711 system_program: self
712 .instruction
713 .system_program
714 .expect("system_program is not set"),
715
716 rent: self.instruction.rent.expect("rent is not set"),
717
718 use_authority_record: self.instruction.use_authority_record,
719
720 burner: self.instruction.burner,
721 __args: args,
722 };
723 instruction.invoke_signed_with_remaining_accounts(
724 signers_seeds,
725 &self.instruction.__remaining_accounts,
726 )
727 }
728}
729
730struct UtilizeCpiBuilderInstruction<'a, 'b> {
731 __program: &'b solana_program::account_info::AccountInfo<'a>,
732 metadata: Option<&'b solana_program::account_info::AccountInfo<'a>>,
733 token_account: Option<&'b solana_program::account_info::AccountInfo<'a>>,
734 mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
735 use_authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
736 owner: Option<&'b solana_program::account_info::AccountInfo<'a>>,
737 token_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
738 ata_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
739 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
740 rent: Option<&'b solana_program::account_info::AccountInfo<'a>>,
741 use_authority_record: Option<&'b solana_program::account_info::AccountInfo<'a>>,
742 burner: Option<&'b solana_program::account_info::AccountInfo<'a>>,
743 number_of_uses: Option<u64>,
744 __remaining_accounts: Vec<(
746 &'b solana_program::account_info::AccountInfo<'a>,
747 bool,
748 bool,
749 )>,
750}