From da8215c7224ace888d399f689917fae97dd049a7 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 8 Sep 2025 15:48:35 +0200 Subject: [PATCH 1/8] Adds cmd for setting subnet symbol. --- bittensor_cli/cli.py | 32 ++++++++++ bittensor_cli/src/commands/subnets/subnets.py | 63 +++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index d3d490d25..47205d661 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -960,6 +960,9 @@ def __init__(self): self.subnets_app.command( "check-start", rich_help_panel=HELP_PANELS["SUBNETS"]["INFO"] )(self.subnets_check_start) + self.subnets_app.command( + "set-symbol", rich_help_panel=HELP_PANELS["SUBNETS"]["IDENTITY"] + )(self.subnets_set_symbol) # weights commands self.weights_app.command( @@ -5793,6 +5796,35 @@ def subnets_metagraph( ) ) + def subnets_set_symbol( + self, + wallet_name: str = Options.wallet_name, + wallet_path: str = Options.wallet_path, + wallet_hotkey: str = Options.wallet_hotkey, + network: Optional[list[str]] = Options.network, + netuid: int = Options.netuid, + json_output: bool = Options.json_output, + prompt: bool = Options.prompt, + quiet: bool = Options.quiet, + verbose: bool = Options.verbose, + symbol: str = typer.Argument(help="The symbol to set for your subnet."), + ): + """ + Allows the user to update their subnet symbol. + + EXAMPLE + + [green]$[/green] btcli subnets set-symbol --netuid 1 ‡ + """ + self.verbosity_handler(quiet, verbose, json_output) + wallet = self.wallet_ask( + wallet_name, + wallet_path, + wallet_hotkey, + ask_for=[WO.NAME, WO.HOTKEY], + validate=WV.WALLET_AND_HOTKEY, + ) + def weights_reveal( self, network: Optional[list[str]] = Options.network, diff --git a/bittensor_cli/src/commands/subnets/subnets.py b/bittensor_cli/src/commands/subnets/subnets.py index bb42132c9..8daec6d22 100644 --- a/bittensor_cli/src/commands/subnets/subnets.py +++ b/bittensor_cli/src/commands/subnets/subnets.py @@ -2448,3 +2448,66 @@ async def start_subnet( await get_start_schedule(subtensor, netuid) print_error(f":cross_mark: Failed to start subnet: {error_msg}") return False + + +async def set_symbol( + wallet: "Wallet", + subtensor: "SubtensorInterface", + netuid: int, + symbol: str, + prompt: bool = False, + json_output: bool = False, +) -> bool: + """Set a subtensor's symbol""" + if not await subtensor.subnet_exists(netuid): + err = f"Subnet {netuid} does not exist." + if json_output: + json_console.print_json(data={"success": False, "message": err}) + else: + err_console.print(err) + return False + + if prompt and not json_output: + sn_info = await subtensor.subnet(netuid=netuid) + if not Confirm.ask( + f"Your current subnet symbol for SN{netuid} is {sn_info.symbol}. Do you want to update it to {symbol}?" + ): + return False + + if not (unlock_status := unlock_key(wallet, print_out=False)).success: + err = unlock_status.message + if json_output: + json_console.print_json(data={"success": False, "message": err}) + else: + console.print(err) + return False + + start_call = await subtensor.substrate.compose_call( + call_module="SubtensorModule", + call_function="update_symbol", + call_params={"netuid": netuid, "symbol": symbol}, + ) + + signed_ext = await subtensor.substrate.create_signed_extrinsic( + call=start_call, + keypair=wallet.coldkey, + ) + + response = await subtensor.substrate.submit_extrinsic( + extrinsic=signed_ext, + wait_for_inclusion=True, + ) + if await response.is_success: + message = f"Successfully updated SN{netuid}'s symbol to {symbol}." + if json_output: + json_console.print_json(data={"success": True, "message": message}) + else: + console.print(f":white_heavy_check_mark:[dark_sea_green3] {message}\n") + return True + else: + err = format_error_message(await response.error_message) + if json_output: + json_console.print_json(data={"success": False, "message": err}) + else: + err_console.print(f":cross_mark: [red]Failed[/red]: {err}") + return False From 1694d4c71d4e504ff2be38343261c48e3b220892 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 8 Sep 2025 15:52:35 +0200 Subject: [PATCH 2/8] Add test --- tests/e2e_tests/test_staking_sudo.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/e2e_tests/test_staking_sudo.py b/tests/e2e_tests/test_staking_sudo.py index cd4bf09c3..571f86ce2 100644 --- a/tests/e2e_tests/test_staking_sudo.py +++ b/tests/e2e_tests/test_staking_sudo.py @@ -10,6 +10,7 @@ * btcli subnets create * btcli subnets set-identity * btcli subnets get-identity +* btcli subnets set-symbol * btcli subnets register * btcli subnets price * btcli stake add @@ -235,6 +236,33 @@ def test_staking(local_chain, wallet_setup): assert get_identity_output["logo_url"] == sn_logo_url assert get_identity_output["additional"] == sn_add_info + # set symbol + set_symbol = exec_command_alice( + "subnets", + "set-symbol", + extra_args=[ + "--wallet-path", + wallet_path_alice, + "--wallet-name", + wallet_alice.name, + "--hotkey", + wallet_alice.hotkey_str, + "--chain", + "ws://127.0.0.1:9945", + "--netuid", + netuid, + "--json-output", + "--no-prompt", + "‡", + ], + ) + set_symbol_output = json.loads(set_symbol.stdout) + assert set_symbol_output["success"] is True + assert ( + set_symbol_output["message"] + == f"Successfully updated SN{netuid}'s symbol to ‡." + ) + get_s_price = exec_command_alice( "subnets", "price", From 438a6a578efd4af18f5baf1ab2b4e8b061c8a315 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 8 Sep 2025 15:58:27 +0200 Subject: [PATCH 3/8] Forgot to include the actual run logic. --- bittensor_cli/cli.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 47205d661..b559c1f1c 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -5817,6 +5817,9 @@ def subnets_set_symbol( [green]$[/green] btcli subnets set-symbol --netuid 1 ‡ """ self.verbosity_handler(quiet, verbose, json_output) + if len(symbol) > 1: + err_console.print("Your symbol must be a single character.") + return False wallet = self.wallet_ask( wallet_name, wallet_path, @@ -5824,6 +5827,16 @@ def subnets_set_symbol( ask_for=[WO.NAME, WO.HOTKEY], validate=WV.WALLET_AND_HOTKEY, ) + return self._run_command( + subnets.set_symbol( + wallet=wallet, + subtensor=self.initialize_chain(network), + netuid=netuid, + symbol=symbol, + prompt=prompt, + json_output=json_output, + ) + ) def weights_reveal( self, From 1ee8160625dd3ed4df8a1c6b3f03afdd4c97a217 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 8 Sep 2025 16:03:41 +0200 Subject: [PATCH 4/8] debug --- tests/e2e_tests/test_staking_sudo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_staking_sudo.py b/tests/e2e_tests/test_staking_sudo.py index 571f86ce2..bc3e9b6ee 100644 --- a/tests/e2e_tests/test_staking_sudo.py +++ b/tests/e2e_tests/test_staking_sudo.py @@ -257,7 +257,7 @@ def test_staking(local_chain, wallet_setup): ], ) set_symbol_output = json.loads(set_symbol.stdout) - assert set_symbol_output["success"] is True + assert set_symbol_output["success"] is True, set_identity_output assert ( set_symbol_output["message"] == f"Successfully updated SN{netuid}'s symbol to ‡." From e13f1a00415d38cc463c5cf7812d6fae4680d39a Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 8 Sep 2025 16:09:23 +0200 Subject: [PATCH 5/8] Debug --- bittensor_cli/src/commands/subnets/subnets.py | 2 +- tests/e2e_tests/test_staking_sudo.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bittensor_cli/src/commands/subnets/subnets.py b/bittensor_cli/src/commands/subnets/subnets.py index 8daec6d22..14562a4ec 100644 --- a/bittensor_cli/src/commands/subnets/subnets.py +++ b/bittensor_cli/src/commands/subnets/subnets.py @@ -2485,7 +2485,7 @@ async def set_symbol( start_call = await subtensor.substrate.compose_call( call_module="SubtensorModule", call_function="update_symbol", - call_params={"netuid": netuid, "symbol": symbol}, + call_params={"netuid": netuid, "symbol": symbol.encode("utf-8")}, ) signed_ext = await subtensor.substrate.create_signed_extrinsic( diff --git a/tests/e2e_tests/test_staking_sudo.py b/tests/e2e_tests/test_staking_sudo.py index bc3e9b6ee..fbc981b2c 100644 --- a/tests/e2e_tests/test_staking_sudo.py +++ b/tests/e2e_tests/test_staking_sudo.py @@ -257,7 +257,8 @@ def test_staking(local_chain, wallet_setup): ], ) set_symbol_output = json.loads(set_symbol.stdout) - assert set_symbol_output["success"] is True, set_identity_output + assert set_symbol_output["success"] is True + assert set_symbol_output["success"] is True, set_symbol_output assert ( set_symbol_output["message"] == f"Successfully updated SN{netuid}'s symbol to ‡." From 7e215b9a88fb76965e23a8a712e2aa225c924ab0 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 8 Sep 2025 16:12:28 +0200 Subject: [PATCH 6/8] Debug --- tests/e2e_tests/test_staking_sudo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_staking_sudo.py b/tests/e2e_tests/test_staking_sudo.py index fbc981b2c..79e7c96ac 100644 --- a/tests/e2e_tests/test_staking_sudo.py +++ b/tests/e2e_tests/test_staking_sudo.py @@ -257,7 +257,7 @@ def test_staking(local_chain, wallet_setup): ], ) set_symbol_output = json.loads(set_symbol.stdout) - assert set_symbol_output["success"] is True + assert set_symbol_output["success"] is True, set_symbol_output assert set_symbol_output["success"] is True, set_symbol_output assert ( set_symbol_output["message"] From e64fd597bf21b2f7dcbfda50e9d92de4ce782cdf Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 8 Sep 2025 16:18:05 +0200 Subject: [PATCH 7/8] Symbol didn't exist. --- bittensor_cli/cli.py | 2 +- tests/e2e_tests/test_staking_sudo.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index b559c1f1c..242be57fb 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -5814,7 +5814,7 @@ def subnets_set_symbol( EXAMPLE - [green]$[/green] btcli subnets set-symbol --netuid 1 ‡ + [green]$[/green] btcli subnets set-symbol --netuid 1 シ """ self.verbosity_handler(quiet, verbose, json_output) if len(symbol) > 1: diff --git a/tests/e2e_tests/test_staking_sudo.py b/tests/e2e_tests/test_staking_sudo.py index 79e7c96ac..359fbb508 100644 --- a/tests/e2e_tests/test_staking_sudo.py +++ b/tests/e2e_tests/test_staking_sudo.py @@ -253,7 +253,7 @@ def test_staking(local_chain, wallet_setup): netuid, "--json-output", "--no-prompt", - "‡", + "シ", ], ) set_symbol_output = json.loads(set_symbol.stdout) @@ -261,7 +261,7 @@ def test_staking(local_chain, wallet_setup): assert set_symbol_output["success"] is True, set_symbol_output assert ( set_symbol_output["message"] - == f"Successfully updated SN{netuid}'s symbol to ‡." + == f"Successfully updated SN{netuid}'s symbol to シ." ) get_s_price = exec_command_alice( From 0c5b70af3d8ae9a1e37e684913a0868c8b66c974 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 8 Sep 2025 18:41:56 +0200 Subject: [PATCH 8/8] Update docstrings --- bittensor_cli/cli.py | 11 +++++++++-- bittensor_cli/src/commands/subnets/subnets.py | 7 ++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 242be57fb..39b401589 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -5810,11 +5810,18 @@ def subnets_set_symbol( symbol: str = typer.Argument(help="The symbol to set for your subnet."), ): """ - Allows the user to update their subnet symbol. + Allows the user to update their subnet symbol to a different available symbol. The full list of available symbols can be found here: + [#8CB9E9]https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/symbols.rs#L8[/#8CB9E9] + EXAMPLE - [green]$[/green] btcli subnets set-symbol --netuid 1 シ + [green]$[/green] btcli subnets set-symbol [dark_orange]--netuid 1 シ[/dark_orange] + + + JSON OUTPUT: + If --json-output is used, the output will be in the following schema: + [#AFEFFF]{success: [dark_orange]bool[/dark_orange], message: [dark_orange]str[/dark_orange]}[/#AFEFFF] """ self.verbosity_handler(quiet, verbose, json_output) if len(symbol) > 1: diff --git a/bittensor_cli/src/commands/subnets/subnets.py b/bittensor_cli/src/commands/subnets/subnets.py index 14562a4ec..d8571f3f6 100644 --- a/bittensor_cli/src/commands/subnets/subnets.py +++ b/bittensor_cli/src/commands/subnets/subnets.py @@ -2458,7 +2458,12 @@ async def set_symbol( prompt: bool = False, json_output: bool = False, ) -> bool: - """Set a subtensor's symbol""" + """ + Set a subtensor's symbol, given the netuid and symbol. + + The symbol must be a symbol that subtensor recognizes as available + (defined in https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/symbols.rs#L8) + """ if not await subtensor.subnet_exists(netuid): err = f"Subnet {netuid} does not exist." if json_output: