Runnable examples for the official Polyester Python SDK.
These examples are intentionally small. Start with read-only market data, then move to authenticated reads, then opt in to live devnet order writes, transfers, withdrawals, or chain Funding UserOps when your credentials and balances are ready.
- Python 3.11+
- A Polyester API key for authenticated examples
- Trading balance for order-writing examples
- Funding balance + owner private key for chain Funding→Trading / Funding→external submit
python3.11 -m venv .venv
source .venv/bin/activateWhen working inside the Fabric monorepo (sibling ../polyester-sdk-python), install the
local SDK first so examples track current wire shapes:
pip install -e "../polyester-sdk-python[realtime,dev]"
pip install -e ".[dev]"Otherwise install the published SDK from PyPI (polyester-sdk[realtime]>=0.1.0a45) via
pip install -e ".[dev]".
Use python3 (or .venv/bin/python) to run examples.
cp .env.example .envFill in:
POLYESTER_API_KEY_IDPOLYESTER_API_PRIVATE_KEYPOLYESTER_ACCOUNT_ID
Public market-data examples can run without credentials. Authenticated reads and all order examples require an API key.
For a subaccount-scoped key, attach an API-key policy granting ledger reads for balances and private balance streams, plus Spot trading for order mutations. The API-key policy is distinct from the subaccount policy; both apply.
The SDK does not implicitly read environment variables in application code. These examples load
.env, then pass credentials explicitly to AsyncPolyester.
Opt-in flags are separate. Never overload POLYESTER_EXAMPLES_ENABLE_TRADING onto
transfers, withdrawals, or chain submit:
| Flag | Gates |
|---|---|
POLYESTER_EXAMPLES_ENABLE_TRADING=1 |
Order / trigger writes (03, 07–12, 18, live 10) |
POLYESTER_EXAMPLES_ENABLE_TRANSFERS=1 |
Internal transfer submit (14) + dest account env |
POLYESTER_EXAMPLES_ENABLE_WITHDRAWALS=1 |
API-key withdraw submit (15; prepare always runs) |
POLYESTER_EXAMPLES_ENABLE_CHAIN_FUNDING_TO_TRADING=1 |
Funding→Trading UserOp submit (16; encode always) |
POLYESTER_EXAMPLES_ENABLE_CHAIN_EXTERNAL_SUBMIT=1 |
Funding→external UserOp submit (17; encode always) |
The default max quote notional for order examples is:
POLYESTER_EXAMPLES_MAX_QUOTE=10Use a devnet API key with a policy that allows the actions you enable. These examples are educational, not production trading systems.
Examples use decimal strings / Decimal for human-readable order qty and price.
For bots already in wire units, prefer scaled types (no string round-trip):
from polyester import Price, Quantity
await client.orders.create(
symbol="BNB-USDT",
side="buy",
order_type="limit",
tif="gtc",
qty=Quantity.from_scaled(1_000_000, scale=8),
price=Price.from_ticks(100_000_000),
post_only=True,
)Deposits land in the Funding account. Spot orders spend Trading balance.
Before running live order examples, move funds from Funding to Unified Trading:
- In the Polyester UI / wallet flow, or
- Via example
16_funding_to_trading(encodesTradingGateway.deposit; setPOLYESTER_EXAMPLES_ENABLE_CHAIN_FUNDING_TO_TRADING=1plusPOLYESTER_OWNER_PRIVATE_KEYto broadcast a UserOp)
API-key Trading→Funding withdraw is example 15 (prepare always; submit only when
POLYESTER_EXAMPLES_ENABLE_WITHDRAWALS=1).
Run examples from the repository root after installing with pip install -e ".[dev]".
| Script | Credentials | Opt-in | What it teaches |
|---|---|---|---|
01_public_market_data.py |
Optional | — | REST overview, trades, candles |
02_balances_and_orders_read.py |
Required | — | Balances, open orders, history |
19_preview_order.py |
Required | — | PreviewOrder admissibility + protected price bound |
20_lifecycle_flows.py |
Required | LIFECYCLE_TX_HASH (optional) |
Lifecycle reasons, Zipper details, paginated transaction matches |
21_vip_fees_rate_limits.py |
Required | — | VIP catalog/status, effective spot fees, trading rate limits |
03_place_and_cancel_limit_order.py |
Required | ENABLE_TRADING |
Post-only limit create and cleanup |
04_public_realtime_trades.py |
Optional | — | Public trade websocket |
05_public_orderbook_stream.py |
Optional | — | Snapshot + stream order book |
06_market_overview_stream.py |
Optional | — | Snapshot + stream market overview |
07_batch_create_and_cancel_all.py |
Required | ENABLE_TRADING |
Batch create + targeted per-order cancel |
08_batch_replace.py |
Required | ENABLE_TRADING |
Batch create, batch_replace, cleanup |
09_batch_cancel.py |
Required | ENABLE_TRADING |
Batch create, batch_cancel by client id |
10_rsi_signal_bot.py |
Required for live | Optional ENABLE_TRADING |
Candles + RSI; optional small limit |
11_twap_trigger.py |
Required | ENABLE_TRADING |
Triggers API TWAP create → list → cancel |
12_ladder_trigger.py |
Required | ENABLE_TRADING |
Triggers API ladder create → list → cancel |
13_private_realtime.py |
Required | — | Private orders + balances websocket |
14_internal_transfer.py |
Required | ENABLE_TRANSFERS + dest |
Tiny internal transfer |
15_api_key_trading_withdraw.py |
Required | Prepare always; ENABLE_WITHDRAWALS to submit |
Trading→Funding prepare / submit |
16_funding_to_trading.py |
Required | Encode always; chain flag to submit | Encode deposit; optional UserOp |
17_funding_to_external.py |
Required | Encode needs dest; external-submit flag | Encode withdrawToChain; optional UserOp |
18_trailing_stop_trigger.py |
Required | ENABLE_TRADING |
Standalone trailing-stop (SELL market-IOC) create → list → cancel |
Suggested order: 01 → 04/05/06 → 02 → 13 → 10 (dry) → 03 → 07/08/09 →
11/12/18 → money-movement examples when those flags are intentionally enabled.
make live-smoke
# or: bash scripts/live-smoke.shRuns all examples in order. Gated examples print SKIP and continue when their flag is
missing. Set LIVE_SMOKE_STRICT=1 to fail instead of skipping. Secrets stay in local .env
(never commit them; public CI does not run this with credentials).
python3 examples/01_public_market_data.py
python3 examples/04_public_realtime_trades.py
python3 examples/05_public_orderbook_stream.py
python3 examples/06_market_overview_stream.pyRealtime examples exit after 30 seconds if no data arrives (common on quiet devnet markets).
python3 examples/02_balances_and_orders_read.py
python3 examples/19_preview_order.py
python3 examples/20_lifecycle_flows.py
python3 examples/21_vip_fees_rate_limits.py
python3 examples/13_private_realtime.pySet POLYESTER_EXAMPLES_LIFECYCLE_TX_HASH before running example 20 to list
every lifecycle flow associated with one transaction, following all pagination
tokens.
POLYESTER_EXAMPLES_ENABLE_TRADING=1 python3 examples/03_place_and_cancel_limit_order.py
POLYESTER_EXAMPLES_ENABLE_TRADING=1 python3 examples/07_batch_create_and_cancel_all.py
POLYESTER_EXAMPLES_ENABLE_TRADING=1 python3 examples/08_batch_replace.py
POLYESTER_EXAMPLES_ENABLE_TRADING=1 python3 examples/09_batch_cancel.py
POLYESTER_EXAMPLES_ENABLE_TRADING=1 python3 examples/11_twap_trigger.py
POLYESTER_EXAMPLES_ENABLE_TRADING=1 python3 examples/12_ladder_trigger.py
POLYESTER_EXAMPLES_ENABLE_TRADING=1 python3 examples/18_trailing_stop_trigger.py07 cleans up with per-order cancel. 09 demonstrates orders.batch_cancel.
TWAP/ladder/trailing-stop use the Triggers API (separate lifecycle from normal orders).
Standalone trailing stops are SELL market-IOC; list projects trigger_type, side, and
parent_order_id (empty for standalone).
python3 examples/10_rsi_signal_bot.py
POLYESTER_EXAMPLES_ENABLE_TRADING=1 python3 examples/10_rsi_signal_bot.pyPOLYESTER_EXAMPLES_ENABLE_TRANSFERS=1 \
POLYESTER_EXAMPLES_TRANSFER_DEST_ACCOUNT_ID=... \
python3 examples/14_internal_transfer.py
python3 examples/15_api_key_trading_withdraw.py
POLYESTER_EXAMPLES_ENABLE_WITHDRAWALS=1 python3 examples/15_api_key_trading_withdraw.py
python3 examples/16_funding_to_trading.py
POLYESTER_EXAMPLES_ENABLE_CHAIN_FUNDING_TO_TRADING=1 \
POLYESTER_OWNER_PRIVATE_KEY=0x... \
python3 examples/16_funding_to_trading.py
POLYESTER_EXAMPLES_EXTERNAL_DESTINATION=0x... \
python3 examples/17_funding_to_external.py
POLYESTER_EXAMPLES_ENABLE_CHAIN_EXTERNAL_SUBMIT=1 \
POLYESTER_OWNER_PRIVATE_KEY=0x... \
POLYESTER_EXAMPLES_EXTERNAL_DESTINATION=0x... \
python3 examples/17_funding_to_external.pyPOLYESTER_EXAMPLES_SYMBOL: defaultETH-USDTPOLYESTER_EXAMPLES_MAX_QUOTE: default10POLYESTER_EXAMPLES_TRANSFER_AMOUNT: default0.01POLYESTER_EXAMPLES_WITHDRAW_AMOUNT: default0.01POLYESTER_EXAMPLES_CHAIN_AMOUNT: default1POLYESTER_EXAMPLES_EXTERNAL_DESTINATION: required to encode example17POLYESTER_EXAMPLES_EXTERNAL_CHAIN_ID: default6POLYESTER_OWNER_PRIVATE_KEY: smart-account owner for UserOp submit (16/17)
- Pass decimal strings for
qtyandprice. Do not use floats for order inputs. - Use client order IDs for idempotency and cleanup.
- Treat the RSI strategy as a teaching example. It is deliberately naive.
python3 -m pytest -q
make live-smoke