Skip to main content
1 of 2

Cross-program invocation with unauthorized signer or writable account

Facing verification failed issue and found many similar issues on StackExchange but couldn't solve my problem so posting here.

I have deployed a Rust contract on devnet. It has an instruction which invokes spl_token transfer user's token account to the my contract's token account.

When I call the contract instruction from frontend, the signature verification fails after approve popup from wallet: {"code":-32003,"message":"failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account"}

Here is the Rust code:

let transfer_to_initializer_ix = spl_token::instruction::transfer(
        token_program.key,
        source_token_account.key,
        destination_token_account.key,
        initializer.key,
        &[],
        1,
    )?;
    msg!("Calling token program to transfer tokens");
    invoke(
        &transfer_to_initializer_ix,
        &[
            source_token_account.clone(),
            destination_token_account.clone(),
            initializer.clone(),
            token_program.clone(),
        ]
    )?;

This is how I send the call to instruction from my react app:

const instruction = new web3.TransactionInstruction({
            keys: [
                {
                    pubkey: publicKey,
                    isSigner: true,
                    isWritable: false,
                },
                {
                    pubkey: pda,
                    isSigner: false,
                    isWritable: true
                },
                {
                    isSigner: false,
                    isWritable: true,
                    pubkey: web3.SystemProgram.programId
                },
                {
                    is_signer: false,
                    is_writable: true,
                    pubkey: userAta,
                },
                {
                    is_signer: false,
                    is_writable: true,
                    pubkey: crowdpadATA,
                },
                {
                    is_signer: false,
                    is_writable: false,
                    pubkey: token.TOKEN_PROGRAM_ID,
                },
            ],
            data: buffer,
            programId: crowdpadStakingProgram
        })

        console.log('adding staking instruction')
        transaction.add(instruction)

        try {
            const txid = await sendTransaction(transaction, connection);

            alert(`Transaction submitted: https://explorer.solana.com/tx/${txid}?cluster=devnet`)
            console.log(`Transaction submitted: https://explorer.solana.com/tx/${txid}?cluster=devnet`)
        } catch (e) {
            console.log(JSON.stringify(e))
            alert(JSON.stringify(e))
        }
    }

I checked the documentation and also discussed the issue with peers. Unfortunately the issue persisted. All help is appreciated!