# Client Reference

Complete reference for all `TurbineClient` methods, organized by access level.

## Public Data (No Auth)

These methods work with any client, including read-only clients with no credentials.

### get\_markets

Fetch all markets, optionally filtered by chain.

```python
markets = client.get_markets()
markets = client.get_markets(chain_id=137)

for m in markets:
    print(f"{m.question} | volume={m.volume / 1e6:.2f} USDC | resolved={m.resolved}")
```

| Parameter  | Type  | Required | Description        |
| ---------- | ----- | -------- | ------------------ |
| `chain_id` | `int` | No       | Filter by chain ID |

**Returns:** `list[Market]`

### get\_market

Get stats for a single market.

```python
stats = client.get_market(market_id="0x...")

print(f"Last price: {stats.last_price / 1e6:.4f} (${stats.last_price / 1e6:.4f})")
print(f"24h volume: {stats.volume_24h / 1e6:.2f} USDC")
print(f"Total volume: {stats.total_volume / 1e6:.2f} USDC")
```

| Parameter   | Type  | Required | Description            |
| ----------- | ----- | -------- | ---------------------- |
| `market_id` | `str` | Yes      | Market ID (hex string) |

**Returns:** `MarketStats`

### get\_orderbook

Get the orderbook snapshot for a market, optionally filtered by outcome.

```python
# Full orderbook (both outcomes)
ob = client.get_orderbook("0x...")

# YES side only
yes_ob = client.get_orderbook("0x...", outcome=Outcome.YES)

# Print top of book
if yes_ob.bids:
    best_bid = yes_ob.bids[0]
    print(f"Best bid: {best_bid.price} (${best_bid.price / 1e6:.4f}) x {best_bid.size / 1e6:.2f}")
if yes_ob.asks:
    best_ask = yes_ob.asks[0]
    print(f"Best ask: {best_ask.price} (${best_ask.price / 1e6:.4f}) x {best_ask.size / 1e6:.2f}")
```

| Parameter   | Type      | Required | Description                             |
| ----------- | --------- | -------- | --------------------------------------- |
| `market_id` | `str`     | Yes      | Market ID                               |
| `outcome`   | `Outcome` | No       | Filter by `Outcome.YES` or `Outcome.NO` |

**Returns:** `OrderBookSnapshot`

### get\_trades

Get recent trades for a market.

```python
trades = client.get_trades("0x...", limit=50)

for t in trades:
    side = "BUY" if t.outcome == 0 else "SELL"
    print(f"{side} {t.size / 1e6:.2f} @ {t.price} (${t.price / 1e6:.4f}) | tx={t.tx_hash}")
```

| Parameter   | Type  | Required | Description                           |
| ----------- | ----- | -------- | ------------------------------------- |
| `market_id` | `str` | Yes      | Market ID                             |
| `limit`     | `int` | No       | Max trades to return (default: `100`) |

**Returns:** `list[Trade]`

### get\_stats

Get statistics for a market. Alias for `get_market`.

| Parameter   | Type  | Required | Description |
| ----------- | ----- | -------- | ----------- |
| `market_id` | `str` | Yes      | Market ID   |

**Returns:** `MarketStats`

### get\_platform\_stats

Get platform-wide statistics across all chains.

```python
stats = client.get_platform_stats()

print(f"Total volume: {stats.total_volume / 1e6:.2f} USDC")
print(f"Total trades: {stats.total_trades}")

for chain in stats.chains:
    print(f"  Chain {chain.chain_id}: {chain.total_volume / 1e6:.2f} USDC")
```

**Returns:** `PlatformStats`

### get\_holders

Get top position holders for a market.

```python
holders = client.get_holders("0x...", limit=10)

for h in holders:
    print(f"{h.user_address}: YES={h.yes_shares / 1e6:.2f}, NO={h.no_shares / 1e6:.2f}")
```

| Parameter   | Type  | Required | Description                            |
| ----------- | ----- | -------- | -------------------------------------- |
| `market_id` | `str` | Yes      | Market ID                              |
| `limit`     | `int` | No       | Max holders to return (default: `100`) |

**Returns:** `list[Holder]`

### get\_resolution

Get resolution status for a market.

```python
res = client.get_resolution("0x...")

print(f"Resolved: {res.resolved}")
if res.resolved:
    outcome = "YES" if res.outcome == 0 else "NO"
    print(f"Winner: {outcome}")
    print(f"Assertion ID: {res.assertion_id}")
```

| Parameter   | Type  | Required | Description |
| ----------- | ----- | -------- | ----------- |
| `market_id` | `str` | Yes      | Market ID   |

**Returns:** `Resolution`

### get\_health

Check API server health.

```python
health = client.get_health()
print(health)
```

**Returns:** `dict`

### get\_quick\_market

Get the active quick market for an asset.

```python
qm = client.get_quick_market("BTC")

print(f"Market ID: {qm.market_id}")
print(f"Strike: ${qm.start_price / 1e8:,.2f}")
print(f"Ends: {qm.end_time}")
print(f"Contract: {qm.contract_address}")
```

| Parameter | Type  | Required | Description                     |
| --------- | ----- | -------- | ------------------------------- |
| `asset`   | `str` | Yes      | Asset symbol (`"BTC"`, `"ETH"`) |

**Returns:** `QuickMarket`

### get\_quick\_market\_history

Get historical quick markets for an asset.

```python
history = client.get_quick_market_history("BTC", limit=10)

for qm in history:
    outcome = "YES" if qm.outcome == 0 else ("NO" if qm.outcome == 1 else "N/A")
    print(f"ID={qm.id} | resolved={qm.resolved} | outcome={outcome}")
```

| Parameter | Type  | Required | Description                            |
| --------- | ----- | -------- | -------------------------------------- |
| `asset`   | `str` | Yes      | Asset symbol                           |
| `limit`   | `int` | No       | Max markets to return (default: `100`) |

**Returns:** `list[QuickMarket]`

### get\_quick\_market\_price

Get the current price for an asset.

```python
price = client.get_quick_market_price("BTC")
print(f"BTC: ${price.price / 1e8:,.2f}")
```

| Parameter | Type  | Required | Description  |
| --------- | ----- | -------- | ------------ |
| `asset`   | `str` | Yes      | Asset symbol |

**Returns:** `AssetPrice`

### get\_quick\_market\_price\_history

Get price history for an asset.

```python
prices = client.get_quick_market_price_history("BTC", limit=60)

for p in prices:
    print(f"  {p.timestamp}: ${p.price / 1e8:,.2f}")
```

| Parameter | Type  | Required | Description                           |
| --------- | ----- | -------- | ------------------------------------- |
| `asset`   | `str` | Yes      | Asset symbol                          |
| `limit`   | `int` | No       | Max prices to return (default: `100`) |

**Returns:** `list[AssetPrice]`

### get\_failed\_trades

Get all failed trade settlements.

```python
failed = client.get_failed_trades()
for t in failed:
    print(f"tx={t.tx_hash} | reason={t.reason} | size={t.fill_size}")
```

**Returns:** `list[FailedTrade]`

### get\_pending\_trades

Get all pending trade settlements.

```python
pending = client.get_pending_trades()
for t in pending:
    print(f"tx={t.tx_hash} | size={t.fill_size} | batch={t.is_batch}")
```

**Returns:** `list[PendingTrade]`

### get\_failed\_claims

Get all failed redemption claims.

**Returns:** `list[FailedClaim]`

### get\_pending\_claims

Get all pending redemption claims.

**Returns:** `list[PendingClaim]`

### get\_settlement\_status

Check the settlement status for a specific transaction.

```python
status = client.get_settlement_status("0xTxHash...")

print(f"Found: {status.found}")
print(f"Status: {status.status}")
print(f"Error: {status.error}")
```

| Parameter | Type  | Required | Description      |
| --------- | ----- | -------- | ---------------- |
| `tx_hash` | `str` | Yes      | Transaction hash |

**Returns:** `SettlementStatus`

***

## Order Management (Requires Signing)

These methods require a `private_key` in the client constructor (Level 1+).

### create\_order

Create and sign an order from an `OrderArgs` object.

```python
from turbine_client import OrderArgs, Outcome, Side
import time

args = OrderArgs(
    market_id="0x...",
    side=Side.BUY,
    outcome=Outcome.YES,
    price=500000,           # $0.50
    size=10000000,          # 10 shares
    expiration=int(time.time()) + 3600,
)

signed = client.create_order(args)
print(f"Order hash: {signed.order_hash}")
print(f"Signature: {signed.signature}")
```

| Parameter            | Type        | Required | Description                                                       |
| -------------------- | ----------- | -------- | ----------------------------------------------------------------- |
| `order_args`         | `OrderArgs` | Yes      | Order parameters                                                  |
| `settlement_address` | `str`       | No       | Override settlement address (auto-fetched from market if omitted) |

**Returns:** `SignedOrder`

### create\_limit\_buy

Convenience method for creating a signed buy order.

```python
signed = client.create_limit_buy(
    market_id="0x...",
    outcome=Outcome.YES,
    price=450000,       # $0.45
    size=5000000,       # 5 shares
    expiration=int(time.time()) + 3600,
)
```

| Parameter            | Type      | Required | Description                                      |
| -------------------- | --------- | -------- | ------------------------------------------------ |
| `market_id`          | `str`     | Yes      | Market ID                                        |
| `outcome`            | `Outcome` | Yes      | `Outcome.YES` or `Outcome.NO`                    |
| `price`              | `int`     | Yes      | Price (`1`–`999999`, where `500000` = $0.50)     |
| `size`               | `int`     | Yes      | Size in shares (6 decimals; `1000000` = 1 share) |
| `expiration`         | `int`     | No       | Unix timestamp (default: 1 hour from now)        |
| `settlement_address` | `str`     | No       | Override settlement address                      |

**Returns:** `SignedOrder`

### create\_limit\_sell

Same parameters and behavior as `create_limit_buy`, but creates a sell order.

**Returns:** `SignedOrder`

***

## Authenticated Endpoints (Requires Bearer Token)

These methods require `api_key_id` + `api_private_key` (Level 2). Bearer tokens are generated automatically per request.

### post\_order

Submit a signed order to the orderbook.

```python
signed = client.create_limit_buy(
    market_id="0x...",
    outcome=Outcome.YES,
    price=500000,
    size=1000000,
)

result = client.post_order(signed)
print(f"Response: {result}")
```

| Parameter      | Type          | Required | Description    |
| -------------- | ------------- | -------- | -------------- |
| `signed_order` | `SignedOrder` | Yes      | A signed order |

**Returns:** `dict` — API response with match/fill details

### get\_orders

Get orders, optionally filtered.

```python
# All open orders for a market
orders = client.get_orders(market_id="0x...", status="open")

# All orders by a specific trader
orders = client.get_orders(trader="0xAddress...")

for o in orders:
    side = "BUY" if o.side == 0 else "SELL"
    outcome = "YES" if o.outcome == 0 else "NO"
    print(f"{side} {outcome} | {o.remaining_size / 1e6:.2f} @ {o.price} (${o.price / 1e6:.4f}) | {o.status}")
```

| Parameter   | Type  | Required | Description                                 |
| ----------- | ----- | -------- | ------------------------------------------- |
| `trader`    | `str` | No       | Filter by trader address                    |
| `market_id` | `str` | No       | Filter by market ID                         |
| `status`    | `str` | No       | Filter: `"open"`, `"filled"`, `"cancelled"` |

**Returns:** `list[Order]`

### get\_order

Get a specific order by hash.

```python
order = client.get_order("0xOrderHash...")
print(f"Status: {order.status} | Filled: {order.filled_size / 1e6:.2f} / {order.size / 1e6:.2f}")
```

| Parameter    | Type  | Required | Description    |
| ------------ | ----- | -------- | -------------- |
| `order_hash` | `str` | Yes      | The order hash |

**Returns:** `Order`

### cancel\_order

Cancel a single order.

```python
result = client.cancel_order(
    order_hash="0x...",
    market_id="0x...",     # optional
    side=Side.BUY,         # optional
)
```

| Parameter    | Type   | Required | Description                 |
| ------------ | ------ | -------- | --------------------------- |
| `order_hash` | `str`  | Yes      | The order hash              |
| `market_id`  | `str`  | No       | Market ID (for validation)  |
| `side`       | `Side` | No       | Order side (for validation) |

**Returns:** `dict`

### cancel\_market\_orders

Cancel all your orders for a market.

```python
result = client.cancel_market_orders(market_id="0x...")
```

| Parameter   | Type  | Required | Description |
| ----------- | ----- | -------- | ----------- |
| `market_id` | `str` | Yes      | Market ID   |

**Returns:** `dict`

### get\_positions

Get positions for a market, optionally filtered by user.

```python
positions = client.get_positions(market_id="0x...", user_address="0x...")

for p in positions:
    print(f"YES: {p.yes_shares / 1e6:.2f} shares (cost: {p.yes_cost / 1e6:.2f} USDC)")
    print(f"NO:  {p.no_shares / 1e6:.2f} shares (cost: {p.no_cost / 1e6:.2f} USDC)")
```

| Parameter      | Type  | Required | Description            |
| -------------- | ----- | -------- | ---------------------- |
| `market_id`    | `str` | Yes      | Market ID              |
| `user_address` | `str` | No       | Filter by user address |

**Returns:** `list[Position]`

### get\_user\_positions

Get all positions across markets for a user.

```python
positions = client.get_user_positions(address="0x...", chain_id=137)

for p in positions:
    print(f"Market {p.market_id[:16]}... | YES={p.yes_shares / 1e6:.2f} | NO={p.no_shares / 1e6:.2f}")
```

| Parameter  | Type  | Required | Description        |
| ---------- | ----- | -------- | ------------------ |
| `address`  | `str` | Yes      | User address       |
| `chain_id` | `int` | No       | Filter by chain ID |

**Returns:** `list[Position]`

### get\_user\_orders

Get all orders for a user.

| Parameter | Type  | Required | Description                                 |
| --------- | ----- | -------- | ------------------------------------------- |
| `address` | `str` | Yes      | User address                                |
| `status`  | `str` | No       | Filter: `"open"`, `"filled"`, `"cancelled"` |

**Returns:** `list[Order]`

### get\_user\_activity

Get trading activity summary for a user.

```python
activity = client.get_user_activity("0x...")

print(f"Total trades: {activity.total_trades}")
print(f"Total volume: {activity.total_volume / 1e6:.2f} USDC")
print(f"PNL: {activity.pnl / 1e6:.2f} USDC")
print(f"Markets traded: {activity.markets_traded}")
```

| Parameter | Type  | Required | Description  |
| --------- | ----- | -------- | ------------ |
| `address` | `str` | Yes      | User address |

**Returns:** `UserActivity`

### get\_user\_stats

Get statistics for the authenticated user.

```python
stats = client.get_user_stats()

print(f"Total cost: {stats.total_cost / 1e6:.2f} USDC")
print(f"Position value: {stats.position_value / 1e6:.2f} USDC")
print(f"PNL: {stats.pnl / 1e6:.2f} USDC ({stats.pnl_percentage:.1f}%)")
```

**Returns:** `UserStats`

***

## Gasless / Relayer Operations

These methods sign EIP-712 permits and submit them to the relayer for gasless execution. Requires Level 2 access (private key + API credentials). No native gas tokens are needed.

### approve\_usdc\_for\_settlement

Sign and submit a gasless max USDC permit. One-time per settlement contract — all future orders reuse the allowance.

```python
result = client.approve_usdc_for_settlement()
print(f"TX: {result}")

# With explicit settlement address
result = client.approve_usdc_for_settlement(
    settlement_address="0xdB96C91d9e5930fE3Ed1604603CfA4ece454725c"
)
```

| Parameter            | Type  | Required | Description                                    |
| -------------------- | ----- | -------- | ---------------------------------------------- |
| `settlement_address` | `str` | No       | Settlement contract (defaults to chain config) |

**Returns:** `dict` — Relayer response with `tx_hash`

### approve\_ctf\_for\_settlement

Sign and submit a gasless CTF `SetApprovalForAll` permit to let the settlement contract transfer your conditional tokens.

```python
result = client.approve_ctf_for_settlement()
```

| Parameter            | Type  | Required | Description                                    |
| -------------------- | ----- | -------- | ---------------------------------------------- |
| `settlement_address` | `str` | No       | Settlement contract (defaults to chain config) |

**Returns:** `dict` — Relayer response with `tx_hash`

### sign\_usdc\_permit

Sign an EIP-2612 permit for a specific USDC amount. Use this for per-order permits instead of the max permit.

```python
permit = client.sign_usdc_permit(
    value=10000000,  # $10 USDC
)

# Attach to a signed order before submission
signed_order.permit_signature = permit
result = client.post_order(signed_order)
```

| Parameter            | Type  | Required | Description                                         |
| -------------------- | ----- | -------- | --------------------------------------------------- |
| `value`              | `int` | Yes      | Amount to approve (6 decimals; `1000000` = $1 USDC) |
| `settlement_address` | `str` | No       | Spender address (defaults to chain config)          |
| `deadline`           | `int` | No       | Expiration timestamp (default: 1 hour from now)     |

**Returns:** `PermitSignature`

### approve\_usdc

On-chain USDC approval (requires native gas). Alternative to permit-based approval for high-frequency scenarios.

```python
tx_hash = client.approve_usdc(amount=2**256 - 1)  # Max approval
print(f"TX: {tx_hash}")
```

| Parameter | Type  | Required | Description                              |
| --------- | ----- | -------- | ---------------------------------------- |
| `amount`  | `int` | Yes      | Amount to approve (6 decimals)           |
| `spender` | `str` | No       | Spender address (defaults to settlement) |

**Returns:** `str` — Transaction hash

### get\_usdc\_allowance

Query the current USDC allowance for a spender.

```python
allowance = client.get_usdc_allowance()
print(f"Allowance: {allowance / 1e6:.2f} USDC")
```

| Parameter | Type  | Required | Description                               |
| --------- | ----- | -------- | ----------------------------------------- |
| `owner`   | `str` | No       | Token owner (defaults to signer address)  |
| `spender` | `str` | No       | Spender (defaults to settlement contract) |

**Returns:** `int` — Allowance in USDC (6 decimals)

### claim\_winnings

Claim winnings from a single resolved market via gasless permit.

```python
result = client.claim_winnings(
    market_contract_address="0xMarketContractAddress..."
)
print(f"TX: {result}")
```

This method:

{% stepper %}
{% step %}

### Query on-chain

Queries the market contract on-chain for resolution status and condition data.
{% endstep %}

{% step %}

### Check balance

Checks your balance of the winning token.
{% endstep %}

{% step %}

### Sign permit

Signs an EIP-712 `RedeemPositions` permit.
{% endstep %}

{% step %}

### Submit to relayer

Submits to the relayer for gasless execution.
{% endstep %}
{% endstepper %}

| Parameter                 | Type  | Required | Description                                   |
| ------------------------- | ----- | -------- | --------------------------------------------- |
| `market_contract_address` | `str` | Yes      | The market's contract address (not market ID) |

**Returns:** `dict` — Relayer response with `tx_hash`

**Raises:** `ValueError` if the market is not resolved or you have no winning tokens.

### batch\_claim\_winnings

Claim winnings from multiple resolved markets in a single batch transaction.

```python
result = client.batch_claim_winnings([
    "0xMarket1ContractAddress...",
    "0xMarket2ContractAddress...",
    "0xMarket3ContractAddress...",
])
print(f"TX: {result}")
```

Markets that are not resolved or where you have no winning tokens are skipped automatically.

| Parameter                   | Type        | Required | Description                       |
| --------------------------- | ----------- | -------- | --------------------------------- |
| `market_contract_addresses` | `list[str]` | Yes      | List of market contract addresses |

**Returns:** `dict` — Relayer response with `txHash`

### sync\_permit\_nonce

Resync the local permit nonce with the blockchain. Use after a permit failure or when nonces get out of sync.

```python
nonce = client.sync_permit_nonce()
print(f"On-chain nonce: {nonce}")
```

| Parameter          | Type  | Required | Description                       |
| ------------------ | ----- | -------- | --------------------------------- |
| `contract_address` | `str` | No       | Token contract (defaults to USDC) |

**Returns:** `int` — The current on-chain nonce

***

## Static Methods

### request\_api\_credentials

Register for API credentials by proving wallet ownership. This is a static method — no client instance needed.

```python
creds = TurbineClient.request_api_credentials(
    host="https://api.turbinefi.com",
    private_key="0xYourPrivateKey",
    name="my-trading-bot",  # optional
)

print(f"Key ID: {creds['api_key_id']}")
print(f"Private Key: {creds['api_private_key']}")
```

| Parameter     | Type  | Required | Description                   |
| ------------- | ----- | -------- | ----------------------------- |
| `host`        | `str` | Yes      | API base URL                  |
| `private_key` | `str` | Yes      | Wallet private key            |
| `name`        | `str` | No       | Friendly name for the API key |

**Returns:** `dict` with `api_key_id`, `api_private_key`, `message`

**Raises:** `TurbineApiError` with status `409` if the wallet already has a key.
