I am getting some error while sending a transaction in Android (Kotlin)
Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account
This is the function which is creating the Instruction Object.
public fun createQuestion(author: PublicKey, question: String): TransactionInstruction {
val keys = mutableListOf<AccountMeta>()
keys.add(AccountMeta(getQuestionPda().address, false, true))
keys.add(AccountMeta(getProgramInfoPda().address, false, true))
keys.add(AccountMeta(author, true, true))
keys.add(AccountMeta(SystemProgram.PROGRAM_ID, false, false))
return TransactionInstruction(PublicKey(BuildConfig.PROGRAM_ID), keys,
Borsh.encodeToByteArray(AnchorInstructionSerializer("create_question"), Args_createQuestion("Android Question")))
}
PS: Typescript Tests are working, I had one more Instruction in Android which is also working.
This is the structure for this instruction:
{
"name": "createQuestion",
"accounts": [
{
"name": "question",
"isMut": true,
"isSigner": false
},
{
"name": "programInfo",
"isMut": true,
"isSigner": false
},
{
"name": "author",
"isMut": true,
"isSigner": true
},
{
"name": "systemProgram",
"isMut": false,
"isSigner": false
}
],
"args": [
{
"name": "content",
"type": "string"
}
]
}
This is the Anchor Instruction:
#[derive(Accounts)]
#[instruction(content: String)]
pub struct CreateQuestion<'info> {
#[account(
init_if_needed,
payer = author,
space = Question::LEN + content.len(),
seeds = [b"question", program_info.question_count.to_be_bytes().as_ref()],
bump
)]
pub question: Account<'info, Question>,
#[account(mut)]
program_info: Account<'info, ProgramInfo>,
#[account(mut)]
pub author: Signer<'info>,
pub system_program: Program<'info, System>,
}
I have already tried:
- Writing the anchor program again and redeploying.
- Ran typescript tests to check if they were working (and they are)
- Used a new keypair to sign transactions in typescript (still working)
Note: InitializeProgramInfo
instruction is working in Android. Only CreateQuestion
is not working.
This is the instruction for Create Question
pub fn create_question(ctx: Context<CreateQuestion>, content: String) -> Result<()> {
require!(content.chars().count() < 30, QuestionError::QuestionTooLong);
require!(content.chars().count() > 1, QuestionError::QuestionEmpty);
let clock: Clock = Clock::get().unwrap();
ctx.accounts.question.set_inner(
Question::new(
ctx.accounts.author.key(),
clock.unix_timestamp,
content,
ctx.accounts.program_info.question_count,
0,
*ctx.bumps.get("question").unwrap()
)
);
ctx.accounts.program_info.increment_question_count();
Ok(())
}
program_info
also exists and is mutable