Metadata-Version: 2.4
Name: pax-api
Version: 2.2.1
Summary: Official Python SDK for the PredictAsiaX Trader Track API — Web3-native prediction markets
Author-email: PredictAsiaX <support@predictasiax.com>
License: MIT
Project-URL: Homepage, https://predictasiax.com/developer
Project-URL: Documentation, https://docs.predictasiax.com
Project-URL: Repository, https://github.com/predictasiax/pax-python-sdk
Project-URL: Issues, https://github.com/predictasiax/pax-python-sdk/issues
Project-URL: Changelog, https://docs.predictasiax.com/changelog
Keywords: predictasiax,pax,prediction-market,trading-api,web3,hmac,polymarket-compatible
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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: Topic :: Office/Business :: Financial :: Investment
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Requires-Dist: websocket-client>=1.5
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pytest-cov>=4; extra == "dev"
Requires-Dist: responses>=0.23; extra == "dev"
Requires-Dist: ruff>=0.1; extra == "dev"
Requires-Dist: mypy>=1; extra == "dev"
Requires-Dist: build>=1; extra == "dev"
Requires-Dist: twine>=4; extra == "dev"
Dynamic: license-file

# pax-api — Official Python SDK for PredictAsiaX

Web3-native prediction market REST + WebSocket API client. Polymarket-compatible HMAC signing pattern.

**Version 2.2.1** · MIT license · Python 3.8+

- **Docs**: https://docs.predictasiax.com
- **Verify**: https://docs.predictasiax.com/verify — public Merkle verifier over the operational ledger
- **Get API key**: https://predictasiax.com/settings/api-keys
- **Sandbox key (anonymous, 30 seconds)**: `POST /v1/sandbox-keys`
- **Support**: support@predictasiax.com

## Install

```bash
pip install pax-api
```

Upgrade:

```bash
pip install --upgrade pax-api
```

## Quickstart — sandbox key in 30 seconds (no email)

```python
from pax_api import PaxClient

# Mint an anonymous sandbox key
with PaxClient(env="sandbox") as pax:
    res = pax.mint_sandbox_key(org_name="my-app")
    key    = res["data"]["api_key"]
    tier   = res["data"]["tier"]           # e.g. "self_serve"
    limits = res["data"]["limits"]         # e.g. {"per_order_usdt": 10, "per_day_usdt": 100}

# Use the key
with PaxClient(api_key=key, env="sandbox") as pax:
    markets = pax.list_markets(category="crypto", limit=10)
    for m in markets["data"]["items"]:
        print(m["market_id"], m["question"])
```

Same production host either way (`api.predictasiax.com/v1`). Sandbox tier is enforced on the key — no prefix magic.

## Production trading (HMAC-signed)

Machine-to-machine bots use HMAC signing (Polymarket-compatible 5-header pattern):

```python
from pax_api import PaxClient

pax = PaxClient(
    api_key="sk_live_YOUR_KEY",
    secret="<64-hex secret>",
    passphrase="<passphrase>",
    env="production",
)

pax.place_order(
    market_id="m_...",
    outcome_id="yes",
    side="buy",
    order_type="limit",
    size="100",
    price="0.55",
    client_order_id="unique-per-intent-id",   # retry-safe within 24h
)
```

## Batch orders

Place or cancel up to 25 orders / 50 cancels per call:

```python
res = pax.place_orders_batch([
    {"market_id": "m_a", "outcome_id": "yes", "side": "buy",  "order_type": "limit", "size": "10", "price": "0.55"},
    {"market_id": "m_b", "outcome_id": "no",  "side": "sell", "order_type": "limit", "size": "20", "price": "0.42"},
])

for item in res["data"]["results"]:
    print(item["ok"], item.get("order_id"), item.get("error"))

pax.cancel_orders_batch([o["order_id"] for o in res["data"]["results"] if o["ok"]])
```

Env-driven caps: `BATCH_ORDERS_MAX` (default 25), `BATCH_CANCEL_MAX` (default 50).

## Fee estimator

Preview the 5-actor fee split before you place a trade — same shape returned post-trade:

```python
est = pax.estimate_fees(size="100", price="0.55")
print(est["data"]["fee_ledger"])
# {
#   "acquisition_builder_bps": 10, "execution_builder_bps": 10,
#   "operator_bps": 5, "market_creator_bps": 8, "lp_bps": 12,
#   "platform_net_bps": 5, "total_bps": 50,
#   "amounts": {"acquisition_builder": "0.055", ...},
#   "ledger_preview": {...}
# }
```

## Public Merkle verifier

Every fill is recorded in a hash-chained `event_log`, batched into a Merkle tree, and anchored to a public URL (R2). You (or any third party) can independently verify inclusion — no auth required.

```python
status = pax.audit_status()
print(status["data"])
# {"events": 110914, "batches": 7232, "anchored": 7231, ...}

# Get an inclusion proof for event seq=42
proof = pax.audit_proof(42)
leaf  = proof["data"]["leaf"]
root  = proof["data"]["root"]
path  = proof["data"]["proof"]

# Verify client-side (no server round-trip needed)
assert PaxClient.verify_merkle_proof(leaf=leaf, root=root, proof=path)

# Optional: fetch the signed batch anchor
anchor = pax.audit_anchor(proof["data"]["batch_num"])
print(anchor["data"]["url"])       # publicly fetchable
```

See https://docs.predictasiax.com/verify for the browser-side demo + 4-language snippets.

## WebSocket streams

```python
from pax_api import PaxWSClient

ws = PaxWSClient(
    api_key=key,
    env="sandbox",
    subscribe_on_connect=["fast_tick", "trade_executed", "account"],
)
ws.on("fast_tick",      lambda e: print("tick:", e))
ws.on("trade_executed", lambda e: print("trade:", e))
ws.on("account",        lambda e: print("balance:", e.get("balance_free")))
ws.run_forever()   # blocks; Ctrl+C to exit
```

Auto-reconnect + exponential backoff built-in. Client methods supported: `subscribe`, `unsubscribe`, `auth`, `set_locale`.

## Error handling

Every response error becomes a typed exception:

```python
from pax_api import (
    PaxClient,
    PaxRateLimitError,
    PaxReadOnlyModeError,
    PaxValidationError,
    PaxWrongEnvKeyError,
    PaxError,           # base class — catch-all
)

try:
    pax.place_order(...)
except PaxRateLimitError as e:
    time.sleep(e.retry_after or 5)
except PaxValidationError as e:
    print(f"Bad request: {e.details}")
except PaxReadOnlyModeError:
    print("Trading paused by ops")
except PaxWrongEnvKeyError:
    print("Wrong environment key")
except PaxError as e:
    print(f"[{e.code}] {e.message} (request_id={e.request_id})")
```

## Automatic retry

Built-in exponential backoff on `429`, `500`, `502`, `504`. `Retry-After` header respected on rate limits. Non-idempotent creates are safe when you send `client_order_id`.

```python
pax = PaxClient(api_key=key, env="sandbox", max_retries=5)
# max_retries=0 disables retries entirely
```

## Environments

| Env          | Base URL                             |
|--------------|--------------------------------------|
| `production` | `https://api.predictasiax.com/v1`    |
| `sandbox`    | `https://api.predictasiax.com/v1`    |

Sandbox and production share the same host. Sandbox tier is enforced on the key (`tier=self_serve`), which caps per-order / per-day USDT — see the `POST /v1/sandbox-keys` response `limits` field.

## Custom base URL

```python
pax = PaxClient(api_key="...", base_url="https://your-mirror/api/v1")
```

## Applications (progressive trust)

Move from sandbox → trade-capped → trade-full by submitting an application:

```python
res = pax.apply(track="trader", org="my-org", contact="team@my-org.io")
print(res["data"]["application_code"])   # save this

status = pax.get_application(res["data"]["application_code"])
print(status["data"]["status"])           # submitted → in_review → approved / declined
```

## Development

```bash
git clone https://github.com/predictasiax/pax-python-sdk
cd pax-python-sdk
pip install -e ".[dev]"
pytest                 # run all tests
ruff check src tests   # lint
mypy src               # type-check
```

## Links

- [OpenAPI spec](https://docs.predictasiax.com/openapi)
- [AsyncAPI (WebSocket) spec](https://docs.predictasiax.com/asyncapi)
- [Auth guide](https://docs.predictasiax.com/auth)
- [Verify (public Merkle verifier)](https://docs.predictasiax.com/verify)
- [Error codes](https://docs.predictasiax.com/errors)
- [Rate limits](https://docs.predictasiax.com/rate-limits)
- [FAQ](https://docs.predictasiax.com/faq)
- [Changelog](https://docs.predictasiax.com/changelog)
- [API Terms](https://docs.predictasiax.com/api-terms)

## License

MIT — see [LICENSE](LICENSE).
