lib.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. use {
  2. borsh::{BorshDeserialize, BorshSerialize},
  3. solana_program::{
  4. account_info::{next_account_info, AccountInfo},
  5. entrypoint,
  6. entrypoint::ProgramResult,
  7. msg,
  8. program::invoke,
  9. pubkey::Pubkey,
  10. rent::Rent,
  11. system_instruction,
  12. sysvar::Sysvar,
  13. },
  14. spl_token_2022::{
  15. extension::{
  16. default_account_state::instruction::{
  17. initialize_default_account_state, update_default_account_state,
  18. },
  19. ExtensionType,
  20. },
  21. instruction as token_instruction,
  22. state::AccountState,
  23. state::Mint,
  24. },
  25. };
  26. #[derive(BorshSerialize, BorshDeserialize, Debug)]
  27. pub struct CreateTokenArgs {
  28. pub token_decimals: u8,
  29. }
  30. entrypoint!(process_instruction);
  31. fn process_instruction(
  32. _program_id: &Pubkey,
  33. accounts: &[AccountInfo],
  34. instruction_data: &[u8],
  35. ) -> ProgramResult {
  36. let args = CreateTokenArgs::try_from_slice(instruction_data)?;
  37. let accounts_iter = &mut accounts.iter();
  38. let mint_account = next_account_info(accounts_iter)?;
  39. let mint_authority = next_account_info(accounts_iter)?;
  40. let payer = next_account_info(accounts_iter)?;
  41. let rent = next_account_info(accounts_iter)?;
  42. let system_program = next_account_info(accounts_iter)?;
  43. let token_program = next_account_info(accounts_iter)?;
  44. // Find the size for the account with the Extension
  45. let space = ExtensionType::get_account_len::<Mint>(&[ExtensionType::DefaultAccountState]);
  46. // Get the required rent exemption amount for the account
  47. let rent_required = Rent::get()?.minimum_balance(space);
  48. // Create the account for the Mint and allocate space
  49. msg!("Mint account address : {}", mint_account.key);
  50. invoke(
  51. &system_instruction::create_account(
  52. payer.key,
  53. mint_account.key,
  54. rent_required,
  55. space as u64,
  56. token_program.key,
  57. ),
  58. &[
  59. mint_account.clone(),
  60. payer.clone(),
  61. system_program.clone(),
  62. token_program.clone(),
  63. ],
  64. )?;
  65. // This needs to be done before the Mint is initialized
  66. // Initialize the Default Account State as Frozen
  67. invoke(
  68. &initialize_default_account_state(
  69. token_program.key,
  70. mint_account.key,
  71. &AccountState::Frozen,
  72. )
  73. .unwrap(),
  74. &[
  75. mint_account.clone(),
  76. token_program.clone(),
  77. system_program.clone(),
  78. ],
  79. )?;
  80. // Initialize the Token Mint
  81. invoke(
  82. &token_instruction::initialize_mint(
  83. token_program.key,
  84. mint_account.key,
  85. mint_authority.key,
  86. Some(mint_authority.key),
  87. args.token_decimals,
  88. )?,
  89. &[
  90. mint_account.clone(),
  91. mint_authority.clone(),
  92. token_program.clone(),
  93. rent.clone(),
  94. ],
  95. )?;
  96. // Update the Default Account State to Initialized
  97. invoke(
  98. &update_default_account_state(
  99. token_program.key,
  100. mint_account.key,
  101. payer.key,
  102. &[payer.key],
  103. &AccountState::Initialized,
  104. )
  105. .unwrap(),
  106. &[
  107. mint_account.clone(),
  108. payer.clone(),
  109. token_program.clone(),
  110. system_program.clone(),
  111. ],
  112. )?;
  113. msg!("Mint created!");
  114. Ok(())
  115. }