Skip to content
Merged
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

# 9.13.1 /2025-10-14
* Fix for complicated (user_liquidity_enabled) hyperparams by @thewhaleking in https://github.com/opentensor/btcli/pull/652
* Fixes a number of type annotations by @thewhaleking in https://github.com/opentensor/btcli/pull/653

**Full Changelog**: https://github.com/opentensor/btcli/compare/v9.13.0...v9.13.1

## 9.13.0 /2025-10-09

## What's Changed
Expand Down
1 change: 0 additions & 1 deletion bittensor_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3658,7 +3658,6 @@ def get_auto_stake(
self.initialize_chain(network),
coldkey_ss58=coldkey_ss58,
json_output=json_output,
verbose=verbose,
)
)

Expand Down
83 changes: 49 additions & 34 deletions bittensor_cli/src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,47 +626,62 @@ class WalletValidationTypes(Enum):
}


class RootSudoOnly(Enum):
FALSE = 0
TRUE = 1
COMPLICATED = 2


HYPERPARAMS = {
# btcli name: (subtensor method, root-only bool)
"rho": ("sudo_set_rho", False),
"kappa": ("sudo_set_kappa", False),
"immunity_period": ("sudo_set_immunity_period", False),
"min_allowed_weights": ("sudo_set_min_allowed_weights", False),
"max_weights_limit": ("sudo_set_max_weight_limit", False),
"tempo": ("sudo_set_tempo", True),
"min_difficulty": ("sudo_set_min_difficulty", True),
"max_difficulty": ("sudo_set_max_difficulty", False),
"weights_version": ("sudo_set_weights_version_key", False),
"weights_rate_limit": ("sudo_set_weights_set_rate_limit", True),
"adjustment_interval": ("sudo_set_adjustment_interval", True),
"activity_cutoff": ("sudo_set_activity_cutoff", False),
"target_regs_per_interval": ("sudo_set_target_registrations_per_interval", True),
"min_burn": ("sudo_set_min_burn", False),
"max_burn": ("sudo_set_max_burn", True),
"bonds_moving_avg": ("sudo_set_bonds_moving_average", False),
"max_regs_per_block": ("sudo_set_max_registrations_per_block", True),
"serving_rate_limit": ("sudo_set_serving_rate_limit", False),
"max_validators": ("sudo_set_max_allowed_validators", True),
"adjustment_alpha": ("sudo_set_adjustment_alpha", False),
"difficulty": ("sudo_set_difficulty", True),
# btcli name: (subtensor method, root-only enum)
"rho": ("sudo_set_rho", RootSudoOnly.FALSE),
"kappa": ("sudo_set_kappa", RootSudoOnly.FALSE),
"immunity_period": ("sudo_set_immunity_period", RootSudoOnly.FALSE),
"min_allowed_weights": ("sudo_set_min_allowed_weights", RootSudoOnly.FALSE),
"max_weights_limit": ("sudo_set_max_weight_limit", RootSudoOnly.FALSE),
"tempo": ("sudo_set_tempo", RootSudoOnly.TRUE),
"min_difficulty": ("sudo_set_min_difficulty", RootSudoOnly.TRUE),
"max_difficulty": ("sudo_set_max_difficulty", RootSudoOnly.FALSE),
"weights_version": ("sudo_set_weights_version_key", RootSudoOnly.FALSE),
"weights_rate_limit": ("sudo_set_weights_set_rate_limit", RootSudoOnly.TRUE),
"adjustment_interval": ("sudo_set_adjustment_interval", RootSudoOnly.TRUE),
"activity_cutoff": ("sudo_set_activity_cutoff", RootSudoOnly.FALSE),
"target_regs_per_interval": (
"sudo_set_target_registrations_per_interval",
RootSudoOnly.TRUE,
),
"min_burn": ("sudo_set_min_burn", RootSudoOnly.FALSE),
"max_burn": ("sudo_set_max_burn", RootSudoOnly.TRUE),
"bonds_moving_avg": ("sudo_set_bonds_moving_average", RootSudoOnly.FALSE),
"max_regs_per_block": ("sudo_set_max_registrations_per_block", RootSudoOnly.TRUE),
"serving_rate_limit": ("sudo_set_serving_rate_limit", RootSudoOnly.FALSE),
"max_validators": ("sudo_set_max_allowed_validators", RootSudoOnly.TRUE),
"adjustment_alpha": ("sudo_set_adjustment_alpha", RootSudoOnly.FALSE),
"difficulty": ("sudo_set_difficulty", RootSudoOnly.TRUE),
"commit_reveal_period": (
"sudo_set_commit_reveal_weights_interval",
False,
RootSudoOnly.FALSE,
),
"commit_reveal_weights_enabled": (
"sudo_set_commit_reveal_weights_enabled",
RootSudoOnly.FALSE,
),
"alpha_values": ("sudo_set_alpha_values", RootSudoOnly.FALSE),
"liquid_alpha_enabled": ("sudo_set_liquid_alpha_enabled", RootSudoOnly.FALSE),
"registration_allowed": (
"sudo_set_network_registration_allowed",
RootSudoOnly.TRUE,
),
"commit_reveal_weights_enabled": ("sudo_set_commit_reveal_weights_enabled", False),
"alpha_values": ("sudo_set_alpha_values", False),
"liquid_alpha_enabled": ("sudo_set_liquid_alpha_enabled", False),
"registration_allowed": ("sudo_set_network_registration_allowed", True),
"network_pow_registration_allowed": (
"sudo_set_network_pow_registration_allowed",
False,
RootSudoOnly.FALSE,
),
"yuma3_enabled": ("sudo_set_yuma3_enabled", False),
"alpha_sigmoid_steepness": ("sudo_set_alpha_sigmoid_steepness", True),
"user_liquidity_enabled": ("toggle_user_liquidity", True),
"bonds_reset_enabled": ("sudo_set_bonds_reset_enabled", False),
"transfers_enabled": ("sudo_set_toggle_transfer", False),
"min_allowed_uids": ("sudo_set_min_allowed_uids", True),
"yuma3_enabled": ("sudo_set_yuma3_enabled", RootSudoOnly.FALSE),
"alpha_sigmoid_steepness": ("sudo_set_alpha_sigmoid_steepness", RootSudoOnly.TRUE),
"user_liquidity_enabled": ("toggle_user_liquidity", RootSudoOnly.COMPLICATED),
"bonds_reset_enabled": ("sudo_set_bonds_reset_enabled", RootSudoOnly.FALSE),
"transfers_enabled": ("sudo_set_toggle_transfer", RootSudoOnly.FALSE),
"min_allowed_uids": ("sudo_set_min_allowed_uids", RootSudoOnly.TRUE),
}

HYPERPARAMS_MODULE = {
Expand Down
2 changes: 1 addition & 1 deletion bittensor_cli/src/bittensor/subtensor_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ async def get_total_stake_for_hotkey(

async def current_take(
self,
hotkey_ss58: int,
hotkey_ss58: str,
block_hash: Optional[str] = None,
reuse_block: bool = False,
) -> Optional[float]:
Expand Down
15 changes: 8 additions & 7 deletions bittensor_cli/src/commands/liquidity/liquidity.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ async def show_liquidity_list(
wallet: "Wallet",
netuid: int,
json_output: bool = False,
):
) -> None:
current_price_, (success, err_msg, positions) = await asyncio.gather(
subtensor.subnet(netuid=netuid), get_liquidity_list(subtensor, wallet, netuid)
)
Expand All @@ -467,10 +467,10 @@ async def show_liquidity_list(
json_console.print(
json.dumps({"success": success, "err_msg": err_msg, "positions": []})
)
return False
return
else:
err_console.print(f"Error: {err_msg}")
return False
return
liquidity_table = Table(
Column("ID", justify="center"),
Column("Liquidity", justify="center"),
Expand Down Expand Up @@ -535,10 +535,10 @@ async def remove_liquidity(
prompt: Optional[bool] = None,
all_liquidity_ids: Optional[bool] = None,
json_output: bool = False,
) -> tuple[bool, str]:
) -> None:
"""Remove liquidity position from provided subnet."""
if not await subtensor.subnet_exists(netuid=netuid):
return False, f"Subnet with netuid: {netuid} does not exist in {subtensor}."
return None

if all_liquidity_ids:
success, msg, positions = await get_liquidity_list(subtensor, wallet, netuid)
Expand All @@ -549,7 +549,7 @@ async def remove_liquidity(
)
else:
return err_console.print(f"Error: {msg}")
return False, msg
return None
else:
position_ids = [p.id for p in positions]
else:
Expand All @@ -563,7 +563,7 @@ async def remove_liquidity(
console.print(f"\tPosition id: {pos}")

if not Confirm.ask("Would you like to continue?"):
return False, "User cancelled operation."
return None

results = await asyncio.gather(
*[
Expand Down Expand Up @@ -593,6 +593,7 @@ async def remove_liquidity(
"extrinsic_identifier": await ext_receipt.get_extrinsic_identifier(),
}
json_console.print_json(data=json_table)
return None


async def modify_liquidity(
Expand Down
2 changes: 2 additions & 0 deletions bittensor_cli/src/commands/liquidity/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,5 @@ def prompt_position_id() -> int:
return position_id
except ValueError:
console.print("[red]Please enter a valid number[/red].")
# will never return this, but fixes the type checker
return 0
9 changes: 5 additions & 4 deletions bittensor_cli/src/commands/stake/add.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import asyncio
import json
from collections import defaultdict
from functools import partial

Expand Down Expand Up @@ -349,7 +348,7 @@ async def stake_extrinsic(
f"[red]Not enough stake[/red]:[bold white]\n wallet balance:{remaining_wallet_balance} < "
f"staking amount: {amount_to_stake}[/bold white]"
)
return False
return
remaining_wallet_balance -= amount_to_stake

# Calculate slippage
Expand Down Expand Up @@ -432,9 +431,9 @@ async def stake_extrinsic(

if prompt:
if not Confirm.ask("Would you like to continue?"):
return False
return
if not unlock_key(wallet).success:
return False
return

if safe_staking:
stake_coroutines = {}
Expand Down Expand Up @@ -537,6 +536,8 @@ def _prompt_stake_amount(
return Balance.from_tao(amount), False
except ValueError:
console.print("[red]Please enter a valid number or 'all'[/red]")
# will never return this, but fixes the type checker
return Balance(0), False


def _get_hotkeys_to_stake_to(
Expand Down
1 change: 0 additions & 1 deletion bittensor_cli/src/commands/stake/auto_staking.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ async def show_auto_stake_destinations(
subtensor: "SubtensorInterface",
coldkey_ss58: Optional[str] = None,
json_output: bool = False,
verbose: bool = False,
) -> Optional[dict[int, dict[str, Optional[str]]]]:
"""Display auto-stake destinations for the supplied wallet."""

Expand Down
8 changes: 6 additions & 2 deletions bittensor_cli/src/commands/stake/move.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ def prompt_stake_amount(
return Balance.from_tao(amount), False
except ValueError:
console.print("[red]Please enter a valid number or 'all'[/red]")
# can never return this, but fixes the type checker
return Balance(0), False


async def stake_move_transfer_selection(
Expand Down Expand Up @@ -818,14 +820,16 @@ async def swap_stake(
wait_for_finalization (bool): If true, waits for the transaction to be finalized.

Returns:
bool: True if the swap was successful, False otherwise.
(success, extrinsic_identifier):
success is True if the swap was successful, False otherwise.
extrinsic_identifier if the extrinsic was successfully included
"""
hotkey_ss58 = get_hotkey_pub_ss58(wallet)
if interactive_selection:
try:
selection = await stake_swap_selection(subtensor, wallet)
except ValueError:
return False
return False, ""
origin_netuid = selection["origin_netuid"]
amount = selection["amount"]
destination_netuid = selection["destination_netuid"]
Expand Down
10 changes: 5 additions & 5 deletions bittensor_cli/src/commands/stake/remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ async def unstake_all(
era: int = 3,
prompt: bool = True,
json_output: bool = False,
) -> bool:
) -> None:
"""Unstakes all stakes from all hotkeys in all subnets."""
include_hotkeys = include_hotkeys or []
exclude_hotkeys = exclude_hotkeys or []
Expand Down Expand Up @@ -419,7 +419,7 @@ async def unstake_all(

if not stake_info:
console.print("[red]No stakes found to unstake[/red]")
return False
return

all_sn_dynamic_info = {info.netuid: info for info in all_sn_dynamic_info_}

Expand Down Expand Up @@ -531,10 +531,10 @@ async def unstake_all(
if prompt and not Confirm.ask(
"\nDo you want to proceed with unstaking everything?"
):
return False
return

if not unlock_key(wallet).success:
return False
return
successes = {}
with console.status("Unstaking all stakes...") as status:
for hotkey_ss58 in hotkey_ss58s:
Expand All @@ -553,7 +553,7 @@ async def unstake_all(
"extrinsic_identifier": ext_id,
}
if json_output:
return json_console.print(json.dumps({"success": successes}))
json_console.print(json.dumps({"success": successes}))


# Extrinsics
Expand Down
Loading
Loading