spl_simplified/simplespl.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
use anchor_lang::solana_program::account_info::AccountInfo;
use anchor_lang::solana_program::pubkey::Pubkey;
use anchor_lang::Key;
use anchor_lang::{context::CpiContext, Accounts};
use anchor_lang::{solana_program, Result};
use mpl_token_metadata::types::{Creator, DataV2};
use solana_program::program::invoke_signed;
pub use spl_token::ID;
use crate::metadata::{create_metadata_accounts_v3, CreateMetadataAccountsV3};
/// Mints a specified amount of tokens to a given account.
///
/// # Arguments
///
/// * `ctx` - The context for the CPI (Cross-Program Invocation) which includes
/// the accounts necessary for the minting process.
/// * `amount` - The number of tokens to mint.
///
/// # Returns
///
/// A `Result` that is `Ok(())` on success or an error if the minting fails.
pub fn mint_to<'info>(
ctx: CpiContext<'_, '_, '_, 'info, MintTo<'info>>,
amount: u64,
) -> Result<()> {
// Create the mint instruction using the SPL Token program.
let ix = spl_token::instruction::mint_to(
&spl_token::ID,
ctx.accounts.mint.key,
ctx.accounts.to.key,
ctx.accounts.authority.key,
&[],
amount,
)?;
// Invoke the mint instruction with the provided accounts and signer seeds.
invoke_signed(
&ix,
&[ctx.accounts.to, ctx.accounts.mint, ctx.accounts.authority],
ctx.signer_seeds,
)
.map_err(Into::into)
}
/// Mints a new token and creates its associated metadata.
///
/// # Arguments
///
/// * `token_name` - The name of the token being minted.
/// * `token_symbol` - The symbol associated with the token.
/// * `token_uri` - The URI pointing to the token's metadata.
/// * `token_tax` - The seller fee basis points for the token.
/// * `payer` - The account that will pay for the transaction.
/// * `token_metadata_program` - The metadata program account.
/// * `update_authority` - The authority responsible for updating the token metadata.
/// * `metadata` - The account where metadata for the token will be stored.
/// * `mint_authority` - The account that has the authority to mint new tokens.
/// * `system_program` - The system program account for account management.
/// * `rent` - The rent account for Solana's rent exemption.
/// * `token_program` - The SPL token program account.
/// * `mint` - The account of the mint being created.
/// * `to` - The account where the newly minted tokens will be sent.
/// * `owner` - The account that will own the minted tokens.
/// * `signer_seeds` - The seeds used for signing the transaction.
/// * `amount` - The number of tokens to mint.
///
/// # Returns
///
/// A `Result` that is `Ok(())` on success or an error if the minting or metadata
/// creation fails.
pub fn mint_simple<'info>(
token_name: String,
token_symbol: String,
token_uri: String,
token_tax: u16,
payer: AccountInfo<'info>,
token_metadata_program: AccountInfo<'info>,
update_authority: AccountInfo<'info>,
metadata: AccountInfo<'info>,
mint_authority: AccountInfo<'info>,
system_program: AccountInfo<'info>,
rent: AccountInfo<'info>,
token_program: AccountInfo<'info>,
mint: AccountInfo<'info>,
to: AccountInfo<'info>,
owner: AccountInfo<'info>,
signer_seeds: &[&[u8]],
amount: u64,
) -> Result<()> {
// Call the metadata creation function to create the token's metadata.
metadata_thing(
token_name.clone(),
token_symbol.clone(),
token_uri.clone(),
token_tax.clone(),
payer,
token_metadata_program,
update_authority,
mint.clone(),
metadata,
mint_authority,
system_program,
rent,
&[&signer_seeds],
)?;
// Create the mint instruction for the specified amount.
let ix = spl_token::instruction::mint_to(
&spl_token::ID,
&mint.key(),
&to.key(),
&owner.key(),
&[],
amount,
)?;
// Invoke the mint instruction with the provided accounts and signer seeds.
invoke_signed(
&ix,
&[mint.clone(), to.clone(), owner.clone(), token_program],
&[signer_seeds],
)?;
Ok(())
}
/// Helper function to create metadata for a newly minted token.
///
/// # Arguments
///
/// * `token_name` - The name of the token.
/// * `token_symbol` - The symbol for the token.
/// * `token_uri` - The URI for the token's metadata.
/// * `token_tax` - The seller fee basis points for the token.
/// * `payer` - The account responsible for paying for metadata creation.
/// * `token_metadata_program` - The metadata program account.
/// * `update_authority` - The authority that can update the metadata.
/// * `mint` - The mint account associated with the token.
/// * `metadata` - The account where the metadata will be stored.
/// * `mint_authority` - The authority for minting new tokens.
/// * `system_program` - The system program account.
/// * `rent` - The rent account for rent exemption.
/// * `signer_seed` - The seeds used for signing the transaction.
///
/// # Returns
///
/// A `Result` that is `Ok(())` on success or an error if metadata creation fails.
fn metadata_thing<'info>(
token_name: String,
token_symbol: String,
token_uri: String,
token_tax: u16,
payer: AccountInfo<'info>,
token_metadata_program: AccountInfo<'info>,
update_authority: AccountInfo<'info>,
mint: AccountInfo<'info>,
metadata: AccountInfo<'info>,
mint_authority: AccountInfo<'info>,
system_program: AccountInfo<'info>,
rent: AccountInfo<'info>,
signer_seed: &[&[&[u8]]],
) -> Result<()> {
let mut creators: Vec<Creator> = Vec::<Creator>::new();
// Create the creator object for the token metadata.
let creator: Creator = Creator {
address: mint.key(),
verified: true,
share: 100,
};
creators.push(creator);
// Create the token data structure with the provided information.
let token_data: DataV2 = DataV2 {
name: token_name.clone(),
symbol: token_symbol,
uri: token_uri,
seller_fee_basis_points: token_tax,
creators: Some(creators),
collection: None,
uses: None,
};
// Create a context for calling the metadata creation function.
let metadata_ctx = CpiContext::new_with_signer(
token_metadata_program,
CreateMetadataAccountsV3 {
payer,
update_authority,
mint,
metadata,
mint_authority,
system_program,
rent,
},
signer_seed,
);
// Invoke the metadata creation function.
create_metadata_accounts_v3(metadata_ctx, token_data, false, true, None)?;
Ok(())
}
/// Struct to define the accounts required for the minting process.
///
/// # Fields
///
/// * `mint` - The account of the mint to be used.
/// * `to` - The account that will receive the newly minted tokens.
/// * `authority` - The authority account responsible for the minting.
#[derive(Accounts)]
pub struct MintTo<'info> {
pub mint: AccountInfo<'info>,
pub to: AccountInfo<'info>,
pub authority: AccountInfo<'info>,
}