Skip to content

ultrade-org/ultrade-python-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ultrade

Table of Contents

  1. Introduction
  2. Installation
  3. Quick start
  4. Public methods
  5. Required login methods

Introduction

This is an early preview version of this SDK. It is work in progress. More detailed documentation will be added, and there may still be bugs lurking around. The SDK is available via this github but is NOT yet available via PIP.

The ultrade package is a Python SDK for interacting with ULTRADE's V2 platform, the Bridgeless Crosschain Orderbook DEX. It provides a simple interface for creating and managing orders, as well as for interacting with the Ultrade API and streams. Depositing assets to ultrade is currently done via the UI at testnet.ultrade.org by performing a login with the same account that you intend to use with this SDK, and then either depositing assets from that same account, or, from any other account/chain while logged in. Deposits are always credited to the logged in account. (programattic deposits will be added to this SDK soon). Creating orders are done via this SDK. The login account is used to create orders by cryptographically signing order messages and sending them to the API. This process does not involve on-chain transactions and does not incur any gas costs. Please note that in an upcoming update, you will have the option to provide a trading-key instead of using a login account. The trading key will be associated with a specific login account and its balances and will be used for managing orders, but will not be able to withdraw.

When using this SDK, please note that token amounts and prices that are stated to be in Atomic Units mean the smallest indivisible units of the token based on its number of decimals, in a unsigned integern format. For example 1 ETH from Ethereum will be represented as 1 with 18 zeros, while 1 USDC from Algorand will be 1 with 6 zeros (6 decimals asset). The price is denominated based on the Price (Quote) token, while amounts of a base token are denominated according to that base tokens' decimals.

Funds Management on Ultrade Exchange

Ultrade Exchange provides a straightforward approach to funds management:

Users deposit funds into their Ultrade accounts. When creating orders, a portion of the user's funds may be temporarily locked to cover the order. These locked funds are used for order execution. Unused funds remain accessible for other purposes, including withdrawals. Ultrade ensures that users cannot spend more than their available balance. This straightforward approach eliminates the need for complex liquidation procedures, allowing users to trade securely and efficiently.

Installation

To install the ultrade package, you can use pip:

pip install ultrade

Quick start

Structure

Import Description
ultrade.Client The core class encompassing essential methods for working with Ultrade DeFi, including functionalities secured by user login.
ultrade.Signer A class designed for generating signers based on the provided private key. It can be used for user login as well as signing deposit transactions.
ultrade.types A module containing data type definitions used throughout the SDK.
ultrade.socket_options Options related to WebSocket connections.
ultrade.utils Contains helper functions that can be useful.

Creating a client

To create a client, you must specify the network, which can be either mainnet or testnet. Depending on the selected network, optional parameters are set by default. These parameters are primarily intended for testing purposes and can be manually configured if necessary. A detailed description of these optional parameters is provided in the table below.

Option Description Default value
api_url The URL of the Ultrade API. Testnet: api.testnet.ultrade.org
Mainnet: api.ultrade.org
websocket_url The URL of the Ultrade WebSocket API. Testnet: ws.testnet.ultrade.org
Mainnet: ws.mainnet.ultrade.org
algo_sdk_client The Algorand SDK client. Public client
from ultrade import Client

client = Client(network="testnet")

Creating a signer

To create a signer, you must provide a mnemonic key. This key is a 25-word phrase used for Algorand or an EVM private key. The signer is utilized for various functions such as logging in, depositing, withdrawing, and signing transactions.

from ultrade import Signer

#algorand
mnemonic_key = "lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod ..."
signer = Signer.create_signer(mnemonic_key)

#EVM
private_key = "e421abcdb55899d7bc2be1652a64a63fffc3cf654e989ebcce45k121d6a34a"
signer = Signer.create_signer(private_key)

Logging in

To initiate a login, invoke the set_login_user method on the client instance, passing a signer instance as its argument. This login process generates a special token that grants access to the SDK's protected methods, which require authentication. These methods, offering enhanced security and functionality, are detailed in the "Private Methods" table. This token ensures secure interaction with the SDK's privileged features.

from ultrade import Signer, Client

private_key = #your EVM private key or Algorand mnemonic
client = Client(private_key)
signer = Signer.create_signer(mnemonic_key)
await client.set_login_user(signer)

isLogged = client.is_logged_in() #returns True or False

Trading Key Example

Sets the trading key for the SDK client. This method is used to authenticate the client with the Ultrade exchange. The key allows you to carry out trading operations, but does not have the ability to perform deposit/withdraw. Alternatively, you can use the set_login_user method to authenticate the client.

Option Description
trading_key The trading key.
address Login address of the account for which the trading key was issued
trading_key_mnemonic The mnemonic of the trading key. The mnemonic is a string of words that is generated when you register a trading key
client.set_trading_key(
        trading_key=TRADING_KEY,
        address=LOGIN_ADDRESS,
        trading_key_mnemonic=TRADING_KEY_MNEMONIC,
    )

Public methods

Below are methods that do not require the login function to be executed

Method Description
get_pair_list Retrieves a list of trading pairs available on the exchange.
get_pair_info Retrieves detailed information about a specific trading pair.
ping Checks the latency between the client and the server.
get_price Retrieves the current market price for a specified trading pair.
get_depth Retrieves the order book depth for a specified trading pair.
get_symbols Retrieves a list of trading pairs that match a given pattern.
get_last_trades Retrieves the most recent trades for a specified trading pair.
get_order_by_id Retrieves detailed information about an order by its ID.
get_company_by_domain Retrieves the company ID based on the domain name.
get_avaible_chains Retrieves the list of chains supported by Ultrade.
get_cctp_assets Retrieves the list of CCTP assets from the market endpoint.
get_cctp_unified_assets Retrieves the list of unified CCTP assets from the market endpoint.

get_pair_list

To get the listed pair list, you need to call the get_pair_list method on the API instance. The get_pair_list method takes an optional company_id argument. If the company_id argument is not provided, all pairs are returned.

pairs = await client.get_pair_list()

Returns: List[TradingPair] from ultrade.types

TradingPair
Field Type Description
base_chain_id int Blockchain ID of the base currency.
base_currency str Base currency code.
base_decimal int Decimal precision of the base currency.
base_id str Unique identifier of the base currency.
created_at str Timestamp of creation.
id int Unique identifier of the trading pair.
is_active bool Indicates if the trading pair is active.
is_verified int (0 or 1) Indicates if the trading pair is verified.
min_order_size str Minimum order size.
min_price_increment str Minimum price increment in atomic units.
min_size_increment str Minimum size increment for orders in atomic units.
pair_key str Unique key of the trading pair.
pair_name str Display name of the trading pair.
pairId int Alternate identifier for the trading pair.
price_chain_id int Blockchain ID of the price currency.
price_currency str Price currency code.
price_decimal int Decimal precision of the price currency.
price_id str Unique identifier of the price currency.
trade_fee_buy int Trading fee for buying in atomic units.
trade_fee_sell int Trading fee for selling in atomic units.
updated_at str Timestamp of the last update.
inuseWithPartners List[int] List of partner IDs using this pair.
restrictedCountries List[str] List of countries where the pair is restricted.
pairSettings PairSettings Additional settings for the pair.
partner_id int Identifier of the partner associated with the pair.
PairSettings
Field Type Description
mft_audioLink Optional[str] MFT audio link.
view_baseCoinIconLink Optional[str] Link to the icon of the base currency.
mft_title Optional[str] MFT title

get_pair_info

The get_pair_info method retrieves detailed information about a specific trading pair on the Ultrade platform. It provides key data such as current price and trading volume.

Parameter Type Description
symbol str The symbol representing the trading pair, e.g., 'algo_usdt'.
info = await client.get_pair_info("algo_usdt")

Returns: PairInfo dict from ultrade.types

PairInfo
Field Type Description
id int Unique identifier of the trading pair.
pairId int Alternate identifier for the trading pair.
pair_key str Unique key of the trading pair.
is_active bool Indicates if the trading pair is active.
is_verified int (0/1) Indicates if the trading pair is verified.
base_chain_id int Blockchain ID of the base currency.
base_currency str Base currency code.
base_decimal int Decimal precision of the base currency.
base_id str Unique identifier of the base currency.
price_chain_id int Blockchain ID of the price currency.
price_currency str Price currency code.
price_decimal int Decimal precision of the price currency.
price_id str Unique identifier of the price currency.
pair_name str Display name of the trading pair.
min_price_increment str Minimum price increment in atomic units.
min_order_size str Minimum order size in atomic units.
min_size_increment str Minimum size increment for orders in atomic units.
created_at str Timestamp of creation.
updated_at str Timestamp of the last update.

ping

The ping method measures the latency between the client and the server by calculating the round-trip time of a request. It returns the latency in milliseconds. This method is useful for checking the responsiveness of the server or the network connection.

latency = await client.ping()
print(f"Latency: {latency} ms")

get_price

The get_price method fetches the current market price for a specific trading pair. It provides details such as the current ask, bid, and last trade price.

Parameter Type Description
symbol str The symbol representing the trading pair, e.g., 'algo_usdt'.

The method returns a dictionary containing the price information.

price_info = await client.get_price("algo_usdt")
print(price_info)

Returns: Price from ultrade.types

Price
Field Type Description
last str or None The last trade price in atomic units.
bid str or None The current bid price in atomic units.
ask str or None The current ask price in atomic units.

get_depth

The get_depth method retrieves the order book depth for a specified trading pair, showing the demand and supply at different price levels.

Parameter Type Description
symbol str The symbol representing the trading pair, e.g., 'algo_usdt'.
depth Optional[int] The depth of the order book to retrieve. Optional, defaults to 100.

The method returns a dictionary representing the order book, including lists of bids and asks.

order_book = await client.get_depth("algo_usdt", 100)
print(order_book)

Returns: Depth from ultrade.types

Depth
Field Type Description
sell List[List[str]] List of sell orders. Each element contains price and quantity in atomic units.
buy List[List[str]] List of buy orders. Each element contains price and quantity atomic units.
ts int Timestamp of data retrieval.
pair str The trading pair for which the order book depth was retrieved.
u int A unique identifier for the last data update (lastUpdateId). This identifier can be used to compare with other update IDs to determine whether to apply the order book depth or not.

get_symbols

The get_symbols method retrieves a list of trading pairs that match a given pattern or partial symbol.

Parameter Type Description
mask str A pattern or partial symbol to filter the trading pairs, e.g., 'algo'.

The method returns a list of dictionaries, each containing a 'pairKey' that matches the provided mask.

symbols = await client.get_symbols("algo")
print(symbols)

Returns: List of Symbol from ultrade.types

Field Type Description
pairKey str A string representing a trading pair, e.g., 'algo_usdt' for 'algo' or 'usdt'.

get_last_trades

The get_last_trades method retrieves the most recent trades for a specified trading pair.

Parameter Type Description
symbol str The symbol representing the trading pair, e.g., 'algo_usdt'.
last_trades = await client.get_last_trades("algo_usdt")
print(last_trades)

Returns: List of LastTrade from ultrade.types

LastTrade
Field Type Description
price str The price at which the trade was executed (in atomic units).
amount str The amount of the asset traded (in atomic units).
created_at str The timestamp indicating when the trade was executed, in ISO 8601 format (e.g., '2023-12-19T16:43:40.256Z').
buy_user_id str The user ID or address of the buyer in the trade.
sell_user_id str The user ID or address of the seller in the trade.
trade_side int An integer indicating the trade side. A value of 0 represents a buy, and 1 represents a sell.

get_order_by_id

The get_order_by_id method retrieves detailed information about an order using its unique identifier.

Parameter Type Description
order_id int The unique identifier of the order.

The method returns a dictionary containing detailed information about the specified order.

order_details = await client.get_order_by_id(123456)
print(order_details)

Returns: Dict: Order

Order Details
Field Type Description
id int Unique identifier of the order.
pair_id int Identifier of the trading pair.
order_side int Side of the order (0 for buy, 1 for sell).
order_type int The type of the order (0 for limit order, 1 for ioc, 2 for post, 3 for market). OrderType enum from types
order_price str Price at which order was placed (in atomic units).
excuted_price str Price at which order was executed (in atomic units).
amount str Amount of tokens in the order (in atomic units).
filled_amount str Amount of the order that has been filled (in atomic units).
total str Total cost of the order (in atomic units).
filled_total str Total cost of the filled amount (in atomic units).
status int Status of the order. Enum OrderStatus values: 1 (Open), 2 (Canceled), 3 (Matched), 4 (SelfMatched).
user_id str User identifier.
created_at str Timestamp of when the order was created.
partner_id None or str Partner identifier (if applicable).
direct_settle int Indicates if the settlement is direct.
pair_key str Key of the trading pair.
base_decimal int Decimal precision of the base currency.
price_decimal int Decimal precision of the price currency.
min_size_increment str Minimum size increment for orders (in atomic units).
min_price_increment str Minimum price increment for orders (in atomic units).
base_id str Identifier of the base currency.
price_id str Identifier of the price currency.

get_company_by_domain

The get_company_by_domain method retrieves the company ID based on the domain name.

Parameter Type Description
domain str The domain of the company, e.g., "app.ultrade.org" or "https://app.ultrade.org/".

The method returns an integer representing the company ID.

company_id = await client.get_company_by_domain("app.ultrade.org")
print(company_id)

get_avaible_chains

Retrieves the list of chains supported by Ultrade DeFi.

avaible_chains = await client.get_avaible_chains()
print(avaible_chains)

get_cctp_assets

This method retrieves the list of CCTP assets available on the Ultrade platform from the market endpoint.

cctp_assets = await client.get_cctp_assets()

Returns: dict: A dictionary containing the CCTP assets.

get_cctp_unified_assets

This method retrieves the list of unified CCTP assets from the market endpoint, providing a standardized interface across different blockchain platforms.

unified_cctp_assets = await client.get_cctp_unified_assets()

Returns: dict: A dictionary containing the unified CCTP assets.


Required login methods

Below are methods that require the login function to be executed

Method Description
get_balances Retrieves the current balance information for the logged-in user.
get_orders_with_trades Retrieves a list of orders along with their trade details for the logged-in user.
get_operations Returns a list of operations and it statuses (deposits/withdrawals) for the logged-in user.
create_order Creates an order on the Ultrade platform.
cancel_order Cancels an existing order on the Ultrade platform.
deposit Deposit a specified amont of tokens to the Token Manager Contract.
withdraw Withdraws a specified amount of tokens to a designated recipient.
subscribe Subscribes the client to various websocket streams.
unsubscribe Unsubscribes from a previously established websocket connection.

get_balances

The get_balances method retrieves the current balance information for the logged-in user on the Ultrade platform. It returns a list of balance details for each token associated with the user's account.

balances = await client.get_balances()

The method returns a list of dictionaries with the following key-value pairs:

Key Type Description
loginAddress str The blockchain address of the logged user.
loginChainId int The chain ID associated with the user's login address.
tokenId int or str The identifier of the token.
tokenChainId int The chain ID of the token.
amount int The total amount of the token.
lockedAmount int The amount of the token that is locked.

get_orders_with_trades

The get_orders_with_trades method retrieves a list of orders along with their trade details for the logged-in user on the Ultrade platform. It allows filtering orders based on a specific trading pair symbol and order status.

Parameter Type Description
symbol Optional[str] The symbol of the trading pair.
status Optional[OrderStatus] The status of the orders. Defaults to OrderStatus.OPEN_ORDER.
from ultrade.types import OrderStatus

orders = await client.get_orders_with_trades(symbol="algo_usdc", status=OrderStatus.OPEN_ORDER)

Returns: List of OrderWithTrade from ultrade.types

OrderWithTrade
Field Type Description
id int Unique identifier of the order.
pair_id int Identifier of the trading pair.
order_side int Side of the order (0 for buy, 1 for sell).
order_type int Type of the order: M (market), L (limit), I (ioc), P (post only).
order_price str Price at which the order was placed. Values are in atomic units.
order_executed_price str Price at which the order was executed. Values are in atomic units.
order_amount str Amount of the order. Values are in atomic units.
order_filled_amount str Amount of the order that has been filled. Values are in atomic units.
order_total str Total value of the order. Values are in atomic units.
order_filled_total str Total value of the filled portion of the order. Values are in atomic units.
order_status int Status of the order (1: Open, 2: Canceled, 3: Matched, 4: SelfMatched).
user_id str Identifier of the user who placed the order.
completed_at Optional[datetime] Timestamp when the order was completed.
cancel_at Optional[datetime] Timestamp when the order was cancelled, if applicable.
created_at datetime Timestamp when the order was created.
updated_at datetime Timestamp of the last update to the order.
trades Optional[List[Trade]] List of trades associated with the order, if any.
Trade
Field Type Description
trades_id int Unique identifier of the trade.
trade_price Optional[str] Price at which the trade was executed. In atomic units.
trade_amount Optional[str] Amount of tokens traded. In atomic units.
trade_fee Optional[str] Fee associated with the trade. In atomic units.
trade_rebate Optional[str] Rebate received for the trade. In atomic units.
trade_created_at Optional[datetime] Timestamp when the trade was created.

get_operations

The get_operations method fetches the operation history for the logged-in user on the Ultrade platform (deposit/withdraw).

operations = client.get_transactions()
print(operations)

Returns: a list of WalletOperations dictionaries from ultrade.types

WalletOperations
Field Type Description
primaryId int Primary identifier of the transaction.
id str Unique transaction identifier.
login_address str Address of the user who initiated the transaction.
login_chain_id int Chain ID associated with the user's login address.
action_type str Type of action "deposit" or "withdraw.
status str Current status of the transaction (pending, completed, failed)
amount str Amount involved in the transaction. In atomic units.
targetAddress str Target address for the transaction.
timestamp str Timestamp when the transaction occurred.
createdAt str Timestamp when the transaction record was created.
updatedAt str Timestamp of the last update to the transaction record.
token_id dict Details about the token involved in the transaction.
id int Identifier of the token.
address str Blockchain address of the token.
chainId int Chain ID of the token.
unitName str Unit name of the token.
name str Name of the token.
decimals int Decimal precision of the token.

deposit

The deposit method allows for depositing a specified amount of tokens into the Token Manager Contract. This function requires the user to create a Signer instance using the mnemonic of the wallet that will act as the source for the deposit. The Signer wallet must be part of the same blockchain network as the asset to be deposited. For EVM-compatible networks (like Ethereum, Polygon, Binance Smart Chain, etc.), specifying the network's RPC URL via the 'rpc_url' parameter is necessary. For other blockchain networks, this parameter is optional.

Parameter Type Description
signer Signer The 'Signer' instance, created from the wallet's mnemonic.
amount int The amount of tokens to be deposited.
token_address str | int The ID of the token to be deposited.
rpc_url str, optional The RPC URL of the EVM-compatible chain for the deposit. Defaults to None.

Raises

try:
    await client.deposit(
        signer=your_signer_instance,
        amount=5000,
        token_address="0xTokenIDorAddress",
        rpc_url="http://example.rpc.url"
    )
except Exception as e:
    print(f"Error depositing funds: {str(e)}")

withdraw

The withdraw method enables the withdrawal of a specified amount of tokens to a designated recipient. To perform a withdrawal, you need to specify the recipient's wallet address where you wish to transfer the funds. This operation requires the user to be logged in and have a sufficient balance of the token they intend to withdraw.

Parameter Type Description
amount int The amount of tokens to withdraw in atomic units
token_address str The blockchain address of the token.
token_chain_id int The chain ID of the token.
recipient str The blockchain address of the recipient.
from ultrade.types import WormholeChains

try:
    await client.withdraw(
        amount=10000,
        token_address="0xTokenAddress",
        token_chain_id=WormholeChains.POLYGON.value,
        recipient="0xRecipientAddress",
    )
except Exception as e:
    print(f"Error withdrawing funds: {str(e)}")

create_order

The create_order method is used to create a new order on the Ultrade platform. This method allows you to specify various parameters for the order, including the type, side, amount, and price.

Parameter Type Description
pair_id int The ID of the trading pair.
order_side str The side of the order, 'B' (buy) or 'S' (sell).
order_type str The type of the order: 'M' (market), 'L' (limit), 'I' (IOC), 'P' (post).
amount int The amount of tokens to buy or sell in atomic units.
price int The price per token for the order in atomic units.
company_id Optional[int] The ID of the company associated with the order. Default Ultrade.
pair = await client.get_pair_info("algo_moon")
try:
    await client.create_order(
        pair_id=pair["id"],
        order_side="B",
        order_type="L",
        amount=350000000,  # in atomic units
        price=1000,       # in atomic units
        company_id=1,
    )
except Exception as e:
    print(f"Error creating order: {str(e)}")

This function does not return a value.
Raises: ValueError: If the order amount is below the minimum order size. ValueError: If the price does not meet the minimum price increment. ValueError: If there are insufficient funds in the price currency balance to execute the buy order. ValueError: If there are insufficient funds in the base currency balance to execute the sell order.


cancel_order

The cancel_order method is used to cancel an existing order on the Ultrade platform. This method requires the user to be logged in and have a valid order to cancel.

Parameter Type Description
order_id int The ID of the order to be cancelled.

To cancel an order, provide the ID of the order you wish to cancel. The method checks if the user is logged in before proceeding. It is asynchronous and must be awaited.

Returns: void if order succsesfully canceled

Raises: Exception: If there is an error in the response from the server. Exception: {'statusCode': 404, 'message': 'Order not found', 'error': 'Not Found'}

orders = await client.get_orders_with_trades()
order = orders[0] # the first one order in array
order_id = order["id"]
try:
    await client.cancel_order(order_id)
    print(f"Order with ID {order_id} has been successfully canceled.")
except Exception as e:
    print(f"Error canceling order with ID {order_id}: {str(e)}")

subscribe

The subscribe method subscribes the client to various WebSocket streams based on the provided options. This method is useful for real-time data monitoring on the Ultrade platform.

Parameter Type Description
options dict A dictionary containing the WebSocket subscription options.
callback function A function to be called on receiving a WebSocket event.

Websocket Subscription Options:

Field Type Description
symbol str The symbol representing the trading pair, e.g., "yldy_stbl".
streams List[int] Identifiers for the types of data streams to subscribe to. Each number represents a different type of stream.
options Dict[str, Optional[str]] Additional options for the subscription.

Stream Identifiers in socket_options:

  • QUOTE: 1 - Real-time quotes for a trading pair.
  • LAST_PRICE: 2 - The latest price of the trading pair.
  • DEPTH: 3 - The depth of the order book.
  • LAST_CANDLESTICK: 4 - The last candlestick data.
  • ORDERS: 5 - Real-time updates of orders.
  • TRADES: 6 - Real-time trade data.
  • MAINTENANCE: 7 - Notifications of maintenance events.
  • WALLET_TRANSACTIONS: 8 - Updates on wallet transactions.
  • ALL_STAT: 9 - Statistics about all trading pairs.
  • CODEX_BALANCES: 10 - Balance information on the Codex platform.
  • LAST_LOOK: 11 - Last look liquidity data.
  • CODEX_ASSETS: 12 - Information about assets on the Codex platform.

options Parameter:

  • address: Optional. The wallet address to use for subscriptions. If the user is logged in, this is optional and will default to the logged-in user's address.
  • companyId: Optional. The identifier for a specific company. Used to receive data specific to that company.
from ultrade import socket_options

options = {
    'symbol': "yldy_stbl",
    'streams': [socket_options.ORDERS, socket_options.TRADES],
    'options': {"address": "your wallet address here", "companyId": "optional company ID"}
}

async def event_handler(event, data):
    print(event)
    print(data)

connection_id = await client.subscribe(options, event_handler)

unsubscribe

The unsubscribe method is used to disconnect the client from a previously established websocket connection. This is particularly useful for stopping real-time data feeds that are no longer needed, helping to manage resource usage effectively.

Parameter Type Description
connection_id str The ID of the websocket connection to be unsubscribed from.

To unsubscribe from a websocket stream, you need to provide the connection ID obtained when you initially subscribed to the stream. The method is asynchronous and must be awaited.

await client.unsubscribe("your_connection_id")

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published