mirror of
https://github.com/mortdeus/legacy-cc.git
synced 2026-10-07 11:21:05 +00:00
194 lines
7.9 KiB
JavaScript
194 lines
7.9 KiB
JavaScript
import { newlunched_subscribeCommand, stopNewLaunch } from "./grpc.js";
|
|
import { token_buy, token_sell, getSplTokenBalance, getPublicKeyFromPrivateKey } from "./fuc.js";
|
|
import chalk from "chalk";
|
|
import dotenv from "dotenv";
|
|
|
|
dotenv.config();
|
|
|
|
// Trading configuration
|
|
const SNIPER_AMOUNT = parseFloat(process.env.SNIPERAMOUNT || "0.1"); // SOL amount to snipe with
|
|
const PROFIT_TARGET = parseFloat(process.env.PROFIT_TARGET || "2.0"); // 2x profit target
|
|
const STOP_LOSS = parseFloat(process.env.STOP_LOSS || "0.5"); // 50% stop loss
|
|
const MAX_HOLD_TIME = parseInt(process.env.MAX_HOLD_TIME || "300000"); // 5 minutes in ms
|
|
|
|
// Track active positions
|
|
const activePositions = new Map();
|
|
|
|
export const pump_geyser = async () => {
|
|
try {
|
|
const walletKey = getPublicKeyFromPrivateKey();
|
|
// INSERT_YOUR_CODE
|
|
console.log(chalk.magentaBright(`
|
|
██████╗██████╗ ██╗ ██╗██████╗ ████████╗ ██████╗ ██╗ ██╗██╗███╗ ██╗ ██████╗
|
|
██╔════╝██╔══██╗██║ ██║██╔══██╗╚══██╔══╝██╔═══██╗██║ ██╔╝██║████╗ ██║██╔════╝
|
|
██║ ██████╔╝ ██║ ██╔╝██████╔╝ ██║ ██║ ██║█████╔╝ ██║██╔██╗ ██║██║ ██╗
|
|
██║ ██╔══██╗ ██╔═╝ ██╔═══╝ ██║ ██║ ██║██╔═██╗ ██║██║╚██╗██║██║ ██║
|
|
╚██████╗██║ ██║ ██║ ██║ ██║ ╚██████╔╝██║ ██╗██║██║ ╚████║╚██████╔╝
|
|
╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
|
`));
|
|
console.log(chalk.blue.bold("🚀 Starting Solana Raydium Sniper Bot..."));
|
|
console.log(chalk.blue(`🔑 Wallet Public Key: ${chalk.yellow(walletKey)}`));
|
|
console.log(chalk.blue(`💰 Sniper Amount: ${chalk.green(SNIPER_AMOUNT)} SOL`));
|
|
console.log(chalk.blue(`🎯 Profit Target: ${chalk.green(PROFIT_TARGET)}x`));
|
|
console.log(chalk.blue(`🛑 Stop Loss: ${chalk.green(STOP_LOSS)}x`));
|
|
console.log(chalk.blue(`⏱️ Max Hold Time: ${chalk.green(MAX_HOLD_TIME/1000)}s`));
|
|
|
|
// Start monitoring for new token launches
|
|
await newlunched_subscribeCommand();
|
|
|
|
// Set up position monitoring
|
|
setInterval(monitorPositions, 5000); // Check positions every 5 seconds
|
|
|
|
// Set up graceful shutdown
|
|
process.on('SIGINT', async () => {
|
|
console.log(chalk.yellow("\n🛑 Shutting down sniper bot..."));
|
|
stopNewLaunch();
|
|
|
|
// Close all positions before exit
|
|
for (const [mint, position] of activePositions) {
|
|
try {
|
|
console.log(chalk.yellow(`🔄 Closing position for ${mint}...`));
|
|
await closePosition(mint, position);
|
|
} catch (error) {
|
|
console.error(chalk.red(`Error closing position for ${mint}:`, error.message));
|
|
}
|
|
}
|
|
|
|
process.exit(0);
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error(chalk.red("Error in pump_geyser:", error));
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// Monitor active positions for profit taking or stop loss
|
|
async function monitorPositions() {
|
|
for (const [mint, position] of activePositions) {
|
|
try {
|
|
const currentBalance = await getSplTokenBalance(mint);
|
|
if (!currentBalance || currentBalance <= 0) {
|
|
console.log(chalk.yellow(`⚠️ No balance for ${mint}, removing from active positions`));
|
|
activePositions.delete(mint);
|
|
continue;
|
|
}
|
|
|
|
const currentValue = currentBalance * position.currentPrice;
|
|
const profitRatio = currentValue / position.entryValue;
|
|
const holdTime = Date.now() - position.entryTime;
|
|
|
|
// Check profit target
|
|
if (profitRatio >= PROFIT_TARGET) {
|
|
console.log(chalk.green(`🎯 Profit target reached for ${mint}: ${profitRatio.toFixed(2)}x`));
|
|
await closePosition(mint, position);
|
|
continue;
|
|
}
|
|
|
|
// Check stop loss
|
|
if (profitRatio <= STOP_LOSS) {
|
|
console.log(chalk.red(`🛑 Stop loss triggered for ${mint}: ${profitRatio.toFixed(2)}x`));
|
|
await closePosition(mint, position);
|
|
continue;
|
|
}
|
|
|
|
// Check max hold time
|
|
if (holdTime >= MAX_HOLD_TIME) {
|
|
console.log(chalk.yellow(`⏰ Max hold time reached for ${mint}, closing position`));
|
|
await closePosition(mint, position);
|
|
continue;
|
|
}
|
|
|
|
// Update current price (you might want to implement price fetching here)
|
|
// For now, we'll use a simple approach
|
|
position.currentPrice = position.entryPrice; // Placeholder
|
|
|
|
} catch (error) {
|
|
console.error(chalk.red(`Error monitoring position for ${mint}:`, error.message));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Close a position by selling tokens
|
|
async function closePosition(mint, position) {
|
|
try {
|
|
const currentBalance = await getSplTokenBalance(mint);
|
|
if (!currentBalance || currentBalance <= 0) {
|
|
console.log(chalk.yellow(`No balance to sell for ${mint}`));
|
|
activePositions.delete(mint);
|
|
return;
|
|
}
|
|
|
|
console.log(chalk.blue(`🔄 Closing position for ${mint}, selling ${currentBalance} tokens`));
|
|
|
|
const txid = await token_sell(mint, currentBalance, position.poolStatus, true, position.context);
|
|
|
|
if (txid && txid !== "stop") {
|
|
console.log(chalk.green(`✅ Position closed for ${mint}: ${txid}`));
|
|
|
|
// Calculate final PnL
|
|
const finalValue = currentBalance * position.currentPrice;
|
|
const pnl = finalValue - position.entryValue;
|
|
const pnlRatio = (pnl / position.entryValue) * 100;
|
|
|
|
console.log(chalk.cyan(`📊 Final PnL for ${mint}: ${pnl.toFixed(4)} SOL (${pnlRatio.toFixed(2)}%)`));
|
|
} else {
|
|
console.log(chalk.red(`❌ Failed to close position for ${mint}`));
|
|
}
|
|
|
|
activePositions.delete(mint);
|
|
|
|
} catch (error) {
|
|
console.error(chalk.red(`Error closing position for ${mint}:`, error.message));
|
|
}
|
|
}
|
|
|
|
// Function to handle new token launches (called from grpc.js)
|
|
export const handleNewTokenLaunch = async (tokenMint, poolStatus, context) => {
|
|
try {
|
|
console.log(chalk.green(`🎯 New token launch detected: ${tokenMint}`));
|
|
console.log(chalk.blue(`🏊 Pool type: ${poolStatus}`));
|
|
|
|
// Check if we already have a position in this token
|
|
if (activePositions.has(tokenMint)) {
|
|
console.log(chalk.yellow(`⚠️ Already have position in ${tokenMint}, skipping`));
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
// Execute snipe
|
|
console.log(chalk.blue(`🚀 Sniping ${tokenMint} with ${SNIPER_AMOUNT} SOL...`));
|
|
|
|
const txid = await token_buy(tokenMint, SNIPER_AMOUNT, poolStatus, context);
|
|
|
|
if (txid) {
|
|
console.log(chalk.green(`✅ Snipe successful! TX: ${txid}`));
|
|
|
|
// Add to active positions
|
|
activePositions.set(tokenMint, {
|
|
entryTime: Date.now(),
|
|
entryValue: SNIPER_AMOUNT,
|
|
entryPrice: 1, // Placeholder - you might want to calculate actual price
|
|
currentPrice: 1,
|
|
poolStatus: poolStatus,
|
|
context: context,
|
|
txid: txid
|
|
});
|
|
|
|
console.log(chalk.cyan(`📊 Position opened for ${tokenMint}`));
|
|
console.log(chalk.cyan(`💰 Entry Value: ${SNIPER_AMOUNT} SOL`));
|
|
console.log(chalk.cyan(`🎯 Profit Target: ${PROFIT_TARGET}x`));
|
|
console.log(chalk.cyan(`🛑 Stop Loss: ${STOP_LOSS}x`));
|
|
|
|
} else {
|
|
console.log(chalk.red(`❌ Snipe failed for ${tokenMint}`));
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error(chalk.red(`Error handling new token launch for ${tokenMint}:`, error.message));
|
|
}
|
|
};
|
|
|
|
// // Export for external use
|
|
// export { activePositions, handleNewTokenLaunch };
|