Packages
polymarket_sdk
0.2.0
Higher-level Elixir SDK for Polymarket: Gamma market discovery, Data API, CTF/pUSD helpers, and convenience facades. Depends on polymarket_clob for the low-level CLOB surface.
Current section
Files
Jump to
Current section
Files
polymarket_sdk
CHANGELOG.md
CHANGELOG.md
# Changelog
## 0.2.0 - 2026-07-25
### Added
- **Convenience facade** on the top-level `Polymarket` module —
`defdelegate` re-exports of the common read-side calls:
`get_markets/get_market/get_events/get_event` (Gamma),
`get_positions/get_activity/get_trades` (Data API), and
`get_order_book/get_midpoint/get_tick_size` (CLOB market data).
Stateful surfaces (CTF, collateral, RTDS, RPC) deliberately stay
behind their explicit module names.
## 0.1.0
- Initial package scaffold.
- Depends on `polymarket_clob` for the low-level CLOB surface.
- Adds `Polymarket.Config` with shared Gamma and Data API host constants
(Data API host re-exports from `PolymarketClob.Config` to prevent drift).
- Adds `Polymarket.Gamma` — first read-only slice of Polymarket's Gamma
market-discovery API:
- `get_markets/1`, `get_market/2`, `get_events/1`, `get_event/2`.
- Tuple-shaped responses: `{:ok, body}`, `{:error, {:http_error, status, body}}`,
`{:error, {:transport_error, reason}}`. No `Polymarket.Error` struct yet.
- Default Req `:transient` retry on GETs; configurable per-call.
- Caller-provided query params via `:params` keyword option.
- Adds `Polymarket.HTTP` — shared transport helper extracted from
`Polymarket.Gamma` once `Polymarket.Data` introduced a second consumer.
Owns host/path composition, query param serialization, retry policy,
and tuple-shaped error normalization. `Polymarket.Gamma` now delegates
to it. The public surface is documented but user code should still
prefer the higher-level wrappers.
- Adds `Polymarket.Data` — read-only Polymarket Data API wrappers:
- `get_positions/2` (`/positions`), `get_activity/2` (`/activity`),
`get_trades/2` (`/trades`). All take a wallet address as the first
positional argument; the API is public and the address is passed
as a query parameter.
- Defaults aligned with the live bot at
`/Users/maxdon/Desktop/Elixir/polymarket_bot`:
`size_threshold: 0.1`, activity `limit: 1000`, trades `limit: 20`.
- Adds `Polymarket.Activity` and `Polymarket.Activity.Event` — pure
(no-HTTP) normalization and join helpers extracted from the live bot's
inlined `extract_activity_cost/3` at `polymarket_bot/lib/polymarket_bot/live.ex`:
- `normalize/1` turns raw `/activity` rows into typed `Event` structs,
accepting both camelCase and snake_case input keys.
- `cost_for_order/3` and `revenue_for_order/3` resolve `tx_hash` from
fills and sum fee-inclusive USDC across every matching activity row.
A legacy fallback matches activity by `orderHash` / `taker_order_id`
when fills are unavailable.
- `redemption_for_market/2` sums REDEEM payouts for a conditionId.
- All three return `nil` (not `0.0`) when no event matches, keeping
"no activity yet" distinct from "events summed to zero". Sums across
multiple matching events so GTC partial fills are correctly totalled.
- Adds `Polymarket.RTDS` — minimal real-time trade feed client ported
from v1 `PolymarketClob.RTDS`. Connects to
`wss://ws-live-data.polymarket.com`, subscribes to the global trades
topic, and forwards each trade payload to a callback PID as
`{:polymarket_rtds, :trade, payload}`. Configurable `:url` and
`:ping_interval`. Phase 10 keeps the surface narrow — no
backpressure / batching, no supervised reconnect strategy, no topic
generalization beyond trades, no `{module, function}` callback shape.
Reintroduces `:websockex` and `:jason` as direct deps.
- Adds `Polymarket.RLP` (Phase 11b) — hand-rolled Ethereum RLP encoder.
`encode_bytes/1`, `encode_integer/1`, `encode_list/1`. Validated
byte-for-byte against `ethers.encodeRlp` across 11 spec vectors
including empty / single-byte / 55- and 56-byte boundaries / 1024-byte
long form / empty list / 11-element long-list boundary.
- Adds `Polymarket.Tx` (Phase 11b) — legacy (type-0) EIP-155 Ethereum
transaction serialization and signing. `new/1`, `signing_payload/1`,
`signing_hash/1`, `sign/2`, `serialize/1`, `hash/1`. EIP-155 v
formula (`chain_id * 2 + 35 + yParity`). Validated against ethers.js
v6 across 5 fixture cases on Polygon (137) and Ethereum mainnet (1):
simple transfer, ERC-20 approve calldata, contract creation,
high-byte-nonce edge case, and a mainnet sanity check.
Reintroduces `:ex_secp256k1` as a direct runtime dep.
- EIP-1559 / type-2 transactions are intentionally **deferred** — not
needed for the planned CTF / pUSD on-chain helpers on Polygon.
- Phase 11b ships **only** RLP and tx serialization. JSON-RPC, nonce
management, gas estimation, and the public CTF / Collateral
submission wrappers all remain placeholder scope.
- Adds `Polymarket.RPC` (Phase 11c) — stateless JSON-RPC 2.0 client
for Polygon and any other EVM chain. `new/1` configures URL,
headers, timeout, and Req retry; `call/3` is the raw passthrough.
Typed helpers: `chain_id/1`, `block_number/1`, `gas_price/1`,
`nonce/2-3` (default block tag `"pending"`), `estimate_gas/2`,
`send_raw_transaction/2` (accepts hex string, raw binary, or a
signed `Polymarket.Tx` struct). Errors are tagged tuples:
`{:rpc_error, code, message, data}` for JSON-RPC protocol errors,
`{:http_error, status, body}` for non-2xx, `{:transport_error,
reason}` for Req-level failures, `{:invalid_response, body}` for
unparseable shapes. Default Req retry is OFF so a tx submission
doesn't accidentally double-spend nonce.
- Adds public submit wrappers (Phase 11d) — six `(rpc, opts)`
functions that compose Phase 11a calldata + Phase 11b legacy tx +
Phase 11c `eth_sendRawTransaction` into a single call:
- `Polymarket.ERC20.approve/2`
- `Polymarket.CTF.redeem_positions/2`, `merge_positions/2`,
`split_position/2`
- `Polymarket.Collateral.wrap/2`, `unwrap/2`
Each requires `:contract`, `:nonce`, `:gas_price`, `:gas_limit`,
`:chain_id`, `:private_key`, plus function-specific args.
Returns `{:ok, "0x"<>tx_hash}` from the RPC node or pass-through
`{:error, ...}` shapes from `Polymarket.RPC`. Phase 11d does NOT
auto-fetch nonce or gas — callers use `Polymarket.RPC.nonce/2`,
`gas_price/1`, `estimate_gas/2` first.
- Adds an internal submit helper (`@moduledoc false`) that the six
wrappers share. Not part of the public surface; callers who need
general contract-call submission should use `Polymarket.Tx` and
`Polymarket.RPC` directly.