1use borsh::BorshDeserialize;
9use borsh::BorshSerialize;
10
11pub struct MintTo {
13 pub token_account: solana_program::pubkey::Pubkey,
15 pub mint: solana_program::pubkey::Pubkey,
17 pub authority: solana_program::pubkey::Pubkey,
19 pub payer: Option<solana_program::pubkey::Pubkey>,
21 pub system_program: Option<solana_program::pubkey::Pubkey>,
23}
24
25impl MintTo {
26 pub fn instruction(
27 &self,
28 args: MintToInstructionArgs,
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: MintToInstructionArgs,
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(
44 self.mint, false,
45 ));
46 accounts.push(solana_program::instruction::AccountMeta::new(
47 self.authority,
48 true,
49 ));
50 if let Some(payer) = self.payer {
51 accounts.push(solana_program::instruction::AccountMeta::new(payer, true));
52 } else {
53 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
54 crate::SIGIL_ID,
55 false,
56 ));
57 }
58 if let Some(system_program) = self.system_program {
59 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
60 system_program,
61 false,
62 ));
63 } else {
64 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
65 crate::SIGIL_ID,
66 false,
67 ));
68 }
69 accounts.extend_from_slice(remaining_accounts);
70 let mut data = MintToInstructionData::new().try_to_vec().unwrap();
71 let mut args = args.try_to_vec().unwrap();
72 data.append(&mut args);
73
74 solana_program::instruction::Instruction {
75 program_id: crate::SIGIL_ID,
76 accounts,
77 data,
78 }
79 }
80}
81
82#[derive(BorshDeserialize, BorshSerialize)]
83pub struct MintToInstructionData {
84 discriminator: u8,
85}
86
87impl MintToInstructionData {
88 pub fn new() -> Self {
89 Self { discriminator: 5 }
90 }
91}
92
93#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
94#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
95pub struct MintToInstructionArgs {
96 pub amount: u32,
97}
98
99#[derive(Default)]
109pub struct MintToBuilder {
110 token_account: Option<solana_program::pubkey::Pubkey>,
111 mint: Option<solana_program::pubkey::Pubkey>,
112 authority: Option<solana_program::pubkey::Pubkey>,
113 payer: Option<solana_program::pubkey::Pubkey>,
114 system_program: Option<solana_program::pubkey::Pubkey>,
115 amount: Option<u32>,
116 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
117}
118
119impl MintToBuilder {
120 pub fn new() -> Self {
121 Self::default()
122 }
123 #[inline(always)]
125 pub fn token_account(&mut self, token_account: solana_program::pubkey::Pubkey) -> &mut Self {
126 self.token_account = Some(token_account);
127 self
128 }
129 #[inline(always)]
131 pub fn mint(&mut self, mint: solana_program::pubkey::Pubkey) -> &mut Self {
132 self.mint = Some(mint);
133 self
134 }
135 #[inline(always)]
137 pub fn authority(&mut self, authority: solana_program::pubkey::Pubkey) -> &mut Self {
138 self.authority = Some(authority);
139 self
140 }
141 #[inline(always)]
144 pub fn payer(&mut self, payer: Option<solana_program::pubkey::Pubkey>) -> &mut Self {
145 self.payer = payer;
146 self
147 }
148 #[inline(always)]
151 pub fn system_program(
152 &mut self,
153 system_program: Option<solana_program::pubkey::Pubkey>,
154 ) -> &mut Self {
155 self.system_program = system_program;
156 self
157 }
158 #[inline(always)]
159 pub fn amount(&mut self, amount: u32) -> &mut Self {
160 self.amount = Some(amount);
161 self
162 }
163 #[inline(always)]
165 pub fn add_remaining_account(
166 &mut self,
167 account: solana_program::instruction::AccountMeta,
168 ) -> &mut Self {
169 self.__remaining_accounts.push(account);
170 self
171 }
172 #[inline(always)]
174 pub fn add_remaining_accounts(
175 &mut self,
176 accounts: &[solana_program::instruction::AccountMeta],
177 ) -> &mut Self {
178 self.__remaining_accounts.extend_from_slice(accounts);
179 self
180 }
181 #[allow(clippy::clone_on_copy)]
182 pub fn instruction(&self) -> solana_program::instruction::Instruction {
183 let accounts = MintTo {
184 token_account: self.token_account.expect("token_account is not set"),
185 mint: self.mint.expect("mint is not set"),
186 authority: self.authority.expect("authority is not set"),
187 payer: self.payer,
188 system_program: self.system_program,
189 };
190 let args = MintToInstructionArgs {
191 amount: self.amount.clone().expect("amount is not set"),
192 };
193
194 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
195 }
196}
197
198pub struct MintToCpiAccounts<'a, 'b> {
200 pub token_account: &'b solana_program::account_info::AccountInfo<'a>,
202 pub mint: &'b solana_program::account_info::AccountInfo<'a>,
204 pub authority: &'b solana_program::account_info::AccountInfo<'a>,
206 pub payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
208 pub system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
210}
211
212pub struct MintToCpi<'a, 'b> {
214 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
216 pub token_account: &'b solana_program::account_info::AccountInfo<'a>,
218 pub mint: &'b solana_program::account_info::AccountInfo<'a>,
220 pub authority: &'b solana_program::account_info::AccountInfo<'a>,
222 pub payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
224 pub system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
226 pub __args: MintToInstructionArgs,
228}
229
230impl<'a, 'b> MintToCpi<'a, 'b> {
231 pub fn new(
232 program: &'b solana_program::account_info::AccountInfo<'a>,
233 accounts: MintToCpiAccounts<'a, 'b>,
234 args: MintToInstructionArgs,
235 ) -> Self {
236 Self {
237 __program: program,
238 token_account: accounts.token_account,
239 mint: accounts.mint,
240 authority: accounts.authority,
241 payer: accounts.payer,
242 system_program: accounts.system_program,
243 __args: args,
244 }
245 }
246 #[inline(always)]
247 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
248 self.invoke_signed_with_remaining_accounts(&[], &[])
249 }
250 #[inline(always)]
251 pub fn invoke_with_remaining_accounts(
252 &self,
253 remaining_accounts: &[(
254 &'b solana_program::account_info::AccountInfo<'a>,
255 bool,
256 bool,
257 )],
258 ) -> solana_program::entrypoint::ProgramResult {
259 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
260 }
261 #[inline(always)]
262 pub fn invoke_signed(
263 &self,
264 signers_seeds: &[&[&[u8]]],
265 ) -> solana_program::entrypoint::ProgramResult {
266 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
267 }
268 #[allow(clippy::clone_on_copy)]
269 #[allow(clippy::vec_init_then_push)]
270 pub fn invoke_signed_with_remaining_accounts(
271 &self,
272 signers_seeds: &[&[&[u8]]],
273 remaining_accounts: &[(
274 &'b solana_program::account_info::AccountInfo<'a>,
275 bool,
276 bool,
277 )],
278 ) -> solana_program::entrypoint::ProgramResult {
279 let mut accounts = Vec::with_capacity(5 + remaining_accounts.len());
280 accounts.push(solana_program::instruction::AccountMeta::new(
281 *self.token_account.key,
282 false,
283 ));
284 accounts.push(solana_program::instruction::AccountMeta::new(
285 *self.mint.key,
286 false,
287 ));
288 accounts.push(solana_program::instruction::AccountMeta::new(
289 *self.authority.key,
290 true,
291 ));
292 if let Some(payer) = self.payer {
293 accounts.push(solana_program::instruction::AccountMeta::new(
294 *payer.key, true,
295 ));
296 } else {
297 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
298 crate::SIGIL_ID,
299 false,
300 ));
301 }
302 if let Some(system_program) = self.system_program {
303 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
304 *system_program.key,
305 false,
306 ));
307 } else {
308 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
309 crate::SIGIL_ID,
310 false,
311 ));
312 }
313 remaining_accounts.iter().for_each(|remaining_account| {
314 accounts.push(solana_program::instruction::AccountMeta {
315 pubkey: *remaining_account.0.key,
316 is_signer: remaining_account.1,
317 is_writable: remaining_account.2,
318 })
319 });
320 let mut data = MintToInstructionData::new().try_to_vec().unwrap();
321 let mut args = self.__args.try_to_vec().unwrap();
322 data.append(&mut args);
323
324 let instruction = solana_program::instruction::Instruction {
325 program_id: crate::SIGIL_ID,
326 accounts,
327 data,
328 };
329 let mut account_infos = Vec::with_capacity(5 + 1 + remaining_accounts.len());
330 account_infos.push(self.__program.clone());
331 account_infos.push(self.token_account.clone());
332 account_infos.push(self.mint.clone());
333 account_infos.push(self.authority.clone());
334 if let Some(payer) = self.payer {
335 account_infos.push(payer.clone());
336 }
337 if let Some(system_program) = self.system_program {
338 account_infos.push(system_program.clone());
339 }
340 remaining_accounts
341 .iter()
342 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
343
344 if signers_seeds.is_empty() {
345 solana_program::program::invoke(&instruction, &account_infos)
346 } else {
347 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
348 }
349 }
350}
351
352pub struct MintToCpiBuilder<'a, 'b> {
362 instruction: Box<MintToCpiBuilderInstruction<'a, 'b>>,
363}
364
365impl<'a, 'b> MintToCpiBuilder<'a, 'b> {
366 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
367 let instruction = Box::new(MintToCpiBuilderInstruction {
368 __program: program,
369 token_account: None,
370 mint: None,
371 authority: None,
372 payer: None,
373 system_program: None,
374 amount: None,
375 __remaining_accounts: Vec::new(),
376 });
377 Self { instruction }
378 }
379 #[inline(always)]
381 pub fn token_account(
382 &mut self,
383 token_account: &'b solana_program::account_info::AccountInfo<'a>,
384 ) -> &mut Self {
385 self.instruction.token_account = Some(token_account);
386 self
387 }
388 #[inline(always)]
390 pub fn mint(&mut self, mint: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
391 self.instruction.mint = Some(mint);
392 self
393 }
394 #[inline(always)]
396 pub fn authority(
397 &mut self,
398 authority: &'b solana_program::account_info::AccountInfo<'a>,
399 ) -> &mut Self {
400 self.instruction.authority = Some(authority);
401 self
402 }
403 #[inline(always)]
406 pub fn payer(
407 &mut self,
408 payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
409 ) -> &mut Self {
410 self.instruction.payer = payer;
411 self
412 }
413 #[inline(always)]
416 pub fn system_program(
417 &mut self,
418 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
419 ) -> &mut Self {
420 self.instruction.system_program = system_program;
421 self
422 }
423 #[inline(always)]
424 pub fn amount(&mut self, amount: u32) -> &mut Self {
425 self.instruction.amount = Some(amount);
426 self
427 }
428 #[inline(always)]
430 pub fn add_remaining_account(
431 &mut self,
432 account: &'b solana_program::account_info::AccountInfo<'a>,
433 is_writable: bool,
434 is_signer: bool,
435 ) -> &mut Self {
436 self.instruction
437 .__remaining_accounts
438 .push((account, is_writable, is_signer));
439 self
440 }
441 #[inline(always)]
446 pub fn add_remaining_accounts(
447 &mut self,
448 accounts: &[(
449 &'b solana_program::account_info::AccountInfo<'a>,
450 bool,
451 bool,
452 )],
453 ) -> &mut Self {
454 self.instruction
455 .__remaining_accounts
456 .extend_from_slice(accounts);
457 self
458 }
459 #[inline(always)]
460 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
461 self.invoke_signed(&[])
462 }
463 #[allow(clippy::clone_on_copy)]
464 #[allow(clippy::vec_init_then_push)]
465 pub fn invoke_signed(
466 &self,
467 signers_seeds: &[&[&[u8]]],
468 ) -> solana_program::entrypoint::ProgramResult {
469 let args = MintToInstructionArgs {
470 amount: self.instruction.amount.clone().expect("amount is not set"),
471 };
472 let instruction = MintToCpi {
473 __program: self.instruction.__program,
474
475 token_account: self
476 .instruction
477 .token_account
478 .expect("token_account is not set"),
479
480 mint: self.instruction.mint.expect("mint is not set"),
481
482 authority: self.instruction.authority.expect("authority is not set"),
483
484 payer: self.instruction.payer,
485
486 system_program: self.instruction.system_program,
487 __args: args,
488 };
489 instruction.invoke_signed_with_remaining_accounts(
490 signers_seeds,
491 &self.instruction.__remaining_accounts,
492 )
493 }
494}
495
496struct MintToCpiBuilderInstruction<'a, 'b> {
497 __program: &'b solana_program::account_info::AccountInfo<'a>,
498 token_account: Option<&'b solana_program::account_info::AccountInfo<'a>>,
499 mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
500 authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
501 payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
502 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
503 amount: Option<u32>,
504 __remaining_accounts: Vec<(
506 &'b solana_program::account_info::AccountInfo<'a>,
507 bool,
508 bool,
509 )>,
510}