lib.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. // Initialize the Default Account State as Frozen
  66. invoke(
  67. &initialize_default_account_state(
  68. token_program.key,
  69. mint_account.key,
  70. &AccountState::Frozen,
  71. )
  72. .unwrap(),
  73. &[
  74. mint_account.clone(),
  75. token_program.clone(),
  76. system_program.clone(),
  77. ],
  78. )?;
  79. // Initialize the Token Mint
  80. invoke(
  81. &token_instruction::initialize_mint(
  82. &token_program.key,
  83. &mint_account.key,
  84. &mint_authority.key,
  85. Some(&mint_authority.key),
  86. args.token_decimals,
  87. )?,
  88. &[
  89. mint_account.clone(),
  90. mint_authority.clone(),
  91. token_program.clone(),
  92. rent.clone(),
  93. ],
  94. )?;
  95. // Update the Default Account State to Initialized
  96. invoke(
  97. &update_default_account_state(
  98. token_program.key,
  99. mint_account.key,
  100. payer.key,
  101. &[&payer.key],
  102. &AccountState::Initialized,
  103. )
  104. .unwrap(),
  105. &[
  106. mint_account.clone(),
  107. payer.clone(),
  108. token_program.clone(),
  109. system_program.clone(),
  110. ],
  111. )?;
  112. msg!("Mint created!");
  113. Ok(())
  114. }