lib.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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::{extension::ExtensionType, instruction as token_instruction, state::Mint},
  15. };
  16. #[derive(BorshSerialize, BorshDeserialize, Debug)]
  17. pub struct CreateTokenArgs {
  18. pub token_decimals: u8,
  19. }
  20. entrypoint!(process_instruction);
  21. fn process_instruction(
  22. _program_id: &Pubkey,
  23. accounts: &[AccountInfo],
  24. instruction_data: &[u8],
  25. ) -> ProgramResult {
  26. let args = CreateTokenArgs::try_from_slice(instruction_data)?;
  27. let accounts_iter = &mut accounts.iter();
  28. let mint_account = next_account_info(accounts_iter)?;
  29. let mint_authority = next_account_info(accounts_iter)?;
  30. let close_authority = next_account_info(accounts_iter)?;
  31. let payer = next_account_info(accounts_iter)?;
  32. let rent = next_account_info(accounts_iter)?;
  33. let system_program = next_account_info(accounts_iter)?;
  34. let token_program = next_account_info(accounts_iter)?;
  35. // Find the size for the Mint account with the the number of extensions we want to use.
  36. let space = ExtensionType::get_account_len::<Mint>(&[
  37. ExtensionType::MintCloseAuthority,
  38. ExtensionType::NonTransferable,
  39. ]);
  40. // Get the required rent exemption amount for the account
  41. let rent_required = Rent::get()?.minimum_balance(space);
  42. // Create the account for the Mint and allocate space
  43. msg!("Mint account address : {}", mint_account.key);
  44. invoke(
  45. &system_instruction::create_account(
  46. payer.key,
  47. mint_account.key,
  48. rent_required,
  49. space as u64,
  50. token_program.key,
  51. ),
  52. &[
  53. mint_account.clone(),
  54. payer.clone(),
  55. system_program.clone(),
  56. token_program.clone(),
  57. ],
  58. )?;
  59. // Here, let's enable two extensions for the Mint. This needs to be done before the Mint is initialized
  60. // Initialize the Mint close authority Extension
  61. invoke(
  62. &token_instruction::initialize_mint_close_authority(
  63. token_program.key,
  64. mint_account.key,
  65. Some(close_authority.key),
  66. )
  67. .unwrap(),
  68. &[
  69. mint_account.clone(),
  70. close_authority.clone(),
  71. token_program.clone(),
  72. system_program.clone(),
  73. ],
  74. )?;
  75. // Initialize the Non Transferable Mint Extension
  76. invoke(
  77. &token_instruction::initialize_non_transferable_mint(token_program.key, mint_account.key)
  78. .unwrap(),
  79. &[
  80. mint_account.clone(),
  81. token_program.clone(),
  82. system_program.clone(),
  83. ],
  84. )?;
  85. // Initialize the Token Mint
  86. invoke(
  87. &token_instruction::initialize_mint(
  88. token_program.key,
  89. mint_account.key,
  90. mint_authority.key,
  91. Some(mint_authority.key),
  92. args.token_decimals,
  93. )?,
  94. &[
  95. mint_account.clone(),
  96. mint_authority.clone(),
  97. token_program.clone(),
  98. rent.clone(),
  99. ],
  100. )?;
  101. msg!("Mint created!");
  102. Ok(())
  103. }