Crypto Bots

Pump.fun and Solana Meme Coin Bots: How to Automate the Hottest Trend

Pump.fun launched over 5 million tokens on Solana in 2025. Learn how automated bots detect new launches, snipe early, and take profit before the inevitable dump โ€” with real Python and TypeScript code.

A
AI Agents Hubยท2026-03-31ยท5 min readยท820 words

Builder of AI agents, crypto trading bots, and open-source automation tools. Sharing practical guides on how to build, deploy, and profit from AI and DeFi technology.

Why Pump.fun Changed Everything

Pump.fun made launching a Solana meme coin as easy as filling out a form. The result: tens of thousands of new tokens per day, a 24/7 casino atmosphere, and enormous opportunity for automated bots.

The model is simple: tokens launch via a bonding curve โ€” early buyers get cheap tokens, the price rises as more people buy, and when the token "graduates" (hits $69K market cap), it lists on Raydium with real liquidity.

The bot opportunity: Detect launches early, buy before price pumps, sell near the graduation threshold.

Understanding the Bonding Curve

Pump.fun uses a constant product AMM bonding curve:

Price = k / remaining_supply

The earlier you buy, the lower the price. A bot that buys within the first 10-30 seconds has a significant price advantage over bots that enter at minute 5.

Setting Up a Pump.fun Monitor Bot

import asyncio
import aiohttp
from solana.rpc.async_api import AsyncClient
from solders.pubkey import Pubkey
import base58
import struct

PUMP_PROGRAM = Pubkey.from_string("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")

async def monitor_pumpfun_launches():
    """Monitor Pump.fun for new token launches using WebSocket logs"""
    
    async with aiohttp.ClientSession() as session:
        ws_url = "wss://mainnet.helius-rpc.com/?api-key=YOUR_HELIUS_KEY"
        
        async with session.ws_connect(ws_url) as ws:
            # Subscribe to Pump.fun program logs
            subscribe_msg = {
                "jsonrpc": "2.0",
                "id": 1,
                "method": "logsSubscribe",
                "params": [
                    {"mentions": [str(PUMP_PROGRAM)]},
                    {"commitment": "processed"}
                ]
            }
            await ws.send_json(subscribe_msg)
            
            print("๐Ÿ” Monitoring Pump.fun for new launches...")
            
            async for msg in ws:
                if msg.type == aiohttp.WSMsgType.TEXT:
                    data = msg.json()
                    
                    if 'params' not in data:
                        continue
                    
                    logs = data['params']['result']['value']['logs']
                    signature = data['params']['result']['value']['signature']
                    
                    # "Program log: Instruction: Create" indicates new token
                    if any("Instruction: Create" in log for log in logs):
                        print(f"๐Ÿš€ New token launch detected!")
                        print(f"   Tx: https://solscan.io/tx/{signature}")
                        
                        # Parse the token details
                        await process_new_launch(signature)

async def process_new_launch(signature: str):
    """Extract token details from launch transaction"""
    client = AsyncClient("https://api.mainnet-beta.solana.com")
    
    tx = await client.get_transaction(signature, max_supported_transaction_version=0)
    if not tx.value:
        return
    
    # Parse token mint address from transaction accounts
    accounts = tx.value.transaction.transaction.message.account_keys
    
    # Pump.fun launch follows a specific account order
    # accounts[0] = creator, accounts[1] = mint, accounts[2] = bonding_curve
    if len(accounts) >= 3:
        token_mint = str(accounts[1])
        bonding_curve = str(accounts[2])
        
        print(f"   Token Mint: {token_mint}")
        print(f"   Bonding Curve: {bonding_curve}")
        
        # Safety check and potential buy
        await evaluate_and_snipe(token_mint, bonding_curve)

Safety Filters Before Sniping

Not all Pump.fun tokens are worth buying. Apply these filters:

async def evaluate_and_snipe(token_mint: str, bonding_curve: str):
    """Evaluate a new Pump.fun token before sniping"""
    
    # 1. Check if creator has launched rugs before
    creator_history = await get_creator_history(token_mint)
    if creator_history['rug_count'] > 2:
        print(f"โ›” Creator has {creator_history['rug_count']} rugs โ€” skipping")
        return
    
    # 2. Check social links (real projects usually have Twitter/Telegram)
    metadata = await get_token_metadata(token_mint)
    has_socials = bool(metadata.get('twitter') or metadata.get('telegram'))
    
    # 3. Check initial liquidity (too low = rug risk)
    sol_in_curve = await get_bonding_curve_sol(bonding_curve)
    if sol_in_curve < 0.5:  # Less than 0.5 SOL initial = risky
        print(f"โ›” Only {sol_in_curve:.2f} SOL initial โ€” skipping")
        return
    
    # 4. Check buyer count (creator alone? More buyers = less rug risk)
    initial_buyers = await get_early_buyer_count(bonding_curve)
    
    if has_socials and initial_buyers >= 3 and sol_in_curve >= 0.5:
        sol_to_spend = 0.1  # Never more than 0.1 SOL per snipe
        print(f"โœ… SNIPING: {token_mint[:16]}... | {initial_buyers} buyers | {sol_in_curve:.2f} SOL")
        await buy_pump_token(token_mint, bonding_curve, sol_to_spend)

Buying via Pump.fun Bonding Curve

from solana.rpc.async_api import AsyncClient
from solders.transaction import Transaction
from solders.system_program import TransferParams
import struct

PUMP_GLOBAL = Pubkey.from_string("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf")
PUMP_FEE_RECIPIENT = Pubkey.from_string("CebN5WGQ4jvEPvsVU4EoHEpgznyZtZbAQN5ZMDTfdh2k")

async def buy_pump_token(mint: str, bonding_curve: str, sol_amount: float):
    """Buy a Pump.fun token on the bonding curve"""
    
    client = AsyncClient("https://mainnet.helius-rpc.com/?api-key=YOUR_KEY")
    
    # Pump.fun buy instruction discriminator
    BUY_DISCRIMINATOR = bytes([102, 6, 61, 18, 1, 218, 235, 234])
    
    # Calculate tokens out with 5% slippage tolerance
    tokens_out = await get_tokens_out(bonding_curve, sol_amount)
    min_tokens = int(tokens_out * 0.95)  # 5% slippage
    
    # Pack instruction data
    data = BUY_DISCRIMINATOR + struct.pack('<QQ', min_tokens, int(sol_amount * 1e9))
    
    print(f"Buying {sol_amount} SOL worth of tokens (min {min_tokens:,} tokens)")
    # ... build and send transaction ...

Auto-Sell Strategy

The key to Pump.fun profitability is disciplined exit:

async def monitor_and_sell(token_mint: str, entry_price_sol: float, entry_amount: int):
    """Monitor position and auto-sell at targets"""
    
    TAKE_PROFIT_1 = 2.0   # Sell 50% at 2x
    TAKE_PROFIT_2 = 5.0   # Sell remaining at 5x
    STOP_LOSS = 0.5        # Stop loss at -50%
    
    while True:
        current_price = await get_token_price_in_sol(token_mint)
        ratio = current_price / entry_price_sol
        
        if ratio >= TAKE_PROFIT_2:
            print(f"๐ŸŽฏ 5x target hit! Selling all remaining")
            await sell_all_tokens(token_mint)
            break
        elif ratio >= TAKE_PROFIT_1:
            # Sell half at 2x
            await sell_tokens(token_mint, entry_amount // 2)
            print(f"๐Ÿ“ˆ 2x hit! Sold half, holding rest for 5x")
            # Update tracking
            entry_amount = entry_amount // 2
        elif ratio <= STOP_LOSS:
            print(f"๐Ÿ›‘ Stop loss hit at {ratio:.2f}x โ€” selling all")
            await sell_all_tokens(token_mint)
            break
        
        await asyncio.sleep(3)

Risk Reality Check

Pump.fun is high-risk gambling territory. Realistic stats:

  • ~80-90% of tokens dump to zero
  • Top 10% of launches can 2-20x
  • Bots that survive filter aggressively and size positions conservatively

Golden rule: Never risk more than 0.1 SOL per snipe. Treat it like lottery tickets โ€” expected value positive only with strict position sizing and many attempts.

Related Articles