Skip to main content

Nado Protocol SDK

Project description

Nado Protocol Python SDK

This is the Python SDK for the Nado Protocol API.

See SDK docs to get started.

Requirements

  • Python 3.9 or above

Installation

You can install the SDK via pip:

pip install nado-protocol

Basic usage

Import the necessary utilities:

from nado_protocol.client import create_nado_client, NadoClientMode
from nado_protocol.contracts.types import DepositCollateralParams
from nado_protocol.engine_client.types.execute import (
    OrderParams,
    PlaceOrderParams,
    SubaccountParams
)
from nado_protocol.utils.expiration import OrderType, get_expiration_timestamp
from nado_protocol.utils.math import to_pow_10, to_x18
from nado_protocol.utils.nonce import gen_order_nonce
from nado_protocol.utils.order import build_appendix

Create the NadoClient providing your private key:

print("setting up nado client...")
private_key = "xxx"
client = create_nado_client(NadoClientMode.DEVNET, private_key)

Perform basic operations:

# Depositing collaterals
print("approving allowance...")
approve_allowance_tx_hash = client.spot.approve_allowance(0, to_pow_10(100000, 6))
print("approve allowance tx hash:", approve_allowance_tx_hash)

print("querying my allowance...")
token_allowance = client.spot.get_token_allowance(0, client.context.signer.address)
print("token allowance:", token_allowance)

print("depositing collateral...")
deposit_tx_hash = client.spot.deposit(
   DepositCollateralParams(
      subaccount_name="default", product_id=0, amount=to_pow_10(100000, 6)
   )
)
print("deposit collateral tx hash:", deposit_tx_hash)

# Placing orders
print("placing order...")
owner = client.context.engine_client.signer.address
product_id = 1
order = OrderParams(
   sender=SubaccountParams(
      subaccount_owner=owner,
      subaccount_name="default",
   ),
   priceX18=to_x18(20000),
   amount=to_pow_10(1, 17),
   expiration=get_expiration_timestamp(40),
   nonce=gen_order_nonce(),
   appendix=build_appendix(order_type=OrderType.POST_ONLY)
)
res = client.market.place_order({"product_id": product_id, "order": order})
print("order result:", res.json(indent=2))

TWAP and Trigger Orders

The SDK provides comprehensive support for Time-Weighted Average Price (TWAP) orders and price trigger orders through the Trigger Client.

TWAP Orders

TWAP orders allow you to execute large trades over time with controlled slippage:

from nado_protocol.trigger_client import TriggerClient
from nado_protocol.trigger_client.types import TriggerClientOpts
from nado_protocol.utils.math import to_x18
from nado_protocol.utils.expiration import get_expiration_timestamp

# Create trigger client
trigger_client = TriggerClient(
    opts=TriggerClientOpts(url=TRIGGER_BACKEND_URL, signer=private_key)
)

# Place a TWAP order to buy 5 BTC over 2 hours
twap_result = trigger_client.place_twap_order(
    product_id=1,
    sender=client.signer.address,
    price_x18=str(to_x18(50_000)),        # Max $50k per execution
    total_amount_x18=str(to_x18(5)),      # Buy 5 BTC total
    expiration=get_expiration_timestamp(60 * 24),  # 24 hours
    nonce=client.order_nonce(),
    times=10,                             # Split into 10 executions
    slippage_frac=0.005,                  # 0.5% slippage tolerance
    interval_seconds=720,                 # 12 minutes between executions
)

TWAP with Custom Amounts

For more sophisticated strategies, you can specify custom amounts for each execution:

# Decreasing size strategy: 2 BTC, 1.5 BTC, 1 BTC, 0.5 BTC
custom_amounts = [
    str(to_x18(2)),      # 2 BTC
    str(to_x18(1.5)),    # 1.5 BTC  
    str(to_x18(1)),      # 1 BTC
    str(to_x18(0.5)),    # 0.5 BTC
]

custom_twap_result = trigger_client.place_twap_order(
    product_id=1,
    sender=client.signer.address,
    price_x18=str(to_x18(51_000)),
    total_amount_x18=str(to_x18(5)),      # 5 BTC total
    expiration=get_expiration_timestamp(60 * 12),
    nonce=client.order_nonce(),
    times=4,                              # 4 executions
    slippage_frac=0.01,                   # 1% slippage
    interval_seconds=1800,                # 30 minutes
    custom_amounts_x18=custom_amounts,
)

Price Trigger Orders

Create conditional orders that execute when price conditions are met:

# Stop-loss order (sell when price drops below $45k)
stop_loss = trigger_client.place_price_trigger_order(
    product_id=1,
    sender=client.signer.address,
    price_x18=str(to_x18(44_000)),        # Sell at $44k
    amount_x18=str(-to_x18(1)),           # Sell 1 BTC (negative for sell)
    expiration=get_expiration_timestamp(60 * 24 * 7),  # 1 week
    nonce=client.order_nonce(),
    trigger_price_x18=str(to_x18(45_000)), # Trigger below $45k
    trigger_type="last_price_below",
    reduce_only=True,                     # Only reduce position
)

# Take-profit order (sell when price rises above $55k)
take_profit = trigger_client.place_price_trigger_order(
    product_id=1,
    sender=client.signer.address,
    price_x18=str(to_x18(56_000)),        # Sell at $56k
    amount_x18=str(-to_x18(1)),           # Sell 1 BTC
    expiration=get_expiration_timestamp(60 * 24 * 7),
    nonce=client.order_nonce(),
    trigger_price_x18=str(to_x18(55_000)), # Trigger above $55k
    trigger_type="last_price_above",
    reduce_only=True,
)

Supported Trigger Types

The SDK supports six types of price triggers:

  • "last_price_above": Trigger when last traded price goes above threshold
  • "last_price_below": Trigger when last traded price goes below threshold
  • "oracle_price_above": Trigger when oracle price goes above threshold
  • "oracle_price_below": Trigger when oracle price goes below threshold
  • "mid_price_above": Trigger when mid price goes above threshold
  • "mid_price_below": Trigger when mid price goes below threshold

Complete Trading Strategy Example

Here's how to set up a complete trading strategy with stop-loss, take-profit, and DCA:

# 1. Stop-loss protection
stop_loss = trigger_client.place_price_trigger_order(
    product_id=1,
    sender=client.signer.address,
    price_x18=str(to_x18(44_000)),
    amount_x18=str(-to_x18(2)),           # Close 2 BTC position
    expiration=get_expiration_timestamp(60 * 24 * 30),
    nonce=client.order_nonce(),
    trigger_price_x18=str(to_x18(45_000)),
    trigger_type="last_price_below",
    reduce_only=True,
)

# 2. Take-profit target
take_profit = trigger_client.place_price_trigger_order(
    product_id=1,
    sender=client.signer.address,
    price_x18=str(to_x18(58_000)),
    amount_x18=str(-to_x18(2)),           # Close 2 BTC position
    expiration=get_expiration_timestamp(60 * 24 * 30),
    nonce=client.order_nonce(),
    trigger_price_x18=str(to_x18(57_000)),
    trigger_type="last_price_above", 
    reduce_only=True,
)

# 3. DCA accumulation strategy
dca_strategy = trigger_client.place_twap_order(
    product_id=1,
    sender=client.signer.address,
    price_x18=str(to_x18(52_000)),        # Max $52k per buy
    total_amount_x18=str(to_x18(10)),     # Buy 10 BTC over time
    expiration=get_expiration_timestamp(60 * 24 * 7),
    nonce=client.order_nonce(),
    times=20,                             # 20 executions
    slippage_frac=0.005,                  # 0.5% slippage
    interval_seconds=1800,                # 30 minutes
)

See Getting Started for more.

Running locally

  1. Clone github repo

  2. Install poetry


$ curl -sSL https://install.python-poetry.org | python3 -

  1. Setup a virtual environment and activate it

$ python3 -m venv venv
$ source ./venv/bin/activate

  1. Install dependencies via poetry install
  2. Setup an .env file and set the following envvars
CLIENT_MODE='devnet'
SIGNER_PRIVATE_KEY="0x..."
LINKED_SIGNER_PRIVATE_KEY="0x..." # not required

Run tests

$ poetry run test

Run sanity checks

  • poetry run client-sanity: runs sanity checks for the top-level client.
  • poetry run engine-sanity: runs sanity checks for the engine-client.
  • poetry run indexer-sanity: runs sanity checks for the indexer-client.
  • poetry run trigger-sanity: runs sanity checks for the trigger-client including TWAP and price trigger examples.
  • poetry run contracts-sanity: runs sanity checks for the contracts module.

Build Docs

To build the docs locally run:

$ poetry run sphinx-build docs/source docs/build

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

nado_protocol-0.2.7.tar.gz (76.3 kB view details)

Uploaded Source

Built Distribution

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

nado_protocol-0.2.7-py3-none-any.whl (108.2 kB view details)

Uploaded Python 3

File details

Details for the file nado_protocol-0.2.7.tar.gz.

File metadata

  • Download URL: nado_protocol-0.2.7.tar.gz
  • Upload date:
  • Size: 76.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.11.14 Linux/6.11.0-1018-azure

File hashes

Hashes for nado_protocol-0.2.7.tar.gz
Algorithm Hash digest
SHA256 77f3541ac212a535df66482ca95c1ec1c3b4cb564c1074de20d35f7a807ab145
MD5 5efe6c9fc80d0d5160b1584348e66336
BLAKE2b-256 b37f02d25c390e6c6bb43746af073143fd51a86193c829c8902554b00e607d2e

See more details on using hashes here.

File details

Details for the file nado_protocol-0.2.7-py3-none-any.whl.

File metadata

  • Download URL: nado_protocol-0.2.7-py3-none-any.whl
  • Upload date:
  • Size: 108.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.11.14 Linux/6.11.0-1018-azure

File hashes

Hashes for nado_protocol-0.2.7-py3-none-any.whl
Algorithm Hash digest
SHA256 1b923d16609b6821b5648fd9888751a0ed3595aac50295addca202d8c11073f6
MD5 3900aed2321af7f82d8058fcc8f10d6c
BLAKE2b-256 2b3d3c6af731455b29cb09d59929ddb787e217dab288ffdeccb3b83f9fae9282

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