1

I have this simple solana/anchor app written in Rust

use anchor_lang::prelude::*;

declare_id!("4ahwNyytPQ9cUguDLz9fcjbzEBMM4jsaVfYxTUV4Sf7r");

#[program]
mod myanchorapp {
    use super::*;

    pub fn create(ctx: Context<Create>, name: String, description: String) -> Result<()> { //Result<()>
        let campaign = &mut ctx.accounts.campaign;
        
        campaign.name = name;
        campaign.description = description;
        campaign.amount_donated = 0;
        campaign.admin = *ctx.accounts.user.key;

        Ok(())
    }
}

// Transaction instructions
#[derive(Accounts)]
pub struct Create<'info> {
    #[account(init, payer=user, space=9000, seeds=[b"CAMPAIGN_DEMO".as_ref(), user.key().as_ref()], bump)]
    pub campaign: Account<'info, Campaign>,

    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>
}

// An account that goes inside a transaction instruction
#[account]
pub struct Campaign {
    pub admin: Pubkey,
    pub name: String,
    pub description: String,
    pub amount_donated: u64
}

Here is my test file

const assert = require("assert");
const anchor = require("@coral-xyz/anchor");
const { SystemProgram } = anchor.web3;

describe("myanchorapp", () => {
  /* create and set a Provider */
  const provider = anchor.AnchorProvider.env();
  anchor.setProvider(provider);
  const program = anchor.workspace.Myanchorapp;

  let _campaign;

  it("Create campaign", async () => {
    /* Call the create function via RPC */
    const campaign = anchor.web3.Keypair.generate();

    const testName = "Campaign1";
    const testDescription = "A new campaign.";

    await program.rpc.create(
      testName,
      testDescription,
      {
      accounts: {
        campaign: campaign.publicKey,
        user: provider.wallet.publicKey,
        systemProgram: SystemProgram.programId,
      },
      signers: [campaign],
    });

    /* Fetch the account and check the value of count */
    const account = await program.account.campaign.fetch(campaign.publicKey);
    console.log('Campaign name: ', account.name)
    assert.ok(account.name == testName);
    _campaign = campaign;

  });
});

No matter what I try I receive the following error:

  myanchorapp
    1) Creates a counter


  0 passing (61ms)
  1 failing

  1) myanchorapp
       Creates a counter:
     Error: unknown signer: GbgASb46CEkk83VS22UWhYcMawAQ15EVbhnWySmAGcVM

I'm not able to find anything to help me fix this issue online.

Would anyone be able to point me in the right direction of a solution?

3 Answers 3

2

campaign is a program-derived address, so it's not allowed to be a random keypair. So when your program defines the instruction, it doesn't declare campaign to be a signer, but then you're adding a signature from campaign.

Since the library sees an unexpected signature, it returns Error: unknown signer.

To fix the issue, be sure to derive campaign correctly:

const campaign = PublicKey.findProgramAddressSync(
  [Buffer.from("CAMPAIGN_DEMO", "utf-8"), Buffer.from(provider.wallet.publicKey)],
  programId
);

Since that gives a PublicKey, you can just pass it directly:

await program.rpc.create(
      testName,
      testDescription,
      {
      accounts: {
        campaign: campaign,
        user: provider.wallet.publicKey,
        systemProgram: SystemProgram.programId,
      },
    });

I think the Anchor client gives easier ways to do this, but at least this way you see how it works under the hood!

0

One solution i could suggest would be to remove campaign from the signers array. So it would be something like this:

await program.rpc.create( testName, testDescription, { accounts: { campaign: campaign.publicKey, user: provider.wallet.publicKey, systemProgram: SystemProgram.programId, }, signers: [], } );

Try this and let's see if it would work

1
  • Unfortunately that gives a new Error Error: AnchorError caused by account: campaign. Error Code: ConstraintSeeds. Error Number: 2006. Error Message: A seeds constraint was violated. Commented Apr 15 at 19:57
0

that's rather unfortunate from my research i found out that:

  1. based on the "ConstraintSeeds" error, there might be a mismatch between the seeds used to derive the PDA for your campaign account and how you're constructing the accounts object in the create function call.
  2. another thing is your accounts object includes the campaign.publicKey, it doesn't explicitly specify the seeds used to derive that public key. Anchor might be looking for seeds within the accounts object to verify the PDA.

Based on recommendations i found you could either; Pass Seeds as Separate Arguments or if that doesn't work you could Update Accounts Object

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.