2

I'm a Ethereum dev, started solana development recently finding it bit confuse due to my previous Eth concepts. I'm developing a NFT marketplace on solana and its a type of P2E model. In Ethereum you mint nfts and approve the smart contract so anyone can buy it. As Solana doesn't store data with code, it stores in accounts eg PDA. I want to be able to have same functionality in solana program eg: owner mints tokens to PDA so buyers can buy directly from marketplace. because PDA's are special accounts and program can sign for them.

PS: I wrote the code for first minting and then transferring nft to PDA in same transaction but it doesn't work. it gives this error: Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 1: Cross-program invocation with unauthorized signer or writable account.

If I remove the transferring nft code minting works fine. any help would be appreciated.

4
  • did you solve the issue? Let me know I am facing a similar situation. I need to store NFTs (probably in PDA) and keep a record of which users transfer which NFTs. Nov 29, 2022 at 5:01
  • Well, I did't found perfect solution for this, but what I did was to mint NFT in my wallet and send that to PDA in same transaction, so for me it doesn't matter because what I wanted was only one transaction that does my work. For your case you can have a escrow PDA that you transfer nft to and an other state pda that you record the data in so you can keep record of your nft.
    – Naveed Ali
    Nov 29, 2022 at 5:20
  • I am exactly trying to do what you are trying to do. First mint NFT in the wallet then I need a button to send it to PDA. Can you share code snippet or your repo link where I can see code on how you are actually transferring in PDA. Nov 29, 2022 at 7:31
  • There's a stackexchange for solana development. Probably, it will be better to ask there solana.stackexchange.com.
    – Ismael
    Dec 5, 2022 at 3:16

1 Answer 1

1

Ok so after the days of R&D and giving it my time and energy I got the solution for this. This works creating a associated token account for mint with anchor you can create ata in accounts validation struct like this(btw anchor really is lifesaver)

 #[account(mut)]
    mint_authority: Signer<'info>,
    #[account(
        init,
        payer = mint_authority,
        mint::decimals = 0,
        mint::authority = mint_authority,
        mint::freeze_authority = mint_authority,
    )]
    pub mint: Account<'info, Mint>,
    #[account(
        init,
        payer = mint_authority,
        space = 400,
        seeds = [b"nftDetails".as_ref(),
        mint.key().as_ref()],
        bump
    )]
    nft_details: Account<'info, NftDetails>,
    #[account(
        init,
        payer = mint_authority, // minter, the one who is minting
        associated_token::mint = mint, // mint of the token
        associated_token::authority = nft_details //authority that should be a PDA account
    )]
    token_account: Account<'info, TokenAccount>,

Call the mint_to instruction from spl_token_program like this,

        token::mint_to(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                MintTo{
                    mint:ctx.accounts.mint.to_account_info(),
                    to: ctx.accounts.token_account.to_account_info(),
                    authority: ctx.accounts.mint_authority.to_account_info(),
                },
            ),
            1
        )?;

The code above is onchain code, as we pass accounts from client side, you will need to find the authority PDA account (nft_details in this case) using the seeds and bump. And for token_account, you will need to get ata. This is how it looks offchain,

        const [nftDetails,  nftDetailsBump] = await
           anchor.web3.PublicKey.findProgramAddress(
             [Buffer.from(`nftDetails`), mintKey.publicKey.toBuffer()],
             new anchor.web3.PublicKey(program.programId
        ));

      const nftTokenAccount = await getAssociatedTokenAddress(
           mintKey.publicKey,
           nftDetails,
           true
      );

Phew, that is how we take our ship to shore.

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.