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;
25
26pub const CLAIM_PROTOCOL_FEES_DISCRIMINATOR: [u8; 8] =
27 [34, 142, 219, 112, 109, 54, 133, 23];
28
29#[derive(Debug)]
31pub struct ClaimProtocolFees {
32 pub payer: solana_address::Address,
33 pub bonding_curve: solana_address::Address,
34 pub base_mint: solana_address::Address,
35 pub quote_mint: solana_address::Address,
36 pub quote_vault: solana_address::Address,
37 pub nexus_staking_config: solana_address::Address,
38 pub staking_reward_state: solana_address::Address,
39 pub reward_accrual: solana_address::Address,
40 pub staking_vault: solana_address::Address,
41 pub quote_token_program: solana_address::Address,
42 pub system_program: solana_address::Address,
43 pub event_authority: solana_address::Address,
44 pub program: solana_address::Address,
45}
46
47impl ClaimProtocolFees {
48 pub fn instruction(&self) -> solana_instruction::Instruction {
49 self.instruction_with_remaining_accounts(&[])
50 }
51 #[allow(clippy::arithmetic_side_effects)]
52 #[allow(clippy::vec_init_then_push)]
53 pub fn instruction_with_remaining_accounts(
54 &self,
55 remaining_accounts: &[solana_instruction::AccountMeta],
56 ) -> solana_instruction::Instruction {
57 let mut accounts = Vec::with_capacity(13 + remaining_accounts.len());
58 accounts.push(solana_instruction::AccountMeta::new(self.payer, true));
59 accounts.push(solana_instruction::AccountMeta::new(
60 self.bonding_curve,
61 false,
62 ));
63 accounts.push(solana_instruction::AccountMeta::new_readonly(
64 self.base_mint,
65 false,
66 ));
67 accounts.push(solana_instruction::AccountMeta::new_readonly(
68 self.quote_mint,
69 false,
70 ));
71 accounts.push(solana_instruction::AccountMeta::new(
72 self.quote_vault,
73 false,
74 ));
75 accounts.push(solana_instruction::AccountMeta::new_readonly(
76 self.nexus_staking_config,
77 false,
78 ));
79 accounts.push(solana_instruction::AccountMeta::new_readonly(
80 self.staking_reward_state,
81 false,
82 ));
83 accounts.push(solana_instruction::AccountMeta::new(
84 self.reward_accrual,
85 false,
86 ));
87 accounts.push(solana_instruction::AccountMeta::new(
88 self.staking_vault,
89 false,
90 ));
91 accounts.push(solana_instruction::AccountMeta::new_readonly(
92 self.quote_token_program,
93 false,
94 ));
95 accounts.push(solana_instruction::AccountMeta::new_readonly(
96 self.system_program,
97 false,
98 ));
99 accounts.push(solana_instruction::AccountMeta::new_readonly(
100 self.event_authority,
101 false,
102 ));
103 accounts.push(solana_instruction::AccountMeta::new_readonly(
104 self.program,
105 false,
106 ));
107 accounts.extend_from_slice(remaining_accounts);
108 let data = ClaimProtocolFeesInstructionData::new()
109 .try_to_vec()
110 .unwrap();
111
112 solana_instruction::Instruction {
113 program_id: crate::launchpad::generated::SEND_LAUNCHPAD_ID,
114 accounts,
115 data,
116 }
117 }
118}
119
120#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
121#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
122#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
123pub struct ClaimProtocolFeesInstructionData {
124 discriminator: [u8; 8],
125}
126
127impl ClaimProtocolFeesInstructionData {
128 pub fn new() -> Self {
129 Self {
130 discriminator: [34, 142, 219, 112, 109, 54, 133, 23],
131 }
132 }
133
134 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
135 borsh::to_vec(self)
136 }
137}
138
139impl Default for ClaimProtocolFeesInstructionData {
140 fn default() -> Self {
141 Self::new()
142 }
143}
144
145#[derive(Clone, Debug)]
163pub struct ClaimProtocolFeesBuilder {
164 payer: solana_address::Address,
165 bonding_curve: Option<solana_address::Address>,
166 base_mint: solana_address::Address,
167 quote_mint: solana_address::Address,
168 quote_vault: Option<solana_address::Address>,
169 nexus_staking_config: Option<solana_address::Address>,
170 staking_reward_state: Option<solana_address::Address>,
171 reward_accrual: Option<solana_address::Address>,
172 staking_vault: Option<solana_address::Address>,
173 quote_token_program: solana_address::Address,
174 __remaining_accounts: Vec<solana_instruction::AccountMeta>,
175}
176
177impl ClaimProtocolFeesBuilder {
178 pub fn new(
179 payer: solana_address::Address,
180 base_mint: solana_address::Address,
181 quote_mint: solana_address::Address,
182 quote_token_program: solana_address::Address,
183 ) -> Self {
184 Self {
185 payer,
186 bonding_curve: None,
187 base_mint,
188 quote_mint,
189 quote_vault: None,
190 nexus_staking_config: None,
191 staking_reward_state: None,
192 reward_accrual: None,
193 staking_vault: None,
194 quote_token_program,
195 __remaining_accounts: Vec::new(),
196 }
197 }
198 #[inline(always)]
200 pub fn bonding_curve(
201 &mut self,
202 bonding_curve: solana_address::Address,
203 ) -> &mut Self {
204 self.bonding_curve = Some(bonding_curve);
205 self
206 }
207 #[inline(always)]
209 pub fn quote_vault(
210 &mut self,
211 quote_vault: solana_address::Address,
212 ) -> &mut Self {
213 self.quote_vault = Some(quote_vault);
214 self
215 }
216 #[inline(always)]
218 pub fn nexus_staking_config(
219 &mut self,
220 nexus_staking_config: solana_address::Address,
221 ) -> &mut Self {
222 self.nexus_staking_config = Some(nexus_staking_config);
223 self
224 }
225 #[inline(always)]
227 pub fn staking_reward_state(
228 &mut self,
229 staking_reward_state: solana_address::Address,
230 ) -> &mut Self {
231 self.staking_reward_state = Some(staking_reward_state);
232 self
233 }
234 #[inline(always)]
236 pub fn reward_accrual(
237 &mut self,
238 reward_accrual: solana_address::Address,
239 ) -> &mut Self {
240 self.reward_accrual = Some(reward_accrual);
241 self
242 }
243 #[inline(always)]
245 pub fn staking_vault(
246 &mut self,
247 staking_vault: solana_address::Address,
248 ) -> &mut Self {
249 self.staking_vault = Some(staking_vault);
250 self
251 }
252 #[inline(always)]
254 pub fn add_remaining_account(
255 &mut self,
256 account: solana_instruction::AccountMeta,
257 ) -> &mut Self {
258 self.__remaining_accounts.push(account);
259 self
260 }
261 #[inline(always)]
263 pub fn add_remaining_accounts(
264 &mut self,
265 accounts: &[solana_instruction::AccountMeta],
266 ) -> &mut Self {
267 self.__remaining_accounts.extend_from_slice(accounts);
268 self
269 }
270 #[allow(clippy::clone_on_copy)]
271 pub fn instruction(&self) -> solana_instruction::Instruction {
272 let payer = self.payer;
273 let base_mint = self.base_mint;
274 let quote_mint = self.quote_mint;
275 let bonding_curve = self.bonding_curve.unwrap_or_else(|| {
276 crate::launchpad::generated::pdas::find_bonding_curve_pda(
277 &self.base_mint,
278 &self.quote_mint,
279 )
280 .0
281 });
282 let quote_token_program = self.quote_token_program;
283 let quote_vault = self.quote_vault.unwrap_or_else(|| {
284 solana_address::Address::find_program_address(
285 &[
286 bonding_curve.as_ref(),
287 self.quote_token_program.as_ref(),
288 self.quote_mint.as_ref(),
289 ],
290 &solana_address::address!(
291 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
292 ),
293 )
294 .0
295 });
296 let nexus_staking_config =
297 self.nexus_staking_config.unwrap_or_else(|| {
298 solana_address::Address::find_program_address(
299 &[&[
300 115, 116, 97, 107, 105, 110, 103, 95, 99, 111, 110,
301 102, 105, 103,
302 ]],
303 &solana_address::address!(
304 "7rrCurqdWFesbzwtYPo95fM8waTtVXgXwCom45x1sfNX"
305 ),
306 )
307 .0
308 });
309 let staking_reward_state =
310 self.staking_reward_state.unwrap_or_else(|| {
311 solana_address::Address::find_program_address(
312 &[
313 &[114, 101, 119, 97, 114, 100],
314 nexus_staking_config.as_ref(),
315 self.quote_mint.as_ref(),
316 ],
317 &solana_address::address!(
318 "7rrCurqdWFesbzwtYPo95fM8waTtVXgXwCom45x1sfNX"
319 ),
320 )
321 .0
322 });
323 let reward_accrual = self.reward_accrual.unwrap_or_else(|| {
324 crate::launchpad::generated::pdas::find_reward_accrual_pda(
325 &self.quote_mint,
326 )
327 .0
328 });
329 let staking_vault = self.staking_vault.unwrap_or_else(|| {
330 solana_address::Address::find_program_address(
331 &[
332 nexus_staking_config.as_ref(),
333 self.quote_token_program.as_ref(),
334 self.quote_mint.as_ref(),
335 ],
336 &solana_address::address!(
337 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
338 ),
339 )
340 .0
341 });
342 let system_program =
343 solana_address::address!("11111111111111111111111111111111");
344 let event_authority =
345 crate::launchpad::generated::pdas::EVENT_AUTHORITY_ADDRESS;
346 let program = solana_address::address!(
347 "5R1uFyEE4oxqkm7hJDqHq6gXaLVF9dxeF3LF4yz1sfLP"
348 );
349 let accounts = ClaimProtocolFees {
350 payer,
351 bonding_curve,
352 base_mint,
353 quote_mint,
354 quote_vault,
355 nexus_staking_config,
356 staking_reward_state,
357 reward_accrual,
358 staking_vault,
359 quote_token_program,
360 system_program,
361 event_authority,
362 program,
363 };
364
365 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
366 }
367}
368
369pub struct ClaimProtocolFeesCpiAccounts<'a, 'b> {
371 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
372 pub bonding_curve: &'b solana_program::account_info::AccountInfo<'a>,
373 pub base_mint: &'b solana_program::account_info::AccountInfo<'a>,
374 pub quote_mint: &'b solana_program::account_info::AccountInfo<'a>,
375 pub quote_vault: &'b solana_program::account_info::AccountInfo<'a>,
376 pub nexus_staking_config: &'b solana_program::account_info::AccountInfo<'a>,
377 pub staking_reward_state: &'b solana_program::account_info::AccountInfo<'a>,
378 pub reward_accrual: &'b solana_program::account_info::AccountInfo<'a>,
379 pub staking_vault: &'b solana_program::account_info::AccountInfo<'a>,
380 pub quote_token_program: &'b solana_program::account_info::AccountInfo<'a>,
381 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
382 pub event_authority: &'b solana_program::account_info::AccountInfo<'a>,
383 pub program: &'b solana_program::account_info::AccountInfo<'a>,
384}
385
386pub struct ClaimProtocolFeesCpi<'a, 'b> {
388 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
390 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
391 pub bonding_curve: &'b solana_program::account_info::AccountInfo<'a>,
392 pub base_mint: &'b solana_program::account_info::AccountInfo<'a>,
393 pub quote_mint: &'b solana_program::account_info::AccountInfo<'a>,
394 pub quote_vault: &'b solana_program::account_info::AccountInfo<'a>,
395 pub nexus_staking_config: &'b solana_program::account_info::AccountInfo<'a>,
396 pub staking_reward_state: &'b solana_program::account_info::AccountInfo<'a>,
397 pub reward_accrual: &'b solana_program::account_info::AccountInfo<'a>,
398 pub staking_vault: &'b solana_program::account_info::AccountInfo<'a>,
399 pub quote_token_program: &'b solana_program::account_info::AccountInfo<'a>,
400 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
401 pub event_authority: &'b solana_program::account_info::AccountInfo<'a>,
402 pub program: &'b solana_program::account_info::AccountInfo<'a>,
403}
404
405impl<'a, 'b> ClaimProtocolFeesCpi<'a, 'b> {
406 pub fn new(
407 program: &'b solana_program::account_info::AccountInfo<'a>,
408 accounts: ClaimProtocolFeesCpiAccounts<'a, 'b>,
409 ) -> Self {
410 Self {
411 __program: program,
412 payer: accounts.payer,
413 bonding_curve: accounts.bonding_curve,
414 base_mint: accounts.base_mint,
415 quote_mint: accounts.quote_mint,
416 quote_vault: accounts.quote_vault,
417 nexus_staking_config: accounts.nexus_staking_config,
418 staking_reward_state: accounts.staking_reward_state,
419 reward_accrual: accounts.reward_accrual,
420 staking_vault: accounts.staking_vault,
421 quote_token_program: accounts.quote_token_program,
422 system_program: accounts.system_program,
423 event_authority: accounts.event_authority,
424 program: accounts.program,
425 }
426 }
427 #[inline(always)]
428 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
429 self.invoke_signed_with_remaining_accounts(&[], &[])
430 }
431 #[inline(always)]
432 pub fn invoke_with_remaining_accounts(
433 &self,
434 remaining_accounts: &[(
435 &'b solana_program::account_info::AccountInfo<'a>,
436 bool,
437 bool,
438 )],
439 ) -> solana_program::entrypoint::ProgramResult {
440 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
441 }
442 #[inline(always)]
443 pub fn invoke_signed(
444 &self,
445 signers_seeds: &[&[&[u8]]],
446 ) -> solana_program::entrypoint::ProgramResult {
447 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
448 }
449 #[allow(clippy::arithmetic_side_effects)]
450 #[allow(clippy::clone_on_copy)]
451 #[allow(clippy::vec_init_then_push)]
452 pub fn invoke_signed_with_remaining_accounts(
453 &self,
454 signers_seeds: &[&[&[u8]]],
455 remaining_accounts: &[(
456 &'b solana_program::account_info::AccountInfo<'a>,
457 bool,
458 bool,
459 )],
460 ) -> solana_program::entrypoint::ProgramResult {
461 let mut accounts = Vec::with_capacity(13 + remaining_accounts.len());
462 accounts
463 .push(solana_instruction::AccountMeta::new(*self.payer.key, true));
464 accounts.push(solana_instruction::AccountMeta::new(
465 *self.bonding_curve.key,
466 false,
467 ));
468 accounts.push(solana_instruction::AccountMeta::new_readonly(
469 *self.base_mint.key,
470 false,
471 ));
472 accounts.push(solana_instruction::AccountMeta::new_readonly(
473 *self.quote_mint.key,
474 false,
475 ));
476 accounts.push(solana_instruction::AccountMeta::new(
477 *self.quote_vault.key,
478 false,
479 ));
480 accounts.push(solana_instruction::AccountMeta::new_readonly(
481 *self.nexus_staking_config.key,
482 false,
483 ));
484 accounts.push(solana_instruction::AccountMeta::new_readonly(
485 *self.staking_reward_state.key,
486 false,
487 ));
488 accounts.push(solana_instruction::AccountMeta::new(
489 *self.reward_accrual.key,
490 false,
491 ));
492 accounts.push(solana_instruction::AccountMeta::new(
493 *self.staking_vault.key,
494 false,
495 ));
496 accounts.push(solana_instruction::AccountMeta::new_readonly(
497 *self.quote_token_program.key,
498 false,
499 ));
500 accounts.push(solana_instruction::AccountMeta::new_readonly(
501 *self.system_program.key,
502 false,
503 ));
504 accounts.push(solana_instruction::AccountMeta::new_readonly(
505 *self.event_authority.key,
506 false,
507 ));
508 accounts.push(solana_instruction::AccountMeta::new_readonly(
509 *self.program.key,
510 false,
511 ));
512 remaining_accounts.iter().for_each(|remaining_account| {
513 accounts.push(solana_instruction::AccountMeta {
514 pubkey: *remaining_account.0.key,
515 is_writable: remaining_account.1,
516 is_signer: remaining_account.2,
517 })
518 });
519 let data = ClaimProtocolFeesInstructionData::new()
520 .try_to_vec()
521 .unwrap();
522
523 let instruction = solana_instruction::Instruction {
524 program_id: crate::launchpad::generated::SEND_LAUNCHPAD_ID,
525 accounts,
526 data,
527 };
528 let mut account_infos =
529 Vec::with_capacity(14 + remaining_accounts.len());
530 account_infos.push(self.__program.clone());
531 account_infos.push(self.payer.clone());
532 account_infos.push(self.bonding_curve.clone());
533 account_infos.push(self.base_mint.clone());
534 account_infos.push(self.quote_mint.clone());
535 account_infos.push(self.quote_vault.clone());
536 account_infos.push(self.nexus_staking_config.clone());
537 account_infos.push(self.staking_reward_state.clone());
538 account_infos.push(self.reward_accrual.clone());
539 account_infos.push(self.staking_vault.clone());
540 account_infos.push(self.quote_token_program.clone());
541 account_infos.push(self.system_program.clone());
542 account_infos.push(self.event_authority.clone());
543 account_infos.push(self.program.clone());
544 remaining_accounts.iter().for_each(|remaining_account| {
545 account_infos.push(remaining_account.0.clone())
546 });
547
548 if signers_seeds.is_empty() {
549 solana_program::program::invoke(&instruction, &account_infos)
550 } else {
551 solana_program::program::invoke_signed(
552 &instruction,
553 &account_infos,
554 signers_seeds,
555 )
556 }
557 }
558}
559
560#[derive(Clone, Debug)]
578pub struct ClaimProtocolFeesCpiBuilder<'a, 'b> {
579 instruction: Box<ClaimProtocolFeesCpiBuilderInstruction<'a, 'b>>,
580}
581
582impl<'a, 'b> ClaimProtocolFeesCpiBuilder<'a, 'b> {
583 pub fn new(
584 __program: &'b solana_program::account_info::AccountInfo<'a>,
585 payer: &'b solana_program::account_info::AccountInfo<'a>,
586 bonding_curve: &'b solana_program::account_info::AccountInfo<'a>,
587 base_mint: &'b solana_program::account_info::AccountInfo<'a>,
588 quote_mint: &'b solana_program::account_info::AccountInfo<'a>,
589 quote_vault: &'b solana_program::account_info::AccountInfo<'a>,
590 nexus_staking_config: &'b solana_program::account_info::AccountInfo<'a>,
591 staking_reward_state: &'b solana_program::account_info::AccountInfo<'a>,
592 reward_accrual: &'b solana_program::account_info::AccountInfo<'a>,
593 staking_vault: &'b solana_program::account_info::AccountInfo<'a>,
594 quote_token_program: &'b solana_program::account_info::AccountInfo<'a>,
595 system_program: &'b solana_program::account_info::AccountInfo<'a>,
596 event_authority: &'b solana_program::account_info::AccountInfo<'a>,
597 program: &'b solana_program::account_info::AccountInfo<'a>,
598 ) -> Self {
599 let instruction = Box::new(ClaimProtocolFeesCpiBuilderInstruction {
600 __program,
601 payer,
602 bonding_curve,
603 base_mint,
604 quote_mint,
605 quote_vault,
606 nexus_staking_config,
607 staking_reward_state,
608 reward_accrual,
609 staking_vault,
610 quote_token_program,
611 system_program,
612 event_authority,
613 program,
614 __remaining_accounts: Vec::new(),
615 });
616 Self { instruction }
617 }
618 #[inline(always)]
620 pub fn add_remaining_account(
621 &mut self,
622 account: &'b solana_program::account_info::AccountInfo<'a>,
623 is_writable: bool,
624 is_signer: bool,
625 ) -> &mut Self {
626 self.instruction.__remaining_accounts.push((
627 account,
628 is_writable,
629 is_signer,
630 ));
631 self
632 }
633 #[inline(always)]
638 pub fn add_remaining_accounts(
639 &mut self,
640 accounts: &[(
641 &'b solana_program::account_info::AccountInfo<'a>,
642 bool,
643 bool,
644 )],
645 ) -> &mut Self {
646 self.instruction
647 .__remaining_accounts
648 .extend_from_slice(accounts);
649 self
650 }
651 #[inline(always)]
652 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
653 self.invoke_signed(&[])
654 }
655 #[allow(clippy::clone_on_copy)]
656 #[allow(clippy::vec_init_then_push)]
657 pub fn invoke_signed(
658 &self,
659 signers_seeds: &[&[&[u8]]],
660 ) -> solana_program::entrypoint::ProgramResult {
661 let instruction = ClaimProtocolFeesCpi {
662 __program: self.instruction.__program,
663 payer: self.instruction.payer,
664 bonding_curve: self.instruction.bonding_curve,
665 base_mint: self.instruction.base_mint,
666 quote_mint: self.instruction.quote_mint,
667 quote_vault: self.instruction.quote_vault,
668 nexus_staking_config: self.instruction.nexus_staking_config,
669 staking_reward_state: self.instruction.staking_reward_state,
670 reward_accrual: self.instruction.reward_accrual,
671 staking_vault: self.instruction.staking_vault,
672 quote_token_program: self.instruction.quote_token_program,
673 system_program: self.instruction.system_program,
674 event_authority: self.instruction.event_authority,
675 program: self.instruction.program,
676 };
677 instruction.invoke_signed_with_remaining_accounts(
678 signers_seeds,
679 &self.instruction.__remaining_accounts,
680 )
681 }
682}
683
684#[derive(Clone, Debug)]
685struct ClaimProtocolFeesCpiBuilderInstruction<'a, 'b> {
686 __program: &'b solana_program::account_info::AccountInfo<'a>,
687 payer: &'b solana_program::account_info::AccountInfo<'a>,
688 bonding_curve: &'b solana_program::account_info::AccountInfo<'a>,
689 base_mint: &'b solana_program::account_info::AccountInfo<'a>,
690 quote_mint: &'b solana_program::account_info::AccountInfo<'a>,
691 quote_vault: &'b solana_program::account_info::AccountInfo<'a>,
692 nexus_staking_config: &'b solana_program::account_info::AccountInfo<'a>,
693 staking_reward_state: &'b solana_program::account_info::AccountInfo<'a>,
694 reward_accrual: &'b solana_program::account_info::AccountInfo<'a>,
695 staking_vault: &'b solana_program::account_info::AccountInfo<'a>,
696 quote_token_program: &'b solana_program::account_info::AccountInfo<'a>,
697 system_program: &'b solana_program::account_info::AccountInfo<'a>,
698 event_authority: &'b solana_program::account_info::AccountInfo<'a>,
699 program: &'b solana_program::account_info::AccountInfo<'a>,
700 __remaining_accounts: Vec<(
702 &'b solana_program::account_info::AccountInfo<'a>,
703 bool,
704 bool,
705 )>,
706}