create.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. use {
  2. borsh::{BorshDeserialize, BorshSerialize},
  3. mpl_token_metadata::instruction as mpl_instruction,
  4. solana_program::{
  5. account_info::{next_account_info, AccountInfo},
  6. entrypoint::ProgramResult,
  7. msg,
  8. program::{invoke, invoke_signed},
  9. program_pack::Pack,
  10. pubkey::Pubkey,
  11. rent::Rent,
  12. system_instruction,
  13. sysvar::Sysvar,
  14. },
  15. spl_token::{instruction as token_instruction, state::Mint},
  16. };
  17. use crate::state::MintAuthorityPda;
  18. #[derive(BorshSerialize, BorshDeserialize, Debug)]
  19. pub struct CreateTokenArgs {
  20. pub nft_title: String,
  21. pub nft_symbol: String,
  22. pub nft_uri: String,
  23. }
  24. pub fn create_token(
  25. program_id: &Pubkey,
  26. accounts: &[AccountInfo],
  27. args: CreateTokenArgs,
  28. ) -> ProgramResult {
  29. let accounts_iter = &mut accounts.iter();
  30. let mint_account = next_account_info(accounts_iter)?;
  31. let mint_authority = next_account_info(accounts_iter)?;
  32. let metadata_account = next_account_info(accounts_iter)?;
  33. let payer = next_account_info(accounts_iter)?;
  34. let rent = next_account_info(accounts_iter)?;
  35. let system_program = next_account_info(accounts_iter)?;
  36. let token_program = next_account_info(accounts_iter)?;
  37. let token_metadata_program = next_account_info(accounts_iter)?;
  38. let (mint_authority_pda, bump) =
  39. Pubkey::find_program_address(&[MintAuthorityPda::SEED_PREFIX.as_bytes()], program_id);
  40. assert!(&mint_authority_pda.eq(mint_authority.key));
  41. // First create the account for the Mint
  42. //
  43. msg!("Creating mint account...");
  44. msg!("Mint: {}", mint_account.key);
  45. invoke(
  46. &system_instruction::create_account(
  47. payer.key,
  48. mint_account.key,
  49. (Rent::get()?).minimum_balance(Mint::LEN),
  50. Mint::LEN as u64,
  51. token_program.key,
  52. ),
  53. &[
  54. mint_account.clone(),
  55. payer.clone(),
  56. system_program.clone(),
  57. token_program.clone(),
  58. ],
  59. )?;
  60. // Now initialize that account as a Mint (standard Mint)
  61. //
  62. msg!("Initializing mint account...");
  63. msg!("Mint: {}", mint_account.key);
  64. invoke(
  65. &token_instruction::initialize_mint(
  66. token_program.key,
  67. mint_account.key,
  68. mint_authority.key,
  69. Some(mint_authority.key),
  70. 0, // 0 Decimals for the NFT standard
  71. )?,
  72. &[
  73. mint_account.clone(),
  74. mint_authority.clone(),
  75. token_program.clone(),
  76. rent.clone(),
  77. ],
  78. )?;
  79. // Now create the account for that Mint's metadata
  80. //
  81. msg!("Creating metadata account...");
  82. msg!("Metadata account address: {}", metadata_account.key);
  83. invoke_signed(
  84. &mpl_instruction::create_metadata_accounts_v3(
  85. *token_metadata_program.key,
  86. *metadata_account.key,
  87. *mint_account.key,
  88. *mint_authority.key,
  89. *payer.key,
  90. *mint_authority.key,
  91. args.nft_title,
  92. args.nft_symbol,
  93. args.nft_uri,
  94. None,
  95. 0,
  96. true,
  97. false,
  98. None,
  99. None,
  100. None,
  101. ),
  102. &[
  103. metadata_account.clone(),
  104. mint_account.clone(),
  105. mint_authority.clone(),
  106. payer.clone(),
  107. token_metadata_program.clone(),
  108. rent.clone(),
  109. ],
  110. &[&[MintAuthorityPda::SEED_PREFIX.as_bytes(), &[bump]]],
  111. )?;
  112. msg!("Token mint created successfully.");
  113. Ok(())
  114. }