Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 9.18.1 /2026-02-05

## What's Changed

* Error message handled properly by @thewhaleking in https://github.com/opentensor/btcli/pull/814
* Adds more to the debug section of the readme by @thewhaleking in https://github.com/opentensor/btcli/pull/817
* Fix/proxy stake add remove by @ibraheem-abe in https://github.com/opentensor/btcli/pull/819
* Fix/update proxy usage stuff by @ibraheem-abe in https://github.com/opentensor/btcli/pull/820
* Feat: Add help cmd alias by @ibraheem-abe in https://github.com/opentensor/btcli/pull/821

**Full Changelog**: https://github.com/opentensor/btcli/compare/v9.18.0...v9.18.1

## 9.18.0 /2026-01-15

## What's Changed
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ calls (such as block number to block hash mapping), which can speed up subsequen
---

## Debugging
If a command is failing with an odd error, you can usually rerun the command with `--verbose` for a more detailed output
of any errors/exceptions that occur. This should be done prior to reporting the issue, as it helps us substantially in
determining the root cause of issues.

Additionally, you can pull a debug log.

BTCLI will store a debug log for every command run. This file is overwritten for each new command run. The default location
of this file is `~/.bittensor/debug.txt` and can be set with the `BTCLI_DEBUG_FILE` env var (see above section).

Expand All @@ -191,6 +197,12 @@ and set the save file location. We recommend doing this first before anything, a
us on our [Discord](https://discord.gg/bittensor), or by opening an issue on [GitHub](https://github.com/opentensor/btcli/issues/new)
(where you can also upload your debug file).


Steps:
1. Re-run the command with `--verbose` at the end, e.g. `btcli st remove --verbose`
2. Run `btcli --debug` to save the debug log
3. Report the issue on GitHub or Discord

---

## License
Expand Down
22 changes: 16 additions & 6 deletions bittensor_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,7 @@ def __init__(self):
callback=self.main_callback,
epilog=_epilog,
no_args_is_help=True,
context_settings={"help_option_names": ["-h", "--help"]},
)
self.config_app = typer.Typer(
epilog=_epilog,
Expand Down Expand Up @@ -4860,12 +4861,21 @@ def stake_add(

# TODO: Ask amount for each subnet explicitly if more than one
if not stake_all and not amount:
free_balance = self._run_command(
wallets.wallet_balance(
wallet, self.initialize_chain(network), False, None
),
exit_early=False,
)
staker_ss58 = proxy or wallet.coldkeypub.ss58_address
if proxy:
free_balance = self._run_command(
wallets.wallet_balance(
None, self.initialize_chain(network), False, [staker_ss58]
),
exit_early=False,
)
else:
free_balance = self._run_command(
wallets.wallet_balance(
wallet, self.initialize_chain(network), False, None
),
exit_early=False,
)
logger.debug(f"Free balance: {free_balance}")
if free_balance == Balance.from_tao(0):
print_error("You dont have any balance to stake.")
Expand Down
4 changes: 2 additions & 2 deletions bittensor_cli/src/commands/crowd/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ async def create_crowdloan(
table.add_row(
"Estimated fee",
f"[{COLORS.P.TAO}]{extrinsic_fee}[/{COLORS.P.TAO}]"
+ (" (paid by real account)" if proxy else ""),
+ (" (paid by signer account)" if proxy else ""),
)
console.print(table)

Expand Down Expand Up @@ -678,7 +678,7 @@ async def finalize_crowdloan(
table.add_row(
"Transaction Fee",
f"[{COLORS.S.TAO}]{extrinsic_fee.tao}[/{COLORS.S.TAO}]"
+ (" (paid by real account)" if proxy else ""),
+ (" (paid by signer account)" if proxy else ""),
)

table.add_section()
Expand Down
5 changes: 3 additions & 2 deletions bittensor_cli/src/commands/stake/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ async def safe_stake_extrinsic(
)
current_balance, next_nonce, call = await asyncio.gather(
subtensor.get_balance(coldkey_ss58),
subtensor.substrate.get_account_next_index(coldkey_ss58),
subtensor.substrate.get_account_next_index(signer_ss58),
subtensor.substrate.compose_call(
call_module="SubtensorModule",
call_function="add_stake_limit",
Expand Down Expand Up @@ -228,7 +228,7 @@ async def stake_extrinsic(
block_hash = await subtensor.substrate.get_chain_head()
current_balance, next_nonce, call = await asyncio.gather(
subtensor.get_balance(coldkey_ss58, block_hash=block_hash),
subtensor.substrate.get_account_next_index(coldkey_ss58),
subtensor.substrate.get_account_next_index(signer_ss58),
subtensor.substrate.compose_call(
call_module="SubtensorModule",
call_function="add_stake",
Expand Down Expand Up @@ -308,6 +308,7 @@ async def stake_extrinsic(
netuids if netuids is not None else await subtensor.get_all_subnet_netuids()
)
coldkey_ss58 = proxy or wallet.coldkeypub.ss58_address
signer_ss58 = wallet.coldkeypub.ss58_address

hotkeys_to_stake_to = _get_hotkeys_to_stake_to(
wallet=wallet,
Expand Down
7 changes: 4 additions & 3 deletions bittensor_cli/src/commands/stake/claim.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,12 @@ async def process_pending_claims(
) -> tuple[bool, str, Optional[str]]:
"""Claims root network emissions for the coldkey across specified subnets"""

coldkey_ss58 = proxy or wallet.coldkeypub.ss58_address
with console.status(":satellite: Discovering claimable emissions..."):
block_hash = await subtensor.substrate.get_chain_head()
all_stakes, identities = await asyncio.gather(
subtensor.get_stake_for_coldkey(
coldkey_ss58=wallet.coldkeypub.ss58_address, block_hash=block_hash
coldkey_ss58=coldkey_ss58, block_hash=block_hash
),
subtensor.query_all_identities(block_hash=block_hash),
)
Expand All @@ -272,7 +273,7 @@ async def process_pending_claims(
(stake.hotkey_ss58, stake.netuid): stake for stake in all_stakes
}
claimable_by_hotkey = await subtensor.get_claimable_stakes_for_coldkey(
coldkey_ss58=wallet.coldkeypub.ss58_address,
coldkey_ss58=coldkey_ss58,
stakes_info=all_stakes,
block_hash=block_hash,
)
Expand Down Expand Up @@ -344,7 +345,7 @@ async def process_pending_claims(
)
console.print(
f"\n[dim]Estimated extrinsic fee: {extrinsic_fee.tao:.9f} τ"
+ (" (paid by real account)" if proxy else "")
+ (" (paid by signer account)" if proxy else "")
)

if prompt:
Expand Down
8 changes: 2 additions & 6 deletions bittensor_cli/src/commands/stake/move.py
Original file line number Diff line number Diff line change
Expand Up @@ -882,9 +882,7 @@ async def transfer_stake(
amount=amount_to_transfer.rao,
),
subtensor.get_extrinsic_fee(call, wallet.coldkeypub, proxy=proxy),
subtensor.substrate.get_account_next_index(
proxy or wallet.coldkeypub.ss58_address
),
subtensor.substrate.get_account_next_index(wallet.coldkeypub.ss58_address),
)

# Display stake movement details
Expand Down Expand Up @@ -1112,9 +1110,7 @@ async def swap_stake(
amount=amount_to_swap.rao,
),
subtensor.get_extrinsic_fee(call, wallet.coldkeypub, proxy=proxy),
subtensor.substrate.get_account_next_index(
proxy or wallet.coldkeypub.ss58_address
),
subtensor.substrate.get_account_next_index(wallet.coldkeypub.ss58_address),
)

# Display stake movement details
Expand Down
13 changes: 7 additions & 6 deletions bittensor_cli/src/commands/stake/remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ async def _unstake_extrinsic(
f":cross_mark: [red]Failed[/red] to unstake {amount} on Netuid {netuid}"
)
coldkey_ss58 = proxy or wallet.coldkeypub.ss58_address
signer_ss58 = wallet.coldkeypub.ss58_address

if status:
status.update(
Expand All @@ -624,7 +625,7 @@ async def _unstake_extrinsic(

current_balance, next_nonce, call = await asyncio.gather(
subtensor.get_balance(coldkey_ss58),
subtensor.substrate.get_account_next_index(coldkey_ss58),
subtensor.substrate.get_account_next_index(signer_ss58),
subtensor.substrate.compose_call(
call_module="SubtensorModule",
call_function="remove_stake",
Expand Down Expand Up @@ -721,6 +722,7 @@ async def _safe_unstake_extrinsic(
f":cross_mark: [red]Failed[/red] to unstake {amount} on Netuid {netuid}"
)
coldkey_ss58 = proxy or wallet.coldkeypub.ss58_address
signer_ss58 = wallet.coldkeypub.ss58_address

if status:
status.update(
Expand All @@ -731,7 +733,7 @@ async def _safe_unstake_extrinsic(

current_balance, next_nonce, current_stake, call = await asyncio.gather(
subtensor.get_balance(coldkey_ss58, block_hash),
subtensor.substrate.get_account_next_index(coldkey_ss58),
subtensor.substrate.get_account_next_index(signer_ss58),
subtensor.get_stake(
hotkey_ss58=hotkey_ss58,
coldkey_ss58=coldkey_ss58,
Expand Down Expand Up @@ -813,9 +815,7 @@ async def _safe_unstake_extrinsic(
status=status,
)
else:
err_out(
f"\n{failure_prelude} with error: {format_error_message(await response.error_message)}"
)
err_out(f"\n{failure_prelude} with error: {err_msg}")
return False, None


Expand Down Expand Up @@ -845,6 +845,7 @@ async def _unstake_all_extrinsic(
f":cross_mark: [red]Failed[/red] to unstake all from {hotkey_name}"
)
coldkey_ss58 = proxy or wallet.coldkeypub.ss58_address
signer_ss58 = wallet.coldkeypub.ss58_address

if status:
status.update(
Expand Down Expand Up @@ -875,7 +876,7 @@ async def _unstake_all_extrinsic(
call_function=call_function,
call_params={"hotkey": hotkey_ss58},
),
subtensor.substrate.get_account_next_index(coldkey_ss58),
subtensor.substrate.get_account_next_index(signer_ss58),
)
try:
success_, err_msg, response = await subtensor.sign_and_send_extrinsic(
Expand Down
2 changes: 1 addition & 1 deletion bittensor_cli/src/commands/subnets/subnets.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ async def _find_event_attributes_in_extrinsic_receipt(
if not unlock_key(wallet).success:
return False, None, None

coldkey_ss58 = proxy or wallet.coldkeypub.ss58_address
coldkey_ss58 = wallet.coldkeypub.ss58_address

with console.status(":satellite: Registering subnet...", spinner="earth") as status:
substrate = subtensor.substrate
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"

[project]
name = "bittensor-cli"
version = "9.18.0"
version = "9.18.1"
description = "Bittensor CLI"
readme = "README.md"
authors = [
Expand Down
Loading