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