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 CREATE_USER_REWARD_DEBT_DISCRIMINATOR: [u8; 8] =
27 [155, 124, 113, 190, 252, 235, 113, 155];
28
29#[derive(Debug)]
31pub struct CreateUserRewardDebt {
32 pub user: solana_address::Address,
33 pub payer: solana_address::Address,
34 pub staking_mint: solana_address::Address,
35 pub reward_mint: solana_address::Address,
36 pub staking_config: solana_address::Address,
37 pub reward_state: solana_address::Address,
38 pub user_stake_position: solana_address::Address,
39 pub user_reward_debt: solana_address::Address,
40 pub system_program: solana_address::Address,
41}
42
43impl CreateUserRewardDebt {
44 pub fn instruction(&self) -> solana_instruction::Instruction {
45 self.instruction_with_remaining_accounts(&[])
46 }
47 #[allow(clippy::arithmetic_side_effects)]
48 #[allow(clippy::vec_init_then_push)]
49 pub fn instruction_with_remaining_accounts(
50 &self,
51 remaining_accounts: &[solana_instruction::AccountMeta],
52 ) -> solana_instruction::Instruction {
53 let mut accounts = Vec::with_capacity(9 + remaining_accounts.len());
54 accounts.push(solana_instruction::AccountMeta::new_readonly(
55 self.user, false,
56 ));
57 accounts.push(solana_instruction::AccountMeta::new(self.payer, true));
58 accounts.push(solana_instruction::AccountMeta::new_readonly(
59 self.staking_mint,
60 false,
61 ));
62 accounts.push(solana_instruction::AccountMeta::new_readonly(
63 self.reward_mint,
64 false,
65 ));
66 accounts.push(solana_instruction::AccountMeta::new_readonly(
67 self.staking_config,
68 false,
69 ));
70 accounts.push(solana_instruction::AccountMeta::new_readonly(
71 self.reward_state,
72 false,
73 ));
74 accounts.push(solana_instruction::AccountMeta::new(
75 self.user_stake_position,
76 false,
77 ));
78 accounts.push(solana_instruction::AccountMeta::new(
79 self.user_reward_debt,
80 false,
81 ));
82 accounts.push(solana_instruction::AccountMeta::new_readonly(
83 self.system_program,
84 false,
85 ));
86 accounts.extend_from_slice(remaining_accounts);
87 let data = CreateUserRewardDebtInstructionData::new()
88 .try_to_vec()
89 .unwrap();
90
91 solana_instruction::Instruction {
92 program_id: crate::nexus::generated::SEND_NEXUS_ID,
93 accounts,
94 data,
95 }
96 }
97}
98
99#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
102pub struct CreateUserRewardDebtInstructionData {
103 discriminator: [u8; 8],
104}
105
106impl CreateUserRewardDebtInstructionData {
107 pub fn new() -> Self {
108 Self {
109 discriminator: [155, 124, 113, 190, 252, 235, 113, 155],
110 }
111 }
112
113 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
114 borsh::to_vec(self)
115 }
116}
117
118impl Default for CreateUserRewardDebtInstructionData {
119 fn default() -> Self {
120 Self::new()
121 }
122}
123
124#[derive(Clone, Debug)]
138pub struct CreateUserRewardDebtBuilder {
139 user: solana_address::Address,
140 payer: solana_address::Address,
141 staking_mint: solana_address::Address,
142 reward_mint: solana_address::Address,
143 staking_config: Option<solana_address::Address>,
144 reward_state: Option<solana_address::Address>,
145 user_stake_position: Option<solana_address::Address>,
146 user_reward_debt: Option<solana_address::Address>,
147 __remaining_accounts: Vec<solana_instruction::AccountMeta>,
148}
149
150impl CreateUserRewardDebtBuilder {
151 pub fn new(
152 user: solana_address::Address,
153 payer: solana_address::Address,
154 staking_mint: solana_address::Address,
155 reward_mint: solana_address::Address,
156 ) -> Self {
157 Self {
158 user,
159 payer,
160 staking_mint,
161 reward_mint,
162 staking_config: None,
163 reward_state: None,
164 user_stake_position: None,
165 user_reward_debt: None,
166 __remaining_accounts: Vec::new(),
167 }
168 }
169 #[inline(always)]
171 pub fn staking_config(
172 &mut self,
173 staking_config: solana_address::Address,
174 ) -> &mut Self {
175 self.staking_config = Some(staking_config);
176 self
177 }
178 #[inline(always)]
180 pub fn reward_state(
181 &mut self,
182 reward_state: solana_address::Address,
183 ) -> &mut Self {
184 self.reward_state = Some(reward_state);
185 self
186 }
187 #[inline(always)]
189 pub fn user_stake_position(
190 &mut self,
191 user_stake_position: solana_address::Address,
192 ) -> &mut Self {
193 self.user_stake_position = Some(user_stake_position);
194 self
195 }
196 #[inline(always)]
198 pub fn user_reward_debt(
199 &mut self,
200 user_reward_debt: solana_address::Address,
201 ) -> &mut Self {
202 self.user_reward_debt = Some(user_reward_debt);
203 self
204 }
205 #[inline(always)]
207 pub fn add_remaining_account(
208 &mut self,
209 account: solana_instruction::AccountMeta,
210 ) -> &mut Self {
211 self.__remaining_accounts.push(account);
212 self
213 }
214 #[inline(always)]
216 pub fn add_remaining_accounts(
217 &mut self,
218 accounts: &[solana_instruction::AccountMeta],
219 ) -> &mut Self {
220 self.__remaining_accounts.extend_from_slice(accounts);
221 self
222 }
223 #[allow(clippy::clone_on_copy)]
224 pub fn instruction(&self) -> solana_instruction::Instruction {
225 let user = self.user;
226 let payer = self.payer;
227 let staking_mint = self.staking_mint;
228 let reward_mint = self.reward_mint;
229 let staking_config = self
230 .staking_config
231 .unwrap_or(crate::nexus::generated::pdas::STAKING_CONFIG_ADDRESS);
232 let reward_state = self.reward_state.unwrap_or_else(|| {
233 crate::nexus::generated::pdas::find_reward_state_pda(
234 &staking_config,
235 &self.reward_mint,
236 )
237 .0
238 });
239 let user_stake_position =
240 self.user_stake_position.unwrap_or_else(|| {
241 crate::nexus::generated::pdas::find_user_stake_position_pda(
242 &self.user,
243 &self.staking_mint,
244 )
245 .0
246 });
247 let user_reward_debt = self.user_reward_debt.unwrap_or_else(|| {
248 crate::nexus::generated::pdas::find_user_reward_debt_pda(
249 &self.user,
250 &self.staking_mint,
251 &self.reward_mint,
252 )
253 .0
254 });
255 let system_program =
256 solana_address::address!("11111111111111111111111111111111");
257 let accounts = CreateUserRewardDebt {
258 user,
259 payer,
260 staking_mint,
261 reward_mint,
262 staking_config,
263 reward_state,
264 user_stake_position,
265 user_reward_debt,
266 system_program,
267 };
268
269 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
270 }
271}
272
273pub struct CreateUserRewardDebtCpiAccounts<'a, 'b> {
275 pub user: &'b solana_program::account_info::AccountInfo<'a>,
276 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
277 pub staking_mint: &'b solana_program::account_info::AccountInfo<'a>,
278 pub reward_mint: &'b solana_program::account_info::AccountInfo<'a>,
279 pub staking_config: &'b solana_program::account_info::AccountInfo<'a>,
280 pub reward_state: &'b solana_program::account_info::AccountInfo<'a>,
281 pub user_stake_position: &'b solana_program::account_info::AccountInfo<'a>,
282 pub user_reward_debt: &'b solana_program::account_info::AccountInfo<'a>,
283 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
284}
285
286pub struct CreateUserRewardDebtCpi<'a, 'b> {
288 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
290 pub user: &'b solana_program::account_info::AccountInfo<'a>,
291 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
292 pub staking_mint: &'b solana_program::account_info::AccountInfo<'a>,
293 pub reward_mint: &'b solana_program::account_info::AccountInfo<'a>,
294 pub staking_config: &'b solana_program::account_info::AccountInfo<'a>,
295 pub reward_state: &'b solana_program::account_info::AccountInfo<'a>,
296 pub user_stake_position: &'b solana_program::account_info::AccountInfo<'a>,
297 pub user_reward_debt: &'b solana_program::account_info::AccountInfo<'a>,
298 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
299}
300
301impl<'a, 'b> CreateUserRewardDebtCpi<'a, 'b> {
302 pub fn new(
303 program: &'b solana_program::account_info::AccountInfo<'a>,
304 accounts: CreateUserRewardDebtCpiAccounts<'a, 'b>,
305 ) -> Self {
306 Self {
307 __program: program,
308 user: accounts.user,
309 payer: accounts.payer,
310 staking_mint: accounts.staking_mint,
311 reward_mint: accounts.reward_mint,
312 staking_config: accounts.staking_config,
313 reward_state: accounts.reward_state,
314 user_stake_position: accounts.user_stake_position,
315 user_reward_debt: accounts.user_reward_debt,
316 system_program: accounts.system_program,
317 }
318 }
319 #[inline(always)]
320 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
321 self.invoke_signed_with_remaining_accounts(&[], &[])
322 }
323 #[inline(always)]
324 pub fn invoke_with_remaining_accounts(
325 &self,
326 remaining_accounts: &[(
327 &'b solana_program::account_info::AccountInfo<'a>,
328 bool,
329 bool,
330 )],
331 ) -> solana_program::entrypoint::ProgramResult {
332 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
333 }
334 #[inline(always)]
335 pub fn invoke_signed(
336 &self,
337 signers_seeds: &[&[&[u8]]],
338 ) -> solana_program::entrypoint::ProgramResult {
339 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
340 }
341 #[allow(clippy::arithmetic_side_effects)]
342 #[allow(clippy::clone_on_copy)]
343 #[allow(clippy::vec_init_then_push)]
344 pub fn invoke_signed_with_remaining_accounts(
345 &self,
346 signers_seeds: &[&[&[u8]]],
347 remaining_accounts: &[(
348 &'b solana_program::account_info::AccountInfo<'a>,
349 bool,
350 bool,
351 )],
352 ) -> solana_program::entrypoint::ProgramResult {
353 let mut accounts = Vec::with_capacity(9 + remaining_accounts.len());
354 accounts.push(solana_instruction::AccountMeta::new_readonly(
355 *self.user.key,
356 false,
357 ));
358 accounts
359 .push(solana_instruction::AccountMeta::new(*self.payer.key, true));
360 accounts.push(solana_instruction::AccountMeta::new_readonly(
361 *self.staking_mint.key,
362 false,
363 ));
364 accounts.push(solana_instruction::AccountMeta::new_readonly(
365 *self.reward_mint.key,
366 false,
367 ));
368 accounts.push(solana_instruction::AccountMeta::new_readonly(
369 *self.staking_config.key,
370 false,
371 ));
372 accounts.push(solana_instruction::AccountMeta::new_readonly(
373 *self.reward_state.key,
374 false,
375 ));
376 accounts.push(solana_instruction::AccountMeta::new(
377 *self.user_stake_position.key,
378 false,
379 ));
380 accounts.push(solana_instruction::AccountMeta::new(
381 *self.user_reward_debt.key,
382 false,
383 ));
384 accounts.push(solana_instruction::AccountMeta::new_readonly(
385 *self.system_program.key,
386 false,
387 ));
388 remaining_accounts.iter().for_each(|remaining_account| {
389 accounts.push(solana_instruction::AccountMeta {
390 pubkey: *remaining_account.0.key,
391 is_writable: remaining_account.1,
392 is_signer: remaining_account.2,
393 })
394 });
395 let data = CreateUserRewardDebtInstructionData::new()
396 .try_to_vec()
397 .unwrap();
398
399 let instruction = solana_instruction::Instruction {
400 program_id: crate::nexus::generated::SEND_NEXUS_ID,
401 accounts,
402 data,
403 };
404 let mut account_infos =
405 Vec::with_capacity(10 + remaining_accounts.len());
406 account_infos.push(self.__program.clone());
407 account_infos.push(self.user.clone());
408 account_infos.push(self.payer.clone());
409 account_infos.push(self.staking_mint.clone());
410 account_infos.push(self.reward_mint.clone());
411 account_infos.push(self.staking_config.clone());
412 account_infos.push(self.reward_state.clone());
413 account_infos.push(self.user_stake_position.clone());
414 account_infos.push(self.user_reward_debt.clone());
415 account_infos.push(self.system_program.clone());
416 remaining_accounts.iter().for_each(|remaining_account| {
417 account_infos.push(remaining_account.0.clone())
418 });
419
420 if signers_seeds.is_empty() {
421 solana_program::program::invoke(&instruction, &account_infos)
422 } else {
423 solana_program::program::invoke_signed(
424 &instruction,
425 &account_infos,
426 signers_seeds,
427 )
428 }
429 }
430}
431
432#[derive(Clone, Debug)]
446pub struct CreateUserRewardDebtCpiBuilder<'a, 'b> {
447 instruction: Box<CreateUserRewardDebtCpiBuilderInstruction<'a, 'b>>,
448}
449
450impl<'a, 'b> CreateUserRewardDebtCpiBuilder<'a, 'b> {
451 pub fn new(
452 __program: &'b solana_program::account_info::AccountInfo<'a>,
453 user: &'b solana_program::account_info::AccountInfo<'a>,
454 payer: &'b solana_program::account_info::AccountInfo<'a>,
455 staking_mint: &'b solana_program::account_info::AccountInfo<'a>,
456 reward_mint: &'b solana_program::account_info::AccountInfo<'a>,
457 staking_config: &'b solana_program::account_info::AccountInfo<'a>,
458 reward_state: &'b solana_program::account_info::AccountInfo<'a>,
459 user_stake_position: &'b solana_program::account_info::AccountInfo<'a>,
460 user_reward_debt: &'b solana_program::account_info::AccountInfo<'a>,
461 system_program: &'b solana_program::account_info::AccountInfo<'a>,
462 ) -> Self {
463 let instruction = Box::new(CreateUserRewardDebtCpiBuilderInstruction {
464 __program,
465 user,
466 payer,
467 staking_mint,
468 reward_mint,
469 staking_config,
470 reward_state,
471 user_stake_position,
472 user_reward_debt,
473 system_program,
474 __remaining_accounts: Vec::new(),
475 });
476 Self { instruction }
477 }
478 #[inline(always)]
480 pub fn add_remaining_account(
481 &mut self,
482 account: &'b solana_program::account_info::AccountInfo<'a>,
483 is_writable: bool,
484 is_signer: bool,
485 ) -> &mut Self {
486 self.instruction.__remaining_accounts.push((
487 account,
488 is_writable,
489 is_signer,
490 ));
491 self
492 }
493 #[inline(always)]
498 pub fn add_remaining_accounts(
499 &mut self,
500 accounts: &[(
501 &'b solana_program::account_info::AccountInfo<'a>,
502 bool,
503 bool,
504 )],
505 ) -> &mut Self {
506 self.instruction
507 .__remaining_accounts
508 .extend_from_slice(accounts);
509 self
510 }
511 #[inline(always)]
512 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
513 self.invoke_signed(&[])
514 }
515 #[allow(clippy::clone_on_copy)]
516 #[allow(clippy::vec_init_then_push)]
517 pub fn invoke_signed(
518 &self,
519 signers_seeds: &[&[&[u8]]],
520 ) -> solana_program::entrypoint::ProgramResult {
521 let instruction = CreateUserRewardDebtCpi {
522 __program: self.instruction.__program,
523 user: self.instruction.user,
524 payer: self.instruction.payer,
525 staking_mint: self.instruction.staking_mint,
526 reward_mint: self.instruction.reward_mint,
527 staking_config: self.instruction.staking_config,
528 reward_state: self.instruction.reward_state,
529 user_stake_position: self.instruction.user_stake_position,
530 user_reward_debt: self.instruction.user_reward_debt,
531 system_program: self.instruction.system_program,
532 };
533 instruction.invoke_signed_with_remaining_accounts(
534 signers_seeds,
535 &self.instruction.__remaining_accounts,
536 )
537 }
538}
539
540#[derive(Clone, Debug)]
541struct CreateUserRewardDebtCpiBuilderInstruction<'a, 'b> {
542 __program: &'b solana_program::account_info::AccountInfo<'a>,
543 user: &'b solana_program::account_info::AccountInfo<'a>,
544 payer: &'b solana_program::account_info::AccountInfo<'a>,
545 staking_mint: &'b solana_program::account_info::AccountInfo<'a>,
546 reward_mint: &'b solana_program::account_info::AccountInfo<'a>,
547 staking_config: &'b solana_program::account_info::AccountInfo<'a>,
548 reward_state: &'b solana_program::account_info::AccountInfo<'a>,
549 user_stake_position: &'b solana_program::account_info::AccountInfo<'a>,
550 user_reward_debt: &'b solana_program::account_info::AccountInfo<'a>,
551 system_program: &'b solana_program::account_info::AccountInfo<'a>,
552 __remaining_accounts: Vec<(
554 &'b solana_program::account_info::AccountInfo<'a>,
555 bool,
556 bool,
557 )>,
558}