lib.rs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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 payer = next_account_info(accounts_iter)?;
  31. let rent = next_account_info(accounts_iter)?;
  32. let system_program = next_account_info(accounts_iter)?;
  33. let token_program = next_account_info(accounts_iter)?;
  34. // Find the size for the account with the Extension
  35. let space = ExtensionType::get_account_len::<Mint>(&[ExtensionType::NonTransferable]);
  36. // Get the required rent exemption amount for the account
  37. let rent_required = Rent::get()?.minimum_balance(space);
  38. // Create the account for the Mint and allocate space
  39. msg!("Mint account address : {}", mint_account.key);
  40. invoke(
  41. &system_instruction::create_account(
  42. payer.key,
  43. mint_account.key,
  44. rent_required,
  45. space as u64,
  46. token_program.key,
  47. ),
  48. &[
  49. mint_account.clone(),
  50. payer.clone(),
  51. system_program.clone(),
  52. token_program.clone(),
  53. ],
  54. )?;
  55. // This needs to be done before the Mint is initialized
  56. // Initialize the Non Transferable Mint Extension
  57. invoke(
  58. &token_instruction::initialize_non_transferable_mint(token_program.key, mint_account.key)
  59. .unwrap(),
  60. &[
  61. mint_account.clone(),
  62. token_program.clone(),
  63. system_program.clone(),
  64. ],
  65. )?;
  66. // Initialize the Token Mint
  67. invoke(
  68. &token_instruction::initialize_mint(
  69. token_program.key,
  70. mint_account.key,
  71. mint_authority.key,
  72. Some(mint_authority.key),
  73. args.token_decimals,
  74. )?,
  75. &[
  76. mint_account.clone(),
  77. mint_authority.clone(),
  78. token_program.clone(),
  79. rent.clone(),
  80. ],
  81. )?;
  82. msg!("Mint created!");
  83. Ok(())
  84. }