I am trying to create a simple swap contract.
The part of the swap function is like this:
// Transfer tokens from user to pool
let cpi_accounts_in = token::Transfer {
from: ctx.accounts.user_token_in.to_account_info(),
to: ctx.accounts.pool_token_in.to_account_info(),
authority: ctx.accounts.user.to_account_info(), // User must authorize this transfer
};
let cpi_ctx_in = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
cpi_accounts_in,
);
token::transfer(cpi_ctx_in, amount_in)?;
// Transfer tokens from pool to user
let cpi_accounts_out = token::Transfer {
from: ctx.accounts.pool_token_out.to_account_info(),
to: ctx.accounts.user_token_out.to_account_info(),
authority: ctx.accounts.pool.to_account_info(), // Pool must be the authority for this transfer
};
let cpi_ctx_out = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
cpi_accounts_out,
);
token::transfer(cpi_ctx_out, output_amount)?;
As you can see, there are 2 different authorities.
However, in the TS test code I have somehting like this:
const tx = await program.methods
.swap(new anchor.BN(swapAmountIn), new anchor.BN(minAmountOut))
.accounts({
pool: pool.publicKey,
userTokenIn: userTokenAccountA,
userTokenOut: userTokenAccountB,
poolTokenIn: poolTokenAccountA,
poolTokenOut: poolTokenAccountB,
user: payer.publicKey,
tokenProgram: TOKEN_PROGRAM_ID,
})
.signers([payer])
.rpc();
Since in this code, I am providing only 1 signer, I am getting this error during anchor test
:
Simulation failed.
Message: Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account.
Logs:
[
"Program E7nE9N9yiLHhMZDdD9U7duT8SKuiUVLhkE7WJkSwSpkt invoke [1]",
"Program log: Instruction: Swap",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: Transfer",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 188115 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"7hGVDEXUfomYMppU7ibSzEvTwgFMg9SWBfrGaWJSY5dL's signer privilege escalated",
"Program E7nE9N9yiLHhMZDdD9U7duT8SKuiUVLhkE7WJkSwSpkt consumed 18859 of 200000 compute units",
"Program E7nE9N9yiLHhMZDdD9U7duT8SKuiUVLhkE7WJkSwSpkt failed: Cross-program invocation with unauthorized signer or writable account"
].
Is there any way I can provide both the signers (user and pool) in the test code? Or maybe there is a better and neat solution that I am missing? Thanks!