1

I attempt to create a new account with the anchor #[account(init)] macro, then assign ownership of the new account to the token program, and then attempt to send the initialize_mint instruction to the token program via a CPI call.

But I seem to always get the following error:

     Error: AnchorError caused by account: mint. Error Code: AccountOwnedByWrongProgram. Error Number: 3007. Error Message: The given account is owned by a different program than expected.
Program log: Left:
Program log: CgduZwGapBDVX3bJLRG8RR3HUYf2rQ8xjvtiBWE9bbbN
Program log: Right:
Program log: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA

My code:

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

    pub fn create(ctx: Context<Create>) -> Result<()> {
        // assign ownership of the mint account to the token program
        ctx.accounts.mint.to_account_info().assign(&token::ID);

        // Create a new token mint
        let cpi_accounts = InitializeMint {
            mint: ctx.accounts.mint.to_account_info(),
            rent: ctx.accounts.rent.to_account_info(),
        };

        let decimals = 9;
        let cpi_program = ctx.accounts.token_program.clone().to_account_info();
        let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
        token::initialize_mint(cpi_ctx, decimals, &ctx.accounts.mint_authority.key(), None)?;

        Ok(())
    }
}

#[derive(Accounts)]
pub struct Create<'info> {
    #[account(init, payer = user, space = Mint::LEN)]
    pub mint: Account<'info, Mint>,
    #[account(mut)]
    pub user: Signer<'info>,
    #[account(seeds = [b"mint-authority"], bump)]
    /// CHECK: The mint authority is the program derived address.
    pub mint_authority: UncheckedAccount<'info>,
    pub rent: Sysvar<'info, Rent>,
    pub system_program: Program<'info, System>,
    pub token_program: Program<'info, Token>,
}

This error goes away if I change the Create struct to use an UncheckedAccount:

#[derive(Accounts)]
pub struct Create<'info> {
    #[account(init, payer = user, space = Mint::LEN)]
    /// CHECK: foobar
    pub mint: UncheckedAccount<'info>, // by changing this to be UncheckedAccount
    // ... snip ...
}

What is going on here? Why does it work when I change from Account<'info, Mint> to UncheckedAccount<'info>? Is it safe to do this? Is there a better way of fixing this error?

1 Answer 1

2

Here's an example on Solana Playground you can reference.

You don't need the cpis in the instruction logic. When creating a mint account, Anchor handles those for you through the constraints.

use anchor_lang::prelude::*;
use anchor_spl::token::{Mint, Token};

declare_id!("3bA9ovdNzycPGkdF8Pt31gxkV4BNzgZ2iKhWTpF5FcME");

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

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        msg!("Created Mint Account: {}", ctx.accounts.mint.key());
        Ok(())
    }

    pub fn account_validation(ctx: Context<AccountValidation>) -> Result<()> {
        // Checked that `signer` is the both mint and freeze authority of `mint
        msg!("Mint : {}", ctx.accounts.mint.key());
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub signer: Signer<'info>,
    #[account(
        init,
        payer = signer,
        mint::decimals = 9,
        mint::authority = signer,
        mint::freeze_authority = signer
    )]
    pub mint: Account<'info, Mint>,
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct AccountValidation<'info> {
    pub signer: Signer<'info>,
    #[account(
        mint::authority = signer,
        mint::freeze_authority = signer
    )]
    pub mint: Account<'info, Mint>,
}
3
  • In this example, the example program would be the owner of the Mint account. Shouldn't the owner of the Mint account be the Token program (because it needs to be able to do edit data such as incrementing the supply when new mints occur in the Mint account)? Commented Jan 5 at 17:37
  • 1
    When using init with the Mint type, Anchor will handle creating the Mint Account owned by the token program. This is also the case for token accounts.
    – john
    Commented Jan 5 at 18:20
  • Are there any other special cases like this? How does anchor know to point the mint account owner to the token program instead of the example program? Commented Jan 5 at 19:50

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.