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