Metadata-Version: 2.4
Name: madeonsol-x402
Version: 1.13.0
Summary: x402 client SDK for MadeOnSol Solana KOL intelligence API. Works with LangChain, CrewAI, and standalone.
License: MIT
Project-URL: Homepage, https://madeonsol.com/solana-api
Project-URL: Repository, https://github.com/LamboPoewert/madeonsol-python
Keywords: solana,x402,kol,kol-tracker,trading,api,langchain,crewai,ai-agent,memecoin,memecoin-tracker,alpha,alpha-bot,pumpfun,pumpfun-sniper,deployer-hunter,smart-money,copy-trading,solana-trading-bot,madeonsol
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27
Requires-Dist: x402[httpx,svm]>=0.1
Provides-Extra: stream
Requires-Dist: websockets>=12; extra == "stream"
Provides-Extra: langchain
Requires-Dist: langchain-core>=0.3; extra == "langchain"
Provides-Extra: crewai
Requires-Dist: crewai>=0.80; extra == "crewai"

# madeonsol-x402

[![PyPI](https://img.shields.io/pypi/v/madeonsol-x402?style=flat-square)](https://pypi.org/project/madeonsol-x402/)
[![Python](https://img.shields.io/pypi/pyversions/madeonsol-x402?style=flat-square)](https://pypi.org/project/madeonsol-x402/)
[![Downloads](https://img.shields.io/pypi/dm/madeonsol-x402?style=flat-square)](https://pypi.org/project/madeonsol-x402/)
[![GitHub stars](https://img.shields.io/github/stars/LamboPoewert/madeonsol-python?style=flat-square&logo=github)](https://github.com/LamboPoewert/madeonsol-python)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=flat-square)](LICENSE)

> ⭐ **[Star on GitHub](https://github.com/LamboPoewert/madeonsol-python)** · 📂 **[Examples](./examples/)** · 📚 **[API docs](https://madeonsol.com/api-docs)**

Python SDK for the [MadeOnSol](https://madeonsol.com) Solana KOL intelligence API.

> Real-time Solana trading intelligence: track 1,069 KOL wallets with <3s latency, score 23,000+ Pump.fun deployers, surface deshred deploy signals ~500ms before on-chain confirmation, score 1M+ early-buyer wallets (incl. dump-cluster detection), push every pump.fun graduation, and stream every DEX trade. Free tier: 200 requests/day at [madeonsol.com/pricing](https://madeonsol.com/pricing) — no credit card required.

> **New in 1.13.0** — `rest.tokens_list()` gains three new filter params: `min_liq_mc_ratio`, `max_liq_mc_ratio`, and `deployer_tier` (`'elite'` | `'good'` | `'moderate'` | `'rising'` | `'cold'` | `'unranked'`). Response items now include `liquidity_to_mc_ratio` and `deployer_tier`. KOL leaderboard entries now include `median_hold_minutes_30d` and `percentile_early_entry_30d`. `/token/{mint}` and `/token/batch` responses now include `liquidity_to_mc_ratio`, `launch_cohort_sol`, and `launch_cohort_size`.
>
> **New in 1.12.1** — Deployer alerts/profiles now carry `runner_rate` + `labeled_tokens` (fraction of a deployer's labeled tokens that ran vs dumped, gate on `labeled_tokens` >= 3) plus `avg_time_to_bond_minutes`.

> **New in 1.12** — **Graduation events + dump-cluster detection.** Subscribe `token:graduations` for every pump.fun bond in real time (tracked deployer or not). Buyer-quality `breakdown` adds `dump_cluster_count` (out-of-sample: 3+ → 94% dump vs 61% base) + `recycled_early_buyer_count`. DEX firehose: replay buffer deepened to ~5 min; mint-scoped subs get in-band `dex:graduations` frames.

> **New in 1.10** — **Deshred Sniper.** `client.rest.sniper_recent()` — deshred deploy feed ~500ms before on-chain confirmation. PRO: elite/good. ULTRA: all tiers + `sniper_watchlist_add()`. Use `sniper:deploys` WebSocket for push.
>
> **New in 1.9** — **Price alerts, scout leaderboard, coordination history.** `client.rest.price_alerts_create()` (PRO=5, ULTRA=25). `scout_leaderboard()`, `kol_consensus()`, `peak_history()`, `coordination_history()`. `wallet_stats()` now returns `derived`: win_rate, roi, verdict, biggest_miss.
>
> **New in 1.8** — **Universal Wallet API.** `client.rest.wallet_stats()`, `wallet_pnl()`, `wallet_positions()`, `wallet_trades()` — FIFO cost-basis PnL for any Solana wallet. PRO+. Cache hits free.
>
> **New in 1.7.1** *(2026-05-13)* — Velocity field shape corrected to match the API: `mc_change_pct`, `volume_usd`, `mev_volume_pct` are top-level on the token response, each keyed by `'5m'`/`'15m'`/`'1h'`/`'2h'`/`'4h'`. The 1.7.0 README documented a `velocity[window]` shape that didn't match the wire format.
>
> **New in 1.7.0** *(2026-05-12)* — **Token directory + account inspection.** `client.rest.tokens_list(min_liq=10000, min_volume_1h_usd=5000, max_mev_share_pct=60, mc_change_1h_min_pct=20, sort="mc_desc", min_liq_mc_ratio=0.05, deployer_tier="elite")` filters every active mint by MC band, liquidity floor, primary DEX, authority/safety flags, computed 1h volume, MEV-share ceiling, MC-change deltas, liq/MC ratio, and deployer tier. Response items include `liquidity_to_mc_ratio` and `deployer_tier`. Default `min_liq=2000` skips phantom-MC dust; pass `min_liq=0` to opt out. `client.rest.me()` — read your tier, daily/burst quota state, and per-feature usage in one call (no header parsing). Velocity / MEV-share fields added to every token response: `mc_change_pct`, `volume_usd`, `mev_volume_pct` (each keyed by `'5m'`/`'15m'`/`'1h'`/`'2h'`/`'4h'`) plus `history_age_seconds`. `/token/{mint}` 400s now ship structured `code`, `reason`, `received_length`, `example`, and `docs`. Deprecated `avg_entry_mc_usd` fully removed.

## Quick start (10 seconds)

```bash
pip install madeonsol-x402
```

```python
from madeonsol_x402 import MadeOnSolClient
client = MadeOnSolClient(api_key="msk_...")  # free tier at https://madeonsol.com/pricing
trades = client.kol_feed(limit=5, action="buy")
```

## Authentication

Two options:

| Method | Parameter / Env var | Best for |
|---|---|---|
| **MadeOnSol API key** (recommended) | `api_key` / `MADEONSOL_API_KEY` | Developers — [get a free key](https://madeonsol.com/pricing) |
| x402 micropayments | `private_key` / `SVM_PRIVATE_KEY` | AI agents with Solana wallets |

> **v1.0 breaking change:** RapidAPI auth has been removed. The MadeOnSol RapidAPI marketplace was retired on 2026-04-19. If you were using `rapidapi_key=` or `RAPIDAPI_KEY`, get a free `msk_` key at [madeonsol.com/pricing](https://madeonsol.com/pricing).

## Install

```bash
pip install madeonsol-x402                    # core SDK
pip install madeonsol-x402[langchain]         # + LangChain tools
pip install madeonsol-x402[crewai]            # + CrewAI tools
```

> x402 dependencies are only needed when using `private_key` / `SVM_PRIVATE_KEY`.

## Quick Start

```python
from madeonsol_x402 import MadeOnSolClient

client = MadeOnSolClient(api_key="msk_your_api_key_here")

# Real-time KOL trades — each trade now includes
# market_cap_usd_at_trade and price_usd_at_trade (real-time MC at the
# moment the swap fired, sourced from our in-memory price tracker).
trades = client.kol_feed(limit=10, action="buy")
for t in trades["trades"]:
    print(f'{t["kol_name"]} bought {t["token_symbol"]} for {t["sol_amount"]:.2f} SOL @ MC ${t.get("market_cap_usd_at_trade") or "?"}')

# KOL convergence signals
signals = client.kol_coordination(period="24h", min_kols=3)

# KOL leaderboard — 180 days of history
leaders = client.kol_leaderboard(period="7d")  # today | 7d | 30d | 90d | 180d

# Deployer alerts (all tiers can filter by tier)
alerts = client.deployer_alerts(limit=10)
elite_only = client.deployer_alerts(limit=10, tier="elite")

# Alpha wallet leaderboard (REST)
top = client.rest.alpha_leaderboard(period="30d", sort="win_rate")

# Wallet Tracker (REST)
client.rest.wallet_tracker_add("WALLET_ADDRESS", label="whale")
events = client.rest.wallet_tracker_trades(limit=50)

# Inspect rate-limit headers from the most recent REST call
print(client.rest.last_rate_limit)
# {'limit': 100, 'remaining': 92, 'reset': 1714000000, 'request_id': 'rid_abc123'}
```

## Real-time streaming *(new in 1.11)*

Managed WebSocket stream — auto-reconnect, 24h-token refresh, and typed callbacks handled for you. Needs the `stream` extra: `pip install "madeonsol-x402[stream]"`.

```python
import asyncio
from madeonsol_x402 import MadeOnSolREST

client = MadeOnSolREST(api_key="msk_...")

async def main():
    stream = client.stream()

    @stream.on("kol:trade")
    async def on_trade(data, evt):
        print(data["token_symbol"], data["action"])

    stream.subscribe(["kol:trades", "deployer:alerts"])
    await stream.run()   # blocks; manages connection + reconnects

asyncio.run(main())
```

Channels: `kol:trades`, `kol:coordination`, `kol:first_touches`, `deployer:alerts`, `wallet_tracker:events`, `copytrade:signals`, `price_alert:events`, `sniper:deploys`, `token:graduations` (every pump.fun graduation in real time, tracked deployer or not). Lifecycle events: `open`, `close`, `reconnect`, `heartbeat`, `error`.

## LangChain

```python
from madeonsol_x402.langchain_tools import ALL_TOOLS

# Set MADEONSOL_API_KEY or SVM_PRIVATE_KEY env var
agent = create_react_agent(llm, tools=ALL_TOOLS)
```

## CrewAI

```python
from madeonsol_x402.crewai_tools import ALL_TOOLS

agent = Agent(role="Solana Analyst", tools=ALL_TOOLS)
```

## Endpoints

### KOL Intelligence (x402-priced — also reachable via `msk_` API key)

| Method | Description |
|---|---|
| `kol_feed()` | Real-time KOL trade feed (1,000+ wallets) |
| `kol_coordination()` | Multi-KOL convergence signals |
| `kol_leaderboard()` | PnL and win rate rankings — windows: today, 7d, 30d, 90d, 180d (180-day retention) |
| `kol_pairs()` | KOL affinity matrix — which KOLs co-trade the same tokens |
| `kol_hot_tokens()` | KOL momentum tokens — accelerating buy interest |
| `kol_trending_tokens()` | Tokens ranked by KOL buy volume |
| `kol_token_entry_order(mint)` | Ranked KOL first-buyer order for a token |
| `kol_compare_wallets(wallets)` | Side-by-side comparison of 2–5 KOL wallets |
| `kol_alerts_recent()` | Live KOL alert feed — clusters, fresh-token buys, heating-up |
| `deployer_alerts()` | Pump.fun deployer launches with KOL enrichment |
| `wallet_stats(address)` | **New 1.8** · Universal wallet stats (90d) + cross-product flags. $0.005 |
| `wallet_pnl(address)` | **New 1.8** · FIFO cost-basis PnL: realized + unrealized, profit factor, drawdown, daily curve, closed + open positions. $0.02 |
| `wallet_positions(address)` | **New 1.8** · Open positions with live unrealized from market-cap tracker. Shares /pnl cache. $0.01 |
| `wallet_trades(address, ...)` | **New 1.8** · Cursor-paginated raw trades with action / token / since-until filters. $0.005 |
| `discovery()` | Free — list all endpoints and prices |

### REST API — KOL/deployer detail

| Method | Description |
|---|---|
| `rest.kol_pnl(wallet, period=)` | Deep per-wallet PnL: equity curve, risk metrics, closed positions. ULTRA adds open positions (tokens bought but not yet sold). |
| `rest.kol_timing(wallet, period=)` | KOL entry/exit timing profile — available on all tiers |
| `rest.deployer_trajectory(wallet)` | Deployer skill curve — streaks, rolling bond rate, trend — available on all tiers |

### Alpha Wallet Intelligence

Scored from 1M+ early-buyer records (wallets seen in the first 20 buyers of Pump.fun tokens).

| Method | Tier | Description |
|---|---|---|
| `rest.alpha_leaderboard(period=, min_tokens=, sort=, exclude_bots=)` | All | Up to 100 results on Free/Pro; ULTRA unlocks 500 + bot signals |
| `rest.alpha_wallet(wallet)` | ULTRA | Full per-token breakdown + bot_signals array |
| `rest.alpha_linked(wallet)` | ULTRA | Wallets behaviorally linked (co-bought 3+ tokens within 2s) |

### Token Quality

| Method | Tier | Description |
|---|---|---|
| `rest.token_cap_table(mint)` | PRO+ | First non-deployer early buyers, enriched with PnL/KOL/bot flags. PRO=10, ULTRA=20 |
| `rest.token_buyer_quality(mint)` | All | 0–100 buyer-quality score + full breakdown (5-min cached) |

### Deshred Sniper Alerts *(new in 1.10)*

The fastest path to a new pump.fun launch. Deploys are reconstructed from shred-level (**deshred**) data and surface **~500ms before the chain confirms them**. **PRO** sees elite + good deployers; **ULTRA** sees every tier and can keep a custom deployer watchlist. For live push use the `sniper:deploy` webhook or the `sniper:deploys` WebSocket channel.

| Method | Tier | Description |
|---|---|---|
| `rest.sniper_recent(limit=, deployer_tier=, min_bond_rate=, since=, watchlist=)` | PRO+ | Deshred deploy feed, newest first. PRO=elite/good, ULTRA=all tiers. `watchlist=True` (ULTRA) narrows to your watchlist |
| `rest.sniper_by_deployer(wallet, limit=)` | ULTRA | Deshred deploys for one deployer |
| `rest.sniper_watchlist()` | ULTRA | List your custom deployer watchlist (max 50) |
| `rest.sniper_watchlist_add(wallet=/wallets=, label=)` | ULTRA | Add one or many deployers |
| `rest.sniper_watchlist_remove(wallet)` | ULTRA | Remove a deployer |

```python
feed = client.rest.sniper_recent(limit=50, min_bond_rate=0.5)
client.rest.sniper_watchlist_add(wallets=["7dEx...4pQ8", "9aBc...2zZ1"], label="alpha devs")
tracked = client.rest.sniper_recent(watchlist=True)  # ULTRA — only your tracked deployers
```

### KOL Coordination Alerts (v1.1 — push signals)

Real-time push alerts when a cluster of KOLs co-buys the same token. Fires within ~1s of the triggering trade (pg_notify push, not polling). Delivered via WebSocket (`kol:coordination` channel, user-scoped) and/or HMAC-signed webhook. PRO=5 rules, ULTRA=20.

```python
res = client.rest.coordination_alerts_create(
    name="fresh pump cluster",
    min_kols=4,
    window_minutes=15,     # peak-density window (1-60)
    min_score=70,          # 0-100 composite score cutoff
    include_majors=False,  # filter WIF/BONK/POPCAT
    cooldown_min=60,       # one fire per (rule, token) per 60min...
    score_jump_break=10,   # ...unless score jumps +10 vs last fire
    delivery_mode="both",
    webhook_url="https://you.com/hooks/coord",
)
# store res["webhook_secret"] — shown ONCE
```

`coordination_alerts_list()`, `coordination_alerts_get(id)`, `coordination_alerts_update(id, **fields)`, `coordination_alerts_delete(id)`.

**Webhook signature:** `X-MadeOnSol-Signature: sha256=<hmac>` where `hmac = HMAC-SHA256(webhook_secret, timestamp + "." + rawBody)`, and `X-MadeOnSol-Timestamp` carries the unix seconds used.

**The `kol_coordination()` response** now includes v1.1 fields: `peak_window_start/end`, `peak_kols`, `peak_buys` (the busiest slice within the period), `exited_count` + per-KOL `exited` (net-flow-negative wallets), and `coordination_score` (0-100). Pass `min_score=`, `window_minutes=`, `include_majors=` to filter.

### KOL First-Touch Signal *(new in 1.3)*

Every "first KOL buy on a token mint" event — when a tracked KOL is the first of the cohort to touch a token. Filterable by **scout tier** (S/A/B/C from `mv_kol_scout_score`), KOL winrate, token age, mint suffix.

**Backtest:** S-tier scouts attract ≥3 follow-on KOLs within 4h ~50% of the time vs ~14% baseline (38d / 491k buys / 72,549 events). Public leaderboard at [madeonsol.com/kol/scouts](https://madeonsol.com/kol/scouts).

```python
# REST query — S-tier scouts on tokens younger than 1h
events = client.rest.first_touches(preset="scout", min_scout_tier="S", limit=20)
for e in events["events"]:
    fk = e["first_kol"]
    print(fk["name"], "scouted", e["token_symbol"], f"(scout_score={fk['scout_score']}%)")

# Webhook subscription (Ultra) — HMAC-signed push
res = client.rest.first_touch_subscriptions_create(
    name="S-tier scouts on pump tokens",
    filters={"min_scout_tier": "S", "mint_suffix": "pump"},
    delivery_mode="webhook",
    webhook_url="https://you.com/hooks/scout",
)
# store res["webhook_secret"] — shown ONCE
```

CRUD: `first_touch_subscriptions_list()`, `first_touch_subscriptions_get(id)`, `first_touch_subscriptions_update(id, **fields)`, `first_touch_subscriptions_delete(id)`. ULTRA only — up to 10 active.

> **Don't poll — push.** Median lead time before the second KOL is **12 seconds**. WebSocket channel: `kol:first_touches` (PRO+).

### Price Alerts *(new in 1.9)*

CRUD for token dip/recovery price alerts. Fires via WebSocket (`price:alerts` channel) and/or HMAC-signed webhook when a token's market cap crosses your threshold. PRO=5 rules, ULTRA=25.

```python
res = client.rest.price_alerts_create(
    name="SOL dip buy",
    token_mint="So11111111111111111111111111111111111111112",
    condition="below",          # "below" | "above"
    threshold_mc_usd=5_000_000_000,
    cooldown_min=120,
    delivery_mode="both",
    webhook_url="https://you.com/hooks/price",
)
# store res["webhook_secret"] — shown ONCE
```

`price_alerts_list()`, `price_alerts_get(id)`, `price_alerts_update(id, **fields)`, `price_alerts_delete(id)`.

LangChain: `MadeOnSolPriceAlertsListTool`, `MadeOnSolPriceAlertsCreateTool`. CrewAI: same names via `ALL_TOOLS`.

### Scout Leaderboard & KOL Consensus *(new in 1.9)*

| Method | Tier | Description |
|---|---|---|
| `rest.scout_leaderboard(period=, limit=)` | PRO+ | Top scout-tier KOLs ranked by first-touch follow-on rate, win rate, and ROI |
| `rest.kol_consensus(min_kols=, period=)` | PRO+ | Tokens with the strongest KOL agreement signal — weighted by scout score and recent PnL |
| `rest.peak_history(mint)` | PRO+ | Historical peak-density windows for a token — every coordination spike with KOL breakdown |
| `rest.coordination_history(period=, limit=)` | PRO+ | Global coordination event log with token, KOL count, score, and outcome |

```python
leaders = client.rest.scout_leaderboard(period="30d", limit=25)
consensus = client.rest.kol_consensus(min_kols=5, period="24h")
```

### Wallet Derived Stats *(new in 1.9)*

`wallet_stats(address)` now includes a `stats` object with derived fields computed from the 90-day trade window:

```python
data = client.rest.wallet_stats("WALLET_ADDRESS")
s = data["stats"]
# s["win_rate"]      — fraction 0-1, tokens sold above cost basis
# s["roi"]           — aggregate return on invested SOL
# s["verdict"]       — "strong" | "profitable" | "neutral" | "losing"
# s["biggest_miss"]  — token with the highest post-exit gain the wallet missed
```

### Copy-Trade Rules (PRO/ULTRA)

Server-side rules that fire signals when one of your watched source wallets trades. Delivered via webhook (HMAC-signed) and/or WebSocket. PRO=3 rules × 5 source wallets each; ULTRA=20 × 50.

| Method | Description |
|---|---|
| `rest.copy_trade_list()` | List your rules |
| `rest.copy_trade_create(source_wallets, sizing_amount, ...)` | Create a rule. Returns `webhook_secret` **once** — store it |
| `rest.copy_trade_get(id)` | Get one rule |
| `rest.copy_trade_update(id, **fields)` | Update fields or toggle `is_active` |
| `rest.copy_trade_delete(id)` | Delete permanently |
| `rest.copy_trade_signals(subscription_id=, since=, limit=)` | Recent fired signals (up to 7 days, 1–500) |

### Wallet Tracker

| Method | Description |
|---|---|
| `rest.wallet_tracker_watchlist()` | List tracked wallets and remaining capacity (Free: 10, Pro: 50, Ultra: 100) |
| `rest.wallet_tracker_add(wallet_address, label=)` | Add wallet to watchlist |
| `rest.wallet_tracker_remove(wallet_address)` | Remove wallet from watchlist |
| `rest.wallet_tracker_update_label(wallet_address, label)` | Update wallet label |
| `rest.wallet_tracker_trades(wallet=, action=, event_type=, limit=, before=)` | Historical swap/transfer events (120-day retention) |
| `rest.wallet_tracker_summary(period=, wallet=)` | Per-wallet stats: swap counts, SOL bought/sold, last event |

### Universal Wallet API *(new in 1.8)*

Per-wallet endpoints that work on **any** Solana wallet, not just curated KOLs. FIFO cost-basis PnL over the last 90 days. PRO+ on every endpoint. Cache hits don't count against your daily quota.

| Method | Description |
|---|---|
| `rest.wallet_stats(address)` | Aggregate stats over 90d + cross-product flags (is_kol + kol_name, is_alpha_tracked + bot_confidence + win_rate, is_deployer + tokens_deployed) |
| `rest.wallet_pnl(address)` | Full FIFO cost-basis PnL: realized + unrealized SOL, profit factor, max drawdown, avg + median hold minutes, daily UTC PnL curve, closed positions sorted by pnl desc, open positions with live unrealized from mc-tracker |
| `rest.wallet_positions(address)` | Open lots only — shares /pnl cache, lighter response |
| `rest.wallet_trades(address, limit=, cursor=, action=, token_mint=, since=, until=)` | Cursor-paginated raw trades. Default window: last 90 days. limit 1-500 |

**Cost-basis honesty**: observable only inside the 90-day data window. Overflow sells (no matching buy in window) are silently discarded rather than fabricated. `notes.cost_basis_observable_from` makes the cutoff visible per call.

### Webhooks + Streaming

| Method | Description |
|---|---|
| `rest.create_webhook(url, events, filters=)` | Register webhook. Returns `secret` once — store it for HMAC verification |
| `rest.list_webhooks()` | List your webhooks |
| `rest.get_webhook(id)` | Get one + recent delivery log |
| `rest.update_webhook(id, **kwargs)` | Update URL, events, filters, or re-enable |
| `rest.delete_webhook(id)` | Delete permanently |
| `rest.test_webhook(id)` | Send test payload |
| `rest.get_stream_token()` | Issue a 24h WebSocket streaming token (returns `ws_url` + `dex_ws_url`) |

### Rate-limit headers

Every successful REST response captures rate-limit headers in `rest.last_rate_limit`:

```python
client.rest.alpha_leaderboard()
rl = client.rest.last_rate_limit
# {'limit': 100, 'remaining': 92, 'reset': 1714000000, 'request_id': 'rid_abc123'}
if rl['remaining'] is not None and rl['remaining'] < 5:
    print(f"Throttle warning — {rl['remaining']}/{rl['limit']} requests left")
```

### DEX Firehose (Ultra) — WebSocket

`rest.get_stream_token()` returns `dex_ws_url` (Ultra only). Connect with any WebSocket client (`websockets`, `websocket-client`, etc.) and use the multi-subscription protocol — up to **10 named subs per connection**, each with its own `sub_id`, server-side filters, and optional replay (up to 500 most recent matching trades) from a server-side buffer holding ~5 minutes of firehose history — it backfills trades from before your connection existed. Replayed trades arrive newest-first flagged `"replay": true`, then a `replay_done` frame; sort by `block_time` client-side.

```python
import asyncio, json, websockets
from madeonsol_x402 import MadeOnSolClient

client = MadeOnSolClient(api_key="msk_...")

async def main():
    token = client.rest.get_stream_token()  # {"token", "ws_url", "dex_ws_url", ...}

    # token MUST be appended as query param
    async with websockets.connect(f"{token['dex_ws_url']}?token={token['token']}") as ws:
        await ws.send(json.dumps({
            "type": "subscribe",
            "sub_id": "fresh-pumpfun",
            "replay": 50,                       # up to 500 from ring buffer
            "filters": {
                "dex": "pumpfun",
                "token_age_max_seconds": 300,
                "min_sol": 0.5,
                "action": "buy",
            },
        }))

        async for raw in ws:
            msg = json.loads(raw)
            if msg.get("channel") == "dex:trades":
                d = msg["data"]
                print(msg["sub_id"], d["dex"], d["action"], d["sol_amount"])

asyncio.run(main())
```

**Operations** (all carry `sub_id`): `subscribe`, `update` (replace filters in place), `unsubscribe`, `list`, `ping`. **Filters:** `token_mint(s)` (≤50), `wallet(s)` (≤50), `dex` (`pumpfun` | `pumpamm` | `pumpswap` | `raydium` | `jupiter` | `orca` | `meteora` | `launchlab`), `program`, `deployer_tier`, `token_age_max_seconds`, `market_cap_min/max_sol`, `min_sol`, `max_sol`, `action`. At least one targeting filter is required. Inbound rate limit: 5 messages/sec.

Full protocol reference: [madeonsol.com/api-docs#streaming](https://madeonsol.com/api-docs#streaming).

## Tiers

| Tier | Price | Wallets tracked | Requests/day |
|------|-------|-----------------|--------------|
| BASIC (free) | $0 | 10 | 200 |
| PRO | $49/mo ($490/yr) | 50 | 10,000 |
| ULTRA | $149/mo ($1,490/yr) | 100 + WS events | 100,000 |

Free tier returns the full REST response shape on every endpoint — real wallets, TX signatures, full precision. Paid tiers unlock webhooks, WebSockets, rule engines, and ULTRA-only data depth. Get a key at [madeonsol.com/pricing](https://madeonsol.com/pricing).

## Also Available

| Platform | Package |
|---|---|
| TypeScript SDK | [`madeonsol`](https://www.npmjs.com/package/madeonsol) on npm |
| Rust SDK | [`madeonsol`](https://crates.io/crates/madeonsol) on crates.io |
| MCP Server (Claude, Cursor) | [`mcp-server-madeonsol`](https://www.npmjs.com/package/mcp-server-madeonsol) · [Smithery](https://smithery.ai/servers/madeonsol/solana-kol-intelligence) · [Glama](https://glama.ai/mcp/servers/LamboPoewert/mcp-server-madeonsol) |
| ElizaOS | [`@madeonsol/plugin-madeonsol`](https://www.npmjs.com/package/@madeonsol/plugin-madeonsol) |
| Solana Agent Kit | [`solana-agent-kit-plugin-madeonsol`](https://www.npmjs.com/package/solana-agent-kit-plugin-madeonsol) |

## License

MIT
