I have a multisig address with 3 other signers. Not sure if this was created with cli or serum project (the developer that created it is working anymore).
When trying to transfer a token, I get this error:
'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]',
'Program log: Instruction: Transfer',
'Program log: Error: InvalidAccountData',
'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1810 of 200000 compute units',
'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA failed: invalid account data for instruction'
Code:
const signer1Account = Keypair.fromSecretKey(key1);
const signer2Account = Keypair.fromSecretKey(key2);
const signer3Account = Keypair.fromSecretKey(key3);
const tokenAmount = 10000
const tokenMintPubkey = new PublicKey(' ');
const fromMultisigAddress = new PublicKey(' ');
const fromMultisigOwnerAddress = new PublicKey('');
const toAddress = new PublicKey('');
const amountToTransfer = tokenAmount * Math.pow(10, 6);
(async () => {
let toAddressTokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
signer1Account,
tokenMintPubkey,
toAddress,
true
);
console.log(`toAddressTokenAccount: ${toAddressTokenAccount.address}`);
let tx = new Transaction();
try {
tx.add(
createTransferInstruction(
fromMultisigAddress, // from
toAddressTokenAccount.address, // to
TOKEN_PROGRAM_ID, // from's owner
amountToTransfer, // amount
[signer1Account, signer2Account, signer3Account] //signers
)
);
} catch (error) {
console.error(error)
}
try {
const latestBlockHash = await connection.getLatestBlockhash('confirmed');
tx.recentBlockhash = await latestBlockHash.blockhash;
const signature = await sendAndConfirmTransaction(connection, tx, [signer1Account, signer2Account, signer3Account]);
} catch (error) {
console.error(error)
}
})();
I search and read all questions on it, found this but I am not sure how to solve it. Error: Invalid account data for instruction
Thanks for any help
Update - solved thanks to the help of Jon C.
Adding the working code maybe it will help someone else
import { clusterApiUrl, Keypair, Transaction, Connection, PublicKey, sendAndConfirmTransaction, ParsedAccountData } from "@solana/web3.js";
import { TOKEN_PROGRAM_ID, getOrCreateAssociatedTokenAccount, createTransferInstruction } from "@solana/spl-token";
// connection
const connection = new Connection(clusterApiUrl("mainnet-beta"), "confirmed");
// your array keys
const key1 = new Uint8Array([]);
const key2 = new Uint8Array([]);
const key3 = new Uint8Array([]);
const signer1Account = Keypair.fromSecretKey(key1);
const signer2Account = Keypair.fromSecretKey(key2);
const signer3Account = Keypair.fromSecretKey(key3);
const tokenAmount = 1
// your public keys
const tokenMintPubkey = new PublicKey('');
const fromMultisigAddress = new PublicKey('');
const fromMultisigOwnerAddress = new PublicKey('');
const toAddress = new PublicKey('');
const tokenAddressOnMultisigAddress = new PublicKey('');
async function getNumberDecimals(mintPubkey: PublicKey) : Promise<number> {
const info = await connection.getParsedAccountInfo(mintPubkey);
const result = (info.value?.data as ParsedAccountData).parsed.info.decimals as number;
return result;
}
(async () => {
let toAddressTokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
signer1Account,
tokenMintPubkey,
toAddress,
true
);
console.log(`toAddressTokenAccount: ${toAddressTokenAccount.address}`);
const decimals = await getNumberDecimals(tokenMintPubkey);
console.log(`Token decimals: ${decimals}`);
const amountToTransfer = tokenAmount * Math.pow(10, decimals);
let tx = new Transaction();
try {
tx.add(
createTransferInstruction(
tokenAddressOnMultisigAddress, // from (token account on the source address)
toAddressTokenAccount.address, // to
fromMultisigAddress, // from's owner (owner of the token account - the multisig address)
amountToTransfer, // amount
[signer1Account, signer2Account, signer3Account] //signers
)
);
} catch (error) {
console.error(error)
}
try {
const latestBlockHash = await connection.getLatestBlockhash('confirmed');
tx.recentBlockhash = await latestBlockHash.blockhash;
const signature = await sendAndConfirmTransaction(connection, tx, [signer1Account, signer2Account, signer3Account]);
} catch (error) {
console.error(error)
}
})();