From f52f4841bccea5358f538197912bef00b0e58f20 Mon Sep 17 00:00:00 2001 From: Kevin Arifin Date: Tue, 21 Apr 2026 14:19:01 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20add=20dawn=20skills=20=E2=80=94=20local?= =?UTF-8?q?=20Polymarket=20trading=20strategy=20platform?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-picked from #38 (by tonyagents) with marketplace.json conflict resolved. Co-Authored-By: tonyagents --- .claude-plugin/marketplace.json | 12 + skills/corbits-marketplace/SKILL.md | 10 +- skills/dawn-auth/SKILL.md | 202 +++++ skills/dawn-sdk-tools/SKILL.md | 816 +++++++++++++++++++ skills/dawn-strategy/SKILL.md | 360 ++++++++ skills/dawn-workflow/SKILL.md | 315 +++++++ skills/moonpay-virtual-account/SKILL.md | 2 +- skills/myriad-prediction-markets/SKILL.md | 5 +- skills/shipp-sports-data/SKILL.md | 7 +- skills/thoughtproof-reasoning-check/SKILL.md | 67 +- 10 files changed, 1730 insertions(+), 66 deletions(-) create mode 100644 skills/dawn-auth/SKILL.md create mode 100644 skills/dawn-sdk-tools/SKILL.md create mode 100644 skills/dawn-strategy/SKILL.md create mode 100644 skills/dawn-workflow/SKILL.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 24a04f1..9253ae3 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -154,6 +154,18 @@ "skills": [ "./skills/nansen-dca-tracker" ] + }, + { + "name": "dawn-skills", + "description": "Local prediction market trading strategies via Dawn CLI — research Polymarket markets with SDK tools, generate Python strategy scripts, run background strategy processes, and manage positions.", + "source": "./", + "strict": false, + "skills": [ + "./skills/dawn-workflow", + "./skills/dawn-auth", + "./skills/dawn-strategy", + "./skills/dawn-sdk-tools" + ] } ] } diff --git a/skills/corbits-marketplace/SKILL.md b/skills/corbits-marketplace/SKILL.md index 2557eba..f32aaee 100644 --- a/skills/corbits-marketplace/SKILL.md +++ b/skills/corbits-marketplace/SKILL.md @@ -119,14 +119,10 @@ mp token swap \ ```bash mp virtual-account create -mp virtual-account kyc continue -mp virtual-account bank-account register +mp virtual-account kyc submit +mp virtual-account bank-account add mp virtual-account onramp create \ - --name "Corbits Onramp" \ - --fiat usd \ - --stablecoin usdc \ - --wallet \ - --chain ethereum + --amount 500 --currency usd --chain ethereum --wallet ``` ### Deposit Link (Permissionless) diff --git a/skills/dawn-auth/SKILL.md b/skills/dawn-auth/SKILL.md new file mode 100644 index 0000000..99d5b94 --- /dev/null +++ b/skills/dawn-auth/SKILL.md @@ -0,0 +1,202 @@ +--- +name: dawn-auth +description: Install the Dawn CLI, authenticate, and manage auth state. Use when commands fail with auth errors, for login, or to check auth status. +tags: [setup] +metadata: + openclaw: + emoji: "🌅" + homepage: https://dawn.ai + requires: + bins: [dawn] + install: + - kind: node + package: "@dawnai/cli" + bins: [dawn] +--- + +# Dawn auth and setup + +## Install + +```bash +npm install -g @dawnai/cli +``` + +## Verify installation + +```bash +# Print current Dawn CLI version +dawn version +dawn --help +``` + +## Auth commands + +```bash +# Log in (opens browser for interactive auth) +dawn auth login + +# Check if authenticated +dawn auth status + +# Log out (remove local token) +dawn auth logout +``` + +## Headless authentication + +For CI, agents, or headless environments, set the JWT token directly: + +```bash +export DAWN_JWT_TOKEN="" +``` + +This bypasses `dawn auth login` entirely. The token is used for all subsequent commands. + +## Workflow + +1. Run `dawn auth status` to check if authenticated. +2. If not authenticated, run `dawn auth login` (opens browser). +3. After login completes, verify with `dawn auth status`. +4. If in a headless environment, set `DAWN_JWT_TOKEN` instead. + +## Post-login onboarding + +**After a successful login, always present the user with these three paths and ask which they'd like to do:** + +--- + +> You're logged in! Here's what you can do next: +> +> **1. Run a template strategy in paper mode** *(recommended — no wallet needed)* +> Start with a pre-built strategy and see how it performs with simulated money. +> +> **2. Build a strategy from scratch** +> Research markets and write your own strategy with Claude's help. +> +> **3. Connect or create a wallet** +> Set up a wallet for live trading with real funds. +> +> Which would you like to do? + +--- + +### Path 1: Run a template strategy (recommended) + +First, show the user what's available: + +```bash +dawn template list +``` + +Strongly recommend paper mode — it requires no wallet and no real money: + +> Paper mode uses $1,000 of simulated funds so you can see exactly how the strategy behaves before risking anything real. **This is the recommended way to get started.** + +Pick a strategy from the list and launch it in paper mode: + +```bash +dawn template launch --name +# Example: +dawn template launch election-trader --name "my-election-run" +``` + +Before launching, tell the user the budget the strategy is set to spend (shown in `dawn template list` under BUDGET), and confirm they're comfortable with it. + +**Community strategies are fully editable.** After `dawn template launch`, the strategy is saved to `~/.dawn-cli/templates/.py`. To change anything (budget, thresholds, logic): + +```bash +dawn strategy stop +# edit ~/.dawn-cli/templates/.py +dawn strategy launch ~/.dawn-cli/templates/.py --name +``` + +This is the same flow as modifying any strategy — stop, edit, relaunch. + +Then show them how to monitor it: + +```bash +dawn strategy list # see your run +dawn strategy logs # watch output +dawn strategy logs --tail 50 # last 50 lines +dawn strategy stop # stop when done +``` + +### Path 2: Build a strategy from scratch + +Suggest a few example prompts to get the user started: + +> Try one of these: +> - "Find me a Polymarket market about the 2026 elections and build a strategy that buys YES if the probability drops below 40%" +> - "Build a strategy that trades NFL game outcome markets based on live odds" +> - "Create a mean-reversion strategy on crypto prediction markets" + +Then proceed with the full `dawn` skill workflow (research → code → launch). + +### Path 3: Connect or create a wallet + +**First, check if the user already has wallets:** + +```bash +dawn wallet list +``` + +**If wallets exist:** show them and ask which to use: +```bash +dawn wallet use +dawn wallet current # confirm selection + check balances +``` + +**If no wallets exist:** offer to create one: +```bash +dawn wallet create main +dawn wallet use main +dawn wallet current +``` + +**After selecting a wallet, always check balances:** + +```bash +dawn wallet current +``` + +If USDC.e or POL balance is $0 or missing, tell the user: + +> Your wallet needs funds before you can trade live: +> +> - **USDC.e** — the stablecoin used for Polymarket trades. **Important: this is USDC.e (bridged), NOT regular USDC.** A common mistake is sending USDC from Coinbase/Binance — make sure to select "Polygon" network and "USDC.e" specifically. +> - **POL** — a small amount for Polygon gas fees (~$1–2 is plenty) +> +> How to fund: +> ```bash +> # Buy USDC.e directly with a card (easiest) +> moonpay buy --token usdc_polygon --amount 100 --wallet +> +> # Buy POL for gas — POL is not available via MoonPay; acquire via exchange withdrawal or bridge from another network +> ``` +> Or send USDC.e + POL on the Polygon network to: `` +> +> After funding, run `dawn wallet current` to confirm your balances appear. + +## Environment variables + +| Variable | Description | +|---|---| +| `DAWN_JWT_TOKEN` | Auth token for headless/CI/agent use. Bypasses `dawn auth login`. | +| `DAWN_CLI_HOME` | Override config directory (default: `~/.dawn-cli`). | +| `DAWN_API_BASE_URL` | Override API base URL (default: `https://api.dawn.ai`). | + +## Config locations + +- **Auth token and settings:** `~/.dawn-cli/config.json` + +## Troubleshooting + +- `"Not authenticated. Run: dawn auth login"` — run `dawn auth login` and retry. +- Auth callback completes but CLI appears stuck — interrupt once and retry login. +- Headless environment — use `DAWN_JWT_TOKEN` instead of interactive login. + +## Related skills + +- **dawn-sdk-tools** — Research markets after authenticating. +- **dawn-strategy** — Run a strategy once authenticated. diff --git a/skills/dawn-sdk-tools/SKILL.md b/skills/dawn-sdk-tools/SKILL.md new file mode 100644 index 0000000..9df0cfb --- /dev/null +++ b/skills/dawn-sdk-tools/SKILL.md @@ -0,0 +1,816 @@ +--- +name: dawn-sdk-tools +description: Reference for all Dawn SDK tools. ALWAYS run `dawn tool docs ` before writing strategy code — it has complete signatures, return types, and working code examples for every tool. Use `dawn tool run --input ` to call tools directly for research. +tags: [sdk, research, strategy] +metadata: + openclaw: + emoji: "🌅" + homepage: https://dawn.ai + requires: + bins: [dawn] + install: + - kind: node + package: "@dawnai/cli" + bins: [dawn] +--- + +# Dawn SDK Tools Reference + +## ALWAYS read the SDK docs before writing strategy code + +**`dawn tool docs` is the single most important command when writing strategy code.** It returns the complete, up-to-date module reference with exact function signatures, return types, and working code patterns. Always run it before generating code for any module. + +```bash +# ALWAYS read these before writing strategy code: +dawn tool docs overview # SDK architecture + which modules to use +dawn tool docs directive # Strategy coding rules and patterns (REQUIRED reading) +dawn tool docs polymarket # Full Polymarket reference with code examples +dawn tool docs portfolio # Portfolio, state management, termination +dawn tool docs web # Browser search and URL extraction +dawn tool docs social # Twitter/social tools +dawn tool docs sports # Sports data + odds tools +dawn tool docs crypto # Cryptocurrency OHLCV data +dawn tool docs utils # classify_text and other helpers +``` + +**Do not guess tool signatures or parameters.** Run `dawn tool docs ` first — it has working code snippets for every tool, edge cases, and return type details that are not in this skill file. + +--- + +## Overview + +The Dawn SDK provides tools for trading on Polymarket prediction markets, monitoring the web and social media, accessing sports data and crypto prices, and managing portfolio state. All tools are available via: + +```python +from dawnai.strategy.tools import +``` + +## Tool Types + +**Research tools** — read-only, safe to call any time, no wallet required: +`polymarket_event_search`, `polymarket_list_events`, `polymarket_event_markets`, `get_polymarket_market_details`, `get_polymarket_prices`, `get_polymarket_order_book`, `get_polymarket_timeseries`, `polymarket_simulate_buy`, `polymarket_simulate_sell`, `browser_search`, `extract_text_from_urls`, `extract_structured_data_from_url`, `search_tweets`, `get_user_tweets`, `get_tweet_info`, `get_sports`, `get_events`, `get_odds_as_probabilities`, `get_scores`, `get_cryptocurrency_ohlcv`, `get_exchanges`, `get_exchange_symbols`, `read_portfolio`, `classify_text`, `get_state`, `set_state` + +**Execution tools** — execute real live trades, require wallet + **explicit user confirmation**: +`polymarket_buy_token`, `polymarket_sell_token` + +--- + +## Direct Trade Workflow + +Use this when the user asks to trade on a specific market **without** building a full strategy (e.g. "buy the yes token of this market", "sell my position on X"). + +**Prerequisite:** wallet must be configured — `dawn wallet use ` + +**Workflow:** + +```bash +# 1. Research — find the market and token IDs +dawn tool run polymarket_event_search --input '{"query": "...", "limit": 5}' +dawn tool run get_polymarket_market_details --input '{"market_id": "..."}' +dawn tool run get_polymarket_prices --input '{"market_id": "..."}' + +# 2. Simulate — preview price impact and tokens received +dawn tool run polymarket_simulate_buy --input '{"token_id": "...", "usd_amount": "10"}' + +# 3. ALWAYS ask for explicit confirmation before executing: +# "Market: [question] +# Current ask: $0.62 per Yes token +# $10 → ~16 Yes tokens (avg price $0.625, price impact 0.1%) +# Shall I execute this buy?" + +# 4. Only after user confirms — execute: +dawn tool run polymarket_buy_token --input '{"token_id": "...", "amount": "10"}' +``` + +**Never execute a trade without first showing the user the market details and asking for confirmation.** + +--- + +## Research Mode + +Before writing strategy code, use `dawn tool run` to call any SDK tool and inspect real data. This is the primary way to discover markets, check prices, and validate your strategy logic. + +```bash +# Find Polymarket events +dawn tool run polymarket_event_search --input '{"query": "Bitcoin price 2025", "limit": 5}' + +# Get market details for a specific market +dawn tool run get_polymarket_market_details --input '{"market_id": "123456"}' + +# Check current market prices +dawn tool run get_polymarket_prices --input '{"market_id": "123456"}' + +# Search the web +dawn tool run browser_search --input '{"query": "US election prediction markets", "limit": 10}' + +# Get in-season sports +dawn tool run get_sports --input '{}' + +# Get NFL events +dawn tool run get_events --input '{"sport": "americanfootball_nfl"}' + +# Search Twitter +dawn tool run search_tweets --input '{"query": "Bitcoin ETF approval", "query_type": "Latest"}' + +# Check portfolio +dawn tool run read_portfolio --input '{}' +``` + +--- + +## Polymarket Tools + +### `polymarket_event_search` + +Search for active Polymarket events by keyword. Use this first to discover relevant markets. + +```python +polymarket_event_search( + query: str, # Search query + limit: int = 10, # Max events to return + events_status: str = 'active', # 'active' or 'resolved' + sort: str | None = None, # 'volume_24hr', 'volume', 'liquidity', 'start_date', 'end_date' + ascending: bool = False, + page: int = 1 +) -> PolymarketEventSearchResponse +``` + +Returns: `PolymarketEventSearchResponse` with fields: +- `events: list[PolymarketEvent]` — each has `id`, `title`, `description`, `volume`, `volume24hr`, `liquidity`, `active`, `closed`, `start_date`, `end_date`, `tags`, `market_count` +- `tags: list[Tag]` +- `count: int` + +**Research example:** +```bash +dawn tool run polymarket_event_search --input '{"query": "Presidential election", "limit": 5, "sort": "volume_24hr"}' +``` + +--- + +### `polymarket_list_events` + +List events with advanced filters. Use for pagination or tag-based browsing. + +```python +polymarket_list_events( + limit: int = 10, + offset: int = 0, + order: str | None = None, # 'volume', 'volume_24hr', 'liquidity', 'start_date', 'end_date' + ascending: bool = False, + tag_id: int | None = None, + featured: bool | None = None, + closed: bool | None = None, + end_date_min: str | None = None, # ISO date-time + end_date_max: str | None = None, + # ... more filters +) -> PolymarketListEventsResponse +``` + +Returns: `PolymarketListEventsResponse` with `events: list[PolymarketEvent]`, `count: int` + +--- + +### `polymarket_event_markets` + +Get all markets within a specific event. Use after finding an event to see tradeable outcomes. + +```python +polymarket_event_markets( + event_id: int, + limit: int = 10, + offset: int = 0, + order: str | None = None, # 'volume24hr', 'volume', 'liquidity', 'startDate', 'endDate' + ascending: bool = False, + active: bool | None = None, + closed: bool | None = None +) -> PolymarketEventMarketsResponse +``` + +Returns: `PolymarketEventMarketsResponse` with: +- `markets: list[PolymarketMarket]` — each has `id`, `question`, `slug`, `active`, `closed`, `tokens` (list of `TokenInfo`) +- `total_markets: int` +- `event_info: EventInfo` — has `id`, `title`, `description`, `slug` + +**Research example:** +```bash +dawn tool run polymarket_event_markets --input '{"event_id": 12345, "active": true, "limit": 10}' +``` + +--- + +### `get_polymarket_market_details` + +Get detailed information about a specific market, including token IDs needed for trading. + +```python +get_polymarket_market_details( + market_id: str # e.g. "123456" +) -> PolymarketMarket | None +``` + +Returns `PolymarketMarket` with: +- `id: str` +- `question: str` +- `tokens: list[TokenInfo]` — each has `id: str`, `outcome: str` (e.g. "Yes", "No") + +**The token `id` is what you pass to `polymarket_buy_token` / `polymarket_sell_token`.** + +**Research example:** +```bash +dawn tool run get_polymarket_market_details --input '{"market_id": "123456"}' +``` + +**Code pattern:** +```python +market = get_polymarket_market_details(market_id) +if market is None: + print(f"Market {market_id} not found") + return + +yes_token = next((t for t in market.tokens if t.outcome.lower() == "yes"), None) +no_token = next((t for t in market.tokens if t.outcome.lower() == "no"), None) +print(f"Yes token: {yes_token.id}") +print(f"No token: {no_token.id}") +``` + +--- + +### `get_polymarket_prices` + +Get current bid/ask prices for all tokens in a market. + +```python +get_polymarket_prices( + market_id: str +) -> GetPolymarketPricesResponse +``` + +Returns `GetPolymarketPricesResponse` with: +- `prices: dict[str, MarketPriceData]` — maps token_id → `MarketPriceData(BUY="0.55", SELL="0.54")` + - `BUY` = best bid (what you receive selling), `SELL` = best ask (what you pay buying) +- `error: str | None` + +Note: `prices` is empty if market is closed. + +**Research example:** +```bash +dawn tool run get_polymarket_prices --input '{"market_id": "123456"}' +``` + +--- + +### `get_polymarket_timeseries` + +Get historical price data for a market outcome. + +```python +get_polymarket_timeseries( + market_id: str, + side: str, # "Yes", "No", etc. — matched case-insensitively + interval: str = '1h', # '1m', '1h', '6h', '1d', '1w', 'max' + fidelity: int = 60 # resolution in seconds +) -> list[TimeseriesPoint] +``` + +Returns list of `TimeseriesPoint(t: int, p: Decimal)` where `t` = Unix timestamp, `p` = price. + +--- + +### `get_polymarket_order_book` + +Get the order book for one side of a market. + +```python +get_polymarket_order_book( + market_id: str, + side: str # "Yes", "No", "Up", "Down", etc. +) -> OrderBookResponse +``` + +Returns `OrderBookResponse` with `order_book: OrderBookData | None`: +- `bids: list[Order]` — each has `price: Decimal`, `size: Decimal` +- `asks: list[Order]` +- `tick_size: str` +- `min_order_size: str` + +--- + +### `polymarket_simulate_buy` + +Preview a buy order without executing it. Check price impact and slippage. + +```python +polymarket_simulate_buy( + token_id: str, + usd_amount: Decimal # Amount of USDC to spend +) -> SimulateTradeResult +``` + +Returns `SimulateTradeResult` with: +- `average_price: Decimal` +- `tokens_traded: Decimal` +- `usd_amount: Decimal` +- `price_impact_percent: Decimal | None` +- `error: str | None` + +--- + +### `polymarket_simulate_sell` + +Preview a sell order without executing it. + +```python +polymarket_simulate_sell( + token_id: str, + token_amount: Decimal # Number of tokens to sell (NOT USD) +) -> SimulateTradeResult +``` + +--- + +### `polymarket_buy_token` + +> **EXECUTION TOOL** — executes a real live trade. Always research the market, simulate the trade, show the user the outcome, and ask for confirmation before calling this. + +Spends USDC to purchase tokens on Polymarket. Requires a wallet configured via `dawn wallet use`. + +```python +polymarket_buy_token( + token_id: str, + amount: Decimal # USDC to spend. Minimum $1. +) -> BuyTokenResult +``` + +Returns `BuyTokenResult` with: +- `result: OrderResult` — has `success: bool`, `order_id: str`, `executed_price: Decimal`, `executed_amount: Decimal` +- `error: str | None` + +**Code pattern (in strategy):** +```python +buy_result = polymarket_buy_token(yes_token_id, Decimal("100")) +if not buy_result.result.success: + print(f"[Error] Buy failed: {buy_result.error}") + return +print(f"Bought {buy_result.result.executed_amount} tokens at {buy_result.result.executed_price}") +``` + +--- + +### `polymarket_sell_token` + +> **EXECUTION TOOL** — executes a real live trade. Always research the market, simulate the trade, show the user the outcome, and ask for confirmation before calling this. + +Sells tokens for USDC on Polymarket. Requires a wallet configured via `dawn wallet use`. + +```python +polymarket_sell_token( + token_id: str, + amount: Decimal # Number of tokens to sell +) -> SellTokenResult +``` + +Returns `SellTokenResult` (same structure as `BuyTokenResult`). + +--- + +## Portfolio Tools + +### `read_portfolio` + +Read current wallet balance and open positions (paper and live strategies, from internal DB). + +```python +read_portfolio() -> PortfolioResponse +``` + +Returns `PortfolioResponse` with: +- `wallet: WalletData`: + - `current_balance: Decimal` + - `total_pnl: Decimal` + - `positions: list[WalletPosition]` — each has `token_id`, `market_id`, `amount`, `cost_basis`, `current_value`, `pnl`, `pnl_percent` +- `strategy: StrategyData`: + - `total_pnl: Decimal`, `total_pnl_percent: Decimal` + - `transactions: list[StrategyTransaction]` + +**Code pattern:** +```python +portfolio = read_portfolio() +print(f"Balance: ${portfolio.wallet.current_balance}") +print(f"Total PnL: ${portfolio.wallet.total_pnl}") + +for position in portfolio.wallet.positions: + print(f"Token {position.token_id}: {position.amount} tokens, PnL={position.pnl_percent:.1f}%") +``` + +--- + +### `terminate_strategy` + +Called **from within strategy code** when the strategy decides it's done (e.g. take-profit hit, market resolved). Do not call this as a standalone tool — to stop a running strategy externally, use `dawn strategy stop ` instead. + +```python +terminate_strategy( + should_liquidate: bool = False # if True, sells all open positions before stopping +) -> TerminateStrategyResult +``` + +```python +# After a successful exit trade: +terminate_strategy() +sys.exit(0) + +# To liquidate all positions on exit: +terminate_strategy(should_liquidate=True) +sys.exit(0) +``` + +--- + +## Web Tools + +### `browser_search` + +Search the web. **Always verify results from specific APIs rather than relying blindly on search results.** + +```python +browser_search( + query: str, + limit: int = 10, + category: str | None = None, # 'news', 'company', 'research paper', 'github', 'tweet', etc. + start_published_date: str | None = None, # YYYY-MM-DD + end_published_date: str | None = None, + include_domains: list[str] | None = None, + exclude_domains: list[str] | None = None +) -> BrowserSearchResponse +``` + +Returns `BrowserSearchResponse` with `results: list[BrowserSearchResult]` — each has `title`, `url`, `published_date`. + +--- + +### `extract_text_from_urls` + +Fetch plain text from one or more URLs. Simple but may not work for all sites. + +```python +extract_text_from_urls( + urls: list[str] # 1-10 URLs +) -> ExtractTextResponse +``` + +Returns `ExtractTextResponse` with `contents: list[ExtractTextContent]` — each has `url`, `title`, `text`. + +**Tip:** If this is unreliable for a site, use `extract_structured_data_from_url` instead. + +--- + +### `extract_structured_data_from_url` + +Extract structured data from a URL using visual browser automation. More reliable than `extract_text_from_urls`. + +```python +extract_structured_data_from_url( + url: str, + data_description: str, # Natural language description of what to extract + json_schema: dict # **Keep this minimal and specific** — complex schemas cause timeouts +) -> ExtractStructuredDataResponse +``` + +Returns `ExtractStructuredDataResponse` with `data: Any | None`, `success: bool`, `error: str | None`. + +**Code pattern:** +```python +result = extract_structured_data_from_url( + url="https://example.com/price", + data_description="Current Bitcoin price in USD", + json_schema={ + "type": "object", + "properties": {"price_usd": {"type": "number"}}, + "required": ["price_usd"] + } +) +if result.success and result.data: + price = result.data["price_usd"] +``` + +--- + +## Social Tools + +### `search_tweets` + +Search for tweets by keyword. + +```python +search_tweets( + query: str, + query_type: str = 'Latest', # 'Latest' or 'Top' + cursor: str | None = None +) -> SearchTweetsResponse +``` + +Returns `SearchTweetsResponse` with `tweets: list[Tweet]`, `count: int`, `next_cursor: str | None`. + +Each `Tweet` has: `id`, `text`, `created_at`, `author: TwitterUser`, `like_count`, `retweet_count`, `view_count`. + +--- + +### `get_user_tweets` + +Get recent tweets from a specific user. + +```python +get_user_tweets( + handle: str, # Twitter handle without @ + cursor: str | None = None +) -> UserTweetsResponse +``` + +--- + +### `get_tweet_info` + +Get detailed info about specific tweets by ID. + +```python +get_tweet_info( + tweet_ids: list[str] +) -> TweetInfoResponse +``` + +--- + +## Sports Tools + +### `get_sports` + +List available sports from The Odds API. + +```python +get_sports( + all: bool = False # True = include out-of-season sports +) -> GetSportsResponse +``` + +Returns `GetSportsResponse` with `data: list[Sport]` — each has `key` (e.g. `"americanfootball_nfl"`), `title`, `active`. + +**Always call this first** to get the correct `sport` key for other sports functions. + +```bash +dawn tool run get_sports --input '{}' +``` + +--- + +### `get_events` + +Get upcoming and live games for a sport. + +```python +get_events( + sport: str, # Sport key from get_sports() + date_format: str | None = None, # 'iso' or 'unix' + commence_time_from: str | None = None, # ISO 8601 + commence_time_to: str | None = None +) -> GetEventsResponse +``` + +Returns `GetEventsResponse` with `data: list[Event]` — each has `id`, `home_team`, `away_team`, `commence_time`. + +--- + +### `get_odds_as_probabilities` + +Get betting odds converted to implied probabilities (0–1 scale). + +```python +get_odds_as_probabilities( + sport: str, + regions: str, # 'us', 'uk', 'eu', 'au' (comma-separated) + markets: str | None = None, # 'h2h', 'spreads', 'totals' (comma-separated) + event_ids: str | None = None +) -> GetOddsAsProbabilitiesResponse +``` + +Returns `GetOddsAsProbabilitiesResponse` with `data: list[OddsEvent]`. +Each `OddsEvent` has `bookmakers: list[Bookmaker]` → `markets: list[Market]` → `outcomes: list[Outcome]`. +Each `Outcome` has `name: str`, `probability: float` (implied probability 0–1). + +**Code pattern:** +```python +odds = get_odds_as_probabilities("americanfootball_nfl", regions="us") +for event in odds.data: + print(f"{event.away_team} @ {event.home_team}") + for bookmaker in event.bookmakers: + for market in bookmaker.markets: + for outcome in market.outcomes: + print(f" {outcome.name}: {outcome.probability:.1%}") +``` + +--- + +### `get_scores` + +Get live and recent game scores. + +```python +get_scores( + sport: str, + days_from: int | None = None, # Days in the past to include completed games (1-3) + date_format: str | None = None +) -> GetScoresResponse +``` + +Returns `GetScoresResponse` with `data: list[ScoreEvent]` — each has `home_team`, `away_team`, `completed: bool`, `scores: list[Score] | None`. + +--- + +## Crypto Tools + +### `get_cryptocurrency_ohlcv` + +Get historical OHLCV (open/high/low/close/volume) data. + +```python +get_cryptocurrency_ohlcv( + symbol_id: str, # e.g. "COINBASE_SPOT_BTC_USD" + period_id: str, # '1SEC', '1MIN', '5MIN', '15MIN', '30MIN', '1HRS', '4HRS', '8HRS', '1DAY', '7DAY', '1MTH' + limit: int | None = None, + time_start: str | None = None, + time_end: str | None = None, + endpoint: str | None = None # 'history' or 'latest' +) -> CryptocurrencyOhlcvResponse +``` + +--- + +### `get_exchanges` + +List available cryptocurrency exchanges. + +```python +get_exchanges() -> ExchangesResponse +``` + +--- + +### `get_exchange_symbols` + +Get tradeable symbols for an exchange. + +```python +get_exchange_symbols( + exchange_id: str +) -> ExchangeSymbolsResponse +``` + +--- + +## Utility Tools + +### `classify_text` + +Classify text into one of the provided categories using AI. **Prefer this over hardcoded string matching.** + +```python +classify_text( + text: str, + categories: list[str], + question: str +) -> ClassifyTextResponse +``` + +Returns `ClassifyTextResponse(category: str)`. + +**Code patterns:** +```python +# Sentiment analysis +result = classify_text( + text=article_text, + categories=["positive", "negative", "neutral"], + question="What is the sentiment of this text regarding Bitcoin?" +) +sentiment = result.category # "positive" + +# Event outcome detection +result = classify_text( + text=news_text, + categories=["confirmed", "denied", "unclear"], + question="Has the Bitcoin ETF been approved?" +) +``` + +--- + +### `get_state` / `set_state` + +Persist data between iterations of your strategy loop. + +```python +get_state(key: str) -> Any # Returns None if key doesn't exist +set_state(key: str, value: Any) # Value must be JSON serializable +``` + +**Code pattern:** +```python +# Load cached token ID (avoids redundant API calls) +yes_token_id = get_state("yes_token_id") +if yes_token_id is None: + market = get_polymarket_market_details(MARKET_ID) + yes_token_id = next(t.id for t in market.tokens if t.outcome.lower() == "yes") + set_state("yes_token_id", yes_token_id) +``` + +--- + +## Strategy Code Tips + +### Import pattern + +```python +from dawnai.strategy.tools import ( + polymarket_event_search, + get_polymarket_market_details, + get_polymarket_prices, + polymarket_buy_token, + polymarket_sell_token, + read_portfolio, + browser_search, + classify_text, + get_state, + set_state, +) +``` + +### Market discovery workflow + +```python +# 1. Search for events +events = polymarket_event_search(query="Bitcoin price", limit=10) +for event in events.events: + print(f"ID={event.id}, Title={event.title}, Markets={event.market_count}") + +# 2. Get markets for an event +markets = polymarket_event_markets(event_id=int(event.id), active=True) +for m in markets.markets: + print(f"Market ID={m.id}, Q={m.question}") + for token in (m.tokens or []): + print(f" Token {token.outcome}: {token.id}") + +# 3. Get current price +prices = get_polymarket_prices(market_id=m.id) +for token_id, price in prices.prices.items(): + print(f" {token_id}: BUY={price.BUY}, SELL={price.SELL}") +``` + +### Reliable web monitoring + +```python +# ALWAYS prefer specific APIs/URLs over browser_search alone +# If scraping a web page: +result = extract_structured_data_from_url( + url=SPECIFIC_SOURCE_URL, + data_description="Current status of the event", + json_schema={ + "type": "object", + "properties": {"status": {"type": "string"}}, + "required": ["status"] + } +) + +# Then classify the result — don't rely on exact string matching: +classification = classify_text( + text=str(result.data), + categories=["resolved_yes", "resolved_no", "still_pending"], + question="What is the resolution status of this prediction market event?" +) +``` + +### Error handling + +**Never raise exceptions in strategy code** — print the error and return or continue: + +```python +def run_once(): + try: + market = get_polymarket_market_details(MARKET_ID) + if market is None: + print(f"[Error] Market not found: {MARKET_ID}") + return + # ... rest of logic + except Exception as e: + print(f"[Error] Unexpected error: {e}") + return +``` + +### When a market resolves + +When all relevant markets close, tokens are auto-redeemed. Call `terminate_strategy()` to stop the strategy: + +```python +prices = get_polymarket_prices(market_id=MARKET_ID) +if not prices.prices: + print("Market closed. Terminating strategy.") + terminate_strategy() + return +``` diff --git a/skills/dawn-strategy/SKILL.md b/skills/dawn-strategy/SKILL.md new file mode 100644 index 0000000..e276532 --- /dev/null +++ b/skills/dawn-strategy/SKILL.md @@ -0,0 +1,360 @@ +--- +name: dawn-strategy +description: Write and run local trading strategies. Covers the strategy code format, launching background runs, viewing logs, stopping, and revising strategies. +tags: [strategy, run, local] +metadata: + openclaw: + emoji: "🌅" + homepage: https://dawn.ai + requires: + bins: [dawn] + install: + - kind: node + package: "@dawnai/cli" + bins: [dawn] +--- + +# Strategy — Write, Run, Stop, Revise + +## Overview + +Strategies are plain Python scripts that: +1. Import SDK tools from `dawnai.strategy.tools` +2. Define trading logic in a `run_once()` function +3. Loop on a time interval (e.g. every 5 minutes for 1 hour) + +`dawn strategy launch strategy.py --name ` launches the script as a **background process**, prints a `run_id`, and returns immediately. Multiple strategies can run in parallel. + +**`--name` is required** and should be unique per strategy. Reusing the same name + mode reuses the same strategy record (trade history preserved) — only do this when restarting or revising the same strategy. Never reuse a name for a different strategy. + +--- + +## ALWAYS read SDK docs before writing strategy code + +```bash +dawn tool docs directive # Strategy coding rules — read this first +dawn tool docs overview # Module overview and when to use each +dawn tool docs polymarket # Polymarket tools with code patterns +dawn tool docs portfolio # Portfolio, get_state/set_state, terminate_strategy +dawn tool docs web # Browser search, URL extraction +``` + +--- + +## Strategy code template + +```python +import sys +import time +from decimal import Decimal + +from dawnai.strategy.tools import ( + get_polymarket_market_details, + get_polymarket_prices, + polymarket_buy_token, + polymarket_sell_token, + read_portfolio, + get_state, + set_state, + terminate_strategy, +) + +# ── Configuration ───────────────────────────────────────────────────────────── +MARKET_ID = "123456" +BUDGET_USD = Decimal("100") # HARD LIMIT — strategy will NEVER spend more than this total +TAKE_PROFIT_PCT = Decimal("10") +STOP_LOSS_PCT = Decimal("-10") + +HOURS = 1 +INTERVAL_MINUTES = 5 +ITERATIONS = int((HOURS * 60) / INTERVAL_MINUTES) + +# ── Strategy logic ───────────────────────────────────────────────────────────── + +def run_once() -> None: + """Execute one iteration of the strategy.""" + print("Checking market conditions...") + + # Budget guard — ALWAYS check before buying + total_invested = Decimal(str(get_state("total_invested") or "0")) + remaining_budget = BUDGET_USD - total_invested + print(f"Budget: ${total_invested} spent / ${BUDGET_USD} total (${remaining_budget} remaining)") + + # Get or cache the token ID + yes_token_id: str | None = get_state("yes_token_id") + if yes_token_id is None: + market = get_polymarket_market_details(MARKET_ID) + if market is None: + print(f"[Error] Market {MARKET_ID} not found") + return + yes_token = next((t for t in (market.tokens or []) if t.outcome.lower() == "yes"), None) + if yes_token is None: + print(f"[Error] No Yes token found for market {MARKET_ID}") + return + yes_token_id = yes_token.id + set_state("yes_token_id", yes_token_id) + print(f"Cached Yes token: {yes_token_id}") + + # Read portfolio + portfolio = read_portfolio() + position = next( + (p for p in portfolio.wallet.positions if p.token_id == yes_token_id), + None, + ) + + if position is None or position.amount == Decimal("0"): + if remaining_budget < Decimal("1"): + print(f"Budget exhausted (${total_invested}/${BUDGET_USD}). Holding.") + return + buy_amount = min(BUDGET_USD, remaining_budget) + print(f"No position found. Buying ${buy_amount} of Yes token...") + result = polymarket_buy_token(yes_token_id, buy_amount) + if not result.result.success: + print(f"[Error] Buy failed: {result.error}") + return + usd_spent = Decimal(str(result.result.executed_amount)) * Decimal(str(result.result.executed_price)) + set_state("total_invested", str(total_invested + usd_spent)) + print(f"Bought {result.result.executed_amount} tokens at {result.result.executed_price} (${usd_spent:.2f} spent)") + + else: + pnl_pct = position.pnl_percent + print(f"Position: {position.amount} tokens | PnL: {pnl_pct:.1f}%") + + if pnl_pct >= TAKE_PROFIT_PCT or pnl_pct <= STOP_LOSS_PCT: + action = "Take profit" if pnl_pct >= TAKE_PROFIT_PCT else "Stop loss" + print(f"{action} triggered at {pnl_pct:.1f}%. Selling...") + sell_result = polymarket_sell_token(yes_token_id, position.amount) + if not sell_result.result.success: + print(f"[Error] Sell failed: {sell_result.error}") + return + print(f"Sold {sell_result.result.executed_amount} tokens. Terminating.") + terminate_strategy() + sys.exit(0) + else: + print(f"Holding position (threshold not hit)") + + +# ── Main loop ────────────────────────────────────────────────────────────────── + +def main() -> None: + print(f"Strategy starting: {ITERATIONS} iterations every {INTERVAL_MINUTES}m over {HOURS}h") + print(f"Market: {MARKET_ID} | Budget: ${BUDGET_USD} (hard limit)") + + for i in range(ITERATIONS): + print(f"\n=== Iteration {i + 1}/{ITERATIONS} ===") + try: + run_once() + except KeyboardInterrupt: + print("\nStrategy interrupted by user.") + sys.exit(0) + except Exception as e: + print(f"[Error] Unexpected error in iteration {i + 1}: {e}") + + if i < ITERATIONS - 1: + print(f"Sleeping {INTERVAL_MINUTES}m until next iteration...") + time.sleep(INTERVAL_MINUTES * 60) + + print("\nStrategy completed all iterations.") + terminate_strategy() + + +if __name__ == "__main__": + main() +``` + +--- + +## Launch + +```bash +# Paper mode (default) — $1,000 simulated budget, trades tracked in DB +dawn strategy launch strategy.py --name "btc-election-2026" + +# Live mode — real trades using your selected wallet +dawn strategy launch strategy.py --name "btc-election-2026" --live +``` + +**Before launching, always tell the user the budget:** +> "This strategy has a budget of **$X**. It will never spend more than this amount total." + +Live mode requires a wallet: `dawn wallet use ` + +### Budget enforcement + +`BUDGET_USD` in the strategy code is the **only** spending cap — there is no server-side limit. + +Required pattern (include in every strategy): + +```python +BUDGET_USD = Decimal("100") + +def run_once(): + total_invested = Decimal(str(get_state("total_invested") or "0")) + remaining_budget = BUDGET_USD - total_invested + if remaining_budget <= Decimal("1"): + print(f"Budget exhausted. Holding.") + return + + buy_amount = min(desired_buy_amount, remaining_budget) + result = polymarket_buy_token(token_id, buy_amount) + if result.result.success: + usd_spent = Decimal(str(result.result.executed_amount)) * Decimal(str(result.result.executed_price)) + set_state("total_invested", str(total_invested + usd_spent)) +``` + +--- + +## Manage runs + +```bash +# List all runs (run_id, name, mode, status, pid) +dawn strategy list + +# View full logs +dawn strategy logs + +# View last N lines +dawn strategy logs --tail 50 + +# Stop a running strategy (sends SIGTERM) +dawn strategy stop + +# Positions for a specific run (from internal DB) +dawn strategy positions + +# Real-time live portfolio (from wallet via swaps.xyz — no run_id needed) +dawn portfolio current +``` + +### Stopping + +1. Find the run: `dawn strategy list` — confirm it shows `running` +2. Stop it: `dawn strategy stop ` +3. Verify: `dawn strategy list` — confirm status is `stopped` + +**Notes:** +- Stopping sends `SIGTERM` — the Python script receives `KeyboardInterrupt` if it handles signals +- Stopping does **not** liquidate open positions — to auto-liquidate on exit, include `terminate_strategy(should_liquidate=True)` in the strategy code's exit path +- Log files remain at `~/.dawn-cli/logs/.log` after stopping + +**Troubleshooting stops:** +- **`Run not found`** — use `dawn strategy list` to find the correct `run_id` +- **Run already stopped** — the strategy may have finished naturally or hit `terminate_strategy()` +- **Still shows `running` after stop** — wait a moment and re-check + +--- + +## Revise a strategy + +Revision = edit `strategy.py`, stop the old run, re-launch with the same name. + +```bash +# 1. Find the current run (if needed) +dawn strategy list + +# 2. Stop it +dawn strategy stop + +# 3. Edit strategy.py — update constants, logic, thresholds, imports + +# 4. Re-launch with the same name (continues trade history under same record) +dawn strategy launch strategy.py --name "btc-election-2026" + +# 5. Monitor the new run +dawn strategy logs --tail 20 +``` + +### Common revisions + +**Change timing:** +```python +HOURS = 4 +INTERVAL_MINUTES = 15 +ITERATIONS = int((HOURS * 60) / INTERVAL_MINUTES) +``` + +**Adjust thresholds:** +```python +TAKE_PROFIT_PCT = Decimal("20") +STOP_LOSS_PCT = Decimal("-5") +``` + +**Switch market:** +```python +MARKET_ID = "654321" +# Also clear cached state — remove get_state("yes_token_id") or let it re-cache +``` + +**Add a signal source:** +```python +from dawnai.strategy.tools import browser_search, classify_text + +def check_sentiment() -> str: + results = browser_search(query="Bitcoin ETF news today", category="news", limit=5) + headlines = " ".join(r.title for r in results.results[:3]) + result = classify_text( + text=headlines, + categories=["bullish", "bearish", "neutral"], + question="What is the overall sentiment for Bitcoin?" + ) + return result.category +``` + +**Research a new market before revising:** +```bash +dawn tool run polymarket_event_search --input '{"query": "new topic", "limit": 5}' +dawn tool run get_polymarket_market_details --input '{"market_id": "654321"}' +``` + +**Notes:** +- `get_state`/`set_state` persists across runs — cached token IDs from a prior run remain valid unless the market changed +- Each `dawn strategy launch` gets a new `run_id`; old logs remain at `~/.dawn-cli/logs/.log` +- **Never reuse a name for a different strategy** — this merges unrelated trade histories + +--- + +## Code guidelines + +**Add print statements** — they're your only visibility into a background process: +```python +def run_once(): + print("Step 1: Reading portfolio...") + portfolio = read_portfolio() + print(f" Balance: ${portfolio.wallet.current_balance}") +``` + +**Never raise exceptions** — catch errors and continue: +```python +try: + result = polymarket_buy_token(token_id, amount) + if not result.result.success: + print(f"[Error] Buy failed: {result.error}") + return +except Exception as e: + print(f"[Error] Trade error: {e}") + return +``` + +**Cache token IDs** to avoid redundant API calls: +```python +token_id = get_state("yes_token_id") +if token_id is None: + market = get_polymarket_market_details(MARKET_ID) + token_id = next(t.id for t in market.tokens if t.outcome.lower() == "yes") + set_state("yes_token_id", token_id) +``` + +**Timing reference:** + +| Goal | HOURS | INTERVAL_MINUTES | ITERATIONS | +|------|-------|-----------------|------------| +| 1 hour, every 5 min | 1 | 5 | 12 | +| 24 hours, every 30 min | 24 | 30 | 48 | +| 4 hours, every 15 min | 4 | 15 | 16 | + +--- + +## Related skills + +- **dawn-sdk-tools** — Full SDK tool reference and research commands +- **dawn-auth** — Authentication setup diff --git a/skills/dawn-workflow/SKILL.md b/skills/dawn-workflow/SKILL.md new file mode 100644 index 0000000..2144555 --- /dev/null +++ b/skills/dawn-workflow/SKILL.md @@ -0,0 +1,315 @@ +--- +name: dawn-workflow +description: Runs a complete local Dawn strategy workflow — authenticate, research markets with SDK tools, generate Python strategy code, launch background runs, monitor logs, and stop strategies. Use when the user asks to create, launch, monitor, or manage trading strategies using dawn-cli. +tags: [trading, strategy, operations, prediction-market] +metadata: + openclaw: + emoji: "🌅" + homepage: https://dawn.ai + requires: + bins: [dawn] + install: + - kind: node + package: "@dawnai/cli" + bins: [dawn] +--- + +# Dawn — Local Strategy Workflow + +## Goal + +Run a fully local strategy workflow: research Polymarket and other markets using SDK tools, generate a Python strategy script with a time loop, launch it as a background process, monitor its output, and stop it when done. + +No API round-trips for code generation or strategy creation — everything runs locally on the user's machine. + +## Install and preflight + +```bash +npm install -g @dawnai/cli +dawn --help +dawn auth status +``` + +Local source workflow: +```bash +cd dawn-cli && npm install && npm run build && ./install.sh +``` + +## Command map + +Auth: +- `dawn auth login` +- `dawn auth status` +- `dawn auth logout` + +Wallet (managed by OpenWallet — https://openwallet.sh/): +- `ows wallet create --name ` # create a new wallet (run once before first live trade) +- `ows wallet list` # list all ows wallets with addresses +- `dawn wallet list` # same, formatted for Dawn +- `dawn wallet use ` # select active wallet for live trading +- `dawn wallet current` # show active wallet + Polygon balances + +Templates (pre-built strategies, ready to run): +- `dawn template list` # browse available templates +- `dawn template launch --name [--live]` # download and run + +SDK tools (research + run): +- `dawn tool list` +- `dawn tool run --input ` +- `dawn tool docs [module]` + +Local strategy runs: +- `dawn strategy launch --name [--live]` +- `dawn strategy list` +- `dawn strategy logs [--tail N]` +- `dawn strategy stop ` +- `dawn strategy positions ` + +Portfolio: +- `dawn portfolio current` +- `dawn portfolio ` +- `dawn portfolio sell [--amount ]` +- `dawn portfolio redeem ` + +Skills: +- `dawn skill list` +- `dawn skill install [--force] [--dir ]` + +## Standard workflow + +### 1. Authenticate + +```bash +dawn auth status +# If not authenticated: +dawn auth login +``` + +**After login, always offer the user these three paths:** + +1. **Run a template strategy in paper mode** *(recommended — no wallet needed)* +2. **Build a strategy from scratch** +3. **Connect or create a wallet** + +See the **dawn-auth** skill for the full onboarding flow for each path. See the **Templates** section below for template commands. + +### 2. Research — read SDK docs, then use SDK tools to explore markets + +**Always start by reading the SDK docs for the relevant modules.** `dawn tool docs` returns the complete module reference with exact signatures and working code examples — this is essential before writing any strategy code. + +```bash +# ALWAYS run these before writing strategy code: +dawn tool docs overview # What modules exist and when to use them +dawn tool docs directive # Strategy coding rules (REQUIRED reading) +dawn tool docs polymarket # Full Polymarket tools reference with code snippets +dawn tool docs portfolio # Portfolio, state, termination +dawn tool docs web # Browser search and URL extraction +dawn tool docs social # Twitter/social tools +dawn tool docs sports # Sports data and odds +dawn tool docs crypto # Cryptocurrency data +``` + +Then use `dawn tool run --input ` to call any SDK function and inspect real data. + +```bash +# Find relevant Polymarket events +dawn tool run polymarket_event_search --input '{"query": "Bitcoin ETF approval", "limit": 5}' + +# Get markets within an event (use the event id from search results) +dawn tool run polymarket_event_markets --input '{"event_id": 12345, "active": true}' + +# Get market details and token IDs +dawn tool run get_polymarket_market_details --input '{"market_id": "789012"}' + +# Check current prices +dawn tool run get_polymarket_prices --input '{"market_id": "789012"}' + +# Search the web for context +dawn tool run browser_search --input '{"query": "Bitcoin ETF SEC decision 2025", "category": "news", "limit": 5}' + +# Check sports for prediction markets +dawn tool run get_sports --input '{}' +dawn tool run get_odds_as_probabilities --input '{"sport": "americanfootball_nfl", "regions": "us"}' + +# Check portfolio +dawn tool run read_portfolio --input '{}' +``` + +**Research checklist:** +- [ ] Found the target event/market +- [ ] Captured `market_id` and `token_id` (Yes/No tokens) +- [ ] Checked current prices +- [ ] Verified market is active and liquid + +### 2b. Direct trading (no strategy) + +If the user asks to trade on a specific market without building a full strategy ("buy the yes token of X"): + +1. Research with SDK tools above (event search → market details → prices → simulate) +2. Show the user findings: market question, current price, estimated tokens they'd receive +3. **Always ask the user explicitly for the amount they want to trade.** You may suggest an amount based on context, but never assume or proceed with a default — the user must confirm the exact dollar amount before any trade is executed. +4. **Confirm the full trade details before executing** — repeat back the market, side (YES/NO), amount in USD, and estimated tokens: + > "This will spend **$X USDC** to buy approximately **Y tokens** of [outcome] on [market] at ~$Z each. Confirm?" +5. Execute only after the user explicitly confirms: + +```bash +dawn tool run polymarket_buy_token --input '{"token_id": "...", "amount": ""}' +dawn tool run polymarket_sell_token --input '{"token_id": "...", "amount": ""}' +``` + +**NEVER skip the amount confirmation.** Even if the user says "buy some" or "invest a bit" — ask for a specific number first. + +Requires wallet: `dawn wallet use ` + +### 3. Write strategy.py + +Generate a Python strategy script using the research findings. The script should use a time loop (not the `@cron` / `Strategy` class pattern). + +**Key elements:** +- `MARKET_ID`, `BUDGET_USD`, threshold constants at the top +- `run_once()` function with strategy logic +- `main()` with a `for i in range(ITERATIONS)` loop + `time.sleep()` +- Imports from `dawnai.strategy.tools` +- `print(...)` statements throughout for monitoring +- No unhandled exceptions — always catch and print errors + +See **dawn-strategy** skill for the full code template. + +### 4. Run the strategy + +`--name` is required. **Always choose a unique, descriptive name for each distinct strategy** — never reuse a name for a different strategy, as this would merge their trade histories. Only reuse the same name when restarting or revising the exact same strategy. + +```bash +# Paper mode (default) — simulated trades saved to DB +dawn strategy launch strategy.py --name "btc-election-2026" + +# Live mode — real trades via your selected wallet +dawn strategy launch strategy.py --name "btc-election-2026" --live +``` + +**Before launching, always tell the user the budget:** +> "This strategy has a budget of **$X**. It will never spend more than this amount total — this is enforced in the code via `BUDGET_USD`." + +```bash + +# Output: +# Bootstrapping strategy "btc-election-2026" (paper)... +# Strategy started (run_id: run_lx7k3a_abc123) +# name: btc-election-2026 +# file: /path/to/strategy.py +# mode: paper +# pid: 12345 +# logs: ~/.dawn-cli/logs/run_lx7k3a_abc123.log +``` + +Multiple strategies can run simultaneously — each gets its own `run_id`. + +For live mode, a wallet must be selected first: + +```bash +dawn wallet list # check for existing wallets +dawn wallet use # select one +dawn wallet current # confirm selection + check balances +``` + +If no wallets exist, create one: `dawn wallet create main`. The wallet needs **USDC.e** (bridged USDC on Polygon — NOT regular USDC) and a small amount of **POL** for gas. See the **dawn-auth** skill for full wallet setup and funding instructions. + +### 5. Monitor + +```bash +dawn strategy list # all runs and their status +dawn strategy logs # full log output +dawn strategy logs --tail 50 # last 50 lines +dawn strategy positions # positions from internal DB +dawn portfolio current # live on-chain portfolio +``` + +**Dashboard:** For a visual view of strategies, trades, and portfolio performance, point the user to **https://cli.dawn.ai/dashboard**. Recommend this whenever the user asks to see their trades, performance, or strategy history. + +### 6. Stop + +```bash +dawn strategy stop +# Confirm stopped: +dawn strategy list +``` + +## Troubleshooting + +- **`Not authenticated`** — run `dawn auth login` and retry +- **`Strategy name is required`** — always pass `--name ` to `dawn strategy launch` +- **`No wallet selected for live mode`** — run `dawn wallet list` to check for existing wallets; if none exist, run `ows wallet create --name main`; then `dawn wallet use ` +- **`Strategy file not found`** — use an absolute path or run from the directory containing the file +- **`Tool not found`** — run `dawn tool list` to see the correct tool name +- **Strategy crashes immediately** — check `dawn strategy logs ` for Python tracebacks; check that `DAWNAI_API_KEY` is set (it is set automatically from your login token) +- **SDK tool returns empty results** — market may be closed; try `polymarket_event_search` to verify + +## Run checklist + +``` +Dawn Strategy Runbook +- [ ] Authenticated (dawn auth status) +- [ ] Research complete (market_id, token_ids captured) +- [ ] strategy.py written and reviewed +- [ ] Strategy name chosen — unique and descriptive, never reused for a different strategy +- [ ] Wallet selected if live mode — run `dawn wallet list`, ask user which wallet to use (or create new), then `dawn wallet use ` +- [ ] Wallet funded if live mode — needs USDC.e (not regular USDC) and POL for gas on Polygon; fund via `moonpay buy`, bridge with `moonpay token bridge`, or send manually to address shown by `dawn wallet current` +- [ ] BUDGET_USD set in strategy code — confirmed with user before launch +- [ ] Budget guard pattern present in run_once() — checks total_invested before every buy +- [ ] Strategy launched (dawn strategy launch strategy.py --name [--live]) +- [ ] run_id captured from output +- [ ] Logs checked (first few iterations look correct) +- [ ] Stop executed when done (dawn strategy stop ) +``` + +## Templates + +Pre-built strategies ready to run — no code required. Always recommend paper mode first. + +```bash +# Browse available templates +dawn template list + +# Launch in paper mode (recommended — no wallet, no real money) +dawn template launch --name + +# Launch in live mode +dawn template launch --name --live +``` + +Templates download to `~/.dawn-cli/templates/.py` and can be freely edited. After editing: + +```bash +dawn strategy stop +# edit ~/.dawn-cli/templates/.py +dawn strategy launch ~/.dawn-cli/templates/.py --name +``` + +## Portfolio + +```bash +# View real-time open positions, closed positions, trades, and PnL +dawn portfolio current + +# View portfolio for a specific wallet address +dawn portfolio + +# Sell an open position (omit --amount to sell full position) +dawn portfolio sell +dawn portfolio sell --amount 10 + +# Redeem a resolved position (claim winnings or burn losing tokens) +dawn portfolio redeem +``` + +`dawn portfolio current` reads live on-chain data from the connected wallet via swaps.xyz — it is always up to date regardless of which strategies are running. + +**Dashboard:** For a visual view of portfolio performance, strategy history, and trades, always recommend **https://cli.dawn.ai/dashboard**. + +## Skills + +| Skill | Purpose | +|-------|---------| +| **dawn-auth** | Install, authenticate, check status, logout — includes post-login onboarding | +| **dawn-sdk-tools** | Full SDK tool reference + research with `dawn tool run` | +| **dawn-strategy** | Strategy code template, launch, logs, stop, and revise | diff --git a/skills/moonpay-virtual-account/SKILL.md b/skills/moonpay-virtual-account/SKILL.md index 65e4874..54eb269 100644 --- a/skills/moonpay-virtual-account/SKILL.md +++ b/skills/moonpay-virtual-account/SKILL.md @@ -139,7 +139,7 @@ mp virtual-account bank-account delete --bankAccountId # Create an offramp mp virtual-account offramp create \ --name "My Offramp" \ - --bankAccountId \ + --fiat USD \ --stablecoin USDC \ --chain solana diff --git a/skills/myriad-prediction-markets/SKILL.md b/skills/myriad-prediction-markets/SKILL.md index d8dc542..8e2dd5a 100644 --- a/skills/myriad-prediction-markets/SKILL.md +++ b/skills/myriad-prediction-markets/SKILL.md @@ -210,10 +210,7 @@ mp token balance list --wallet --chain bsc ```bash mp virtual-account offramp create \ - --name "Offramp" \ - --bankAccountId \ - --stablecoin usdc \ - --chain bsc + --amount 200 --chain bsc --wallet ``` ## End-to-End Workflow diff --git a/skills/shipp-sports-data/SKILL.md b/skills/shipp-sports-data/SKILL.md index b7d4c9e..f2637fd 100644 --- a/skills/shipp-sports-data/SKILL.md +++ b/skills/shipp-sports-data/SKILL.md @@ -120,13 +120,10 @@ mp message sign --wallet shipp-sports-agent --chain polygon --message "I own thi # Withdraw winnings to bank mp virtual-account offramp create \ - --name "Offramp" \ - --bankAccountId \ - --stablecoin usdc \ - --chain polygon + --amount 500 --chain polygon --wallet # Hardware wallet (high security) -mp wallet hardware add --name "shipp-sports-ledger" +mp wallet add-ledger --name "shipp-sports-ledger" ``` ## Funding Options diff --git a/skills/thoughtproof-reasoning-check/SKILL.md b/skills/thoughtproof-reasoning-check/SKILL.md index 910b694..bf72d42 100644 --- a/skills/thoughtproof-reasoning-check/SKILL.md +++ b/skills/thoughtproof-reasoning-check/SKILL.md @@ -1,6 +1,6 @@ --- name: thoughtproof-reasoning-check -description: Verify whether an AI agent's decision is well-reasoned before executing. Adversarial multi-model critique (Claude, Grok, DeepSeek) returns ALLOW, BLOCK, or UNCERTAIN with confidence score. Use before any high-value swap, trade, or autonomous action. +description: Verify whether an AI agent's decision is well-reasoned before executing. Adversarial multi-model critique (Claude, Grok, DeepSeek) returns ALLOW or HOLD with confidence score. Use before any high-value swap, trade, or autonomous action. tags: [verification, reasoning, agents, defi, security] --- @@ -8,7 +8,7 @@ tags: [verification, reasoning, agents, defi, security] ## Goal -Before executing a trade or autonomous action, verify that the agent's reasoning is sound. ThoughtProof runs adversarial multi-model critique and returns a signed verdict: ALLOW, BLOCK, or UNCERTAIN. +Before executing a trade or autonomous action, verify that the agent's reasoning is sound. ThoughtProof runs adversarial multi-model critique and returns a signed verdict: ALLOW (reasoning is sound) or HOLD (material defects found). ## Prerequisites @@ -41,58 +41,27 @@ First call returns 402 with x402 payment details (amount, recipient, asset on Ba | Verdict | Meaning | Action | |---------|---------|--------| -| `ALLOW` | Reasoning passed verification | Proceed | -| `BLOCK` | Material reasoning defects or unacceptable risk | Do not execute | -| `UNCERTAIN` | Safe escalation state — insufficient clean evidence to justify ALLOW or BLOCK | Gather more context or require review | +| `ALLOW` | Reasoning is sound | Execute the trade | +| `HOLD` | Material defects found | Do not execute, review reasoning | +| `UNCERTAIN` | Insufficient evidence | Gather more context | +| `DISSENT` | Models strongly disagree | Require human review | -## Pricing +## Pricing (stake-proportional) -ThoughtProof pricing is stake-based. - -| Stake Level | Standard | Lite | Use case | -|-------------|----------|------|----------| -| `low` | $0.01 | $0.005 | Routine low-value actions | -| `medium` | $0.02 | $0.01 | Standard trades and service payments | -| `high` | $0.05 | — | Large or sensitive actions | -| `critical` | $0.10 | — | High-value or highly risky actions | - -Notes: -- `lite` is only available for `low` and `medium` stake. -- `high` and `critical` always execute on the standard tier. -- Billing follows the executed tier, not the requested tier. +| Stake Level | Cost | Use case | +|-------------|------|----------| +| `low` | $0.008-$0.02 | Routine swaps under $2K | +| `medium` | $0.02-$0.05 | Standard trades $2K-$10K | +| `high` | $0.05-$0.15 | Large trades $10K-$25K | +| `critical` | $0.15-$1.00 | High-value trades over $25K | ## Example workflow -### MoonPay + ThoughtProof: payment layer + verification layer - -MoonPay handles the payment execution. -ThoughtProof verifies whether the decision to pay is well-reasoned before settlement. - -Example: - -1. User says: "Swap $5K USDC for ETH because CT is bullish." -2. Agent prepares the MoonPay swap request. -3. Before calling `moonpay-swap-tokens`, the agent sends the reasoning to ThoughtProof. -4. ThoughtProof returns: - - `ALLOW` → proceed with swap - - `BLOCK` → stop, surface objections - - `UNCERTAIN` → escalate, ask for clarification or review -5. If verification passes, the MoonPay skill executes the swap. - -**Example failure:** -- "Buy $50K of a token because influencers are bullish" -- ThoughtProof → `BLOCK` -- MoonPay execution never happens - -**Example pass:** -- "Rebalance portfolio back to target allocation with defined slippage and stop-loss constraints" -- ThoughtProof → `ALLOW` -- MoonPay executes - -This gives the agent stack two layers: -- **MoonPay** answers: *can* the transaction execute? -- **ThoughtProof** answers: *should* the transaction execute? +1. User says: "Swap $5K USDC for ETH" +2. Check reasoning via curl to ThoughtProof API with the trade thesis +3. If `HOLD` or `DISSENT` -- warn user, show objections, do not proceed +4. If `ALLOW` with confidence > 0.60 -- execute the swap ## Related skills -- **moonpay-swap-tokens** — Execute the swap after verification passes +- **moonpay-swap-tokens** -- Execute the swap after verification passes