1use borsh::BorshSerialize;
9use borsh::BorshDeserialize;
10
11#[derive(Debug)]
13pub struct WithdrawLocked {
14 pub authority: solana_pubkey::Pubkey,
19
20
21 pub position_owner: solana_pubkey::Pubkey,
22
23
24 pub treasury: solana_pubkey::Pubkey,
25
26
27 pub position: solana_pubkey::Pubkey,
28
29
30 pub vesting_strategy: solana_pubkey::Pubkey,
31
32
33 pub treasury_staked_token_account: solana_pubkey::Pubkey,
34
35
36 pub authority_staked_token_account: solana_pubkey::Pubkey,
37
38
39 pub token_program: solana_pubkey::Pubkey,
40 }
41
42impl WithdrawLocked {
43 pub fn instruction(&self) -> solana_instruction::Instruction {
44 self.instruction_with_remaining_accounts(&[])
45 }
46 #[allow(clippy::arithmetic_side_effects)]
47 #[allow(clippy::vec_init_then_push)]
48 pub fn instruction_with_remaining_accounts(&self, remaining_accounts: &[solana_instruction::AccountMeta]) -> solana_instruction::Instruction {
49 let mut accounts = Vec::with_capacity(8+ remaining_accounts.len());
50 accounts.push(solana_instruction::AccountMeta::new(
51 self.authority,
52 true
53 ));
54 accounts.push(solana_instruction::AccountMeta::new_readonly(
55 self.position_owner,
56 false
57 ));
58 accounts.push(solana_instruction::AccountMeta::new(
59 self.treasury,
60 false
61 ));
62 accounts.push(solana_instruction::AccountMeta::new(
63 self.position,
64 false
65 ));
66 accounts.push(solana_instruction::AccountMeta::new(
67 self.vesting_strategy,
68 false
69 ));
70 accounts.push(solana_instruction::AccountMeta::new(
71 self.treasury_staked_token_account,
72 false
73 ));
74 accounts.push(solana_instruction::AccountMeta::new(
75 self.authority_staked_token_account,
76 false
77 ));
78 accounts.push(solana_instruction::AccountMeta::new_readonly(
79 self.token_program,
80 false
81 ));
82 accounts.extend_from_slice(remaining_accounts);
83 let data = borsh::to_vec(&WithdrawLockedInstructionData::new()).unwrap();
84
85 solana_instruction::Instruction {
86 program_id: crate::TUNA_STAKING_ID,
87 accounts,
88 data,
89 }
90 }
91}
92
93#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
94#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
95 pub struct WithdrawLockedInstructionData {
96 discriminator: [u8; 8],
97 }
98
99impl WithdrawLockedInstructionData {
100 pub fn new() -> Self {
101 Self {
102 discriminator: [96, 224, 88, 102, 223, 189, 8, 228],
103 }
104 }
105}
106
107impl Default for WithdrawLockedInstructionData {
108 fn default() -> Self {
109 Self::new()
110 }
111}
112
113
114
115#[derive(Clone, Debug, Default)]
128pub struct WithdrawLockedBuilder {
129 authority: Option<solana_pubkey::Pubkey>,
130 position_owner: Option<solana_pubkey::Pubkey>,
131 treasury: Option<solana_pubkey::Pubkey>,
132 position: Option<solana_pubkey::Pubkey>,
133 vesting_strategy: Option<solana_pubkey::Pubkey>,
134 treasury_staked_token_account: Option<solana_pubkey::Pubkey>,
135 authority_staked_token_account: Option<solana_pubkey::Pubkey>,
136 token_program: Option<solana_pubkey::Pubkey>,
137 __remaining_accounts: Vec<solana_instruction::AccountMeta>,
138}
139
140impl WithdrawLockedBuilder {
141 pub fn new() -> Self {
142 Self::default()
143 }
144 #[inline(always)]
146 pub fn authority(&mut self, authority: solana_pubkey::Pubkey) -> &mut Self {
147 self.authority = Some(authority);
148 self
149 }
150 #[inline(always)]
151 pub fn position_owner(&mut self, position_owner: solana_pubkey::Pubkey) -> &mut Self {
152 self.position_owner = Some(position_owner);
153 self
154 }
155 #[inline(always)]
156 pub fn treasury(&mut self, treasury: solana_pubkey::Pubkey) -> &mut Self {
157 self.treasury = Some(treasury);
158 self
159 }
160 #[inline(always)]
161 pub fn position(&mut self, position: solana_pubkey::Pubkey) -> &mut Self {
162 self.position = Some(position);
163 self
164 }
165 #[inline(always)]
166 pub fn vesting_strategy(&mut self, vesting_strategy: solana_pubkey::Pubkey) -> &mut Self {
167 self.vesting_strategy = Some(vesting_strategy);
168 self
169 }
170 #[inline(always)]
171 pub fn treasury_staked_token_account(&mut self, treasury_staked_token_account: solana_pubkey::Pubkey) -> &mut Self {
172 self.treasury_staked_token_account = Some(treasury_staked_token_account);
173 self
174 }
175 #[inline(always)]
176 pub fn authority_staked_token_account(&mut self, authority_staked_token_account: solana_pubkey::Pubkey) -> &mut Self {
177 self.authority_staked_token_account = Some(authority_staked_token_account);
178 self
179 }
180 #[inline(always)]
182 pub fn token_program(&mut self, token_program: solana_pubkey::Pubkey) -> &mut Self {
183 self.token_program = Some(token_program);
184 self
185 }
186 #[inline(always)]
188 pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self {
189 self.__remaining_accounts.push(account);
190 self
191 }
192 #[inline(always)]
194 pub fn add_remaining_accounts(&mut self, accounts: &[solana_instruction::AccountMeta]) -> &mut Self {
195 self.__remaining_accounts.extend_from_slice(accounts);
196 self
197 }
198 #[allow(clippy::clone_on_copy)]
199 pub fn instruction(&self) -> solana_instruction::Instruction {
200 let accounts = WithdrawLocked {
201 authority: self.authority.expect("authority is not set"),
202 position_owner: self.position_owner.expect("position_owner is not set"),
203 treasury: self.treasury.expect("treasury is not set"),
204 position: self.position.expect("position is not set"),
205 vesting_strategy: self.vesting_strategy.expect("vesting_strategy is not set"),
206 treasury_staked_token_account: self.treasury_staked_token_account.expect("treasury_staked_token_account is not set"),
207 authority_staked_token_account: self.authority_staked_token_account.expect("authority_staked_token_account is not set"),
208 token_program: self.token_program.unwrap_or(solana_pubkey::pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")),
209 };
210
211 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
212 }
213}
214
215 pub struct WithdrawLockedCpiAccounts<'a, 'b> {
217 pub authority: &'b solana_account_info::AccountInfo<'a>,
222
223
224 pub position_owner: &'b solana_account_info::AccountInfo<'a>,
225
226
227 pub treasury: &'b solana_account_info::AccountInfo<'a>,
228
229
230 pub position: &'b solana_account_info::AccountInfo<'a>,
231
232
233 pub vesting_strategy: &'b solana_account_info::AccountInfo<'a>,
234
235
236 pub treasury_staked_token_account: &'b solana_account_info::AccountInfo<'a>,
237
238
239 pub authority_staked_token_account: &'b solana_account_info::AccountInfo<'a>,
240
241
242 pub token_program: &'b solana_account_info::AccountInfo<'a>,
243 }
244
245pub struct WithdrawLockedCpi<'a, 'b> {
247 pub __program: &'b solana_account_info::AccountInfo<'a>,
249 pub authority: &'b solana_account_info::AccountInfo<'a>,
254
255
256 pub position_owner: &'b solana_account_info::AccountInfo<'a>,
257
258
259 pub treasury: &'b solana_account_info::AccountInfo<'a>,
260
261
262 pub position: &'b solana_account_info::AccountInfo<'a>,
263
264
265 pub vesting_strategy: &'b solana_account_info::AccountInfo<'a>,
266
267
268 pub treasury_staked_token_account: &'b solana_account_info::AccountInfo<'a>,
269
270
271 pub authority_staked_token_account: &'b solana_account_info::AccountInfo<'a>,
272
273
274 pub token_program: &'b solana_account_info::AccountInfo<'a>,
275 }
276
277impl<'a, 'b> WithdrawLockedCpi<'a, 'b> {
278 pub fn new(
279 program: &'b solana_account_info::AccountInfo<'a>,
280 accounts: WithdrawLockedCpiAccounts<'a, 'b>,
281 ) -> Self {
282 Self {
283 __program: program,
284 authority: accounts.authority,
285 position_owner: accounts.position_owner,
286 treasury: accounts.treasury,
287 position: accounts.position,
288 vesting_strategy: accounts.vesting_strategy,
289 treasury_staked_token_account: accounts.treasury_staked_token_account,
290 authority_staked_token_account: accounts.authority_staked_token_account,
291 token_program: accounts.token_program,
292 }
293 }
294 #[inline(always)]
295 pub fn invoke(&self) -> solana_program_entrypoint::ProgramResult {
296 self.invoke_signed_with_remaining_accounts(&[], &[])
297 }
298 #[inline(always)]
299 pub fn invoke_with_remaining_accounts(&self, remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)]) -> solana_program_entrypoint::ProgramResult {
300 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
301 }
302 #[inline(always)]
303 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_entrypoint::ProgramResult {
304 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
305 }
306 #[allow(clippy::arithmetic_side_effects)]
307 #[allow(clippy::clone_on_copy)]
308 #[allow(clippy::vec_init_then_push)]
309 pub fn invoke_signed_with_remaining_accounts(
310 &self,
311 signers_seeds: &[&[&[u8]]],
312 remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)]
313 ) -> solana_program_entrypoint::ProgramResult {
314 let mut accounts = Vec::with_capacity(8+ remaining_accounts.len());
315 accounts.push(solana_instruction::AccountMeta::new(
316 *self.authority.key,
317 true
318 ));
319 accounts.push(solana_instruction::AccountMeta::new_readonly(
320 *self.position_owner.key,
321 false
322 ));
323 accounts.push(solana_instruction::AccountMeta::new(
324 *self.treasury.key,
325 false
326 ));
327 accounts.push(solana_instruction::AccountMeta::new(
328 *self.position.key,
329 false
330 ));
331 accounts.push(solana_instruction::AccountMeta::new(
332 *self.vesting_strategy.key,
333 false
334 ));
335 accounts.push(solana_instruction::AccountMeta::new(
336 *self.treasury_staked_token_account.key,
337 false
338 ));
339 accounts.push(solana_instruction::AccountMeta::new(
340 *self.authority_staked_token_account.key,
341 false
342 ));
343 accounts.push(solana_instruction::AccountMeta::new_readonly(
344 *self.token_program.key,
345 false
346 ));
347 remaining_accounts.iter().for_each(|remaining_account| {
348 accounts.push(solana_instruction::AccountMeta {
349 pubkey: *remaining_account.0.key,
350 is_signer: remaining_account.1,
351 is_writable: remaining_account.2,
352 })
353 });
354 let data = borsh::to_vec(&WithdrawLockedInstructionData::new()).unwrap();
355
356 let instruction = solana_instruction::Instruction {
357 program_id: crate::TUNA_STAKING_ID,
358 accounts,
359 data,
360 };
361 let mut account_infos = Vec::with_capacity(9 + remaining_accounts.len());
362 account_infos.push(self.__program.clone());
363 account_infos.push(self.authority.clone());
364 account_infos.push(self.position_owner.clone());
365 account_infos.push(self.treasury.clone());
366 account_infos.push(self.position.clone());
367 account_infos.push(self.vesting_strategy.clone());
368 account_infos.push(self.treasury_staked_token_account.clone());
369 account_infos.push(self.authority_staked_token_account.clone());
370 account_infos.push(self.token_program.clone());
371 remaining_accounts.iter().for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
372
373 if signers_seeds.is_empty() {
374 solana_cpi::invoke(&instruction, &account_infos)
375 } else {
376 solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds)
377 }
378 }
379}
380
381#[derive(Clone, Debug)]
394pub struct WithdrawLockedCpiBuilder<'a, 'b> {
395 instruction: Box<WithdrawLockedCpiBuilderInstruction<'a, 'b>>,
396}
397
398impl<'a, 'b> WithdrawLockedCpiBuilder<'a, 'b> {
399 pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self {
400 let instruction = Box::new(WithdrawLockedCpiBuilderInstruction {
401 __program: program,
402 authority: None,
403 position_owner: None,
404 treasury: None,
405 position: None,
406 vesting_strategy: None,
407 treasury_staked_token_account: None,
408 authority_staked_token_account: None,
409 token_program: None,
410 __remaining_accounts: Vec::new(),
411 });
412 Self { instruction }
413 }
414 #[inline(always)]
416 pub fn authority(&mut self, authority: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
417 self.instruction.authority = Some(authority);
418 self
419 }
420 #[inline(always)]
421 pub fn position_owner(&mut self, position_owner: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
422 self.instruction.position_owner = Some(position_owner);
423 self
424 }
425 #[inline(always)]
426 pub fn treasury(&mut self, treasury: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
427 self.instruction.treasury = Some(treasury);
428 self
429 }
430 #[inline(always)]
431 pub fn position(&mut self, position: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
432 self.instruction.position = Some(position);
433 self
434 }
435 #[inline(always)]
436 pub fn vesting_strategy(&mut self, vesting_strategy: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
437 self.instruction.vesting_strategy = Some(vesting_strategy);
438 self
439 }
440 #[inline(always)]
441 pub fn treasury_staked_token_account(&mut self, treasury_staked_token_account: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
442 self.instruction.treasury_staked_token_account = Some(treasury_staked_token_account);
443 self
444 }
445 #[inline(always)]
446 pub fn authority_staked_token_account(&mut self, authority_staked_token_account: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
447 self.instruction.authority_staked_token_account = Some(authority_staked_token_account);
448 self
449 }
450 #[inline(always)]
451 pub fn token_program(&mut self, token_program: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
452 self.instruction.token_program = Some(token_program);
453 self
454 }
455 #[inline(always)]
457 pub fn add_remaining_account(&mut self, account: &'b solana_account_info::AccountInfo<'a>, is_writable: bool, is_signer: bool) -> &mut Self {
458 self.instruction.__remaining_accounts.push((account, is_writable, is_signer));
459 self
460 }
461 #[inline(always)]
466 pub fn add_remaining_accounts(&mut self, accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)]) -> &mut Self {
467 self.instruction.__remaining_accounts.extend_from_slice(accounts);
468 self
469 }
470 #[inline(always)]
471 pub fn invoke(&self) -> solana_program_entrypoint::ProgramResult {
472 self.invoke_signed(&[])
473 }
474 #[allow(clippy::clone_on_copy)]
475 #[allow(clippy::vec_init_then_push)]
476 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_entrypoint::ProgramResult {
477 let instruction = WithdrawLockedCpi {
478 __program: self.instruction.__program,
479
480 authority: self.instruction.authority.expect("authority is not set"),
481
482 position_owner: self.instruction.position_owner.expect("position_owner is not set"),
483
484 treasury: self.instruction.treasury.expect("treasury is not set"),
485
486 position: self.instruction.position.expect("position is not set"),
487
488 vesting_strategy: self.instruction.vesting_strategy.expect("vesting_strategy is not set"),
489
490 treasury_staked_token_account: self.instruction.treasury_staked_token_account.expect("treasury_staked_token_account is not set"),
491
492 authority_staked_token_account: self.instruction.authority_staked_token_account.expect("authority_staked_token_account is not set"),
493
494 token_program: self.instruction.token_program.expect("token_program is not set"),
495 };
496 instruction.invoke_signed_with_remaining_accounts(signers_seeds, &self.instruction.__remaining_accounts)
497 }
498}
499
500#[derive(Clone, Debug)]
501struct WithdrawLockedCpiBuilderInstruction<'a, 'b> {
502 __program: &'b solana_account_info::AccountInfo<'a>,
503 authority: Option<&'b solana_account_info::AccountInfo<'a>>,
504 position_owner: Option<&'b solana_account_info::AccountInfo<'a>>,
505 treasury: Option<&'b solana_account_info::AccountInfo<'a>>,
506 position: Option<&'b solana_account_info::AccountInfo<'a>>,
507 vesting_strategy: Option<&'b solana_account_info::AccountInfo<'a>>,
508 treasury_staked_token_account: Option<&'b solana_account_info::AccountInfo<'a>>,
509 authority_staked_token_account: Option<&'b solana_account_info::AccountInfo<'a>>,
510 token_program: Option<&'b solana_account_info::AccountInfo<'a>>,
511 __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>,
513}
514