I'm attempting to transfer SPL tokens using Solana's Web3.js, but I'm encountering a SendTransactionError related to invalid account data during the transaction simulation. I need help understanding and resolving this issue.
const web3 = require('@solana/web3.js');
const splToken = require('@solana/spl-token');
const base58 = require('bs58');
const RPC_URL = "https://api.mainnet-beta.solana.com";
const connection = new web3.Connection(RPC_URL, "confirmed");
const privateKeyFile = 'prvt.txt';
const destinationAddress = ''; //adress
async function getTokenAccountInfo(publicKey) {
try {
const tokenAccounts = await connection.getParsedTokenAccountsByOwner(publicKey, { programId: splToken.TOKEN_PROGRAM_ID });
let tokensInfo = [];
for (const { account } of tokenAccounts.value) {
const { mint, tokenAmount } = account.data.parsed.info;
if (tokenAmount.uiAmount > 0) {
tokensInfo.push({
mint: mint,
amount: tokenAmount.uiAmount,
decimals: tokenAmount.decimals
});
}
}
return tokensInfo;
} catch (error) {
console.error('Error fetching token accounts:', error);
return [];
}
}
async function transferTokens(senderKeypair, mintAddress, destinationPublicKey, amount, decimals) {
const senderTokenAccount = await splToken.getAssociatedTokenAddress(
mintAddress,
senderKeypair.publicKey
);
const destinationTokenAccount = await splToken.getAssociatedTokenAddress(
mintAddress,
destinationPublicKey
);
const roundedAmount = Math.floor(amount * Math.pow(10, decimals));
const transaction = new web3.Transaction().add(
splToken.createTransferInstruction(
senderTokenAccount,
destinationTokenAccount,
senderKeypair.publicKey,
roundedAmount,
[],
splToken.TOKEN_PROGRAM_ID
)
);
await web3.sendAndConfirmTransaction(connection, transaction, [senderKeypair]);
}
async function main() {
const privateKeys = fs.readFileSync(privateKeyFile, 'utf-8').split('\n').filter(line => line.trim().length > 0);
const destinationPublicKey = new web3.PublicKey(destinationAddress);
for (const privateKeyBase58 of privateKeys) {
const privateKeyBytes = base58.decode(privateKeyBase58.trim());
const senderKeypair = web3.Keypair.fromSecretKey(privateKeyBytes);
const tokensInfo = await getTokenAccountInfo(senderKeypair.publicKey);
for (const { mint, amount, decimals } of tokensInfo) {
const mintPublicKey = new web3.PublicKey(mint);
await transferTokens(senderKeypair, mintPublicKey, destinationPublicKey, amount, decimals);
await new Promise(resolve => setTimeout(resolve, 1000)); // delay
}
}
}
main();