I’ll be honest — my first sniper bot was terrible. It missed every launch by at least 10 blocks, and when it did buy, the slippage ate me alive.
But after rewriting it three times, I got something that actually works. It detects new Raydium liquidity pools, checks basic safety signals, and executes a buy — all within a few seconds of pool creation.
I’m not going to pretend this will make you rich. Most new tokens are garbage. But the technical challenge is real, and understanding how this works will teach you more about Solana than any tutorial.
1. The Core Idea
New tokens on Solana usually launch by adding liquidity to Raydium. When a new pool is created, a specific instruction is sent to Raydium’s AMM program.
If you can detect that instruction fast enough, you can buy before most people even see the token.
The flow is:
- Listen for new transactions on Raydium’s program
- Detect
initializeinstructions (new pool creation) - Extract the token mint and pool addresses
- Run basic checks
- Execute a swap
2. Listen for Raydium Pool Creation
import { Connection, PublicKey } from "@solana/web3.js";
const connection = new Connection("https://api.mainnet-beta.solana.com", {
wsEndpoint: "wss://api.mainnet-beta.solana.com",
commitment: "confirmed",
});
const RAYDIUM_AMM = new PublicKey(
"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"
);
connection.onLogs(RAYDIUM_AMM, (logInfo) => {
if (logInfo.err) return;
const isNewPool = logInfo.logs.some(
(log) => log.includes("initialize2") || log.includes("Initialize")
);
if (isNewPool) {
console.log("New pool detected:", logInfo.signature);
handleNewPool(logInfo.signature);
}
}, "confirmed");
This watches every transaction on Raydium’s AMM program. When a new pool is initialized, you get the transaction signature instantly.
3. Extract Pool Info from the Transaction
Once you have the signature, fetch the full transaction and pull out what you need:
async function handleNewPool(signature: string) {
const tx = await connection.getParsedTransaction(signature, {
maxSupportedTransactionVersion: 0,
commitment: "confirmed",
});
if (!tx || !tx.meta) return;
// Find the token mints from post token balances
const mints = new Set<string>();
for (const balance of tx.meta.postTokenBalances || []) {
if (balance.mint !== "So11111111111111111111111111111111111111112") {
mints.add(balance.mint);
}
}
if (mints.size === 0) return;
const tokenMint = [...mints][0];
console.log("New token:", tokenMint);
// Now decide if you want to buy
await evaluateAndBuy(tokenMint);
}
I filter out the SOL mint because every Raydium pool pairs against SOL. The other mint is the new token.
4. Basic Safety Checks
Buying blindly is how you lose money. At minimum, check these things:
import { getMint } from "@solana/spl-token";
async function evaluateAndBuy(mintAddress: string) {
const mint = new PublicKey(mintAddress);
// Check mint authority — if it's not revoked, they can mint more tokens
const mintInfo = await getMint(connection, mint);
if (mintInfo.mintAuthority !== null) {
console.log("SKIP: Mint authority not revoked");
return;
}
// Check freeze authority — if set, they can freeze your tokens
if (mintInfo.freezeAuthority !== null) {
console.log("SKIP: Freeze authority active");
return;
}
// Check supply
const supply = Number(mintInfo.supply) / 10 ** mintInfo.decimals;
console.log("Supply:", supply);
// If checks pass, execute the buy
await executeBuy(mintAddress);
}
These aren’t foolproof. Scammers have gotten creative. But filtering out tokens with active mint/freeze authority eliminates a lot of obvious rugs.
5. Execute the Swap
For the actual swap, I use Jupiter’s API. You could build the Raydium swap instruction manually, but Jupiter handles routing and slippage better.
async function executeBuy(tokenMint: string) {
const SOL_MINT = "So11111111111111111111111111111111111111112";
const AMOUNT_LAMPORTS = 100_000_000; // 0.1 SOL
const SLIPPAGE_BPS = 1500; // 15% — high, but new pools are volatile
// Get quote from Jupiter
const quoteUrl =
`https://quote-api.jup.ag/v6/quote?` +
`inputMint=${SOL_MINT}&outputMint=${tokenMint}` +
`&amount=${AMOUNT_LAMPORTS}&slippageBps=${SLIPPAGE_BPS}`;
const quoteRes = await fetch(quoteUrl);
const quote = await quoteRes.json();
if (!quote || quote.error) {
console.log("No route found yet — pool might not be indexed");
return;
}
// Get swap transaction
const swapRes = await fetch("https://quote-api.jup.ag/v6/swap", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
quoteResponse: quote,
userPublicKey: YOUR_WALLET.publicKey.toBase58(),
wrapAndUnwrapSol: true,
}),
});
const { swapTransaction } = await swapRes.json();
// Sign and send
const txBuf = Buffer.from(swapTransaction, "base64");
const tx = VersionedTransaction.deserialize(txBuf);
tx.sign([YOUR_WALLET]);
const sig = await connection.sendRawTransaction(tx.serialize(), {
skipPreflight: true,
maxRetries: 3,
});
console.log("Buy executed:", sig);
}
A few things to note:
- 15% slippage sounds insane. But new pools have almost no liquidity, so price impact is massive. Adjust based on your risk tolerance.
skipPreflight: truesaves time. The transaction either lands or it doesn’t.- Jupiter might not have the route indexed immediately after pool creation. That’s the main bottleneck.
6. Speed Matters — A Lot
The difference between buying at block N and block N+5 can be 10x in price. Here’s what I do to stay fast:
- Use a paid RPC like Helius or Triton. Free RPCs are too slow for this.
- Pre-sign transactions where possible. Have your wallet loaded and ready.
- Skip
getParsedTransactionif you can parse the raw transaction yourself — it’s faster. - Run your bot geographically close to Solana validators. US East or Amsterdam.
7. What This Won’t Do
I’m not going to oversell this. Here’s what you’re up against:
- MEV bots will front-run you. They have direct validator access.
- Most new tokens are scams. Even with checks, you’ll buy garbage.
- Jupiter routing delay means you might miss the first few blocks.
- This is for learning. Treat any money you put in as already gone.
If you want to compete with the real snipers, you’d need Jito bundles, private mempools, and a lot more infrastructure. That’s a different post.
What I Actually Use This For
I don’t run this to blindly snipe anymore. I use it as a detection system. It alerts me when new pools are created, shows me the basic stats, and I decide manually whether to buy.
The bot does the fast part — detecting and analyzing. I do the slow part — deciding if it’s worth it. That combo works way better than full automation.
Build the bot, learn how Solana works under the hood, but don’t bet your rent money on it.