i'm trying to track buys and sells from 1 token on the solana chain. But i don't get it properly done to receive every buy and every sell from this token, and get the correct amount of tokens that have been bought or sold. I receive in the console sometimes the correct amount . But also allot of times there was a buy or sell but the code didn't track it.
this is the code i have, i hope i can get some help.
const solanaweb3 = require('@solana/web3.js');
const searchAddress = 'The token contract address';
const endpoint = 'https://api.mainnet-beta.solana.com'; // https://api.devnet.solana.com or https://api.mainnet-beta.solana.com
const solanaConnection = new solanaweb3.Connection(endpoint);
const processedSignatures = new Set(); // Set to store processed signatures
const getTransactions = async (address, numTx) => {
const pubKey = new solanaweb3.PublicKey(address);
while (true) {
try {
let transactionList = await solanaConnection.getSignaturesForAddress(pubKey, { limit: numTx });
let signatureList = transactionList.map(transaction => transaction.signature);
let transactionDetails = await solanaConnection.getParsedTransactions(signatureList, { maxSupportedTransactionVersion: 0 });
for (let i = 0; i < transactionList.length; i++) {
const transaction = transactionList[i];
const signature = transaction.signature;
// Check if the signature has already been processed
if (processedSignatures.has(signature)) {
console.log(`Signature ${signature} has already been processed. Skipping.`);
continue; // Skip processing this transaction
}
// Mark the signature as processed
processedSignatures.add(signature);
const date = new Date(transaction.blockTime * 1000);
const Transactions = transactionDetails[i];
const transactionInstructions = Transactions.transaction.message.instructions;
//console.log('metadata:', Transactions.meta)
//console.log('Transactions:', Transactions.meta.preTokenBalances);
console.log(`Transaction No: ${i + 1}`);
console.log(`Signature: ${signature}`);
console.log(`Time: ${date}`);
console.log(`Status: ${transaction.confirmationStatus}`);
// Find the token balances before and after the transaction
const preBalance = Transactions.meta.preTokenBalances.find(balance => balance.mint === searchAddress);
const postBalance = Transactions.meta.postTokenBalances.find(balance => balance.mint === searchAddress);
if (preBalance && postBalance) {
// Calculate the difference in token balance
const Diff = postBalance.uiTokenAmount.uiAmount - preBalance.uiTokenAmount.uiAmount;
console.log(` tokens bought/sold: ${Math.abs(Diff)}`);
console.log(` tokens bought: ${Diff > 0 ? Diff : 0}`);
console.log(` tokens sold: ${Diff < 0 ? Math.abs(Diff) : 0}`);
} else {
console.log(' token balance not found in transaction metadata.');
}
// Check if the transaction is successful
const isSuccess = transaction.confirmationStatus === 'confirmed';
console.log(transaction.err)
// Check if the transaction has an instruction error
if (Transactions.meta && Transactions.meta.err) {
const instructionError = Transactions.meta.err;
console.log(`Transaction ${signature} encountered an instruction error:`, instructionError);
}
if (isSuccess) {
// Transaction is successful
console.log(`Transaction ${signature} is successful.`);
} else {
// Transaction is failed or not yet finalized
console.log(`Transaction ${signature} has not been confirmed or has failed.`);
}
// Search for the first occurrence of the mint address with non-zero amount
const foundInstruction = Transactions.meta.preTokenBalances.find(instruction => {
return instruction.mint === searchAddress && instruction.uiTokenAmount.uiAmountString !== '0';
});
if (foundInstruction) {
console.log('Found first instruction with non-zero amount for mint address:', searchAddress);
console.log('uiAmountString:', foundInstruction.uiTokenAmount.uiAmountString);
break; // Stop searching after finding the first occurrence
} else {
console.log(`No non-zero amount found for mint address: ${searchAddress}`);
}
console.log("-".repeat(20));
}
} catch (error) {
console.error('Error occurred:', error);
}
await new Promise(resolve => setTimeout(resolve, 15000)); // Wait for 15 seconds before fetching transactions again
}
};
getTransactions(searchAddress, 1);