Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,38 @@

All notable changes to this project will be documented in this file.

## [2.49.1] - 2026-06-08

Positioning-shift patch on top of 2.49.0 — the hosted trading mode shipped in 2.49.0 but the docs, READMEs, and OpenAPI schemas still defaulted to the self-hosted sidecar path. This release flips the default everywhere the SDK + docs surface a customer hits: hosted PMXT is the primary experience; self-hosting becomes the advanced escape hatch. No SDK runtime behavior changes — pure documentation, schema, and copy work. Marketing-site changes ship separately in a sibling pmxt-website PR.

### Added

- **Docs**: 11 new MDX pages on the Mintlify site covering the hosted trading mode end-to-end — `trading-quickstart` (60-second walkthrough), `concepts/hosted-trading` (feature landing), `concepts/hosted-vs-self-hosted` (one-pager comparison), `concepts/catalog-uuid-vs-venue-id` (the UUID/venue-id gotcha), `guides/escrow-lifecycle` (PreFundedEscrow walkthrough), `guides/signing` (EthAccountSigner / EthersSigner + EIP-712), `guides/hosted-errors` (the 5 most-common subclasses with `try/except` cookbook), `guides/migrate-to-hosted-trading` (ported `MIGRATION.md` content with language tabs), `guides/self-hosted` (consolidated local-sidecar story), `api-reference/errors` (full `HostedTradingError` tree with dual-parent semantic-map), `api-reference/configuration` (`ExchangeOptions` + env vars + base-URL resolution).
- **Docs**: New "Hosted Trading" and "Self-host" sidebar groups in `docs.json`, plus a "Reference" group at the top of the API Reference tab. `sdk/server` moved out of the previous "SDK" group into "Self-host" (without slug rename — link-stability preserved for this release).
- **Core**: New `ExchangeOptions` component schema in `core/src/server/openapi.yaml` documenting constructor-level options (`pmxtApiKey`, `walletAddress`, `signer`, `privateKey`, `baseUrl`, etc.) — previously only `ExchangeCredentials` (per-request body credentials) existed at the schema level.
- **Core**: `BuiltOrder.expiry` field added to the OpenAPI schema (the TTL that triggers `BuiltOrderExpired` at submit time was implicit in the SDK and undocumented at the spec level).

### Changed

- **Docs**: `introduction.mdx` "It runs two ways" bullet order inverted — hosted listed first as the default, self-hosted second as the advanced path. First code block swapped from a dual-variant local/hosted snippet to a single hosted-default `pmxt.Polymarket(pmxt_api_key=...)` constructor.
- **Docs**: `authentication.mdx` venue-credentials section reframed — "Hosted writes (recommended)" subsection added on top showing the `pmxt_api_key + wallet_address + private_key` constructor with a one-line `client.escrow.deposit()` example. The raw-private-key prose was preserved but relabeled as "Self-hosted / direct venue credentials (advanced)". Status/body/meaning error table picked up a fourth "SDK exception" column cross-linking to the new `/api-reference/errors` page.
- **Docs**: `security.mdx` "Run pmxt locally" callout downgraded from `<Warning>` to `<Note>` and reworded — self-hosting is positioned as one option among several rather than the implicit "safer choice". PreFundedEscrow custody surfaced as the hosted alternative.
- **Docs**: `sdk/server.mdx` got a top `<Note>` banner clarifying that the page applies to self-hosted mode only and hosted-mode users can skip it. (File location and slug intentionally not renamed in this release to preserve external links.)
- **Docs**: `concepts/venues.mdx` gained a third table at the bottom — "Hosted-trading venues" — listing Polymarket and Opinion with custody type, cross-chain support, and minimum-order-size columns.
- **READMEs (root, Python, TypeScript)**: All three flipped to hosted-default. Subtitles, "Why pmxt?" bullets, Quick Start, and Trading sections now lead with `pmxt.Polymarket(pmxt_api_key=...)`. Per-venue raw-credentials blocks preserved verbatim but moved into "Self-hosted trading (advanced)" subsections. Root README's "No API key required" bullet (actively anti-hosted-positioning) replaced with a "Hosted API" lead bullet. Net +176 lines across the three files.

### Fixed

- **Core**: `Order` schema in `core/src/server/openapi.yaml` (and the generated `docs/api-reference/openapi.json`) now includes the nullable `txHash`, `chain`, and `blockNumber` fields the SDK has been returning in hosted mode since 2.49.0. Previous spec was silent on these and downstream codegen consumers missed them.
- **Core**: `UserTrade` schema gained the same `txHash` / `chain` / `blockNumber` nullable trio.
- **Core**: `Position` schema — `required` list trimmed from `[marketId, outcomeId, outcomeLabel, size, entryPrice, currentPrice, unrealizedPnL]` to `[marketId, outcomeId, size]`. The other four became optional in 2.49.0 when the SDK stopped fabricating mark-to-market defaults for positions without a known current price; the schema kept claiming they were required, so generated clients with strict-null checking were rejecting valid responses. New `currentValue` field added (`size * currentPrice` when available). `txHash` / `chain` / `blockNumber` enrichment added.
- **Core**: `Balance` schema gained the optional `venue` field that hosted-mode responses already carry on multi-venue queries.
- **Core**: `ErrorDetail` schema expanded from `{ message: string }` to the full envelope shipping in production responses — `code` (with a populated enum covering all `HostedTradingError` codes plus the pre-existing tree), `retryable: boolean`, optional `exchange`, optional free-form `detail` object. Downstream codegen can now branch on `code`.

### Docs

- **`docs.json`**: First-time `redirects` array added (empty for this release; reserves the structure for future slug renames).

## [2.49.0] - 2026-06-08

### Added
Expand Down
168 changes: 168 additions & 0 deletions docs/api-reference/configuration.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
---
title: Configuration
description: "Exchange constructor arguments, environment variables, and base-URL resolution rules."
---

The PMXT SDKs share one configuration surface across hosted and self-hosted modes. The same `ExchangeOptions` object selects mode, supplies credentials, and overrides defaults. Hosted is the default; self-hosted is the explicit fallback when no `pmxt_api_key` is present.

## ExchangeOptions

Constructor arguments, Python kwargs alongside TypeScript option keys.

### Hosted (the default)

| Python kwarg | TypeScript key | Type | Required? | Description |
| ------------ | -------------- | ---- | --------- | ----------- |
| `pmxt_api_key` | `pmxtApiKey` | `str` | Required for hosted | PMXT API key from [pmxt.dev/dashboard](https://pmxt.dev/dashboard). Triggers hosted mode. |
| `wallet_address` | `walletAddress` | `str` | Required for hosted writes + escrow | Address that owns the escrow balance and signs orders. |
| `private_key` | `privateKey` | `str` | Required for hosted writes | EVM private key used to sign EIP-712 typed-data locally. Auto-wrapped into a signer. |
| `signer` | `signer` | `Signer` | Optional (alt to `private_key`) | Custom signer implementing `sign_typed_data` / `signTypedData`. For hardware wallets, MPC, remote signing. |
| `base_url` | `baseUrl` | `str` | Optional | Override the default `https://api.pmxt.dev`. Rarely needed. |
| `trade_base_url` | `tradeBaseUrl` | `str` | Optional | Override the default `https://trade.pmxt.dev`. Rarely needed. |
| `timeout` | `timeout` | `float` (s) | Optional | Per-request timeout in seconds. Default 30. |

<CodeGroup>
```python Python
import pmxt

# Read-only: no private_key
read_only = pmxt.Polymarket(
pmxt_api_key="pmxt_live_...",
wallet_address="0xYourWallet...",
)

# Trading-capable: private_key auto-wraps into EthAccountSigner
trader = pmxt.Polymarket(
pmxt_api_key="pmxt_live_...",
wallet_address="0xYourWallet...",
private_key="0xYourPrivateKey...",
)

# Custom signer (hardware wallet, MPC, etc.)
trader = pmxt.Polymarket(
pmxt_api_key="pmxt_live_...",
wallet_address="0xYourWallet...",
signer=my_ledger_signer,
)
```

```typescript TypeScript
import { Polymarket } from "pmxtjs";

// Read-only
const readOnly = new Polymarket({
pmxtApiKey: "pmxt_live_...",
walletAddress: "0xYourWallet...",
});

// Trading-capable
const trader = new Polymarket({
pmxtApiKey: "pmxt_live_...",
walletAddress: "0xYourWallet...",
privateKey: "0xYourPrivateKey...",
});

// Custom signer
const traderCustom = new Polymarket({
pmxtApiKey: "pmxt_live_...",
walletAddress: "0xYourWallet...",
signer: myLedgerSigner,
});
```
</CodeGroup>

### Self-hosted (fallback)

When `pmxt_api_key` is absent, the SDK enters self-hosted mode and routes through the local `pmxt-core` server. Venue-native credentials apply here.

| Python kwarg | TypeScript key | Type | Description |
| ------------ | -------------- | ---- | ----------- |
| `private_key` | `privateKey` | `str` | EVM private key, for Polymarket / Limitless / Probable / Opinion / etc. |
| `api_key_id`, `private_key_pem` | `apiKeyId`, `privateKeyPem` | `str` | Kalshi RSA credentials. |
| `email`, `password` | `email`, `password` | `str` | Smarkets session credentials. |
| `local_port` | `localPort` | `int` | Override the default pmxt-core port (`3847`). |

See [Self-hosted](/guides/self-hosted) for per-venue credential examples.

## Environment variables

| Variable | Effect |
| -------- | ------ |
| `PMXT_API_KEY` | Default `pmxt_api_key` for all SDK clients. Explicit constructor arg wins. |
| `PMXT_BASE_URL` | Override `api.pmxt.dev`. Useful for staging environments. |
| `PMXT_TRADE_BASE_URL` | Override `trade.pmxt.dev`. Useful for staging hosted-trading environments. |
| `PMXT_LOCAL_PORT` | Override the local pmxt-core port (default `3847`). Self-hosted only. |
| `PMXT_ALWAYS_RESTART=1` | Force-restart the local pmxt-core on every `ensure_server_running` call. Useful during local SDK development. |
| `PMXT_TIMEOUT` | Default per-request timeout in seconds. |
| `PMXT_LOG_LEVEL` | Log verbosity for SDK + local server: `debug`, `info`, `warn`, `error`. |

<Info>
Constructor arguments always take precedence over environment variables. The env-var path is for ergonomics in deploy environments where you set `PMXT_API_KEY` once.
</Info>

## Base URL resolution

When the SDK makes a request, it picks one of three base URLs based on the operation and configuration:

1. **`trade.pmxt.dev` (hosted trading)** — used for `/v0/trade/*`, `/v0/user/*`, and `/v0/escrow/*` whenever `pmxt_api_key` is set. Override with `trade_base_url` or `PMXT_TRADE_BASE_URL`.
2. **`api.pmxt.dev` (hosted catalog + reads)** — used for `/v0/markets`, `/v0/events`, `/api/{venue}/*` whenever `pmxt_api_key` is set and the operation is not a hosted-trading write. Override with `base_url` or `PMXT_BASE_URL`.
3. **`http://localhost:3847` (self-hosted)** — used for **every** operation when `pmxt_api_key` is absent. Override port with `local_port` or `PMXT_LOCAL_PORT`.

### Precedence (highest to lowest)

1. Explicit constructor `base_url` / `trade_base_url`.
2. `PMXT_BASE_URL` / `PMXT_TRADE_BASE_URL` env var.
3. Default (`https://api.pmxt.dev` / `https://trade.pmxt.dev` / `http://localhost:3847`).

### Worked example

```python
import os
os.environ["PMXT_BASE_URL"] = "https://api-staging.pmxt.dev"

# Hosted mode (because pmxt_api_key is set); base_url comes from env
client = pmxt.Polymarket(pmxt_api_key="pmxt_test_...")
# → reads go to https://api-staging.pmxt.dev
# → trade writes still go to https://trade.pmxt.dev (PMXT_TRADE_BASE_URL not set)

# Self-hosted mode (no pmxt_api_key); env var ignored
local = pmxt.Polymarket(private_key="0x...")
# → reads + writes go to http://localhost:3847
```

## Hosted as default

The configuration philosophy:

- Setting `pmxt_api_key` (or `PMXT_API_KEY`) is the **single switch** that opts in to hosted mode. No other flag is required.
- All hosted-specific URLs default to PMXT's production endpoints — no setup beyond the API key.
- Self-hosted is the explicit fallback path. The SDK only attempts to spawn `pmxt-core` when no API key is configured.

The result: the **shortest correct config is hosted**. A single env var (`PMXT_API_KEY`) plus a constructor with a wallet and private key is everything you need to trade.

```python
# Minimum hosted trading config:
import os
os.environ["PMXT_API_KEY"] = "pmxt_live_..."

client = pmxt.Polymarket(
wallet_address="0x...",
private_key="0x...",
)
```

## Self-hosted fallback (advanced)

If you have specific reasons to run local — sub-100ms latency, raw venue credentials, regulatory custody — drop the API key. See [Self-hosted](/guides/self-hosted) for the full guide and [Server Management](/sdk/server) for lifecycle controls.

```python
# Self-hosted: no PMXT_API_KEY, no pmxt_api_key arg
client = pmxt.Polymarket(private_key="0x...")
```

## See also

- [Authentication](/authentication) — API keys and venue credentials.
- [Self-hosted](/guides/self-hosted) — running pmxt-core locally.
- [Server Management](/sdk/server) — local server lifecycle.
- [Hosted vs self-hosted](/concepts/hosted-vs-self-hosted) — when each mode applies.
Loading
Loading