POST /info), the signed write API
(POST /exchange), and the realtime WebSocket streams behind two typed client
classes. Authentication is EIP-712 wallet signing (secp256k1) — there are no
API keys to manage.
upsidemax/upside-python-sdk
Source, examples, and issue tracker on GitHub. MIT licensed.
- EIP-712 request signing across the Agent and Typed paths — handled for you.
- Synchronous REST with a threaded WebSocket client that auto-reconnects.
- Raw-dict responses, typed inputs, and full type hints (ships
py.typed). - Agent (API-wallet) delegation, TP/SL, leverage / margin, and collateral actions.
Installation
requests, websocket-client,
eth-account, eth-utils.
Quick start
The two clients
Info — reads & streams
Market data, account and order queries, and realtime WebSocket
subscriptions. No wallet or signing required.
Exchange — signed writes
Orders, cancels, margin and leverage, TP/SL, collateral, and agent
delegation — every call signed with your wallet key.
Key behaviors
Prices and sizes are raw integer strings. The wire protocol is
integer-only: convert a display price with the contract’s
priceScale and a
display size with its qtyScale, both read from
configs — never hardcode a scale. For example, on a contract
with priceScale = 2, a display price of 500.00 is sent as "50000".- Order placement is asynchronous. A batch returns
{"status": "accepted", "response": {"type": "order", "data": {"count": n}}}— not the resting order id. Read the result fromInfo.user_orders/orders_by_cloids, or theorderUpdates/userFillsWebSocket channels. Cancels, modifies, and margin actions respond synchronously. - HTTP 200 does not always mean success. Gateway-level failures (invalid
signature, reused nonce, rate limiting) raise
ClientError(4xx) orServerError(5xx). Business rejections come back as HTTP 200 — a per-itemerrorstring insidestatuses[], or a non-zeroerrorCodeinsideresponse.data. Always inspect the response.
Error handling
Every SDK error derives fromUpsideError:
Environments
The SDK defaults to the QA testnet,constants.QA_API_URL
(https://dev.upsidemax.xyz). Pass base_url explicitly to target a different
environment. For UAT or production access, contact the Upside team.
Contract IDs, coin IDs, scales, and tick / step sizes are server-assigned and
differ per environment — always read them from Info.configs() rather than
hardcoding.
Signing
Every/exchange write is authorized by an EIP-712 signature over the fixed
domain (Exchange / version 1 / chain id 9767 / zero verifying contract).
The SDK selects the correct path automatically — the Typed path for
registerAccount, approveAgent, revokeAgent, and the collateral actions, and
the Agent path for everything else. Nonces are strictly increasing
millisecond timestamps managed per Exchange instance. See
Authentication for the full scheme.