Use when user asks about event probabilities, prediction market odds, what people are betting on, Polymarket or Kalshi prices, sports markets, wallet identity / clustering, or wants to find markets on a specific topic (elections, crypto, sports, macro events). Predexon v2 endpoints (canonical cross-venue markets, sports, wallet identity, keyset pagination) live in production as of 2026-05.
Scanned 5/27/2026
Install via CLI
openskills install BlockRunAI/blockrun-mcp---
name: prediction-markets
description: Use when user asks about event probabilities, prediction market odds, what people are betting on, Polymarket or Kalshi prices, sports markets, wallet identity / clustering, or wants to find markets on a specific topic (elections, crypto, sports, macro events). Predexon v2 endpoints (canonical cross-venue markets, sports, wallet identity, keyset pagination) live in production as of 2026-05.
triggers:
- "polymarket"
- "kalshi"
- "dflow"
- "prediction market"
- "event probability"
- "betting odds"
- "what are people betting on"
- "election odds"
- "crypto market odds"
- "binance futures"
- "yes/no market"
- "implied probability"
- "sports markets"
- "wallet identity"
- "wallet cluster"
- "cross-venue markets"
- "predexon"
---
# Prediction Markets
Real-time prediction market data via BlockRun (powered by Predexon v2). Covers canonical cross-venue markets, Polymarket, Kalshi, Limitless, Opinion, Predict.Fun, dFlow, sports, and Binance Futures.
## Quick Decision Table
| User wants... | Method | Path | Cost |
|--------------|--------|------|------|
| **Canonical cross-venue markets** | `client.pm(path)` | `"markets"` | $0.001 |
| **Venue-native flattened listings** | `client.pm(path)` | `"markets/listings"` | $0.001 |
| **Resolve canonical outcome ID** | `client.pm(path)` | `"outcomes/{predexon_id}"` | $0.001 |
| **Search across all venues** | `client.pm(path, q=...)` | `"markets/search"` | $0.005 |
| Active Polymarket events | `client.pm(path)` | `"polymarket/events"` | $0.001 |
| Polymarket events (keyset paginated) | `client.pm(path, pagination_key=...)` | `"polymarket/events/keyset"` | $0.001 |
| Polymarket markets (keyset paginated) | `client.pm(path, pagination_key=...)` | `"polymarket/markets/keyset"` | $0.001 |
| Specific Kalshi market | `client.pm(path)` | `"kalshi/markets/TICKER"` | $0.001 |
| **Sports categories** | `client.pm(path)` | `"sports/categories"` | $0.001 |
| **Sports markets (by league/sport)** | `client.pm(path, league=...)` | `"sports/markets"` | $0.001 |
| **Wallet identity (single)** | `client.pm(path)` | `"polymarket/wallet/identity/{wallet}"` | $0.005 |
| **Wallet identity (bulk, up to 200)** | `client.pm_query(path, body)` | `"polymarket/wallet/identities"` | $0.005 |
| **Wallet on-chain cluster** | `client.pm(path)` | `"polymarket/wallet/{address}/cluster"` | $0.005 |
| dFlow markets | `client.pm(path)` | `"dflow/..."` | $0.001-$0.005 |
| Binance Futures | `client.pm(path)` | `"binance/..."` | $0.005 |
## Instructions
### 1. Initialize
```python
import os
from pathlib import Path
chain_file = Path.home() / ".blockrun" / ".chain"
chain = chain_file.read_text().strip() if chain_file.exists() else "base"
if chain == "solana":
from blockrun_llm import setup_agent_solana_wallet
client = setup_agent_solana_wallet()
else:
from blockrun_llm import setup_agent_wallet
client = setup_agent_wallet()
```
### 2. List Active Events
```python
# All active Polymarket events
events = client.pm("polymarket/events")
for event in events.get("data", events if isinstance(events, list) else [])[:10]:
print(f"{event.get('title', '?')} — {event.get('slug', '')}")
```
### 3. Search by Topic
```python
# Search Polymarket for a topic
results = client.pm("polymarket/search", q="bitcoin ETF")
for market in results.get("data", results if isinstance(results, list) else [])[:10]:
title = market.get("title", "?")
# Outcome prices are in the market object
print(f"{title}")
for outcome in market.get("outcomes", []):
print(f" {outcome.get('title', '?')}: {outcome.get('price', '?')}")
```
### 4. Specific Kalshi Market
```python
# Get a specific Kalshi market by ticker
market = client.pm("kalshi/markets/KXBTC-25MAR14")
print(f"Market: {market.get('title', market.get('ticker', '?'))}")
yes_price = market.get("yes_bid", market.get("yes_price", "?"))
no_price = market.get("no_bid", market.get("no_price", "?"))
print(f"YES: {yes_price} | NO: {no_price}")
```
### 5. Structured Query (POST)
Use for complex filtering — active markets only, sorted by volume, with pagination.
```python
# Polymarket: active markets sorted by volume, limit 20
data = client.pm_query("polymarket/query", {
"filter": "active",
"limit": 20,
"order": "volume",
})
# Kalshi: all markets in a specific series
data = client.pm_query("kalshi/query", {
"series_ticker": "KXBTC",
"limit": 50,
})
```
### 6. Canonical Cross-Venue Markets (v2)
Predexon v2 unifies markets across Polymarket, Kalshi, Limitless, Opinion, Predict.Fun behind canonical IDs. One call returns the same question regardless of venue.
```python
# All canonical markets (filter by venue, status, category, league, event_id)
markets = client.pm("markets", venue="polymarket", status="active")
for m in markets.get("markets", [])[:10]:
print(f"{m.get('predexon_id')} — {m.get('title')}")
# Flattened venue-native listings (each row = a tradable listing on one venue)
listings = client.pm("markets/listings", category="elections")
# Resolve a canonical outcome ID across venues
detail = client.pm("outcomes/PXM-12345")
print(detail.get("title"), detail.get("venue_listings"))
```
### 7. Sports Markets (v2)
```python
# List sports categories (NBA, NFL, MLB, soccer leagues, …)
categories = client.pm("sports/categories")
# Sports markets grouped by game — filter by league or venue
nba = client.pm("sports/markets", league="NBA", status="open")
for game in nba.get("markets", [])[:10]:
print(f"{game.get('title')} @ {game.get('start_time')}")
for venue in game.get("venue_listings", []):
print(f" {venue.get('venue')}: {venue.get('price')}")
```
### 8. Keyset Pagination (v2)
For large Polymarket result sets, prefer keyset pagination over offset. It is stable across writes and faster on big tables.
```python
# First page
page = client.pm("polymarket/markets/keyset", limit="100")
markets = page.get("markets", [])
next_key = page.get("pagination", {}).get("next_key")
# Subsequent pages
while next_key:
page = client.pm("polymarket/markets/keyset", limit="100", pagination_key=next_key)
markets.extend(page.get("markets", []))
next_key = page.get("pagination", {}).get("next_key")
```
### 9. Wallet Identity & On-Chain Clustering (v2, Tier 2)
Cross-context wallet labels (ENS, Twitter, Discord, portfolio metrics) plus on-chain relationship graph data — exposed as three endpoints. **All Tier 2 ($0.005/call).**
```python
# Single wallet identity
ident = client.pm("polymarket/wallet/identity/0xabc...")
print(ident.get("ens_name"), ident.get("twitter"), ident.get("portfolio_value"))
# Bulk identity lookup (POST, up to 200 wallets per call)
batch = client.pm_query("polymarket/wallet/identities", {
"addresses": ["0xabc...", "0xdef...", "0x123..."],
})
for row in batch.get("results", []):
print(row.get("wallet"), row.get("label"))
# Cluster — discover wallets connected via on-chain transfers + identity proofs
cluster = client.pm("polymarket/wallet/0xabc.../cluster")
for related in cluster.get("cluster", []):
print(related.get("wallet"), related.get("relationship_type"), related.get("confidence_score"))
```
## Common Workflows
**"What are people betting on in crypto right now?"**
```python
events = client.pm("polymarket/search", q="crypto bitcoin ethereum")
for e in events.get("data", [])[:5]:
print(e.get("title", "?"))
for o in e.get("outcomes", []):
print(f" {o.get('title')}: {o.get('price')} (implies {round(float(o.get('price', 0))*100)}%)")
```
**"Track a smart wallet's identity + cluster"**
```python
seed = "0xabc..."
ident = client.pm(f"polymarket/wallet/identity/{seed}")
cluster = client.pm(f"polymarket/wallet/{seed}/cluster")
print(f"{ident.get('label')} (ENS {ident.get('ens_name')})")
print(f" Cluster size: {len(cluster.get('cluster', []))} wallets")
```
**"What's the probability of X event?"**
```python
# 1. Search for the event
results = client.pm("polymarket/search", q="US election 2026")
# 2. Get specific market details
if results.get("data"):
market_id = results["data"][0].get("id", results["data"][0].get("slug"))
detail = client.pm(f"polymarket/events/{market_id}")
print(detail)
```
**"Show me all active Kalshi markets"**
```python
data = client.pm_query("kalshi/query", {"limit": 50, "status": "open"})
markets = data.get("markets", data.get("data", []))
for m in markets[:10]:
print(f"{m.get('ticker')} — {m.get('title')}: YES={m.get('yes_bid')} NO={m.get('no_bid')}")
```
## Data Case Study: Sentiment Signal from Markets
Prediction markets are often better probability estimates than polls or pundit takes. Pattern:
```python
import json
# 1. Find relevant markets
crypto_markets = client.pm("polymarket/search", q="bitcoin price end of year")
# 2. Extract implied probabilities
for market in crypto_markets.get("data", [])[:3]:
print(f"\n{market.get('title', '?')}")
for outcome in market.get("outcomes", []):
p = float(outcome.get("price", 0)) * 100
print(f" {outcome.get('title')}: {p:.0f}% implied probability")
# 3. Save for later analysis
with open(os.path.expanduser("~/.blockrun/data/markets_snapshot.json"), "w") as f:
json.dump(crypto_markets, f, indent=2, default=str)
```
## Notes on Response Shape
Predexon returns raw API responses. Structure varies by exchange:
- **Polymarket**: usually `{ "data": [...] }` or `{ "events": [...] }`
- **Kalshi**: usually `{ "markets": [...] }` with `ticker`, `yes_bid`, `no_bid` fields
- **Print raw response first** when exploring a new path: `print(json.dumps(result, indent=2)[:1000])`
## Requirements
- BlockRun SDK: `pip install blockrun-llm`
- USDC wallet funded (`client.get_balance()`)
- Kalshi tickers: format is `KXBTC-25MAR14` (series + expiry date)
No comments yet. Be the first to comment!