Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8f2d3a8
Update wording for burn cost for sn registration
thewhaleking Feb 21, 2025
ef30f5b
Merge pull request #333 from opentensor/feat/thewhaleking/updating-bu…
thewhaleking Feb 21, 2025
976742f
use chk_take = 0 if None
camfairchild Feb 22, 2025
91822be
Merge pull request #335 from opentensor/fix/chk-take-display-if-none
ibraheem-abe Feb 22, 2025
d0011f9
Use `unlock_key` function.
thewhaleking Feb 24, 2025
bd6af44
Merge remote-tracking branch 'origin/staging' into feat/thewhaleking/…
thewhaleking Feb 24, 2025
73d0cd4
Merge pull request #336 from opentensor/feat/thewhaleking/use-unlock-key
thewhaleking Feb 24, 2025
b675ca5
Warn users about root-only hyperparams
thewhaleking Feb 25, 2025
fc4540c
Adds `origin_hotkey` for `transfer_stake` to allow users to specify t…
thewhaleking Feb 25, 2025
8c70771
Edge case: avoid 2 prompts for wallet
ibraheem-abe Feb 25, 2025
7c8ebe5
testing
ibraheem-abe Feb 25, 2025
e8b5cfa
testing
ibraheem-abe Feb 25, 2025
322e891
testing
ibraheem-abe Feb 25, 2025
eeea1da
Merge pull request #339 from opentensor/fix/e2e-tests-cargo-error
ibraheem-abe Feb 25, 2025
ca7d0fd
Merge remote-tracking branch 'origin/staging' into fix/thewhaleking/s…
thewhaleking Feb 25, 2025
b93d038
Merge remote-tracking branch 'origin/staging' into feat/thewhaleking/…
thewhaleking Feb 25, 2025
9777e08
Merge pull request #337 from opentensor/feat/thewhaleking/warn-users-…
thewhaleking Feb 25, 2025
4b03bb4
Merge pull request #338 from opentensor/fix/thewhaleking/st-transfer-…
thewhaleking Feb 25, 2025
a892cb4
Adds limit of ss58s per call
ibraheem-abe Feb 26, 2025
708eb42
We regressed due to setting `Repo = None`. This ensures you're able t…
thewhaleking Feb 26, 2025
76ee615
Adds e2e test
ibraheem-abe Feb 26, 2025
9644861
Merge pull request #341 from opentensor/fix/thewhaleking/git-not-requ…
ibraheem-abe Feb 26, 2025
5e13369
Merge pull request #340 from opentensor/fix/balance/chunks-for-stake-…
ibraheem-abe Feb 26, 2025
86112d2
Merge branch 'main' into backmerge/main-staging-902
ibraheem-abe Feb 26, 2025
c2bfdd6
Merge pull request #342 from opentensor/backmerge/main-staging-902
ibraheem-abe Feb 26, 2025
9340202
Bumps version and changelog
ibraheem-abe Feb 27, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/e2e-subtensor-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
timeout-minutes: 180
env:
RELEASE_NAME: development
RUSTV: nightly-2024-03-05
RUSTV: stable
RUST_BACKTRACE: full
RUST_BIN_DIR: target/x86_64-unknown-linux-gnu
TARGET: x86_64-unknown-linux-gnu
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## 9.0.3 /2025-02-26

## What's Changed
* Update wording for burn for sn registration by @thewhaleking in https://github.com/opentensor/btcli/pull/333
* [fix] use chk_take = 0 if None by @camfairchild in https://github.com/opentensor/btcli/pull/335
* Use `unlock_key` fn globally by @thewhaleking in https://github.com/opentensor/btcli/pull/336
* Updates Rust version to stable by @ibraheem-opentensor in https://github.com/opentensor/btcli/pull/339
* Warn Users When Setting Root-Only Hyperparams by @thewhaleking in https://github.com/opentensor/btcli/pull/337
* st transfer allow hotkey ss58 by @thewhaleking in https://github.com/opentensor/btcli/pull/338
* Git not required by @thewhaleking in https://github.com/opentensor/btcli/pull/341
* Adds limit of ss58 addresses per call when fetching total_stake by @ibraheem-opentensor in https://github.com/opentensor/btcli/pull/340
* Backmerge/main staging 902 by @ibraheem-opentensor in https://github.com/opentensor/btcli/pull/342

**Full Changelog**: https://github.com/opentensor/btcli/compare/v9.0.2...v9.0.3

## 9.0.2 /2025-02-20

## What's Changed
Expand Down
52 changes: 41 additions & 11 deletions bittensor_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ class GitError(Exception):
pass




_epilog = "Made with [bold red]:heart:[/bold red] by The Openτensor Foundaτion"

np.set_printoptions(precision=8, suppress=True, floatmode="fixed")
Expand Down Expand Up @@ -481,7 +479,7 @@ def version_callback(value: bool):
f"{repo.active_branch.name}/"
f"{repo.commit()}"
)
except (NameError, GitError):
except (TypeError, GitError):
version = f"BTCLI version: {__version__}"
typer.echo(version)
raise typer.Exit()
Expand Down Expand Up @@ -3323,9 +3321,9 @@ def stake_remove(
def stake_move(
self,
network: Optional[list[str]] = Options.network,
wallet_name=Options.wallet_name,
wallet_path=Options.wallet_path,
wallet_hotkey=Options.wallet_hotkey,
wallet_name: Optional[str] = Options.wallet_name,
wallet_path: Optional[str] = Options.wallet_path,
wallet_hotkey: Optional[str] = Options.wallet_hotkey,
origin_netuid: Optional[int] = typer.Option(
None, "--origin-netuid", help="Origin netuid"
),
Expand Down Expand Up @@ -3535,14 +3533,45 @@ def stake_transfer(
)
self.verbosity_handler(quiet, verbose)

if not wallet_name:
wallet_name = Prompt.ask(
"Enter the [blue]origin wallet name[/blue]",
default=self.config.get("wallet_name") or defaults.wallet.name,
)
wallet = self.wallet_ask(
wallet_name,
wallet_path,
wallet_hotkey,
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
validate=WV.WALLET_AND_HOTKEY,
wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME]
)

if not wallet_hotkey:
origin_hotkey = Prompt.ask(
"Enter the [blue]origin hotkey[/blue] name or "
"[blue]ss58 address[/blue] where the stake will be moved from",
default=self.config.get("wallet_hotkey") or defaults.wallet.hotkey,
)
if is_valid_ss58_address(origin_hotkey):
origin_hotkey = origin_hotkey
else:
wallet = self.wallet_ask(
wallet_name,
wallet_path,
origin_hotkey,
ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
validate=WV.WALLET_AND_HOTKEY,
)
origin_hotkey = wallet.hotkey.ss58_address
else:
if is_valid_ss58_address(wallet_hotkey):
origin_hotkey = wallet_hotkey
else:
wallet = self.wallet_ask(
wallet_name,
wallet_path,
wallet_hotkey,
ask_for=[],
validate=WV.WALLET_AND_HOTKEY,
)
origin_hotkey = wallet.hotkey.ss58_address

if not dest_ss58:
dest_ss58 = Prompt.ask(
"Enter the [blue]destination wallet name[/blue] or [blue]coldkey SS58 address[/blue]"
Expand Down Expand Up @@ -3580,6 +3609,7 @@ def stake_transfer(
move_stake.transfer_stake(
wallet=wallet,
subtensor=self.initialize_chain(network),
origin_hotkey=origin_hotkey,
origin_netuid=origin_netuid,
dest_netuid=dest_netuid,
dest_coldkey_ss58=dest_ss58,
Expand Down
35 changes: 22 additions & 13 deletions bittensor_cli/src/bittensor/subtensor_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -1327,20 +1327,29 @@ async def get_stake_for_coldkeys(
This function is useful for analyzing the stake distribution and delegation patterns of multiple
accounts simultaneously, offering a broader perspective on network participation and investment strategies.
"""
result = await self.query_runtime_api(
runtime_api="StakeInfoRuntimeApi",
method="get_stake_info_for_coldkeys",
params=[coldkey_ss58_list],
block_hash=block_hash,
)
if result is None:
return None

BATCH_SIZE = 60

tasks = []
for i in range(0, len(coldkey_ss58_list), BATCH_SIZE):
ss58_chunk = coldkey_ss58_list[i : i + BATCH_SIZE]
tasks.append(
self.query_runtime_api(
runtime_api="StakeInfoRuntimeApi",
method="get_stake_info_for_coldkeys",
params=[ss58_chunk],
block_hash=block_hash,
)
)
results = await asyncio.gather(*tasks)
stake_info_map = {}
for coldkey_bytes, stake_info_list in result:
coldkey_ss58 = decode_account_id(coldkey_bytes)
stake_info_map[coldkey_ss58] = StakeInfo.list_from_any(stake_info_list)
return stake_info_map
for result in results:
if result is None:
continue
for coldkey_bytes, stake_info_list in result:
coldkey_ss58 = decode_account_id(coldkey_bytes)
stake_info_map[coldkey_ss58] = StakeInfo.list_from_any(stake_info_list)

return stake_info_map if stake_info_map else None

async def all_subnets(self, block_hash: Optional[str] = None) -> list[DynamicInfo]:
result = await self.query_runtime_api(
Expand Down
6 changes: 2 additions & 4 deletions bittensor_cli/src/commands/stake/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
is_valid_ss58_address,
print_error,
print_verbose,
unlock_key,
)
from bittensor_wallet import Wallet
from bittensor_wallet.errors import KeyFileError
Expand Down Expand Up @@ -338,10 +339,7 @@ async def stake_extrinsic(
if prompt:
if not Confirm.ask("Would you like to continue?"):
raise typer.Exit()
try:
wallet.unlock_coldkey()
except KeyFileError:
err_console.print("Error decrypting coldkey (possibly incorrect password)")
if not unlock_key(wallet).success:
return False

if safe_staking:
Expand Down
2 changes: 2 additions & 0 deletions bittensor_cli/src/commands/stake/children_hotkeys.py
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,8 @@ async def display_chk_take(ss58, netuid):
chk_take = await get_childkey_take(
subtensor=subtensor, netuid=netuid, hotkey=ss58
)
if chk_take is None:
chk_take = 0
chk_take = u16_to_float(chk_take)
console.print(
f"Child take for {ss58} is: {chk_take * 100:.2f}% on netuid {netuid}."
Expand Down
33 changes: 13 additions & 20 deletions bittensor_cli/src/commands/stake/move.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
format_error_message,
group_subnets,
get_subnet_name,
unlock_key,
)

if TYPE_CHECKING:
Expand Down Expand Up @@ -621,10 +622,7 @@ async def move_stake(
raise typer.Exit()

# Perform moving operation.
try:
wallet.unlock_coldkey()
except KeyFileError:
err_console.print("Error decrypting coldkey (possibly incorrect password)")
if not unlock_key(wallet).success:
return False
with console.status(
f"\n:satellite: Moving [blue]{amount_to_move_as_balance}[/blue] from [blue]{origin_hotkey}[/blue] on netuid: [blue]{origin_netuid}[/blue] \nto "
Expand Down Expand Up @@ -697,6 +695,7 @@ async def transfer_stake(
wallet: Wallet,
subtensor: "SubtensorInterface",
amount: float,
origin_hotkey: str,
origin_netuid: int,
dest_netuid: int,
dest_coldkey_ss58: str,
Expand All @@ -709,6 +708,7 @@ async def transfer_stake(
wallet (Wallet): Bittensor wallet object.
subtensor (SubtensorInterface): Subtensor interface instance.
amount (float): Amount to transfer.
origin_hotkey (str): The hotkey SS58 to transfer the stake from.
origin_netuid (int): The netuid to transfer stake from.
dest_netuid (int): The netuid to transfer stake to.
dest_coldkey_ss58 (str): The destination coldkey to transfer stake to.
Expand Down Expand Up @@ -739,16 +739,15 @@ async def transfer_stake(
return False

# Get current stake balances
hotkey_ss58 = wallet.hotkey.ss58_address
with console.status(f"Retrieving stake data from {subtensor.network}..."):
current_stake = await subtensor.get_stake(
coldkey_ss58=wallet.coldkeypub.ss58_address,
hotkey_ss58=hotkey_ss58,
hotkey_ss58=origin_hotkey,
netuid=origin_netuid,
)
current_dest_stake = await subtensor.get_stake(
coldkey_ss58=dest_coldkey_ss58,
hotkey_ss58=hotkey_ss58,
hotkey_ss58=origin_hotkey,
netuid=dest_netuid,
)
amount_to_transfer = Balance.from_tao(amount).set_unit(origin_netuid)
Expand All @@ -768,19 +767,16 @@ async def transfer_stake(
subtensor=subtensor,
origin_netuid=origin_netuid,
destination_netuid=dest_netuid,
origin_hotkey=hotkey_ss58,
destination_hotkey=hotkey_ss58,
origin_hotkey=origin_hotkey,
destination_hotkey=origin_hotkey,
amount_to_move=amount_to_transfer,
)

if not Confirm.ask("Would you like to continue?"):
raise typer.Exit()

# Perform transfer operation
try:
wallet.unlock_coldkey()
except KeyFileError:
err_console.print("Error decrypting coldkey (possibly incorrect password)")
if not unlock_key(wallet).success:
return False

with console.status("\n:satellite: Transferring stake ..."):
Expand All @@ -789,7 +785,7 @@ async def transfer_stake(
call_function="transfer_stake",
call_params={
"destination_coldkey": dest_coldkey_ss58,
"hotkey": hotkey_ss58,
"hotkey": origin_hotkey,
"origin_netuid": origin_netuid,
"destination_netuid": dest_netuid,
"alpha_amount": amount_to_transfer.rao,
Expand Down Expand Up @@ -820,12 +816,12 @@ async def transfer_stake(
new_stake, new_dest_stake = await asyncio.gather(
subtensor.get_stake(
coldkey_ss58=wallet.coldkeypub.ss58_address,
hotkey_ss58=hotkey_ss58,
hotkey_ss58=origin_hotkey,
netuid=origin_netuid,
),
subtensor.get_stake(
coldkey_ss58=dest_coldkey_ss58,
hotkey_ss58=hotkey_ss58,
hotkey_ss58=origin_hotkey,
netuid=dest_netuid,
),
)
Expand Down Expand Up @@ -933,10 +929,7 @@ async def swap_stake(
raise typer.Exit()

# Perform swap operation
try:
wallet.unlock_coldkey()
except KeyFileError:
err_console.print("Error decrypting coldkey (possibly incorrect password)")
if not unlock_key(wallet).success:
return False

with console.status(
Expand Down
11 changes: 3 additions & 8 deletions bittensor_cli/src/commands/stake/remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
is_valid_ss58_address,
format_error_message,
group_subnets,
unlock_key,
)

if TYPE_CHECKING:
Expand Down Expand Up @@ -268,10 +269,7 @@ async def unstake(
raise typer.Exit()

# Execute extrinsics
try:
wallet.unlock_coldkey()
except KeyFileError:
err_console.print("Error decrypting coldkey (possibly incorrect password)")
if not unlock_key(wallet).success:
return False

with console.status("\n:satellite: Performing unstaking operations...") as status:
Expand Down Expand Up @@ -465,10 +463,7 @@ async def unstake_all(
):
return False

try:
wallet.unlock_coldkey()
except KeyFileError:
err_console.print("Error decrypting coldkey (possibly incorrect password)")
if not unlock_key(wallet).success:
return False

with console.status("Unstaking all stakes...") as status:
Expand Down
13 changes: 6 additions & 7 deletions bittensor_cli/src/commands/subnets/subnets.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,10 @@ async def _find_event_attributes_in_extrinsic_receipt(
sn_burn_cost = await burn_cost(subtensor)
if sn_burn_cost > your_balance:
err_console.print(
f"Your balance of: [{COLOR_PALETTE['POOLS']['TAO']}]{your_balance}[{COLOR_PALETTE['POOLS']['TAO']}] is not enough to pay the subnet lock cost of: "
f"[{COLOR_PALETTE['POOLS']['TAO']}]{sn_burn_cost}[{COLOR_PALETTE['POOLS']['TAO']}]"
f"Your balance of: [{COLOR_PALETTE['POOLS']['TAO']}]{your_balance}[{COLOR_PALETTE['POOLS']['TAO']}]"
f" is not enough to burn "
f"[{COLOR_PALETTE['POOLS']['TAO']}]{sn_burn_cost}[{COLOR_PALETTE['POOLS']['TAO']}] "
f"to register a subnet."
)
return False

Expand All @@ -107,7 +109,7 @@ async def _find_event_attributes_in_extrinsic_receipt(
f"Your balance is: [{COLOR_PALETTE['POOLS']['TAO']}]{your_balance}"
)
if not Confirm.ask(
f"Do you want to register a subnet for [{COLOR_PALETTE['POOLS']['TAO']}]{sn_burn_cost}?"
f"Do you want to burn [{COLOR_PALETTE['POOLS']['TAO']}]{sn_burn_cost} to register a subnet?"
):
return False

Expand Down Expand Up @@ -145,10 +147,7 @@ async def _find_event_attributes_in_extrinsic_receipt(
)
return False

try:
wallet.unlock_coldkey()
except KeyFileError:
err_console.print("Error decrypting coldkey (possibly incorrect password)")
if not unlock_key(wallet).success:
return False

with console.status(":satellite: Registering subnet...", spinner="earth"):
Expand Down
5 changes: 5 additions & 0 deletions bittensor_cli/src/commands/sudo.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ async def set_hyperparameter_extrinsic(
":cross_mark: [red]Invalid hyperparameter specified.[/red]"
)
return False
if sudo_:
if not Confirm.ask(
"This hyperparam is only settable by root sudo users. If you are not, this will fail. Please confirm"
):
return False

substrate = subtensor.substrate
msg_value = value if not arbitrary_extrinsic else call_params
Expand Down
3 changes: 2 additions & 1 deletion bittensor_cli/version.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re


def version_as_int(version):
_core_version = re.match(r"^\d+\.\d+\.\d+", version).group(0)
_version_split = _core_version.split(".")
Expand All @@ -14,5 +15,5 @@ def version_as_int(version):
__new_signature_version__ = 360
return __version_as_int__

__version__ = "9.0.2"
__version__ = "9.0.3"
__version_as_int__ = version_as_int(__version__)
Loading
Loading