

The Double Fail That Wasn't
So I saw spacexbt and DidiTrading talking about insider tracking bots for Polymarket. Space mentioned he built one in about 3 hours. I'm a sucker for hype, so of course I had to build my own.
But here's where it gets interesting. Instead of just diving in, I did what I always do: I started overengineering the preparation phase.
First fail: I built a todo list website. A whole HTML/CSS thing where you can click through the steps. Beautiful checkboxes. Nice design. Completely unnecessary. It was so useless that I didn't even open it myself while building the bot, so I can only assume nobody else will either. I initially thought it would be quick content I could share on X. Spoiler: it wasn't quick.
Second fail: I then spent over an hour tweaking the design of that todo list. Changed the layout multiple times. Rewrote the content. Perfectionism kicked in for something that literally nobody asked for.

Classic Wenzel moment. I've been self-employed for 20 years, and I still fall into this trap.
Here's the twist I didn't expect.
By obsessing over that stupid todo list, I had actually forced myself to think through every single aspect of the bot. What data do I need? What endpoints? What filters make sense? How do I avoid spam? What's the detection logic?
When I finally opened Codex, I didn't have a vague idea. I had a complete PRD (Product Requirements Document). Every edge case thought through. Every config parameter defined.
I dumped the whole thing into Codex and... 30 minutes later, the bot was done. Autonomously built by the AI agent while I grabbed a beer.
spacexbt needed 3 hours. I needed 30 minutes.
But let's be real: I also spent 3 hours on that todo list beforehand. So in total? Same time. The difference is that I now have a detailed PRD that I can share, iterate on, and use as a foundation for improvements.
Now here's where I need to be transparent, because there's way too much bullshit in this space.
Yes, the bot works. It polls Polymarket trades every second, filters for large trades (2k+ USD), checks if the wallet has been inactive, and sends Discord alerts. Technically, it does exactly what it's supposed to do.

But no, this is not a money printer.
In its current state, the bot is very basic. Even if you improve it massively, add ML models, track PnL, whatever... it can only ever be a small decision-making aid. Not a crystal ball. Not alpha that makes you rich on autopilot.
I see too many people on social media claiming they made crazy money with bots like this. Maybe some did. But for every winner, there are 100 people who lost money by blindly trusting alerts. Don't be that person.
I want more honesty and transparency in the online world. Especially in crypto. Especially in AI. Especially where those two overlap.
So I'm sharing my complete PRD below. Not because it's perfect, but because:
You'll learn more by building your own bot (even if it's just prompting Claude Code or Codex) than by copy-pasting someone else's code
You can see exactly what goes into something like this
You can call me out if my approach is dumb
The bot will eventually become part of thethirdeye.xyz and be available to users there once it's properly fine-tuned. But for now, I want to document the journey publicly.
Quick shoutout to everyone who's been supportive since I launched thethirdeye.xyz
. The feedback, the engagement, the questions... it means a lot. Building in public is scary, but also incredibly rewarding when people actually give a shit.
If you want to follow along as I improve this bot and share more details, you know what to do. I'll be posting updates over the next days and weeks.
And yes, I would appreciate likes and shares. Not for the ego (okay, maybe a little), but because I genuinely believe we need more transparency in this space. The more people see real, honest content about what these tools can and cannot do, the better.
Let's go.
Below is the complete PRD I used. Feel free to use it, modify it, improve it. If you build something cool with it, let me know.
You can simply copy and paste the whole thing, dump it into Codex (or Claude), and get a working bot. It worked for me.
One bug I ran into that you should watch out for: The Polymarket API returns timestamps in Unix seconds, but JavaScript's Datenow() returns milliseconds. If you compare them directly, every trade gets filtered as "old". I've added explicit notes about this in the PRD below.
That's it. Now go build something. ❤️
The Double Fail That Wasn't
So I saw spacexbt and DidiTrading talking about insider tracking bots for Polymarket. Space mentioned he built one in about 3 hours. I'm a sucker for hype, so of course I had to build my own.
But here's where it gets interesting. Instead of just diving in, I did what I always do: I started overengineering the preparation phase.
First fail: I built a todo list website. A whole HTML/CSS thing where you can click through the steps. Beautiful checkboxes. Nice design. Completely unnecessary. It was so useless that I didn't even open it myself while building the bot, so I can only assume nobody else will either. I initially thought it would be quick content I could share on X. Spoiler: it wasn't quick.
Second fail: I then spent over an hour tweaking the design of that todo list. Changed the layout multiple times. Rewrote the content. Perfectionism kicked in for something that literally nobody asked for.

Classic Wenzel moment. I've been self-employed for 20 years, and I still fall into this trap.
Here's the twist I didn't expect.
By obsessing over that stupid todo list, I had actually forced myself to think through every single aspect of the bot. What data do I need? What endpoints? What filters make sense? How do I avoid spam? What's the detection logic?
When I finally opened Codex, I didn't have a vague idea. I had a complete PRD (Product Requirements Document). Every edge case thought through. Every config parameter defined.
I dumped the whole thing into Codex and... 30 minutes later, the bot was done. Autonomously built by the AI agent while I grabbed a beer.
spacexbt needed 3 hours. I needed 30 minutes.
But let's be real: I also spent 3 hours on that todo list beforehand. So in total? Same time. The difference is that I now have a detailed PRD that I can share, iterate on, and use as a foundation for improvements.
Now here's where I need to be transparent, because there's way too much bullshit in this space.
Yes, the bot works. It polls Polymarket trades every second, filters for large trades (2k+ USD), checks if the wallet has been inactive, and sends Discord alerts. Technically, it does exactly what it's supposed to do.

But no, this is not a money printer.
In its current state, the bot is very basic. Even if you improve it massively, add ML models, track PnL, whatever... it can only ever be a small decision-making aid. Not a crystal ball. Not alpha that makes you rich on autopilot.
I see too many people on social media claiming they made crazy money with bots like this. Maybe some did. But for every winner, there are 100 people who lost money by blindly trusting alerts. Don't be that person.
I want more honesty and transparency in the online world. Especially in crypto. Especially in AI. Especially where those two overlap.
So I'm sharing my complete PRD below. Not because it's perfect, but because:
You'll learn more by building your own bot (even if it's just prompting Claude Code or Codex) than by copy-pasting someone else's code
You can see exactly what goes into something like this
You can call me out if my approach is dumb
The bot will eventually become part of thethirdeye.xyz and be available to users there once it's properly fine-tuned. But for now, I want to document the journey publicly.
Quick shoutout to everyone who's been supportive since I launched thethirdeye.xyz
. The feedback, the engagement, the questions... it means a lot. Building in public is scary, but also incredibly rewarding when people actually give a shit.
If you want to follow along as I improve this bot and share more details, you know what to do. I'll be posting updates over the next days and weeks.
And yes, I would appreciate likes and shares. Not for the ego (okay, maybe a little), but because I genuinely believe we need more transparency in this space. The more people see real, honest content about what these tools can and cannot do, the better.
Let's go.
Below is the complete PRD I used. Feel free to use it, modify it, improve it. If you build something cool with it, let me know.
You can simply copy and paste the whole thing, dump it into Codex (or Claude), and get a working bot. It worked for me.
One bug I ran into that you should watch out for: The Polymarket API returns timestamps in Unix seconds, but JavaScript's Datenow() returns milliseconds. If you compare them directly, every trade gets filtered as "old". I've added explicit notes about this in the PRD below.
That's it. Now go build something. ❤️
# PRD: Polymarket Insider Tracker Bot (Discord Alerts, no UI)
Owner: YOU
Copyright: © thethirdeye.xyz - 2026
Target: AI Coding Agent (Codex, Claude Code, etc.)
## 1. Goal and Problem
We're building a background bot that continuously monitors Polymarket trades and detects "insider-style" activity:
- Focus: New or inactive wallets that suddenly place large trades
- Output: Discord Alerts (Embeds)
- No UI, no dashboard, no trading, no order automation
The bot should feel "live" through 1s ingestion, even though upstream is polled via HTTP.
## 2. Success Metrics
- Time-to-alert: < 3 seconds from trade timestamp (best effort)
- False positives: Low through Activity Gate and Cooldowns
- Uptime: 24/7 operation on server (systemd) intended
- Discord Spam: Under control through dedupe and cooldowns
## 3. Scope
### In Scope (MVP)
- 1s polling of Polymarket trades (global, all markets)
- Filter: Notional >= 2000 USD (CASH filter)
- Wallet Activity Gate: Only alert if wallet has "low activity"
- Dedupe: No double alerting on same trades
- Discord Webhook output with consistent embed layout
- Persistence: SQLite (recommended) or JSON state (minimal)
- Configuration via .env
### Out of Scope (MVP)
- Web UI, login, admin panel
- Telegram, X posting
- PnL tracking, portfolio, performance analytics
- ML models
- Onchain WebSocket event decoding
## 4. User Stories
1) As a user, I want to see in Discord when a previously quiet wallet suddenly enters a market with >= $2k
2) As a user, I want only few, strong alerts and no constant whale spam flood
3) As an operator, I want to configure the bot via env vars and run it as a service
## 5. Data Sources
MVP is based on Polymarket Data API:
- Trades Endpoint: GET {DATA_API_BASE}/trades
- Activity Endpoint: GET {DATA_API_BASE}/activity?user=0x...
Market Metadata Enrichment (optional):
- Gamma API: {GAMMA_API_BASE}/markets or /events
Note: Define endpoints as config, keep parameters easily adjustable.
## 6. Core Pipeline (High Level)
Loop every 1000ms:
**Step A: Fetch Trades (only "big trades")**
- Request: /trades with FilterType=CASH, FilterAmount=2000, limit=200-500
- Result: List of trades, sorted (typically newest first)
**Step B: Dedupe and Normalization**
- Dedupe Key: transactionHash + conditionId + side + proxyWallet (conservative)
- Normalize to internal Trade format
**Step C: Pre-Filters**
- Exclude categories (optional, configurable)
- Exclude obvious noise trades (optional)
**Step D: Wallet Activity Gate (critical)**
- For proxyWallet: Load Activity Summary for last N days
- Decide "low activity" or "active whale"
- Cache activity per wallet (TTL) to save API calls
**Step E: Detection and Alert Decision**
- MVP Detector: Low Activity Wallet + Large Trade
- Optional: z-score vs baseline, timing near close (don't implement if data missing)
**Step F: Discord Alert**
- Send Discord Embed
- Rate limit: Queue with 1 msg/sec
**Step G: Persist State**
- Store seen trades (dedupe)
- Store wallet stats cache (optional)
- Store alert cooldowns per wallet
## 7. Detectors (MVP Definition)
### Detector 1: Low Activity Wallet + Large Trade
Trigger when all conditions are met:
- trade.notional_usd >= 2000
- wallet_activity_30d_trades < ACTIVE_TRADES_30D_CUTOFF
- wallet_last_trade_ts is older than INACTIVE_DAYS or not present
- cooldown for wallet not active
Config Defaults:
- INACTIVE_DAYS = 30 (parameterizable later)
- ACTIVE_TRADES_30D_CUTOFF = 50
- WALLET_COOLDOWN_HOURS = 6
Output details:
- wallet
- side (BUY/SELL or YES/NO if available)
- market title + slug
- size, price, notional (if available)
- timestamp
- optional: unique markets lifetime estimate (if available via Activity)
## 8. Data Models (TypeScript Interfaces)
Define types centrally in src/types.ts.
Minimal Required Trade Fields (internal format):
- id: string (dedupe key)
- timestamp: number (unix milliseconds - see CRITICAL NOTE below)
- proxyWallet: string
- conditionId: string
- side: string
- outcome: string | null
- size: number | null
- price: number | null
- notionalUsd: number | null
- title: string | null
- slug: string | null
- transactionHash: string | null
- raw: unknown (optional for debug)
WalletActivitySummary:
- wallet: string
- windowDays: number
- tradesCount: number
- lastTradeTs: number | null
- uniqueMarketsCount: number | null
- winRateResolved: number | null (optional)
AlertPayload:
- type: "LOW_ACTIVITY"
- trade: Trade
- details: object (detector specific)
### CRITICAL: Timestamp Normalization Bug
The Polymarket API returns timestamps in Unix SECONDS (e.g., 1767824287).
JavaScript's Date.now() returns MILLISECONDS.
If you compare them directly, every trade will be filtered as "ancient" because
1767824287 (seconds) is way smaller than ~1767824287000 (milliseconds).
**FIX: Always normalize timestamps to milliseconds immediately after fetching:**
typescript
function normalizeTimestamp(ts: number): number {
// If timestamp is less than year 2100 in seconds, it's in seconds
// 4102444800 = Jan 1, 2100 in Unix seconds
if (ts < 4102444800) {
return ts * 1000; // Convert seconds to milliseconds
}
return ts; // Already in milliseconds
}
Apply this to every trade.timestamp right after parsing the API response.
### CRITICAL: Notional USD Calculation
The API may not always return notionalUsd directly. Calculate it yourself:
typescript
const notionalUsd = trade.size * trade.price;
Always do this calculation as a fallback if notionalUsd is missing or null.
## 9. Config (.env)
Create .env.example.
Required:
- DATA_API_BASE=https://data-api.polymarket.com
- DISCORD_WEBHOOK_URL=
- POLL_MS=1000
- MIN_NOTIONAL_USD=2000
Recommended:
- ACTIVITY_WINDOW_DAYS=30
- INACTIVE_DAYS=30
- ACTIVE_TRADES_30D_CUTOFF=50
- WALLET_COOLDOWN_HOURS=6
- DISCORD_RATE_LIMIT_MS=1000
- SQLITE_PATH=./polymarket-monitor.db
- LOG_LEVEL=info
- BACKFILL_MINUTES=10
Optional:
- GAMMA_API_BASE=https://gamma-api.polymarket.com
- EXCLUDED_CATEGORIES=Sports
- DEBUG_SAVE_RAW=false
## 10. Persistence
Recommended: SQLite via better-sqlite3 or sqlite3.
Minimum Tables:
- seen_trades(id TEXT PRIMARY KEY, ts INTEGER, wallet TEXT, conditionId TEXT, txHash TEXT)
- wallet_state(wallet TEXT PRIMARY KEY, last_alert_ts INTEGER, last_seen_ts INTEGER)
- kv_cache(key TEXT PRIMARY KEY, value TEXT, updated_ts INTEGER) (for Activity Cache)
Alternative (minimal):
- JSON files in ./data/ for seenTrades and walletState
- But SQLite is more stable for 24/7 operation
## 11. Module Structure (File Plan)
Build complete, runnable base with clear separation:
- src/index.ts: main loop, boot, graceful shutdown
- src/config.ts: env parsing, defaults, validation
- src/api.ts: http client, fetchTrades, fetchActivity
- src/database.ts: sqlite init, dedupe store, wallet state store
- src/filters.ts: category filter, size filter
- src/detection.ts: runDetections(trade) -> AlertPayload[], detectorLowActivity(trade)
- src/enrichment.ts: optional market metadata caching
- src/discord.ts: queue, embed builder, send webhook
- src/types.ts: TypeScript interfaces
- src/utils.ts: sleep, time, retry with backoff, hashing keys, normalizeTimestamp
Non-src:
- .env.example
- package.json scripts: build, start, dev
- README.md quickstart
## 12. Error Handling and Robustness
- API Errors: retry with exponential backoff (max 3), then skip cycle
- Rate limits: respect, optional adaptive poll (fallback 2s)
- Memory: seenTrades in DB, not only in RAM
- Graceful shutdown: SIGINT/SIGTERM flush queue, close DB
## 13. Observability
Console Logs:
- Boot: Config summary (without secrets)
- Poll cycle: fetched, deduped, filtered, checked, alerted counts
- Alerts: one line summary + trade id
- Errors: endpoint, status code, message
Optional: write logs to file via process manager (systemd journal is enough)
## 14. Local Run and Deployment
Local:
- npm install
- cp .env.example .env
- npm run dev or npm start
Server (later, not MVP code task):
- systemd service file
- env file on server
- restart=always
## 15. Acceptance Criteria (Definition of Done)
Deliverables:
1) Repo starts with npm start without crash
2) Poll loop runs every 1s and logs poll stats
3) Dedupe prevents double processing of same trades
4) Activity Gate is applied per new wallet, with cache
5) On trigger, a Discord Embed is sent
6) Cooldown prevents repeated alerts per wallet within set hours
7) .env.example present and README describes setup
## 16. Activity Endpoint Parameters
For the /activity endpoint, use these parameters:
- type=TRADE (to get trade activity specifically)
- start=[unix timestamp] (to limit the time window)
- limit=100 (adjust as needed)
- sortDirection=DESC (newest first)
This ensures your "low activity" gate actually works correctly.# PRD: Polymarket Insider Tracker Bot (Discord Alerts, no UI)
Owner: YOU
Copyright: © thethirdeye.xyz - 2026
Target: AI Coding Agent (Codex, Claude Code, etc.)
## 1. Goal and Problem
We're building a background bot that continuously monitors Polymarket trades and detects "insider-style" activity:
- Focus: New or inactive wallets that suddenly place large trades
- Output: Discord Alerts (Embeds)
- No UI, no dashboard, no trading, no order automation
The bot should feel "live" through 1s ingestion, even though upstream is polled via HTTP.
## 2. Success Metrics
- Time-to-alert: < 3 seconds from trade timestamp (best effort)
- False positives: Low through Activity Gate and Cooldowns
- Uptime: 24/7 operation on server (systemd) intended
- Discord Spam: Under control through dedupe and cooldowns
## 3. Scope
### In Scope (MVP)
- 1s polling of Polymarket trades (global, all markets)
- Filter: Notional >= 2000 USD (CASH filter)
- Wallet Activity Gate: Only alert if wallet has "low activity"
- Dedupe: No double alerting on same trades
- Discord Webhook output with consistent embed layout
- Persistence: SQLite (recommended) or JSON state (minimal)
- Configuration via .env
### Out of Scope (MVP)
- Web UI, login, admin panel
- Telegram, X posting
- PnL tracking, portfolio, performance analytics
- ML models
- Onchain WebSocket event decoding
## 4. User Stories
1) As a user, I want to see in Discord when a previously quiet wallet suddenly enters a market with >= $2k
2) As a user, I want only few, strong alerts and no constant whale spam flood
3) As an operator, I want to configure the bot via env vars and run it as a service
## 5. Data Sources
MVP is based on Polymarket Data API:
- Trades Endpoint: GET {DATA_API_BASE}/trades
- Activity Endpoint: GET {DATA_API_BASE}/activity?user=0x...
Market Metadata Enrichment (optional):
- Gamma API: {GAMMA_API_BASE}/markets or /events
Note: Define endpoints as config, keep parameters easily adjustable.
## 6. Core Pipeline (High Level)
Loop every 1000ms:
**Step A: Fetch Trades (only "big trades")**
- Request: /trades with FilterType=CASH, FilterAmount=2000, limit=200-500
- Result: List of trades, sorted (typically newest first)
**Step B: Dedupe and Normalization**
- Dedupe Key: transactionHash + conditionId + side + proxyWallet (conservative)
- Normalize to internal Trade format
**Step C: Pre-Filters**
- Exclude categories (optional, configurable)
- Exclude obvious noise trades (optional)
**Step D: Wallet Activity Gate (critical)**
- For proxyWallet: Load Activity Summary for last N days
- Decide "low activity" or "active whale"
- Cache activity per wallet (TTL) to save API calls
**Step E: Detection and Alert Decision**
- MVP Detector: Low Activity Wallet + Large Trade
- Optional: z-score vs baseline, timing near close (don't implement if data missing)
**Step F: Discord Alert**
- Send Discord Embed
- Rate limit: Queue with 1 msg/sec
**Step G: Persist State**
- Store seen trades (dedupe)
- Store wallet stats cache (optional)
- Store alert cooldowns per wallet
## 7. Detectors (MVP Definition)
### Detector 1: Low Activity Wallet + Large Trade
Trigger when all conditions are met:
- trade.notional_usd >= 2000
- wallet_activity_30d_trades < ACTIVE_TRADES_30D_CUTOFF
- wallet_last_trade_ts is older than INACTIVE_DAYS or not present
- cooldown for wallet not active
Config Defaults:
- INACTIVE_DAYS = 30 (parameterizable later)
- ACTIVE_TRADES_30D_CUTOFF = 50
- WALLET_COOLDOWN_HOURS = 6
Output details:
- wallet
- side (BUY/SELL or YES/NO if available)
- market title + slug
- size, price, notional (if available)
- timestamp
- optional: unique markets lifetime estimate (if available via Activity)
## 8. Data Models (TypeScript Interfaces)
Define types centrally in src/types.ts.
Minimal Required Trade Fields (internal format):
- id: string (dedupe key)
- timestamp: number (unix milliseconds - see CRITICAL NOTE below)
- proxyWallet: string
- conditionId: string
- side: string
- outcome: string | null
- size: number | null
- price: number | null
- notionalUsd: number | null
- title: string | null
- slug: string | null
- transactionHash: string | null
- raw: unknown (optional for debug)
WalletActivitySummary:
- wallet: string
- windowDays: number
- tradesCount: number
- lastTradeTs: number | null
- uniqueMarketsCount: number | null
- winRateResolved: number | null (optional)
AlertPayload:
- type: "LOW_ACTIVITY"
- trade: Trade
- details: object (detector specific)
### CRITICAL: Timestamp Normalization Bug
The Polymarket API returns timestamps in Unix SECONDS (e.g., 1767824287).
JavaScript's Date.now() returns MILLISECONDS.
If you compare them directly, every trade will be filtered as "ancient" because
1767824287 (seconds) is way smaller than ~1767824287000 (milliseconds).
**FIX: Always normalize timestamps to milliseconds immediately after fetching:**
typescript
function normalizeTimestamp(ts: number): number {
// If timestamp is less than year 2100 in seconds, it's in seconds
// 4102444800 = Jan 1, 2100 in Unix seconds
if (ts < 4102444800) {
return ts * 1000; // Convert seconds to milliseconds
}
return ts; // Already in milliseconds
}
Apply this to every trade.timestamp right after parsing the API response.
### CRITICAL: Notional USD Calculation
The API may not always return notionalUsd directly. Calculate it yourself:
typescript
const notionalUsd = trade.size * trade.price;
Always do this calculation as a fallback if notionalUsd is missing or null.
## 9. Config (.env)
Create .env.example.
Required:
- DATA_API_BASE=https://data-api.polymarket.com
- DISCORD_WEBHOOK_URL=
- POLL_MS=1000
- MIN_NOTIONAL_USD=2000
Recommended:
- ACTIVITY_WINDOW_DAYS=30
- INACTIVE_DAYS=30
- ACTIVE_TRADES_30D_CUTOFF=50
- WALLET_COOLDOWN_HOURS=6
- DISCORD_RATE_LIMIT_MS=1000
- SQLITE_PATH=./polymarket-monitor.db
- LOG_LEVEL=info
- BACKFILL_MINUTES=10
Optional:
- GAMMA_API_BASE=https://gamma-api.polymarket.com
- EXCLUDED_CATEGORIES=Sports
- DEBUG_SAVE_RAW=false
## 10. Persistence
Recommended: SQLite via better-sqlite3 or sqlite3.
Minimum Tables:
- seen_trades(id TEXT PRIMARY KEY, ts INTEGER, wallet TEXT, conditionId TEXT, txHash TEXT)
- wallet_state(wallet TEXT PRIMARY KEY, last_alert_ts INTEGER, last_seen_ts INTEGER)
- kv_cache(key TEXT PRIMARY KEY, value TEXT, updated_ts INTEGER) (for Activity Cache)
Alternative (minimal):
- JSON files in ./data/ for seenTrades and walletState
- But SQLite is more stable for 24/7 operation
## 11. Module Structure (File Plan)
Build complete, runnable base with clear separation:
- src/index.ts: main loop, boot, graceful shutdown
- src/config.ts: env parsing, defaults, validation
- src/api.ts: http client, fetchTrades, fetchActivity
- src/database.ts: sqlite init, dedupe store, wallet state store
- src/filters.ts: category filter, size filter
- src/detection.ts: runDetections(trade) -> AlertPayload[], detectorLowActivity(trade)
- src/enrichment.ts: optional market metadata caching
- src/discord.ts: queue, embed builder, send webhook
- src/types.ts: TypeScript interfaces
- src/utils.ts: sleep, time, retry with backoff, hashing keys, normalizeTimestamp
Non-src:
- .env.example
- package.json scripts: build, start, dev
- README.md quickstart
## 12. Error Handling and Robustness
- API Errors: retry with exponential backoff (max 3), then skip cycle
- Rate limits: respect, optional adaptive poll (fallback 2s)
- Memory: seenTrades in DB, not only in RAM
- Graceful shutdown: SIGINT/SIGTERM flush queue, close DB
## 13. Observability
Console Logs:
- Boot: Config summary (without secrets)
- Poll cycle: fetched, deduped, filtered, checked, alerted counts
- Alerts: one line summary + trade id
- Errors: endpoint, status code, message
Optional: write logs to file via process manager (systemd journal is enough)
## 14. Local Run and Deployment
Local:
- npm install
- cp .env.example .env
- npm run dev or npm start
Server (later, not MVP code task):
- systemd service file
- env file on server
- restart=always
## 15. Acceptance Criteria (Definition of Done)
Deliverables:
1) Repo starts with npm start without crash
2) Poll loop runs every 1s and logs poll stats
3) Dedupe prevents double processing of same trades
4) Activity Gate is applied per new wallet, with cache
5) On trigger, a Discord Embed is sent
6) Cooldown prevents repeated alerts per wallet within set hours
7) .env.example present and README describes setup
## 16. Activity Endpoint Parameters
For the /activity endpoint, use these parameters:
- type=TRADE (to get trade activity specifically)
- start=[unix timestamp] (to limit the time window)
- limit=100 (adjust as needed)
- sortDirection=DESC (newest first)
This ensures your "low activity" gate actually works correctly.>1.2K subscribers
>1.2K subscribers
Share Dialog
Share Dialog
1 comment
How I One-Shot a Polymarket Insider Tracker Bot With Codex (Full PRD Inside) Want to track possible insiders? Copy the code in the blog and go for it!