1use borsh::BorshSerialize;
9use borsh::BorshDeserialize;
10
11#[derive(Debug)]
13pub struct Withdraw {
14
15
16 pub authority: solana_program::pubkey::Pubkey,
17
18
19 pub mint: solana_program::pubkey::Pubkey,
20
21
22 pub tuna_config: solana_program::pubkey::Pubkey,
23
24
25 pub lending_position: solana_program::pubkey::Pubkey,
26
27
28 pub vault: solana_program::pubkey::Pubkey,
29
30
31 pub vault_ata: solana_program::pubkey::Pubkey,
32
33
34 pub authority_ata: solana_program::pubkey::Pubkey,
35
36
37 pub token_program: solana_program::pubkey::Pubkey,
38
39
40 pub memo_program: solana_program::pubkey::Pubkey,
41 }
42
43impl Withdraw {
44 pub fn instruction(&self, args: WithdrawInstructionArgs) -> solana_program::instruction::Instruction {
45 self.instruction_with_remaining_accounts(args, &[])
46 }
47 #[allow(clippy::arithmetic_side_effects)]
48 #[allow(clippy::vec_init_then_push)]
49 pub fn instruction_with_remaining_accounts(&self, args: WithdrawInstructionArgs, remaining_accounts: &[solana_program::instruction::AccountMeta]) -> solana_program::instruction::Instruction {
50 let mut accounts = Vec::with_capacity(9+ remaining_accounts.len());
51 accounts.push(solana_program::instruction::AccountMeta::new(
52 self.authority,
53 true
54 ));
55 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
56 self.mint,
57 false
58 ));
59 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
60 self.tuna_config,
61 false
62 ));
63 accounts.push(solana_program::instruction::AccountMeta::new(
64 self.lending_position,
65 false
66 ));
67 accounts.push(solana_program::instruction::AccountMeta::new(
68 self.vault,
69 false
70 ));
71 accounts.push(solana_program::instruction::AccountMeta::new(
72 self.vault_ata,
73 false
74 ));
75 accounts.push(solana_program::instruction::AccountMeta::new(
76 self.authority_ata,
77 false
78 ));
79 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
80 self.token_program,
81 false
82 ));
83 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
84 self.memo_program,
85 false
86 ));
87 accounts.extend_from_slice(remaining_accounts);
88 let mut data = borsh::to_vec(&WithdrawInstructionData::new()).unwrap();
89 let mut args = borsh::to_vec(&args).unwrap();
90 data.append(&mut args);
91
92 solana_program::instruction::Instruction {
93 program_id: crate::TUNA_ID,
94 accounts,
95 data,
96 }
97 }
98}
99
100#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
101#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
102 pub struct WithdrawInstructionData {
103 discriminator: [u8; 8],
104 }
105
106impl WithdrawInstructionData {
107 pub fn new() -> Self {
108 Self {
109 discriminator: [183, 18, 70, 156, 148, 109, 161, 34],
110 }
111 }
112}
113
114impl Default for WithdrawInstructionData {
115 fn default() -> Self {
116 Self::new()
117 }
118}
119
120#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
121#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
122 pub struct WithdrawInstructionArgs {
123 pub funds: u64,
124 pub shares: u64,
125 }
126
127
128#[derive(Clone, Debug, Default)]
142pub struct WithdrawBuilder {
143 authority: Option<solana_program::pubkey::Pubkey>,
144 mint: Option<solana_program::pubkey::Pubkey>,
145 tuna_config: Option<solana_program::pubkey::Pubkey>,
146 lending_position: Option<solana_program::pubkey::Pubkey>,
147 vault: Option<solana_program::pubkey::Pubkey>,
148 vault_ata: Option<solana_program::pubkey::Pubkey>,
149 authority_ata: Option<solana_program::pubkey::Pubkey>,
150 token_program: Option<solana_program::pubkey::Pubkey>,
151 memo_program: Option<solana_program::pubkey::Pubkey>,
152 funds: Option<u64>,
153 shares: Option<u64>,
154 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
155}
156
157impl WithdrawBuilder {
158 pub fn new() -> Self {
159 Self::default()
160 }
161 #[inline(always)]
162 pub fn authority(&mut self, authority: solana_program::pubkey::Pubkey) -> &mut Self {
163 self.authority = Some(authority);
164 self
165 }
166 #[inline(always)]
167 pub fn mint(&mut self, mint: solana_program::pubkey::Pubkey) -> &mut Self {
168 self.mint = Some(mint);
169 self
170 }
171 #[inline(always)]
172 pub fn tuna_config(&mut self, tuna_config: solana_program::pubkey::Pubkey) -> &mut Self {
173 self.tuna_config = Some(tuna_config);
174 self
175 }
176 #[inline(always)]
177 pub fn lending_position(&mut self, lending_position: solana_program::pubkey::Pubkey) -> &mut Self {
178 self.lending_position = Some(lending_position);
179 self
180 }
181 #[inline(always)]
182 pub fn vault(&mut self, vault: solana_program::pubkey::Pubkey) -> &mut Self {
183 self.vault = Some(vault);
184 self
185 }
186 #[inline(always)]
187 pub fn vault_ata(&mut self, vault_ata: solana_program::pubkey::Pubkey) -> &mut Self {
188 self.vault_ata = Some(vault_ata);
189 self
190 }
191 #[inline(always)]
192 pub fn authority_ata(&mut self, authority_ata: solana_program::pubkey::Pubkey) -> &mut Self {
193 self.authority_ata = Some(authority_ata);
194 self
195 }
196 #[inline(always)]
198 pub fn token_program(&mut self, token_program: solana_program::pubkey::Pubkey) -> &mut Self {
199 self.token_program = Some(token_program);
200 self
201 }
202 #[inline(always)]
203 pub fn memo_program(&mut self, memo_program: solana_program::pubkey::Pubkey) -> &mut Self {
204 self.memo_program = Some(memo_program);
205 self
206 }
207 #[inline(always)]
208 pub fn funds(&mut self, funds: u64) -> &mut Self {
209 self.funds = Some(funds);
210 self
211 }
212 #[inline(always)]
213 pub fn shares(&mut self, shares: u64) -> &mut Self {
214 self.shares = Some(shares);
215 self
216 }
217 #[inline(always)]
219 pub fn add_remaining_account(&mut self, account: solana_program::instruction::AccountMeta) -> &mut Self {
220 self.__remaining_accounts.push(account);
221 self
222 }
223 #[inline(always)]
225 pub fn add_remaining_accounts(&mut self, accounts: &[solana_program::instruction::AccountMeta]) -> &mut Self {
226 self.__remaining_accounts.extend_from_slice(accounts);
227 self
228 }
229 #[allow(clippy::clone_on_copy)]
230 pub fn instruction(&self) -> solana_program::instruction::Instruction {
231 let accounts = Withdraw {
232 authority: self.authority.expect("authority is not set"),
233 mint: self.mint.expect("mint is not set"),
234 tuna_config: self.tuna_config.expect("tuna_config is not set"),
235 lending_position: self.lending_position.expect("lending_position is not set"),
236 vault: self.vault.expect("vault is not set"),
237 vault_ata: self.vault_ata.expect("vault_ata is not set"),
238 authority_ata: self.authority_ata.expect("authority_ata is not set"),
239 token_program: self.token_program.unwrap_or(solana_program::pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")),
240 memo_program: self.memo_program.expect("memo_program is not set"),
241 };
242 let args = WithdrawInstructionArgs {
243 funds: self.funds.clone().expect("funds is not set"),
244 shares: self.shares.clone().expect("shares is not set"),
245 };
246
247 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
248 }
249}
250
251 pub struct WithdrawCpiAccounts<'a, 'b> {
253
254
255 pub authority: &'b solana_program::account_info::AccountInfo<'a>,
256
257
258 pub mint: &'b solana_program::account_info::AccountInfo<'a>,
259
260
261 pub tuna_config: &'b solana_program::account_info::AccountInfo<'a>,
262
263
264 pub lending_position: &'b solana_program::account_info::AccountInfo<'a>,
265
266
267 pub vault: &'b solana_program::account_info::AccountInfo<'a>,
268
269
270 pub vault_ata: &'b solana_program::account_info::AccountInfo<'a>,
271
272
273 pub authority_ata: &'b solana_program::account_info::AccountInfo<'a>,
274
275
276 pub token_program: &'b solana_program::account_info::AccountInfo<'a>,
277
278
279 pub memo_program: &'b solana_program::account_info::AccountInfo<'a>,
280 }
281
282pub struct WithdrawCpi<'a, 'b> {
284 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
286
287
288 pub authority: &'b solana_program::account_info::AccountInfo<'a>,
289
290
291 pub mint: &'b solana_program::account_info::AccountInfo<'a>,
292
293
294 pub tuna_config: &'b solana_program::account_info::AccountInfo<'a>,
295
296
297 pub lending_position: &'b solana_program::account_info::AccountInfo<'a>,
298
299
300 pub vault: &'b solana_program::account_info::AccountInfo<'a>,
301
302
303 pub vault_ata: &'b solana_program::account_info::AccountInfo<'a>,
304
305
306 pub authority_ata: &'b solana_program::account_info::AccountInfo<'a>,
307
308
309 pub token_program: &'b solana_program::account_info::AccountInfo<'a>,
310
311
312 pub memo_program: &'b solana_program::account_info::AccountInfo<'a>,
313 pub __args: WithdrawInstructionArgs,
315 }
316
317impl<'a, 'b> WithdrawCpi<'a, 'b> {
318 pub fn new(
319 program: &'b solana_program::account_info::AccountInfo<'a>,
320 accounts: WithdrawCpiAccounts<'a, 'b>,
321 args: WithdrawInstructionArgs,
322 ) -> Self {
323 Self {
324 __program: program,
325 authority: accounts.authority,
326 mint: accounts.mint,
327 tuna_config: accounts.tuna_config,
328 lending_position: accounts.lending_position,
329 vault: accounts.vault,
330 vault_ata: accounts.vault_ata,
331 authority_ata: accounts.authority_ata,
332 token_program: accounts.token_program,
333 memo_program: accounts.memo_program,
334 __args: args,
335 }
336 }
337 #[inline(always)]
338 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
339 self.invoke_signed_with_remaining_accounts(&[], &[])
340 }
341 #[inline(always)]
342 pub fn invoke_with_remaining_accounts(&self, remaining_accounts: &[(&'b solana_program::account_info::AccountInfo<'a>, bool, bool)]) -> solana_program::entrypoint::ProgramResult {
343 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
344 }
345 #[inline(always)]
346 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program::entrypoint::ProgramResult {
347 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
348 }
349 #[allow(clippy::arithmetic_side_effects)]
350 #[allow(clippy::clone_on_copy)]
351 #[allow(clippy::vec_init_then_push)]
352 pub fn invoke_signed_with_remaining_accounts(
353 &self,
354 signers_seeds: &[&[&[u8]]],
355 remaining_accounts: &[(&'b solana_program::account_info::AccountInfo<'a>, bool, bool)]
356 ) -> solana_program::entrypoint::ProgramResult {
357 let mut accounts = Vec::with_capacity(9+ remaining_accounts.len());
358 accounts.push(solana_program::instruction::AccountMeta::new(
359 *self.authority.key,
360 true
361 ));
362 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
363 *self.mint.key,
364 false
365 ));
366 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
367 *self.tuna_config.key,
368 false
369 ));
370 accounts.push(solana_program::instruction::AccountMeta::new(
371 *self.lending_position.key,
372 false
373 ));
374 accounts.push(solana_program::instruction::AccountMeta::new(
375 *self.vault.key,
376 false
377 ));
378 accounts.push(solana_program::instruction::AccountMeta::new(
379 *self.vault_ata.key,
380 false
381 ));
382 accounts.push(solana_program::instruction::AccountMeta::new(
383 *self.authority_ata.key,
384 false
385 ));
386 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
387 *self.token_program.key,
388 false
389 ));
390 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
391 *self.memo_program.key,
392 false
393 ));
394 remaining_accounts.iter().for_each(|remaining_account| {
395 accounts.push(solana_program::instruction::AccountMeta {
396 pubkey: *remaining_account.0.key,
397 is_signer: remaining_account.1,
398 is_writable: remaining_account.2,
399 })
400 });
401 let mut data = borsh::to_vec(&WithdrawInstructionData::new()).unwrap();
402 let mut args = borsh::to_vec(&self.__args).unwrap();
403 data.append(&mut args);
404
405 let instruction = solana_program::instruction::Instruction {
406 program_id: crate::TUNA_ID,
407 accounts,
408 data,
409 };
410 let mut account_infos = Vec::with_capacity(10 + remaining_accounts.len());
411 account_infos.push(self.__program.clone());
412 account_infos.push(self.authority.clone());
413 account_infos.push(self.mint.clone());
414 account_infos.push(self.tuna_config.clone());
415 account_infos.push(self.lending_position.clone());
416 account_infos.push(self.vault.clone());
417 account_infos.push(self.vault_ata.clone());
418 account_infos.push(self.authority_ata.clone());
419 account_infos.push(self.token_program.clone());
420 account_infos.push(self.memo_program.clone());
421 remaining_accounts.iter().for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
422
423 if signers_seeds.is_empty() {
424 solana_program::program::invoke(&instruction, &account_infos)
425 } else {
426 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
427 }
428 }
429}
430
431#[derive(Clone, Debug)]
445pub struct WithdrawCpiBuilder<'a, 'b> {
446 instruction: Box<WithdrawCpiBuilderInstruction<'a, 'b>>,
447}
448
449impl<'a, 'b> WithdrawCpiBuilder<'a, 'b> {
450 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
451 let instruction = Box::new(WithdrawCpiBuilderInstruction {
452 __program: program,
453 authority: None,
454 mint: None,
455 tuna_config: None,
456 lending_position: None,
457 vault: None,
458 vault_ata: None,
459 authority_ata: None,
460 token_program: None,
461 memo_program: None,
462 funds: None,
463 shares: None,
464 __remaining_accounts: Vec::new(),
465 });
466 Self { instruction }
467 }
468 #[inline(always)]
469 pub fn authority(&mut self, authority: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
470 self.instruction.authority = Some(authority);
471 self
472 }
473 #[inline(always)]
474 pub fn mint(&mut self, mint: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
475 self.instruction.mint = Some(mint);
476 self
477 }
478 #[inline(always)]
479 pub fn tuna_config(&mut self, tuna_config: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
480 self.instruction.tuna_config = Some(tuna_config);
481 self
482 }
483 #[inline(always)]
484 pub fn lending_position(&mut self, lending_position: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
485 self.instruction.lending_position = Some(lending_position);
486 self
487 }
488 #[inline(always)]
489 pub fn vault(&mut self, vault: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
490 self.instruction.vault = Some(vault);
491 self
492 }
493 #[inline(always)]
494 pub fn vault_ata(&mut self, vault_ata: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
495 self.instruction.vault_ata = Some(vault_ata);
496 self
497 }
498 #[inline(always)]
499 pub fn authority_ata(&mut self, authority_ata: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
500 self.instruction.authority_ata = Some(authority_ata);
501 self
502 }
503 #[inline(always)]
504 pub fn token_program(&mut self, token_program: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
505 self.instruction.token_program = Some(token_program);
506 self
507 }
508 #[inline(always)]
509 pub fn memo_program(&mut self, memo_program: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
510 self.instruction.memo_program = Some(memo_program);
511 self
512 }
513 #[inline(always)]
514 pub fn funds(&mut self, funds: u64) -> &mut Self {
515 self.instruction.funds = Some(funds);
516 self
517 }
518 #[inline(always)]
519 pub fn shares(&mut self, shares: u64) -> &mut Self {
520 self.instruction.shares = Some(shares);
521 self
522 }
523 #[inline(always)]
525 pub fn add_remaining_account(&mut self, account: &'b solana_program::account_info::AccountInfo<'a>, is_writable: bool, is_signer: bool) -> &mut Self {
526 self.instruction.__remaining_accounts.push((account, is_writable, is_signer));
527 self
528 }
529 #[inline(always)]
534 pub fn add_remaining_accounts(&mut self, accounts: &[(&'b solana_program::account_info::AccountInfo<'a>, bool, bool)]) -> &mut Self {
535 self.instruction.__remaining_accounts.extend_from_slice(accounts);
536 self
537 }
538 #[inline(always)]
539 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
540 self.invoke_signed(&[])
541 }
542 #[allow(clippy::clone_on_copy)]
543 #[allow(clippy::vec_init_then_push)]
544 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program::entrypoint::ProgramResult {
545 let args = WithdrawInstructionArgs {
546 funds: self.instruction.funds.clone().expect("funds is not set"),
547 shares: self.instruction.shares.clone().expect("shares is not set"),
548 };
549 let instruction = WithdrawCpi {
550 __program: self.instruction.__program,
551
552 authority: self.instruction.authority.expect("authority is not set"),
553
554 mint: self.instruction.mint.expect("mint is not set"),
555
556 tuna_config: self.instruction.tuna_config.expect("tuna_config is not set"),
557
558 lending_position: self.instruction.lending_position.expect("lending_position is not set"),
559
560 vault: self.instruction.vault.expect("vault is not set"),
561
562 vault_ata: self.instruction.vault_ata.expect("vault_ata is not set"),
563
564 authority_ata: self.instruction.authority_ata.expect("authority_ata is not set"),
565
566 token_program: self.instruction.token_program.expect("token_program is not set"),
567
568 memo_program: self.instruction.memo_program.expect("memo_program is not set"),
569 __args: args,
570 };
571 instruction.invoke_signed_with_remaining_accounts(signers_seeds, &self.instruction.__remaining_accounts)
572 }
573}
574
575#[derive(Clone, Debug)]
576struct WithdrawCpiBuilderInstruction<'a, 'b> {
577 __program: &'b solana_program::account_info::AccountInfo<'a>,
578 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
579 mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
580 tuna_config: Option<&'b solana_program::account_info::AccountInfo<'a>>,
581 lending_position: Option<&'b solana_program::account_info::AccountInfo<'a>>,
582 vault: Option<&'b solana_program::account_info::AccountInfo<'a>>,
583 vault_ata: Option<&'b solana_program::account_info::AccountInfo<'a>>,
584 authority_ata: Option<&'b solana_program::account_info::AccountInfo<'a>>,
585 token_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
586 memo_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
587 funds: Option<u64>,
588 shares: Option<u64>,
589 __remaining_accounts: Vec<(&'b solana_program::account_info::AccountInfo<'a>, bool, bool)>,
591}
592