|
|
@@ -0,0 +1,183 @@
|
|
|
+# 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 |
|