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!