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