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.
Recommended: use the SDK¶
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
-
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.
-
Sign. The user's wallet signs the instruction exactly as authored. The service never sees the key.
- 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. - Execute. TAO.com submits the signed order to Bittensor. The order moves through
SUBMITTEDtoFILLED, or toFAILEDwith a reason. - 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.