1
0
mirror of https://github.com/mortdeus/legacy-cc.git synced 2026-10-08 11:52:22 +00:00
Files
mortdeus_legacy-cc/2_copy trading bot(node) using gRPC/parsingtransaction.js
cryptoking1106 086ec82844 init
2025-09-18 18:12:50 -03:00

267 lines
11 KiB
JavaScript

import bs58 from "bs58";
// New function to handle parsed transaction data from getDataFromTx
export async function parseTransactionFromData(parsedTx) {
if (!parsedTx) return null;
const meta = parsedTx.meta;
// const logs = meta?.logMessages;
// const logFilter = logs?.some((instruction) => instruction.match(/MintTo/i));
const innerInstructions = meta.innerInstructions;
const flattenedInnerInstructions = (await innerInstructions?.flatMap((ix) => ix.instructions || [])) || [];
const allInstructions = [...flattenedInnerInstructions];
// console.log(allInstructions)
if (allInstructions.length === 0) return null;
// Filter out instructions that don't have data property
const validInstructions = allInstructions.filter((instruction) => instruction && instruction.data);
if (validInstructions.length === 0) return null;
const largestDataInstruction = await validInstructions.reduce((largest, current) => {
if (!current || !current.data || !largest || !largest.data) {
return largest || current;
}
return current.data.length > largest.data.length ? current : largest;
});
// console.log(largestDataInstruction)
if (!largestDataInstruction || !largestDataInstruction.data) {
return null;
}
// console.log(largestDataInstruction.data)
const rawData = bs58.decode(largestDataInstruction.data);
const buffer = Buffer.from(rawData);
// console.log(buffer)
const parsedInstructionData = parseTransactionData(buffer);
// console.log(parsedInstructionData)
if (!parsedInstructionData) return null;
return {
solChanges: parseFloat(parsedInstructionData.solchange),
tokenChanges: parseFloat(parsedInstructionData.tokenchange),
isBuy: parsedInstructionData.isBuy,
user: parsedInstructionData.user,
mint: parsedInstructionData.mint,
pool: parsedInstructionData.pool,
liquidity: parsedInstructionData.liquidity,
coinCreator: parsedInstructionData.coinCreator,
context: parsedInstructionData.context,
};
}
export async function tOutPut(data) {
// Check if this is parsed transaction data from getDataFromTx
if (data && data.meta && data.transaction) {
// This is parsed transaction data from getDataFromTx
return await parseTransactionFromData(data);
}
// Original format handling
const dataTx = data?.transaction?.transaction;
if (!dataTx) return;
const signature = bs58.encode(Buffer.from(dataTx?.transaction.signatures?.[0]));
// console.log("signature:::", signature);
const meta = dataTx?.meta;
const logs = meta?.logMessages;
const logFilter = logs?.some((instruction) => instruction.match(instruction.match(/MintTo/i)));
const innerInstructions = meta.innerInstructions;
// console.log(innerInstructions)
const flattenedInnerInstructions = (await innerInstructions?.flatMap((ix) => ix.instructions || [])) || [];
// console.log(flattenedInnerInstructions)
const allInstructions = [...flattenedInnerInstructions];
// console.log("allInstructions",allInstructions)
if (allInstructions.length === 0) return;
// Filter out instructions that don't have data property
const validInstructions = allInstructions.filter((instruction) => instruction && instruction.data);
if (validInstructions.length === 0) return null;
const largestDataInstruction = await validInstructions.reduce((largest, current) => {
if (!current || !current.data || !largest || !largest.data) {
return largest || current;
}
return current.data.length > largest.data.length ? current : largest;
});
if (!largestDataInstruction || !largestDataInstruction.data) {
return null;
}
// console.log("🎈🎈🎈largestDataInstruction:::", largestDataInstruction.data);
const parsedInstructionData = parseTransactionData(largestDataInstruction.data);
// console.log("🎈",JSON.stringify(parsedInstructionData,null,2))
if (!parsedInstructionData) return null;
// console.log(parsedInstructionData);
// console.log("Mint>>>>>>>>", parsedInstructionData.mint);
return {
solChanges: parseFloat(parsedInstructionData.solchange),
tokenChanges: parseFloat(parsedInstructionData.tokenchange),
isBuy: parsedInstructionData.isBuy,
user: parsedInstructionData.user,
mint: parsedInstructionData.mint,
pool: parsedInstructionData.pool,
liquidity: parsedInstructionData.liquidity / 10 ** 9,
coinCreator: parsedInstructionData.coinCreator,
pool_status: parsedInstructionData.pool_status,
signature: signature,
context: parsedInstructionData.context,
};
// console.log("Signature>>>>>>>>", signature);
}
export function parseTransactionData(buffer) {
try {
function parsePublicKey(offset) {
return bs58.encode(buffer.slice(offset, offset + 32)); // Convert 32 bytes to Base58
}
function parseBigInt(offset) {
return buffer.readBigUInt64LE(offset).toString(); // Read 8 bytes as Little-Endian
}
if (buffer.length == 368) {
const parsedData_PumpSwap = {
mint: null,
timestamp: parseBigInt(16), // 8 bytes (Timestamp)
baseAmountIn: parseBigInt(24), // 8 bytes (Base amount in)
minQuoteAmountOut: parseBigInt(32), // 8 bytes (Minimum quote amount out)
userBaseTokenReserves: parseBigInt(40), // 8 bytes (User base token reserves)
userQuoteTokenReserves: parseBigInt(48), // 8 bytes (User quote token reserves)
poolBaseTokenReserves: parseBigInt(56), // 8 bytes (Pool base token reserves)
poolQuoteTokenReserves: parseBigInt(64), // 8 bytes (Pool quote token reserves)
quoteAmountOut: parseBigInt(72), // 8 bytes (Quote amount out)
lpFeeBasisPoints: parseBigInt(80), // 8 bytes (LP fee basis points)
lpFee: parseBigInt(88), // 8 bytes (LP fee)
protocolFeeBasisPoints: parseBigInt(96), // 8 bytes (Protocol fee basis points)
protocolFee: parseBigInt(104), // 8 bytes (Protocol fee)
quoteAmountOutWithoutLpFee: parseBigInt(112), // 8 bytes (Quote amount out without LP fee)
userQuoteAmountOut: parseBigInt(120), // 8 bytes (User quote amount out)
pool: parsePublicKey(128), // 32 bytes (Pool address)
user: parsePublicKey(160), // 32 bytes (User address)
userBaseTokenAccount: parsePublicKey(192), // 32 bytes (User base token account)
userQuoteTokenAccount: parsePublicKey(224), // 32 bytes (User quote token account)
protocolFeeRecipient: parsePublicKey(256), // 32 bytes (Protocol fee recipient)
protocolFeeRecipientTokenAccount: parsePublicKey(288), // 32 bytes (Protocol fee recipient token account)
coinCreator: parsePublicKey(320), // 32 bytes (Coin creator address)
coinCreatorFeeBasisPoints: parseBigInt(328), // 8 bytes (Coin creator fee basis points)
coinCreatorFee: parseBigInt(336), // 8 bytes (Coin creator fee)
};
// console.log(parsedData_PumpSwap);
let isBuy = parsedData_PumpSwap.quoteAmountOutWithoutLpFee > parsedData_PumpSwap.quoteAmountOut;
return {
solchange: parsedData_PumpSwap.userQuoteAmountOut,
tokenchange: parsedData_PumpSwap.baseAmountIn,
isBuy,
user: parsedData_PumpSwap.user,
mint: parsedData_PumpSwap.mint,
pool: parsedData_PumpSwap.pool,
liquidity: parsedData_PumpSwap.poolQuoteTokenReserves * 2,
coinCreator: parsedData_PumpSwap.coinCreator,
pool_status: "pumpswap",
context: parsedData_PumpSwap,
};
} else if (buffer.length == 233) {
const parsedData_PumpFun = {
mint: parsePublicKey(16), // 32 bytes (Mint address)
solAmount: parseBigInt(48), // 8 bytes (Amount in SOL)
tokenAmount: parseBigInt(56), // 8 bytes (Token amount)
isBuy: buffer[64] === 1, // 1 byte (Boolean: 0 = Sell, 1 = Buy)
user: parsePublicKey(65), // 32 bytes (User address)
timestamp: parseBigInt(97), // 8 bytes (Timestamp - Unix format)
virtualSolReserves: parseBigInt(105), // 8 bytes (Virtual reserves)
virtualTokenReserves: parseBigInt(113), // 8 bytes (Virtual token reserves)
realSolReserves: parseBigInt(121), // 8 bytes (Real reserves)
realTokenReserves: parseBigInt(129), // 8 bytes (Real token reserves)
feeRecipient: parsePublicKey(137), // 32 bytes (Fee recipient address)
feeBasisPoints: parseBigInt(169), // 8 bytes (Fee basis points)
fee: parseBigInt(177), // 8 bytes (Fee amount)
creator: parsePublicKey(185), // 32 bytes (Creator address)
creatorFeeBasisPoints: parseBigInt(217), // 8 bytes (Creator fee basis points)
creatorFee: parseBigInt(225), // 8 bytes (Creator fee amount)
};
// console.log(parsedData_PumpFun);
let isBuy = parsedData_PumpFun.isBuy;
return {
solchange: parsedData_PumpFun.solAmount,
tokenchange: parsedData_PumpFun.tokenAmount,
isBuy,
user: parsedData_PumpFun.user,
mint: parsedData_PumpFun.mint,
pool: null,
liquidity: parsedData_PumpFun.virtualSolReserves,
coinCreator: parsedData_PumpFun.creator,
pool_status: "pumpfun",
context: parsedData_PumpFun,
};
} else if (buffer.length == 146) {
const parsedData_Raydium_LaunchLab = {
poolState: parsePublicKey(16), // 32 bytes (Pool state address)
totalBaseSell: parseBigInt(48), // 8 bytes (Total base sold)
virtualBase: parseBigInt(56), // 8 bytes (Virtual base reserves)
virtualQuote: parseBigInt(64), // 8 bytes (Virtual quote reserves)
realBaseBefore: parseBigInt(72), // 8 bytes (Real base before)
realQuoteBefore: parseBigInt(80), // 8 bytes (Real quote before)
realBaseAfter: parseBigInt(88), // 8 bytes (Real base after)
realQuoteAfter: parseBigInt(96), // 8 bytes (Real quote after)
amountIn: parseBigInt(104), // 8 bytes (Amount in)
amountOut: parseBigInt(112), // 8 bytes (Amount out)
protocolFee: parseBigInt(120), // 8 bytes (Protocol fee)
platformFee: parseBigInt(128), // 8 bytes (Platform fee)
shareFee: parseBigInt(136), // 8 bytes (Share fee)
tradeDirection: buffer[144] , // 1 byte (1 = sell, 0 = buy)
poolStatus: buffer[145] === 0 ? { normal: {} } : { fund: {} }, // 1 byte (0 = normal, 1 = fund)
};
const isBuy = !parsedData_Raydium_LaunchLab.tradeDirection;
let solAmount = 0;
let tokenAmount = 0;
// console.log("🎈🎈🎈parsedData_Raydium_LaunchLab:::", parsedData_Raydium_LaunchLab);
if (isBuy){
solAmount = parsedData_Raydium_LaunchLab.amountIn;
tokenAmount = parsedData_Raydium_LaunchLab.amountOut;
}else{
solAmount = parsedData_Raydium_LaunchLab.amountOut;
tokenAmount = parsedData_Raydium_LaunchLab.amountIn;
}
return {
solchange: solAmount,
tokenchange: tokenAmount,
isBuy,
user: null,
mint: null,
pool: parsedData_Raydium_LaunchLab.poolState,
liquidity: 2*parsedData_Raydium_LaunchLab.realQuoteAfter,
coinCreator: parsedData_Raydium_LaunchLab.poolState,
pool_status: "raydium_launchlab",
context: parsedData_Raydium_LaunchLab,
};
} else {
return {
solchange: 0,
tokenchange: 0,
isBuy: false,
user: null,
mint: null,
pool: null,
liquidity: 0,
coinCreator: null,
pool_status: "raydium",
context: null,
};
} }catch (error) {
console.error("Error parsing transaction data:", error);
}
}