AGENTS.md 8.4 KB

Agents Guide

This document describes the key components of the Meteora DLMM Copy Trading Bot and how they interact.

Architecture Overview

┌─────────────────┐     ┌──────────────────────────────────────────┐
│   Next.js Web   │     │              Worker Process              │
│                 │     │                                          │
│  Dashboard UI   │     │  ┌─────────┐  ┌─────────┐  ┌─────────┐ │
│  (page.tsx)     │     │  │ Monitor │──│ Tracker │──│Executor │ │
│                 │     │  └────┬────┘  └─────────┘  └────┬────┘ │
│  API Routes     │     │       │                          │      │
│  /api/wallets   │◄────┤       │ WebSocket                │ DLMM │
│  /api/positions │     │       │ onLogs                   │ SDK  │
│  /api/trades    │     │       ▼                          ▼      │
│  /api/settings  │     │  Solana RPC ◄───────────── Solana RPC   │
└────────┬────────┘     └──────────────────────────────────────────┘
         │                              │
         ▼                              ▼
    ┌──────────┐                  ┌──────────┐
    │  SQLite  │◄─────────────────│  SQLite  │
    │ Database │  (shared volume) │ Database │
    └──────────┘                  └──────────┘

Components

1. Transaction Monitor (src/worker/monitor.ts)

Role: Watches leader wallets for DLMM transactions in real-time.

How it works:

  • Subscribes to Solana onLogs WebSocket for each active monitored wallet
  • Filters logs for mentions of the DLMM program ID (LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo)
  • On match, fetches the full transaction and passes it to the transaction parser
  • Emits meteoraTx events with parsed operations
  • Maintains a dedup set to avoid processing the same signature twice

Key behaviors:

  • Subscription sync runs every 30 seconds to pick up new wallets added via the dashboard
  • Processes only confirmed commitment level transactions

2. Transaction Parser (src/lib/solana/transaction-parser.ts)

Role: Decodes raw Solana transactions into structured DLMM operations.

How it works:

  • Resolves all account keys from the transaction message, including address lookup tables (v0 transactions)
  • Iterates through all instructions, matching by DLMM program ID
  • Uses Anchor's BorshInstructionCoder with the DLMM IDL to decode instruction data
  • Maps decoded instruction names to action types (ADD_LIQUIDITY, REMOVE_LIQUIDITY, etc.)
  • Extracts account addresses (position, lbPair, sender) from account indices using predefined account maps
  • Extracts parameters (bin ranges, amounts, BPS) from decoded instruction data

Supported instructions: | Instruction | Action | |---|---| | addLiquidity, addLiquidityByStrategy, addLiquidityByStrategy2, addLiquidityByStrategyOneSide | ADD_LIQUIDITY | | removeLiquidity, removeLiquidityByRange, removeLiquidityByRange2 | REMOVE_LIQUIDITY | | closePosition, closePosition2, closePositionIfEmpty | CLOSE_POSITION | | initializePosition, initializePosition2 | INIT_POSITION | | rebalanceLiquidity | REBALANCE_LIQUIDITY |

3. Position Tracker (src/worker/position-tracker.ts)

Role: Maintains the state of leader and follower positions in the database.

How it works:

  • On INIT_POSITION / ADD_LIQUIDITY: creates or updates leader position records with bin range and strategy info
  • On REMOVE_LIQUIDITY: logs activity (position stays open)
  • On CLOSE_POSITION: marks leader position as closed
  • On REBALANCE_LIQUIDITY: updates leader position bin range
  • Provides lookup for follower positions mapped to leader positions

4. Copy Executor (src/worker/executor.ts)

Role: Mirrors leader operations on the follower wallet.

Supported operations:

Leader Action Follower Action
ADD_LIQUIDITY Open new position + add scaled liquidity
REMOVE_LIQUIDITY Remove liquidity (same BPS ratio)
CLOSE_POSITION Remove all liquidity + close position
REBALANCE_LIQUIDITY Remove liquidity + re-add in new bin range
INIT_POSITION Track only (no copy, waits for ADD_LIQUIDITY)

Scaling: The copy ratio (COPY_RATIO env var, default 1.0) scales the leader's deposit amounts. For example, if the leader deposits 1 SOL and the ratio is 0.5, the follower deposits 0.5 SOL.

Safety: Each copy trade is recorded in the database with status tracking (PENDING → SUCCESS/FAILED) and error messages for debugging.

5. DLMM Client (src/lib/meteora/dlmm-client.ts)

Role: Wraps the @meteora-ag/dlmm SDK for copy trading operations.

Functions:

  • copyOpenPosition: Creates a new DLMM position and adds liquidity using the leader's strategy type and bin range
  • copyRemoveLiquidity: Removes liquidity from a follower position (by BPS)
  • copyClosePosition: Closes a follower position
  • copyRebalanceLiquidity: Removes all liquidity and re-adds in a new bin range matching the leader's rebalance

6. WebSocket Heartbeat (src/worker/heartbeat.ts)

Role: Keeps the Solana WebSocket connection alive and handles reconnection.

How it works:

  • Sends periodic getSlot ping requests (every 30 seconds)
  • Detects stale connections (no response within timeout)
  • On connection loss, triggers a reconnection callback that re-subscribes all wallets
  • Uses exponential backoff for reconnection attempts

7. Web Dashboard (src/app/page.tsx)

Role: Provides a UI for managing monitored wallets.

Features:

  • Add new wallets by Solana address (with optional label)
  • View all monitored wallets with status (Active/Paused)
  • Toggle wallet active state
  • Delete wallets
  • Validates Solana addresses (base58, 32-44 chars)

8. API Routes (src/app/api/)

Role: REST API for CRUD operations on wallets, positions, trades, and settings.

Routes:

  • /api/wallets — Wallet CRUD with Solana address validation
  • /api/positions — Read leader and follower positions
  • /api/trades — Read copy trade history (with status and error info)
  • /api/settings — Read/update worker settings (copy ratio, slippage, max size, auto-copy toggle)
  • /api/health — Health check returning wallet count and worker status

Data Flow

Copy Trade Lifecycle

1. Leader wallet sends DLMM transaction on Solana
   ↓
2. Monitor detects tx via WebSocket onLogs (confirmed)
   ↓
3. Monitor fetches full tx → Parser decodes DLMM instructions
   ↓
4. Tracker updates leader position state in DB
   ↓
5. Executor checks if follower should copy:
   - Is auto_copy enabled?
   - Is there already a follower position? (skip duplicate adds)
   - Is there a follower position to modify? (for remove/close/rebalance)
   ↓
6. Executor creates CopyTrade record (status: PENDING)
   ↓
7. Executor calls DLMM SDK to mirror the operation
   ↓
8. CopyTrade updated to SUCCESS or FAILED

Database Schema

Table Purpose
MonitoredWallet Wallets to watch (address, label, active flag)
LeaderPosition Leader's DLMM positions (pair, bins, status)
FollowerPosition Follower's mirrored positions (linked to leader)
CopyTrade Record of every copy attempt (action, status, tx sigs)
ActivityLog General activity logging (worker start/stop, errors)

Environment Configuration

Variable Required Default Description
RPC_ENDPOINT Yes https://api.mainnet-beta.solana.com Solana RPC URL
WS_ENDPOINT No Derived from RPC Solana WebSocket URL
FOLLOWER_PRIVATE_KEY Yes Base58 private key of the follower wallet
DATABASE_URL Yes file:./dev.db SQLite database path
COPY_RATIO No 1.0 Amount scaling factor
MAX_POSITION_SIZE_SOL No 10 Maximum SOL per position
SLIPPAGE_BPS No 100 Slippage tolerance (basis points)
AUTO_COPY_ENABLED No true Enable/disable automatic copy trading