1use borsh::BorshDeserialize;
9use borsh::BorshSerialize;
10
11pub struct BuyWithToken {
13 pub raffle: solana_program::pubkey::Pubkey,
15 pub registrar: Option<solana_program::pubkey::Pubkey>,
17 pub ticket: solana_program::pubkey::Pubkey,
19 pub stub: solana_program::pubkey::Pubkey,
21 pub owner: solana_program::pubkey::Pubkey,
23 pub payer: solana_program::pubkey::Pubkey,
25 pub system_program: solana_program::pubkey::Pubkey,
27 pub spl_token_program: solana_program::pubkey::Pubkey,
29 pub spl_ata_program: Option<solana_program::pubkey::Pubkey>,
31 pub owner_token: solana_program::pubkey::Pubkey,
33 pub ticket_token: solana_program::pubkey::Pubkey,
35 pub mint: Option<solana_program::pubkey::Pubkey>,
37}
38
39impl BuyWithToken {
40 pub fn instruction(&self) -> solana_program::instruction::Instruction {
41 self.instruction_with_remaining_accounts(&[])
42 }
43 #[allow(clippy::vec_init_then_push)]
44 pub fn instruction_with_remaining_accounts(
45 &self,
46 remaining_accounts: &[solana_program::instruction::AccountMeta],
47 ) -> solana_program::instruction::Instruction {
48 let mut accounts = Vec::with_capacity(12 + remaining_accounts.len());
49 accounts.push(solana_program::instruction::AccountMeta::new(
50 self.raffle,
51 false,
52 ));
53 if let Some(registrar) = self.registrar {
54 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
55 registrar, true,
56 ));
57 } else {
58 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
59 crate::MPL_WAFFLE_ID,
60 false,
61 ));
62 }
63 accounts.push(solana_program::instruction::AccountMeta::new(
64 self.ticket,
65 false,
66 ));
67 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
68 self.stub, true,
69 ));
70 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
71 self.owner, true,
72 ));
73 accounts.push(solana_program::instruction::AccountMeta::new(
74 self.payer, true,
75 ));
76 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
77 self.system_program,
78 false,
79 ));
80 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
81 self.spl_token_program,
82 false,
83 ));
84 if let Some(spl_ata_program) = self.spl_ata_program {
85 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
86 spl_ata_program,
87 false,
88 ));
89 } else {
90 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
91 crate::MPL_WAFFLE_ID,
92 false,
93 ));
94 }
95 accounts.push(solana_program::instruction::AccountMeta::new(
96 self.owner_token,
97 false,
98 ));
99 accounts.push(solana_program::instruction::AccountMeta::new(
100 self.ticket_token,
101 false,
102 ));
103 if let Some(mint) = self.mint {
104 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
105 mint, false,
106 ));
107 } else {
108 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
109 crate::MPL_WAFFLE_ID,
110 false,
111 ));
112 }
113 accounts.extend_from_slice(remaining_accounts);
114 let data = BuyWithTokenInstructionData::new().try_to_vec().unwrap();
115
116 solana_program::instruction::Instruction {
117 program_id: crate::MPL_WAFFLE_ID,
118 accounts,
119 data,
120 }
121 }
122}
123
124#[derive(BorshDeserialize, BorshSerialize)]
125struct BuyWithTokenInstructionData {
126 discriminator: u8,
127}
128
129impl BuyWithTokenInstructionData {
130 fn new() -> Self {
131 Self { discriminator: 3 }
132 }
133}
134
135#[derive(Default)]
137pub struct BuyWithTokenBuilder {
138 raffle: Option<solana_program::pubkey::Pubkey>,
139 registrar: Option<solana_program::pubkey::Pubkey>,
140 ticket: Option<solana_program::pubkey::Pubkey>,
141 stub: Option<solana_program::pubkey::Pubkey>,
142 owner: Option<solana_program::pubkey::Pubkey>,
143 payer: Option<solana_program::pubkey::Pubkey>,
144 system_program: Option<solana_program::pubkey::Pubkey>,
145 spl_token_program: Option<solana_program::pubkey::Pubkey>,
146 spl_ata_program: Option<solana_program::pubkey::Pubkey>,
147 owner_token: Option<solana_program::pubkey::Pubkey>,
148 ticket_token: Option<solana_program::pubkey::Pubkey>,
149 mint: Option<solana_program::pubkey::Pubkey>,
150 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
151}
152
153impl BuyWithTokenBuilder {
154 pub fn new() -> Self {
155 Self::default()
156 }
157 #[inline(always)]
159 pub fn raffle(&mut self, raffle: solana_program::pubkey::Pubkey) -> &mut Self {
160 self.raffle = Some(raffle);
161 self
162 }
163 #[inline(always)]
166 pub fn registrar(&mut self, registrar: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
167 self.registrar = registrar;
168 self
169 }
170 #[inline(always)]
172 pub fn ticket(&mut self, ticket: solana_program::pubkey::Pubkey) -> &mut Self {
173 self.ticket = Some(ticket);
174 self
175 }
176 #[inline(always)]
178 pub fn stub(&mut self, stub: solana_program::pubkey::Pubkey) -> &mut Self {
179 self.stub = Some(stub);
180 self
181 }
182 #[inline(always)]
184 pub fn owner(&mut self, owner: solana_program::pubkey::Pubkey) -> &mut Self {
185 self.owner = Some(owner);
186 self
187 }
188 #[inline(always)]
190 pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self {
191 self.payer = Some(payer);
192 self
193 }
194 #[inline(always)]
197 pub fn system_program(&mut self, system_program: solana_program::pubkey::Pubkey) -> &mut Self {
198 self.system_program = Some(system_program);
199 self
200 }
201 #[inline(always)]
203 pub fn spl_token_program(
204 &mut self,
205 spl_token_program: solana_program::pubkey::Pubkey,
206 ) -> &mut Self {
207 self.spl_token_program = Some(spl_token_program);
208 self
209 }
210 #[inline(always)]
213 pub fn spl_ata_program(
214 &mut self,
215 spl_ata_program: Option<solana_program::pubkey::Pubkey>,
216 ) -> &mut Self {
217 self.spl_ata_program = spl_ata_program;
218 self
219 }
220 #[inline(always)]
222 pub fn owner_token(&mut self, owner_token: solana_program::pubkey::Pubkey) -> &mut Self {
223 self.owner_token = Some(owner_token);
224 self
225 }
226 #[inline(always)]
228 pub fn ticket_token(&mut self, ticket_token: solana_program::pubkey::Pubkey) -> &mut Self {
229 self.ticket_token = Some(ticket_token);
230 self
231 }
232 #[inline(always)]
235 pub fn mint(&mut self, mint: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
236 self.mint = mint;
237 self
238 }
239 #[inline(always)]
241 pub fn add_remaining_account(
242 &mut self,
243 account: solana_program::instruction::AccountMeta,
244 ) -> &mut Self {
245 self.__remaining_accounts.push(account);
246 self
247 }
248 #[inline(always)]
250 pub fn add_remaining_accounts(
251 &mut self,
252 accounts: &[solana_program::instruction::AccountMeta],
253 ) -> &mut Self {
254 self.__remaining_accounts.extend_from_slice(accounts);
255 self
256 }
257 #[allow(clippy::clone_on_copy)]
258 pub fn instruction(&self) -> solana_program::instruction::Instruction {
259 let accounts = BuyWithToken {
260 raffle: self.raffle.expect("raffle is not set"),
261 registrar: self.registrar,
262 ticket: self.ticket.expect("ticket is not set"),
263 stub: self.stub.expect("stub is not set"),
264 owner: self.owner.expect("owner is not set"),
265 payer: self.payer.expect("payer is not set"),
266 system_program: self
267 .system_program
268 .unwrap_or(solana_program::pubkey!("11111111111111111111111111111111")),
269 spl_token_program: self
270 .spl_token_program
271 .expect("spl_token_program is not set"),
272 spl_ata_program: self.spl_ata_program,
273 owner_token: self.owner_token.expect("owner_token is not set"),
274 ticket_token: self.ticket_token.expect("ticket_token is not set"),
275 mint: self.mint,
276 };
277
278 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
279 }
280}
281
282pub struct BuyWithTokenCpiAccounts<'a, 'b> {
284 pub raffle: &'b solana_program::account_info::AccountInfo<'a>,
286 pub registrar: Option<&'b solana_program::account_info::AccountInfo<'a>>,
288 pub ticket: &'b solana_program::account_info::AccountInfo<'a>,
290 pub stub: &'b solana_program::account_info::AccountInfo<'a>,
292 pub owner: &'b solana_program::account_info::AccountInfo<'a>,
294 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
296 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
298 pub spl_token_program: &'b solana_program::account_info::AccountInfo<'a>,
300 pub spl_ata_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
302 pub owner_token: &'b solana_program::account_info::AccountInfo<'a>,
304 pub ticket_token: &'b solana_program::account_info::AccountInfo<'a>,
306 pub mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
308}
309
310pub struct BuyWithTokenCpi<'a, 'b> {
312 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
314 pub raffle: &'b solana_program::account_info::AccountInfo<'a>,
316 pub registrar: Option<&'b solana_program::account_info::AccountInfo<'a>>,
318 pub ticket: &'b solana_program::account_info::AccountInfo<'a>,
320 pub stub: &'b solana_program::account_info::AccountInfo<'a>,
322 pub owner: &'b solana_program::account_info::AccountInfo<'a>,
324 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
326 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
328 pub spl_token_program: &'b solana_program::account_info::AccountInfo<'a>,
330 pub spl_ata_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
332 pub owner_token: &'b solana_program::account_info::AccountInfo<'a>,
334 pub ticket_token: &'b solana_program::account_info::AccountInfo<'a>,
336 pub mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
338}
339
340impl<'a, 'b> BuyWithTokenCpi<'a, 'b> {
341 pub fn new(
342 program: &'b solana_program::account_info::AccountInfo<'a>,
343 accounts: BuyWithTokenCpiAccounts<'a, 'b>,
344 ) -> Self {
345 Self {
346 __program: program,
347 raffle: accounts.raffle,
348 registrar: accounts.registrar,
349 ticket: accounts.ticket,
350 stub: accounts.stub,
351 owner: accounts.owner,
352 payer: accounts.payer,
353 system_program: accounts.system_program,
354 spl_token_program: accounts.spl_token_program,
355 spl_ata_program: accounts.spl_ata_program,
356 owner_token: accounts.owner_token,
357 ticket_token: accounts.ticket_token,
358 mint: accounts.mint,
359 }
360 }
361 #[inline(always)]
362 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
363 self.invoke_signed_with_remaining_accounts(&[], &[])
364 }
365 #[inline(always)]
366 pub fn invoke_with_remaining_accounts(
367 &self,
368 remaining_accounts: &[(
369 &'b solana_program::account_info::AccountInfo<'a>,
370 bool,
371 bool,
372 )],
373 ) -> solana_program::entrypoint::ProgramResult {
374 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
375 }
376 #[inline(always)]
377 pub fn invoke_signed(
378 &self,
379 signers_seeds: &[&[&[u8]]],
380 ) -> solana_program::entrypoint::ProgramResult {
381 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
382 }
383 #[allow(clippy::clone_on_copy)]
384 #[allow(clippy::vec_init_then_push)]
385 pub fn invoke_signed_with_remaining_accounts(
386 &self,
387 signers_seeds: &[&[&[u8]]],
388 remaining_accounts: &[(
389 &'b solana_program::account_info::AccountInfo<'a>,
390 bool,
391 bool,
392 )],
393 ) -> solana_program::entrypoint::ProgramResult {
394 let mut accounts = Vec::with_capacity(12 + remaining_accounts.len());
395 accounts.push(solana_program::instruction::AccountMeta::new(
396 *self.raffle.key,
397 false,
398 ));
399 if let Some(registrar) = self.registrar {
400 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
401 *registrar.key,
402 true,
403 ));
404 } else {
405 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
406 crate::MPL_WAFFLE_ID,
407 false,
408 ));
409 }
410 accounts.push(solana_program::instruction::AccountMeta::new(
411 *self.ticket.key,
412 false,
413 ));
414 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
415 *self.stub.key,
416 true,
417 ));
418 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
419 *self.owner.key,
420 true,
421 ));
422 accounts.push(solana_program::instruction::AccountMeta::new(
423 *self.payer.key,
424 true,
425 ));
426 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
427 *self.system_program.key,
428 false,
429 ));
430 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
431 *self.spl_token_program.key,
432 false,
433 ));
434 if let Some(spl_ata_program) = self.spl_ata_program {
435 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
436 *spl_ata_program.key,
437 false,
438 ));
439 } else {
440 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
441 crate::MPL_WAFFLE_ID,
442 false,
443 ));
444 }
445 accounts.push(solana_program::instruction::AccountMeta::new(
446 *self.owner_token.key,
447 false,
448 ));
449 accounts.push(solana_program::instruction::AccountMeta::new(
450 *self.ticket_token.key,
451 false,
452 ));
453 if let Some(mint) = self.mint {
454 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
455 *mint.key, false,
456 ));
457 } else {
458 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
459 crate::MPL_WAFFLE_ID,
460 false,
461 ));
462 }
463 remaining_accounts.iter().for_each(|remaining_account| {
464 accounts.push(solana_program::instruction::AccountMeta {
465 pubkey: *remaining_account.0.key,
466 is_signer: remaining_account.1,
467 is_writable: remaining_account.2,
468 })
469 });
470 let data = BuyWithTokenInstructionData::new().try_to_vec().unwrap();
471
472 let instruction = solana_program::instruction::Instruction {
473 program_id: crate::MPL_WAFFLE_ID,
474 accounts,
475 data,
476 };
477 let mut account_infos = Vec::with_capacity(12 + 1 + remaining_accounts.len());
478 account_infos.push(self.__program.clone());
479 account_infos.push(self.raffle.clone());
480 if let Some(registrar) = self.registrar {
481 account_infos.push(registrar.clone());
482 }
483 account_infos.push(self.ticket.clone());
484 account_infos.push(self.stub.clone());
485 account_infos.push(self.owner.clone());
486 account_infos.push(self.payer.clone());
487 account_infos.push(self.system_program.clone());
488 account_infos.push(self.spl_token_program.clone());
489 if let Some(spl_ata_program) = self.spl_ata_program {
490 account_infos.push(spl_ata_program.clone());
491 }
492 account_infos.push(self.owner_token.clone());
493 account_infos.push(self.ticket_token.clone());
494 if let Some(mint) = self.mint {
495 account_infos.push(mint.clone());
496 }
497 remaining_accounts
498 .iter()
499 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
500
501 if signers_seeds.is_empty() {
502 solana_program::program::invoke(&instruction, &account_infos)
503 } else {
504 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
505 }
506 }
507}
508
509pub struct BuyWithTokenCpiBuilder<'a, 'b> {
511 instruction: Box<BuyWithTokenCpiBuilderInstruction<'a, 'b>>,
512}
513
514impl<'a, 'b> BuyWithTokenCpiBuilder<'a, 'b> {
515 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
516 let instruction = Box::new(BuyWithTokenCpiBuilderInstruction {
517 __program: program,
518 raffle: None,
519 registrar: None,
520 ticket: None,
521 stub: None,
522 owner: None,
523 payer: None,
524 system_program: None,
525 spl_token_program: None,
526 spl_ata_program: None,
527 owner_token: None,
528 ticket_token: None,
529 mint: None,
530 __remaining_accounts: Vec::new(),
531 });
532 Self { instruction }
533 }
534 #[inline(always)]
536 pub fn raffle(
537 &mut self,
538 raffle: &'b solana_program::account_info::AccountInfo<'a>,
539 ) -> &mut Self {
540 self.instruction.raffle = Some(raffle);
541 self
542 }
543 #[inline(always)]
546 pub fn registrar(
547 &mut self,
548 registrar: Option<&'b solana_program::account_info::AccountInfo<'a>>,
549 ) -> &mut Self {
550 self.instruction.registrar = registrar;
551 self
552 }
553 #[inline(always)]
555 pub fn ticket(
556 &mut self,
557 ticket: &'b solana_program::account_info::AccountInfo<'a>,
558 ) -> &mut Self {
559 self.instruction.ticket = Some(ticket);
560 self
561 }
562 #[inline(always)]
564 pub fn stub(&mut self, stub: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
565 self.instruction.stub = Some(stub);
566 self
567 }
568 #[inline(always)]
570 pub fn owner(&mut self, owner: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
571 self.instruction.owner = Some(owner);
572 self
573 }
574 #[inline(always)]
576 pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
577 self.instruction.payer = Some(payer);
578 self
579 }
580 #[inline(always)]
582 pub fn system_program(
583 &mut self,
584 system_program: &'b solana_program::account_info::AccountInfo<'a>,
585 ) -> &mut Self {
586 self.instruction.system_program = Some(system_program);
587 self
588 }
589 #[inline(always)]
591 pub fn spl_token_program(
592 &mut self,
593 spl_token_program: &'b solana_program::account_info::AccountInfo<'a>,
594 ) -> &mut Self {
595 self.instruction.spl_token_program = Some(spl_token_program);
596 self
597 }
598 #[inline(always)]
601 pub fn spl_ata_program(
602 &mut self,
603 spl_ata_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
604 ) -> &mut Self {
605 self.instruction.spl_ata_program = spl_ata_program;
606 self
607 }
608 #[inline(always)]
610 pub fn owner_token(
611 &mut self,
612 owner_token: &'b solana_program::account_info::AccountInfo<'a>,
613 ) -> &mut Self {
614 self.instruction.owner_token = Some(owner_token);
615 self
616 }
617 #[inline(always)]
619 pub fn ticket_token(
620 &mut self,
621 ticket_token: &'b solana_program::account_info::AccountInfo<'a>,
622 ) -> &mut Self {
623 self.instruction.ticket_token = Some(ticket_token);
624 self
625 }
626 #[inline(always)]
629 pub fn mint(
630 &mut self,
631 mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
632 ) -> &mut Self {
633 self.instruction.mint = mint;
634 self
635 }
636 #[inline(always)]
638 pub fn add_remaining_account(
639 &mut self,
640 account: &'b solana_program::account_info::AccountInfo<'a>,
641 is_writable: bool,
642 is_signer: bool,
643 ) -> &mut Self {
644 self.instruction
645 .__remaining_accounts
646 .push((account, is_writable, is_signer));
647 self
648 }
649 #[inline(always)]
654 pub fn add_remaining_accounts(
655 &mut self,
656 accounts: &[(
657 &'b solana_program::account_info::AccountInfo<'a>,
658 bool,
659 bool,
660 )],
661 ) -> &mut Self {
662 self.instruction
663 .__remaining_accounts
664 .extend_from_slice(accounts);
665 self
666 }
667 #[inline(always)]
668 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
669 self.invoke_signed(&[])
670 }
671 #[allow(clippy::clone_on_copy)]
672 #[allow(clippy::vec_init_then_push)]
673 pub fn invoke_signed(
674 &self,
675 signers_seeds: &[&[&[u8]]],
676 ) -> solana_program::entrypoint::ProgramResult {
677 let instruction = BuyWithTokenCpi {
678 __program: self.instruction.__program,
679
680 raffle: self.instruction.raffle.expect("raffle is not set"),
681
682 registrar: self.instruction.registrar,
683
684 ticket: self.instruction.ticket.expect("ticket is not set"),
685
686 stub: self.instruction.stub.expect("stub is not set"),
687
688 owner: self.instruction.owner.expect("owner is not set"),
689
690 payer: self.instruction.payer.expect("payer is not set"),
691
692 system_program: self
693 .instruction
694 .system_program
695 .expect("system_program is not set"),
696
697 spl_token_program: self
698 .instruction
699 .spl_token_program
700 .expect("spl_token_program is not set"),
701
702 spl_ata_program: self.instruction.spl_ata_program,
703
704 owner_token: self
705 .instruction
706 .owner_token
707 .expect("owner_token is not set"),
708
709 ticket_token: self
710 .instruction
711 .ticket_token
712 .expect("ticket_token is not set"),
713
714 mint: self.instruction.mint,
715 };
716 instruction.invoke_signed_with_remaining_accounts(
717 signers_seeds,
718 &self.instruction.__remaining_accounts,
719 )
720 }
721}
722
723struct BuyWithTokenCpiBuilderInstruction<'a, 'b> {
724 __program: &'b solana_program::account_info::AccountInfo<'a>,
725 raffle: Option<&'b solana_program::account_info::AccountInfo<'a>>,
726 registrar: Option<&'b solana_program::account_info::AccountInfo<'a>>,
727 ticket: Option<&'b solana_program::account_info::AccountInfo<'a>>,
728 stub: Option<&'b solana_program::account_info::AccountInfo<'a>>,
729 owner: Option<&'b solana_program::account_info::AccountInfo<'a>>,
730 payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
731 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
732 spl_token_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
733 spl_ata_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
734 owner_token: Option<&'b solana_program::account_info::AccountInfo<'a>>,
735 ticket_token: Option<&'b solana_program::account_info::AccountInfo<'a>>,
736 mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
737 __remaining_accounts: Vec<(
739 &'b solana_program::account_info::AccountInfo<'a>,
740 bool,
741 bool,
742 )>,
743}