DEV Community

Lambo Poewert
Lambo Poewert

Posted on

Build a Solana KOL Copy-Trading Bot with Real-Time Webhooks

Every profitable Solana trading bot has one thing in common: speed. The faster you know a KOL bought, the faster you can follow.

Most APIs make you poll every few seconds. That wastes requests, adds latency, and burns your rate limit. The MadeOnSol API now supports webhooks and WebSocket streaming — your server gets notified the instant a trade happens.

In this post I'll show you how to:

  1. Set up a webhook to receive KOL trades in real-time
  2. Verify the HMAC signature to prove it's authentic
  3. Build a simple Express server that logs trades as they happen

What is MadeOnSol?

MadeOnSol tracks 946 Solana KOL wallets in real-time via dual gRPC streams across 9 DEX programs (Pump.fun, Raydium, Jupiter, Orca, etc.). It also monitors 6,700+ Pump.fun deployers and classifies them by bonding success rate.

The API is available on RapidAPI with Free, Pro ($49/mo), and Ultra ($149/mo) tiers.

Step 1: Get your API key

Sign up on RapidAPI and subscribe to Pro or Ultra (webhooks require a paid tier).

Step 2: Register a webhook

const API_KEY = "your-rapidapi-key";
const HOST = "madeonsol-solana-kol-tracker-tools-api.p.rapidapi.com";

const res = await fetch("https://madeonsol.com/api/v1/webhooks", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-rapidapi-key": API_KEY,
    "x-rapidapi-host": HOST,
  },
  body: JSON.stringify({
    url: "https://your-server.com/webhooks/madeonsol",
    events: ["kol:trade", "deployer:alert"],
    filters: {
      min_sol: 1, // Only trades >= 1 SOL
    },
  }),
});

const data = await res.json();
console.log("Webhook ID:", data.webhook.id);
console.log("Secret:", data.webhook.secret); // Save this! Only shown once.
Enter fullscreen mode Exit fullscreen mode

The secret is an HMAC-SHA256 key. Every webhook delivery includes an X-MadeOnSol-Signature header — you use the secret to verify it.

Available events

Event Description
kol:trade A KOL wallet buys or sells a token
kol:coordination Multiple KOLs converge on the same token
deployer:alert A tracked deployer launches a new token
deployer:bond A tracked deployer's token graduates the bonding curve

Available filters

Filter Type Description
min_sol number Minimum SOL amount (for kol:trade)
action string "buy" or "sell" only
kol_name string Filter by specific KOL name
deployer_tier string[] Filter by deployer tier: ["elite", "good"]
min_kols number Minimum KOL count (for kol:coordination)

Step 3: Build your webhook receiver

Here's a minimal Express server that receives and verifies webhook payloads:

import express from "express";
import crypto from "crypto";

const app = express();
app.use(express.json());

const WEBHOOK_SECRET = "your-webhook-secret-from-step-2";

app.post("/webhooks/madeonsol", (req, res) => {
  // 1. Verify HMAC signature
  const signature = req.headers["x-madeonsol-signature"] as string;
  const expected = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(JSON.stringify(req.body))
    .digest("hex");

  if (signature !== expected) {
    console.warn("Invalid signature — rejecting");
    return res.status(401).send("Invalid signature");
  }

  // 2. Process the event
  const { event, data, timestamp } = req.body;

  if (event === "kol:trade") {
    console.log(
      `${data.kol_name} ${data.action.toUpperCase()} ${data.sol_amount} SOL`,
      `→ ${data.token_symbol || data.token_mint.slice(0, 8)}`,
      `at ${timestamp}`
    );

    // This is where you'd trigger your copy-trade logic:
    // await copyTrade(data.token_mint, data.action, data.sol_amount);
  }

  if (event === "deployer:alert") {
    console.log(
      `${data.deployer_tier} deployer launched ${data.token_symbol}`,
      `Bond rate: ${(data.bonding_rate * 100).toFixed(0)}%`
    );
  }

  res.status(200).send("OK");
});

app.listen(3000, () => console.log("Webhook server running on :3000"));
Enter fullscreen mode Exit fullscreen mode

Step 4: Test your webhook

Before waiting for a real trade, send a test payload to make sure everything works:

await fetch("https://madeonsol.com/api/v1/webhooks/test", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-rapidapi-key": API_KEY,
    "x-rapidapi-host": HOST,
  },
  body: JSON.stringify({ webhook_id: 1 }),
});
Enter fullscreen mode Exit fullscreen mode

This sends a sample KOL trade event to your URL. If your server responds 200, you'll see { success: true, status_code: 200, response_time_ms: ... }.

Alternative: WebSocket Streaming

If you prefer a persistent connection instead of webhooks, you can use WebSocket streaming:

// 1. Get a streaming token (valid 24 hours)
const tokenRes = await fetch("https://madeonsol.com/api/v1/stream/token", {
  method: "POST",
  headers: {
    "x-rapidapi-key": API_KEY,
    "x-rapidapi-host": HOST,
  },
});
const { token } = await tokenRes.json();

// 2. Connect to WebSocket
import WebSocket from "ws";

const ws = new WebSocket(`wss://madeonsol.com/ws/v1/stream?token=${token}`);

ws.on("open", () => {
  // 3. Subscribe to channels
  ws.send(JSON.stringify({
    type: "subscribe",
    channels: ["kol:trades", "deployer:alerts"],
    filters: { min_sol: 1 },
  }));
});

ws.on("message", (raw) => {
  const msg = JSON.parse(raw.toString());

  if (msg.type === "heartbeat") return; // 30s keepalive

  if (msg.event === "kol:trade") {
    console.log(`${msg.data.kol_name} ${msg.data.action} ${msg.data.sol_amount} SOL`);
  }
});
Enter fullscreen mode Exit fullscreen mode

Connection limits: Pro = 1 concurrent connection, Ultra = 3.

Retry & reliability

MadeOnSol webhooks are built for reliability:

  • 3 retries with exponential backoff (5s, 30s, 2min)
  • 10s timeout per delivery attempt
  • Auto-disable after 10 consecutive failures (re-enable via PATCH)
  • Delivery log — check recent deliveries with GET /webhooks/{id}

What can you build with this?

  • Copy-trading bot — follow KOL buys automatically via Raydium/Jupiter
  • Telegram/Discord alerts — push KOL trades to a group chat
  • Analytics dashboard — track KOL performance in real-time
  • Token screener — filter new tokens by deployer reputation before buying
  • Multi-KOL detector — get notified when 3+ KOLs buy the same token

SDKs

The MadeOnSol API has SDKs for multiple platforms:

  • TypeScript: npm install madeonsol-x402
  • Python: pip install madeonsol-x402
  • MCP Server (Claude/Cursor): npm install -g mcp-server-madeonsol
  • ElizaOS Plugin: npm install @madeonsol/plugin-madeonsol
  • Solana Agent Kit: npm install solana-agent-kit-plugin-madeonsol

Links

Top comments (0)