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