- Rewrite patch-clob-client.cjs to use regex instead of exact string matching, so it works regardless of code formatting differences between npm versions (fixes "Could not find request config line" on fresh VPS install) - Add multiple fallback patterns (config regex → fallback regex → axios call injection) with debug output if all fail - Add Polymarket geoblock API check (polymarket.com/api/geoblock) for both VPS direct IP and proxy IP at startup Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Polymarket Terminal
An automated trading terminal for Polymarket — copy trades, provide liquidity, and snipe low-priced orderbook fills, all from your command line.
Created by @direkturcrypto
Table of Contents
- Features
- Prerequisites
- Installation
- Configuration
- Usage
- Running on VPS with PM2
- How It Works
- Project Structure
- Important Warnings
- License
Features
Copy Trade Bot
- Watch Trader — Monitor any Polymarket wallet address in real time via WebSocket
- Copy Buy — Automatically mirror buy orders with configurable position sizing
- Copy Sell — Automatically mirror sell orders (market or limit)
- Auto Sell — Place a GTC limit sell at a target profit % immediately after a buy fills
- Auto Redeem — Periodically check and redeem winning positions on-chain
- Market Expiry Guard — Skip buys if market closes within
MIN_MARKET_TIME_LEFTseconds - GTC Fallback — Falls back to a GTC limit order when copying "next market" trades with no liquidity
- Per-Market Queue — Concurrent events for the same market are serialized to prevent duplicate buys
- Dry Run Mode — Simulate the full flow without placing real orders
Market Maker Bot
- Automated Liquidity — Splits USDC into YES+NO tokens and places limit sells on both sides at $0.50 entry
- Cut-Loss Protection — Merges unsold tokens back to USDC before market close
- Recovery Buy — Optional directional bet after a cut-loss triggers
- Multi-Asset — Supports BTC, ETH, SOL, and any 5m/15m Polymarket market
- Simulation Mode — Full dry-run with P&L tracking
Orderbook Sniper Bot
- 3-Tier Strategy — Places GTC BUY orders at 3c, 2c, and 1c with weighted sizing (20%/30%/50%)
- Multi-Asset — Targets ETH, SOL, XRP, and more simultaneously
- Simulation Mode — Preview orders without spending funds
- Session Scheduling — Per-asset time windows (UTC+8) for selective trading
Prerequisites
| Requirement | Details |
|---|---|
| Node.js | v18 or higher (ESM support required) |
| Polygon Wallet | An EOA wallet with a private key |
| Polymarket Proxy Wallet | Your proxy wallet address (visible on your Polymarket profile → Deposit) |
| USDC.e on Polygon | Deposited via Polymarket's deposit flow |
| MATIC on Polygon | A small amount for gas fees (redeem & on-chain operations) |
| PM2 (optional) | For running on a VPS: npm install -g pm2 |
Installation
# 1. Clone the repository
git clone https://github.com/direkturcrypto/polymarket-terminal.git
cd polymarket-terminal
# 2. Install dependencies
npm install
# 3. Copy the environment template
cp .env.example .env
# 4. Fill in your credentials
nano .env
Configuration
All settings are controlled via the .env file. Never commit your .env file — it is already listed in .gitignore.
Wallet Setup
| Variable | Description | Required |
|---|---|---|
PRIVATE_KEY |
Your EOA private key (signing only, does not hold USDC) | Yes |
PROXY_WALLET_ADDRESS |
Your Polymarket proxy wallet address | Yes |
POLYGON_RPC_URL |
Polygon JSON-RPC endpoint | Yes |
How to find your Proxy Wallet: Log in to polymarket.com → click your profile → Deposit → copy the wallet address shown.
Polymarket API Credentials (Optional)
Leave these blank to have the client auto-derive credentials from your private key.
| Variable | Description |
|---|---|
CLOB_API_KEY |
CLOB API key |
CLOB_API_SECRET |
CLOB API secret |
CLOB_API_PASSPHRASE |
CLOB API passphrase |
Copy Trade Bot Settings
| Variable | Description | Default |
|---|---|---|
TRADER_ADDRESS |
Proxy wallet address of the trader to copy | (required) |
SIZE_MODE |
percentage (of MAX_POSITION_SIZE) or balance (of your USDC balance) |
balance |
SIZE_PERCENT |
Percentage to use per trade | 10 |
MIN_TRADE_SIZE |
Minimum trade size in USDC (skip if below) | 1 |
MAX_POSITION_SIZE |
Maximum USDC per market position | 10 |
AUTO_SELL_ENABLED |
Place a limit sell after each buy fills | true |
AUTO_SELL_PROFIT_PERCENT |
Target profit % for the auto-sell limit order | 10 |
SELL_MODE |
market or limit when copying a sell |
market |
REDEEM_INTERVAL |
Seconds between redemption checks | 60 |
MIN_MARKET_TIME_LEFT |
Skip buy if market closes within this many seconds | 300 |
GTC_FALLBACK_TIMEOUT |
Seconds to wait for GTC fill when FAK finds no liquidity | 60 |
DRY_RUN |
Simulate without placing real orders | true |
Market Maker Bot Settings
| Variable | Description | Default |
|---|---|---|
MM_ASSETS |
Comma-separated assets to market-make (e.g. btc,eth) |
btc |
MM_DURATION |
Market duration: 5m or 15m |
5m |
MM_TRADE_SIZE |
USDC per side (total exposure = 2×) | 5 |
MM_SELL_PRICE |
Limit sell price target (e.g. 0.60) |
0.60 |
MM_CUT_LOSS_TIME |
Seconds before close to trigger cut-loss | 60 |
MM_MARKET_KEYWORD |
Keyword to filter market questions | Bitcoin Up or Down |
MM_ENTRY_WINDOW |
Max seconds after open to enter (0 = open only) | 45 |
MM_POLL_INTERVAL |
Seconds between new market polls | 10 |
MM_RECOVERY_BUY |
Enable recovery buy after cut-loss | false |
MM_RECOVERY_THRESHOLD |
Minimum dominant-side price to qualify for recovery | 0.70 |
MM_RECOVERY_SIZE |
USDC for recovery buy (0 = use MM_TRADE_SIZE) |
0 |
Orderbook Sniper Settings
3-Tier Strategy: Places orders at 3 price levels with weighted sizing
| Variable | Description | Default |
|---|---|---|
SNIPER_ASSETS |
Comma-separated assets to snipe (e.g. eth,sol,xrp) |
eth,sol,xrp |
SNIPER_TIER1_PRICE |
Highest price tier (e.g. 0.03 = 3c) |
0.03 |
SNIPER_TIER2_PRICE |
Mid price tier (e.g. 0.02 = 2c) |
0.02 |
SNIPER_TIER3_PRICE |
Lowest price tier (e.g. 0.01 = 1c) |
0.01 |
SNIPER_MAX_SHARES |
Max total shares per side (min 5 per tier) | 15 |
Allocation:
- Tier 1 (3c): 20% of max shares (min 5)
- Tier 2 (2c): 30% of max shares (min 5)
- Tier 3 (1c): 50% of max shares (min 5)
Example with SNIPER_MAX_SHARES=15:
- 3 shares @ 3c = $0.09
- 5 shares @ 2c = $0.10
- 7 shares @ 1c = $0.07
- Total per side: 15 shares = $0.26
Usage
Terminal UI (local)
Runs with an interactive split-panel dashboard (blessed TUI).
# Copy Trade Bot
npm start # live trading
npm run dev # live + auto-reload on file changes
# Market Maker Bot
npm run mm # live trading
npm run mm-sim # simulation (DRY_RUN=true)
npm run mm-dev # simulation + auto-reload
# Orderbook Sniper Bot
npm run sniper # live trading
npm run sniper-sim # simulation
npm run sniper-dev # simulation + auto-reload
Plain Log Mode (no TUI)
Writes plain timestamped text to stdout — suitable for piping, tail -f, or PM2.
# Copy Trade Bot
npm run bot # live trading
npm run bot-sim # simulation
npm run bot-dev # simulation + auto-reload
# Market Maker Bot
npm run mm-bot # live trading
npm run mm-bot-sim # simulation
npm run mm-bot-dev # simulation + auto-reload
Always test with
DRY_RUN=true(or*-simscripts) first before committing real funds.
Running on VPS with PM2
Each bot has its own PM2 config file inside the pm2/ folder.
Install PM2
npm install -g pm2
Copy Trade Bot
# Live trading
pm2 start pm2/copy.config.cjs
# Simulation
pm2 start pm2/copy.config.cjs --env sim
# View logs
pm2 logs polymarket-copy
tail -f logs/copy-out.log
# Management
pm2 restart polymarket-copy
pm2 stop polymarket-copy
pm2 delete polymarket-copy
Market Maker Bot
# Live trading
pm2 start pm2/mm.config.cjs
# Simulation
pm2 start pm2/mm.config.cjs --env sim
# View logs
pm2 logs polymarket-mm
tail -f logs/mm-out.log
# Management
pm2 restart polymarket-mm
pm2 stop polymarket-mm
pm2 delete polymarket-mm
Auto-start on reboot
pm2 startup # generates a startup command — run the command it prints
pm2 save # saves current process list
How It Works
Copy Trade Bot Flow
WebSocket (RTDS) — real-time trade events from trader
│
▼
Per-market queue (prevents concurrent duplicate buys)
│
┌────┴──────┐
│ │
BUY SELL
│ │
├─ Expiry guard (MIN_MARKET_TIME_LEFT)
├─ Max position cap ├─ Cancel open orders
├─ FAK market buy ├─ Reconcile on-chain balance
│ └─ 0 fill? → GTC fallback ├─ FAK market sell / limit sell
├─ Place auto-sell GTC └─ Remove position
└─ Save position
│
▼
Redeemer loop (every REDEEM_INTERVAL seconds)
→ Check on-chain payout → redeemPositions via Gnosis Safe
Market Maker Flow
New Market Detected
│
▼
Split USDC → YES + NO tokens ($0.50 each, zero slippage)
│
▼
Place limit SELL on both sides at MM_SELL_PRICE
│
▼
Monitor fills every few seconds
│
┌────┴────┐
│ │
Fill Time < MM_CUT_LOSS_TIME
│ │
▼ ▼
Collect Cancel orders → Merge YES+NO back to USDC
profit (recovery buy optional)
Project Structure
polymarket-terminal/
├── src/
│ ├── index.js — Copy trade bot (TUI)
│ ├── bot.js — Copy trade bot (plain log / PM2)
│ ├── mm.js — Market maker bot (TUI)
│ ├── mm-bot.js — Market maker bot (plain log / PM2)
│ ├── sniper.js — Orderbook sniper bot
│ │
│ ├── config/
│ │ └── index.js — Environment variable loading & validation
│ │
│ ├── services/
│ │ ├── client.js — CLOB client initialization & USDC balance
│ │ ├── watcher.js — Poll-based trader activity detection
│ │ ├── wsWatcher.js — WebSocket real-time trade listener
│ │ ├── executor.js — Buy & sell order execution logic
│ │ ├── position.js — Position state management (CRUD)
│ │ ├── autoSell.js — Auto limit-sell placement
│ │ ├── redeemer.js — Market resolution check & CTF redemption
│ │ ├── ctf.js — On-chain CTF contract interactions
│ │ ├── mmDetector.js — Market detection for market maker
│ │ ├── mmExecutor.js — Market maker strategy execution
│ │ ├── sniperDetector.js — Market detection for sniper
│ │ └── sniperExecutor.js — Orderbook sniper order placement
│ │
│ ├── ui/
│ │ └── dashboard.js — Terminal UI (blessed)
│ │
│ └── utils/
│ ├── logger.js — Timestamped logging (TUI + plain modes)
│ ├── state.js — Atomic JSON state file management
│ └── simStats.js — Simulation P&L statistics
│
├── pm2/
│ ├── copy.config.cjs — PM2 config for copy trade bot
│ └── mm.config.cjs — PM2 config for market maker bot
│
├── data/ — Runtime state files (gitignored)
├── logs/ — PM2 log files (gitignored)
├── .env.example — Configuration template
├── .gitignore
└── package.json
Important Warnings
- Never commit your
.envfile. Your private key must remain secret. The.gitignorealready excludes it. - Always start with
DRY_RUN=true(or a*-simscript) to verify the bot behaves as expected before using real funds. - Use a small
SIZE_PERCENTfor initial live runs to limit exposure. - Keep MATIC in your EOA wallet for gas fees (redeem operations and on-chain CTF calls).
- This software is provided as-is, with no guarantees. Prediction market trading carries significant financial risk. You are solely responsible for any losses.
Credits
Built and maintained by @direkturcrypto.
License
ISC License — see LICENSE for details.