Metadata-Version: 2.4
Name: cookin-fun
Version: 0.2.0
Summary: Python SDK for the Cookin API — Pump.fun and Solana memecoin data (REST + WebSocket).
Project-URL: Homepage, https://cookin.fun/api
Project-URL: Documentation, https://cookin.fun/api
Project-URL: Repository, https://github.com/cookin-fun/cookin-python
Project-URL: Discord, https://cookin.fun/discord
Author: cookin.fun
License: MIT
License-File: LICENSE
Keywords: bundle-detection,cookin,memecoin,pump.fun,pumpfun,pumpswap,sdk,solana,trading,websocket
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: httpx>=0.25
Requires-Dist: typing-extensions>=4.0; python_version < '3.11'
Requires-Dist: websockets>=13.0
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# cookin-fun

Python SDK for the **[Cookin API](https://cookin.fun/api)** — real-time Pump.fun and Solana memecoin data. REST + WebSocket over the same pipeline that powers the [cookin.fun](https://cookin.fun) UI. Quality scores, bundle detection, trader behavioral stats, live trade frames.

- **Pro: 1 SOL per 30 days**, 600 requests per minute, both WebSocket channels. Mint a key at [cookin.fun/account/api-keys](https://cookin.fun/account/api-keys).
- **No key? Pay per call** in USDC on Solana with [x402](https://cookin.fun/api/x402), from $0.01, or use the MCP server: `npx -y @cookinfun/mcp`.
- **Docs:** https://cookin.fun/api
- **Discord:** https://cookin.fun/discord

## Install

```bash
pip install cookin-fun
```

Python 3.9+.

## Quickstart

Mint an API key at [cookin.fun/account/api-keys](https://cookin.fun/account/api-keys) and set it as `COOKIN_API_KEY`.

```python
from cookin_fun import Cookin
import os

cookin = Cookin(api_key=os.environ["COOKIN_API_KEY"])

# Full snapshot for one token
snap = cookin.tokens.get("BgNrWZKAaZAa...")
print(snap["data"]["score"]["value"], snap["data"]["holders"]["count"])
```

That's it. Every REST method returns the raw envelope dict `{"data": ..., "meta": ...}`. TypedDict definitions ship with the package so IDEs get autocomplete for every field.

## REST

Every REST method returns the envelope as a plain `dict`. Field types are documented via `TypedDict`s in `cookin_fun.types`.

```python
# Token feeds. All four return a list of token cards.
cookin.tokens.new()          # recently deployed
cookin.tokens.pumps()        # currently pumping
cookin.tokens.graduated()    # recently on Raydium / PumpSwap
cookin.tokens.agents()       # the 20 most recent buys by the top Cookin agents

# One token, one call. Filter to the field groups you actually need.
cookin.tokens.get(mint, fields=["meta", "market", "score", "ratings"])

# Most recent trades for a token, enriched with per-trade trader context.
cookin.tokens.trades(mint)

# Full behavioral profile for a wallet.
cookin.traders.get(wallet_address)
```

## WebSocket

Two channels, both multiplexed on one socket connection. Use `.on_tokens` / `.on_frames` to register handlers, then `.run_forever()` to pump events.

```python
socket = cookin.connect()

# Token lifecycle events: created, graduated, DEX-paid, metadata,
# duplication flags flipped.
def on_token_event(event):
    if event["type"] == "token_created":
        card = event["data"]
        print("new token:", card["symbol"], card["score"])

# Every enriched trade, ~1s off Solana block time. One message per
# {signature, mint} unit, so multi-hop swaps arrive grouped.
def on_frame(frame):
    for trade in frame["trades"]:
        print(trade["signature"], trade["user_address"], trade["sol_amount"])

with socket:
    socket.on_tokens(on_token_event)
    socket.on_frames(on_frame)
    socket.run_forever()
```

The SDK handles the Phoenix Channels v2 wire protocol (join, heartbeat, event dispatch) internally. **Reconnect and back-pressure are left to callers on purpose** so the SDK stays predictable. Wrap `.connect()` in your own reconnect loop for long-lived processes.

## Examples

Two runnable scripts in [`examples/`](./examples):

- **[`lifecycle_events.py`](./examples/lifecycle_events.py)** — subscribes to `tokens:live` and prints one line per event type (`token_created`, `token_metadata_retrieved`, `token_graduated`, `token_dex_paid`, `token_duplication_status_updated`).
- **[`wallet_watcher.py`](./examples/wallet_watcher.py)** — streams `frames:live` filtered to a list of wallets.

```bash
COOKIN_API_KEY=sk_live_... python examples/lifecycle_events.py
```

## Errors

Non-2xx responses raise a typed `CookinError`:

```python
from cookin_fun import CookinError

try:
    cookin.tokens.get(mint)
except CookinError as exc:
    print(exc.status, exc.code, exc.request_id)
```

Every response carries a `request_id` in `meta` (and on errors, on the exception). Quote it when reporting issues.

## Rate limits

60 requests per minute per key. `X-RateLimit-*` headers on every response. See [Rate limits](https://cookin.fun/api/rate-limits) for details.

## Full reference

Every endpoint, every field, every WebSocket event: **[cookin.fun/api](https://cookin.fun/api)**.

- [Token snapshot fields](https://cookin.fun/api/tokens/snapshot)
- [tokens:live event schema](https://cookin.fun/api/websocket/tokens)
- [frames:live schema](https://cookin.fun/api/websocket/frames)
- [Supported DEXes](https://cookin.fun/api/dexes)

## Contributing

Bug reports and feature requests: [Discord](https://cookin.fun/discord).

## License

MIT

## Ratings

Every card and snapshot carries ``ratings``: a ``green``, ``yellow``,
``red`` or ``neutral`` verdict per metric, using the same thresholds the
Cookin UI colours with. Gate on those instead of interpreting each
number.

```python
snapshot = cookin.tokens.get(mint, fields=["ratings"])["data"]

if snapshot["ratings"]["bundle"] == "red":
    return  # coordinated supply

# Every token one deployer launched, with bond rate and peak market caps.
cookin.devs.tokens(deployer_address, limit=20)
```

``neutral`` means the metric has no reading yet, which is normal in a
token's first seconds. It is not a pass.

## Changelog

### 0.2.0

- ``tokens.agents()`` replaces ``tokens.survivors()``. The survivors route
  was removed from the API; calling ``survivors()`` now raises a clear
  error instead of returning a 404 at runtime.
- ``devs.tokens(address, limit=..., offset=...)`` for a deployer's launch
  history.
- ``ratings`` on every card and snapshot, and ``agent_bought_at`` /
  ``agent_buyer`` on cards from the agents feed.
- README corrected: the API is paid (Pro, or per call with x402), not free
  during beta.
