Skip to main content

Upside Python SDK

A Python client for the Upside decentralized perpetuals exchange — REST reads (POST /info), signed writes (POST /exchange), and realtime WebSocket streams.

  • EIP-712 request signing (secp256k1) with the Agent and Typed paths — no API keys.
  • Synchronous REST over requests, threaded WebSocket over websocket-client.
  • Raw-dict responses, TypedDict inputs, full type hints (ships py.typed).
  • Agent (API-wallet) delegation, TP/SL, leverage/margin, and collateral actions.

The default environment is the QA testnet (https://dev.upsidemax.xyz). Contract IDs, scales, and tick/step sizes are server-assigned — always read them from configs, never hardcode.

Installation

pip install upside-python-sdk

Requires Python 3.9+. Runtime dependencies: requests, websocket-client, eth-account, eth-utils.

Quick start

from upside import Info, Exchange
from upside.utils import constants

# --- reads (no signing) ---
info = Info(base_url=constants.QA_API_URL)
cfg = info.configs()
contract = next(c for c in cfg["contracts"] if c["status"] == "Active")
asset = contract["contractId"]
print(info.market_state(asset))

# --- writes (EIP-712 signed) ---
exchange = Exchange("0x<private-key>", base_url=constants.QA_API_URL)

# Register (QA requires an invite code from the Upside team). A 10,000 USDC
# test airdrop lands within ~10s.
exchange.register_account(invite_code="<invite-code>")

# Place a resting limit buy. Prices/sizes are raw integer strings — scale them
# with the contract's priceScale / qtyScale from configs.
exchange.order(asset=asset, is_buy=True, size="10", price="50")

Reading data — Info

All methods return the raw parsed JSON. See docs.upsidemax.xyz/info for response shapes.

info.configs()                                  # contracts, coins, scales, tiers (cache this)
info.l2_book(asset)                             # full order book snapshot
info.market_state(asset)                        # mark/oracle/last price, funding
info.candle_snapshot(asset, "1m", start, end)   # historical OHLCV
info.user_account(account_id, market_deployer_id)
info.user_orders(account_id, market_deployer_id, contract_id=0)
info.orders_by_ids(market_deployer_id, ["8280"])
info.orders_by_cloids(account_id, market_deployer_id, ["1778844423064"])
info.user_agents(account_id)
info.user_market_deployers(account_id)
info.share_group_state()

Trading — Exchange

from upside import Cloid

exchange.order(asset=1, is_buy=True, size="10", price="50", cloid=Cloid.from_int(1001))
exchange.market_order(asset=1, is_buy=False, size="5")
exchange.bulk_orders([...])                     # up to 10 orders, one signature
exchange.cancel(asset=1, oid=15)
exchange.cancel_by_cloid(asset=1, cloid=1001)
exchange.cancel_all(asset=1)
exchange.modify(asset=1, oid=15, price="151", size="8")

exchange.update_leverage(asset=1, leverage=20)
exchange.update_margin_mode(asset=1, is_cross=False, is_hedge=True)
exchange.update_isolated_margin(asset=1, ntli=5000)

exchange.tp_sl(asset=1, tp_price="90000", sl_price="80000")
exchange.cancel_tp_sl(asset=1)
exchange.cancel_conditional(oid=123)

exchange.lock_collateral(market_deployer_id=1, coin_id=1, amount="1000")
exchange.transfer_between_deployers(1, 2, coin_id=1, amount="1000")

Order placement is asynchronous

A batch returns {"status": "accepted", "response": {"type": "order", "data": {"count": n}}}not the resting order id. Read the resulting state from Info.user_orders / orders_by_cloids, or the orderUpdates / userFills WebSocket channels. Cancels, modifies, and margin actions respond synchronously.

HTTP 200 ≠ success

Gateway failures (bad signature, reused nonce, rate limit) raise ClientError (4xx) / ServerError (5xx). Business rejections come back as HTTP 200 — a per-item error string in statuses[], or a non-zero errorCode in response.data. Always inspect them.

Agent (API-wallet) delegation

Keep the master key offline; authorize a hot agent key to sign trades. The server routes agent-signed actions to the master account.

response, agent_key = master.approve_agent(agent_name="bot1")   # generates a fresh key
agent = Exchange(agent_key, base_url=constants.QA_API_URL, account_id=master.account_id)
agent.order(asset=1, is_buy=True, size="10", price="50")
master.revoke_agent(agent.address)

WebSocket streams

info = Info(base_url=constants.QA_API_URL)          # WS starts automatically

sid = info.subscribe({"type": "l2Book", "asset": "1"}, lambda m: print(m["data"]["bookVersion"]))
info.subscribe({"type": "trades", "asset": "1"}, print)
info.subscribe({"type": "orderUpdates", "user": "0x<address>"}, print)   # private: pass the wallet address
info.subscribe({"type": "userFills", "user": "0x<address>"}, print)

info.unsubscribe({"type": "l2Book", "asset": "1"}, sid)
info.close()

Channels: l2Book, bbo, trades, candle, config (public) and orderUpdates, openOrders, userFills (per-address). The client pings every 30s and auto-reconnects, replaying subscriptions. WebSocket does not push position or balance changes — poll userAccount for those.

Signing

Every /exchange write is authorized by an EIP-712 signature over a fixed domain (Exchange / 1 / chainId 9767 / zero verifying contract). The SDK handles both paths automatically:

  • Typed pathregisterAccount, approveAgent, revokeAgent, lockCollateral, unlockCollateral, transferBetweenDeployers.
  • Agent path — every other action (canonical-JSON actionHash).

Nonces are strictly increasing millisecond timestamps managed per Exchange instance (NonceManager). See docs.upsidemax.xyz/guide/authentication.

Examples

Runnable scripts live in examples/. Copy config.json.example to config.json, set your test wallet and invite code, then:

python examples/01_register_and_airdrop.py
python examples/03_place_and_cancel_order.py
python examples/06_websocket_streams.py

Development

make install     # poetry install
make test        # pytest
make lint        # black --check + ruff
make typecheck   # mypy
make check       # all of the above

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

upside_python_sdk-0.1.0.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

upside_python_sdk-0.1.0-py3-none-any.whl (23.2 kB view details)

Uploaded Python 3

File details

Details for the file upside_python_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: upside_python_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for upside_python_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a2b773032579e4832cd51865bfdd9eff66e5b983c3fae5ae6b96eb8847c336ce
MD5 dc09040f19a332e9ecc41dae10d5cf0b
BLAKE2b-256 0b0dde1f4e51e1d43cf64b230c4d3bc3efc37e4fe16b4e9c106ef15cdf73ee92

See more details on using hashes here.

Provenance

The following attestation bundles were made for upside_python_sdk-0.1.0.tar.gz:

Publisher: release.yml on upsidemax/upside-python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file upside_python_sdk-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for upside_python_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 876d59fb7a280f9ea4f3357cd7d91859f3965dd836fcae6f0ef77232c2b9b34f
MD5 97ed31369f9ac68a495a2c3a02f6a840
BLAKE2b-256 b7932bfd5a19d55c1473a6c95980160c62878f5d9eeb21e1d293f75fede4dbd6

See more details on using hashes here.

Provenance

The following attestation bundles were made for upside_python_sdk-0.1.0-py3-none-any.whl:

Publisher: release.yml on upsidemax/upside-python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page