create_token.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. use solana_program::msg;
  2. use solana_program::program_pack::Pack;
  3. use spl_token::state::Mint;
  4. use steel::*;
  5. use steel_api::prelude::*;
  6. pub fn process_create_token(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
  7. //Parse Args
  8. let args = CreateToken::try_from_bytes(data)?;
  9. let name = String::from_utf8(args.name.to_vec()).expect("Invalid UTF-8");
  10. let symbol = String::from_utf8(args.symbol.to_vec()).expect("Invalid UTF-8");
  11. let uri = String::from_utf8(args.uri.to_vec()).expect("Invalid UTF-8");
  12. let decimals = args.decimals;
  13. msg!("Parsed Arguments");
  14. // Load accounts.
  15. let [signer_info, mint_info, metadata_info, system_program, token_program, metadata_program, rent_sysvar] =
  16. accounts
  17. else {
  18. return Err(ProgramError::NotEnoughAccountKeys);
  19. };
  20. msg!("Loaded Accounts");
  21. //Validation
  22. signer_info.is_signer()?;
  23. mint_info.is_signer()?.is_empty()?.is_writable()?;
  24. metadata_info.is_empty()?.is_writable()?.has_seeds(
  25. &[
  26. METADATA,
  27. mpl_token_metadata::ID.as_ref(),
  28. mint_info.key.as_ref(),
  29. ],
  30. &mpl_token_metadata::ID,
  31. )?;
  32. system_program.is_program(&system_program::ID)?;
  33. token_program.is_program(&spl_token::ID)?;
  34. metadata_program.is_program(&mpl_token_metadata::ID)?;
  35. rent_sysvar.is_sysvar(&sysvar::rent::ID)?;
  36. msg!("Accounts validated");
  37. // First, create an account for the Mint.
  38. //
  39. msg!("Creating mint account...");
  40. msg!("Mint: {}", mint_info.key);
  41. solana_program::program::invoke(
  42. &solana_program::system_instruction::create_account(
  43. signer_info.key,
  44. mint_info.key,
  45. (solana_program::rent::Rent::get()?).minimum_balance(Mint::LEN),
  46. Mint::LEN as u64,
  47. token_program.key,
  48. ),
  49. &[
  50. mint_info.clone(),
  51. signer_info.clone(),
  52. system_program.clone(),
  53. token_program.clone(),
  54. ],
  55. )?;
  56. // Second, Initialize account as Mint Account
  57. //
  58. msg!("Initializing mint account...");
  59. solana_program::program::invoke(
  60. &spl_token::instruction::initialize_mint(
  61. token_program.key,
  62. mint_info.key,
  63. signer_info.key,
  64. Some(signer_info.key),
  65. decimals, // 9 Decimals for the default SPL Token standard
  66. )?,
  67. &[
  68. mint_info.clone(),
  69. signer_info.clone(),
  70. token_program.clone(),
  71. rent_sysvar.clone(),
  72. ],
  73. )?;
  74. // Lastly, create the account for that Mint's metadata
  75. //
  76. msg!("Creating metadata account...");
  77. msg!("Metadata account address: {}", metadata_info.key);
  78. mpl_token_metadata::instructions::CreateMetadataAccountV3Cpi {
  79. __program: metadata_program,
  80. metadata: metadata_info,
  81. mint: mint_info,
  82. mint_authority: signer_info,
  83. payer: signer_info,
  84. update_authority: (signer_info, true),
  85. system_program,
  86. rent: Some(rent_sysvar),
  87. __args: mpl_token_metadata::instructions::CreateMetadataAccountV3InstructionArgs {
  88. data: mpl_token_metadata::types::DataV2 {
  89. name: name,
  90. symbol: symbol,
  91. uri: uri,
  92. seller_fee_basis_points: 0,
  93. creators: None,
  94. collection: None,
  95. uses: None,
  96. },
  97. is_mutable: true,
  98. collection_details: None,
  99. },
  100. }
  101. .invoke()?;
  102. msg!("Token mint created successfully.");
  103. Ok(())
  104. }