5

I want to transfer tokens from one account to another using Solana-py library. Here's what I have now:

sender_address = '7FdZ8Rv5QZ8zLzGhDpyGYB95uXEK5BaxpKKCjqmBZJnL'
sender_secret_key = '...'
recipient_address = ''8wzfzwsMzgFePkTgq1JQePq41eMWC4uoBNT7e45B8C8v'

solana = SolanaClient("https://api.devnet.solana.com")
token = Token(
        solana, PublicKey('4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU'),
        TOKEN_PROGRAM_ID, Keypair.from_secret_key(sender_secret_key)
    )
token_account = token.get_accounts(sender_address)['result']['value'][0]['pubkey']

token.transfer_checked(
        PublicKey(token_account),
        PublicKey(recipient_address),
        Keypair.from_secret_key(sender_secret_key),
        20000,
        6
    )

But when I run this code, I'm getting an error:

solana.rpc.core.RPCException:
{
    "code": -32002,
    "message": "Transaction simulation failed: Error processing Instruction 0: invalid account data for instruction",
    "data": {
        "accounts": null,
        "err": {
            "InstructionError": [
                0,
                "InvalidAccountData"
            ]
        },
        "logs": [
            "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]",
            "Program log: Instruction: TransferChecked",
            "Program log: Error: InvalidAccountData",
            "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3066 of 200000 compute units",
            "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA failed: invalid account data for instruction"
        ],
        "unitsConsumed": 0
    }
}
1
  • Did you solve the issue already? Did the answer help?
    – mikemaccana
    Feb 20, 2023 at 10:54

2 Answers 2

5

Make sure you're sending the token to an associated token account, not to a wallet address.

As the OP mentioned in a comment.

Ensure the recipient associated token account actually exists - if it doesn't exist, add an instruction to make it.

You will need to make the recipient associated token account before you send tokens to it.

I also received the error:

Transaction simulation failed: Error processing Instruction 2: invalid account data for instruction

Or the longer version

 'Program log: Instruction: Transfer',
    'Program log: Error: InvalidAccountData',
    'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2881 of 200000 compute units',
    'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA failed: invalid account data for instruction'

This was because of a small bug I had in the code that checked for the existence of the receiving associated token account.

I found the error by logging the recipient associated token account and then looking it up in explorer - note Account does not exist below:

enter image description here

To check if an account exists:

export const checkIfTokenAccountExists = async (
  connection,
  receiverTokenAccountAddress
) => {
  // Check if the receiver's token account exists
  try {
    await getAccount(
      connection,
      receiverTokenAccountAddress,
      "confirmed",
      TOKEN_PROGRAM_ID
    );

    return true;
  } catch (thrownObject) {
    const error = thrownObject as Error;
    // error.message is am empty string
    // TODO: fix upstream
    if (error.name === "TokenAccountNotFoundError") {
      return false;
    }

    throw error;
  }
};

To add an instruction to make an account if it doesn't already exist

const isTokenAccountAlreadyMade = await checkIfTokenAccountExists(
  connection,
  destinationTokenAccount
);

if (isTokenAccountAlreadyMade) {
  log(
    `Token account already exists at ${destinationTokenAccount}, no need to make it`
  );
} else {
  log(
    `Token account does not exist at ${destinationTokenAccount}, adding instruction to make it`
  );
  // If the account does not exist, add the create account instruction to the transaction
  // Logic from node_modules/@solana/spl-token/src/actions/getOrCreateAssociatedTokenAccount.ts
  transaction.add(
    createAssociatedTokenAccountInstruction(
      ownerAndPayer.publicKey,
      destinationTokenAccount,
      recipientWalletAddress,
      mintAddress,
      TOKEN_PROGRAM_ID,
      ASSOCIATED_TOKEN_PROGRAM_ID
    )
  );
}
3

It seems one of the accounts passed in is not owned by the Token Program. Are you sure both token_account and recipient_address are token accounts(they are owned by Token Program)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.