Skip to main content

Python SDK for the O2 Exchange — a fully on-chain order book DEX on the Fuel Network

Project description

O2 Exchange

O2 SDK for Python

CI Python 3.10+ License: Apache 2.0

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:

  1. Create/load owner wallet
  2. Call setup_account() (idempotent setup + faucet mint attempt on testnet/devnet)
  3. (Optional) Call top_up_from_faucet() for an explicit testnet/devnet top-up
  4. Create session
  5. Place orders
  6. Read balances/orders
  7. 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.rst for 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_id is 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_address is 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_id is wallet identity (b256_address) used for ownership/auth and session setup.
  • trade_account_id is 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

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


Download files

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

Source Distribution

o2_sdk-0.2.0.tar.gz (109.7 kB view details)

Uploaded Source

Built Distribution

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

o2_sdk-0.2.0-py3-none-any.whl (48.5 kB view details)

Uploaded Python 3

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

Hashes for o2_sdk-0.2.0.tar.gz
Algorithm Hash digest
SHA256 8981cd726045b1bf3da3b278a74e0bc52530aef77f387c420a54b2ce33a29b9a
MD5 a922d7a6cfc69eb6a0014b3e89482f51
BLAKE2b-256 a847c4f96e8105c347b43a411a23c0b4977ed86771114ef9cc2313a6def39fc2

See more details on using hashes here.

Provenance

The following attestation bundles were made for o2_sdk-0.2.0.tar.gz:

Publisher: release.yml on o2-exchange/sdks

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

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

Hashes for o2_sdk-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b3e521efc34b2f6ddf4171ce92ceabfb73517c54ffa2da7ed995bf85dc3febea
MD5 32de95273a98f4b313457aab441812b0
BLAKE2b-256 c1741568763e4657329fb9e94cd260e1130227ca418cb4a04fa89355cc39bcc4

See more details on using hashes here.

Provenance

The following attestation bundles were made for o2_sdk-0.2.0-py3-none-any.whl:

Publisher: release.yml on o2-exchange/sdks

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page