Skip to main content

This is a lightweight library that works as a connector to Orderly API and Websocket.

Project description

Orderly Open API Connector Python

PyPI version Python version Documentation Code Style License: MIT

Orderly Open API Connector Python is a connector to Orderly open API

  • Supported APIs:
    • Public API Endpoints
    • Private API Endpoints
    • Websockets API Endpoints
  • Inclusion of test cases and examples
  • Client for both Mainnet and Testnet
  • Utility methods needed for connecting Orderly Endpoints such as authentication

Note: This connector is for Orderly EVM. It is not compatible with Orderly NEAR.

Installation

pip install orderly-evm-connector

Documentation

https://orderly.network/docs/build-on-evm/building-on-evm

RESTful APIs

Usage examples:

from orderly_evm_connector.rest import Rest as Client
from orderly_evm_connector.lib.utils import get_account_info

(
    orderly_key,
    orderly_secret,
    orderly_account_id,
    orderly_testnet,
    wallet_secret,
    wss_id,
) = get_account_info('config.ini')
client = Client(
    orderly_key=orderly_key,
    orderly_secret=orderly_secret,
    orderly_account_id=orderly_account_id,
    orderly_testnet=True,
    timeout=5
)

# Orders APIs
response = client.create_order(
    symbol="PERP_NEAR_USDC",
    order_type="LIMIT",
    side="BUY",
    order_price=1.95,
    order_quantity=1,
)

Please find examples folder in github to check for more endpoints.

  • In order to set your Orderly Key and Orderly Secret for use of the examples, create a file config.ini with your keys.
  • Eg:
    # examples/config.ini
    [keys]
    orderly_key=ed25519:xxxx
    orderly_secret=ed25519:xxxx
    orderly_account_id=0xaaaa
    orderly_testnet=False
    wallet_secret=xxxx
    wss_id=ClientID
    debug=False
    

Display logs

Setting the debug=True will log the request URL, payload and response text.

Authentication

Requests to Orderly API needs to be signed using orderly-key and orderly-secret. Orderly Network uses the ed25519 elliptic curve standard for request authentication. The lib.utils class provides methods for signing and generating request signatures.

from orderly_evm_connector.lib.utils import generate_signature

orderly_secret = "YOUR_ORDERLY_SECRET_HERE"

# A normalized orderly request string, see Authentication section of the Orderly API Doc for details
request_str = """1649920583000POST/v1/order{"symbol": "SPOT_NEAR_USDC", "order_type": "LIMIT", "order_price": 15.23, "order_quantity": 23.11, "side": "BUY"}"""
sginature = generate_signature(orderly_secret, request_str)

Heartbeat

Once connected, the websocket server sends a ping frame every 10 seconds and is asked to return a response pong frame within 1 minute. This package automatically handles pong responses.

Reconnect

Once the connection is abnormal, the websocket connection tries a maximum of 30 times every 5s(WEBSOCKET_RETRY_SLEEP_TIME = 5,WEBSOCKET_FAILED_MAX_RETRIES = 30). After the connection is established, the subscription is completed again

Testnet

When creating a Rest or Websocket client, set the orderly_testnet parameter to true to use Testnet.

orderly_testnet = True

# Private Websocket Client on Testnet
wss_client = WebsocketPrivateAPIClient(
    orderly_testnet=orderly_testnet,
    orderly_account_id=orderly_account_id,
    wss_id=wss_id,
    orderly_key=orderly_key,
    orderly_secret=orderly_secret,
    on_message=message_handler,
    on_close=on_close,
)

# Private REST API Client
client = Client(
    orderly_key=orderly_key,
    orderly_secret=orderly_secret,
    orderly_account_id=orderly_account_id,
    orderly_testnet=orderly_testnet,
    timeout=5
)

Error

There are 2 types of error returned from the library:

  • orderly_evm_connector.error.ClientError
    • This is thrown when server returns 4XX, it's an issue from client side.
    • It has 5 properties:
      • status_code - HTTP status code
      • error_code - Server's error code, e.g. -1102
      • error_message - Server's error message, e.g. Unknown order sent.
      • header - Full response header.
      • error_data* - Additional detailed data which supplements the error_message.
        • *Only applicable on select endpoints, eg. cancelReplace
  • orderly_evm_connector.error.ServerError
    • This is thrown when server returns 5XX, it's an issue from server side. In addition, there are 3 types of Parameter Error:
  • orderly_evm_connector.error.ParameterRequiredError
    • This error is thrown when a required parameter for the endpoint is not present in the request.
  • orderly_evm_connector.error.ParameterValueError
    • This error is thrown when a value passed in for an ENUM type parameter is invalid. For example the order_type parameter is an ENUM with a fixed set of values users could pass in. Passing a value out of the ENUM definition will result in this error.
  • orderly_evm_connector.error.ParameterTypeError
    • This error is thrown when a value passed in is not in consistency with the type definition of the parameter. Websocket Client has 1 type of Error:
  • WebsocketClientError
    • This error is thrown when there is an exception thrown by the WebsocketClient class.

Websocket

Websocket Client

Orderly has two Websocket endpoints, the Market Data Base Endpoint(public endpoint) and the Private User Data Stream Base Endpoint(private endpoint). orderly-connector supports connecting to both endpoints in both Mainnet and Testnet. See below for example:

from orderly_evm_connector.lib.utils import get_account_info
import time, logging
from orderly_evm_connector.websocket.websocket_api import WebsocketPublicAPIClient

(
    orderly_key,
    orderly_secret,
    orderly_account_id,
    orderly_testnet,
    wallet_secret,
    wss_id,
) = get_account_info('config.ini')


def on_close(_):
    logging.info("Do custom stuff when connection is closed")


def message_handler(_, message):
    logging.info(message)


# Public websocket does not need to pass orderly_key and orderly_secret arguments

wss_client = WebsocketPublicAPIClient(
    orderly_testnet=orderly_testnet,
    orderly_account_id=orderly_account_id,
    wss_id=wss_id,
    on_message=message_handler,
    on_close=on_close,
    debug=True,
)

wss_client.get_24h_tickers()
time.sleep(1000)
wss_client.stop()[orderly-share-service.xml](../orderly-repomix-code/orderly_packs/orderly-backend/orderly-share-service.xml)

For private endpoint, user will need to pass in the orderly_key and orderly_secret to the orderly.websocket.WebsocketPrivateAPIClient class. Private endpoint also requires signature of the message sent using orderly_key and orderly_secret. This function is encapsulated by the WebsocketPrivateAPIClient class. See Orderly API Docs for more detai.

from orderly_evm_connector.websocket.websocket_api import WebsocketPrivateAPIClient

wss_client = WebsocketPrivateAPIClient(
    orderly_testnet=orderly_testnet,
    orderly_account_id=orderly_account_id,
    wss_id=wss_id,
    orderly_key=orderly_key,
    orderly_secret=orderly_secret,
    on_message=message_handler,
    on_close=on_close,
    debug=True,
)
# wss_client.get_liquidator_liquidations()
wss_client.get_notifications()
time.sleep(1000)
wss_client.stop()

wss_id

wss_id is the request id of included in each of websocket request to orderly. This is defined by user and has a max length of 64 bytes.

Asynchronous Clients (Asyncio)

This connector also provides asynchronous clients for use with Python's asyncio framework. The async clients mirror the functionality of the synchronous clients.

Async RESTful APIs

Usage example for the RestAsync client:

import asyncio
from orderly_evm_connector.rest import RestAsync as AsyncClient
from utils.config import get_account_info

async def main():
    (
        orderly_key,
        orderly_secret,
        orderly_account_id,
        wallet_secret,
        orderly_testnet,
        _wss_id,
    ) = get_account_info()

    # Public async client
    client_async_public = AsyncClient(
        orderly_testnet=orderly_testnet,
        debug=True,
    )

    # Private async client
    client_async_private = AsyncClient(
        orderly_key=orderly_key,
        orderly_secret=orderly_secret,
        orderly_account_id=orderly_account_id,
        wallet_secret=wallet_secret,
        orderly_testnet=orderly_testnet,
        debug=True,
    )

    # Example: Requesting registration nonce (public)
    nonce_response = await client_async_public.get_registration_nonce()
    print("Async Public Response:", nonce_response)

    # Example: Requesting current holdings (private)
    holdings_response = await client_async_private.get_current_holdings(True)
    print("Async Private Response:", holdings_response)

if __name__ == "__main__":
    asyncio.run(main())

Async Websocket

The async websocket clients provide the same functionality as their synchronous counterparts but must be run within an asyncio event loop.

import asyncio
import logging
from orderly_evm_connector.lib.utils import get_account_info
from orderly_evm_connector.websocket.websocket_api import WebsocketPublicAPIClientAsync, WebsocketPrivateAPIClientAsync

# Define async message handlers
async def message_handler(_, message):
    logging.info(message)

async def on_close(_):
    logging.info("Connection closed")

async def public_websocket_example():
    (
        _orderly_key,
        _orderly_secret,
        orderly_account_id,
        _wallet_secret,
        orderly_testnet,
        wss_id,
    ) = get_account_info()
    
    # Public async websocket
    wss_client_public = WebsocketPublicAPIClientAsync(
        orderly_testnet=orderly_testnet,
        orderly_account_id=orderly_account_id,
        wss_id=wss_id,
        on_message=message_handler,
        on_close=on_close,
    )
    await wss_client_public.run()
    await wss_client_public.get_24h_tickers()
    await asyncio.sleep(10) # Listen for 10 seconds
    await wss_client_public.stop_async()

async def private_websocket_example():
    (
        orderly_key,
        orderly_secret,
        orderly_account_id,
        _wallet_secret,
        orderly_testnet,
        wss_id,
    ) = get_account_info()

    # Private async websocket
    wss_client_private = WebsocketPrivateAPIClientAsync(
        orderly_testnet=orderly_testnet,
        orderly_account_id=orderly_account_id,
        orderly_key=orderly_key,
        orderly_secret=orderly_secret,
        wss_id=wss_id,
        on_message=message_handler,
        on_close=on_close,
    )
    await wss_client_private.run()
    wss_client_private.get_notifications()
    await asyncio.sleep(10) # Listen for 10 seconds
    await wss_client_private.stop_async()

async def main():
    logging.basicConfig(level=logging.INFO)
    print("--- Running Public Async Websocket Example ---")
    await public_websocket_example()
    print("\n--- Running Private Async Websocket Example ---")
    await private_websocket_example()

if __name__ == "__main__":
    asyncio.run(main())

Limitation

Contributing

Contributions are welcome.
If you've found a bug within this project, please open an issue to discuss what you would like to change.
If it's an issue with the API, please open a topic at Orderly Developer Community

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

orderly_evm_connector-0.2.8.tar.gz (53.6 kB view details)

Uploaded Source

Built Distribution

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

orderly_evm_connector-0.2.8-py3-none-any.whl (66.8 kB view details)

Uploaded Python 3

File details

Details for the file orderly_evm_connector-0.2.8.tar.gz.

File metadata

  • Download URL: orderly_evm_connector-0.2.8.tar.gz
  • Upload date:
  • Size: 53.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.14.0 Darwin/23.6.0

File hashes

Hashes for orderly_evm_connector-0.2.8.tar.gz
Algorithm Hash digest
SHA256 f03ac03f5b9bb5f67cfb40249cb5bed5ed2deb92e0dc8cc0c2cbc2cd29e42b6d
MD5 a33ddc2a98d83bbdb362df4af67743e7
BLAKE2b-256 1095e33edc9f253be1bd75e019292b52c3e89a4cb7dcdf6aa99833ef05ec3993

See more details on using hashes here.

File details

Details for the file orderly_evm_connector-0.2.8-py3-none-any.whl.

File metadata

File hashes

Hashes for orderly_evm_connector-0.2.8-py3-none-any.whl
Algorithm Hash digest
SHA256 1dfe87efcdfd7a940a5fc3584b9f29c41f3fac60d996bee43a010c1c8c90dfe4
MD5 a98509c578c541ea26ec2534545d2bbf
BLAKE2b-256 bad0e078bfd516fc306b16cae74ae7e717b35e326c594d19511f6a34d6f07d1f

See more details on using hashes here.

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