1#![allow(
2 clippy::all,
3 clippy::pedantic,
4 clippy::nursery,
5 clippy::expect_used,
6 clippy::unwrap_used,
7 clippy::indexing_slicing,
8 clippy::allow_attributes,
9 clippy::allow_attributes_without_reason,
10 clippy::mem_forget,
11 unfulfilled_lint_expectations,
12 unexpected_cfgs,
13 unused_imports
14)]
15
16use borsh::BorshDeserialize;
24use borsh::BorshSerialize;
25use solana_address::Address;
26
27pub const SELL_EXACT_OUT_DISCRIMINATOR: [u8; 8] =
28 [95, 200, 71, 34, 8, 9, 11, 166];
29
30#[derive(Debug)]
32pub struct SellExactOut {
33 pub user: solana_address::Address,
34 pub payer: solana_address::Address,
35 pub bonding_curve: solana_address::Address,
36 pub base_mint: solana_address::Address,
37 pub quote_mint: solana_address::Address,
38 pub base_vault: solana_address::Address,
39 pub quote_vault: solana_address::Address,
40 pub user_base_account: solana_address::Address,
42 pub user_quote_account: solana_address::Address,
44 pub partner: (solana_address::Address, bool),
46 pub partner_config: solana_address::Address,
47 pub base_token_program: solana_address::Address,
48 pub quote_token_program: solana_address::Address,
49 pub associated_token_program: solana_address::Address,
50 pub system_program: solana_address::Address,
51 pub event_authority: solana_address::Address,
52 pub program: solana_address::Address,
53}
54
55impl SellExactOut {
56 pub fn instruction(
57 &self,
58 args: SellExactOutInstructionArgs,
59 ) -> solana_instruction::Instruction {
60 self.instruction_with_remaining_accounts(args, &[])
61 }
62 #[allow(clippy::arithmetic_side_effects)]
63 #[allow(clippy::vec_init_then_push)]
64 pub fn instruction_with_remaining_accounts(
65 &self,
66 args: SellExactOutInstructionArgs,
67 remaining_accounts: &[solana_instruction::AccountMeta],
68 ) -> solana_instruction::Instruction {
69 let mut accounts = Vec::with_capacity(17 + remaining_accounts.len());
70 accounts.push(solana_instruction::AccountMeta::new_readonly(
71 self.user, true,
72 ));
73 accounts.push(solana_instruction::AccountMeta::new(self.payer, true));
74 accounts.push(solana_instruction::AccountMeta::new(
75 self.bonding_curve,
76 false,
77 ));
78 accounts.push(solana_instruction::AccountMeta::new_readonly(
79 self.base_mint,
80 false,
81 ));
82 accounts.push(solana_instruction::AccountMeta::new_readonly(
83 self.quote_mint,
84 false,
85 ));
86 accounts
87 .push(solana_instruction::AccountMeta::new(self.base_vault, false));
88 accounts.push(solana_instruction::AccountMeta::new(
89 self.quote_vault,
90 false,
91 ));
92 accounts.push(solana_instruction::AccountMeta::new(
93 self.user_base_account,
94 false,
95 ));
96 accounts.push(solana_instruction::AccountMeta::new(
97 self.user_quote_account,
98 false,
99 ));
100 accounts.push(solana_instruction::AccountMeta::new_readonly(
101 self.partner.0,
102 self.partner.1,
103 ));
104 accounts.push(solana_instruction::AccountMeta::new_readonly(
105 self.partner_config,
106 false,
107 ));
108 accounts.push(solana_instruction::AccountMeta::new_readonly(
109 self.base_token_program,
110 false,
111 ));
112 accounts.push(solana_instruction::AccountMeta::new_readonly(
113 self.quote_token_program,
114 false,
115 ));
116 accounts.push(solana_instruction::AccountMeta::new_readonly(
117 self.associated_token_program,
118 false,
119 ));
120 accounts.push(solana_instruction::AccountMeta::new_readonly(
121 self.system_program,
122 false,
123 ));
124 accounts.push(solana_instruction::AccountMeta::new_readonly(
125 self.event_authority,
126 false,
127 ));
128 accounts.push(solana_instruction::AccountMeta::new_readonly(
129 self.program,
130 false,
131 ));
132 accounts.extend_from_slice(remaining_accounts);
133 let mut data = SellExactOutInstructionData::new().try_to_vec().unwrap();
134 let mut args = args.try_to_vec().unwrap();
135 data.append(&mut args);
136
137 solana_instruction::Instruction {
138 program_id: crate::launchpad::generated::SEND_LAUNCHPAD_ID,
139 accounts,
140 data,
141 }
142 }
143}
144
145#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
146#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
147#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
148pub struct SellExactOutInstructionData {
149 discriminator: [u8; 8],
150}
151
152impl SellExactOutInstructionData {
153 pub fn new() -> Self {
154 Self {
155 discriminator: [95, 200, 71, 34, 8, 9, 11, 166],
156 }
157 }
158
159 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
160 borsh::to_vec(self)
161 }
162}
163
164impl Default for SellExactOutInstructionData {
165 fn default() -> Self {
166 Self::new()
167 }
168}
169
170#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
171#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
172#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
173pub struct SellExactOutInstructionArgs {
174 pub amount_out: u64,
175 pub max_amount_in: u64,
176}
177
178impl SellExactOutInstructionArgs {
179 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
180 borsh::to_vec(self)
181 }
182}
183
184#[derive(Clone, Debug)]
206pub struct SellExactOutBuilder {
207 user: solana_address::Address,
208 payer: solana_address::Address,
209 bonding_curve: Option<solana_address::Address>,
210 base_mint: solana_address::Address,
211 quote_mint: solana_address::Address,
212 base_vault: Option<solana_address::Address>,
213 quote_vault: Option<solana_address::Address>,
214 user_base_account: Option<solana_address::Address>,
215 user_quote_account: Option<solana_address::Address>,
216 partner: (solana_address::Address, bool),
217 partner_config: Option<solana_address::Address>,
218 quote_token_program: solana_address::Address,
219 amount_out: u64,
220 max_amount_in: u64,
221 platform_config: Address,
222 __remaining_accounts: Vec<solana_instruction::AccountMeta>,
223}
224
225impl SellExactOutBuilder {
226 pub fn new(
227 user: solana_address::Address,
228 payer: solana_address::Address,
229 base_mint: solana_address::Address,
230 quote_mint: solana_address::Address,
231 partner: (solana_address::Address, bool),
232 quote_token_program: solana_address::Address,
233 amount_out: u64,
234 max_amount_in: u64,
235 platform_config: Address,
236 ) -> Self {
237 Self {
238 user,
239 payer,
240 bonding_curve: None,
241 base_mint,
242 quote_mint,
243 base_vault: None,
244 quote_vault: None,
245 user_base_account: None,
246 user_quote_account: None,
247 partner,
248 partner_config: None,
249 quote_token_program,
250 amount_out,
251 max_amount_in,
252 platform_config,
253 __remaining_accounts: Vec::new(),
254 }
255 }
256 #[inline(always)]
258 pub fn bonding_curve(
259 &mut self,
260 bonding_curve: solana_address::Address,
261 ) -> &mut Self {
262 self.bonding_curve = Some(bonding_curve);
263 self
264 }
265 #[inline(always)]
267 pub fn base_vault(
268 &mut self,
269 base_vault: solana_address::Address,
270 ) -> &mut Self {
271 self.base_vault = Some(base_vault);
272 self
273 }
274 #[inline(always)]
276 pub fn quote_vault(
277 &mut self,
278 quote_vault: solana_address::Address,
279 ) -> &mut Self {
280 self.quote_vault = Some(quote_vault);
281 self
282 }
283 #[inline(always)]
286 pub fn user_base_account(
287 &mut self,
288 user_base_account: solana_address::Address,
289 ) -> &mut Self {
290 self.user_base_account = Some(user_base_account);
291 self
292 }
293 #[inline(always)]
296 pub fn user_quote_account(
297 &mut self,
298 user_quote_account: solana_address::Address,
299 ) -> &mut Self {
300 self.user_quote_account = Some(user_quote_account);
301 self
302 }
303 #[inline(always)]
305 pub fn partner_config(
306 &mut self,
307 partner_config: solana_address::Address,
308 ) -> &mut Self {
309 self.partner_config = Some(partner_config);
310 self
311 }
312 #[inline(always)]
314 pub fn add_remaining_account(
315 &mut self,
316 account: solana_instruction::AccountMeta,
317 ) -> &mut Self {
318 self.__remaining_accounts.push(account);
319 self
320 }
321 #[inline(always)]
323 pub fn add_remaining_accounts(
324 &mut self,
325 accounts: &[solana_instruction::AccountMeta],
326 ) -> &mut Self {
327 self.__remaining_accounts.extend_from_slice(accounts);
328 self
329 }
330 #[allow(clippy::clone_on_copy)]
331 pub fn instruction(&self) -> solana_instruction::Instruction {
332 let user = self.user;
333 let payer = self.payer;
334 let base_mint = self.base_mint;
335 let quote_mint = self.quote_mint;
336 let bonding_curve = self.bonding_curve.unwrap_or_else(|| {
337 crate::launchpad::generated::pdas::find_bonding_curve_pda(
338 &self.base_mint,
339 &self.quote_mint,
340 )
341 .0
342 });
343 let base_vault = self.base_vault.unwrap_or_else(|| {
344 solana_address::Address::find_program_address(
345 &[
346 bonding_curve.as_ref(),
347 &[
348 6, 221, 246, 225, 238, 117, 143, 222, 24, 66, 93, 188,
349 228, 108, 205, 218, 182, 26, 252, 77, 131, 185, 13, 39,
350 254, 189, 249, 40, 216, 161, 139, 252,
351 ],
352 self.base_mint.as_ref(),
353 ],
354 &solana_address::address!(
355 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
356 ),
357 )
358 .0
359 });
360 let quote_token_program = self.quote_token_program;
361 let quote_vault = self.quote_vault.unwrap_or_else(|| {
362 solana_address::Address::find_program_address(
363 &[
364 bonding_curve.as_ref(),
365 self.quote_token_program.as_ref(),
366 self.quote_mint.as_ref(),
367 ],
368 &solana_address::address!(
369 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
370 ),
371 )
372 .0
373 });
374 let user_base_account = self.user_base_account.unwrap_or_else(|| {
375 solana_address::Address::find_program_address(
376 &[
377 self.user.as_ref(),
378 &[
379 6, 221, 246, 225, 238, 117, 143, 222, 24, 66, 93, 188,
380 228, 108, 205, 218, 182, 26, 252, 77, 131, 185, 13, 39,
381 254, 189, 249, 40, 216, 161, 139, 252,
382 ],
383 self.base_mint.as_ref(),
384 ],
385 &solana_address::address!(
386 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
387 ),
388 )
389 .0
390 });
391 let user_quote_account = self.user_quote_account.unwrap_or_else(|| {
392 solana_address::Address::find_program_address(
393 &[
394 self.user.as_ref(),
395 self.quote_token_program.as_ref(),
396 self.quote_mint.as_ref(),
397 ],
398 &solana_address::address!(
399 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
400 ),
401 )
402 .0
403 });
404 let partner = self.partner;
405 let partner_config = self.partner_config.unwrap_or_else(|| {
406 solana_address::Address::find_program_address(
407 &[
408 &[112, 97, 114, 116, 110, 101, 114],
409 self.platform_config.clone().as_ref(),
410 self.partner.0.as_ref(),
411 ],
412 &solana_address::address!(
413 "7rrCurqdWFesbzwtYPo95fM8waTtVXgXwCom45x1sfNX"
414 ),
415 )
416 .0
417 });
418 let base_token_program = solana_address::address!(
419 "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
420 );
421 let associated_token_program = solana_address::address!(
422 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
423 );
424 let system_program =
425 solana_address::address!("11111111111111111111111111111111");
426 let event_authority =
427 crate::launchpad::generated::pdas::EVENT_AUTHORITY_ADDRESS;
428 let program = solana_address::address!(
429 "5R1uFyEE4oxqkm7hJDqHq6gXaLVF9dxeF3LF4yz1sfLP"
430 );
431 let accounts = SellExactOut {
432 user,
433 payer,
434 bonding_curve,
435 base_mint,
436 quote_mint,
437 base_vault,
438 quote_vault,
439 user_base_account,
440 user_quote_account,
441 partner,
442 partner_config,
443 base_token_program,
444 quote_token_program,
445 associated_token_program,
446 system_program,
447 event_authority,
448 program,
449 };
450 let args = SellExactOutInstructionArgs {
451 amount_out: self.amount_out.clone(),
452 max_amount_in: self.max_amount_in.clone(),
453 };
454
455 accounts.instruction_with_remaining_accounts(
456 args,
457 &self.__remaining_accounts,
458 )
459 }
460}
461
462pub struct SellExactOutCpiAccounts<'a, 'b> {
464 pub user: &'b solana_program::account_info::AccountInfo<'a>,
465 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
466 pub bonding_curve: &'b solana_program::account_info::AccountInfo<'a>,
467 pub base_mint: &'b solana_program::account_info::AccountInfo<'a>,
468 pub quote_mint: &'b solana_program::account_info::AccountInfo<'a>,
469 pub base_vault: &'b solana_program::account_info::AccountInfo<'a>,
470 pub quote_vault: &'b solana_program::account_info::AccountInfo<'a>,
471 pub user_base_account: &'b solana_program::account_info::AccountInfo<'a>,
473 pub user_quote_account: &'b solana_program::account_info::AccountInfo<'a>,
475 pub partner: (&'b solana_program::account_info::AccountInfo<'a>, bool),
477 pub partner_config: &'b solana_program::account_info::AccountInfo<'a>,
478 pub base_token_program: &'b solana_program::account_info::AccountInfo<'a>,
479 pub quote_token_program: &'b solana_program::account_info::AccountInfo<'a>,
480 pub associated_token_program:
481 &'b solana_program::account_info::AccountInfo<'a>,
482 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
483 pub event_authority: &'b solana_program::account_info::AccountInfo<'a>,
484 pub program: &'b solana_program::account_info::AccountInfo<'a>,
485}
486
487pub struct SellExactOutCpi<'a, 'b> {
489 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
491 pub user: &'b solana_program::account_info::AccountInfo<'a>,
492 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
493 pub bonding_curve: &'b solana_program::account_info::AccountInfo<'a>,
494 pub base_mint: &'b solana_program::account_info::AccountInfo<'a>,
495 pub quote_mint: &'b solana_program::account_info::AccountInfo<'a>,
496 pub base_vault: &'b solana_program::account_info::AccountInfo<'a>,
497 pub quote_vault: &'b solana_program::account_info::AccountInfo<'a>,
498 pub user_base_account: &'b solana_program::account_info::AccountInfo<'a>,
500 pub user_quote_account: &'b solana_program::account_info::AccountInfo<'a>,
502 pub partner: (&'b solana_program::account_info::AccountInfo<'a>, bool),
504 pub partner_config: &'b solana_program::account_info::AccountInfo<'a>,
505 pub base_token_program: &'b solana_program::account_info::AccountInfo<'a>,
506 pub quote_token_program: &'b solana_program::account_info::AccountInfo<'a>,
507 pub associated_token_program:
508 &'b solana_program::account_info::AccountInfo<'a>,
509 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
510 pub event_authority: &'b solana_program::account_info::AccountInfo<'a>,
511 pub program: &'b solana_program::account_info::AccountInfo<'a>,
512 pub __args: SellExactOutInstructionArgs,
514}
515
516impl<'a, 'b> SellExactOutCpi<'a, 'b> {
517 pub fn new(
518 program: &'b solana_program::account_info::AccountInfo<'a>,
519 accounts: SellExactOutCpiAccounts<'a, 'b>,
520 args: SellExactOutInstructionArgs,
521 ) -> Self {
522 Self {
523 __program: program,
524 user: accounts.user,
525 payer: accounts.payer,
526 bonding_curve: accounts.bonding_curve,
527 base_mint: accounts.base_mint,
528 quote_mint: accounts.quote_mint,
529 base_vault: accounts.base_vault,
530 quote_vault: accounts.quote_vault,
531 user_base_account: accounts.user_base_account,
532 user_quote_account: accounts.user_quote_account,
533 partner: accounts.partner,
534 partner_config: accounts.partner_config,
535 base_token_program: accounts.base_token_program,
536 quote_token_program: accounts.quote_token_program,
537 associated_token_program: accounts.associated_token_program,
538 system_program: accounts.system_program,
539 event_authority: accounts.event_authority,
540 program: accounts.program,
541 __args: args,
542 }
543 }
544 #[inline(always)]
545 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
546 self.invoke_signed_with_remaining_accounts(&[], &[])
547 }
548 #[inline(always)]
549 pub fn invoke_with_remaining_accounts(
550 &self,
551 remaining_accounts: &[(
552 &'b solana_program::account_info::AccountInfo<'a>,
553 bool,
554 bool,
555 )],
556 ) -> solana_program::entrypoint::ProgramResult {
557 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
558 }
559 #[inline(always)]
560 pub fn invoke_signed(
561 &self,
562 signers_seeds: &[&[&[u8]]],
563 ) -> solana_program::entrypoint::ProgramResult {
564 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
565 }
566 #[allow(clippy::arithmetic_side_effects)]
567 #[allow(clippy::clone_on_copy)]
568 #[allow(clippy::vec_init_then_push)]
569 pub fn invoke_signed_with_remaining_accounts(
570 &self,
571 signers_seeds: &[&[&[u8]]],
572 remaining_accounts: &[(
573 &'b solana_program::account_info::AccountInfo<'a>,
574 bool,
575 bool,
576 )],
577 ) -> solana_program::entrypoint::ProgramResult {
578 let mut accounts = Vec::with_capacity(17 + remaining_accounts.len());
579 accounts.push(solana_instruction::AccountMeta::new_readonly(
580 *self.user.key,
581 true,
582 ));
583 accounts
584 .push(solana_instruction::AccountMeta::new(*self.payer.key, true));
585 accounts.push(solana_instruction::AccountMeta::new(
586 *self.bonding_curve.key,
587 false,
588 ));
589 accounts.push(solana_instruction::AccountMeta::new_readonly(
590 *self.base_mint.key,
591 false,
592 ));
593 accounts.push(solana_instruction::AccountMeta::new_readonly(
594 *self.quote_mint.key,
595 false,
596 ));
597 accounts.push(solana_instruction::AccountMeta::new(
598 *self.base_vault.key,
599 false,
600 ));
601 accounts.push(solana_instruction::AccountMeta::new(
602 *self.quote_vault.key,
603 false,
604 ));
605 accounts.push(solana_instruction::AccountMeta::new(
606 *self.user_base_account.key,
607 false,
608 ));
609 accounts.push(solana_instruction::AccountMeta::new(
610 *self.user_quote_account.key,
611 false,
612 ));
613 accounts.push(solana_instruction::AccountMeta::new_readonly(
614 *self.partner.0.key,
615 self.partner.1,
616 ));
617 accounts.push(solana_instruction::AccountMeta::new_readonly(
618 *self.partner_config.key,
619 false,
620 ));
621 accounts.push(solana_instruction::AccountMeta::new_readonly(
622 *self.base_token_program.key,
623 false,
624 ));
625 accounts.push(solana_instruction::AccountMeta::new_readonly(
626 *self.quote_token_program.key,
627 false,
628 ));
629 accounts.push(solana_instruction::AccountMeta::new_readonly(
630 *self.associated_token_program.key,
631 false,
632 ));
633 accounts.push(solana_instruction::AccountMeta::new_readonly(
634 *self.system_program.key,
635 false,
636 ));
637 accounts.push(solana_instruction::AccountMeta::new_readonly(
638 *self.event_authority.key,
639 false,
640 ));
641 accounts.push(solana_instruction::AccountMeta::new_readonly(
642 *self.program.key,
643 false,
644 ));
645 remaining_accounts.iter().for_each(|remaining_account| {
646 accounts.push(solana_instruction::AccountMeta {
647 pubkey: *remaining_account.0.key,
648 is_writable: remaining_account.1,
649 is_signer: remaining_account.2,
650 })
651 });
652 let mut data = SellExactOutInstructionData::new().try_to_vec().unwrap();
653 let mut args = self.__args.try_to_vec().unwrap();
654 data.append(&mut args);
655
656 let instruction = solana_instruction::Instruction {
657 program_id: crate::launchpad::generated::SEND_LAUNCHPAD_ID,
658 accounts,
659 data,
660 };
661 let mut account_infos =
662 Vec::with_capacity(18 + remaining_accounts.len());
663 account_infos.push(self.__program.clone());
664 account_infos.push(self.user.clone());
665 account_infos.push(self.payer.clone());
666 account_infos.push(self.bonding_curve.clone());
667 account_infos.push(self.base_mint.clone());
668 account_infos.push(self.quote_mint.clone());
669 account_infos.push(self.base_vault.clone());
670 account_infos.push(self.quote_vault.clone());
671 account_infos.push(self.user_base_account.clone());
672 account_infos.push(self.user_quote_account.clone());
673 account_infos.push(self.partner.0.clone());
674 account_infos.push(self.partner_config.clone());
675 account_infos.push(self.base_token_program.clone());
676 account_infos.push(self.quote_token_program.clone());
677 account_infos.push(self.associated_token_program.clone());
678 account_infos.push(self.system_program.clone());
679 account_infos.push(self.event_authority.clone());
680 account_infos.push(self.program.clone());
681 remaining_accounts.iter().for_each(|remaining_account| {
682 account_infos.push(remaining_account.0.clone())
683 });
684
685 if signers_seeds.is_empty() {
686 solana_program::program::invoke(&instruction, &account_infos)
687 } else {
688 solana_program::program::invoke_signed(
689 &instruction,
690 &account_infos,
691 signers_seeds,
692 )
693 }
694 }
695}
696
697#[derive(Clone, Debug)]
719pub struct SellExactOutCpiBuilder<'a, 'b> {
720 instruction: Box<SellExactOutCpiBuilderInstruction<'a, 'b>>,
721}
722
723impl<'a, 'b> SellExactOutCpiBuilder<'a, 'b> {
724 pub fn new(
725 __program: &'b solana_program::account_info::AccountInfo<'a>,
726 user: &'b solana_program::account_info::AccountInfo<'a>,
727 payer: &'b solana_program::account_info::AccountInfo<'a>,
728 bonding_curve: &'b solana_program::account_info::AccountInfo<'a>,
729 base_mint: &'b solana_program::account_info::AccountInfo<'a>,
730 quote_mint: &'b solana_program::account_info::AccountInfo<'a>,
731 base_vault: &'b solana_program::account_info::AccountInfo<'a>,
732 quote_vault: &'b solana_program::account_info::AccountInfo<'a>,
733 user_base_account: &'b solana_program::account_info::AccountInfo<'a>,
734 user_quote_account: &'b solana_program::account_info::AccountInfo<'a>,
735 partner: (&'b solana_program::account_info::AccountInfo<'a>, bool),
736 partner_config: &'b solana_program::account_info::AccountInfo<'a>,
737 base_token_program: &'b solana_program::account_info::AccountInfo<'a>,
738 quote_token_program: &'b solana_program::account_info::AccountInfo<'a>,
739 associated_token_program: &'b solana_program::account_info::AccountInfo<
740 'a,
741 >,
742 system_program: &'b solana_program::account_info::AccountInfo<'a>,
743 event_authority: &'b solana_program::account_info::AccountInfo<'a>,
744 program: &'b solana_program::account_info::AccountInfo<'a>,
745 amount_out: u64,
746 max_amount_in: u64,
747 ) -> Self {
748 let instruction = Box::new(SellExactOutCpiBuilderInstruction {
749 __program,
750 user,
751 payer,
752 bonding_curve,
753 base_mint,
754 quote_mint,
755 base_vault,
756 quote_vault,
757 user_base_account,
758 user_quote_account,
759 partner,
760 partner_config,
761 base_token_program,
762 quote_token_program,
763 associated_token_program,
764 system_program,
765 event_authority,
766 program,
767 amount_out,
768 max_amount_in,
769 __remaining_accounts: Vec::new(),
770 });
771 Self { instruction }
772 }
773 #[inline(always)]
775 pub fn add_remaining_account(
776 &mut self,
777 account: &'b solana_program::account_info::AccountInfo<'a>,
778 is_writable: bool,
779 is_signer: bool,
780 ) -> &mut Self {
781 self.instruction.__remaining_accounts.push((
782 account,
783 is_writable,
784 is_signer,
785 ));
786 self
787 }
788 #[inline(always)]
793 pub fn add_remaining_accounts(
794 &mut self,
795 accounts: &[(
796 &'b solana_program::account_info::AccountInfo<'a>,
797 bool,
798 bool,
799 )],
800 ) -> &mut Self {
801 self.instruction
802 .__remaining_accounts
803 .extend_from_slice(accounts);
804 self
805 }
806 #[inline(always)]
807 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
808 self.invoke_signed(&[])
809 }
810 #[allow(clippy::clone_on_copy)]
811 #[allow(clippy::vec_init_then_push)]
812 pub fn invoke_signed(
813 &self,
814 signers_seeds: &[&[&[u8]]],
815 ) -> solana_program::entrypoint::ProgramResult {
816 let args = SellExactOutInstructionArgs {
817 amount_out: self.instruction.amount_out.clone(),
818 max_amount_in: self.instruction.max_amount_in.clone(),
819 };
820 let instruction = SellExactOutCpi {
821 __program: self.instruction.__program,
822 user: self.instruction.user,
823 payer: self.instruction.payer,
824 bonding_curve: self.instruction.bonding_curve,
825 base_mint: self.instruction.base_mint,
826 quote_mint: self.instruction.quote_mint,
827 base_vault: self.instruction.base_vault,
828 quote_vault: self.instruction.quote_vault,
829 user_base_account: self.instruction.user_base_account,
830 user_quote_account: self.instruction.user_quote_account,
831 partner: self.instruction.partner,
832 partner_config: self.instruction.partner_config,
833 base_token_program: self.instruction.base_token_program,
834 quote_token_program: self.instruction.quote_token_program,
835 associated_token_program: self.instruction.associated_token_program,
836 system_program: self.instruction.system_program,
837 event_authority: self.instruction.event_authority,
838 program: self.instruction.program,
839 __args: args,
840 };
841 instruction.invoke_signed_with_remaining_accounts(
842 signers_seeds,
843 &self.instruction.__remaining_accounts,
844 )
845 }
846}
847
848#[derive(Clone, Debug)]
849struct SellExactOutCpiBuilderInstruction<'a, 'b> {
850 __program: &'b solana_program::account_info::AccountInfo<'a>,
851 user: &'b solana_program::account_info::AccountInfo<'a>,
852 payer: &'b solana_program::account_info::AccountInfo<'a>,
853 bonding_curve: &'b solana_program::account_info::AccountInfo<'a>,
854 base_mint: &'b solana_program::account_info::AccountInfo<'a>,
855 quote_mint: &'b solana_program::account_info::AccountInfo<'a>,
856 base_vault: &'b solana_program::account_info::AccountInfo<'a>,
857 quote_vault: &'b solana_program::account_info::AccountInfo<'a>,
858 user_base_account: &'b solana_program::account_info::AccountInfo<'a>,
859 user_quote_account: &'b solana_program::account_info::AccountInfo<'a>,
860 partner: (&'b solana_program::account_info::AccountInfo<'a>, bool),
861 partner_config: &'b solana_program::account_info::AccountInfo<'a>,
862 base_token_program: &'b solana_program::account_info::AccountInfo<'a>,
863 quote_token_program: &'b solana_program::account_info::AccountInfo<'a>,
864 associated_token_program: &'b solana_program::account_info::AccountInfo<'a>,
865 system_program: &'b solana_program::account_info::AccountInfo<'a>,
866 event_authority: &'b solana_program::account_info::AccountInfo<'a>,
867 program: &'b solana_program::account_info::AccountInfo<'a>,
868 amount_out: u64,
869 max_amount_in: u64,
870 __remaining_accounts: Vec<(
872 &'b solana_program::account_info::AccountInfo<'a>,
873 bool,
874 bool,
875 )>,
876}