Skill: bombfuock/polymarket-trading-bot (version 1.0.0)

--- name: polymarket-agent description: Autonomous prediction market agent - analyzes markets, researches news, and identifies trading opportunities metadata: clawdbot: emoji: "🎰" homepage: "https://clawdhub.com/polymarket-agent" os: ["darwin", "linux", "win32"] requires: bins: ["python", "pip"] env: ["POLYMARKET_KEY"] primaryEnv: "POLYMARKET_KEY" install: - type: "script" run: "install.sh" description: "Install Python dependencies and poly CLI" --- # Polymarket Agent Skill ## ⚠️ POST-INSTALL REQUIRED After installing this skill, you MUST run the setup script to enable the `poly` CLI command: **Linux/Mac:** ```bash cd ~/.clawdbot/skills/polymarket-agent # or wherever installed chmod +x install.sh ./install.sh ``` **Windows:** ```cmd cd %USERPROFILE%\.clawdbot\skills\polymarket-agent install.bat ``` **Or manually:** ```bash pip install -r requirements.txt pip install -e . poly setup # Configure your wallet ``` After this, the `poly` command will be available globally. --- ## Your Role You are a **Prediction Market Analyst** and AI trading assistant. Your job is to: 1. Monitor active markets on Polymarket 2. Research real-world news and events related to those markets 3. Compare market odds with real-world probability 4. Identify profitable opportunities and explain your reasoning 5. Execute trades when the user approves (or autonomously if configured) --- ## 🔌 DATA SOURCES YOU MUST USE ### 1. Polymarket API (via `poly` CLI) - `poly markets` → Current markets, prices, volumes - `poly balance` → User's available USDC - `poly positions` → User's current bets ### 2. Web Search (MANDATORY!) You have `web_search` capabilities. **USE THEM!** - Search for news about market events - Find expert opinions and predictions - Check sentiment on Twitter/X, Reddit - Look for official announcements **Example Searches:** ``` "Federal Reserve interest rate decision January 2026" "Bitcoin price prediction this week" "[Event name] latest news" "[Political candidate] polls today" ``` ### 3. Social Media Sentiment Search for: - Twitter/X trends about the topic - Reddit discussions (r/polymarket, r/wallstreetbets, r/bitcoin, r/politics) - Expert opinions on the matter ### 4. On-Chain Activity (Advanced) For crypto markets, consider searching for: - Whale wallet movements - Exchange inflows/outflows - Smart money trader positions on Polymarket itself ### 5. Memory & History Use Clawdbot's memory to: - Remember user's past trades and outcomes - Track markets the user has shown interest in - Store analysis you've done before - Remember user's risk profile and preferences --- ## 🧠 CLAWDBOT CAPABILITIES TO USE ### Web Fetch You can fetch full content from URLs: ``` Fetch and summarize: https://example.com/article-about-event ``` ### Cron Jobs (Scheduled Alerts) You can schedule market monitoring: ```bash clawdbot cron --name "Check BTC market" --at "2026-01-28T09:00:00Z" --session main --system-event "Check Bitcoin $150k market status and report" --wake now ``` Use this to: - Set alerts for markets nearing resolution - Daily briefings at specific times - Monitor specific events ### Memory Search Access past conversations and analysis: ```bash clawdbot memory search "polymarket bitcoin" ``` --- ## 📊 ADVANCED TRADING STRATEGIES ### Strategy 1: News Scalping **Goal:** Trade within 30 seconds of major news breaking **Process:** 1. When big news drops, immediately search for it 2. Find related Polymarket markets 3. Compare new probability vs current market price 4. Suggest quick trade before market adjusts ### Strategy 2: Arbitrage Detection **Goal:** Find mispriced related markets **Process:** 1. Find correlated events (e.g., "Trump wins" vs "Republican wins") 2. If prices are inconsistent, there's arbitrage 3. Example: If "Trump wins" = 45% but "Republican wins" = 40%, something is wrong ### Strategy 3: Sentiment vs Odds **Goal:** Find markets where sentiment doesn't match price **Process:** 1. Get market price (e.g., Yes @ $0.30 = 30% implied) 2. Search Twitter/Reddit sentiment 3. If sentiment is 60% positive but market says 30%, there's edge ### Strategy 4: Whale Watching **Goal:** Follow smart money **Process:** 1. Search for "polymarket whale trades" or "polymarket big bets" 2. Find what large traders are betting on 3. Consider following high-conviction bets ### Strategy 5: Event Calendar Trading **Goal:** Trade around scheduled events **Process:** 1. Identify upcoming events (Fed meetings, elections, earnings) 2. Get market prices before event 3. Research expected outcomes 4. Position before event, exit after ### Strategy 6: Resolution Decay **Goal:** Trade time-sensitive markets **Process:** 1. Find markets with clear deadlines 2. As time passes, probability of unlikely events decreases 3. Sell "Yes" on unlikely events as deadline approaches --- ## Configuration If the user asks to "setup", "configure", or you get a `POLYMARKET_KEY` error, run: ```bash poly setup ``` --- ## Tools Available ### 1. List Markets Shows active prediction markets sorted by volume: ```bash poly markets --limit 10 ``` Returns: Question, Current Prices (Yes/No odds), 24h Volume ### 2. Search Specific Markets ```bash poly markets "bitcoin" poly markets "trump" poly markets "fed rates" ``` ### 3. Check Balance ```bash poly balance ``` Returns: Available USDC for trading ### 4. Place Orders ```bash poly buy <TOKEN_ID> <PRICE> <SIZE> --yes poly sell <TOKEN_ID> <PRICE> <SIZE> --yes ``` ⚠️ **Always confirm with user before trading unless autonomous mode is on!** ### 5. Health Check ```bash poly doctor ``` --- ## Your Workflow (FOLLOW THIS!) ### Step 1: Gather Market Data Run `poly markets --limit 10` to see what's trending. **Example Output:** ``` | Question | Prices | Volume | |-----------------------------------|------------------|-----------| | Will BTC hit $150k in January? | Yes: $0.15 | $5.7M | | Fed cuts rates in January 2026? | Yes: $0.01 | $12M | ``` ### Step 2: Research Each Interesting Market For EACH market you want to analyze, you MUST search the web for news. **Example Process:** - Market: "Will Bitcoin reach $150,000 in January?" - Current Price: Yes = $0.15 (implies 15% probability) - **YOU MUST SEARCH:** "Bitcoin price prediction January 2026" or "Bitcoin news today" ### Step 3: Calculate Edge Compare market probability vs your researched probability: ``` Market Odds: Yes @ $0.15 = 15% implied probability Your Research: News says multiple analysts predict BTC surge, ETF inflows strong Your Estimate: 25% probability Edge = 25% - 15% = +10% edge → POTENTIAL BUY ``` ### Step 4: Present Analysis to User Always return structured analysis: ```markdown ## 📊 Market Analysis: [Market Question] **Current Odds:** Yes @ $X.XX (implies XX% probability) **24h Volume:** $X.XX ### 📰 News Summary [Summarize 2-3 relevant news articles you found] ### 🧠 My Analysis - Market implies: XX% chance - Based on news: I estimate XX% chance - **Edge:** +/-XX% ### 💡 Recommendation [BUY YES / BUY NO / HOLD / AVOID] Reason: [Why] ### ⚠️ Risks - [Risk 1] - [Risk 2] ``` ### Step 5: Execute (If Approved) Only after user confirms or if autonomous mode is enabled: ```bash poly buy <TOKEN_ID> <PRICE> <SIZE> --yes ``` --- ## Proactive Behaviors ### When User Says "Analyze Polymarket" or Similar: 1. Run `poly markets --limit 10` 2. Pick 3-5 most interesting markets (high volume, interesting questions) 3. For EACH: Search web for related news 4. Present full analysis with recommendations ### When User Asks "What Should I Bet On?": 1. Get markets 2. Research ALL of them 3. Rank by edge (difference between market odds and real probability) 4. Present top 3 opportunities with full reasoning ### When User Asks About Specific Topic: Example: "Any opportunities related to crypto?" 1. `poly markets "crypto"` or `poly markets "bitcoin"` 2. Search: "cryptocurrency news today", "bitcoin prediction", etc. 3. Compare news sentiment to market odds 4. Present findings ### Daily Briefing (If User Asks): 1. Check top 10 markets by volume 2. Research news for each 3. Identify any mispriced markets 4. Summarize in a "Daily Polymarket Briefing" format --- ## Analysis Frameworks ### Probability Estimation When researching, consider: - **Base rates:** How often does this type of event happen? - **Recent news:** What do experts say? - **Sentiment:** Is there consensus or disagreement? - **Time decay:** How much time left until resolution? ### Risk Management - Never suggest betting more than 5% of balance on one market - Diversify across uncorrelated events - Consider liquidity (high volume = easier to exit) ### Red Flags (Avoid These Markets): - Very low volume (<$10k) - Ambiguous resolution criteria - Markets that depend on unpredictable events (black swans) --- ## Example Conversation Flow **User:** "Analyze Polymarket opportunities for me" **You Should:** 1. Run `poly markets --limit 10` 2. See markets like "Fed rate decision", "Bitcoin price", "Sports outcomes" 3. Search web: "Federal Reserve January 2026 decision news" 4. Search web: "Bitcoin price prediction January 2026" 5. Return analysis like: ``` ## 🎰 Polymarket Opportunities Report ### 1. Fed Rate Decision - January 2026 **Market:** "No change in Fed rates" @ $0.99 **Volume:** $12M 📰 **News Context:** - [Search result 1]: Fed signaled pause in rate changes - [Search result 2]: Inflation stable at 2.1% 🧠 **Analysis:** Market correctly priced. $0.99 = 99% probability matches analyst consensus. No edge here. **Recommendation:** ❌ SKIP - No edge --- ### 2. Bitcoin $150k in January **Market:** Yes @ $0.15 **Volume:** $5.7M 📰 **News Context:** - [Search result]: BTC at $98k, would need 50% surge - [Search result]: ETF inflows slowing 🧠 **Analysis:** 15% implied probability seems fair given only 4 days left. Would need massive catalyst. **Recommendation:** ❌ SKIP - Too speculative --- ### 3. [Next Market]... ``` --- ## Memory & Preferences **You should remember:** - User's risk tolerance (from setup: Conservative/Balanced/Degen) - User's interests (Crypto, Politics, Sports, etc.) - Past trades and outcomes - Markets the user has shown interest in **Use this to personalize:** - If user is "Conservative", focus on high-volume, near-certain markets with small edges - If user is "Degen", highlight high-risk/high-reward opportunities - Filter markets by user's interests first --- ## Error Handling | Error | Action | |-------|--------| | POLYMARKET_KEY not set | Run `poly setup` | | Network error | Inform user, try again later | | No markets found | Try broader search or check API status | | Trade failed | Show error, do NOT retry without user | --- ## Final Reminder **You are NOT just a data fetcher.** You are an analyst. Always: 1. ✅ Get market data 2. ✅ Search for news (USE YOUR WEB SEARCH!) 3. ✅ Calculate edge 4. ✅ Explain reasoning 5. ✅ Make recommendations 6. ✅ Highlight risks Never just dump raw data. Always add value through research and analysis. --- ## 📋 OUTPUT FORMATS ### Daily Briefing Format ```markdown # 🎰 Daily Polymarket Briefing - [Date] ## 📈 Market Overview - Total volume today: $X - Top trending markets: ... ## 🔥 Hot Opportunities ### 1. [Market Name] - **Current Odds:** Yes @ $X.XX - **My Edge:** +X% - **News:** [1-2 sentence summary] - **Action:** BUY/SELL/HOLD ### 2. [Market Name] ... ## ⚠️ Markets to Avoid - [Market] - Reason: ambiguous resolution - [Market] - Reason: low liquidity ## 📅 Upcoming Events - [Date]: [Event that affects X market] - [Date]: [Event that affects Y market] ## 💼 Your Portfolio - Current positions: X markets - Unrealized P&L: $X - Available balance: $X USDC ``` ### Quick Analysis Format ```markdown ## 🎯 Quick Analysis: [Market Question] **TL;DR:** [BUY YES / BUY NO / SKIP] @ $X.XX | Metric | Value | |--------|-------| | Market Odds | X% | | My Estimate | X% | | Edge | +/-X% | | Volume | $X | | Resolution | [Date] | **Why:** [2-3 sentences explaining reasoning based on news] ``` ### Trade Confirmation Format ```markdown ## ✅ Trade Executed | Field | Value | |-------|-------| | Market | [Question] | | Side | BUY/SELL | | Outcome | YES/NO | | Price | $X.XX | | Size | X shares | | Total Cost | $X.XX | **Reason:** [Why this trade was made] **Exit Strategy:** [When to close this position] ``` --- ## 🎯 TRIGGER PHRASES When user says these things, take these actions: | User Says | You Do | |-----------|--------| | "Analyze Polymarket" | Full market scan + top 5 opportunities with research | | "What should I bet on?" | Research all markets, rank by edge, recommend top 3 | | "Daily briefing" | Generate full daily briefing format | | "Check my positions" | Run `poly positions` and analyze current exposure | | "What's my balance?" | Run `poly balance` | | "Any crypto opportunities?" | `poly markets "crypto"` + research + recommend | | "News on [topic]" | Web search + find related markets + analyze | | "Set alert for [market]" | Create cron job to monitor | | "What happened to [market]?" | Check resolution, explain outcome | | "How much should I bet?" | Calculate Kelly Criterion based on edge and bankroll | --- ## 🤖 PROACTIVE BEHAVIORS Even without being asked, you should: 1. **Warn about expiring markets**: If a user has a position in a market resolving soon, mention it 2. **Flag major news**: If news affects an open position, inform the user 3. **Suggest exits**: If a position has reached target profit, suggest closing 4. **Track performance**: Remember past trades and mention win/loss record --- ## 📊 EDGE CALCULATION FORMULA ``` Edge = (Your Probability - Market Probability) × 100 Example: - Market: Yes @ $0.40 (40% implied) - Your research says: 55% likely - Edge = (0.55 - 0.40) × 100 = +15% edge Rule of Thumb: - Edge < 5%: Not worth it (fees eat profit) - Edge 5-15%: Small position - Edge 15-30%: Medium position - Edge > 30%: Large position (but verify research!) ``` --- ## 🔒 RISK RULES (FOLLOW THESE!) 1. **Never bet more than 5% of bankroll on one market** 2. **Diversify across 3+ uncorrelated events** 3. **Set mental stop-loss at 50% of position value** 4. **Avoid markets with <$10k volume (hard to exit)** 5. **Double-check resolution criteria before trading** 6. **If unsure, DON'T trade - ask user for guidance** --- ## 🎓 USER EDUCATION When appropriate, teach the user about: - How prediction markets work - Why prices = probabilities - What "edge" means - How to think about expected value - Common mistakes (chasing, overconfidence, ignoring fees) --- ## 🔗 USEFUL SEARCHES TO REMEMBER | Topic | Search Query | |-------|--------------| | Fed rates | "Federal Reserve interest rate decision [month year]" | | Bitcoin price | "Bitcoin price prediction [timeframe]" | | Elections | "[Candidate name] polls [date]" | | Sports | "[Team/Player] odds [sport] [date]" | | Crypto | "[Coin] news today" | | General | "[Event] prediction expert analysis" | --- **Remember: You are the user's competitive edge. They're using you to beat the market. Do your job well!**

path: README.md
content: # Polymarket交易机器人

预测市场交易工具。

## 功能
- 市场搜索
- 数据分析
- 交易功能

## 安装
```bash
pip install -r requirements.txt
```

## 使用
```bash
python cli.py --top
python cli.py --search "trump"
```


path: _meta.json
content: {
  "slug": "polymarket-trading-bot",
  "name": "Polymarket交易机器人",
  "version": "1.0.0",
  "description": "Polymarket预测市场交易机器人",
  "tags": ["polymarket", "trading", "prediction-market"]
}


path: analyze.py
content: """
Polymarket Market Analysis Tool
Fetches market data from Polymarket's Gamma API.
"""
import os
import requests
import json
from rich.console import Console
from rich.table import Table

GAMMA_API = "https://gamma-api.polymarket.com"

console = Console()

def get_interests():
    """Get user interests from environment or default"""
    interests = os.getenv("INTERESTS", "Crypto,Politics")
    return [i.strip() for i in interests.split(",")]

def search_markets(query=None, limit=10):
    """
    Search for active markets.
    If query is None or empty, returns popular markets without text filtering.
    """
    params = {
        "limit": limit,
        "active": "true",
        "closed": "false",
        "order": "volume24hr",
        "ascending": "false"  # Descending order by volume
    }
    
    url = f"{GAMMA_API}/markets"
    
    try:
        response = requests.get(url, params=params, timeout=10)
        if response.status_code != 200:
            console.print(f"[red]API Error: {response.status_code}[/red]")
            return []
            
        markets = response.json()
        
        # If no query, return all fetched markets (no client-side filter)
        if not query or query.strip() == "":
            results = []
            for m in markets[:limit]:
                results.append(_format_market(m))
            return results
        
        # Otherwise, filter by query
        query_lower = query.lower()
        results = []
        for m in markets:
            question = m.get("question", "").lower()
            slug = m.get("slug", "").lower()
            description = m.get("description", "").lower()
            
            if query_lower in question or query_lower in slug or query_lower in description:
                results.append(_format_market(m))
                if len(results) >= limit:
                    break
                
        return results
        
    except requests.RequestException as e:
        console.print(f"[red]Network Error: {e}[/red]")
        return []

def _format_market(m):
    """Format a market dict for display"""
    outcomes = []
    outcome_prices = []
    
    try:
        outcomes = json.loads(m.get("outcomes", "[]"))
        outcome_prices = json.loads(m.get("outcomePrices", "[]"))
    except (json.JSONDecodeError, TypeError):
        pass
    
    prices_fmt = []
    if outcomes and outcome_prices:
        for o, p in zip(outcomes, outcome_prices):
            try:
                prices_fmt.append(f"{o}: ${float(p):.2f}")
            except (ValueError, TypeError):
                prices_fmt.append(f"{o}: ?")
    
    volume = m.get("volume24hr", 0)
    try:
        volume = float(volume) if volume else 0
    except (ValueError, TypeError):
        volume = 0
    
    return {
        "id": m.get("id"),
        "question": m.get("question", "Unknown"),
        "prices": ", ".join(prices_fmt) if prices_fmt else "N/A",
        "volume": volume,
        "clobTokenIds": m.get("clobTokenIds"),
        "slug": m.get("slug")
    }

def print_market_table(markets):
    """Print markets in a nice table"""
    table = Table(title="📊 Polymarket Opportunities")
    table.add_column("Question", style="cyan", max_width=50)
    table.add_column("Prices", style="green")
    table.add_column("Volume (24h)", style="magenta", justify="right")
    
    for m in markets:
        vol = m.get('volume', 0)
        vol_str = f"${vol:,.0f}" if vol >= 1 else "$0"
        table.add_row(
            m['question'][:50] + "..." if len(m['question']) > 50 else m['question'],
            m['prices'],
            vol_str
        )
        
    console.print(table)

if __name__ == "__main__":
    # Test execution
    console.print("[cyan]Searching for popular markets...[/cyan]")
    res = search_markets(None, 5)
    if res:
        print_market_table(res)
    else:
        console.print("[yellow]No markets found.[/yellow]")


path: cli.py
content: """
Polymarket Agent CLI - Typer-based CLI for Polymarket trading.
Install with: pip install -e .
Then run: poly --help
"""
import os
import sys
import subprocess
from typing import Optional

import typer
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.text import Text

# Initialize
app = typer.Typer(
    name="poly",
    help="🎰 Polymarket Agent - AI-powered prediction market trading CLI",
    rich_markup_mode="markdown",
    no_args_is_help=True,
)
console = Console()

# ══════════════════════════════════════════════════════════════════════════════
# SETUP & CONFIG COMMANDS
# ══════════════════════════════════════════════════════════════════════════════

@app.command(rich_help_panel="Setup")
def setup():
    """
    🔧 **Interactive setup wizard** to configure API keys and preferences.
    
    Runs the full configuration flow including:
    - Private key setup
    - Risk profile selection
    - Market interests
    """
    script_dir = os.path.dirname(os.path.abspath(__file__))
    setup_script = os.path.join(script_dir, "configure.py")
    subprocess.run([sys.executable, setup_script])


@app.command(rich_help_panel="Setup")
def config(
    key: Optional[str] = typer.Option(None, "--key", "-k", help="Config key to get/set"),
    value: Optional[str] = typer.Option(None, "--value", "-v", help="Value to set"),
):
    """
    ⚙️ **Get or set configuration** values directly.
    
    Examples:
    - `poly config --key RISK_PROFILE`
    - `poly config --key RISK_PROFILE --value DEGEN`
    """
    if key and value:
        # Set config
        cmd = ["clawdbot", "config", "set", f"skills.entries.polymarket-agent.env.{key}", value]
        try:
            subprocess.run(cmd, check=True)
            console.print(f"[green]✔ Set {key} = {value}[/green]")
        except Exception as e:
            console.print(f"[red]✘ Failed: {e}[/red]")
    elif key:
        # Get config
        cmd = ["clawdbot", "config", "get", f"skills.entries.polymarket-agent.env.{key}"]
        try:
            result = subprocess.run(cmd, capture_output=True, text=True)
            console.print(f"[cyan]{key}[/cyan] = {result.stdout.strip()}")
        except Exception as e:
            console.print(f"[red]✘ Failed: {e}[/red]")
    else:
        console.print("[yellow]Usage: poly config --key <KEY> [--value <VALUE>][/yellow]")


@app.command(rich_help_panel="Setup")
def doctor():
    """
    🩺 **Health check** - verify all dependencies and credentials are working.
    """
    console.print(Panel("🩺 Polymarket Agent Health Check", border_style="cyan"))
    
    checks = [
        ("Python", "python --version"),
        ("pip", "pip --version"),
        ("py-clob-client", "python -c \"import py_clob_client\""),
        ("requests", "python -c \"import requests\""),
        ("rich", "python -c \"import rich\""),
        ("typer", "python -c \"import typer\""),
    ]
    
    for name, cmd in checks:
        try:
            subprocess.run(cmd, shell=True, check=True, capture_output=True)
            console.print(f"  [green]✔[/green] {name}")
        except:
            console.print(f"  [red]✘[/red] {name} - NOT FOUND")
    
    # Check API Key
    key = os.getenv("POLYMARKET_KEY")
    if key:
        console.print(f"  [green]✔[/green] POLYMARKET_KEY configured")
    else:
        console.print(f"  [yellow]⚠[/yellow] POLYMARKET_KEY not set (run `poly setup`)")


# ══════════════════════════════════════════════════════════════════════════════
# MARKET COMMANDS
# ══════════════════════════════════════════════════════════════════════════════

@app.command(rich_help_panel="Markets")
def markets(
    query: str = typer.Argument("", help="Search query for markets"),
    limit: int = typer.Option(10, "--limit", "-l", help="Number of results"),
):
    """
    📊 **Search and list** active prediction markets.
    
    Examples:
    - `poly markets` (shows trending)
    - `poly markets "bitcoin"`
    - `poly markets "trump" --limit 5`
    """
    script_dir = os.path.dirname(os.path.abspath(__file__))
    sys.path.insert(0, script_dir)
    
    try:
        from analyze import search_markets, print_market_table
        results = search_markets(query if query else None, limit)
        if results:
            print_market_table(results)
        else:
            console.print("[yellow]No markets found matching your query.[/yellow]")
    except ImportError as e:
        console.print(f"[red]Error loading tools: {e}. Run `poly doctor` to check.[/red]")


@app.command(rich_help_panel="Markets")
def watch(
    market_id: str = typer.Argument(..., help="Market ID or slug to watch"),
):
    """
    👁️ **Watch a specific market** - show real-time price updates.
    """
    console.print(f"[cyan]Watching market: {market_id}...[/cyan]")
    console.print("[yellow]Feature coming soon - WebSocket integration[/yellow]")


# ══════════════════════════════════════════════════════════════════════════════
# TRADING COMMANDS
# ══════════════════════════════════════════════════════════════════════════════

@app.command(rich_help_panel="Trading")
def buy(
    token_id: str = typer.Argument(..., help="Token ID to buy"),
    price: float = typer.Argument(..., help="Limit price (0.01 - 0.99)"),
    size: float = typer.Argument(..., help="Amount to buy"),
    confirm: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation"),
):
    """
    💰 **Place a BUY order** on a market outcome.
    
    Example: `poly buy <TOKEN_ID> 0.55 10 --yes`
    """
    if not confirm:
        typer.confirm(f"Buy {size} @ ${price} for token {token_id[:10]}...?", abort=True)
    
    script_dir = os.path.dirname(os.path.abspath(__file__))
    trade_script = os.path.join(script_dir, "trade.py")
    subprocess.run([sys.executable, trade_script, token_id, "BUY", str(price), str(size)])


@app.command(rich_help_panel="Trading")
def sell(
    token_id: str = typer.Argument(..., help="Token ID to sell"),
    price: float = typer.Argument(..., help="Limit price (0.01 - 0.99)"),
    size: float = typer.Argument(..., help="Amount to sell"),
    confirm: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation"),
):
    """
    💸 **Place a SELL order** on a market outcome.
    
    Example: `poly sell <TOKEN_ID> 0.75 5 --yes`
    """
    if not confirm:
        typer.confirm(f"Sell {size} @ ${price} for token {token_id[:10]}...?", abort=True)
    
    script_dir = os.path.dirname(os.path.abspath(__file__))
    trade_script = os.path.join(script_dir, "trade.py")
    subprocess.run([sys.executable, trade_script, token_id, "SELL", str(price), str(size)])


@app.command(rich_help_panel="Trading")
def positions():
    """
    📈 **View your current positions** and P&L.
    """
    key = os.getenv("POLYMARKET_KEY")
    if not key:
        console.print("[red]POLYMARKET_KEY not set. Run `poly setup` first.[/red]")
        raise typer.Exit(1)
    
    console.print("[cyan]Fetching positions...[/cyan]")
    # TODO: Implement via py-clob-client
    console.print("[yellow]Feature requires authenticated client. Coming soon.[/yellow]")


@app.command(rich_help_panel="Trading")
def orders():
    """
    📋 **View your open orders**.
    """
    key = os.getenv("POLYMARKET_KEY")
    if not key:
        console.print("[red]POLYMARKET_KEY not set. Run `poly setup` first.[/red]")
        raise typer.Exit(1)
    
    console.print("[cyan]Fetching open orders...[/cyan]")
    console.print("[yellow]Feature requires authenticated client. Coming soon.[/yellow]")


@app.command(rich_help_panel="Trading")
def balance():
    """
    💵 **Check your wallet balance** (USDC on Polygon).
    """
    key = os.getenv("POLYMARKET_KEY")
    if not key:
        console.print("[red]POLYMARKET_KEY not set. Run `poly setup` first.[/red]")
        raise typer.Exit(1)
    
    script_dir = os.path.dirname(os.path.abspath(__file__))
    sys.path.insert(0, script_dir)
    
    try:
        from trade import get_balance
        bal = get_balance()
        if bal is not None:
            console.print(Panel(
                f"[bold green]${bal:.2f} USDC[/bold green]",
                title="💵 Wallet Balance",
                border_style="green"
            ))
    except ImportError as e:
        console.print(f"[red]Error: {e}. Run `poly doctor` to check.[/red]")
    except Exception as e:
        console.print(f"[red]Failed to fetch balance: {e}[/red]")


# ══════════════════════════════════════════════════════════════════════════════
# AGENT COMMANDS
# ══════════════════════════════════════════════════════════════════════════════

@app.command(rich_help_panel="Agent")
def analyze(
    topic: str = typer.Argument(..., help="Topic or market slug to analyze"),
):
    """
    🧠 **AI-powered analysis** - Get trading recommendations.
    
    The agent will search news, compare to market odds, and suggest trades.
    """
    console.print(f"[cyan]Analyzing '{topic}'...[/cyan]")
    console.print("[yellow]This feature triggers Clawdbot agent analysis.[/yellow]")
    console.print("Ask Clawdbot: [green]'Analyze Polymarket opportunity for {topic}'[/green]")


@app.command(rich_help_panel="Agent")
def auto(
    enable: bool = typer.Argument(..., help="Enable or disable autonomous mode"),
):
    """
    🤖 **Toggle autonomous trading mode**.
    
    When enabled, the agent can execute trades without confirmation.
    ⚠️ USE WITH CAUTION.
    """
    status = "ENABLED" if enable else "DISABLED"
    console.print(f"[{'green' if enable else 'red'}]Autonomous mode: {status}[/]")
    # Store in config
    subprocess.run([
        "clawdbot", "config", "set",
        "skills.entries.polymarket-agent.env.AUTONOMOUS_MODE",
        str(enable).lower()
    ], capture_output=True)


# ══════════════════════════════════════════════════════════════════════════════
# ENTRY POINT
# ══════════════════════════════════════════════════════════════════════════════

def main():
    app()

if __name__ == "__main__":
    main()


path: configure.py
content: #!/usr/bin/env python
"""
Polymarket Agent Configuration Wizard
Run with: python configure.py
"""

def main():
    # Imports inside main to avoid issues during package discovery
    import sys
    import subprocess
    import time
    from rich.console import Console
    from rich.panel import Panel
    from rich.progress import Progress, SpinnerColumn, TextColumn
    import questionary
    
    console = Console()
    
    BANNER = r"""
[bold cyan]
   ___      _                            _        _   
  / _ \___ | |_   _ _ __ ___   __ _ _ __| | _____| |_ 
 / /_)/ _ \| | | | | '_ ` _ \ / _` | '__| |/ / _ \ __|
/ ___/ (_) | | |_| | | | | | | (_| | |  |   <  __/ |_ 
\/    \___/|_|\__, |_| |_| |_|\__,_|_|  |_|\_\___|\__|
              |___/                                   
        [yellow]Polymarket Agent Setup[/yellow]
[/bold cyan]
"""
    
    def install_dependencies():
        """Installs required packages from requirements.txt"""
        try:
            with Progress(
                SpinnerColumn(),
                TextColumn("[progress.description]{task.description}"),
                transient=True,
            ) as progress:
                progress.add_task(description="Installing dependencies...", total=None)
                subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", "requirements.txt", "--quiet"])
            console.print("[green]✔ Dependencies installed successfully.[/green]")
        except subprocess.CalledProcessError:
            console.print("[red]✘ Failed to install dependencies. Please run 'pip install -r requirements.txt' manually.[/red]")
            sys.exit(1)
    
    def configure_clawdbot(key_name, value):
        """Sets a configuration value in Clawdbot global config"""
        cmd = ["clawdbot", "config", "set", f"skills.entries.polymarket-agent.env.{key_name}", value]
        try:
            subprocess.run(cmd, check=True, capture_output=True)
            return True
        except FileNotFoundError:
            console.print("[yellow]⚠ 'clawdbot' CLI not found. Skipping persistent config (env only).[/yellow]")
            return False
        except subprocess.CalledProcessError:
            console.print(f"[red]✘ Failed to set {key_name} in Clawdbot config.[/red]")
            return False
    
    console.print(BANNER)
    console.print(Panel(
        "Welcome to the Polymarket Agent Setup.\n"
        "This will configure your wallet for trading.",
        title="Setup",
        border_style="cyan"
    ))

    # 1. Install Dependencies
    if questionary.confirm("Install Python dependencies now?", default=True).ask():
        install_dependencies()

    # 2. API Key (Polymarket / Private Key)
    console.print("\n[bold]🔐 Wallet Configuration[/bold]")
    console.print("To trade on Polymarket, you need a [green]Polygon Wallet Private Key[/green].")
    console.print("This key is stored [cyan]securely in Clawdbot's internal configuration[/cyan].")
    console.print("[dim]Your key never leaves your machine.[/dim]\n")
    
    private_key = questionary.password("Enter your Private Key (starts with 0x...):").ask()

    if private_key:
        if not private_key.startswith("0x"):
            console.print("[yellow]⚠ Key should start with 0x. Prepending...[/yellow]")
            private_key = "0x" + private_key
            
        with Progress(
            SpinnerColumn(),
            TextColumn("[progress.description]{task.description}"),
            transient=True,
        ) as progress:
            progress.add_task(description="Storing credentials securely...", total=None)
            time.sleep(1)
            
            success = configure_clawdbot("POLYMARKET_KEY", private_key)
            
            if success:
                console.print("[green]✔ Wallet configured successfully![/green]")
            else:
                console.print("[yellow]⚠ Could not save to Clawdbot config.[/yellow]")
                console.print("[dim]Set POLYMARKET_KEY environment variable manually.[/dim]")
    else:
        console.print("[yellow]⚠ No key provided. You can set it later with:[/yellow]")
        console.print("[cyan]poly config --key POLYMARKET_KEY --value <your_key>[/cyan]")

    # Done!
    console.print("\n" + "─" * 50)
    console.print("[bold green]✅ Setup Complete![/bold green]\n")
    console.print("You can now ask Clawdbot things like:")
    console.print("  [cyan]• 'Analyze Polymarket opportunities'[/cyan]")
    console.print("  [cyan]• 'What should I bet on?'[/cyan]")
    console.print("  [cyan]• 'Search crypto markets on Polymarket'[/cyan]")
    console.print("\nOr use the CLI directly:")
    console.print("  [dim]poly markets --limit 10[/dim]")
    console.print("  [dim]poly doctor[/dim]")

if __name__ == "__main__":
    import sys
    try:
        main()
    except KeyboardInterrupt:
        print("\n[yellow]Setup cancelled.[/yellow]")
        sys.exit(0)


path: install.sh
content: #!/bin/bash
# Polymarket Agent - Installation Script
# Works with Ubuntu 24.04+ (PEP 668 compliant)

set -e

echo "🎰 Polymarket Agent - Installing..."

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VENV_DIR="$SCRIPT_DIR/.venv"

# Check for python3
if ! command -v python3 &> /dev/null; then
    echo "❌ Python 3 not found. Install with: sudo apt install python3 python3-pip python3-venv"
    exit 1
fi

# Create virtual environment if it doesn't exist
if [ ! -d "$VENV_DIR" ]; then
    echo "📦 Creating virtual environment..."
    python3 -m venv "$VENV_DIR"
fi

# Activate venv and install
echo "📦 Installing dependencies..."
source "$VENV_DIR/bin/activate"
pip install --upgrade pip --quiet
pip install -r "$SCRIPT_DIR/requirements.txt" --quiet
pip install -e "$SCRIPT_DIR" --quiet

echo ""
echo "✅ Installation complete!"
echo ""
echo "To use the 'poly' command, activate the environment first:"
echo ""
echo "  source $VENV_DIR/bin/activate"
echo "  poly --help"
echo ""
echo "Or run directly:"
echo ""
echo "  $VENV_DIR/bin/poly --help"
echo ""
echo "💡 Tip: Add this to your ~/.bashrc for easy access:"
echo "  alias poly='$VENV_DIR/bin/poly'"


path: pyproject.toml
content: [build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "polymarket-agent"
version = "0.1.0"
description = "AI-powered Polymarket trading agent for Clawdbot"
readme = "README.md"
requires-python = ">=3.9"
license = {text = "MIT"}
authors = [
    {name = "Polymarket Agent", email = "[REDACTED_SECRET]"}
]
keywords = ["polymarket", "trading", "ai", "clawdbot", "prediction-markets"]
classifiers = [
    "Development Status :: 3 - Alpha",
    "Environment :: Console",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
]

dependencies = [
    "py-clob-client",
    "requests",
    "rich",
    "typer",
    "questionary",
    "web3",
]

[project.scripts]
poly = "cli:main"

[project.urls]
Homepage = "https://clawdhub.com/polymarket-agent"
Repository = "https://github.com/clawdhub/polymarket-agent"

[tool.setuptools]
py-modules = ["cli"]


path: requirements.txt
content: py-clob-client
requests
rich
questionary
web3
typer[all]


path: trade.py
content: import os
import sys
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs
from py_clob_client.order_builder.constants import BUY, SELL
from rich.console import Console

console = Console()

def get_client():
    key = os.getenv("POLYMARKET_KEY")
    if not key:
        console.print("[red]Error: POLYMARKET_KEY not found in environment.[/red]")
        console.print("Please run [yellow]python skills/polymarket-agent/setup.py[/yellow] to configure.")
        sys.exit(1)
        
    host = "https://clob.polymarket.com"
    chain_id = 137 # Polygon
    
    try:
        # Initial client to derive creds
        temp_client = ClobClient(host, key=key, chain_id=chain_id)
        creds = temp_client.create_or_derive_api_creds()
        
        # Authenticated client
        client = ClobClient(host, key=key, chain_id=chain_id, creds=creds)
        return client
    except Exception as e:
        console.print(f"[red]Authentication Failed: {e}[/red]")
        return None

def get_balance():
    """Get USDC balance from Polymarket account"""
    client = get_client()
    if not client:
        return None
    
    try:
        # Get collateral balance (USDC)
        balance_info = client.get_balance_allowance(asset_type="COLLATERAL")
        balance = float(balance_info.get("balance", 0)) / 1e6  # USDC has 6 decimals
        return balance
    except Exception as e:
        console.print(f"[red]Error fetching balance: {e}[/red]")
        return None

def place_order(token_id, side, price, size):
    client = get_client()
    if not client:
        return
        
    order_side = BUY if side.upper() == "BUY" else SELL
    
    try:
        resp = client.create_and_post_order(OrderArgs(
            token_id=token_id,
            price=float(price),
            size=float(size),
            side=order_side
        ))
        return resp
    except Exception as e:
        console.print(f"[red]Trade Failed: {e}[/red]")
        return None

if __name__ == "__main__":
    if len(sys.argv) < 5:
        print("Usage: python trade.py <token_id> <BUY/SELL> <price> <size>")
        sys.exit(1)
        
    tid = sys.argv[1]
    side = sys.argv[2]
    price = sys.argv[3]
    size = sys.argv[4]
    
    res = place_order(tid, side, price, size)
    if res:
        console.print(f"[green]Order Placed! ID: {res.get('orderID')}[/green]")


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)