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