Transactions

swap-basket-many

Atomically execute up to 128 legs of one validator basket rebalance.

View as Markdown

The runtime flushes queued dividends and values the fund once, then applies every swap_basket guardrail to each leg in order. If any leg fails, all trade legs roll back; the dividend flush remains settled. Each leg is an object with origin_netuid, dest_netuid, amount, and optional min_amount_out. Amounts use the origin subnet's alpha unit and floors use the destination subnet's alpha unit (TAO for netuid 0).

SignerOriginPalletWraps
coldkeysigned account (pallet role may apply)SubtensorModuleSubtensorModule.swap_basket_many

Parameters

ParameterTypeRequiredDescription
hotkey_ss58stringyesRoot-registered validator whose basket to rebalance.
legsarray of objectyesOne to 128 ordered trade objects: origin_netuid, dest_netuid, amount, and optional min_amount_out. The entire trade sequence is atomic.

Address parameters (--hotkey, --coldkey, --dest, ...) accept a raw ss58 address, an address-book or proxy-book name, or a local wallet/hotkey name.

CLI

Preview with --dry-run (shows fee, effects, and policy result without submitting), then submit:

btcli tx swap-basket-many \
  --hotkey <ss58|name> \
  --legs <a,b,c> --dry-run
btcli tx swap-basket-many \
  --hotkey <ss58|name> \
  --legs <a,b,c> -w my_coldkey

Python

import bittensor as bt
from bittensor.wallet import Wallet

wallet = Wallet(name="my_coldkey", hotkey="my_hotkey")
intent = bt.SwapBasketMany(hotkey_ss58="5F...", legs=[...])

sub = bt.Subtensor()
plan = sub.plan(intent, wallet)   # fee, effects, policy — no submission
result = sub.execute(intent, wallet)
if not result.success:
    print(result.error.code, result.error.remediation)

(bt.Subtensor is also the async client — async with bt.Subtensor() as client: — see The client.) Or build the intent by op name, as an agent would:

result = sub.execute_tool("swap_basket_many", {...}, wallet)

On-chain implementation

SubtensorModule.swap_basket_manypallets/subtensor/src/macros/dispatches.rs#L2312:

#[pallet::call_index(151)]
#[pallet::weight((Pallet::<T>::swap_basket_many_declared_weight(legs.len() as u32), DispatchClass::Normal, Pays::Yes))]
pub fn swap_basket_many(
    origin: OriginFor<T>,
    hotkey: T::AccountId,
    legs: BoundedVec<(NetUid, NetUid, AlphaBalance, u64), ConstU32<MAX_BASKET_SWAP_LEGS>>,
) -> DispatchResultWithPostInfo {
    let coldkey: T::AccountId = ensure_signed(origin)?;
    let weight = Self::do_swap_basket_many_tracked(coldkey, hotkey, legs.as_slice())
        .map_err(|(done, error)| Self::fail_with_weight(error, done))?;
    Ok((Some(weight), Pays::Yes).into())
}

Delegates to do_swap_basket_many_tracked, fail_with_weight.

Every file is browsable under /code exactly as built into the runtime, or as plain text under /code/raw/<path> (index: /code/index.json).