Build a Memecoin Copy Trading Bot on BNB Chain with QuickNode Streams

๐Ÿ“… April 9, 2026  |  ๐Ÿ“ˆ 22 min read ๐Ÿค– BNB Chain | QuickNode | JavaScript | Copy Trading

In April 2026, QuickNode released a comprehensive guide on building a production-ready copy trading bot for memecoins on BNB Chain. The bot monitors successful traders on the four.meme platform โ€” BNB Chain's popular memecoin launchpad similar to Solana's Pump.fun โ€” and automatically executes proportional trades when a target wallet makes a purchase. The architecture leverages QuickNode Streams for real-time blockchain data, Express for webhook handling, and Viem for transaction execution.

๐Ÿš€ One Stream, One Cost, Multiple Destinations: QuickNode Streams can now deliver to multiple destinations simultaneously from a single pipeline. No duplicate streams, no config drift, and no additional charge per destination.

Project Overview

Copy trading allows you to automatically mirror the trades of successful traders by monitoring their onchain transactions and executing similar trades in real-time. By leveraging QuickNode Streams, your bot receives instant notifications of onchain events, enabling reaction within seconds of a tracked wallet's trade.

4.meme
BNB Chain Launchpad
QuickNode
Streams + Webhooks
Viem
Ethereum Library

What You Will Build

Technical Requirements

Understanding the four.meme Smart Contract

The four.meme platform uses a bonding curve mechanism similar to Solana's Pump.fun. When users create tokens on the platform:

The main contract, TokenManager2, is deployed at 0x5c952063c7fc8610FFDB798152D69F0B9550762b on the BNB Chain mainnet.

TokenPurchase Event Structure

When a user buys a token on the platform, the contract emits a TokenPurchase event with the following structure:

event TokenPurchase(
    address token,
    address account,
    uint256 price,
    uint256 amount,
    uint256 cost,
    uint256 fee,
    uint256 offers,
    uint256 funds
);

The event signature hash is 0x7db52723a3b2cdd6164364b3b766e65e540d7be48ffa89582956d8eaebe62942, used to filter for TokenPurchase events.

๐Ÿ” Important: None of these parameters are indexed, meaning they all appear in the event's data field rather than as separate topics. This requires manual decoding of the data field to extract individual values.

Decoding the Data Field

Each parameter occupies 32 bytes (64 hex characters). Here is a sample breakdown:

// 64 hex chars (bytes32/uint256 - zero-padded address - token)
00000000000000000000000076138888158f7ce4bbe14c59e18e880d57ab4444

// 64 hex chars (bytes32/uint256 - zero-padded address - buyer)
0000000000000000000000004262f7b70b81538258eb2c5ecad3947ba4e0c8b0

// 64 hex chars (uint256 - price)
000000000000000000000000000000000000000000000000000000029c13f537

// 64 hex chars (uint256 - amount)
00000000000000000000000000000000000000000003a339d3d41d9ad2a45200

Offset calculation (zero-indexed):

QuickNode Streams JavaScript Filter

QuickNode Streams allow you to filter blockchain events server-side before they are delivered to your endpoint, saving bandwidth and reducing costs. The filter function below processes each block's receipts, filters for relevant logs, decodes the TokenPurchase event parameters, and returns a structured payload optimized for the copy trading bot.

function main(payload) {
  const { data, metadata } = payload;

  // Configuration constants
  const TARGET_WALLET = "0xYOUR_TARGET_WALLET_ADDRESS_HERE";
  const TARGET_CONTRACT = "0x5c952063c7fc8610FFDB798152D69F0B9550762b";
  const TOKEN_PURCHASE_SIG = "0x7db52723a3b2cdd6164364b3b766e65e540d7be48ffa89582956d8eaebe62942";

  const copyTrades = [];

  function extractAddress(dataHex, offset) {
    const data = dataHex.slice(2);
    const start = offset * 64 + 24;
    const addressHex = data.slice(start, start + 40);
    return "0x" + addressHex.toLowerCase();
  }

  function extractUint256(dataHex, offset) {
    const data = dataHex.slice(2);
    const start = offset * 64;
    const uint256Hex = data.slice(start, start + 64);
    return "0x" + uint256Hex;
  }

  // Process all receipts
  data[0].receipts.forEach((receipt) => {
    const relevantLogs = receipt.logs.filter((log) => {
      if (log.address?.toLowerCase() !== TARGET_CONTRACT.toLowerCase()) return false;
      if (log.topics?.[0] !== TOKEN_PURCHASE_SIG) return false;
      
      const buyerAddress = extractAddress(log.data, 1);
      return buyerAddress === TARGET_WALLET.toLowerCase();
    });

    if (relevantLogs.length > 0) {
      const decodedLogs = relevantLogs.map((log) => ({
        token: extractAddress(log.data, 0),
        buyer: extractAddress(log.data, 1),
        price: extractUint256(log.data, 2),
        amount: extractUint256(log.data, 3),
        cost: extractUint256(log.data, 4),
        fee: extractUint256(log.data, 5),
        offers: extractUint256(log.data, 6),
        funds: extractUint256(log.data, 7)
      }));
      
      copyTrades.push({
        transactionHash: receipt.transactionHash,
        blockNumber: receipt.blockNumber,
        trades: decodedLogs
      });
    }
  });
  
  return copyTrades.length ? { copyTrades } : null;
}

Project Architecture

The bot follows a modular architecture with the following components:

File Structure

โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ config.ts           # Configuration and environment variables
โ”‚   โ”œโ”€โ”€ webhookServer.ts    # Express server for receiving webhooks
โ”‚   โ”œโ”€โ”€ tradingBot.ts       # Viem-based trading logic
โ”‚   โ””โ”€โ”€ index.ts            # Entry point
โ”œโ”€โ”€ .env.example            # Template for environment variables
โ””โ”€โ”€ package.json            # Node.js project file

Webhook Server with HMAC Verification

app.post("/webhook", async (req: Request, res: Response) => {
  try {
    const nonce = req.headers["x-qn-nonce"] as string;
    const timestamp = req.headers["x-qn-timestamp"] as string;
    const signature = req.headers["x-qn-signature"] as string;
    
    // Verify HMAC signature for security
    const isValid = verifySignature(req.body, signature, nonce, timestamp);
    if (!isValid) return res.status(401).send("Invalid signature");
    
    const { copyTrades } = req.body;
    for (const trade of copyTrades) {
      await executeCopyTrade(trade);
    }
    res.sendStatus(200);
  } catch (error) {
    res.status(500).send("Error processing webhook");
  }
});

Execution Logic with Viem

The trading bot uses Viem โ€” a modern TypeScript library for Ethereum โ€” to interact with the blockchain. Key features include proportional trade sizing, slippage protection, and automatic transaction signing.

import { createWalletClient, http, parseEther } from 'viem';
import { bsc } from 'viem/chains';

const walletClient = createWalletClient({
  chain: bsc,
  transport: http(process.env.QUICKNODE_RPC_URL)
});

async function executeCopyTrade(tradeData) {
  const { token, cost, amount } = tradeData;
  const proportionalAmount = calculateProportionalSize(cost);
  
  const { request } = await publicClient.simulateContract({
    address: token,
    abi: TOKEN_ABI,
    functionName: 'buy',
    args: [proportionalAmount],
    account: walletAccount
  });
  
  const hash = await walletClient.writeContract(request);
  console.log(`Trade executed: ${hash}`);
}

Cost Optimization with Server-Side Filtering

Returning null for non-matching blocks prevents unnecessary data transfer. QuickNode only charges for delivered payloads, making server-side filtering highly cost-effective for high-frequency trading applications.

๐Ÿ’ก Bandwidth Efficiency: By filtering at the edge, you receive only the relevant data you need, minimizing bandwidth usage and the amount of data you need to parse and store locally.

Community Resources and Alternative Implementations

The four.meme ecosystem has seen significant developer activity in 2026. Multiple open-source implementations are available on GitHub, including modular TypeScript bots and SDKs for automated trading:

As of April 2026, multiple actively maintained repositories on GitHub continue to enhance the four.meme trading ecosystem, with updates ranging from bundler optimizations to zero-block sniper implementations.


Key Takeaways