diff --git a/CMakeLists.txt b/CMakeLists.txt index 2448435..977792f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ if(POLICY CMP0135) cmake_policy(SET CMP0135 NEW) endif() -project(polymarket_cpp_client VERSION 3.0.0 LANGUAGES CXX C) +project(polymarket_cpp_client VERSION 4.0.0 LANGUAGES CXX C) if(PROJECT_IS_TOP_LEVEL) set(CMAKE_CXX_STANDARD 20) diff --git a/README.md b/README.md index 8657f0c..2c6dc60 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,10 @@ Tick size and neg-risk metadata are resolved and cached for you. See | **Trading** | CLOB V2 EIP-712 order signing (EOA, proxy, Safe, `POLY_1271` deposit wallets), limit and market orders, batch posting, cancels, tick-size rounding | | **Order flow** | Book-walk fill estimates, one-call limit and market orders with post-only, GTD, and worst-price bounds, on-chain settlement waits | | **Market data** | REST books, prices, midpoints, markets, trades; WebSocket orderbook streaming with reconnect, subscription replay, gap detection, backpressure | +| **Discovery** | Typed `GammaClient` for markets, events, tags, series, sports, teams, search, comments, and profiles | +| **Data API** | Typed `DataClient` for wallet activity, positions, portfolio analytics, market data, and leaderboards | +| **Public streams** | `RtdsStream` for comments, reactions, and prices; `SportsStream` for live game results, with gap and recovery callbacks | +| **Pagination** | `Paginator` and CLOB, Gamma, and Data API pagers with page iteration, bounded collection, resume tokens, and explicit errors | | **User stream** | Authenticated `UserStream` with typed order/trade events, gap callbacks, and REST reconciliation hooks | | **On-chain positions** | `PositionClient` split/merge/redeem for CTF and Protocol V2, trading approvals, gasless Safe operations through the Polymarket relayer | | **Polygon indexing** | JSON-RPC HTTP catch-up + WebSocket subscriptions, persistent `EvmEventIndexer`, UMA and Conditional Tokens event decoders | @@ -114,7 +118,7 @@ include(FetchContent) FetchContent_Declare( polymarket_client GIT_REPOSITORY https://github.com/SebastianBoehler/polymarket-cpp-client.git - GIT_TAG v3.0.0 # or any release tag + GIT_TAG v4.0.0 # or any release tag ) FetchContent_MakeAvailable(polymarket_client) @@ -129,13 +133,13 @@ dependencies and headers: ```bash # macOS arm64 (use polymarket-cpp-client-linux-x64.tar.gz on Linux) -curl -LO https://github.com/SebastianBoehler/polymarket-cpp-client/releases/download/v3.0.0/polymarket-cpp-client-macos-arm64.tar.gz -mkdir -p polymarket-cpp-client-3.0.0 -tar -xzf polymarket-cpp-client-macos-arm64.tar.gz -C polymarket-cpp-client-3.0.0 +curl -LO https://github.com/SebastianBoehler/polymarket-cpp-client/releases/download/v4.0.0/polymarket-cpp-client-macos-arm64.tar.gz +mkdir -p polymarket-cpp-client-4.0.0 +tar -xzf polymarket-cpp-client-macos-arm64.tar.gz -C polymarket-cpp-client-4.0.0 ``` ```cmake -# cmake -S . -B build -DCMAKE_PREFIX_PATH=/absolute/path/to/polymarket-cpp-client-3.0.0 +# cmake -S . -B build -DCMAKE_PREFIX_PATH=/absolute/path/to/polymarket-cpp-client-4.0.0 find_package(polymarket_client REQUIRED) target_link_libraries(your_target PRIVATE polymarket::client) ``` @@ -391,6 +395,7 @@ Methodology and how to compare branches: [docs/benchmarks.md](docs/benchmarks.md | [CLOB V2 migration](docs/clob-v2-migration.md) | V2 order signing and exchange contracts | | [Benchmarks](docs/benchmarks.md) | Benchmark targets and methodology | | [Migration guide](docs/migration.md) | Upgrading between major versions | +| [v4.0.0 release notes](docs/releases/v4.0.0.md) | New APIs, compatibility changes, and validation limits | | [Protocol development](docs/protocol-development.md) | Rules for protocol, signing, and stream lifecycle work | | [Releasing](docs/releasing.md) | Release process for maintainers | diff --git a/docs/migration.md b/docs/migration.md index 35a1888..8ec2de8 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -3,6 +3,56 @@ Rebuild consumers against matching headers and libraries whenever you upgrade. Release notes for each version live in [`docs/releases/`](releases/). +## v4 + +The string-based `ClobClient` constructors now accept only chain 137. Code such +as `ClobClient(url, 80002)` throws `std::invalid_argument`; it previously paired +that chain ID with production exchange addresses. For another deployment, pass +an `Environment` containing its endpoints, chain ID, and contract addresses. +Changing only the URL in a string constructor still changes only the production +CLOB host, not the Data API or contracts. + +```cpp +#include +#include +#include + +const auto env = polymarket::Environment::production(); +polymarket::ClobClient client(env); +const auto stream_config = polymarket::Config::for_environment(env); +const auto position_config = polymarket::PositionClientConfig::for_environment(env); +``` + +For a fork or local chain, copy a preset and replace all endpoints and contracts +that differ before passing it to a client. `Environment::preproduction()` is +not a testnet: it uses Polygon mainnet and production contracts. Orders and +on-chain operations can use real funds, and API credentials are per environment. + +Rebuild all consumers and shared plugins against matching v4 headers and +libraries. Public layouts changed, including `ClobClient`, `MarketFetcher`, +`PolymarketContracts`, `HttpClientOptions`, `WebSocketOptions`, `WebSocketStats`, +`Config`, and `SdkError`. Include paths remain `` and the CMake +target remains `polymarket::client`. CMake package version checks reject a v3 +requirement against v4; update `find_package(polymarket_client 3 ...)` to request +version 4 if you specify a major version. + +Review these behavior changes when upgrading: + +- Rate-limited reads now retry HTTP 429 up to twice using `Retry-After`, subject + to a five-second maximum delay. Writes are not retried. Use + `set_rate_limit_retry(std::nullopt)` to disable read retries on `ClobClient`. +- Heartbeats no longer contribute to HTTP connection statistics or last-request + metrics. A caller-supplied `tick_size` is checked against a cached minimum + when available; otherwise the server validates it. +- Settlement waits require final transaction hashes for confirmed fills. A + confirmation without hashes triggers REST reconciliation and remains pending + if the hashes are still missing. +- `SdkErrorCode` adds `InsufficientLiquidity`, `Timeout`, and + `TransactionFailed`. Update exhaustive switches. + +See [the v4.0.0 release notes](releases/v4.0.0.md) for the new data clients, +pagers, streams, and trading helpers. + ## v3 Public headers now live under `polymarket/`. Update includes such as diff --git a/docs/releases/v4.0.0.md b/docs/releases/v4.0.0.md new file mode 100644 index 0000000..9b310f1 --- /dev/null +++ b/docs/releases/v4.0.0.md @@ -0,0 +1,135 @@ +# v4.0.0 + +This release adds typed Gamma and Data API clients, public RTDS and Sports +streams, reusable pagination, and trading setup and order-flow helpers. +It includes all changes since v3.0.0. + +## Migration and compatibility + +This is a major release because the string-based `ClobClient` constructors now +reject chain IDs other than 137. `ClobClient(url, 80002)` throws instead of +signing against production exchange addresses with a different chain ID. +Use an `Environment` with explicit endpoints and contracts for another +deployment. A string constructor changes only the production CLOB host. + +Rebuild consumers and shared plugins against matching v4 headers and libraries: +several public layouts changed, including client, config, transport option, +statistics, contract, and error types. Namespaced headers and the CMake target +`polymarket::client` are unchanged. Update CMake package requirements from major +version 3 to 4 where specified. See the [migration guide](https://github.com/SebastianBoehler/polymarket-cpp-client/blob/v4.0.0/docs/migration.md#v4). + +`Environment::production()` and `preproduction()` select endpoints and contracts +together. `Config::for_environment()` and +`PositionClientConfig::for_environment()` configure streams and positions from +the same deployment. Preproduction is not a testnet: it uses Polygon mainnet +and production contracts, so orders and on-chain operations can use real funds. +API credentials are per environment. + +## Data and discovery + +- `GammaClient` provides typed market and event discovery, lookups by ID, slug, + or URL, tags, series, sports, teams, search, comments, and public profiles. + Market lists skip non-binary markets. Position market resolution now uses + Gamma's keyset endpoint. +- `DataClient` covers trades, wallet activity, positions, portfolio value, + statistics, PnL, user volume, accounting snapshot downloads, holders, open + interest, live event volume, price history, resolutions, and leaderboards. + Data amounts use `double`; rows preserve their raw JSON. +- `Paginator` supports cursor, offset, keyset, and page-numbered APIs through + `next_page()`, bounded collection, range iteration, and resume tokens. + CLOB pagers expose markets, open orders, trades, and position lists. Inspect + `error()` after iteration and `truncated()` when an endpoint's offset cap is + reached. Items fetched before an error are retained. + +## Public streams + +- `SportsStream` delivers typed live game results, answers server text pings, + and reconnects after 30 seconds without frames. +- `RtdsStream` combines comment, reaction, Binance and Chainlink crypto-price, + Chainlink 30/60-second TWAP, and Pyth equity-price subscriptions. Server + subscriptions are shared, diffed while connected, and replayed on reconnect; + per-subscriber filters run locally. Full-accuracy string prices preserve + decimal precision, including exact scaling of Chainlink's 18-decimal integers. +- Both streams report gaps and recovery. Malformed Sports updates and malformed + RTDS events on supported topics report parser errors and trigger recovery. + RTDS stops further subscriber delivery when a callback stops the stream. + These public feeds do not replay missed events; reconcile application state + through REST when needed. +- `WebSocketOptions` adds configurable text pings, server-ping replies, and an + idle reconnect timeout. Existing CLOB heartbeat defaults are preserved. +- Gamma comment parsing now accepts integer-string `positionSize` values. + +RTDS's authenticated v2 price service and `activity` topic are not included. +The official SDKs deprecate the included RTDS price topics in favor of the +authenticated price service. + +## Trading and wallet setup + +- `PositionClient::get_trading_approvals_state()` reads missing token approvals. + `setup_trading_approvals()` grants only those still missing, using the shared + approval set from `required_trading_approvals()`. Low-level ERC-20 approval, + ERC-1155 operator approval, and ERC-20 transfer helpers are also available. +- `estimate_market_price()` simulates fills from REST or an existing book. + `place_limit_order()` supports GTC/GTD and post-only orders; + `place_market_order()` supports FAK/FOK and worst-price bounds. Book-priced + FOK orders reject insufficient liquidity before signing. +- `get_trade()` and `wait_for_order_fill_settlement()` track terminal fill + status and final transaction hashes. Confirmations without hashes reconcile + through REST and remain pending until final hashes arrive. Earlier MINED or + order-response hashes are not reused as final settlement evidence. +- Rate-limited reads retry HTTP 429 up to twice using `Retry-After`, with a + five-second maximum accepted delay. Writes are never retried automatically. + Rate-limit listeners expose server headers and enforcement warnings. +- `SdkErrorCode` adds `InsufficientLiquidity`, `Timeout`, and + `TransactionFailed`; update exhaustive switches. + +EOAs pay Polygon gas. Safe operations use the relayer and require +`RELAYER_API_KEY`. Safe batches are atomic; EOA batches can complete partially. +Approval setup grants maximum ERC-20 allowances and ERC-1155 operator access +to the configured contracts, including the perps deposit spender. That approval +does not add perps trading support. Position operations still support EOA and +Gnosis Safe wallets, not `POLY_PROXY`, `POLY_1271`, or combo positions. See the +[position guide](https://github.com/SebastianBoehler/polymarket-cpp-client/blob/v4.0.0/docs/position-operations.md) and [order-flow guide](https://github.com/SebastianBoehler/polymarket-cpp-client/blob/v4.0.0/docs/order-flow.md). + +## Networking and request behavior + +- REST and WebSocket connections support HTTP/HTTPS/SOCKS proxies and interface + binding through `set_default_network_route()` or per-client options. + Configured routes fail closed. Geoblock checks can reuse an HTTP client. +- HTTP responses can be compressed. Book responses seed tick-size and neg-risk + caches; off-grid prices invalidate only the tick cache. Market discovery reuses + Gamma clients. These changes remove redundant requests and connection setup. +- Orderbook parsing and signing avoid unnecessary copies and allocations. + HTTP heartbeats no longer affect connection statistics or last-request + metrics. Explicit tick sizes use cached minimum validation when available; + otherwise the server validates them. + +See the [networking guide](https://github.com/SebastianBoehler/polymarket-cpp-client/blob/v4.0.0/docs/networking.md) for route configuration and limits. + +## Validation and evidence limits + +The offline suite covers local HTTP/RPC/relayer fixtures, pagination, parsing, +stream recovery, callback shutdown, and installed-package consumers. ASan/UBSan +and libFuzzer checks cover REST and WebSocket parsers. Release publication is +gated on Linux x86-64 and macOS arm64 package builds and offline tests. + +Local release preparation passed 84/84 offline tests on macOS arm64 in Release, +including the installed-package consumer and both fuzz corpus replays. A +separate installed-package consumer linked the new clients and streams, +verified version 4.0.0, and checked the chain-80002 rejection without network +requests. The migration example compiled against the release headers. + +Contributors reported read-only live checks for production and preproduction +CLOB reads, book estimates, routed streams, Gamma and Data API responses, +Sports updates, and RTDS comments and crypto prices. Equity stream updates and +history, removed comments, and Sports finish timestamps have fixture coverage +only. The preproduction Gamma, Data API, and relayer were not validated live. +Order placement and settlement helpers have local fixture coverage; release +validation does not place orders or move funds. An approval setup transaction +was separately reported by the contributor, not executed by release CI. + +Thanks to Bill Luo (@yluoc) for the trading approvals, environment support, +rate-limit handling, order-flow helpers, parsers, pagination, data clients, +and public streams. + +[Full changes](https://github.com/SebastianBoehler/polymarket-cpp-client/compare/v3.0.0...v4.0.0) diff --git a/include/polymarket/version.hpp b/include/polymarket/version.hpp index b8da4a0..8246a3c 100644 --- a/include/polymarket/version.hpp +++ b/include/polymarket/version.hpp @@ -1,9 +1,9 @@ #pragma once -#define POLYMARKET_CLIENT_VERSION_MAJOR 3 +#define POLYMARKET_CLIENT_VERSION_MAJOR 4 #define POLYMARKET_CLIENT_VERSION_MINOR 0 #define POLYMARKET_CLIENT_VERSION_PATCH 0 -#define POLYMARKET_CLIENT_VERSION "3.0.0" +#define POLYMARKET_CLIENT_VERSION "4.0.0" namespace polymarket {