1use borsh::{BorshDeserialize, BorshSerialize};
8
9pub struct OperatorDelegateTokenAccount {
11 pub operator: solana_program::pubkey::Pubkey,
12
13 pub delegate_admin: solana_program::pubkey::Pubkey,
14
15 pub token_mint: solana_program::pubkey::Pubkey,
16
17 pub token_account: solana_program::pubkey::Pubkey,
18
19 pub delegate: solana_program::pubkey::Pubkey,
20
21 pub token_program: solana_program::pubkey::Pubkey,
22}
23
24impl OperatorDelegateTokenAccount {
25 pub fn instruction(&self) -> solana_program::instruction::Instruction {
26 self.instruction_with_remaining_accounts(&[])
27 }
28 #[allow(clippy::vec_init_then_push)]
29 pub fn instruction_with_remaining_accounts(
30 &self,
31 remaining_accounts: &[solana_program::instruction::AccountMeta],
32 ) -> solana_program::instruction::Instruction {
33 let mut accounts = Vec::with_capacity(6 + remaining_accounts.len());
34 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
35 self.operator,
36 false,
37 ));
38 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
39 self.delegate_admin,
40 true,
41 ));
42 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
43 self.token_mint,
44 false,
45 ));
46 accounts.push(solana_program::instruction::AccountMeta::new(
47 self.token_account,
48 false,
49 ));
50 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
51 self.delegate,
52 false,
53 ));
54 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
55 self.token_program,
56 false,
57 ));
58 accounts.extend_from_slice(remaining_accounts);
59 let data = OperatorDelegateTokenAccountInstructionData::new()
60 .try_to_vec()
61 .unwrap();
62
63 solana_program::instruction::Instruction {
64 program_id: crate::JITO_RESTAKING_ID,
65 accounts,
66 data,
67 }
68 }
69}
70
71#[derive(BorshDeserialize, BorshSerialize)]
72pub struct OperatorDelegateTokenAccountInstructionData {
73 discriminator: u8,
74}
75
76impl OperatorDelegateTokenAccountInstructionData {
77 pub fn new() -> Self {
78 Self { discriminator: 23 }
79 }
80}
81
82impl Default for OperatorDelegateTokenAccountInstructionData {
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88#[derive(Clone, Debug, Default)]
99pub struct OperatorDelegateTokenAccountBuilder {
100 operator: Option<solana_program::pubkey::Pubkey>,
101 delegate_admin: Option<solana_program::pubkey::Pubkey>,
102 token_mint: Option<solana_program::pubkey::Pubkey>,
103 token_account: Option<solana_program::pubkey::Pubkey>,
104 delegate: Option<solana_program::pubkey::Pubkey>,
105 token_program: Option<solana_program::pubkey::Pubkey>,
106 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
107}
108
109impl OperatorDelegateTokenAccountBuilder {
110 pub fn new() -> Self {
111 Self::default()
112 }
113 #[inline(always)]
114 pub fn operator(&mut self, operator: solana_program::pubkey::Pubkey) -> &mut Self {
115 self.operator = Some(operator);
116 self
117 }
118 #[inline(always)]
119 pub fn delegate_admin(&mut self, delegate_admin: solana_program::pubkey::Pubkey) -> &mut Self {
120 self.delegate_admin = Some(delegate_admin);
121 self
122 }
123 #[inline(always)]
124 pub fn token_mint(&mut self, token_mint: solana_program::pubkey::Pubkey) -> &mut Self {
125 self.token_mint = Some(token_mint);
126 self
127 }
128 #[inline(always)]
129 pub fn token_account(&mut self, token_account: solana_program::pubkey::Pubkey) -> &mut Self {
130 self.token_account = Some(token_account);
131 self
132 }
133 #[inline(always)]
134 pub fn delegate(&mut self, delegate: solana_program::pubkey::Pubkey) -> &mut Self {
135 self.delegate = Some(delegate);
136 self
137 }
138 #[inline(always)]
140 pub fn token_program(&mut self, token_program: solana_program::pubkey::Pubkey) -> &mut Self {
141 self.token_program = Some(token_program);
142 self
143 }
144 #[inline(always)]
146 pub fn add_remaining_account(
147 &mut self,
148 account: solana_program::instruction::AccountMeta,
149 ) -> &mut Self {
150 self.__remaining_accounts.push(account);
151 self
152 }
153 #[inline(always)]
155 pub fn add_remaining_accounts(
156 &mut self,
157 accounts: &[solana_program::instruction::AccountMeta],
158 ) -> &mut Self {
159 self.__remaining_accounts.extend_from_slice(accounts);
160 self
161 }
162 #[allow(clippy::clone_on_copy)]
163 pub fn instruction(&self) -> solana_program::instruction::Instruction {
164 let accounts = OperatorDelegateTokenAccount {
165 operator: self.operator.expect("operator is not set"),
166 delegate_admin: self.delegate_admin.expect("delegate_admin is not set"),
167 token_mint: self.token_mint.expect("token_mint is not set"),
168 token_account: self.token_account.expect("token_account is not set"),
169 delegate: self.delegate.expect("delegate is not set"),
170 token_program: self.token_program.unwrap_or(solana_program::pubkey!(
171 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
172 )),
173 };
174
175 accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
176 }
177}
178
179pub struct OperatorDelegateTokenAccountCpiAccounts<'a, 'b> {
181 pub operator: &'b solana_program::account_info::AccountInfo<'a>,
182
183 pub delegate_admin: &'b solana_program::account_info::AccountInfo<'a>,
184
185 pub token_mint: &'b solana_program::account_info::AccountInfo<'a>,
186
187 pub token_account: &'b solana_program::account_info::AccountInfo<'a>,
188
189 pub delegate: &'b solana_program::account_info::AccountInfo<'a>,
190
191 pub token_program: &'b solana_program::account_info::AccountInfo<'a>,
192}
193
194pub struct OperatorDelegateTokenAccountCpi<'a, 'b> {
196 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
198
199 pub operator: &'b solana_program::account_info::AccountInfo<'a>,
200
201 pub delegate_admin: &'b solana_program::account_info::AccountInfo<'a>,
202
203 pub token_mint: &'b solana_program::account_info::AccountInfo<'a>,
204
205 pub token_account: &'b solana_program::account_info::AccountInfo<'a>,
206
207 pub delegate: &'b solana_program::account_info::AccountInfo<'a>,
208
209 pub token_program: &'b solana_program::account_info::AccountInfo<'a>,
210}
211
212impl<'a, 'b> OperatorDelegateTokenAccountCpi<'a, 'b> {
213 pub fn new(
214 program: &'b solana_program::account_info::AccountInfo<'a>,
215 accounts: OperatorDelegateTokenAccountCpiAccounts<'a, 'b>,
216 ) -> Self {
217 Self {
218 __program: program,
219 operator: accounts.operator,
220 delegate_admin: accounts.delegate_admin,
221 token_mint: accounts.token_mint,
222 token_account: accounts.token_account,
223 delegate: accounts.delegate,
224 token_program: accounts.token_program,
225 }
226 }
227 #[inline(always)]
228 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
229 self.invoke_signed_with_remaining_accounts(&[], &[])
230 }
231 #[inline(always)]
232 pub fn invoke_with_remaining_accounts(
233 &self,
234 remaining_accounts: &[(
235 &'b solana_program::account_info::AccountInfo<'a>,
236 bool,
237 bool,
238 )],
239 ) -> solana_program::entrypoint::ProgramResult {
240 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
241 }
242 #[inline(always)]
243 pub fn invoke_signed(
244 &self,
245 signers_seeds: &[&[&[u8]]],
246 ) -> solana_program::entrypoint::ProgramResult {
247 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
248 }
249 #[allow(clippy::clone_on_copy)]
250 #[allow(clippy::vec_init_then_push)]
251 pub fn invoke_signed_with_remaining_accounts(
252 &self,
253 signers_seeds: &[&[&[u8]]],
254 remaining_accounts: &[(
255 &'b solana_program::account_info::AccountInfo<'a>,
256 bool,
257 bool,
258 )],
259 ) -> solana_program::entrypoint::ProgramResult {
260 let mut accounts = Vec::with_capacity(6 + remaining_accounts.len());
261 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
262 *self.operator.key,
263 false,
264 ));
265 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
266 *self.delegate_admin.key,
267 true,
268 ));
269 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
270 *self.token_mint.key,
271 false,
272 ));
273 accounts.push(solana_program::instruction::AccountMeta::new(
274 *self.token_account.key,
275 false,
276 ));
277 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
278 *self.delegate.key,
279 false,
280 ));
281 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
282 *self.token_program.key,
283 false,
284 ));
285 remaining_accounts.iter().for_each(|remaining_account| {
286 accounts.push(solana_program::instruction::AccountMeta {
287 pubkey: *remaining_account.0.key,
288 is_signer: remaining_account.1,
289 is_writable: remaining_account.2,
290 })
291 });
292 let data = OperatorDelegateTokenAccountInstructionData::new()
293 .try_to_vec()
294 .unwrap();
295
296 let instruction = solana_program::instruction::Instruction {
297 program_id: crate::JITO_RESTAKING_ID,
298 accounts,
299 data,
300 };
301 let mut account_infos = Vec::with_capacity(6 + 1 + remaining_accounts.len());
302 account_infos.push(self.__program.clone());
303 account_infos.push(self.operator.clone());
304 account_infos.push(self.delegate_admin.clone());
305 account_infos.push(self.token_mint.clone());
306 account_infos.push(self.token_account.clone());
307 account_infos.push(self.delegate.clone());
308 account_infos.push(self.token_program.clone());
309 remaining_accounts
310 .iter()
311 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
312
313 if signers_seeds.is_empty() {
314 solana_program::program::invoke(&instruction, &account_infos)
315 } else {
316 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
317 }
318 }
319}
320
321#[derive(Clone, Debug)]
332pub struct OperatorDelegateTokenAccountCpiBuilder<'a, 'b> {
333 instruction: Box<OperatorDelegateTokenAccountCpiBuilderInstruction<'a, 'b>>,
334}
335
336impl<'a, 'b> OperatorDelegateTokenAccountCpiBuilder<'a, 'b> {
337 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
338 let instruction = Box::new(OperatorDelegateTokenAccountCpiBuilderInstruction {
339 __program: program,
340 operator: None,
341 delegate_admin: None,
342 token_mint: None,
343 token_account: None,
344 delegate: None,
345 token_program: None,
346 __remaining_accounts: Vec::new(),
347 });
348 Self { instruction }
349 }
350 #[inline(always)]
351 pub fn operator(
352 &mut self,
353 operator: &'b solana_program::account_info::AccountInfo<'a>,
354 ) -> &mut Self {
355 self.instruction.operator = Some(operator);
356 self
357 }
358 #[inline(always)]
359 pub fn delegate_admin(
360 &mut self,
361 delegate_admin: &'b solana_program::account_info::AccountInfo<'a>,
362 ) -> &mut Self {
363 self.instruction.delegate_admin = Some(delegate_admin);
364 self
365 }
366 #[inline(always)]
367 pub fn token_mint(
368 &mut self,
369 token_mint: &'b solana_program::account_info::AccountInfo<'a>,
370 ) -> &mut Self {
371 self.instruction.token_mint = Some(token_mint);
372 self
373 }
374 #[inline(always)]
375 pub fn token_account(
376 &mut self,
377 token_account: &'b solana_program::account_info::AccountInfo<'a>,
378 ) -> &mut Self {
379 self.instruction.token_account = Some(token_account);
380 self
381 }
382 #[inline(always)]
383 pub fn delegate(
384 &mut self,
385 delegate: &'b solana_program::account_info::AccountInfo<'a>,
386 ) -> &mut Self {
387 self.instruction.delegate = Some(delegate);
388 self
389 }
390 #[inline(always)]
391 pub fn token_program(
392 &mut self,
393 token_program: &'b solana_program::account_info::AccountInfo<'a>,
394 ) -> &mut Self {
395 self.instruction.token_program = Some(token_program);
396 self
397 }
398 #[inline(always)]
400 pub fn add_remaining_account(
401 &mut self,
402 account: &'b solana_program::account_info::AccountInfo<'a>,
403 is_writable: bool,
404 is_signer: bool,
405 ) -> &mut Self {
406 self.instruction
407 .__remaining_accounts
408 .push((account, is_writable, is_signer));
409 self
410 }
411 #[inline(always)]
416 pub fn add_remaining_accounts(
417 &mut self,
418 accounts: &[(
419 &'b solana_program::account_info::AccountInfo<'a>,
420 bool,
421 bool,
422 )],
423 ) -> &mut Self {
424 self.instruction
425 .__remaining_accounts
426 .extend_from_slice(accounts);
427 self
428 }
429 #[inline(always)]
430 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
431 self.invoke_signed(&[])
432 }
433 #[allow(clippy::clone_on_copy)]
434 #[allow(clippy::vec_init_then_push)]
435 pub fn invoke_signed(
436 &self,
437 signers_seeds: &[&[&[u8]]],
438 ) -> solana_program::entrypoint::ProgramResult {
439 let instruction = OperatorDelegateTokenAccountCpi {
440 __program: self.instruction.__program,
441
442 operator: self.instruction.operator.expect("operator is not set"),
443
444 delegate_admin: self
445 .instruction
446 .delegate_admin
447 .expect("delegate_admin is not set"),
448
449 token_mint: self.instruction.token_mint.expect("token_mint is not set"),
450
451 token_account: self
452 .instruction
453 .token_account
454 .expect("token_account is not set"),
455
456 delegate: self.instruction.delegate.expect("delegate is not set"),
457
458 token_program: self
459 .instruction
460 .token_program
461 .expect("token_program is not set"),
462 };
463 instruction.invoke_signed_with_remaining_accounts(
464 signers_seeds,
465 &self.instruction.__remaining_accounts,
466 )
467 }
468}
469
470#[derive(Clone, Debug)]
471struct OperatorDelegateTokenAccountCpiBuilderInstruction<'a, 'b> {
472 __program: &'b solana_program::account_info::AccountInfo<'a>,
473 operator: Option<&'b solana_program::account_info::AccountInfo<'a>>,
474 delegate_admin: Option<&'b solana_program::account_info::AccountInfo<'a>>,
475 token_mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
476 token_account: Option<&'b solana_program::account_info::AccountInfo<'a>>,
477 delegate: Option<&'b solana_program::account_info::AccountInfo<'a>>,
478 token_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
479 __remaining_accounts: Vec<(
481 &'b solana_program::account_info::AccountInfo<'a>,
482 bool,
483 bool,
484 )>,
485}