Reputation: 901
I have a simple contract using Serum Anchor (on Solana) that transfers tokens from one party to another. It is currently failing with:
Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account
Full code from snippets below at: https://gist.github.com/h4rkl/700400f515ab0736fd6d9318d44b2dca
I'm setting up 4 accounts for the transaction:
let mint = null; // key for token mint
let god = null; // main program account to pay from and sign
let creatorAcc = anchor.web3.Keypair.generate(); // account to pay to
let creatorTokenAcc = null; // token account for payment
I'm setting them up as follows:
const [_mint, _god] = await serumCmn.createMintAndVault(
program.provider,
new anchor.BN(MINT_TOKENS),
undefined,
MINT_DECIMALS
);
mint = _mint;
god = _god;
creatorTokenAcc =await serumCmn.createTokenAccount(
program.provider,
mint,
creatorAcc.publicKey
);
And then I make the payment with the following method:
const INTERACTION_FEE = 200000000000000;
await program.rpc.interaction(new anchor.BN(INTERACTION_FEE), {
accounts: {
from: god,
to: creatorTokenAcc,
owner: program.provider.wallet.publicKey,
tokenProgram: TOKEN_PROGRAM_ID,
},
});
In the contract that the method is triggering my interaction process is as follows:
pub fn interaction(ctx: Context<Interaction>, interaction_fee: u64) -> ProgramResult {
let cpi_accounts = Transfer {
from: ctx.accounts.from.to_account_info().clone(),
to: ctx.accounts.to.to_account_info().clone(),
authority: ctx.accounts.owner.clone(),
};
let cpi_program = ctx.accounts.token_program.clone();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
token::transfer(cpi_ctx, interaction_fee)?;
Ok(())
}
I have setup the Interaction pub struct
with the following params:
#[derive(Accounts)]
pub struct Interaction<'info> {
#[account(mut, has_one = owner)]
from: CpiAccount<'info, TokenAccount>,
#[account("from.mint == to.mint")]
to: CpiAccount<'info, TokenAccount>,
#[account(signer)]
owner: AccountInfo<'info>,
token_program: AccountInfo<'info>,
}
As far as I can tell the params are correct, and the god
account owns the wallet as the payer and is the signer. Why is this failing, and what am I missing? I'm completely out of ideas.
Upvotes: 5
Views: 4077