From 65d1609da32964766f1382a781a56cef9f336f66 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Wed, 10 Dec 2025 15:54:24 -0800 Subject: [PATCH 01/28] add delegated type in docs + help text --- bittensor_cli/cli.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index dab315863..8c5a286be 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -163,7 +163,9 @@ def validate_claim_type(value: Optional[str]) -> Optional[claim_stake.ClaimType] return member return claim_stake.ClaimType(value) except ValueError: - raise typer.BadParameter(f"'{value}' is not one of 'Keep', 'Swap'.") + raise typer.BadParameter( + f"'{value}' is not one of 'Keep', 'Swap', 'Delegated'." + ) class Options: @@ -5838,6 +5840,7 @@ def stake_set_claim_type( • [green]Swap[/green]: Future Root Alpha Emissions are swapped to TAO and added to root stake (default) • [yellow]Keep[/yellow]: Future Root Alpha Emissions are kept as Alpha tokens • [cyan]Keep Specific[/cyan]: Keep specific subnets as Alpha, swap others to TAO. You can use this type by selecting the netuids. + • [magenta]Delegated[/magenta]: Delegate claim choice to validator (inherits validator claim type) USAGE: @@ -5846,6 +5849,7 @@ def stake_set_claim_type( [green]$[/green] btcli stake claim swap [cyan](Swap all subnets)[/cyan] [green]$[/green] btcli stake claim keep --netuids 1-5,10,20-30 [cyan](Keep specific subnets)[/cyan] [green]$[/green] btcli stake claim swap --netuids 1-30 [cyan](Swap specific subnets)[/cyan] + [green]$[/green] btcli stake claim delegated [cyan](Delegate claim choice to validator)[/cyan] With specific wallet: From 5bbc924e97be52466a1430579855b121c8fb057e Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Wed, 10 Dec 2025 15:54:45 -0800 Subject: [PATCH 02/28] support setting delegated type --- bittensor_cli/src/commands/stake/claim.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/bittensor_cli/src/commands/stake/claim.py b/bittensor_cli/src/commands/stake/claim.py index 396255198..7845f26d1 100644 --- a/bittensor_cli/src/commands/stake/claim.py +++ b/bittensor_cli/src/commands/stake/claim.py @@ -29,6 +29,7 @@ class ClaimType(Enum): Keep = "Keep" Swap = "Swap" + Delegated = "Delegated" async def set_claim_type( @@ -536,18 +537,22 @@ async def _ask_for_claim_types( "[yellow]Options:[/yellow]\n" " • [green]Swap[/green] - Convert emissions to TAO\n" " • [green]Keep[/green] - Keep emissions as Alpha\n" - " • [green]Keep Specific[/green] - Keep selected subnets, swap others\n", + " • [green]Keep Specific[/green] - Keep selected subnets, swap others\n" + " • [green]Delegated[/green] - Delegate claim choice to validator\n", ) ) primary_choice = Prompt.ask( "\nSelect new root claim type", - choices=["keep", "swap", "cancel"], + choices=["keep", "swap", "delegated", "cancel"], default="cancel", ) if primary_choice == "cancel": return None + if primary_choice == "delegated": + return {"type": "Delegated"} + apply_to_all = Confirm.ask( f"\nSet {primary_choice.capitalize()} to ALL subnets?", default=True ) @@ -713,6 +718,10 @@ def _format_claim_type_display( result += f"\n[yellow] ⟳ Swap:[/yellow] {swap_display}" return result + + elif claim_type == "Delegated": + return "[magenta]Delegated[/magenta]" + else: return "[red]Unknown[/red]" @@ -742,5 +751,7 @@ def _prepare_claim_type_args(claim_info: dict) -> dict: elif claim_type == "KeepSubnets": subnets = claim_info["subnets"] return {"KeepSubnets": {"subnets": subnets}} + elif claim_type == "Delegated": + return {"Delegated": None} else: raise ValueError(f"Unknown claim type: {claim_type}") From 0dc852baa0383edeb14e7c87abd90338da542b93 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Wed, 10 Dec 2025 16:52:01 -0800 Subject: [PATCH 03/28] add get_validator_claim_type --- .../src/bittensor/subtensor_interface.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/bittensor_cli/src/bittensor/subtensor_interface.py b/bittensor_cli/src/bittensor/subtensor_interface.py index 10004797f..c35f01f20 100644 --- a/bittensor_cli/src/bittensor/subtensor_interface.py +++ b/bittensor_cli/src/bittensor/subtensor_interface.py @@ -2034,6 +2034,37 @@ async def get_all_coldkeys_claim_type( return root_claim_types + async def get_validator_claim_type( + self, + hotkey_ss58: str, + netuid: int, + block_hash: Optional[str] = None, + reuse_block: bool = False, + ) -> dict: + """ + Retrieves the validator claim type for a specific hotkey on a subnet. + + Args: + hotkey_ss58: Validator hotkey SS58 address. + netuid: Subnet identifier. + block_hash: Optional block hash for the query. + reuse_block: Whether to reuse the last-used blockchain block hash. + + Returns: + dict: Claim type information in one of these formats: + - {"type": "Swap"} + - {"type": "Keep"} + """ + result = await self.query( + module="SubtensorModule", + storage_function="ValidatorClaimType", + params=[hotkey_ss58, netuid], + block_hash=block_hash, + reuse_block_hash=reuse_block, + ) + claim_type_key = next(iter(result.keys())) + return {"type": claim_type_key} + async def get_staking_hotkeys( self, coldkey_ss58: str, From 460672aaca3e077e5c617d2e9d1c1923cec087e9 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Wed, 10 Dec 2025 16:53:12 -0800 Subject: [PATCH 04/28] add get_all_validator_claim_types --- .../src/bittensor/subtensor_interface.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/bittensor_cli/src/bittensor/subtensor_interface.py b/bittensor_cli/src/bittensor/subtensor_interface.py index c35f01f20..8d7b1efa7 100644 --- a/bittensor_cli/src/bittensor/subtensor_interface.py +++ b/bittensor_cli/src/bittensor/subtensor_interface.py @@ -2065,6 +2065,38 @@ async def get_validator_claim_type( claim_type_key = next(iter(result.keys())) return {"type": claim_type_key} + async def get_all_validator_claim_types( + self, + hotkey_ss58: str, + block_hash: Optional[str] = None, + reuse_block: bool = False, + ) -> dict[int, str]: + """ + Retrieves validator claim types for all netuids for a given validator hotkey. + + Args: + hotkey_ss58: Validator hotkey SS58 address. + block_hash: Optional block hash for the query. + reuse_block: Whether to reuse the last-used block hash. + + Returns: + dict[int, str]: Mapping of netuid -> claim type ("Keep" or "Swap"). + """ + result = await self.substrate.query_map( + module="SubtensorModule", + storage_function="ValidatorClaimType", + params=[hotkey_ss58], + block_hash=block_hash, + reuse_block_hash=reuse_block, + ) + + claim_types: dict[int, str] = {} + async for netuid, claim_type_data in result: + claim_type_key = next(iter(claim_type_data.value.keys())) + claim_types[int(netuid)] = claim_type_key + + return claim_types + async def get_staking_hotkeys( self, coldkey_ss58: str, From 552f837c6adec062ddd8879fef88534a3dcc9461 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Wed, 10 Dec 2025 19:59:23 -0800 Subject: [PATCH 05/28] init file and add table definition --- .../src/commands/stake/validator_claim.py | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 bittensor_cli/src/commands/stake/validator_claim.py diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py new file mode 100644 index 000000000..ab9757a3b --- /dev/null +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -0,0 +1,70 @@ +import asyncio +from typing import Optional, Any + +from rich.table import Table +from rich import box + +from bittensor_cli.src import COLOR_PALETTE +from bittensor_cli.src.bittensor.chain_data import DynamicInfo +from bittensor_cli.src.bittensor.utils import ( + console, + err_console, + get_subnet_name, + millify_tao, +) + + +def _render_table(title: str, rows: list[tuple[str, ...]]) -> None: + table = Table( + title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]{title}[/]", + show_footer=False, + show_edge=False, + header_style="bold white", + border_style="bright_black", + style="bold", + title_justify="center", + show_lines=False, + pad_edge=True, + box=box.MINIMAL_DOUBLE_HEAD, + ) + + table.add_column("[bold white]Netuid", style="grey89", justify="center") + table.add_column("[bold white]Name", style="cyan", justify="left") + table.add_column( + "[bold white]Price \n(τ/α)", + style="dark_sea_green2", + justify="left", + ) + table.add_column( + "[bold white]Market Cap \n(α * Price)", + style="steel_blue3", + justify="left", + ) + table.add_column( + "[bold white]Emission (τ)", + style=COLOR_PALETTE["POOLS"]["EMISSION"], + justify="left", + ) + table.add_column( + "[bold white]Net Inflow EMA (τ)", + style=COLOR_PALETTE["POOLS"]["ALPHA_OUT"], + justify="left", + ) + table.add_column( + "[bold white]Stake (α_out)", + style=COLOR_PALETTE["STAKE"]["STAKE_ALPHA"], + justify="left", + ) + table.add_column( + "[bold white]Mechanisms", + style=COLOR_PALETTE["GENERAL"]["SUBHEADING_EXTRA_1"], + justify="center", + ) + + if not rows: + table.add_row("~", "No subnets", "-", "-", "-", "-", "-", "-") + else: + for row in rows: + table.add_row(*row) + + console.print(table) From f3e1b1c921099ddb9c7ebbde7a17db558e16c7f6 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Wed, 10 Dec 2025 19:59:41 -0800 Subject: [PATCH 06/28] add _format_subnet_row --- .../src/commands/stake/validator_claim.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index ab9757a3b..d4af2fd85 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -14,6 +14,51 @@ ) +def _format_subnet_row( + subnet: DynamicInfo, + mechanisms: dict[int, int], + ema_tao_inflow: dict[int, Any], + verbose: bool, +) -> tuple[str, ...]: + """ + Format a subnet row for display in a table. + """ + symbol = f"{subnet.symbol}\u200e" + netuid = subnet.netuid + price_value = f"{subnet.price.tao:,.4f}" + + market_cap = (subnet.alpha_in.tao + subnet.alpha_out.tao) * subnet.price.tao + market_cap_value = ( + f"{millify_tao(market_cap)}" if not verbose else f"{market_cap:,.4f}" + ) + + emission_tao = 0.0 if netuid == 0 else subnet.tao_in_emission.tao + + alpha_out_value = ( + f"{millify_tao(subnet.alpha_out.tao)}" + if not verbose + else f"{subnet.alpha_out.tao:,.4f}" + ) + alpha_out_cell = ( + f"{alpha_out_value} {symbol}" if netuid != 0 else f"{symbol} {alpha_out_value}" + ) + + ema_value = ema_tao_inflow.get(netuid).tao if netuid in ema_tao_inflow else 0.0 + + return ( + str(netuid), + f"[{COLOR_PALETTE['GENERAL']['SYMBOL']}]" + f"{subnet.symbol if netuid != 0 else 'τ'}[/{COLOR_PALETTE['GENERAL']['SYMBOL']}] " + f"{get_subnet_name(subnet)}", + f"{price_value} τ/{symbol}", + f"τ {market_cap_value}", + f"τ {emission_tao:,.4f}", + f"τ {ema_value:,.4f}", + alpha_out_cell, + str(mechanisms.get(netuid, 1)), + ) + + def _render_table(title: str, rows: list[tuple[str, ...]]) -> None: table = Table( title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]{title}[/]", From 8a5955b73d9c3504e58346542499de57de6273bf Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Wed, 10 Dec 2025 19:59:51 -0800 Subject: [PATCH 07/28] add show_validator_claims --- .../src/commands/stake/validator_claim.py | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index d4af2fd85..0e69255ba 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -14,6 +14,56 @@ ) +async def show_validator_claims( + subtensor, + hotkey_ss58: Optional[str] = None, + block_hash: Optional[str] = None, + verbose: bool = False, +) -> None: + """ + Display validator claim types (Keep/Swap) for all subnets of a validator hotkey. + Renders two tables: Keep & Swap based on subnet claim type. + """ + + hotkey_value = hotkey_ss58 + if not hotkey_value: + err_console.print("[red]Hotkey SS58 address is required.[/red]") + return + + block_hash = block_hash or await subtensor.substrate.get_chain_head() + + validator_claims, subnets, mechanisms, ema_tao_inflow = await asyncio.gather( + subtensor.get_all_validator_claim_types( + hotkey_ss58=hotkey_value, block_hash=block_hash + ), + subtensor.all_subnets(block_hash=block_hash), + subtensor.get_all_subnet_mechanisms(block_hash=block_hash), + subtensor.get_all_subnet_ema_tao_inflow(block_hash=block_hash), + ) + + root_subnet = next(s for s in subnets if s.netuid == 0) + other_subnets = sorted( + [s for s in subnets if s.netuid != 0], + key=lambda x: (x.alpha_in.tao + x.alpha_out.tao) * x.price.tao, + reverse=True, + ) + sorted_subnets = [root_subnet] + other_subnets + + keep_rows = [] + swap_rows = [] + + for subnet in sorted_subnets: + claim_type = validator_claims.get(subnet.netuid, "Keep") + row = _format_subnet_row(subnet, mechanisms, ema_tao_inflow, verbose) + if claim_type == "Swap": + swap_rows.append(row) + else: + keep_rows.append(row) + + _render_table("Keep", keep_rows) + _render_table("[red]Swap[/red]", swap_rows) + + def _format_subnet_row( subnet: DynamicInfo, mechanisms: dict[int, int], From 7c2373fe5a48d7e019a530709518afa5b69cc91d Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:33:50 -0800 Subject: [PATCH 08/28] better organize shoe vali claims --- .../src/commands/stake/validator_claim.py | 237 ++++++++++-------- 1 file changed, 132 insertions(+), 105 deletions(-) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 0e69255ba..d86837d7e 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -1,7 +1,12 @@ +import json import asyncio from typing import Optional, Any - +from rich.prompt import Confirm, Prompt +from rich.panel import Panel from rich.table import Table +from rich.columns import Columns +from rich.text import Text +from rich.console import Group from rich import box from bittensor_cli.src import COLOR_PALETTE @@ -11,6 +16,11 @@ err_console, get_subnet_name, millify_tao, + parse_subnet_range, + group_subnets, + unlock_key, + print_extrinsic_id, + json_console, ) @@ -19,12 +29,120 @@ async def show_validator_claims( hotkey_ss58: Optional[str] = None, block_hash: Optional[str] = None, verbose: bool = False, + json_output: bool = False, ) -> None: """ - Display validator claim types (Keep/Swap) for all subnets of a validator hotkey. - Renders two tables: Keep & Swap based on subnet claim type. + Displays the validator claim configuration (Keep vs Swap) for a given hotkey's subnets. + + This function fetches the current claim status for all subnets where the validator has presence. + + Args: + subtensor: The subtensor interface for chain interaction. + hotkey_ss58: The SS58 address of the validator's hotkey. + block_hash: Optional block hash to query state at. + verbose: If True, displays full precision values. + json_output: If True, prints JSON to stdout and suppresses table render. """ + def _format_subnet_row( + subnet: DynamicInfo, + mechanisms: dict[int, int], + ema_tao_inflow: dict[int, Any], + verbose: bool, + ) -> tuple[str, ...]: + symbol = f"{subnet.symbol}\u200e" + netuid = subnet.netuid + price_value = f"{subnet.price.tao:,.4f}" + + market_cap = (subnet.alpha_in.tao + subnet.alpha_out.tao) * subnet.price.tao + market_cap_value = ( + f"{millify_tao(market_cap)}" if not verbose else f"{market_cap:,.4f}" + ) + + emission_tao = 0.0 if netuid == 0 else subnet.tao_in_emission.tao + + alpha_out_value = ( + f"{millify_tao(subnet.alpha_out.tao)}" + if not verbose + else f"{subnet.alpha_out.tao:,.4f}" + ) + alpha_out_cell = ( + f"{alpha_out_value} {symbol}" + if netuid != 0 + else f"{symbol} {alpha_out_value}" + ) + + ema_value = ema_tao_inflow.get(netuid).tao if netuid in ema_tao_inflow else 0.0 + + return ( + str(netuid), + f"[{COLOR_PALETTE['GENERAL']['SYMBOL']}]" + f"{subnet.symbol if netuid != 0 else 'τ'}[/{COLOR_PALETTE['GENERAL']['SYMBOL']}] " + f"{get_subnet_name(subnet)}", + f"{price_value} τ/{symbol}", + f"τ {market_cap_value}", + f"τ {emission_tao:,.4f}", + f"τ {ema_value:,.4f}", + alpha_out_cell, + str(mechanisms.get(netuid, 1)), + ) + + def _render_table(title: str, rows: list[tuple[str, ...]]) -> None: + table = Table( + title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]{title}[/]", + show_footer=False, + show_edge=False, + header_style="bold white", + border_style="bright_black", + style="bold", + title_justify="center", + show_lines=False, + pad_edge=True, + box=box.MINIMAL_DOUBLE_HEAD, + ) + + table.add_column("[bold white]Netuid", style="grey89", justify="center") + table.add_column("[bold white]Name", style="cyan", justify="left") + table.add_column( + "[bold white]Price \n(τ/α)", + style="dark_sea_green2", + justify="left", + ) + table.add_column( + "[bold white]Market Cap \n(α * Price)", + style="steel_blue3", + justify="left", + ) + table.add_column( + "[bold white]Emission (τ)", + style=COLOR_PALETTE["POOLS"]["EMISSION"], + justify="left", + ) + table.add_column( + "[bold white]Net Inflow EMA (τ)", + style=COLOR_PALETTE["POOLS"]["ALPHA_OUT"], + justify="left", + ) + table.add_column( + "[bold white]Stake (α_out)", + style=COLOR_PALETTE["STAKE"]["STAKE_ALPHA"], + justify="left", + ) + table.add_column( + "[bold white]Mechanisms", + style=COLOR_PALETTE["GENERAL"]["SUBHEADING_EXTRA_1"], + justify="center", + ) + + if not rows: + table.add_row("~", "No subnets", "-", "-", "-", "-", "-", "-") + else: + for row in rows: + table.add_row(*row) + + console.print(table) + + # Main function hotkey_value = hotkey_ss58 if not hotkey_value: err_console.print("[red]Hotkey SS58 address is required.[/red]") @@ -51,7 +169,6 @@ async def show_validator_claims( keep_rows = [] swap_rows = [] - for subnet in sorted_subnets: claim_type = validator_claims.get(subnet.netuid, "Keep") row = _format_subnet_row(subnet, mechanisms, ema_tao_inflow, verbose) @@ -60,106 +177,16 @@ async def show_validator_claims( else: keep_rows.append(row) + if json_output: + output_data = { + "hotkey": hotkey_value, + "claims": {}, + } + for subnet in sorted_subnets: + claim_type = validator_claims.get(subnet.netuid, "Keep") + output_data["claims"][subnet.netuid] = claim_type + json_console.print(json.dumps(output_data)) + _render_table("Keep", keep_rows) _render_table("[red]Swap[/red]", swap_rows) - - -def _format_subnet_row( - subnet: DynamicInfo, - mechanisms: dict[int, int], - ema_tao_inflow: dict[int, Any], - verbose: bool, -) -> tuple[str, ...]: - """ - Format a subnet row for display in a table. - """ - symbol = f"{subnet.symbol}\u200e" - netuid = subnet.netuid - price_value = f"{subnet.price.tao:,.4f}" - - market_cap = (subnet.alpha_in.tao + subnet.alpha_out.tao) * subnet.price.tao - market_cap_value = ( - f"{millify_tao(market_cap)}" if not verbose else f"{market_cap:,.4f}" - ) - - emission_tao = 0.0 if netuid == 0 else subnet.tao_in_emission.tao - - alpha_out_value = ( - f"{millify_tao(subnet.alpha_out.tao)}" - if not verbose - else f"{subnet.alpha_out.tao:,.4f}" - ) - alpha_out_cell = ( - f"{alpha_out_value} {symbol}" if netuid != 0 else f"{symbol} {alpha_out_value}" - ) - - ema_value = ema_tao_inflow.get(netuid).tao if netuid in ema_tao_inflow else 0.0 - - return ( - str(netuid), - f"[{COLOR_PALETTE['GENERAL']['SYMBOL']}]" - f"{subnet.symbol if netuid != 0 else 'τ'}[/{COLOR_PALETTE['GENERAL']['SYMBOL']}] " - f"{get_subnet_name(subnet)}", - f"{price_value} τ/{symbol}", - f"τ {market_cap_value}", - f"τ {emission_tao:,.4f}", - f"τ {ema_value:,.4f}", - alpha_out_cell, - str(mechanisms.get(netuid, 1)), - ) - - -def _render_table(title: str, rows: list[tuple[str, ...]]) -> None: - table = Table( - title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]{title}[/]", - show_footer=False, - show_edge=False, - header_style="bold white", - border_style="bright_black", - style="bold", - title_justify="center", - show_lines=False, - pad_edge=True, - box=box.MINIMAL_DOUBLE_HEAD, - ) - - table.add_column("[bold white]Netuid", style="grey89", justify="center") - table.add_column("[bold white]Name", style="cyan", justify="left") - table.add_column( - "[bold white]Price \n(τ/α)", - style="dark_sea_green2", - justify="left", - ) - table.add_column( - "[bold white]Market Cap \n(α * Price)", - style="steel_blue3", - justify="left", - ) - table.add_column( - "[bold white]Emission (τ)", - style=COLOR_PALETTE["POOLS"]["EMISSION"], - justify="left", - ) - table.add_column( - "[bold white]Net Inflow EMA (τ)", - style=COLOR_PALETTE["POOLS"]["ALPHA_OUT"], - justify="left", - ) - table.add_column( - "[bold white]Stake (α_out)", - style=COLOR_PALETTE["STAKE"]["STAKE_ALPHA"], - justify="left", - ) - table.add_column( - "[bold white]Mechanisms", - style=COLOR_PALETTE["GENERAL"]["SUBHEADING_EXTRA_1"], - justify="center", - ) - - if not rows: - table.add_row("~", "No subnets", "-", "-", "-", "-", "-", "-") - else: - for row in rows: - table.add_row(*row) - - console.print(table) + return True From 465a314eab00ba90c1cdb45530686a40db991119 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:35:15 -0800 Subject: [PATCH 09/28] wip --- .../src/commands/stake/validator_claim.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index d86837d7e..081bf4d07 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -190,3 +190,40 @@ def _render_table(title: str, rows: list[tuple[str, ...]]) -> None: _render_table("Keep", keep_rows) _render_table("[red]Swap[/red]", swap_rows) return True + + +async def set_validator_claim_type( + wallet, + subtensor, + keep: Optional[str] = None, + swap: Optional[str] = None, + keep_all: bool = False, + swap_all: bool = False, + prompt: bool = True, + proxy: Optional[str] = None, + json_output: bool = False, +) -> bool: + """ + Configures the validator claim preference (Keep vs Swap) for subnets. + + Allows bulk updating of claim types for multiple subnets. Subnets set to 'Keep' will accumulate + emissions as Alpha (subnet token), while 'Swap' will automatically convert emissions to TAO. + + Operates in two modes: + 1. CLI Mode: Updates specific ranges via `--keep` and `--swap` flags. + 2. Interactive Mode: Launches a claim selector if no range flags are provided. + + Args: + wallet: The wallet configuration. + subtensor: The subtensor interface. + keep: Range info string for subnets to set to 'Keep'. + swap: Range info string for subnets to set to 'Swap'. + keep_all: If True, sets all valid subnets to 'Keep'. + swap_all: If True, sets all valid subnets to 'Swap'. + prompt: If True, requires confirmation before submitting extrinsic. + proxy: Optional proxy address for signing. + json_output: If True, outputs result as JSON. + + Returns: + bool: True if the operation succeeded, False otherwise. + """ From c04be6d005a57bdded49164af8f7dd59945bd5e2 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:35:47 -0800 Subject: [PATCH 10/28] wip --- .../src/commands/stake/validator_claim.py | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 081bf4d07..c26f5e408 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -227,3 +227,44 @@ async def set_validator_claim_type( Returns: bool: True if the operation succeeded, False otherwise. """ + + def _render_current_claims( + state: dict[int, str], + identity: dict = None, + ss58: str = None, + ): + validator_name = identity.get("name", "Unknown") + header_text = ( + f"[dim]Validator:[/dim] [bold cyan]{validator_name}[/bold cyan]\n" + f"[dim]({ss58})[/dim]" + ) + console.print(header_text, "\n") + + default_list = sorted([n for n, t in state.items() if t == "Default"]) + keep_list = sorted([n for n, t in state.items() if t == "Keep"]) + swap_list = sorted([n for n, t in state.items() if t == "Swap"]) + + default_str = group_subnets(default_list) if default_list else "[dim]None[/dim]" + keep_str = group_subnets(keep_list) if keep_list else "[dim]None[/dim]" + swap_str = group_subnets(swap_list) if swap_list else "[dim]None[/dim]" + + default_panel = Panel( + default_str, + title="[bold blue]Default (Keep - α)[/bold blue]", + border_style="blue", + expand=False, + ) + keep_panel = Panel( + keep_str, + title="[bold green]Keep (α)[/bold green]", + border_style="green", + expand=False, + ) + swap_panel = Panel( + swap_str, + title="[bold red]Swap (τ)[/bold red]", + border_style="red", + expand=False, + ) + + top_row = Columns([keep_panel, swap_panel], expand=False, equal=True) From ecf0417b6ea4711c02d538d3ae5e126961da79f2 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:35:59 -0800 Subject: [PATCH 11/28] adds _render_current_claims --- .../src/commands/stake/validator_claim.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index c26f5e408..529a9d86b 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -268,3 +268,34 @@ def _render_current_claims( ) top_row = Columns([keep_panel, swap_panel], expand=False, equal=True) + + total = len(state) + default_count = len(default_list) + keep_count = len(keep_list) + swap_count = len(swap_list) + + if total > 0: + effective_keep_count = keep_count + default_count + + keep_pct = effective_keep_count / total + bar_width = 30 + keep_chars = int(bar_width * keep_pct) + swap_chars = bar_width - keep_chars + + bar_visual = ( + f"[{'green' if effective_keep_count > 0 else 'dim'}]" + f"{'█' * keep_chars}[/]" + f"[{'red' if swap_count > 0 else 'dim'}]" + f"{'█' * swap_chars}[/]" + ) + + dist_text = ( + f"\n[bold]Distribution:[/bold] {bar_visual} " + f"[green]{effective_keep_count}[/green] vs [red]{swap_count}[/red]\n" + ) + else: + dist_text = "" + + console.print(Group(top_row, default_panel, Text.from_markup(dist_text))) + + \ No newline at end of file From 5a7e4ffcb81c52b3a765ba1c970cee2a5eb16b89 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:36:13 -0800 Subject: [PATCH 12/28] add _print_changes_table --- bittensor_cli/src/commands/stake/validator_claim.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 529a9d86b..2ff30e910 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -298,4 +298,13 @@ def _render_current_claims( console.print(Group(top_row, default_panel, Text.from_markup(dist_text))) - \ No newline at end of file + def _print_changes_table(calls: list[tuple[int, str]]): + table = Table(title="Pending Root Claim Changes", box=box.SIMPLE_HEAD, width=50) + table.add_column("Netuid", justify="center", style="cyan") + table.add_column("New Type", justify="center") + + for netuid, new_type in sorted(calls, key=lambda x: x[0]): + color = "green" if new_type == "Keep" else "red" + table.add_row(str(netuid), f"[{color}]{new_type}[/{color}]") + + console.print("\n\n", table) From 4b608269df8a47574b90ea0fa2b9258a6df8d373 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:36:42 -0800 Subject: [PATCH 13/28] add batched calls --- .../src/commands/stake/validator_claim.py | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 2ff30e910..82e80025f 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -308,3 +308,73 @@ def _print_changes_table(calls: list[tuple[int, str]]): table.add_row(str(netuid), f"[{color}]{new_type}[/{color}]") console.print("\n\n", table) + + async def _execute_claim_change_calls( + calls: list[tuple[int, str]], + ) -> bool: + extrinsic_calls = [] + for netuid, claim_type in calls: + type_arg = {claim_type: None} + + call = await subtensor.substrate.compose_call( + call_module="SubtensorModule", + call_function="set_validator_claim_type", + call_params={ + "hotkey": wallet.hotkey.ss58_address, + "netuid": netuid, + "new_claim_type": type_arg, + }, + ) + extrinsic_calls.append(call) + + with console.status( + ":satellite: Submitting updates...", + spinner="earth", + ): + if len(extrinsic_calls) == 1: + final_call = extrinsic_calls[0] + else: + final_call = await subtensor.substrate.compose_call( + call_module="Utility", + call_function="batch_all", + call_params={"calls": extrinsic_calls}, + ) + + success, err_msg, ext_receipt = await subtensor.sign_and_send_extrinsic( + final_call, wallet, proxy=proxy + ) + + if success: + if json_output: + json_console.print( + json.dumps( + { + "success": True, + "message": "Successfully updated validator claim types", + "extrinsic_hash": ext_receipt.extrinsic_hash, + "changes": [{"netuid": n, "type": t} for n, t in calls], + } + ) + ) + else: + console.print( + "[green]:white_check_mark: Successfully updated validator claim types![/green]" + ) + await print_extrinsic_id(ext_receipt) + return True + else: + if json_output: + json_console.print( + json.dumps( + { + "success": False, + "message": f"Transaction Failed: {err_msg}", + "error": err_msg, + } + ) + ) + else: + err_console.print( + f"[red]:cross_mark: Transaction Failed: {err_msg}[/red]" + ) + return False From 73e5d23081f82450618cbba85e9d66a3ebfc469b Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:36:54 -0800 Subject: [PATCH 14/28] _interactive_claim_selector --- .../src/commands/stake/validator_claim.py | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 82e80025f..0147ce5cb 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -378,3 +378,77 @@ async def _execute_claim_change_calls( f"[red]:cross_mark: Transaction Failed: {err_msg}[/red]" ) return False + + def _interactive_claim_selector( + state: dict[int, str], + all_netuids: list[int], + identity: dict = None, + ss58: str = None, + ) -> Optional[dict[int, str]]: + working_state = {} + for n in all_netuids: + working_state[n] = state.get(n, "Default") + + while True: + console.print("\n") + _render_current_claims(working_state, identity, ss58) + help_table = Table( + box=box.SIMPLE_HEAVY, + show_header=True, + header_style="bold white", + expand=False, + ) + help_table.add_column("Command", style="cyan", no_wrap=True) + help_table.add_column("Description", style="dim") + + help_table.add_row("keep ", "Move subnets to Keep (e.g. '1,3-5')") + help_table.add_row("swap ", "Move subnets to Swap (e.g. '2,10')") + help_table.add_row( + "keep-all / swap-all", "Move ALL subnets to Keep or Swap" + ) + help_table.add_row("[green]done[/green]", "Finish and Apply changes") + help_table.add_row("[red]q / quit[/red]", "Cancel operation") + + console.print(help_table) + + cmd = Prompt.ask("Enter command").strip().lower() + + if cmd in ("q", "quit", "exit"): + return None + + if cmd == "done": + return working_state + + if cmd == "keep-all": + for n in working_state: + working_state[n] = "Keep" + continue + + if cmd == "swap-all": + for n in working_state: + working_state[n] = "Swap" + continue + + parts = cmd.split(" ", 1) + if len(parts) < 2: + console.print("[red]Invalid command format.[/red]") + continue + + action, ranges = parts[0], parts[1] + try: + selected_netuids = parse_subnet_range( + ranges, total_subnets=len(all_netuids) + ) + valid = [n for n in selected_netuids if n in working_state] + + if action == "keep": + for n in valid: + working_state[n] = "Keep" + elif action == "swap": + for n in valid: + working_state[n] = "Swap" + else: + console.print(f"[red]Unknown action '{action}'[/red]") + + except ValueError as e: + console.print(f"[red]Error parsing range: {e}[/red]") From 486ca7f9fbdf869f9ed059a81e22527c704c6156 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:37:08 -0800 Subject: [PATCH 15/28] wip --- .../src/commands/stake/validator_claim.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 0147ce5cb..6640ca585 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -452,3 +452,32 @@ def _interactive_claim_selector( except ValueError as e: console.print(f"[red]Error parsing range: {e}[/red]") + + # Main function + if keep_all and swap_all: + err_console.print( + "[red]Cannot specify both --keep-all and --swap-all flags.[/red]" + ) + return False + + with console.status(":satellite: Fetching current state...", spinner="earth"): + block_hash = await subtensor.substrate.get_chain_head() + current_claims, all_netuids, identity = await asyncio.gather( + subtensor.get_all_validator_claim_types( + hotkey_ss58=wallet.hotkey.ss58_address, block_hash=block_hash + ), + subtensor.get_all_subnet_netuids(block_hash=block_hash), + subtensor.query_identity(wallet.coldkeypub.ss58_address), + ) + valid_subnets = [n for n in all_netuids if n != 0] + + target_keep: set[int] = set() + target_swap: set[int] = set() + + if keep_all: + target_keep = set(valid_subnets) + elif swap_all: + target_swap = set(valid_subnets) + + def process_ranges(arg_value, arg_name, target_set): + \ No newline at end of file From df233ed5cb7860fe106d039d88c27e0a8fd373b9 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:37:31 -0800 Subject: [PATCH 16/28] support interactive mode --- .../src/commands/stake/validator_claim.py | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 6640ca585..d26856f0a 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -480,4 +480,52 @@ def _interactive_claim_selector( target_swap = set(valid_subnets) def process_ranges(arg_value, arg_name, target_set): - \ No newline at end of file + try: + parsed = parse_subnet_range(arg_value, total_subnets=len(valid_subnets)) + valid = {s for s in parsed if s in valid_subnets} + invalid = [s for s in parsed if s not in valid_subnets] + if invalid: + console.print( + f"[yellow]Ignored invalid/unknown subnets for {arg_name}: {invalid}[/yellow]" + ) + target_set.update(valid) + return True + except ValueError as e: + err_console.print(f"[red]Invalid --{arg_name} format: {e}[/red]") + return False + + if keep and not process_ranges(keep, "keep", target_keep): + return False + + if swap and not process_ranges(swap, "swap", target_swap): + return False + + # Check for duplicate entries in keep and swap + intersection = target_keep.intersection(target_swap) + if intersection: + err_console.print( + f"[red]Subnets cannot be both Keep and Swap: {intersection}[/red]" + ) + return False + + calls_to_make = [] + is_interactive = not (keep_all or swap_all or keep or swap) + # Interactive mode + if is_interactive: + state = {} + for netuid in valid_subnets: + state[netuid] = current_claims.get(netuid, "Default") + + final_state = _interactive_claim_selector( + state, list(valid_subnets), identity, wallet.coldkeypub.ss58_address + ) + if final_state is None: + console.print("[yellow]Operation cancelled.[/yellow]") + return False + + for netuid, new_type in final_state.items(): + if new_type == "Default": + continue + current_type = current_claims.get(netuid, "Default") + if new_type != current_type: + calls_to_make.append((netuid, new_type)) From 92de4805e8624b93a06c562bff4385f27dc8e6c1 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:37:45 -0800 Subject: [PATCH 17/28] finish set claim cmd --- .../src/commands/stake/validator_claim.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index d26856f0a..3583978b7 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -529,3 +529,43 @@ def process_ranges(arg_value, arg_name, target_set): current_type = current_claims.get(netuid, "Default") if new_type != current_type: calls_to_make.append((netuid, new_type)) + + # Non-interactive + else: + for netuid in target_keep: + curr_type = current_claims.get(netuid, "Default") + if curr_type != "Keep": + calls_to_make.append((netuid, "Keep")) + + for netuid in target_swap: + curr_type = current_claims.get(netuid, "Default") + if curr_type != "Swap": + calls_to_make.append((netuid, "Swap")) + + final_state = {} + for n in valid_subnets: + final_state[n] = current_claims.get(n, "Default") + for n in target_keep: + final_state[n] = "Keep" + for n in target_swap: + final_state[n] = "Swap" + + _render_current_claims(final_state, identity, wallet.coldkeypub.ss58_address) + + if not calls_to_make: + console.print( + "[green]Desired state matches current chain state. No changes needed.[/green]" + ) + return True + + if prompt: + _print_changes_table(calls_to_make) + if not Confirm.ask("Do you want to apply these changes?"): + console.print("[yellow]Cancelled.[/yellow]") + return False + + if not (unlock := unlock_key(wallet)).success: + err_console.print(f"[red]Failed to unlock wallet: {unlock.message}[/red]") + return False + + return await _execute_claim_change_calls(calls_to_make) From 80bbbf55a0bef1e0f5abf535986eff0810922b19 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:42:25 -0800 Subject: [PATCH 18/28] add vali identity in claim show --- .../src/commands/stake/validator_claim.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 3583978b7..93a6dadfa 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -87,9 +87,11 @@ def _format_subnet_row( str(mechanisms.get(netuid, 1)), ) - def _render_table(title: str, rows: list[tuple[str, ...]]) -> None: + def _render_table( + title: str, identity: str, hotkey_value: str, rows: list[tuple[str, ...]] + ) -> None: table = Table( - title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]{title}[/]", + title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]{title}[/]\n[dim]{identity}:{hotkey_value}\n", show_footer=False, show_edge=False, header_style="bold white", @@ -150,13 +152,20 @@ def _render_table(title: str, rows: list[tuple[str, ...]]) -> None: block_hash = block_hash or await subtensor.substrate.get_chain_head() - validator_claims, subnets, mechanisms, ema_tao_inflow = await asyncio.gather( + ( + validator_claims, + subnets, + mechanisms, + ema_tao_inflow, + identity, + ) = await asyncio.gather( subtensor.get_all_validator_claim_types( hotkey_ss58=hotkey_value, block_hash=block_hash ), subtensor.all_subnets(block_hash=block_hash), subtensor.get_all_subnet_mechanisms(block_hash=block_hash), subtensor.get_all_subnet_ema_tao_inflow(block_hash=block_hash), + subtensor.query_identity(hotkey_value), ) root_subnet = next(s for s in subnets if s.netuid == 0) @@ -187,8 +196,9 @@ def _render_table(title: str, rows: list[tuple[str, ...]]) -> None: output_data["claims"][subnet.netuid] = claim_type json_console.print(json.dumps(output_data)) - _render_table("Keep", keep_rows) - _render_table("[red]Swap[/red]", swap_rows) + validator_name = identity.get("name", "Unknown") + _render_table("Keep", validator_name, hotkey_value, keep_rows) + _render_table("[red]Swap[/red]", validator_name, hotkey_value, swap_rows) return True From aaf0f0bc730d0e2870d96d1c200b67ed2ebeceb8 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:50:12 -0800 Subject: [PATCH 19/28] adds show-validator-claims --- bittensor_cli/cli.py | 56 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 8c5a286be..6cf79d8da 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -97,6 +97,7 @@ add as add_stake, remove as remove_stake, claim as claim_stake, + validator_claim, wizard as stake_wizard, ) from bittensor_cli.src.commands.subnets import ( @@ -1087,6 +1088,9 @@ def __init__(self): self.stake_app.command( "process-claim", rich_help_panel=HELP_PANELS["STAKE"]["CLAIM"] )(self.stake_process_claim) + self.stake_app.command( + "show-validator-claims", rich_help_panel=HELP_PANELS["STAKE"]["CLAIM"] + )(self.show_validator_claims) # stake-children commands children_app = typer.Typer() @@ -5943,6 +5947,56 @@ def stake_process_claim( ) ) + def show_validator_claims( + self, + hotkey_ss58: Optional[str] = Options.wallet_hotkey_ss58, + wallet_name: Optional[str] = Options.wallet_name, + wallet_path: Optional[str] = Options.wallet_path, + network: Optional[list[str]] = Options.network, + prompt: bool = Options.prompt, + quiet: bool = Options.quiet, + verbose: bool = Options.verbose, + json_output: bool = Options.json_output, + ): + """ + Show validator claim types (Keep/Swap) across all subnets for a validator hotkey. + + Provide a hotkey SS58 directly, or supply a wallet and hotkey name to resolve it. + """ + self.verbosity_handler(quiet, verbose, False, prompt) + + if not hotkey_ss58 and not wallet_name: + ss58_or_wallet = Prompt.ask( + "Enter the [blue]hotkey ss58 address[/blue] or [blue]wallet name[/blue]", + default=self.config.get("wallet_name") or defaults.wallet.name, + ) + if is_valid_ss58_address(ss58_or_wallet): + hotkey_ss58 = ss58_or_wallet + else: + wallet_name = ss58_or_wallet + + if hotkey_ss58: + if is_valid_ss58_address(hotkey_ss58): + vali_hk_ss58 = hotkey_ss58 + else: + wallet = self.wallet_ask( + wallet_name, + wallet_path, + hotkey_ss58, + ask_for=[WO.NAME, WO.HOTKEY], + validate=WV.WALLET_AND_HOTKEY, + ) + vali_hk_ss58 = get_hotkey_pub_ss58(wallet) + + return self._run_command( + validator_claim.show_validator_claims( + subtensor=self.initialize_chain(network), + hotkey_ss58=vali_hk_ss58, + verbose=verbose, + json_output=json_output, + ) + ) + def stake_get_children( self, wallet_name: Optional[str] = Options.wallet_name, @@ -6027,9 +6081,9 @@ def stake_set_children( announce_only: bool = Options.announce_only, wait_for_inclusion: bool = Options.wait_for_inclusion, wait_for_finalization: bool = Options.wait_for_finalization, + prompt: bool = Options.prompt, quiet: bool = Options.quiet, verbose: bool = Options.verbose, - prompt: bool = Options.prompt, json_output: bool = Options.json_output, ): """ From 8e15cd4bd5713cb86bf68d1711028374c57ad2a8 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 17:50:22 -0800 Subject: [PATCH 20/28] add set-validator-claims --- bittensor_cli/cli.py | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 6cf79d8da..2d39a0c90 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -1091,6 +1091,9 @@ def __init__(self): self.stake_app.command( "show-validator-claims", rich_help_panel=HELP_PANELS["STAKE"]["CLAIM"] )(self.show_validator_claims) + self.stake_app.command( + "set-validator-claims", rich_help_panel=HELP_PANELS["STAKE"]["CLAIM"] + )(self.set_validator_claim_types) # stake-children commands children_app = typer.Typer() @@ -5879,6 +5882,78 @@ def stake_set_claim_type( ) ) + def set_validator_claim_types( + self, + keep: Optional[str] = typer.Option( + None, + "--keep", + help="Subnets to keep emissions for (e.g. '1,3-5').", + ), + swap: Optional[str] = typer.Option( + None, + "--swap", + help="Subnets to swap emissions for (e.g. '2,6-10').", + ), + keep_all: bool = typer.Option( + False, + "--keep-all", + help="Set all registered subnets to Keep.", + ), + swap_all: bool = typer.Option( + False, + "--swap-all", + help="Set all registered subnets to Swap.", + ), + wallet_name: Optional[str] = Options.wallet_name, + wallet_path: Optional[str] = Options.wallet_path, + wallet_hotkey: Optional[str] = Options.wallet_hotkey, + network: Optional[list[str]] = Options.network, + proxy: Optional[str] = Options.proxy, + announce_only: bool = Options.announce_only, + prompt: bool = Options.prompt, + quiet: bool = Options.quiet, + verbose: bool = Options.verbose, + json_output: bool = Options.json_output, + ): + """ + Set the claim type for a validator across multiple subnets. + + This command allows validators to specify how they want to handle emissions for each subnet: + - [bold]Keep[/bold]: Keep emissions as Alpha tokens on the subnet. + - [bold]Swap[/bold]: Automatically swap Alpha emissions to TAO on the root network. + + You can set preferences for specific subnets using [blue]--keep[/blue] and [blue]--swap[/blue], or update all registered subnets using [blue]--keep-all[/blue] or [blue]--swap-all[/blue]. + + If no arguments are provided, an interactive editor will be launched. + + EXAMPLES: + [green]$[/green] btcli stake set-validator-claim --keep 1,3-5 --swap 2,10 + [green]$[/green] btcli stake set-validator-claim --keep-all + [green]$[/green] btcli stake set-validator-claim (Interactive mode) + """ + self.verbosity_handler(quiet, verbose, json_output, prompt) + proxy = self.is_valid_proxy_name_or_ss58(proxy, announce_only) + wallet = self.wallet_ask( + wallet_name, + wallet_path, + wallet_hotkey, + ask_for=[WO.NAME, WO.HOTKEY], + validate=WV.WALLET_AND_HOTKEY, + ) + return self._run_command( + validator_claim.set_validator_claim_type( + wallet=wallet, + subtensor=self.initialize_chain(network), + keep=keep, + swap=swap, + keep_all=keep_all, + swap_all=swap_all, + prompt=prompt, + proxy=proxy, + json_output=json_output, + ) + ) + def stake_process_claim( self, netuids: Optional[str] = Options.netuids, From 340048ceae7a102dca7e5480042ddee8463fb89e Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 18:38:04 -0800 Subject: [PATCH 21/28] update claim display for subnets & remove from root --- bittensor_cli/src/commands/subnets/subnets.py | 45 +++++++------------ 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/bittensor_cli/src/commands/subnets/subnets.py b/bittensor_cli/src/commands/subnets/subnets.py index 526037bc6..0b6796987 100644 --- a/bittensor_cli/src/commands/subnets/subnets.py +++ b/bittensor_cli/src/commands/subnets/subnets.py @@ -1068,13 +1068,11 @@ async def show_root(): root_state, identities, old_identities, - root_claim_types, ) = await asyncio.gather( subtensor.all_subnets(block_hash=block_hash), subtensor.get_subnet_state(netuid=0, block_hash=block_hash), subtensor.query_all_identities(block_hash=block_hash), subtensor.get_delegate_identities(block_hash=block_hash), - subtensor.get_all_coldkeys_claim_type(block_hash=block_hash), ) root_info = next((s for s in all_subnets if s.netuid == 0), None) if root_info is None: @@ -1134,11 +1132,6 @@ async def show_root(): style=COLOR_PALETTE["GENERAL"]["SYMBOL"], justify="left", ) - table.add_column( - "[bold white]Claim Type", - style=COLOR_PALETTE["GENERAL"]["SUBHEADING"], - justify="center", - ) sorted_hotkeys = sorted( enumerate(root_state.hotkeys), @@ -1170,9 +1163,6 @@ async def show_root(): ) coldkey_ss58 = root_state.coldkeys[idx] - claim_type_info = root_claim_types.get(coldkey_ss58, {"type": "Swap"}) - total_subnets = len([n for n in all_subnets if n != 0]) - claim_type = format_claim_type_for_root(claim_type_info, total_subnets) sorted_rows.append( ( @@ -1194,7 +1184,6 @@ async def show_root(): if not verbose else f"{root_state.coldkeys[idx]}", # Coldkey validator_identity, # Identity - claim_type, # Root Claim Type ) ) sorted_hks_delegation.append(root_state.hotkeys[idx]) @@ -1246,8 +1235,6 @@ async def show_root(): - Emission: The emission accrued to this hotkey across all subnets every block measured in TAO. - Hotkey: The hotkey ss58 address. - Coldkey: The coldkey ss58 address. - - Root Claim: The root claim type for this coldkey. 'Swap' converts Alpha to TAO every epoch. 'Keep' keeps Alpha emissions. - 'Keep (count)' indicates how many subnets this coldkey is keeping Alpha emissions for. """ ) if delegate_selection: @@ -1300,7 +1287,7 @@ async def show_subnet( identities, old_identities, current_burn_cost, - root_claim_types, + validator_claim_types, ema_tao_inflow, ) = await asyncio.gather( subtensor.subnet(netuid=netuid_, block_hash=block_hash), @@ -1309,7 +1296,7 @@ async def show_subnet( subtensor.get_hyperparameter( param_name="Burn", netuid=netuid_, block_hash=block_hash ), - subtensor.get_all_coldkeys_claim_type(block_hash=block_hash), + subtensor.get_all_validator_claim_types(block_hash=block_hash), subtensor.get_subnet_ema_tao_inflow( netuid=netuid_, block_hash=block_hash ), @@ -1420,14 +1407,19 @@ async def show_subnet( # Modify tao stake with TAO_WEIGHT tao_stake = metagraph_info.tao_stake[idx] * TAO_WEIGHT - # Get claim type for this coldkey if applicable TAO stake - coldkey_ss58 = metagraph_info.coldkeys[idx] - claim_type_info = {"type": "Swap"} # Default - claim_type = "-" - + # Get claim type for this hotkey if applicable TAO stake + hotkey_ss58 = metagraph_info.hotkeys[idx] + claim_type_value = None + claim_display = "-" if tao_stake.tao > 0: - claim_type_info = root_claim_types.get(coldkey_ss58, {"type": "Swap"}) - claim_type = format_claim_type_for_subnet(claim_type_info, netuid_) + claim_type_value = validator_claim_types.get(hotkey_ss58, {}).get( + netuid_, "Keep" + ) + claim_display = ( + f"[green]{claim_type_value}[/green]" + if claim_type_value == "Keep" + else f"[red]{claim_type_value}[/red]" + ) rows.append( ( @@ -1451,7 +1443,7 @@ async def show_subnet( if not verbose else f"{metagraph_info.coldkeys[idx]}", # Coldkey uid_identity, # Identity - claim_type, # Root Claim Type + claim_display, # Claim Type ) ) json_out_rows.append( @@ -1468,12 +1460,7 @@ async def show_subnet( "hotkey": metagraph_info.hotkeys[idx], "coldkey": metagraph_info.coldkeys[idx], "identity": uid_identity, - "claim_type": claim_type_info.get("type") - if tao_stake.tao > 0 - else None, - "claim_type_subnets": claim_type_info.get("subnets") - if claim_type_info.get("type") == "KeepSubnets" - else None, + "claim_type": claim_type_value, } ) From b3791e8699451c9caac64fc5bb4b4832c6258787 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 18:40:04 -0800 Subject: [PATCH 22/28] add get_all_vali_claim_types & rename others --- .../src/bittensor/subtensor_interface.py | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/bittensor_cli/src/bittensor/subtensor_interface.py b/bittensor_cli/src/bittensor/subtensor_interface.py index 8d7b1efa7..9b8fcd7de 100644 --- a/bittensor_cli/src/bittensor/subtensor_interface.py +++ b/bittensor_cli/src/bittensor/subtensor_interface.py @@ -2034,7 +2034,7 @@ async def get_all_coldkeys_claim_type( return root_claim_types - async def get_validator_claim_type( + async def get_vali_claim_types_for_hk_netuid( self, hotkey_ss58: str, netuid: int, @@ -2065,7 +2065,41 @@ async def get_validator_claim_type( claim_type_key = next(iter(result.keys())) return {"type": claim_type_key} - async def get_all_validator_claim_types( + async def get_all_vali_claim_types( + self, + block_hash: Optional[str] = None, + reuse_block: bool = False, + ) -> dict[int, str]: + """ + Retrieves validator claim types for all netuids for all validator hotkeys. + + Args: + block_hash: Optional block hash for the query. + reuse_block: Whether to reuse the last-used block hash. + + Returns: + dict[int, str]: Mapping of netuid -> claim type ("Keep" or "Swap"). + """ + result = await self.substrate.query_map( + module="SubtensorModule", + storage_function="ValidatorClaimType", + params=[], + block_hash=block_hash, + reuse_block_hash=reuse_block, + ) + + claim_types: dict[str, dict[int, str]] = {} + async for hk_netuid, claim_type_data in result: + hotkey_ss58 = decode_account_id(hk_netuid[0]) + netuid = int(hk_netuid[1]) + claim_type_key = next(iter(claim_type_data.value.keys())) + if hotkey_ss58 not in claim_types: + claim_types[hotkey_ss58] = {} + claim_types[hotkey_ss58][netuid] = claim_type_key + + return claim_types + + async def get_all_vali_claim_types_for_hk( self, hotkey_ss58: str, block_hash: Optional[str] = None, From 5904a87c7f6de6761c58c3a6baf4efef8fd262ef Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 18:40:15 -0800 Subject: [PATCH 23/28] rename --- bittensor_cli/src/commands/stake/validator_claim.py | 7 ++++--- bittensor_cli/src/commands/subnets/subnets.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 93a6dadfa..add51d385 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -159,7 +159,7 @@ def _render_table( ema_tao_inflow, identity, ) = await asyncio.gather( - subtensor.get_all_validator_claim_types( + subtensor.get_all_vali_claim_types_for_hk( hotkey_ss58=hotkey_value, block_hash=block_hash ), subtensor.all_subnets(block_hash=block_hash), @@ -472,12 +472,13 @@ def _interactive_claim_selector( with console.status(":satellite: Fetching current state...", spinner="earth"): block_hash = await subtensor.substrate.get_chain_head() - current_claims, all_netuids, identity = await asyncio.gather( - subtensor.get_all_validator_claim_types( + current_claims, all_netuids, identity, testing = await asyncio.gather( + subtensor.get_all_vali_claim_types_for_hk( hotkey_ss58=wallet.hotkey.ss58_address, block_hash=block_hash ), subtensor.get_all_subnet_netuids(block_hash=block_hash), subtensor.query_identity(wallet.coldkeypub.ss58_address), + subtensor.get_all_vali_claim_types(block_hash=block_hash), ) valid_subnets = [n for n in all_netuids if n != 0] diff --git a/bittensor_cli/src/commands/subnets/subnets.py b/bittensor_cli/src/commands/subnets/subnets.py index 0b6796987..8ff7030b8 100644 --- a/bittensor_cli/src/commands/subnets/subnets.py +++ b/bittensor_cli/src/commands/subnets/subnets.py @@ -1296,7 +1296,7 @@ async def show_subnet( subtensor.get_hyperparameter( param_name="Burn", netuid=netuid_, block_hash=block_hash ), - subtensor.get_all_validator_claim_types(block_hash=block_hash), + subtensor.get_all_vali_claim_types(block_hash=block_hash), subtensor.get_subnet_ema_tao_inflow( netuid=netuid_, block_hash=block_hash ), From dcbeb620433e3d9987b615f3cf4843b2e13d4ad9 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 18:43:07 -0800 Subject: [PATCH 24/28] add aliases --- bittensor_cli/cli.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 2d39a0c90..ff1523419 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -1295,6 +1295,14 @@ def __init__(self): "unclaim", hidden=True, )(self.stake_set_claim_type) + self.stake_app.command( + "show-validator-claim", + hidden=True, + )(self.show_validator_claims) + self.stake_app.command( + "set-validator-claim", + hidden=True, + )(self.set_validator_claim_types) # Crowdloan self.app.add_typer( From e9874a2bfed5ec0998404d1dbed5b066f79e063b Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 18:44:54 -0800 Subject: [PATCH 25/28] update help --- bittensor_cli/cli.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index ff1523419..43aba3d71 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -6044,7 +6044,9 @@ def show_validator_claims( """ Show validator claim types (Keep/Swap) across all subnets for a validator hotkey. - Provide a hotkey SS58 directly, or supply a wallet and hotkey name to resolve it. + EXAMPLES: + [green]$[/green] btcli stake show-validator-claims --hotkey 5Grw... + [green]$[/green] btcli stake show-validator-claims --wallet-name my_wallet --wallet-hotkey hk """ self.verbosity_handler(quiet, verbose, False, prompt) From 79a2b5c069f5fa31f7a23aa0b07d8f9b25743cff Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 19:09:41 -0800 Subject: [PATCH 26/28] update --- bittensor_cli/cli.py | 4 +- .../src/commands/stake/validator_claim.py | 38 ++++--------------- 2 files changed, 8 insertions(+), 34 deletions(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 43aba3d71..97e0237c9 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -5921,7 +5921,6 @@ def set_validator_claim_types( prompt: bool = Options.prompt, quiet: bool = Options.quiet, verbose: bool = Options.verbose, - json_output: bool = Options.json_output, ): """ Set the claim type for a validator across multiple subnets. @@ -5939,7 +5938,7 @@ def set_validator_claim_types( [green]$[/green] btcli stake set-validator-claim --keep-all [green]$[/green] btcli stake set-validator-claim (Interactive mode) """ - self.verbosity_handler(quiet, verbose, json_output, prompt) + self.verbosity_handler(quiet, verbose, False, prompt) proxy = self.is_valid_proxy_name_or_ss58(proxy, announce_only) wallet = self.wallet_ask( wallet_name, @@ -5958,7 +5957,6 @@ def set_validator_claim_types( swap_all=swap_all, prompt=prompt, proxy=proxy, - json_output=json_output, ) ) diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index add51d385..6d12b4c41 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -211,7 +211,6 @@ async def set_validator_claim_type( swap_all: bool = False, prompt: bool = True, proxy: Optional[str] = None, - json_output: bool = False, ) -> bool: """ Configures the validator claim preference (Keep vs Swap) for subnets. @@ -355,38 +354,15 @@ async def _execute_claim_change_calls( ) if success: - if json_output: - json_console.print( - json.dumps( - { - "success": True, - "message": "Successfully updated validator claim types", - "extrinsic_hash": ext_receipt.extrinsic_hash, - "changes": [{"netuid": n, "type": t} for n, t in calls], - } - ) - ) - else: - console.print( - "[green]:white_check_mark: Successfully updated validator claim types![/green]" - ) - await print_extrinsic_id(ext_receipt) + console.print( + "[green]:white_check_mark: Successfully updated validator claim types![/green]" + ) + await print_extrinsic_id(ext_receipt) return True else: - if json_output: - json_console.print( - json.dumps( - { - "success": False, - "message": f"Transaction Failed: {err_msg}", - "error": err_msg, - } - ) - ) - else: - err_console.print( - f"[red]:cross_mark: Transaction Failed: {err_msg}[/red]" - ) + err_console.print( + f"[red]:cross_mark: Transaction Failed: {err_msg}[/red]" + ) return False def _interactive_claim_selector( From 1891c0400c8ace14f98e502e37e95e6cbe64c050 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 19:29:36 -0800 Subject: [PATCH 27/28] add test --- bittensor_cli/cli.py | 2 +- tests/e2e_tests/test_claim_types.py | 170 ++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 tests/e2e_tests/test_claim_types.py diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 97e0237c9..011bfb450 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -6046,7 +6046,7 @@ def show_validator_claims( [green]$[/green] btcli stake show-validator-claims --hotkey 5Grw... [green]$[/green] btcli stake show-validator-claims --wallet-name my_wallet --wallet-hotkey hk """ - self.verbosity_handler(quiet, verbose, False, prompt) + self.verbosity_handler(quiet, verbose, json_output, False) if not hotkey_ss58 and not wallet_name: ss58_or_wallet = Prompt.ask( diff --git a/tests/e2e_tests/test_claim_types.py b/tests/e2e_tests/test_claim_types.py new file mode 100644 index 000000000..ea5731950 --- /dev/null +++ b/tests/e2e_tests/test_claim_types.py @@ -0,0 +1,170 @@ +""" +Verify commands: + +* btcli stake set-claim swap +* btcli stake set-claim keep +* btcli stake set-claim keep --netuids 2-4 +* btcli stake set-claim delegated +* btcli stake set-validator-claims --swap 2-4 +* btcli stake set-validator-claims --keep 1-3 +""" + + +def test_claim_type_flows(local_chain, wallet_setup): + """ + Cover root claim type transitions (Swap, Keep, KeepSubnets, Delegated) + and validator claim type settings using the CLI. + """ + + # Wallet setup + keypair_alice, wallet_alice, wallet_path_alice, exec_command_alice = wallet_setup( + "//Alice" + ) + + # Create multiple subnets + for netuid in [2, 3, 4]: + result = exec_command_alice( + command="subnets", + sub_command="create", + extra_args=[ + "--wallet-path", + wallet_path_alice, + "--chain", + "ws://127.0.0.1:9945", + "--wallet-name", + wallet_alice.name, + "--wallet-hotkey", + wallet_alice.hotkey_str, + "--subnet-name", + "Test Subnet", + "--repo", + "https://github.com/username/repo", + "--contact", + "test@opentensor.dev", + "--url", + "https://testsubnet.com", + "--discord", + "test#1234", + "--description", + "A test subnet for e2e testing", + "--logo-url", + "https://testsubnet.com/logo.png", + "--additional-info", + "Test subnet", + "--no-prompt", + "--no-mev-protection", + ], + ) + assert f"✅ Registered subnetwork with netuid: {netuid}" in result.stdout + + # 1) Set to Swap (as a holder) + swap_result = exec_command_alice( + command="stake", + sub_command="set-claim", + extra_args=[ + "swap", + "--wallet-name", + wallet_alice.name, + "--wallet-path", + wallet_path_alice, + "--network", + "ws://127.0.0.1:9945", + "--no-prompt", + ], + ) + assert "✅ Successfully changed claim type" in swap_result.stdout + + # 2) Set to Keep (as a holder) + keep_result = exec_command_alice( + command="stake", + sub_command="set-claim", + extra_args=[ + "keep", + "--wallet-name", + wallet_alice.name, + "--wallet-path", + wallet_path_alice, + "--network", + "ws://127.0.0.1:9945", + "--no-prompt", + ], + ) + assert "✅ Successfully changed claim type" in keep_result.stdout + + # 3) Set to KeepSubnets (as a holder) + keep_subnets_result = exec_command_alice( + command="stake", + sub_command="set-claim", + extra_args=[ + "keep", + "--netuids", + "1-3", + "--wallet-name", + wallet_alice.name, + "--wallet-path", + wallet_path_alice, + "--network", + "ws://127.0.0.1:9945", + "--no-prompt", + ], + ) + assert "✅ Successfully changed claim type" in keep_subnets_result.stdout + + # 4) Set to Delegated (as a holder) + delegated_result = exec_command_alice( + command="stake", + sub_command="set-claim", + extra_args=[ + "delegated", + "--wallet-name", + wallet_alice.name, + "--wallet-path", + wallet_path_alice, + "--network", + "ws://127.0.0.1:9945", + "--no-prompt", + ], + ) + assert "✅ Successfully changed claim type" in delegated_result.stdout + + # 5) Validator claim (as a validator) + validator_claim_swap_result = exec_command_alice( + command="stake", + sub_command="set-validator-claims", + extra_args=[ + "--swap", + "1-3", + "--wallet-name", + wallet_alice.name, + "--wallet-path", + wallet_path_alice, + "--network", + "ws://127.0.0.1:9945", + "--no-prompt", + ], + ) + assert ( + "✅ Successfully updated validator claim types" + in validator_claim_swap_result.stdout + ) + + # 6) Validator claim (as a validator) + validator_claim_keep_result = exec_command_alice( + command="stake", + sub_command="set-validator-claims", + extra_args=[ + "--keep", + "1-3", + "--wallet-name", + wallet_alice.name, + "--wallet-path", + wallet_path_alice, + "--network", + "ws://127.0.0.1:9945", + "--no-prompt", + ], + ) + assert ( + "✅ Successfully updated validator claim types" + in validator_claim_keep_result.stdout + ) From 0e61026954642e0f2bb6c5168c941d688dd31579 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 11 Dec 2025 19:30:59 -0800 Subject: [PATCH 28/28] wip --- bittensor_cli/src/bittensor/subtensor_interface.py | 2 +- bittensor_cli/src/commands/stake/validator_claim.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bittensor_cli/src/bittensor/subtensor_interface.py b/bittensor_cli/src/bittensor/subtensor_interface.py index 9b8fcd7de..1dc4c433a 100644 --- a/bittensor_cli/src/bittensor/subtensor_interface.py +++ b/bittensor_cli/src/bittensor/subtensor_interface.py @@ -2099,7 +2099,7 @@ async def get_all_vali_claim_types( return claim_types - async def get_all_vali_claim_types_for_hk( + async def get_vali_claim_types_for_hk( self, hotkey_ss58: str, block_hash: Optional[str] = None, diff --git a/bittensor_cli/src/commands/stake/validator_claim.py b/bittensor_cli/src/commands/stake/validator_claim.py index 6d12b4c41..b6eae5fa4 100644 --- a/bittensor_cli/src/commands/stake/validator_claim.py +++ b/bittensor_cli/src/commands/stake/validator_claim.py @@ -159,7 +159,7 @@ def _render_table( ema_tao_inflow, identity, ) = await asyncio.gather( - subtensor.get_all_vali_claim_types_for_hk( + subtensor.get_vali_claim_types_for_hk( hotkey_ss58=hotkey_value, block_hash=block_hash ), subtensor.all_subnets(block_hash=block_hash), @@ -449,7 +449,7 @@ def _interactive_claim_selector( with console.status(":satellite: Fetching current state...", spinner="earth"): block_hash = await subtensor.substrate.get_chain_head() current_claims, all_netuids, identity, testing = await asyncio.gather( - subtensor.get_all_vali_claim_types_for_hk( + subtensor.get_vali_claim_types_for_hk( hotkey_ss58=wallet.hotkey.ss58_address, block_hash=block_hash ), subtensor.get_all_subnet_netuids(block_hash=block_hash),