Skip to content

Instantly share code, notes, and snippets.

@liushooter
Created October 26, 2023 05:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liushooter/995c30c6736c4dc3154b4096f7ef9f6a to your computer and use it in GitHub Desktop.
Save liushooter/995c30c6736c4dc3154b4096f7ef9f6a to your computer and use it in GitHub Desktop.
solana-nft-anchor.rs
use anchor_lang::prelude::*;
use anchor_spl::{
associated_token::AssociatedToken,
metadata::{
create_master_edition_v3, create_metadata_accounts_v3, CreateMasterEditionV3,
CreateMetadataAccountsV3, Metadata,
},
token::{mint_to, Mint, MintTo, Token, TokenAccount},
};
use mpl_token_metadata::{
pda::{find_master_edition_account, find_metadata_account},
state::DataV2,
};
declare_id!("");
#[program]
pub mod solana_nft_anchor {
use super::*;
// Create new token mint with PDA as mint authority
pub fn init_nft(
ctx: Context<InitNFT>,
name: String,
symbol: String,
uri: String,
) -> Result<()> {
// create mint account
let cpi_context = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
MintTo {
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.associated_token_account.to_account_info(),
authority: ctx.accounts.signer.to_account_info(),
},
);
mint_to(cpi_context, 1)?;
// create metadata account
let cpi_context = CpiContext::new(
ctx.accounts.token_metadata_program.to_account_info(),
CreateMetadataAccountsV3 {
metadata: ctx.accounts.metadata_account.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
mint_authority: ctx.accounts.signer.to_account_info(),
update_authority: ctx.accounts.signer.to_account_info(),
payer: ctx.accounts.signer.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
rent: ctx.accounts.rent.to_account_info(),
},
);
// On-chain token metadata for the mint
let data_v2 = DataV2 {
name: name,
symbol: symbol,
uri: uri,
seller_fee_basis_points: 0,
creators: None,
collection: None,
uses: None,
};
create_metadata_accounts_v3(
cpi_context, // cpi context
data_v2, // token metadata
false, // is_mutable
true, // update_authority_is_signer
None, // collection details
)?;
//create master edition account
let cpi_context = CpiContext::new(
ctx.accounts.token_metadata_program.to_account_info(),
CreateMasterEditionV3 {
edition: ctx.accounts.master_edition_account.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
update_authority: ctx.accounts.signer.to_account_info(),
mint_authority: ctx.accounts.signer.to_account_info(),
payer: ctx.accounts.signer.to_account_info(),
metadata: ctx.accounts.metadata_account.to_account_info(),
token_program: ctx.accounts.token_program.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
rent: ctx.accounts.rent.to_account_info(),
},
);
create_master_edition_v3(cpi_context, None)?;
Ok(())
}
}
#[derive(Accounts)]
pub struct InitNFT<'info> {
/// CHECK: ok, we are passing in this account ourselves
#[account(mut, signer)]
pub signer: AccountInfo<'info>,
#[account(
init,
payer = signer,
mint::decimals = 0,
mint::authority = signer.key(),
mint::freeze_authority = signer.key(),
)]
pub mint: Account<'info, Mint>,
#[account(
init_if_needed,
payer = signer,
associated_token::mint = mint,
associated_token::authority = signer
)]
pub associated_token_account: Account<'info, TokenAccount>,
/// CHECK - address
#[account(
mut,
address=find_metadata_account(&mint.key()).0,
)]
pub metadata_account: AccountInfo<'info>,
/// CHECK: address
#[account(
mut,
address=find_master_edition_account(&mint.key()).0,
)]
pub master_edition_account: AccountInfo<'info>,
pub token_program: Program<'info, Token>,
pub associated_token_program: Program<'info, AssociatedToken>,
pub token_metadata_program: Program<'info, Metadata>,
pub system_program: Program<'info, System>,
pub rent: Sysvar<'info, Rent>,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment