1

I have been working to update this code to solana 1.18.8, anchor 0.29.0, and mpl-token-metadata 4.1.2.

I have repaired most of the issues except 3.

I have tried importing create_metadata_account_v3 and create_master_edition_v3 like you could under anchor_spl::Metadata, but under mpl_token_metadata::instructions in numerous different ways and I am getting errors that it is private even though the .rs file has it pub.

Additionally, my #[derive(Accounts)] is being hijacked by mpl-token-metadata::Accounts rather than associating with use anchor_lang::prelude::*; as it should.

I am including my code, however, I am aware that there are weird use statements based on my multiple attempts to fix the private issue.

use anchor_lang::prelude::*;
use anchor_spl::{
    associated_token::AssociatedToken,
    token::{mint_to, Mint, MintTo, Token, TokenAccount},
};
use mpl_token_metadata::{
    instructions::{CreateMetadataAccountV3CpiAccounts, create_metadata_account_v3, CreateMasterEditionV3, create_master_edition_v3},
    types::DataV2,
    accounts::{MasterEdition, Metadata},
};
declare_id!("");
 
    #[program]
    pub mod solana_nft_anchor {

        use super::*;
    
        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 data_v2 = DataV2 {
            name,
            symbol,
            uri,
            seller_fee_basis_points: 0,
            creators: None,
            collection: None,
            uses: None,
        };
        let metadata_account_pubkey = *ctx.accounts.metadata_account.key;
        let mint_pubkey = *ctx.accounts.mint.to_account_info().key;
        let mint_authority_pubkey = *ctx.accounts.signer.key;
        let payer_pubkey = *ctx.accounts.signer.key;
        let update_authority_pubkey = *ctx.accounts.signer.key;
        let system_program_pubkey = *ctx.accounts.system_program.key;
        let rent_pubkey = Some(*ctx.accounts.rent.to_account_info().key);

        let cpi_accounts = CreateMetadataAccountV3CpiAccounts {
            metadata: &ctx.accounts.metadata_account.to_account_info(),
            mint: &ctx.accounts.mint.to_account_info(),
            mint_authority: &ctx.accounts.signer,
            payer: &ctx.accounts.signer,
            update_authority: (&ctx.accounts.signer, true),
            system_program: &ctx.accounts.system_program,
            rent: Some(&ctx.accounts.rent.to_account_info()),
        };

        let cpi_ctx = ctx.accounts.token_metadata_program.to_account_info();

        // Invoke CPI for creating metadata account
        create_metadata_account_v3(cpi_ctx, None)?;

        let edition_pubkey = *ctx.accounts.master_edition_account.key;
        let token_program_pubkey = *ctx.accounts.token_program.key;
        // Create master edition account
        let cpi_accounts = CreateMasterEditionV3 {
            edition: edition_pubkey,
            mint: mint_pubkey,
            update_authority: update_authority_pubkey,
            mint_authority: mint_authority_pubkey,
            payer: payer_pubkey,
            metadata: metadata_account_pubkey,
            token_program: token_program_pubkey,
            system_program: system_program_pubkey,
            rent: rent_pubkey,
        };

        let cpi_ctx = ctx.accounts.token_metadata_program.to_account_info().clone();

        // Invoke CPI for creating master edition account
        create_master_edition_v3(cpi_ctx, None)?;

        Ok(())
    }

    #[derive(Accounts)]
    pub struct InitNFT<'info> {
        #[account(mut, signer)]
        pub signer: AccountInfo<'info>,
        #[account(
            init,
            payer = signer,
            mint::decimals = 0,
            mint::authority = signer,
            mint::freeze_authority = signer
        )]
        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>,
        #[account(mut, address = Metadata::find_pda(&mint.key()).0)]
        pub metadata_account: AccountInfo<'info>,
        #[account(mut, address = MasterEdition::find_pda(&mint.key()).0)]
        pub master_edition_account: AccountInfo<'info>,
        pub update_authority: 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>,
    }
}

I am new to Solana so any help would be appreciated.

1 Answer 1

0

checkout https://www.anchor-lang.com/release-notes/0.29.0

Build error: could not find `metadata` in `anchor_spl` and could not find `pda` in `mpl_token_metadata`

https://github.com/metaplex-foundation/mpl-token-metadata/issues/80

I had to still keep mpl-token-metadata and not remove it completely

[dependencies]
anchor-spl = { version = "0.29.0", features = ["metadata"] }
mpl-token-metadata = { version = "3.2.3" }

using version 3.2.3 because that's what anchor 0.29.0 is using for mpl-token-metadata and it won't cause any version mismatches.

mpl-token-metadata doesn't have instructions anymore, but they can be used from anchor-spl::metadata

use anchor_spl::metadata::{
    create_metadata_accounts_v3,
    CreateMetadataAccountsV3,
};
use mpl_token_metadata::types::DataV2;

as for creating metadata this worked for me (I'm signing with PDA, that's why I use new_with_signer and seeds)

create_metadata_accounts_v3(
  ctx: CpiContext::new_with_signer(
    program: ctx.accounts.metadata_program.to_account_info().clone(), 
    accounts: CreateMetadataAccountsV3 {
      metadata: ctx.accounts.metadata_account.to_account_info().clone(),
      mint: ctx.accounts.token_mint.to_account_info().clone(),
      mint_authority: ctx.accounts.update_authority.to_account_info().clone(),
      payer: ctx.accounts.signer.to_account_info().clone(),
      update_authority: ctx.accounts.signer.to_account_info().clone(),
      system_program: ctx.accounts.system_program.to_account_info().clone(),
      rent: ctx.accounts.rent.clone(),
    },
    signer_seeds: &[&seeds[..]],
  ),
data: DataV2 {
    name: params.name,
    symbol: params.symbol,
    uri: params.uri,
    creators: None,
    seller_fee_basis_points: 0,
    collection: None,
    uses: None,
  }, 
  is_mutable: true, 
  update_authority_is_signer: false, 
  collection_details: None
)?;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.