2

I'm doing the Anchor Staking part of the solana Buildspace course. I get this error when running the first test:

ReferenceError: METADATA_PROGRAM_ID is not defined

This is the Anchor Smartcontract I deployed:

use anchor_lang::prelude::*;
use anchor_lang::solana_program::program::invoke_signed;
use anchor_spl::token;
use anchor_spl::{
    associated_token::AssociatedToken,
    token::{Approve, Mint, MintTo, Revoke, Token, TokenAccount},
};
use mpl_token_metadata::{
    instruction::{freeze_delegated_account, thaw_delegated_account},
    ID as MetadataTokenId,
};

declare_id!("HyHEFjePsfdvToLSAfGXpE8CYS2V7GD4f75jGhPt4btx");

#[program]
pub mod anchor_nft_staking {
    use super::*;

    pub fn stake(ctx: Context<Stake>) -> Result<()> {
        Ok(())
    }


}


#[account]
pub struct UserStakeInfo {
    pub token_account: Pubkey,
    pub stake_start_time: i64,
    pub last_stake_redeem: i64,
    pub user_pubkey: Pubkey,
    pub stake_state: StakeState,
    pub is_initialized: bool,
}

#[derive(Debug, PartialEq, AnchorDeserialize, AnchorSerialize, Clone)]
pub enum StakeState {
    Unstaked,
    Staked,
}

impl Default for StakeState {
    fn default() -> Self {
        StakeState::Unstaked
    }
}

#[derive(Clone)]
pub struct Metadata;

impl anchor_lang::Id for Metadata {
    fn id() -> Pubkey {
        MetadataTokenId
    }
}

#[derive(Accounts)]
pub struct Stake<'info> {
    #[account(mut)]
    pub user: Signer<'info>,
    #[account(
        mut,
        associated_token::mint=nft_mint,
        associated_token::authority=user
    )]
    pub nft_token_account: Account<'info, TokenAccount>,
    pub nft_mint: Account<'info, Mint>,
    /// CHECK: Manual validation
    #[account(owner=MetadataTokenId)]
    pub nft_edition: UncheckedAccount<'info>,
    #[account(
        init_if_needed,
        payer=user,
        space = std::mem::size_of::<UserStakeInfo>() + 8,
        seeds = [user.key().as_ref(), nft_token_account.key().as_ref()],
        bump
    )]
    pub stake_state: Account<'info, UserStakeInfo>,
    /// CHECK: Manual validation
    #[account(mut, seeds=["authority".as_bytes().as_ref()], bump)]
    pub program_authority: UncheckedAccount<'info>,
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
    pub metadata_program: Program<'info, Metadata>,
}

This is the utils/setupnft.ts file:

import {
    bundlrStorage,
    keypairIdentity,
    Metaplex,
} from "@metaplex-foundation/js"
import { createMint, getAssociatedTokenAddress } from "@solana/spl-token"
import * as anchor from "@project-serum/anchor"

export const setupNft = async (program, payer) => {
    const metaplex = Metaplex.make(program.provider.connection)
        .use(keypairIdentity(payer))
        .use(bundlrStorage())

    const nft = await metaplex
        .nfts()
        .create({
            uri: "",
            name: "Test nft",
            sellerFeeBasisPoints: 0,
        })

    console.log("nft metadata pubkey: ", nft.metadataAddress.toBase58())
    console.log("nft token address: ", nft.tokenAddress.toBase58())
    const [delegatedAuthPda] = await anchor.web3.PublicKey.findProgramAddress(
        [Buffer.from("authority")],
        program.programId
    )
    const [stakeStatePda] = await anchor.web3.PublicKey.findProgramAddress(
        [payer.publicKey.toBuffer(), nft.tokenAddress.toBuffer()],
        program.programId
    )

    console.log("delegated authority pda: ", delegatedAuthPda.toBase58())
    console.log("stake state pda: ", stakeStatePda.toBase58())
    const [mintAuth] = await anchor.web3.PublicKey.findProgramAddress(
        [Buffer.from("mint")],
        program.programId
    )

    const mint = await createMint(
        program.provider.connection,
        payer,
        mintAuth,
        null,
        2
    )
    console.log("Mint pubkey: ", mint.toBase58())

    const tokenAddress = await getAssociatedTokenAddress(mint, payer.publicKey)

    return {
        nft: nft,
        delegatedAuthPda: delegatedAuthPda,
        stakeStatePda: stakeStatePda,
        mint: mint,
        mintAuth: mintAuth,
        tokenAddress: tokenAddress,
    }
}

And this is the testfile:

import { PublicKey } from "@metaplex-foundation/js";
import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { AnchorNftStaking } from "../target/types/anchor_nft_staking";
import { setupNft } from "./utils/setupNft";


describe("anchor-nft-staking", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env());


  const wallet = anchor.workspace.AnchorNftStaking.provider.wallet
  const program = anchor.workspace.AnchorNftStaking as Program<AnchorNftStaking>;



  let delegatedAuthPda: anchor.web3.PublicKey
  let stakeStatePda: anchor.web3.PublicKey
  let nft: any
  let mintAuth: anchor.web3.PublicKey
  let mint: anchor.web3.PublicKey
  let tokenAddress: anchor.web3.PublicKey

  before(async () => {
    ; ({ nft, delegatedAuthPda, stakeStatePda, mint, mintAuth, tokenAddress } =
      await setupNft(program, wallet.payer))
  })

  it("Stakes", async () => {
    // Add your test here.
    await program.methods
      .stake()
      .accounts({
        nftTokenAccount: nft.tokenAddress,
        nftMint: nft.mintAddress,
        nftEdition: nft.masterEditionAddress,
        metadataProgram: METADATA_PROGRAM_ID,
      })
      .rpc()

  })
});


I copied it all from the course, but can't find how to define the METADATA_PROGRAM_ID.

Did I forget to copy something? Or did I do something wrong? Is this the general metaplex metadata program id? It doesn't work when I define it as a string ("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" ) Or has it something to do with my smartcontract?

Thanks in advance!

1 Answer 1

3

You can install @metaplex-foundation/mpl-token-metadata from here and import it like

import { PROGRAM_ID as METADATA_PROGRAM_ID } from "@metaplex-foundation/mpl-token-metadata"

Else you can declare it yourself

const METADATA_PROGRAM_ID = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s");

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.