diff --git a/capacitr/SKILL.md b/capacitr/SKILL.md new file mode 100644 index 00000000..c0549c67 --- /dev/null +++ b/capacitr/SKILL.md @@ -0,0 +1,237 @@ +# Capacitr: Market Discovery Intelligence for AI Agents + +Capacitr turns any URL or text topic into a ranked set of tradeable markets across **Polymarket**, **HyperLiquid**, and **Deribit** — enriched with **Quotient AI edge scores** to surface mispriced opportunities. + +Drop in a news link, a tweet URL, a ticker, or a plain-text topic and get back structured prediction markets, perpetual futures, and options contracts — all ranked by relevance and edge potential. + +--- + +## 🚀 Access + +**Endpoint:** `https://app.capacitr.xyz/api/analyze-link` +**Method:** `POST` +**Payment:** `$0.05 USDC (text query)` or `$0.10 USDC (URL scan)` on Base per request (x402) +**Content-Type:** `application/json` + +No API key needed — pay per request using the x402 protocol. + +--- + +## 📥 Request + +```json +{ + "url": "https://reuters.com/article/oil-opec-cuts", + "query": "" +} +``` + +Pass either `url` (a scraped web page) or `query` (plain text topic). One is required. + +| Field | Type | Description | +|-------|------|-------------| +| `url` | string | Any public URL — news article, tweet, blog post | +| `query` | string | Free-text topic, ticker, or question | + +--- + +## 📤 Response + +```json +{ + "content": { + "summary": "OPEC+ agreed to deeper production cuts...", + "keywords": ["OPEC", "crude oil", "production cuts", "WTI"], + "entities": ["Saudi Arabia", "Russia", "WTI", "Brent"], + "tickers": ["OIL", "BRENTOIL", "CL"] + }, + "predictions": [ + { + "question": "Will WTI crude oil exceed $100 by end of 2025?", + "yesPrice": 0.34, + "noPrice": 0.66, + "volume": 1240000, + "slug": "wti-crude-oil-100-2025", + "quotientOdds": 0.51, + "spread": 0.17, + "spreadDirection": "q_higher", + "bluf": "Q models show undersupply risk from OPEC cuts is underpriced by market.", + "signalCount": 8, + "isQuotientSource": false + } + ], + "perps": [ + { + "asset": "BRENTOIL", + "coinId": "xyz:BRENTOIL", + "markPrice": "89.45", + "funding": "0.0001", + "volume24h": "12400000", + "openInterest": "4200000", + "source": "HyperLiquid (HIP-3)" + } + ], + "options": [ + { + "instrument": "BTC-27JUN25-100000-C", + "markPrice": "0.042", + "markIv": "58.3", + "openInterest": "1240", + "type": "CALL" + } + ] +} +``` + +--- + +## 🧠 Response Fields + +### `content` +Extracted intelligence from the input. + +| Field | Description | +|-------|-------------| +| `summary` | 2–3 sentence summary of the content | +| `keywords` | 5–8 keywords optimized for market search | +| `entities` | Named entities: people, companies, assets, events | +| `tickers` | Trading ticker symbols directly relevant to the content | + +### `predictions` — Polymarket + Quotient +Binary outcome prediction markets. Items with Quotient edge scores appear first. + +| Field | Description | +|-------|-------------| +| `question` | Market question | +| `yesPrice` | Current YES price (0–1) | +| `noPrice` | Current NO price (0–1) | +| `volume` | Total traded volume in USD | +| `slug` | Polymarket event slug for deep-linking | +| `quotientOdds` | Quotient AI forecast probability (if available) | +| `spread` | Absolute divergence between Q forecast and market price | +| `spreadDirection` | `q_higher` = market underprices YES, `q_lower` = overprices YES | +| `bluf` | Bottom Line Up Front — Quotient's one-line rationale | +| `signalCount` | Number of analyst signals backing the forecast | +| `isQuotientSource` | `true` if this market was surfaced by Quotient (not Polymarket search) | + +**Edge signals:** Items with `spread > 0.05` are flagged as mispriced. `q_higher` means BUY YES, `q_lower` means BUY NO. + +Trade link: `https://polymarket.com/event/{slug}` (or search by question if `isQuotientSource: true`) + +### `perps` — HyperLiquid Perpetuals +Perpetual futures matching the topic. Includes standard crypto perps and HIP-3 real-world asset perps (stocks, commodities, indices). + +| Field | Description | +|-------|-------------| +| `asset` | Display ticker (e.g. `BRENTOIL`, `BTC`, `AAPL`) | +| `coinId` | Full HyperLiquid coin identifier for trade URLs (e.g. `xyz:BRENTOIL`, `BTC`) | +| `markPrice` | Current mark price | +| `funding` | Current funding rate (annualized when multiplied by 8760) | +| `volume24h` | 24h notional volume in USD | +| `openInterest` | Open interest in USD | +| `source` | `HyperLiquid` or `HyperLiquid (HIP-3)` for real-world assets | + +Trade link: `https://app.hyperliquid.xyz/trade/{coinId}` + +**HIP-3 assets available:** `xyz:BRENTOIL`, `xyz:CL` (WTI), `xyz:GOLD`, `xyz:SILVER`, `xyz:NATGAS`, `xyz:SP500`, `xyz:XYZ100` (Nasdaq), `xyz:AAPL`, `xyz:TSLA`, `xyz:NVDA`, `xyz:MSFT`, `xyz:AMZN`, `xyz:META`, `xyz:PLTR`, `xyz:MSTR`, `xyz:GME`, `xyz:EUR`, `xyz:JPY` + +### `options` — Deribit Options +Options contracts for crypto assets (BTC, ETH, SOL, XRP) relevant to the topic. + +| Field | Description | +|-------|-------------| +| `instrument` | Deribit instrument name (e.g. `BTC-27JUN25-100000-C`) | +| `markPrice` | Mark price in BTC/ETH | +| `markIv` | Implied volatility % | +| `openInterest` | Open interest (contracts) | +| `type` | `CALL` or `PUT` | + +Trade link: `https://www.deribit.com/options/{currency}/{instrument}` + +--- + +## 💡 Usage Examples + +### From a news article +```bash +curl -X POST https://app.capacitr.xyz/api/analyze-link \ + -H "Content-Type: application/json" \ + -d '{"url": "https://reuters.com/article/some-opec-story"}' +``` + +### From a topic or ticker +```bash +curl -X POST https://app.capacitr.xyz/api/analyze-link \ + -H "Content-Type: application/json" \ + -d '{"query": "Federal Reserve rate cut September 2025"}' +``` + +### With x402 payment (via @x402/fetch) +```javascript +import { wrapFetchWithPayment } from '@x402/fetch'; +import { createWalletClient, http } from 'viem'; +import { base } from 'viem/chains'; +import { privateKeyToAccount } from 'viem/accounts'; + +const account = privateKeyToAccount(process.env.PRIVATE_KEY); +const walletClient = createWalletClient({ account, chain: base, transport: http() }); + +const fetchWithPayment = wrapFetchWithPayment(fetch, walletClient); + +const res = await fetchWithPayment('https://app.capacitr.xyz/api/analyze-link', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query: 'Tesla earnings miss expectations' }), +}); + +const markets = await res.json(); +``` + +### With Bankr agent +```bash +bankr agent prompt "Find tradeable markets for this article: https://bloomberg.com/news/articles/..." +# The agent will call the Capacitr skill, pay $0.10 USDC via x402 (URL) or $0.05 (text query), and return ranked markets +``` + +--- + +## 🔧 Agent Integration Pattern + +``` +User shares link or topic + ↓ +POST /api/analyze-link { url or query } + ↓ +Parse response: + - predictions with spread > 0.05 → flag as EDGE opportunity + - for each edge: log spreadDirection (q_higher = buy YES, q_lower = buy NO) + - perps → use coinId for trade URL construction + - options → use instrument for Deribit deep link + ↓ +Present to user: + - Top 3 EDGE predictions (sorted by spread desc) + - Relevant perps with funding rate context + - Options if crypto asset is involved +``` + +--- + +## ⚡ Pricing & Cost + +| Call type | Cost | Notes | +|-----------|------|-------| +| URL scan + market discovery | **$0.10 USDC** | Includes Jina scraping + Quotient enrichment | +| Text query + market discovery | **$0.05 USDC** | Quotient enrichment only, no scraping | + +Payment via x402 on Base. No subscription, no API key, no account required. + +**Why the difference?** URL calls include a Jina AI scrape pass (renders JS, extracts clean text) on top of the Quotient intelligence layer. Text queries skip the scrape step — faster and cheaper to run. + +--- + +## 🌐 Related Links + +- **App:** https://app.capacitr.xyz +- **Markets Scanner:** https://markets.capacitr.xyz +- **Docs:** https://docs.capacitr.xyz +- **Spec:** https://spec.capacitr.xyz diff --git a/capacitr/references/x402-integration.md b/capacitr/references/x402-integration.md new file mode 100644 index 00000000..a83d8eda --- /dev/null +++ b/capacitr/references/x402-integration.md @@ -0,0 +1,109 @@ +# x402 Integration Guide for Capacitr + +## Overview + +Capacitr uses the [x402 protocol](https://x402.org) to charge $0.01 USDC per API call on Base. +Agents that support x402 pay automatically — no API keys, no subscriptions. + +## How x402 Works + +1. Agent sends request to endpoint +2. If no payment proof: server responds `HTTP 402 Payment Required` with payment details in headers +3. Agent reads `X-Payment-Required` header, signs a payment on Base, retries with `X-Payment` header +4. Server validates payment, processes request, returns results + +## Payment Details + +``` +Network: Base (chain ID 8453) +Token: USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) +Amount: $0.10 (100000 USDC units, 6 decimals) for URL scans + $0.05 (50000 USDC units, 6 decimals) for text queries +Payee: 0x6503fB61705EB6B3C57EE1ab88a1a75A6eE01869 +``` + +## JavaScript / TypeScript + +```javascript +import { wrapFetchWithPayment } from '@x402/fetch'; +import { createWalletClient, http } from 'viem'; +import { base } from 'viem/chains'; +import { privateKeyToAccount } from 'viem/accounts'; + +const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY); +const walletClient = createWalletClient({ + account, + chain: base, + transport: http(), +}); + +const fetchWithPayment = wrapFetchWithPayment(fetch, walletClient); + +async function scanMarkets(input) { + const isUrl = input.startsWith('http'); + const body = isUrl ? { url: input } : { query: input }; + + const response = await fetchWithPayment( + 'https://app.capacitr.xyz/api/analyze-link', + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body), + } + ); + + if (!response.ok) throw new Error(`HTTP ${response.status}`); + return response.json(); +} + +// Usage +const markets = await scanMarkets('https://reuters.com/...'); +const edgeMarkets = markets.predictions.filter(p => p.spread > 0.05); +``` + +## Python + +```python +import httpx +from x402.client import X402Client # pip install x402 + +client = X402Client(private_key=os.environ["AGENT_PRIVATE_KEY"], chain="base") + +response = client.post( + "https://app.capacitr.xyz/api/analyze-link", + json={"query": "Federal Reserve rate decision"}, +) +data = response.json() + +# Edge opportunities +edges = [p for p in data["predictions"] if (p.get("spread") or 0) > 0.05] +for edge in edges: + direction = "BUY YES" if edge["spreadDirection"] == "q_higher" else "BUY NO" + print(f"{direction} +{round(edge['spread']*100)}% | {edge['question']}") +``` + +## Bankr Agent (natural language) + +``` +bankr agent prompt "Scan this article for tradeable markets and show me the best edge opportunities: https://..." +``` + +Bankr's agent automatically handles x402 payments from its embedded wallet. + +## Cost Estimation + +| Volume | Type | Monthly Cost | +|--------|------|-------------| +| 100 calls/day | URL scans | ~$300/month | +| 100 calls/day | Text queries | ~$150/month | +| 500 calls/day | URL scans | ~$1,500/month | +| 500 calls/day | Text queries | ~$750/month | + +## What's Included Per Call + +- URL scraping via Jina AI (handles JavaScript-rendered pages, paywalled content best-effort) +- LLM entity extraction (GPT-4o-mini) — tickers, entities, keywords +- Polymarket search across entities + keywords (up to 15 results) +- HyperLiquid perp + HIP-3 spot perp matching (stocks, commodities, indices) +- Deribit options chain for matched crypto assets +- Quotient AI mispricing scores and edge signals where available diff --git a/capacitr/scripts/capacitr-scan.sh b/capacitr/scripts/capacitr-scan.sh new file mode 100755 index 00000000..93bbc94d --- /dev/null +++ b/capacitr/scripts/capacitr-scan.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# capacitr-scan.sh — query the Capacitr market discovery API +# Usage: +# ./capacitr-scan.sh --url "https://reuters.com/article/..." +# ./capacitr-scan.sh --query "OPEC oil production cuts" +# +# Requires: curl, jq +# Payment: $0.01 USDC on Base via x402 (handled automatically by x402-capable clients) +# For direct curl calls (no x402): the endpoint currently accepts unauthenticated requests +# while x402 enforcement is being rolled out. + +ENDPOINT="https://app.capacitr.xyz/api/analyze-link" +URL_INPUT="" +QUERY_INPUT="" + +# Parse args +while [[ $# -gt 0 ]]; do + case $1 in + --url) URL_INPUT="$2"; shift 2 ;; + --query) QUERY_INPUT="$2"; shift 2 ;; + *) echo "Unknown arg: $1"; exit 1 ;; + esac +done + +if [[ -z "$URL_INPUT" && -z "$QUERY_INPUT" ]]; then + echo "Error: provide --url or --query" + exit 1 +fi + +# Build payload +if [[ -n "$URL_INPUT" ]]; then + PAYLOAD=$(jq -n --arg url "$URL_INPUT" '{"url": $url}') +else + PAYLOAD=$(jq -n --arg query "$QUERY_INPUT" '{"query": $query}') +fi + +echo "Scanning: ${URL_INPUT:-$QUERY_INPUT}" +echo "" + +RESPONSE=$(curl -s -X POST "$ENDPOINT" \ + -H "Content-Type: application/json" \ + -d "$PAYLOAD") + +if echo "$RESPONSE" | jq -e '.error' > /dev/null 2>&1; then + echo "Error: $(echo "$RESPONSE" | jq -r '.error')" + exit 1 +fi + +# Summary +echo "=== SUMMARY ===" +echo "$RESPONSE" | jq -r '.content.summary' +echo "" +echo "Entities: $(echo "$RESPONSE" | jq -r '[.content.entities[]] | join(", ")')" +echo "Tickers: $(echo "$RESPONSE" | jq -r '[.content.tickers[]] | join(", ")')" +echo "" + +# Edge predictions (spread > 0.05) +EDGE=$(echo "$RESPONSE" | jq '[.predictions[] | select(.spread > 0.05)] | sort_by(-.spread)') +EDGE_COUNT=$(echo "$EDGE" | jq 'length') + +if [[ "$EDGE_COUNT" -gt 0 ]]; then + echo "=== ⚡ EDGE OPPORTUNITIES ($EDGE_COUNT) ===" + echo "$EDGE" | jq -r '.[] | "[\(.spreadDirection == "q_higher" | if . then "BUY YES" else "BUY NO" end) +\((.spread * 100 | floor))%] \(.question)\n Market: \((.yesPrice * 100 | floor))% Q: \((.quotientOdds * 100 | floor))% Vol: $\(.volume)\n BLUF: \(.bluf // "—")\n Trade: https://polymarket.com/event/\(.slug)\n"' +fi + +# All predictions +echo "=== PREDICTION MARKETS ($(echo "$RESPONSE" | jq '.predictions | length')) ===" +echo "$RESPONSE" | jq -r '.predictions[:5][] | "[\((.yesPrice * 100 | floor))% YES] \(.question)"' +echo "" + +# Perps +PERPS_COUNT=$(echo "$RESPONSE" | jq '.perps | length') +if [[ "$PERPS_COUNT" -gt 0 ]]; then + echo "=== PERPETUALS ($PERPS_COUNT) ===" + echo "$RESPONSE" | jq -r '.perps[] | "\(.asset)-PERP $\(.markPrice) Funding: \(.funding) Trade: https://app.hyperliquid.xyz/trade/\(.coinId // .asset)"' + echo "" +fi + +# Options +OPTIONS_COUNT=$(echo "$RESPONSE" | jq '.options | length') +if [[ "$OPTIONS_COUNT" -gt 0 ]]; then + echo "=== OPTIONS ($OPTIONS_COUNT) ===" + echo "$RESPONSE" | jq -r '.options[] | "\(.instrument) IV: \(.markIv)% OI: \(.openInterest)"' +fi