How to transfer from 2 accounts to the same vault in Serum Anchor?

Viewed 423

I am writing a simple contract of transferring tokens from 2 accounts in a common check vault. I took the cashiers-check as base example and using this.

    // Create check
    #[access_control(CreateCheck::accounts(&ctx, nonce))]
    pub fn create_check(ctx: Context<CreateCheck>, amount: u64, nonce: u8) -> Result<()> {
        // Transfer funds to the check.
        let cpi_accounts = Transfer {
            from: ctx.accounts.from.to_account_info().clone(),
            to: ctx.accounts.vault.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, amount)?;
        // Print the check.
        let check = &mut ctx.accounts.check;
        check.amount = amount;
        check.from = *ctx.accounts.from.to_account_info().key;
        check.vault = *ctx.accounts.vault.to_account_info().key;
        check.nonce = nonce;
        Ok(())
    }

this is to collect from second account

    pub fn second_send(ctx: Context<SecondSend>) -> Result<()> {
        let seeds = &[
            ctx.accounts.check.to_account_info().key.as_ref(),
            &[ctx.accounts.check.nonce],
        ];
        let signer = &[&seeds[..]];
        let cpi_accounts = Transfer {
            from: ctx.accounts.from.to_account_info().clone(),
            to: ctx.accounts.vault.to_account_info().clone(),
            authority: ctx.accounts.check_signer.clone(),
        };
        let cpi_program = ctx.accounts.token_program.clone();
        let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer);
        token::transfer(cpi_ctx, ctx.accounts.check.amount)?;
        // Burn the check for one time use.
        ctx.accounts.check.burned = true;
        Ok(())
    }

struct:

#[derive(Accounts)]
pub struct SecondSend<'info> {
    #[account(mut, has_one = vault)]
    check: ProgramAccount<'info, Check>,
    #[account(mut)]
    vault: AccountInfo<'info>,

    check_signer: AccountInfo<'info>,

    #[account(mut, has_one = owner)]
    from: CpiAccount<'info, TokenAccount>,
    #[account(signer)]
    owner: AccountInfo<'info>,
    token_program: AccountInfo<'info>,
}

this is the test i wrote:

  it("Sends token from satan", async () => {
    await program.rpc.secondSend({
      accounts: {
        check: check.publicKey,
        vault: vault.publicKey,
        checkSigner: checkSigner,
        from: satan,
        owner: program.provider.wallet.publicKey,
        tokenProgram: TOKEN_PROGRAM_ID,
      },
    });
  });

whatever i do im getting this error : Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x3

im doing something wrong?

1 Answers

I think you missed out on looking at the Program Logs above the error you mentioned here. Try scrolling up, there should be certain logs.

That should provide more context, but if you're still stuck, you can update your question here :D

Related