From 398791fcb10840368c73c0db48c681e7ab2503b1 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Mon, 3 Feb 2025 09:01:34 -0800 Subject: [PATCH 1/6] working --- bittensor_cli/cli.py | 3 +- bittensor_cli/src/commands/stake/stake.py | 8 ++- bittensor_cli/src/commands/subnets/subnets.py | 60 +++++++++---------- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 7bd37fbb3..7393ee8ef 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -2478,6 +2478,7 @@ def stake_list( live: bool = Options.live, quiet: bool = Options.quiet, verbose: bool = Options.verbose, + no_prompt: bool = Options.prompt, # TODO add: all-wallets, reuse_last, html_output ): """List all stake accounts for wallet.""" @@ -2506,7 +2507,7 @@ def stake_list( return self._run_command( stake.stake_list( - wallet, coldkey_ss58, self.initialize_chain(network), live, verbose + wallet, coldkey_ss58, self.initialize_chain(network), live, verbose, no_prompt ) ) diff --git a/bittensor_cli/src/commands/stake/stake.py b/bittensor_cli/src/commands/stake/stake.py index bd95a0e5b..b6fe73e43 100644 --- a/bittensor_cli/src/commands/stake/stake.py +++ b/bittensor_cli/src/commands/stake/stake.py @@ -1185,6 +1185,7 @@ async def stake_list( subtensor: "SubtensorInterface", live: bool = False, verbose: bool = False, + prompt: bool = False, ): coldkey_address = coldkey_ss58 if coldkey_ss58 else wallet.coldkeypub.ss58_address @@ -1217,8 +1218,9 @@ def define_table( live: bool = False, ): title = f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]Hotkey: {hotkey_name}\nNetwork: {subtensor.network}\n\n" - if not live: - title += f"[{COLOR_PALETTE['GENERAL']['HINT']}]See below for an explanation of the columns\n" + # TODO: Add hint back in after adding columns descriptions + # if not live: + # title += f"[{COLOR_PALETTE['GENERAL']['HINT']}]See below for an explanation of the columns\n" table = Table( title=title, show_footer=True, @@ -1729,7 +1731,7 @@ def format_cell( all_hotkeys_total_global_tao += stake all_hotkeys_total_tao_value += value - if num_hotkeys > 1 and counter < num_hotkeys: + if num_hotkeys > 1 and counter < num_hotkeys and prompt: console.print("\nPress Enter to continue to the next hotkey...") input() diff --git a/bittensor_cli/src/commands/subnets/subnets.py b/bittensor_cli/src/commands/subnets/subnets.py index 88fb63ece..c271c430c 100644 --- a/bittensor_cli/src/commands/subnets/subnets.py +++ b/bittensor_cli/src/commands/subnets/subnets.py @@ -983,33 +983,31 @@ async def show_root(): """ ) if delegate_selection: + valid_uids = [str(row[0]) for row in sorted_rows[:max_rows]] while True: selection = Prompt.ask( - "\nEnter the position of the delegate you want to stake to [dim](or press Enter to cancel)[/dim]", + "\nEnter the Position of the delegate you want to stake to [dim](or press Enter to cancel)[/dim]", default="", + choices=[""] + valid_uids, + show_choices=False, + show_default=False, ) if selection == "": return None - - try: - idx = int(selection) - if 1 <= idx <= max_rows: - selected_hotkey = sorted_hks_delegation[idx - 1] - row_data = sorted_rows[idx - 1] - identity = "" if row_data[5] == "~" else row_data[5] - identity_str = f" ({identity})" if identity else "" - console.print( - f"\nSelected delegate: [{COLOR_PALETTE['GENERAL']['SUBHEADING']}]{selected_hotkey}{identity_str}" - ) - - return selected_hotkey - else: - console.print( - f"[red]Invalid selection. Please enter a number between 1 and {max_rows}[/red]" - ) - except ValueError: - console.print("[red]Please enter a valid number[/red]") + + uid = int(selection) + selected_hotkey = root_state.hotkeys[uid] + # Find identity for this UID + coldkey_identity = identities.get(root_state.coldkeys[uid], {}).get("name", "") + hotkey_identity = old_identities.get(selected_hotkey) + validator_identity = coldkey_identity if coldkey_identity else (hotkey_identity.display if hotkey_identity else "") + identity_str = f" ({validator_identity})" if validator_identity else "" + + console.print( + f"\nSelected delegate: [{COLOR_PALETTE['GENERAL']['SUBHEADING']}]{selected_hotkey}{identity_str}" + ) + return selected_hotkey async def show_subnet(netuid_: int): if not await subtensor.subnet_exists(netuid=netuid): @@ -1053,10 +1051,6 @@ async def show_subnet(netuid_: int): pad_edge=True, ) - # Add index for selection if selecting delegates - if delegate_selection: - table.add_column("#", style="cyan", justify="right") - # For hotkey_block_emission calculation emission_sum = sum( [ @@ -1247,8 +1241,6 @@ async def show_subnet(netuid_: int): ) for pos, row in enumerate(rows, 1): table_row = [] - if delegate_selection: - table_row.append(str(pos)) table_row.extend(row) table.add_row(*table_row) if delegate_selection and pos == max_rows: @@ -1301,20 +1293,24 @@ async def show_subnet(netuid_: int): if delegate_selection: while True: + valid_uids = [str(row[0]) for row in rows[:max_rows]] selection = Prompt.ask( - "\nEnter the number of the delegate you want to stake to [dim](or press Enter to cancel)[/dim]", + "\nEnter the UID of the delegate you want to stake to [dim](or press Enter to cancel)[/dim]", default="", + choices=[""] + valid_uids, + show_choices=False, + show_default=False, ) if selection == "": return None try: - idx = int(selection) - if 1 <= idx <= max_rows: - uid = int(rows[idx - 1][0]) + uid = int(selection) + # Check if the UID exists in the subnet + if uid in [int(row[0]) for row in rows]: + row_data = next(row for row in rows if int(row[0]) == uid) hotkey = subnet_state.hotkeys[uid] - row_data = rows[idx - 1] identity = "" if row_data[9] == "~" else row_data[9] identity_str = f" ({identity})" if identity else "" console.print( @@ -1323,7 +1319,7 @@ async def show_subnet(netuid_: int): return hotkey else: console.print( - f"[red]Invalid selection. Please enter a number between 1 and {max_rows}[/red]" + f"[red]Invalid UID. Please enter a valid UID from the table above[/red]" ) except ValueError: console.print("[red]Please enter a valid number[/red]") From 337f416e93001546eeddf01768fec8e315ae732f Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Mon, 3 Feb 2025 14:09:46 -0800 Subject: [PATCH 2/6] Updates dynamicinfo + minor improvements --- CHANGELOG.md | 7 ++++++ bittensor_cli/__init__.py | 2 +- bittensor_cli/cli.py | 2 +- bittensor_cli/src/bittensor/chain_data.py | 4 ++++ bittensor_cli/src/commands/subnets/subnets.py | 22 +++++++++++++------ 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de809acc9..ef8621b85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 8.2.0rc15 /2025-02-03 + +## What's Changed +* Adds subnet volume to root DynamicInfo +* Adds --no-prompt option for stake list +* Removes index and adds uids/position for delegate selection + ## 8.2.0rc14 /2025-01-24 ## What's Changed diff --git a/bittensor_cli/__init__.py b/bittensor_cli/__init__.py index 8ecf1c97d..6274e84ca 100644 --- a/bittensor_cli/__init__.py +++ b/bittensor_cli/__init__.py @@ -18,6 +18,6 @@ from .cli import CLIManager -__version__ = "8.2.0rc14" +__version__ = "8.2.0rc15" __all__ = ["CLIManager", "__version__"] diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 7393ee8ef..194bc8fb4 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -64,7 +64,7 @@ class GitError(Exception): pass -__version__ = "8.2.0rc14" +__version__ = "8.2.0rc15" _core_version = re.match(r"^\d+\.\d+\.\d+", __version__).group(0) diff --git a/bittensor_cli/src/bittensor/chain_data.py b/bittensor_cli/src/bittensor/chain_data.py index 979498677..209cc0cae 100644 --- a/bittensor_cli/src/bittensor/chain_data.py +++ b/bittensor_cli/src/bittensor/chain_data.py @@ -900,6 +900,7 @@ class DynamicInfo: pending_root_emission: Balance network_registered_at: int subnet_identity: Optional[SubnetIdentity] + subnet_volume: float @classmethod def from_vec_u8(cls, vec_u8: list[int]) -> Optional["DynamicInfo"]: @@ -938,6 +939,7 @@ def fix_decoded_values(cls, decoded: dict) -> "DynamicInfo": alpha_in = Balance.from_rao(decoded["alpha_in"]).set_unit(netuid) alpha_out = Balance.from_rao(decoded["alpha_out"]).set_unit(netuid) tao_in = Balance.from_rao(decoded["tao_in"]).set_unit(0) + subnet_volume = Balance.from_rao(decoded["subnet_volume"]).set_unit(netuid) alpha_out_emission = Balance.from_rao(decoded["alpha_out_emission"]).set_unit( netuid ) @@ -991,6 +993,7 @@ def fix_decoded_values(cls, decoded: dict) -> "DynamicInfo": pending_root_emission=pending_root_emission, network_registered_at=int(decoded["network_registered_at"]), subnet_identity=subnet_identity, + subnet_volume=subnet_volume, ) def tao_to_alpha(self, tao: Balance) -> Balance: @@ -1601,6 +1604,7 @@ def decode(result: list[int]) -> list[dict]: ["pending_alpha_emission", "Compact"], ["pending_root_emission", "Compact"], ["network_registered_at", "Compact"], + ["subnet_volume", "Compact"], ["subnet_identity", "Option"], ], }, diff --git a/bittensor_cli/src/commands/subnets/subnets.py b/bittensor_cli/src/commands/subnets/subnets.py index c271c430c..041261bed 100644 --- a/bittensor_cli/src/commands/subnets/subnets.py +++ b/bittensor_cli/src/commands/subnets/subnets.py @@ -995,15 +995,23 @@ async def show_root(): if selection == "": return None - - uid = int(selection) - selected_hotkey = root_state.hotkeys[uid] - # Find identity for this UID - coldkey_identity = identities.get(root_state.coldkeys[uid], {}).get("name", "") + + position = int(selection) + idx = position - 1 + original_idx = sorted_hotkeys[idx][0] + selected_hotkey = root_state.hotkeys[original_idx] + + coldkey_identity = identities.get( + root_state.coldkeys[original_idx], {} + ).get("name", "") hotkey_identity = old_identities.get(selected_hotkey) - validator_identity = coldkey_identity if coldkey_identity else (hotkey_identity.display if hotkey_identity else "") + validator_identity = ( + coldkey_identity + if coldkey_identity + else (hotkey_identity.display if hotkey_identity else "") + ) identity_str = f" ({validator_identity})" if validator_identity else "" - + console.print( f"\nSelected delegate: [{COLOR_PALETTE['GENERAL']['SUBHEADING']}]{selected_hotkey}{identity_str}" ) From 55225eb02f12326be2c563103f70e5980bf6c6e5 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Mon, 3 Feb 2025 14:11:29 -0800 Subject: [PATCH 3/6] Updates release script --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ed1fc6d52..88ce34a0c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,7 +45,7 @@ jobs: fi - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: dist path: dist/ @@ -60,7 +60,7 @@ jobs: steps: - name: Download artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: dist path: dist/ From d921a96eda5916012b16a93889cbe2dfb79d5663 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Mon, 3 Feb 2025 14:17:25 -0800 Subject: [PATCH 4/6] Updated return type --- bittensor_cli/src/bittensor/chain_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor_cli/src/bittensor/chain_data.py b/bittensor_cli/src/bittensor/chain_data.py index 209cc0cae..f846ae0b2 100644 --- a/bittensor_cli/src/bittensor/chain_data.py +++ b/bittensor_cli/src/bittensor/chain_data.py @@ -900,7 +900,7 @@ class DynamicInfo: pending_root_emission: Balance network_registered_at: int subnet_identity: Optional[SubnetIdentity] - subnet_volume: float + subnet_volume: Balance @classmethod def from_vec_u8(cls, vec_u8: list[int]) -> Optional["DynamicInfo"]: From c5d0c76ba9ff243a393454e69d8f1403718dbef7 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 4 Feb 2025 14:53:31 -0800 Subject: [PATCH 5/6] Updates chain data --- bittensor_cli/src/bittensor/chain_data.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bittensor_cli/src/bittensor/chain_data.py b/bittensor_cli/src/bittensor/chain_data.py index 4874acc51..859a2cd6a 100644 --- a/bittensor_cli/src/bittensor/chain_data.py +++ b/bittensor_cli/src/bittensor/chain_data.py @@ -637,14 +637,17 @@ def _fix_decoded(cls, decoded: Any) -> "DynamicInfo": owner_hotkey = decode_account_id(decoded.get("owner_hotkey")) owner_coldkey = decode_account_id(decoded.get("owner_coldkey")) - emission = Balance.from_rao(decoded["emission"]).set_unit(0) - alpha_in = Balance.from_rao(decoded["alpha_in"]).set_unit(netuid) - alpha_out = Balance.from_rao(decoded["alpha_out"]).set_unit(netuid) - tao_in = Balance.from_rao(decoded["tao_in"]).set_unit(0) - subnet_volume = Balance.from_rao(decoded["subnet_volume"]).set_unit(netuid) - alpha_out_emission = Balance.from_rao(decoded["alpha_out_emission"]).set_unit( + emission = Balance.from_rao(decoded.get("emission")).set_unit(0) + alpha_in = Balance.from_rao(decoded.get("alpha_in")).set_unit(netuid) + alpha_out = Balance.from_rao(decoded.get("alpha_out")).set_unit(netuid) + tao_in = Balance.from_rao(decoded.get("tao_in")).set_unit(0) + alpha_out_emission = Balance.from_rao( + decoded.get("alpha_out_emission") + ).set_unit(netuid) + alpha_in_emission = Balance.from_rao(decoded.get("alpha_in_emission")).set_unit( netuid ) + subnet_volume = Balance.from_rao(decoded.get("subnet_volume")).set_unit(netuid) tao_in_emission = Balance.from_rao(decoded.get("tao_in_emission")).set_unit(0) pending_alpha_emission = Balance.from_rao( decoded.get("pending_alpha_emission") From adf9b8833bdf36654d2a687c9c53e6e7057d4d40 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 4 Feb 2025 15:28:00 -0800 Subject: [PATCH 6/6] Adds ss58 option for origin hotkey for stake move --- bittensor_cli/cli.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index fb599cdf1..5038ca06c 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -2580,7 +2580,12 @@ def stake_list( return self._run_command( stake.stake_list( - wallet, coldkey_ss58, self.initialize_chain(network), live, verbose, no_prompt + wallet, + coldkey_ss58, + self.initialize_chain(network), + live, + verbose, + no_prompt, ) ) @@ -3123,22 +3128,25 @@ def stake_move( ) origin_hotkey = wallet.hotkey.ss58_address 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 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 interactive_selection: - if not origin_netuid: + if origin_netuid is None: origin_netuid = IntPrompt.ask( "Enter the [blue]origin subnet[/blue] (netuid) to move stake from" ) - if not destination_netuid: + if destination_netuid is None: destination_netuid = IntPrompt.ask( "Enter the [blue]destination subnet[/blue] (netuid) to move stake to" )