1extern crate self as light_instruction_decoder;
19
20use light_instruction_decoder_derive::InstructionDecoder;
21use light_token_interface::instructions::{
22 mint_action::MintActionCompressedInstructionData,
23 transfer2::CompressedTokenInstructionDataTransfer2,
24};
25use solana_instruction::AccountMeta;
26
27#[cfg(not(target_os = "solana"))]
37fn calculate_packed_accounts_start(data: &CompressedTokenInstructionDataTransfer2) -> usize {
38 let no_compressed_accounts = data.in_token_data.is_empty() && data.out_token_data.is_empty();
39 let cpi_context_write_required = data
40 .cpi_context
41 .as_ref()
42 .map(|ctx| ctx.set_context || ctx.first_set_context)
43 .unwrap_or(false);
44
45 if no_compressed_accounts {
46 2
49 } else if cpi_context_write_required {
50 4
54 } else {
55 let mut start = 7;
59
60 let in_lamports: u64 = data
62 .in_lamports
63 .as_ref()
64 .map(|v| v.iter().sum())
65 .unwrap_or(0);
66 let out_lamports: u64 = data
67 .out_lamports
68 .as_ref()
69 .map(|v| v.iter().sum())
70 .unwrap_or(0);
71 if in_lamports != out_lamports {
72 start += 1; }
74
75 if out_lamports > in_lamports {
77 start += 1; }
79
80 if data.cpi_context.is_some() {
82 start += 1; }
84
85 start
86 }
87}
88
89#[cfg(not(target_os = "solana"))]
98pub fn format_transfer2(
99 data: &CompressedTokenInstructionDataTransfer2,
100 accounts: &[AccountMeta],
101) -> String {
102 use std::fmt::Write;
103 let mut output = String::new();
104
105 let cpi_context_write_mode = data
107 .cpi_context
108 .as_ref()
109 .map(|ctx| ctx.set_context || ctx.first_set_context)
110 .unwrap_or(false);
111
112 let packed_accounts_start = calculate_packed_accounts_start(data);
114
115 let resolve = |index: u8| -> String {
117 if cpi_context_write_mode {
118 format!("packed[{}]", index)
120 } else {
121 accounts
122 .get(packed_accounts_start + index as usize)
123 .map(|a| a.pubkey.to_string())
124 .unwrap_or_else(|| format!("OUT_OF_BOUNDS({})", index))
125 }
126 };
127
128 if cpi_context_write_mode {
130 let _ = writeln!(
131 output,
132 "[CPI Context Write Mode - packed accounts in CPI context]"
133 );
134 }
135
136 let _ = writeln!(output, "output_queue: {}", resolve(data.output_queue));
138 if data.max_top_up > 0 {
139 let _ = writeln!(output, "max_top_up: {}", data.max_top_up);
140 }
141 if data.with_transaction_hash {
142 let _ = writeln!(output, "with_transaction_hash: true");
143 }
144
145 let _ = writeln!(output, "Input Tokens ({}):", data.in_token_data.len());
147 for (i, token) in data.in_token_data.iter().enumerate() {
148 let _ = writeln!(output, " [{}]", i);
149 let _ = writeln!(output, " owner: {}", resolve(token.owner));
150 let _ = writeln!(output, " mint: {}", resolve(token.mint));
151 let _ = writeln!(output, " amount: {}", token.amount);
152 if token.has_delegate {
153 let _ = writeln!(output, " delegate: {}", resolve(token.delegate));
154 }
155 let _ = writeln!(output, " version: {}", token.version);
156 let _ = writeln!(
158 output,
159 " merkle_tree: {}",
160 resolve(token.merkle_context.merkle_tree_pubkey_index)
161 );
162 let _ = writeln!(
163 output,
164 " queue: {}",
165 resolve(token.merkle_context.queue_pubkey_index)
166 );
167 let _ = writeln!(
168 output,
169 " leaf_index: {}",
170 token.merkle_context.leaf_index
171 );
172 let _ = writeln!(output, " root_index: {}", token.root_index);
173 }
174
175 let _ = writeln!(output, "Output Tokens ({}):", data.out_token_data.len());
177 for (i, token) in data.out_token_data.iter().enumerate() {
178 let _ = writeln!(output, " [{}]", i);
179 let _ = writeln!(output, " owner: {}", resolve(token.owner));
180 let _ = writeln!(output, " mint: {}", resolve(token.mint));
181 let _ = writeln!(output, " amount: {}", token.amount);
182 if token.has_delegate {
183 let _ = writeln!(output, " delegate: {}", resolve(token.delegate));
184 }
185 let _ = writeln!(output, " version: {}", token.version);
186 }
187
188 if let Some(compressions) = &data.compressions {
190 let _ = writeln!(output, "Compressions ({}):", compressions.len());
191 for (i, comp) in compressions.iter().enumerate() {
192 let _ = writeln!(output, " [{}]", i);
193 let _ = writeln!(output, " mode: {:?}", comp.mode);
194 let _ = writeln!(output, " amount: {}", comp.amount);
195 let _ = writeln!(output, " mint: {}", resolve(comp.mint));
196 let _ = writeln!(
197 output,
198 " source_or_recipient: {}",
199 resolve(comp.source_or_recipient)
200 );
201 let _ = writeln!(output, " authority: {}", resolve(comp.authority));
202 }
203 }
204
205 output
206}
207
208#[cfg(not(target_os = "solana"))]
232pub fn resolve_transfer2_account_names(
233 data: &CompressedTokenInstructionDataTransfer2,
234 accounts: &[AccountMeta],
235) -> Vec<String> {
236 use std::collections::HashMap;
237
238 let mut names = Vec::with_capacity(accounts.len());
239 let mut idx = 0;
240 let mut known_pubkeys: HashMap<[u8; 32], String> = HashMap::new();
241
242 let mut add_name = |name: &str,
243 accounts: &[AccountMeta],
244 idx: &mut usize,
245 known: &mut HashMap<[u8; 32], String>| {
246 if *idx < accounts.len() {
247 names.push(name.to_string());
248 known.insert(accounts[*idx].pubkey.to_bytes(), name.to_string());
249 *idx += 1;
250 true
251 } else {
252 false
253 }
254 };
255
256 let no_compressed_accounts = data.in_token_data.is_empty() && data.out_token_data.is_empty();
258 let cpi_context_write_required = data
259 .cpi_context
260 .as_ref()
261 .map(|ctx| ctx.set_context || ctx.first_set_context)
262 .unwrap_or(false);
263
264 if no_compressed_accounts {
265 add_name(
267 "compressions_only_cpi_authority_pda",
268 accounts,
269 &mut idx,
270 &mut known_pubkeys,
271 );
272 add_name(
273 "compressions_only_fee_payer",
274 accounts,
275 &mut idx,
276 &mut known_pubkeys,
277 );
278 } else if cpi_context_write_required {
279 add_name(
281 "light_system_program",
282 accounts,
283 &mut idx,
284 &mut known_pubkeys,
285 );
286 add_name("fee_payer", accounts, &mut idx, &mut known_pubkeys);
287 add_name("cpi_authority_pda", accounts, &mut idx, &mut known_pubkeys);
288 add_name("cpi_context", accounts, &mut idx, &mut known_pubkeys);
289 return names;
291 } else {
292 add_name(
294 "light_system_program",
295 accounts,
296 &mut idx,
297 &mut known_pubkeys,
298 );
299 add_name("fee_payer", accounts, &mut idx, &mut known_pubkeys);
300 add_name("cpi_authority_pda", accounts, &mut idx, &mut known_pubkeys);
301 add_name(
302 "registered_program_pda",
303 accounts,
304 &mut idx,
305 &mut known_pubkeys,
306 );
307 add_name(
308 "account_compression_authority",
309 accounts,
310 &mut idx,
311 &mut known_pubkeys,
312 );
313 add_name(
314 "account_compression_program",
315 accounts,
316 &mut idx,
317 &mut known_pubkeys,
318 );
319 add_name("system_program", accounts, &mut idx, &mut known_pubkeys);
320
321 let in_lamports: u64 = data
324 .in_lamports
325 .as_ref()
326 .map(|v| v.iter().sum())
327 .unwrap_or(0);
328 let out_lamports: u64 = data
329 .out_lamports
330 .as_ref()
331 .map(|v| v.iter().sum())
332 .unwrap_or(0);
333 let with_sol_pool = in_lamports != out_lamports;
334 if with_sol_pool {
335 add_name("sol_pool_pda", accounts, &mut idx, &mut known_pubkeys);
336 }
337
338 let with_sol_decompression = out_lamports > in_lamports;
340 if with_sol_decompression {
341 add_name(
342 "sol_decompression_recipient",
343 accounts,
344 &mut idx,
345 &mut known_pubkeys,
346 );
347 }
348
349 if data.cpi_context.is_some() {
351 names.push(String::new()); idx += 1;
353 }
354 }
355
356 let mut packed_roles: HashMap<u8, String> = HashMap::new();
358 let mut owner_count = 0u8;
359 let mut mint_count = 0u8;
360 let mut delegate_count = 0u8;
361 let mut in_merkle_count = 0u8;
362 let mut in_queue_count = 0u8;
363 let mut compress_mint_count = 0u8;
364 let mut compress_source_count = 0u8;
365 let mut compress_auth_count = 0u8;
366
367 packed_roles
369 .entry(data.output_queue)
370 .or_insert_with(|| "output_queue".to_string());
371
372 for token in data.in_token_data.iter() {
374 packed_roles.entry(token.owner).or_insert_with(|| {
375 let name = if owner_count == 0 {
376 "owner".to_string()
377 } else {
378 format!("owner_{}", owner_count)
379 };
380 owner_count = owner_count.saturating_add(1);
381 name
382 });
383 packed_roles.entry(token.mint).or_insert_with(|| {
384 let name = if mint_count == 0 {
385 "mint".to_string()
386 } else {
387 format!("mint_{}", mint_count)
388 };
389 mint_count = mint_count.saturating_add(1);
390 name
391 });
392 if token.has_delegate {
393 packed_roles.entry(token.delegate).or_insert_with(|| {
394 let name = if delegate_count == 0 {
395 "delegate".to_string()
396 } else {
397 format!("delegate_{}", delegate_count)
398 };
399 delegate_count = delegate_count.saturating_add(1);
400 name
401 });
402 }
403 packed_roles
404 .entry(token.merkle_context.merkle_tree_pubkey_index)
405 .or_insert_with(|| {
406 let name = if in_merkle_count == 0 {
407 "in_merkle_tree".to_string()
408 } else {
409 format!("in_merkle_tree_{}", in_merkle_count)
410 };
411 in_merkle_count = in_merkle_count.saturating_add(1);
412 name
413 });
414 packed_roles
415 .entry(token.merkle_context.queue_pubkey_index)
416 .or_insert_with(|| {
417 let name = if in_queue_count == 0 {
418 "in_nullifier_queue".to_string()
419 } else {
420 format!("in_nullifier_queue_{}", in_queue_count)
421 };
422 in_queue_count = in_queue_count.saturating_add(1);
423 name
424 });
425 }
426
427 for token in data.out_token_data.iter() {
429 packed_roles.entry(token.owner).or_insert_with(|| {
430 let name = if owner_count == 0 {
431 "owner".to_string()
432 } else {
433 format!("owner_{}", owner_count)
434 };
435 owner_count = owner_count.saturating_add(1);
436 name
437 });
438 packed_roles.entry(token.mint).or_insert_with(|| {
439 let name = if mint_count == 0 {
440 "mint".to_string()
441 } else {
442 format!("mint_{}", mint_count)
443 };
444 mint_count = mint_count.saturating_add(1);
445 name
446 });
447 if token.has_delegate {
448 packed_roles.entry(token.delegate).or_insert_with(|| {
449 let name = if delegate_count == 0 {
450 "delegate".to_string()
451 } else {
452 format!("delegate_{}", delegate_count)
453 };
454 delegate_count = delegate_count.saturating_add(1);
455 name
456 });
457 }
458 }
459
460 if let Some(compressions) = &data.compressions {
462 for comp in compressions.iter() {
463 packed_roles.entry(comp.mint).or_insert_with(|| {
464 let name = if compress_mint_count == 0 {
465 "compress_mint".to_string()
466 } else {
467 format!("compress_mint_{}", compress_mint_count)
468 };
469 compress_mint_count = compress_mint_count.saturating_add(1);
470 name
471 });
472 packed_roles
473 .entry(comp.source_or_recipient)
474 .or_insert_with(|| {
475 let name = if compress_source_count == 0 {
476 "compress_source".to_string()
477 } else {
478 format!("compress_source_{}", compress_source_count)
479 };
480 compress_source_count = compress_source_count.saturating_add(1);
481 name
482 });
483 packed_roles.entry(comp.authority).or_insert_with(|| {
484 let name = if compress_auth_count == 0 {
485 "compress_authority".to_string()
486 } else {
487 format!("compress_authority_{}", compress_auth_count)
488 };
489 compress_auth_count = compress_auth_count.saturating_add(1);
490 name
491 });
492 }
493 }
494
495 let mut packed_idx: u8 = 0;
497 while idx < accounts.len() {
498 let pubkey_bytes = accounts[idx].pubkey.to_bytes();
499
500 if let Some(role) = packed_roles.get(&packed_idx) {
502 if let Some(known_name) = known_pubkeys.get(&pubkey_bytes) {
504 names.push(format!("{} (={})", role, known_name));
505 } else {
506 names.push(role.clone());
507 known_pubkeys.insert(pubkey_bytes, role.clone());
508 }
509 } else if let Some(known_name) = known_pubkeys.get(&pubkey_bytes) {
510 names.push(format!("packed_{} (={})", packed_idx, known_name));
512 } else {
513 names.push(format!("packed_account_{}", packed_idx));
515 }
516 idx += 1;
517 packed_idx = packed_idx.saturating_add(1);
518 }
519
520 names
521}
522
523#[cfg(not(target_os = "solana"))]
541pub fn resolve_mint_action_account_names(
542 data: &MintActionCompressedInstructionData,
543 accounts: &[AccountMeta],
544) -> Vec<String> {
545 use std::collections::HashMap;
546
547 use light_token_interface::instructions::mint_action::Action;
548
549 let mut names = Vec::with_capacity(accounts.len());
550 let mut idx = 0;
551 let mut known_pubkeys: HashMap<[u8; 32], String> = HashMap::new();
553
554 let mut add_name = |name: &str,
556 accounts: &[AccountMeta],
557 idx: &mut usize,
558 known: &mut HashMap<[u8; 32], String>| {
559 if *idx < accounts.len() {
560 names.push(name.to_string());
561 known.insert(accounts[*idx].pubkey.to_bytes(), name.to_string());
562 *idx += 1;
563 true
564 } else {
565 false
566 }
567 };
568
569 add_name(
571 "light_system_program",
572 accounts,
573 &mut idx,
574 &mut known_pubkeys,
575 );
576
577 if data.create_mint.is_some() {
579 add_name("mint_signer", accounts, &mut idx, &mut known_pubkeys);
580 }
581
582 add_name("authority", accounts, &mut idx, &mut known_pubkeys);
584
585 let write_to_cpi_context = data
587 .cpi_context
588 .as_ref()
589 .map(|ctx| ctx.first_set_context || ctx.set_context)
590 .unwrap_or(false);
591
592 if write_to_cpi_context {
593 add_name("fee_payer", accounts, &mut idx, &mut known_pubkeys);
595 add_name("cpi_authority_pda", accounts, &mut idx, &mut known_pubkeys);
596 add_name("cpi_context", accounts, &mut idx, &mut known_pubkeys);
597 } else {
599 let has_decompress_mint_action = data
601 .actions
602 .iter()
603 .any(|action| matches!(action, Action::DecompressMint(_)));
604
605 let has_compress_and_close_cmint_action = data
606 .actions
607 .iter()
608 .any(|action| matches!(action, Action::CompressAndCloseMint(_)));
609
610 let needs_compressible_accounts =
611 has_decompress_mint_action || has_compress_and_close_cmint_action;
612
613 let cmint_decompressed = data.mint.is_none();
614 let needs_cmint_account =
615 cmint_decompressed || has_decompress_mint_action || has_compress_and_close_cmint_action;
616
617 if needs_compressible_accounts {
619 add_name(
620 "compressible_config",
621 accounts,
622 &mut idx,
623 &mut known_pubkeys,
624 );
625 }
626
627 if needs_cmint_account {
629 add_name("cmint", accounts, &mut idx, &mut known_pubkeys);
630 }
631
632 if needs_compressible_accounts {
634 add_name("rent_sponsor", accounts, &mut idx, &mut known_pubkeys);
635 }
636
637 add_name("fee_payer", accounts, &mut idx, &mut known_pubkeys);
639 add_name("cpi_authority_pda", accounts, &mut idx, &mut known_pubkeys);
640 add_name(
641 "registered_program_pda",
642 accounts,
643 &mut idx,
644 &mut known_pubkeys,
645 );
646 add_name(
647 "account_compression_authority",
648 accounts,
649 &mut idx,
650 &mut known_pubkeys,
651 );
652 add_name(
653 "account_compression_program",
654 accounts,
655 &mut idx,
656 &mut known_pubkeys,
657 );
658 add_name("system_program", accounts, &mut idx, &mut known_pubkeys);
659
660 }
663
664 names
665}
666
667#[cfg(not(target_os = "solana"))]
677fn calculate_mint_action_packed_accounts_start(
678 data: &MintActionCompressedInstructionData,
679) -> usize {
680 let cpi_context_write_mode = data
681 .cpi_context
682 .as_ref()
683 .map(|ctx| ctx.set_context || ctx.first_set_context)
684 .unwrap_or(false);
685
686 if cpi_context_write_mode {
687 3
689 } else {
690 let mut start = 6;
692 if data.cpi_context.is_some() {
693 start += 1; }
695 start
696 }
697}
698
699#[cfg(not(target_os = "solana"))]
708pub fn format_mint_action(
709 data: &MintActionCompressedInstructionData,
710 accounts: &[AccountMeta],
711) -> String {
712 use std::fmt::Write;
713
714 use light_token_interface::instructions::mint_action::Action;
715 let mut output = String::new();
716
717 let cpi_context_write_mode = data
719 .cpi_context
720 .as_ref()
721 .map(|ctx| ctx.set_context || ctx.first_set_context)
722 .unwrap_or(false);
723
724 let packed_accounts_start = calculate_mint_action_packed_accounts_start(data);
726
727 let resolve = |index: u8| -> String {
729 if cpi_context_write_mode {
730 format!("packed[{}]", index)
731 } else {
732 accounts
733 .get(packed_accounts_start + index as usize)
734 .map(|a| a.pubkey.to_string())
735 .unwrap_or_else(|| format!("OUT_OF_BOUNDS({})", index))
736 }
737 };
738
739 if cpi_context_write_mode {
741 let _ = writeln!(
742 output,
743 "[CPI Context Write Mode - packed accounts in CPI context]"
744 );
745 }
746
747 if data.create_mint.is_some() {
749 let _ = writeln!(output, "create_mint: true");
750 } else {
751 let _ = writeln!(output, "leaf_index: {}", data.leaf_index);
752 if data.prove_by_index {
753 let _ = writeln!(output, "prove_by_index: true");
754 }
755 }
756 let _ = writeln!(output, "root_index: {}", data.root_index);
757 if data.max_top_up > 0 {
758 let _ = writeln!(output, "max_top_up: {}", data.max_top_up);
759 }
760
761 if let Some(mint) = &data.mint {
763 let _ = writeln!(output, "Mint:");
764 let _ = writeln!(output, " supply: {}", mint.supply);
765 let _ = writeln!(output, " decimals: {}", mint.decimals);
766 if let Some(auth) = &mint.mint_authority {
767 let _ = writeln!(
768 output,
769 " mint_authority: {}",
770 bs58::encode(auth).into_string()
771 );
772 }
773 if let Some(auth) = &mint.freeze_authority {
774 let _ = writeln!(
775 output,
776 " freeze_authority: {}",
777 bs58::encode(auth).into_string()
778 );
779 }
780 if let Some(exts) = &mint.extensions {
781 let _ = writeln!(output, " extensions: {}", exts.len());
782 }
783 }
784
785 let _ = writeln!(output, "Actions ({}):", data.actions.len());
787 for (i, action) in data.actions.iter().enumerate() {
788 match action {
789 Action::MintToCompressed(a) => {
790 let _ = writeln!(output, " [{}] MintToCompressed:", i);
791 let _ = writeln!(output, " version: {}", a.token_account_version);
792 for (j, r) in a.recipients.iter().enumerate() {
793 let _ = writeln!(
794 output,
795 " recipient[{}]: {} amount: {}",
796 j,
797 bs58::encode(&r.recipient).into_string(),
798 r.amount
799 );
800 }
801 }
802 Action::UpdateMintAuthority(a) => {
803 let authority_str = a
804 .new_authority
805 .as_ref()
806 .map(|p| bs58::encode(p).into_string())
807 .unwrap_or_else(|| "None".to_string());
808 let _ = writeln!(output, " [{}] UpdateMintAuthority: {}", i, authority_str);
809 }
810 Action::UpdateFreezeAuthority(a) => {
811 let authority_str = a
812 .new_authority
813 .as_ref()
814 .map(|p| bs58::encode(p).into_string())
815 .unwrap_or_else(|| "None".to_string());
816 let _ = writeln!(output, " [{}] UpdateFreezeAuthority: {}", i, authority_str);
817 }
818 Action::MintTo(a) => {
819 let _ = writeln!(
820 output,
821 " [{}] MintTo: account: {}, amount: {}",
822 i,
823 resolve(a.account_index),
824 a.amount
825 );
826 }
827 Action::UpdateMetadataField(a) => {
828 let field_name = match a.field_type {
829 0 => "Name",
830 1 => "Symbol",
831 2 => "Uri",
832 _ => "Custom",
833 };
834 let _ = writeln!(
835 output,
836 " [{}] UpdateMetadataField: ext[{}] {} = {:?}",
837 i,
838 a.extension_index,
839 field_name,
840 String::from_utf8_lossy(&a.value)
841 );
842 }
843 Action::UpdateMetadataAuthority(a) => {
844 let _ = writeln!(
845 output,
846 " [{}] UpdateMetadataAuthority: ext[{}] = {}",
847 i,
848 a.extension_index,
849 bs58::encode(&a.new_authority).into_string()
850 );
851 }
852 Action::RemoveMetadataKey(a) => {
853 let _ = writeln!(
854 output,
855 " [{}] RemoveMetadataKey: ext[{}] key={:?} idempotent={}",
856 i,
857 a.extension_index,
858 String::from_utf8_lossy(&a.key),
859 a.idempotent != 0
860 );
861 }
862 Action::DecompressMint(a) => {
863 let _ = writeln!(
864 output,
865 " [{}] DecompressMint: rent_payment={} write_top_up={}",
866 i, a.rent_payment, a.write_top_up
867 );
868 }
869 Action::CompressAndCloseMint(a) => {
870 let _ = writeln!(
871 output,
872 " [{}] CompressAndCloseMint: idempotent={}",
873 i,
874 a.idempotent != 0
875 );
876 }
877 }
878 }
879
880 if let Some(ctx) = &data.cpi_context {
882 let _ = writeln!(output, "CPI Context:");
883 let _ = writeln!(
884 output,
885 " mode: {}",
886 if ctx.first_set_context {
887 "first_set_context"
888 } else if ctx.set_context {
889 "set_context"
890 } else {
891 "read"
892 }
893 );
894 let _ = writeln!(output, " in_tree: packed[{}]", ctx.in_tree_index);
895 let _ = writeln!(output, " in_queue: packed[{}]", ctx.in_queue_index);
896 let _ = writeln!(output, " out_queue: packed[{}]", ctx.out_queue_index);
897 if ctx.token_out_queue_index > 0 {
898 let _ = writeln!(
899 output,
900 " token_out_queue: packed[{}]",
901 ctx.token_out_queue_index
902 );
903 }
904 let _ = writeln!(
905 output,
906 " address_tree: {}",
907 bs58::encode(&ctx.address_tree_pubkey).into_string()
908 );
909 }
910
911 output
912}
913
914#[derive(InstructionDecoder)]
921#[instruction_decoder(
922 program_id = "cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m",
923 program_name = "Light Token",
924 discriminator_size = 1
925)]
926pub enum CTokenInstruction {
927 #[discriminator = 3]
930 #[instruction_decoder(account_names = ["source", "destination", "authority"])]
931 Transfer { amount: u64 },
932
933 #[discriminator = 4]
936 #[instruction_decoder(account_names = ["source", "delegate", "owner"])]
937 Approve { amount: u64 },
938
939 #[discriminator = 5]
942 #[instruction_decoder(account_names = ["source", "owner"])]
943 Revoke,
944
945 #[discriminator = 7]
948 #[instruction_decoder(account_names = ["cmint", "destination", "authority"])]
949 MintTo { amount: u64 },
950
951 #[discriminator = 8]
954 #[instruction_decoder(account_names = ["source", "cmint", "authority"])]
955 Burn { amount: u64 },
956
957 #[discriminator = 9]
959 #[instruction_decoder(account_names = ["account", "destination", "authority"])]
960 CloseTokenAccount,
961
962 #[discriminator = 10]
964 #[instruction_decoder(account_names = ["account", "mint", "authority"])]
965 FreezeAccount,
966
967 #[discriminator = 11]
969 #[instruction_decoder(account_names = ["account", "mint", "authority"])]
970 ThawAccount,
971
972 #[discriminator = 12]
975 #[instruction_decoder(account_names = ["source", "mint", "destination", "authority"])]
976 TransferChecked { amount: u64, decimals: u8 },
977
978 #[discriminator = 14]
981 #[instruction_decoder(account_names = ["cmint", "destination", "authority"])]
982 MintToChecked { amount: u64, decimals: u8 },
983
984 #[discriminator = 15]
987 #[instruction_decoder(account_names = ["source", "cmint", "authority"])]
988 BurnChecked { amount: u64, decimals: u8 },
989
990 #[discriminator = 18]
992 #[instruction_decoder(account_names = ["token_account", "mint", "payer", "config", "system_program", "rent_payer"])]
993 CreateTokenAccount,
994
995 #[discriminator = 100]
997 #[instruction_decoder(account_names = ["owner", "mint", "fee_payer", "ata", "system_program", "config", "rent_payer"])]
998 CreateAssociatedTokenAccount,
999
1000 #[discriminator = 101]
1003 #[instruction_decoder(
1004 params = CompressedTokenInstructionDataTransfer2,
1005 account_names_resolver_from_params = crate::programs::ctoken::resolve_transfer2_account_names,
1006 pretty_formatter = crate::programs::ctoken::format_transfer2
1007 )]
1008 Transfer2,
1009
1010 #[discriminator = 102]
1012 #[instruction_decoder(account_names = ["owner", "mint", "fee_payer", "ata", "system_program", "config", "rent_payer"])]
1013 CreateAssociatedTokenAccountIdempotent,
1014
1015 #[discriminator = 103]
1018 #[instruction_decoder(
1019 params = MintActionCompressedInstructionData,
1020 account_names_resolver_from_params = crate::programs::ctoken::resolve_mint_action_account_names,
1021 pretty_formatter = crate::programs::ctoken::format_mint_action
1022 )]
1023 MintAction,
1024
1025 #[discriminator = 104]
1027 #[instruction_decoder(account_names = ["forester", "ctoken_account", "rent_recipient", "config"])]
1028 Claim,
1029
1030 #[discriminator = 105]
1032 #[instruction_decoder(account_names = ["authority", "rent_recipient", "config", "destination"])]
1033 WithdrawFundingPool,
1034}