Skip to content

Orders

The Order service lets your users swap, stake, and move TAO, Root (SN0), and subnet alpha on Bittensor. Your app describes both sides of the swap, the user signs one transaction with their own wallet, and TAO.com executes it on chain. TAO.com never holds the user's keys.

The TypeScript SDK is the easiest way to integrate. One call authors the order, lets you review it, has your wallet sign it, and registers it:

import { createWalletAuth, OrderServiceClient } from "@tao.com/orders-sdk";

const walletAuth = createWalletAuth({
  address: coldkey, // the wallet's SS58 address
  sign: (bytes) => wallet.signHex(bytes), // the wallet's signature over the login challenge, as hex
});

const client = new OrderServiceClient({
  auth: () => walletAuth.getToken(),
});

// Stake 1 TAO into subnet 18, allowing at most 1% slippage against the current price.
const order = await client.placeMarketOrder({
  source: { currency: "urn:bittensor:mainnet:native", amount: 1_000_000_000n }, // 1 TAO, in rao
  destination: {
    currency: "urn:bittensor:mainnet:alpha:18",
    address: hotkey, // the validator to stake with
    limitPrice: 0.01, // max slippage as a fraction: 0.01 = 1%
  },
  signerAddress: coldkey,
  signer: signInstruction, // signs with the user's wallet, see "Signing" in the SDK guide (sdk.md#signing)
});

console.log(order.id, order.status); // "OPEN"

See the SDK guide for installation, signing, slippage limits, fee review, order tracking, and error handling.

How it works

%%{init: {'theme':'base','themeCSS':'[id$=-sequencenumber]{fill:#9d89ff !important;stroke:#9d89ff !important;}.sequenceNumber{fill:#0a0a0f !important;font-weight:600;font-size:13px;}','themeVariables':{'primaryColor':'#1c1b21','primaryTextColor':'#f5f5f5','primaryBorderColor':'#9d89ff','lineColor':'#a1a1a1','secondaryColor':'#2e2843','tertiaryColor':'#0b080f','noteBkgColor':'#28282d','noteTextColor':'#f5f5f5','noteBorderColor':'#9d89ff','actorBkg':'#1c1b21','actorBorder':'#9d89ff','actorTextColor':'#f5f5f5','actorLineColor':'#a1a1a1','signalColor':'#f5f5f5','signalTextColor':'#f5f5f5','sequenceNumberColor':'#0a0a0f'}}}%%
sequenceDiagram
    participant App as Your app
    participant Wallet as User's wallet
    participant Orders as Order service
    participant Chain as Bittensor

    App->>Orders: Author the order (dry run)
    Orders-->>App: Unsigned instruction, fee estimates, quote, warnings, provenance token
    alt Pre-flight warnings
        App->>App: Stop: do not sign
    else No warnings
        App->>Wallet: Sign the instruction
        Wallet-->>App: Signature
        App->>Orders: Register the signed order
        Orders-->>App: Order, status OPEN
        Orders->>Chain: Execute the order
        Chain-->>Orders: Result
        App->>Orders: Get the order
        Orders-->>App: FILLED or FAILED
    end
  1. Author. Send the two legs of the swap and the signer's address. The service works out the order type and returns the unsigned instruction, the estimated fees, a quote of what the user receives, any pre-flight warnings, and a single-use provenance token. Authoring is a dry run: nothing is opened.

    If the order has warnings, stop here and do not sign it. Registering an order with warnings is rejected.

  2. Sign. The user's wallet signs the instruction exactly as authored. The service never sees the key.

  3. Register. Send the signed order back with the provenance token. The service checks that it is the order it authored and that the signature is valid, then opens it with status OPEN.
  4. Execute. TAO.com submits the signed order to Bittensor. The order moves through SUBMITTED to FILLED, or to FAILED with a reason.
  5. Track. Read the order to follow its status and events. While it is still OPEN, the user can cancel it.

The SDK follows these steps for you. You can also call the Orders API directly.

Start here

Page Use for
SDK (recommended) Install the TypeScript SDK and place an order with one call.
Orders API Integrating without the SDK: endpoints, headers, the order lifecycle, and errors.

Supported swaps

Describe both legs and the service picks the order type. Amounts are integers in rao (1 TAO = 1_000_000_000), and currencies are URNs: urn:bittensor:<network>:native for TAO and urn:bittensor:<network>:alpha:<netuid> for a subnet's alpha, where netuid 0 is Root.

Swap Order type
TAO to subnet alpha tao_to_alpha
Subnet alpha to TAO alpha_to_tao
TAO to Root, Root to TAO tao_to_sn0, sn0_to_tao
Alpha to other alpha, same validator (Root counts as alpha) alpha_swap
Same subnet, different validator alpha_move
Different subnet and different validator alpha_swap_move

If a pair is not supported, the service answers with a 422 error instead of an order.

Fees

The service estimates the fees when it authors the order, so you can show them to the user before anything is signed. They can include the network fee, a platform fee, an MEV shield fee, and the subnet AMM fee, which the user does not pay directly. When the user pays in TAO, the fees come out of the amount, and the rest is swapped or staked. See fees and minimum sizes, because a stake below the chain's minimum fails on chain and still costs the network fee.

Authentication

Orders belong to a wallet, so Orders uses a different token from the API-key flow described in Authentication. Every Orders API call needs a Bearer token whose username claim is the order's signerAddress, and the service answers 403 if they differ. The SDK's createWalletAuth gets and refreshes that token for you by having the wallet sign a login challenge. See authentication in the SDK guide.