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