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