Python SDK for the O2 Exchange — a fully on-chain order book DEX on the Fuel Network
Project description
O2 SDK for Python
Official Python SDK for the O2 Exchange — a fully on-chain order book DEX on the Fuel Network.
Installation
pip install o2-sdk
Or install from source:
pip install -e sdks/python
Requires Python 3.10+.
Quick Start
Recommended first integration path on testnet:
- Create/load owner wallet
- Call
setup_account()(idempotent setup + faucet mint attempt on testnet/devnet) - (Optional) Call
top_up_from_faucet()for an explicit testnet/devnet top-up - Create session
- Place orders
- Read balances/orders
- Settle balances back to your trading account after fills; order funds are moved into the market contract during execution and should be swept after fills or cancellations
import asyncio
from o2_sdk import Network, O2Client, OrderSide
async def main():
client = O2Client(network=Network.TESTNET)
owner = client.generate_wallet()
account = await client.setup_account(owner)
await client.top_up_from_faucet(owner)
await client.create_session(owner=owner, markets=["fFUEL/fUSDC"])
order = await client.create_order("fFUEL/fUSDC", OrderSide.BUY, "0.02", "50")
print(f"order tx={order.tx_id}")
balances = await client.get_balances(account.trade_account_id)
fusdc = balances.get("fUSDC")
print(f"fUSDC balance={fusdc.trading_account_balance if fusdc else 0}")
settle = await client.settle_balance("fFUEL/fUSDC")
print(f"settle tx={settle.tx_id}")
await client.close()
asyncio.run(main())
get_balances(trade_account_id) is an aggregated view across trading account
and market contracts, so settle_balance(...) does not necessarily change aggregate totals.
Network Configuration
Default network configs:
| Network | REST API | WebSocket | Fuel RPC | Faucet |
|---|---|---|---|---|
Network.TESTNET |
https://api.testnet.o2.app |
wss://api.testnet.o2.app/v1/ws |
https://testnet.fuel.network/v1/graphql |
https://fuel-o2-faucet.vercel.app/api/testnet/mint-v2 |
Network.DEVNET |
https://api.devnet.o2.app |
wss://api.devnet.o2.app/v1/ws |
https://devnet.fuel.network/v1/graphql |
https://fuel-o2-faucet.vercel.app/api/devnet/mint-v2 |
Network.MAINNET |
https://api.o2.app |
wss://api.o2.app/v1/ws |
https://mainnet.fuel.network/v1/graphql |
none |
API rate limits: https://docs.o2.app/api-endpoints-reference.html#rate-limits.
Use a custom deployment config:
from o2_sdk import NetworkConfig, O2Client
client = O2Client(
custom_config=NetworkConfig(
api_base="https://my-gateway.example.com",
ws_url="wss://my-gateway.example.com/v1/ws",
fuel_rpc="https://mainnet.fuel.network/v1/graphql",
faucet_url=None,
)
)
[!IMPORTANT] Mainnet note: there is no faucet; account setup requires an owner wallet that already has funds deposited for trading. SDK-native bridging flows are coming soon.
Wallet Security
generate_wallet()/generate_evm_wallet()use cryptographically secure randomness and are suitable for mainnet key generation.- For production custody, use external signers (KMS/HSM/hardware wallets) instead of long-lived in-process private keys.
- See
docs/guides/external_signers.rstfor production signer integration.
Wallet Types and Identifiers
Why choose each wallet type:
- Fuel-native wallet — best for interoperability with other apps in the Fuel ecosystem.
- EVM wallet — best if you want to reuse existing EVM accounts across chains and simplify bridging from EVM chains.
O2 owner identity model:
- O2
owner_idis always a Fuel B256 (0x+ 64 hex chars). - Fuel-native wallets already expose that directly as
b256_address. - EVM wallets expose both:
evm_address(0x+ 40 hex chars)b256_address(0x+ 64 hex chars)
- For EVM wallets,
b256_addressis the EVM address zero-left-padded to 32 bytes:owner_b256 = 0x000000000000000000000000 + evm_address[2:]
Identifier usage:
| Context | Identifier |
|---|---|
| Owner/account/session APIs | owner_id = wallet b256_address |
| Trading account state | trade_account_id (contract ID) |
| Human-visible EVM identity | evm_address |
| Markets | pair ("fFUEL/fUSDC") or market_id |
owner_id vs trade_account_id:
owner_idis wallet identity (b256_address) used for ownership/auth and session setup.trade_account_idis the trading account contract ID used for balances/orders/account state.setup_account(wallet)links these by creating/fetching the trading account for that owner.
Features
- Trading — Place, cancel, and manage orders with automatic price/quantity scaling
- Dual-Mode Numeric Inputs — Pass human values (
"0.02",100.0) or explicit raw chain integers (ChainInt(...)) - Strongly Typed — Enums for order sides/types, dataclasses for actions and order parameters
- Market Data — Fetch order book depth, recent trades, OHLCV candles, and ticker data
- WebSocket Streams — Real-time depth, order, trade, balance, and nonce updates via
async for - Wallet Support — Fuel-native and EVM wallets with session-based signing
- Batch Actions — Submit up to 5 typed actions per request (cancel + settle + create in one call)
- Error Handling — Typed exceptions (
O2Error,InvalidSignature,RateLimitExceeded, etc.)
API Overview
| Method | Description |
|---|---|
generate_wallet() / load_wallet(pk) |
Create or load a Fuel wallet |
generate_evm_wallet() / load_evm_wallet(pk) |
Create or load an EVM wallet |
setup_account(wallet) |
Idempotent account setup (create + fund + whitelist) |
top_up_from_faucet(owner) |
Explicit faucet top-up to the owner's trading account (testnet/devnet) |
create_session(owner, markets) |
Create a trading session |
create_order(market, side, price, qty) |
Place an order (price/qty accept human or ChainInt) |
cancel_order(order_id, market) |
Cancel a specific order |
cancel_all_orders(market) |
Cancel all open orders |
settle_balance(market) |
Settle filled order proceeds |
actions_for(market) |
Build typed market actions with fluent helpers |
batch_actions(actions) |
Submit typed action batch (MarketActions or MarketActionGroup) |
get_markets() / get_market(pair) |
Fetch market info |
get_depth(market) / get_trades(market) |
Order book and trade data |
get_balances(account) / get_orders(market, account) |
Account data |
stream_depth(market) |
Real-time order book stream |
stream_orders(account) / stream_trades(market) |
Real-time updates |
withdraw(owner, asset, amount) |
Withdraw funds |
See AGENTS.md for the complete API reference with all parameters and types.
Guides
docs/guides/identifiers.rstdocs/guides/trading.rstdocs/guides/market_data.rstdocs/guides/websocket_streams.rstdocs/guides/error_handling.rstdocs/guides/external_signers.rst
Examples
| Example | Description |
|---|---|
quickstart.py |
Connect, create a wallet, place your first order |
market_maker.py |
Two-sided quoting loop with cancel/replace |
taker_bot.py |
Monitor depth and take liquidity |
portfolio.py |
Multi-market balance tracking and management |
Run an example:
python examples/quickstart.py
Testing
Unit tests (no network required):
pytest tests/ -m "not integration" -v
Integration tests (requires O2_PRIVATE_KEY env var):
O2_PRIVATE_KEY=0x... pytest tests/test_integration.py -m integration -v --timeout=120
Integration tests reuse cached wallets in sdks/python/.integration-wallets.json (gitignored)
and only faucet when balances are below a conservative threshold, which improves repeat-run speed.
AI Agent Integration
See AGENTS.md for an LLM-optimized reference covering all methods, types, error codes, and common patterns.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file o2_sdk-0.2.0.tar.gz.
File metadata
- Download URL: o2_sdk-0.2.0.tar.gz
- Upload date:
- Size: 109.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8981cd726045b1bf3da3b278a74e0bc52530aef77f387c420a54b2ce33a29b9a
|
|
| MD5 |
a922d7a6cfc69eb6a0014b3e89482f51
|
|
| BLAKE2b-256 |
a847c4f96e8105c347b43a411a23c0b4977ed86771114ef9cc2313a6def39fc2
|
Provenance
The following attestation bundles were made for o2_sdk-0.2.0.tar.gz:
Publisher:
release.yml on o2-exchange/sdks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
o2_sdk-0.2.0.tar.gz -
Subject digest:
8981cd726045b1bf3da3b278a74e0bc52530aef77f387c420a54b2ce33a29b9a - Sigstore transparency entry: 1187946403
- Sigstore integration time:
-
Permalink:
o2-exchange/sdks@d61e5da25db4742873649f3e5965b73ccd54a2a9 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/o2-exchange
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d61e5da25db4742873649f3e5965b73ccd54a2a9 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file o2_sdk-0.2.0-py3-none-any.whl.
File metadata
- Download URL: o2_sdk-0.2.0-py3-none-any.whl
- Upload date:
- Size: 48.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3e521efc34b2f6ddf4171ce92ceabfb73517c54ffa2da7ed995bf85dc3febea
|
|
| MD5 |
32de95273a98f4b313457aab441812b0
|
|
| BLAKE2b-256 |
c1741568763e4657329fb9e94cd260e1130227ca418cb4a04fa89355cc39bcc4
|
Provenance
The following attestation bundles were made for o2_sdk-0.2.0-py3-none-any.whl:
Publisher:
release.yml on o2-exchange/sdks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
o2_sdk-0.2.0-py3-none-any.whl -
Subject digest:
b3e521efc34b2f6ddf4171ce92ceabfb73517c54ffa2da7ed995bf85dc3febea - Sigstore transparency entry: 1187946404
- Sigstore integration time:
-
Permalink:
o2-exchange/sdks@d61e5da25db4742873649f3e5965b73ccd54a2a9 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/o2-exchange
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d61e5da25db4742873649f3e5965b73ccd54a2a9 -
Trigger Event:
workflow_dispatch
-
Statement type: