1
0
mirror of https://github.com/mortdeus/legacy-cc.git synced 2026-09-30 15:55:35 +00:00
Files
mortdeus_legacy-cc/2_copy trading bot(node) using gRPC/grpc.js
cryptoking1106 086ec82844 init
2025-09-18 18:12:50 -03:00

204 lines
6.3 KiB
JavaScript

import "dotenv/config";
import Client from "@triton-one/yellowstone-grpc";
import { CommitmentLevel } from "@triton-one/yellowstone-grpc";
import { decodeInstruction } from '@solana/spl-token';
import { Connection, Keypair } from '@solana/web3.js';
import chalk from "chalk";
import { tOutPut } from "./parsingtransaction.js";
import { handleNewTokenLaunch } from "./main.js";
import dotenv from 'dotenv'
dotenv.config();
const GRPCTOKEN=process.env.GRPCTOKEN
const GRPC_ENDPOINT = process.env.GRPC_ENDPOINT
// Pre-define constants
const SOLANA_TOKEN = "So11111111111111111111111111111111111111112";
const RAYDIUM_FEE = "LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj"//"7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5";
const Raydium_launchpad_authority = "WLHv2UAZm6z4KyaaELi5pjdbJh6RESMva1Rnn8pJVVh"
// Create default client
const defaultClient = new Client(
GRPC_ENDPOINT,
GRPCTOKEN
);
export let isNewLaunchRunning = true;
export const stopNewLaunch = () => {
isNewLaunchRunning = false;
console.log(chalk.red("New launch monitoring stopped"));
};
// Default request args
const defaultArgs = {
accounts: {},
slots: {},
transactions: {
pumpfun: {
vote: false,
failed: false,
signature: undefined,
accountInclude: [RAYDIUM_FEE],
accountExclude: [],
accountRequired: [],
},
},
transactionsStatus: {},
entry: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
ping: undefined,
commitment: CommitmentLevel.PROCESSED,
};
// This function checks for MintTo instructions by comparing with log messages
async function checkMintTo(data) {
const tx = data.transaction?.transaction;
const meta = data.transaction;
if (!tx || !meta?.transaction?.meta?.logMessages) return;
// Find if MintTo is present in log messages
const mintToLog = meta.transaction.meta.logMessages.find((log) =>
typeof log === "string" && log.toLowerCase().includes("instruction: mintto")
);
if (mintToLog) {
console.log("🩸🩸🩸🩸🩸 MintTo found in logs!");
return true
} else {
// No MintTo found in logs
return false
}
}
async function handleStream(client = defaultClient, args = defaultArgs) {
const stream = await client.subscribe(args);
const streamClosed = new Promise((resolve, reject) => {
stream.on("error", (error) => {
console.error("Stream Error:", error);
reject(error);
stream.end();
});
stream.on("end", resolve);
stream.on("close", resolve);
});
stream.on("data", async (data) => {
// Return early if monitoring is disabled
if (!isNewLaunchRunning) {
stream.end();
return;
}
try {
// console.log(chalk.green("start__________new token streaming_________"));
if (!data?.transaction?.transaction) {
return null;
}
const mintTo = await checkMintTo(data)
if(!mintTo){
return null
}
console.log(`[${new Date().toISOString()}] 🩸🩸🩸🩸🩸 MintTo found in logs!`);
const preTokenBalances = data?.transaction?.transaction?.meta?.preTokenBalances;
const postTokenBalances = data?.transaction?.transaction?.meta?.postTokenBalances;
if (!preTokenBalances || !postTokenBalances) {
console.log("Token balances not found in transaction data");
return null;
}
let pre_sol = 0;
let post_sol = 0;
let pre_token = 0;
let post_token = 0;
let token_mint = "";
let token_owner = "";
for (const balance of postTokenBalances) {
if (balance.owner !== Raydium_launchpad_authority) {
if (balance.mint !== SOLANA_TOKEN) {
post_token = balance.uiTokenAmount.uiAmount || 0;
token_mint = balance.mint;
token_owner = balance.owner;
}
} else {
post_sol = balance.uiTokenAmount.uiAmount || 0;
}
}
for (const balance of preTokenBalances) {
if (balance.owner !== Raydium_launchpad_authority) {
if (balance.mint !== SOLANA_TOKEN) {
pre_token = balance.uiTokenAmount.uiAmount || 0;
}
}
}
const solChanges = post_sol-pre_sol;
const tokenChanges = post_token-pre_token;
console.log(chalk.bgBlue.bold(`🪙 Token Mint:`), chalk.white(token_mint));
console.log(chalk.bgMagenta.bold(`👤 Token Owner:`), chalk.white(token_owner));
console.log(chalk.bgYellow.bold(`💸 SOL Balance Change:`), chalk.yellow(`${solChanges > 0 ? "+" : ""}${solChanges}`));
console.log(chalk.bgCyan.bold(`🔄 Token Balance Change:`), chalk.cyan(`${tokenChanges > 0 ? "+" : ""}${tokenChanges}`));
if (solChanges> 0.1) {
console.log(chalk.bgGreen("Found large SOL transfer:", solChanges));
// Parse transaction data to get pool information
const parsedData = await tOutPut(data);
if (parsedData) {
console.log(chalk.cyan(`Pool status: Raydium launchpad`));
// Call the main bot logic to handle the new token launch
await handleNewTokenLaunch(token_mint, parsedData.pool_status, parsedData.context);
} else {
console.log(chalk.yellow("Failed to parse transaction data"));
}
return token_mint;
}
return null;
} catch (error) {
console.error("Error processing transaction data:", error);
return null;
}
});
try {
await stream.write(args);
} catch (error) {
console.error("Subscription request failed:", error);
throw error;
}
await streamClosed;
}
export async function newlunched_subscribeCommand(client = defaultClient, args = defaultArgs) {
// Set monitoring flag to true when starting
isNewLaunchRunning = true;
console.log(chalk.green("New launch monitoring started"));
while (isNewLaunchRunning) {
try {
await handleStream(client, args);
} catch (error) {
console.error("Stream error, restarting in 1 second...", error);
// Only wait and retry if monitoring is still enabled
if (isNewLaunchRunning) {
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
}
console.log("New launch monitoring stopped");
}
// Export client and args for external use
export { defaultClient, defaultArgs };
// Remove the auto-execution to prevent conflicts
// newlunched_subscribeCommand()