Metadata-Version: 2.4
Name: flipcoin-langchain
Version: 0.1.0
Summary: LangChain tools for FlipCoin prediction markets Agent API
Project-URL: Homepage, https://flipcoin.fun
Project-URL: Repository, https://github.com/flipcoin-fun/flipcoin-langchain
Project-URL: Documentation, https://flipcoin.fun/docs
Author-email: FlipCoin <dev@flipcoin.fun>
License-Expression: MIT
License-File: LICENSE
Keywords: agent,flipcoin,langchain,prediction-markets,tools
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.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: flipcoin>=0.1.0
Requires-Dist: langchain-core<1,>=0.3
Requires-Dist: pydantic<3,>=2.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# flipcoin-langchain

LangChain tools for [FlipCoin](https://www.flipcoin.fun) prediction markets. Allows any LangChain agent to discover markets, trade YES/NO shares, manage portfolio positions, and more.

[![PyPI](https://img.shields.io/pypi/v/flipcoin-langchain)](https://pypi.org/project/flipcoin-langchain/)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/)

## Prerequisites

- **Python 3.10+**
- **FlipCoin API key** (`fc_...`) — get yours at [flipcoin.fun/app/agents](https://www.flipcoin.fun/app/agents). Create an agent profile and click **"Generate Key"**. The key is shown **only once** — save it immediately.
- **LLM API key** — e.g. `OPENAI_API_KEY` for GPT-4o, or any LangChain-compatible model.

## Installation

```bash
pip install flipcoin-langchain
```

This installs both `flipcoin-langchain` (LangChain tools) and the [`flipcoin`](https://pypi.org/project/flipcoin/) Python SDK (low-level HTTP client). You do **not** need to install them separately.

## Quick Start

```bash
export FLIPCOIN_API_KEY="fc_..."
export OPENAI_API_KEY="sk-..."
```

```python
import os
from flipcoin_langchain import FlipCoinToolkit
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

# Create toolkit — reads API key from environment
toolkit = FlipCoinToolkit(api_key=os.environ["FLIPCOIN_API_KEY"])
tools = toolkit.get_tools()

# Create a LangChain agent
llm = ChatOpenAI(model="gpt-4o")
agent = create_react_agent(llm, tools)

# Run it
result = agent.invoke({
    "messages": [("user", "Show me the top trending markets and my vault balance")]
})
```

## Available Tools (14)

### Markets
| Tool | Description |
|------|-------------|
| `flipcoin_get_markets` | Search and list prediction markets with filtering and sorting |
| `flipcoin_get_market_details` | Get full details for a specific market (question, prices, trades) |
| `flipcoin_get_market_state` | Get live LMSR AMM state (prices, liquidity, slippage curve) |
| `flipcoin_create_market` | Create a new YES/NO prediction market |

### Trading
| Tool | Description |
|------|-------------|
| `flipcoin_get_quote` | Preview a trade without executing (price, shares, fees, slippage) |
| `flipcoin_trade` | Execute a buy or sell trade via LMSR AMM or CLOB |
| `flipcoin_create_order` | Place a limit order on the CLOB order book |
| `flipcoin_cancel_order` | Cancel an open limit order |

### Portfolio
| Tool | Description |
|------|-------------|
| `flipcoin_get_portfolio` | View all positions with P&L |
| `flipcoin_redeem_positions` | Redeem winning shares from resolved markets |

### Vault
| Tool | Description |
|------|-------------|
| `flipcoin_get_vault_balance` | Check available USDC balance |
| `flipcoin_deposit` | Deposit USDC into the trading vault |

### Resolution
| Tool | Description |
|------|-------------|
| `flipcoin_propose_resolution` | Propose YES/NO outcome for a market you created |
| `flipcoin_finalize_resolution` | Finalize resolution after 24h dispute period |

## Key Concepts

- **Prices** are in basis points (bps): `5000` = 50%, `10000` = 100%
- **USDC amounts** are human-readable decimal strings: `"5.0"` = $5 USDC. The tools automatically convert to the raw 6-decimal format required by the API (e.g., `"5.0"` becomes `"5000000"`)
- **condition_id** is the primary market identifier (bytes32 hex) — required for trading and resolution
- **address** is the on-chain contract address (0x hex) — used for market details and state
- **Sides**: `"yes"` or `"no"`
- **Actions**: `"buy"` or `"sell"`

## Tool Response Examples

All tools return **JSON strings** — never raise exceptions. Parse the result and check for the `"error"` key:

```python
import json

result_str = tool.invoke({...})
result = json.loads(result_str)

if "error" in result:
    print(f"Error: {result['error']}")
else:
    # Use the data
    ...
```

### `flipcoin_get_markets`

```json
{
  "markets": [
    {
      "id": "uuid",
      "marketAddr": "0x1234...abcd",
      "conditionId": "0xabcdef...64hex",
      "title": "Will BTC reach $100k by end of 2026?",
      "description": "...",
      "status": "open",
      "volumeUsdc": 5000000000,
      "liquidityUsdc": 139000000,
      "tradesCount": 42,
      "createdAt": "2026-02-17T10:00:00Z",
      "resolveEndAt": "2026-12-31T23:59:59Z",
      "resolvedOutcome": null,
      "creatorAddr": "0x...",
      "fingerprint": "abc123def456"
    }
  ],
  "pagination": { "offset": 0, "limit": 50, "total": 100 }
}
```

### `flipcoin_get_quote`

```json
{
  "conditionId": "0xabc...",
  "side": "yes",
  "action": "buy",
  "amount": "10000000",
  "venue": "clob",
  "reason": "CLOB preferred, 12 bps better",
  "lmsr": {
    "available": true,
    "sharesOut": "10500000",
    "fee": "150000",
    "avgPriceBps": 4900,
    "priceImpactBps": 100
  },
  "clob": {
    "available": true,
    "canFillFull": true,
    "sharesOut": "11200000",
    "avgPriceBps": 4821,
    "bestBidBps": 4700,
    "bestAskBps": 4800,
    "spreadBps": 100
  }
}
```

### `flipcoin_trade`

```json
{
  "intentId": "uuid",
  "status": "confirmed",
  "venue": "lmsr",
  "txHash": "0x...",
  "sharesOut": "10500000",
  "feeUsdc": "150000",
  "nextNonce": "5"
}
```

### `flipcoin_get_portfolio`

```json
{
  "positions": [
    {
      "marketAddr": "0x...",
      "title": "Will BTC reach $100k?",
      "status": "open",
      "netSide": "yes",
      "netShares": 8,
      "avgEntryPriceUsdc": 0.3125,
      "currentPriceBps": 6000,
      "currentValueUsdc": 4,
      "pnlUsdc": 1
    }
  ],
  "totals": {
    "marketsActive": 3,
    "marketsResolved": 1
  }
}
```

### `flipcoin_get_vault_balance`

```json
{
  "vaultBalance": "50000000",
  "walletBalance": "1000000000"
}
```

### Error Response

```json
{
  "error": "INSUFFICIENT_BALANCE: vault balance too low"
}
```

Error messages include the error code prefix (e.g. `INSUFFICIENT_BALANCE`, `RATE_LIMITED`, `MARKET_NOT_OPEN`) — agents can parse these for programmatic handling.

## Trading Venues: LMSR vs CLOB

FlipCoin has two trading venues. The `flipcoin_get_quote` tool returns both and recommends the best one.

### LMSR AMM (`flipcoin_trade`)

Automated market maker with guaranteed liquidity:
- Deterministic pricing — always available, instant execution
- Best for small-to-medium trades
- Price impact increases with trade size
- Fee: 0.5% (takerFeeBps=50)
- The `venue` parameter defaults to `"lmsr"` or auto-routes if omitted

### CLOB Order Book (`flipcoin_create_order`)

Central Limit Order Book for price-specific orders:
- You set the exact limit price (`price_bps`)
- Maker orders (resting on book): **0% fee**
- Taker orders: 0.5% fee
- Time-in-force: `GTC` (default), `IOC` (Immediate-Or-Cancel), `FOK` (Fill-Or-Kill)
- May partially fill depending on available liquidity

### When to Use Which

| Scenario | Venue | Why |
|----------|-------|-----|
| Quick trade, any size up to ~$1k | LMSR | Guaranteed fill, instant |
| Want a specific price | CLOB | Limit orders sit until filled |
| Large trade (>$1k) | Check `flipcoin_get_quote` | Auto-routes for best execution |
| Providing liquidity | CLOB | 0% maker fee |

## Complete Workflow Example

Real agent workflow: discover → analyze → quote → trade → monitor → redeem.

```python
import json
import os
from flipcoin_langchain import FlipCoinToolkit

toolkit = FlipCoinToolkit(api_key=os.environ["FLIPCOIN_API_KEY"])
tools = toolkit.get_tools()

# Helper: find tool by name
def tool(name: str):
    return next(t for t in tools if t.name == name)

# 1. Check vault balance first
balance = json.loads(tool("flipcoin_get_vault_balance").invoke({}))
print(f"Vault: {int(balance['vaultBalance']) / 1e6:.2f} USDC")

# 2. Find trending open markets
markets = json.loads(tool("flipcoin_get_markets").invoke({
    "status": "open",
    "sort": "trending",
    "limit": 5,
}))
market = markets["markets"][0]
condition_id = market["conditionId"]
address = market["marketAddr"]
print(f"Market: {market['title']}")

# 2b. Get detailed market info (includes live prices)
details = json.loads(tool("flipcoin_get_market_details").invoke({
    "address": address,
}))
price_yes = details["market"]["currentPriceYesBps"]
print(f"YES: {price_yes / 100:.0f}%")

# 3. Get a quote before trading
quote = json.loads(tool("flipcoin_get_quote").invoke({
    "condition_id": condition_id,
    "side": "yes",
    "action": "buy",
    "amount": "5.0",
}))
if "error" in quote:
    print(f"Quote failed: {quote['error']}")
else:
    print(f"Shares: {int(quote['lmsr']['sharesOut']) / 1e6:.2f}")
    print(f"Price impact: {quote['lmsr']['priceImpactBps']} bps")

    # 4. Execute the trade
    trade = json.loads(tool("flipcoin_trade").invoke({
        "condition_id": condition_id,
        "side": "yes",
        "usdc_amount": "5.0",
    }))
    if "error" in trade:
        print(f"Trade failed: {trade['error']}")
    else:
        print(f"Trade confirmed: {trade['txHash']}")

# 5. Check portfolio after trading
portfolio = json.loads(tool("flipcoin_get_portfolio").invoke({"status": "open"}))
for pos in portfolio.get("positions", []):
    print(f"  {pos['title']}: {pos['netSide']} {pos['netShares']} shares, P&L: ${pos['pnlUsdc']}")

# 6. Redeem resolved positions
resolved = json.loads(tool("flipcoin_get_portfolio").invoke({"status": "resolved"}))
for pos in resolved.get("positions", []):
    payout = json.loads(tool("flipcoin_redeem_positions").invoke({
        "condition_id": pos.get("conditionId", ""),
    }))
    print(f"Redeemed: {payout}")
```

## Agent Design Patterns

Best practices for building reliable trading agents:

1. **Always check balance first** — call `flipcoin_get_vault_balance` at the start of each session
2. **Quote before trade** — call `flipcoin_get_quote` before `flipcoin_trade` to preview price impact and fees
3. **Store `condition_id`** — after discovering a market, save its `conditionId` for subsequent operations (quote, trade, redeem)
4. **Handle errors gracefully** — all tools return JSON, check for `"error"` key before proceeding
5. **Respect rate limits** — avoid calling tools in tight loops (see [Rate Limits](#rate-limits) below)
6. **Use the right venue** — let `flipcoin_get_quote` recommend the venue, or use CLOB for limit orders
7. **Resolution workflow** — `propose_resolution` → wait 24h → `finalize_resolution` (cannot skip dispute period)

## Error Handling

All tools return JSON strings — they **never raise exceptions** to the LLM. On failure, the response contains an `"error"` key with a human-readable message that includes the error code:

```python
result = json.loads(trade_tool.invoke({...}))
if "error" in result:
    error_msg = result["error"]
    # Error codes are prefixed: "INSUFFICIENT_BALANCE: vault balance too low"
    if "INSUFFICIENT_BALANCE" in error_msg:
        # Deposit more funds
        ...
    elif "RATE_LIMITED" in error_msg:
        # Back off and retry
        ...
```

### Common Error Codes

| Code | Meaning |
|------|---------|
| `INSUFFICIENT_BALANCE` | Vault USDC balance too low for the trade |
| `RATE_LIMITED` / `RATE_LIMIT_EXCEEDED` | Too many requests — back off and retry |
| `MARKET_NOT_OPEN` | Market is paused, pending, or resolved |
| `INTENT_EXPIRED` | Quote/intent became stale (LMSR intents: 15s) — get a new quote |
| `PRICE_IMPACT_EXCEEDED` | Trade exceeds 30% price impact limit — reduce size |
| `ORDER_TOO_SMALL` | Order below minimum dust threshold |
| `NOT_DELEGATED` | Session key not registered on-chain |
| `DAILY_LIMIT_EXCEEDED` | Daily delegation spend limit exceeded |
| `BadNonce` | Intent nonce mismatch — get fresh nonce |
| `RELAY_NOT_CONFIGURED` | Relay service not available (503) |

## Rate Limits

The Agent API enforces rate limits per API key. Response headers include `X-RateLimit-Remaining` and `Retry-After` (on 429).

| Class | Limit | Endpoints |
|-------|-------|-----------|
| Read | 60 req/min (burst: 120/10s) | `get_markets`, `get_market_details`, `get_market_state`, `get_portfolio`, `get_vault_balance` |
| Trade | 120 req/hr (burst: 10/10s) | `trade`, `create_order`, `cancel_order`, `deposit` |
| Create | 20 req/hr, 50/day | `create_market` |

> **Note:** `flipcoin_get_quote` calls the public quote endpoint which is IP-rate-limited (not counted against your API key quota). `propose_resolution` and `finalize_resolution` use the relay class (30 req/hr).

For autonomous agents, implement exponential backoff when you encounter `RATE_LIMITED` errors.

## Using a Pre-built Client

If you need custom configuration, you can pass a pre-built [`flipcoin`](https://pypi.org/project/flipcoin/) SDK client:

```python
from flipcoin import FlipCoin
from flipcoin_langchain import FlipCoinToolkit

client = FlipCoin(api_key="fc_...", base_url="https://www.flipcoin.fun")
toolkit = FlipCoinToolkit(client=client)
tools = toolkit.get_tools()
```

> **Note:** The `flipcoin` package (PyPI: [`flipcoin`](https://pypi.org/project/flipcoin/)) is the low-level HTTP SDK. `flipcoin-langchain` wraps it as LangChain tools with input validation, USDC conversion, and error handling.

## Using Individual Tools

```python
from flipcoin import FlipCoin
from flipcoin_langchain import FlipCoinGetMarkets, FlipCoinTrade

client = FlipCoin(api_key="fc_...")

# Use tools individually
markets_tool = FlipCoinGetMarkets(client=client)
result = markets_tool.invoke({"status": "open", "sort": "trending"})

trade_tool = FlipCoinTrade(client=client)
result = trade_tool.invoke({
    "condition_id": "0x...",
    "side": "yes",
    "usdc_amount": "5.0",
})
```

## Examples

See the [`examples/`](examples/) directory:

- **[`langchain_agent.py`](examples/langchain_agent.py)** — Complete LangChain ReAct agent with system prompt, tool loading, and conversation loop

## Development

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run tests with coverage
pytest --cov=flipcoin_langchain
```

## Links

- [FlipCoin Platform](https://www.flipcoin.fun) — Main app
- [Agent API Documentation](https://www.flipcoin.fun/docs) — Full API reference
- [FlipCoin Python SDK](https://pypi.org/project/flipcoin/) — Low-level HTTP client (`flipcoin`)

## License

MIT
