Skip to content

Quickstart

This guide will help you get started with the Ethereal Python SDK.

Initialize a client

The SDK provides two client classes: - AsyncRESTClient - Asynchronous client (recommended for new applications) - RESTClient - Synchronous client (for backward compatibility)

This guide uses AsyncRESTClient. For synchronous examples, see the Async Migration Guide.

import asyncio
from decimal import Decimal
from ethereal import AsyncRESTClient

async def main():
    # Create client with optional private key for requests that require signatures
    config = {
        "base_url": "https://api.etherealtest.net",
        "chain_config": {
            "rpc_url": "https://rpc.etherealtest.net",
            "private_key": "your_private_key",  # optional, required for signing
        }
    }
    client = await AsyncRESTClient.create(config)

    # Your code here

    # Remember to close when done
    await client.close()

# Run the async function
asyncio.run(main())

Fetch market data

The client has a mapping for each endpoint on the API. For example, list_products() corresponds to the /products endpoint. See the API Reference for a full list of methods.

# Get all available products
products = await client.list_products()

# Get current prices for all products
cached_products = await client.products()
product_ids = [p.id for p in cached_products]
prices = await client.list_market_prices(product_ids=product_ids)

# Get market liquidity for a specific product
products_by_ticker = await client.products_by_ticker()
btc_id = products_by_ticker['BTCUSD'].id
liquidity = await client.get_market_liquidity(product_id=btc_id)

Accounts and balances

Private Key Required

Some of the following code snippets require an account to be provided at initialization. Account queries can be completed with only an address, however for signing transactions for transfers or orders, you must provide a private key.

If the connected address already has subaccounts, you can view positions and balances for each subaccount. If the address does not have any subaccounts there are two options:

  1. Visit the example for Creating Accounts to create a subaccount.
  2. Deposit using the Ethereal frontend. This will create an account named primary.
# Get all subaccounts
subaccounts = await client.subaccounts()

# Get current positions
positions = await client.list_positions(
    subaccount_id=subaccounts[0].id,
    open=True
)

# Get balances for a subaccount
balances = await client.get_subaccount_balances(subaccount_id=subaccounts[0].id)

Place an order

Orders and other POST requests require that the user provides an EIP-712 signature. The SDK will handle signatures for you if you provide a private key when initializing the client.

# Select a subaccount
subaccounts = await client.subaccounts()
subaccount = subaccounts[0]

# Place a limit order
limit_order = await client.create_order(
    order_type="LIMIT",
    quantity=Decimal("0.01"),
    side=0,  # 0 for buy, 1 for sell
    price=Decimal("50000"),
    time_in_force="GTC",
    ticker="BTCUSD",
    subaccount=subaccount.name,
)

# Place a market order
market_order = await client.create_order(
    order_type="MARKET",
    quantity=Decimal("0.01"),
    side=0,
    ticker="BTCUSD",
    subaccount=subaccount.name,
)

# Refresh the order
market_order = await client.get_order(market_order.id)

# Cancel the limit order
cancel_results = await client.cancel_orders(
    order_ids=[limit_order.id],
    sender=client.chain.address,
    subaccount=subaccount.name,
)