0

I am doing something similar to this issue..

here are the two ix:

let tx = new anchor.web3.Transaction();
 tx.add(
            anchor.web3.SystemProgram.createAccount({
                fromPubkey: provider.wallet.publicKey,
                newAccountPubkey: rafflePDA,
                programId: programId,
                lamports: await provider.connection.getMinimumBalanceForRentExemption(raffleAccountSpace),
                space: raffleAccountSpace,
            }),
        );

        tx.add(
            await program.methods
                .initializeRaffle(args.slug, args.maxEntries.toNumber())
                .accounts({
                    creator: provider.wallet.publicKey,
                    raffle: rafflePDA,
                })
                .instruction()
        );

        let sig = await provider.sendAndConfirm(tx);

This. Below explaination I got from Anchor discord.. But I am not sure how to use it

if rafflePDA is PDA then the system account can't able to create this account. only your programID can able to create it. as PDA stand for Program Derived Address. so each PDA should have to create by the same program itself. remove the createAccount from tx.

So what should I add to signer in

let sig = await provider.sendAndConfirm(tx);

After removing the createAccount..?

UPDATE-----******------

This is my Code

const [wallet, connection] = getWalletConnection(program);

  const lamports = await connection.getMinimumBalanceForRentExemption(
    MINT_SIZE
  );

  const mintKey = anchor.web3.Keypair.generate();

  const associatedTokenAddress = await getAssociatedTokenAddress(
    mintKey.publicKey,
    wallet.publicKey
  );
  console.log("NFT Account: ", associatedTokenAddress.toBase58());

  const mint_tx = new anchor.web3.Transaction().add(
    anchor.web3.SystemProgram.createAccount({
      fromPubkey: wallet.publicKey,
      newAccountPubkey: mintKey.publicKey,
      space: MINT_SIZE,
      programId: TOKEN_PROGRAM_ID,
      lamports,
    }),
    createInitializeMintInstruction(
      mintKey.publicKey,
      0,
      wallet.publicKey,
      wallet.publicKey
    ),
    createAssociatedTokenAccountInstruction(
      wallet.publicKey,
      associatedTokenAddress,
      wallet.publicKey,
      mintKey.publicKey
    )
  );
  let blockhashObj = await connection.getLatestBlockhash();
  console.log("blockhashObj", blockhashObj);
  mint_tx.recentBlockhash = blockhashObj.blockhash;

  try {
    const signature = await wallet.sendTransaction(mint_tx, connection, {
      signers: [mintKey],
    });
    await connection.confirmTransaction(signature, "confirmed");
  } catch {
    return null;
  }

  console.log("Mint key: ", mintKey.publicKey.toString());
  console.log("User: ", wallet.publicKey.toString());

  const metadataAddress = await getMetadata(mintKey.publicKey);
  console.log("Metadata address: ", metadataAddress.toBase58());

  try {
    const tx = program.transaction.mintNft(
      mintKey.publicKey,
      name,
      symbol,
      metadataUrl,
      {
        accounts: {
          mintAuthority: wallet.publicKey,
          mint: mintKey.publicKey,
          tokenAccount: associatedTokenAddress,
          tokenProgram: TOKEN_PROGRAM_ID,
          metadata: metadataAddress,
          tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
          payer: wallet.publicKey,
          systemProgram: anchor.web3.SystemProgram.programId,
          rent: anchor.web3.SYSVAR_RENT_PUBKEY,
        },
      }
    );

    const signature = await wallet.sendTransaction(tx, connection);
    await connection.confirmTransaction(signature, "confirmed");
    console.log("Mint Success!");

2 Answers 2

0

You should do something like the code described below.

The signerKeypair is the keypair of the user for whom you want to create the PDA account. The signer will be creating his/her account with approval from your Program.

It is advised to store the bump and the seed value in your solana program so that the user doesn't have to pass those as arguments to initialize his/her account.

Read more here.

I have assumed that your struct is something like pub struct RaffleState

    // Find account address and bump for the signer's PDA account

    const [rafflePDA, raffleBump] = await anchor.web3.PublicKey.findProgramAddress(
        [Buffer.from(*some_seed*), signerKeypair.publicKey.toBuffer()],
        programId
    );


    it("Initializes PDA.", async () => {
        await program.methods
            .initializeRaffle(args.slug, args.maxEntries.toNumber())
            .accounts({
                // This should contain all the args of the InitializeRaffle struct
                creator : signerKeypair.publicKey,
                raffle: rafflePDA,
                systemProgram: anchor.web3.SystemProgram.programId,
            })
            .signers([signerKeypair])
            .rpc();

       const account = await program.account.raffleState.fetch(linkAccount);
       // Perform your assertions for testing here.

    });

2
  • I am trying to have nfts(mint) as pda then fetch accounts with MintSize 82 to get all the nfts minted by my program.. I am passing in MINT_SIZE as an argument in createAccount in my code... I am confused if I omit that will I be able to fetch pdas of MINT_SIZE...??
    – Lobo1897
    Commented Aug 12, 2022 at 8:39
  • I have provided my code in the question.. Please take a look
    – Lobo1897
    Commented Aug 12, 2022 at 8:46
0

It seems like you need PDA but you created an Associated Token Account instead.

A PDA is derived like:

PublicKey.findProgramAddressSync(
    [Buffer.from("some-seed", "utf-8")],
    programId
  );

and your program will probably init the PDA itself, so there is no need for the createAccount instruction.

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.