From 18ebd57f976442b1abbb73aef3f90b3466e6f23d Mon Sep 17 00:00:00 2001 From: bdhimes Date: Wed, 29 Oct 2025 16:11:44 +0200 Subject: [PATCH 01/13] Allows for installing on Py 3.14 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c9a3e32b3..6c6f552f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ authors = [ ] license = { file = "LICENSE" } scripts = { btcli = "bittensor_cli.cli:main" } -requires-python = ">=3.9,<3.14" +requires-python = ">=3.9,<3.15" dependencies = [ "wheel", "async-substrate-interface>=1.5.2", From a9efc9d9276ef6732294b736292eb1cee27ac391 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Wed, 29 Oct 2025 23:14:23 +0200 Subject: [PATCH 02/13] Update workflow --- .github/workflows/e2e-subtensor-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yml b/.github/workflows/e2e-subtensor-tests.yml index 6b0db3f26..f57b9a1f7 100644 --- a/.github/workflows/e2e-subtensor-tests.yml +++ b/.github/workflows/e2e-subtensor-tests.yml @@ -73,7 +73,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - name: Check-out repository uses: actions/checkout@v4 From 2617c014a3e8a1eceb7d19e6d600a03e13fe143d Mon Sep 17 00:00:00 2001 From: bdhimes Date: Thu, 30 Oct 2025 17:36:17 +0200 Subject: [PATCH 03/13] Clean up tests for easier debugging --- .../src/commands/liquidity/liquidity.py | 16 ++- tests/e2e_tests/test_liquidity.py | 117 ++++++++++++++---- 2 files changed, 107 insertions(+), 26 deletions(-) diff --git a/bittensor_cli/src/commands/liquidity/liquidity.py b/bittensor_cli/src/commands/liquidity/liquidity.py index 47f0141f3..395945c68 100644 --- a/bittensor_cli/src/commands/liquidity/liquidity.py +++ b/bittensor_cli/src/commands/liquidity/liquidity.py @@ -459,9 +459,21 @@ async def show_liquidity_list( netuid: int, json_output: bool = False, ) -> None: - current_price_, (success, err_msg, positions) = await asyncio.gather( - subtensor.subnet(netuid=netuid), get_liquidity_list(subtensor, wallet, netuid) + current_price_, liquidity_list_ = await asyncio.gather( + subtensor.subnet(netuid=netuid), + get_liquidity_list(subtensor, wallet, netuid), + return_exceptions=True, ) + if isinstance(current_price_, Exception): + success = False + err_msg = str(current_price_) + positions = [] + elif isinstance(liquidity_list_, Exception): + success = False + err_msg = str(liquidity_list_) + positions = [] + else: + (success, err_msg, positions) = liquidity_list_ if not success: if json_output: json_console.print( diff --git a/tests/e2e_tests/test_liquidity.py b/tests/e2e_tests/test_liquidity.py index faaf6e05e..012ee471c 100644 --- a/tests/e2e_tests/test_liquidity.py +++ b/tests/e2e_tests/test_liquidity.py @@ -1,6 +1,7 @@ import asyncio import json import re +import time from bittensor_cli.src.bittensor.balances import Balance from .utils import turn_off_hyperparam_freeze_window @@ -16,25 +17,6 @@ def test_liquidity(local_chain, wallet_setup): - def liquidity_list(): - return exec_command_alice( - command="liquidity", - sub_command="list", - 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, - "--netuid", - netuid, - "--json-output", - ], - ) - wallet_path_alice = "//Alice" netuid = 2 @@ -48,6 +30,7 @@ def liquidity_list(): print( "Skipping turning off hyperparams freeze window. This indicates the call does not exist on the chain you are testing." ) + time.sleep(10) # Register a subnet with sudo as Alice result = exec_command_alice( @@ -88,7 +71,23 @@ def liquidity_list(): assert isinstance(result_output["extrinsic_identifier"], str) # verify no results for list thus far (subnet not yet started) - liquidity_list_result = liquidity_list() + liquidity_list_result = exec_command_alice( + command="liquidity", + sub_command="list", + 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, + "--netuid", + netuid, + "--json-output", + ], + ) result_output = json.loads(liquidity_list_result.stdout) assert result_output["success"] is False assert f"Subnet with netuid: {netuid} is not active" in result_output["err_msg"] @@ -118,7 +117,24 @@ def liquidity_list(): ), start_subnet_emissions.stderr assert "Your extrinsic has been included " in start_subnet_emissions.stdout - liquidity_list_result = liquidity_list() + liquidity_list_result = exec_command_alice( + command="liquidity", + sub_command="list", + 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, + "--netuid", + netuid, + "--json-output", + ], + ) + print(">>>", liquidity_list_result.stdout, liquidity_list_result.stderr) result_output = json.loads(liquidity_list_result.stdout) assert result_output["success"] is True assert result_output["err_msg"] == "" @@ -179,7 +195,24 @@ def liquidity_list(): assert add_liquidity_result["message"] == "" assert isinstance(add_liquidity_result["extrinsic_identifier"], str) - liquidity_list_result = liquidity_list() + liquidity_list_result = exec_command_alice( + command="liquidity", + sub_command="list", + 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, + "--netuid", + netuid, + "--json-output", + ], + ) + print(">>>", liquidity_list_result.stdout, liquidity_list_result.stderr) liquidity_list_result = json.loads(liquidity_list_result.stdout) assert liquidity_list_result["success"] is True assert len(liquidity_list_result["positions"]) == 1 @@ -218,7 +251,25 @@ def liquidity_list(): assert modify_liquidity_result["success"] is True assert isinstance(modify_liquidity_result["extrinsic_identifier"], str) - liquidity_list_result = json.loads(liquidity_list().stdout) + llr = exec_command_alice( + command="liquidity", + sub_command="list", + 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, + "--netuid", + netuid, + "--json-output", + ], + ) + print(">>>", llr.stdout, llr.stderr) + liquidity_list_result = json.loads(llr.stdout) assert len(liquidity_list_result["positions"]) == 1 liquidity_position = liquidity_list_result["positions"][0] assert liquidity_position["id"] == 2 @@ -249,6 +300,24 @@ def liquidity_list(): removal_result[str(liquidity_position["id"])]["extrinsic_identifier"], str ) - liquidity_list_result = json.loads(liquidity_list().stdout) + liquidity_list_result = exec_command_alice( + command="liquidity", + sub_command="list", + 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, + "--netuid", + netuid, + "--json-output", + ], + ) + print(">>>", liquidity_list_result.stdout, liquidity_list_result.stderr) + liquidity_list_result = json.loads(liquidity_list_result.stdout) assert liquidity_list_result["success"] is True assert liquidity_list_result["positions"] == [] From 5ff7519fdc01cae434094ffd796234b281e7ab8d Mon Sep 17 00:00:00 2001 From: bdhimes Date: Thu, 30 Oct 2025 18:12:16 +0200 Subject: [PATCH 04/13] test fix --- bittensor_cli/src/commands/liquidity/liquidity.py | 2 ++ tests/e2e_tests/test_liquidity.py | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bittensor_cli/src/commands/liquidity/liquidity.py b/bittensor_cli/src/commands/liquidity/liquidity.py index 395945c68..a262e8874 100644 --- a/bittensor_cli/src/commands/liquidity/liquidity.py +++ b/bittensor_cli/src/commands/liquidity/liquidity.py @@ -342,6 +342,8 @@ async def get_liquidity_list( block_hash=block_hash, ), ) + if len(positions_response.records) == 0: + return False, "No liquidity positions found.", [] current_sqrt_price = fixed_to_float(current_sqrt_price) fee_global_tao = fixed_to_float(fee_global_tao) diff --git a/tests/e2e_tests/test_liquidity.py b/tests/e2e_tests/test_liquidity.py index 012ee471c..cb8b6ebf1 100644 --- a/tests/e2e_tests/test_liquidity.py +++ b/tests/e2e_tests/test_liquidity.py @@ -136,8 +136,8 @@ def test_liquidity(local_chain, wallet_setup): ) print(">>>", liquidity_list_result.stdout, liquidity_list_result.stderr) result_output = json.loads(liquidity_list_result.stdout) - assert result_output["success"] is True - assert result_output["err_msg"] == "" + assert result_output["success"] is False + assert result_output["err_msg"] == "No liquidity positions found." assert result_output["positions"] == [] enable_user_liquidity = exec_command_alice( @@ -218,7 +218,6 @@ def test_liquidity(local_chain, wallet_setup): assert len(liquidity_list_result["positions"]) == 1 liquidity_position = liquidity_list_result["positions"][0] assert liquidity_position["liquidity"] == 1.0 - assert liquidity_position["id"] == 2 assert liquidity_position["fees_tao"] == 0.0 assert liquidity_position["fees_alpha"] == 0.0 assert liquidity_position["netuid"] == netuid @@ -272,7 +271,6 @@ def test_liquidity(local_chain, wallet_setup): liquidity_list_result = json.loads(llr.stdout) assert len(liquidity_list_result["positions"]) == 1 liquidity_position = liquidity_list_result["positions"][0] - assert liquidity_position["id"] == 2 assert liquidity_position["liquidity"] == 21.0 removal = exec_command_alice( From 754b9e5b68a1264918859a9391731a177002e46c Mon Sep 17 00:00:00 2001 From: bdhimes Date: Thu, 30 Oct 2025 18:15:42 +0200 Subject: [PATCH 05/13] test fix --- bittensor_cli/src/commands/stake/add.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bittensor_cli/src/commands/stake/add.py b/bittensor_cli/src/commands/stake/add.py index 5b980af08..5046981da 100644 --- a/bittensor_cli/src/commands/stake/add.py +++ b/bittensor_cli/src/commands/stake/add.py @@ -481,9 +481,10 @@ async def stake_extrinsic( success, er_msg, ext_receipt = await coroutine successes[ni][staking_address] = success error_messages[ni][staking_address] = er_msg - extrinsic_ids[ni][ - staking_address - ] = await ext_receipt.get_extrinsic_identifier() + if success: + extrinsic_ids[ni][ + staking_address + ] = await ext_receipt.get_extrinsic_identifier() if json_output: json_console.print_json( data={ From a83016477049884a0dbd36ef9ece9b5c7fc27278 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Thu, 30 Oct 2025 19:48:50 +0200 Subject: [PATCH 06/13] test fix --- tests/e2e_tests/test_liquidity.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_liquidity.py b/tests/e2e_tests/test_liquidity.py index cb8b6ebf1..efa45ffbc 100644 --- a/tests/e2e_tests/test_liquidity.py +++ b/tests/e2e_tests/test_liquidity.py @@ -317,5 +317,6 @@ def test_liquidity(local_chain, wallet_setup): ) print(">>>", liquidity_list_result.stdout, liquidity_list_result.stderr) liquidity_list_result = json.loads(liquidity_list_result.stdout) - assert liquidity_list_result["success"] is True + assert liquidity_list_result["success"] is False + assert result_output["err_msg"] == "No liquidity positions found." assert liquidity_list_result["positions"] == [] From 8d88a9524d701749d896d3edac8d16a4f3cd3994 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 30 Oct 2025 11:37:16 -0700 Subject: [PATCH 07/13] update staking_sudo --- tests/e2e_tests/test_staking_sudo.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/e2e_tests/test_staking_sudo.py b/tests/e2e_tests/test_staking_sudo.py index 4096c87b0..83a77d38c 100644 --- a/tests/e2e_tests/test_staking_sudo.py +++ b/tests/e2e_tests/test_staking_sudo.py @@ -325,6 +325,32 @@ def test_staking(local_chain, wallet_setup): start_subnet_emissions.stdout ) + # Add initial stake to enable V3 + for netuid_ in multiple_netuids: + stake_to_enable_v3 = exec_command_alice( + command="stake", + sub_command="add", + extra_args=[ + "--netuid", + netuid_, + "--wallet-path", + wallet_path_alice, + "--wallet-name", + wallet_alice.name, + "--hotkey", + wallet_alice.hotkey_str, + "--chain", + "ws://127.0.0.1:9945", + "--amount", + "1", + "--unsafe", + "--no-prompt", + "--era", + "144", + ], + ) + assert "✅ Finalized" in stake_to_enable_v3.stdout, stake_to_enable_v3.stderr + # Add stake to Alice's hotkey add_stake_single = exec_command_alice( command="stake", From 27e8df5c31f26d4a1cf946f5ec5879bdfeedad77 Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 30 Oct 2025 11:37:27 -0700 Subject: [PATCH 08/13] update unstaking e2e --- tests/e2e_tests/test_unstaking.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/e2e_tests/test_unstaking.py b/tests/e2e_tests/test_unstaking.py index d4e3eef76..d0e9efd87 100644 --- a/tests/e2e_tests/test_unstaking.py +++ b/tests/e2e_tests/test_unstaking.py @@ -215,6 +215,32 @@ def test_unstaking(local_chain, wallet_setup): register_result.stdout ) + # Add initial stake to enable V3 + for netuid_ in [0, 2, 3]: + stake_to_enable_v3 = exec_command_bob( + command="stake", + sub_command="add", + extra_args=[ + "--netuid", + netuid_, + "--wallet-path", + wallet_path_bob, + "--wallet-name", + wallet_bob.name, + "--hotkey", + wallet_bob.hotkey_str, + "--chain", + "ws://127.0.0.1:9945", + "--amount", + "1", + "--unsafe", + "--no-prompt", + "--era", + "144", + ], + ) + assert "✅ Finalized" in stake_to_enable_v3.stdout, stake_to_enable_v3.stderr + # Add stake to subnets for netuid in [0, 2, 3]: stake_result = exec_command_bob( From c261c5016641ea555325d326f9293b96218d810d Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 30 Oct 2025 11:37:37 -0700 Subject: [PATCH 09/13] update liquidity e2e --- tests/e2e_tests/test_liquidity.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/e2e_tests/test_liquidity.py b/tests/e2e_tests/test_liquidity.py index efa45ffbc..7a210f0a1 100644 --- a/tests/e2e_tests/test_liquidity.py +++ b/tests/e2e_tests/test_liquidity.py @@ -117,6 +117,30 @@ def test_liquidity(local_chain, wallet_setup): ), start_subnet_emissions.stderr assert "Your extrinsic has been included " in start_subnet_emissions.stdout + stake_to_enable_v3 = exec_command_alice( + command="stake", + sub_command="add", + extra_args=[ + "--netuid", + "2", + "--wallet-path", + wallet_path_alice, + "--wallet-name", + wallet_alice.name, + "--hotkey", + wallet_alice.hotkey_str, + "--chain", + "ws://127.0.0.1:9945", + "--amount", + "1", + "--unsafe", + "--no-prompt", + "--era", + "144", + ], + ) + assert "✅ Finalized" in stake_to_enable_v3.stdout, stake_to_enable_v3.stderr + time.sleep(10) liquidity_list_result = exec_command_alice( command="liquidity", sub_command="list", From 73a1d97bba2bdfe33f55068c916de0151b4af47d Mon Sep 17 00:00:00 2001 From: ibraheem-latent Date: Thu, 30 Oct 2025 11:38:41 -0700 Subject: [PATCH 10/13] ruff --- tests/e2e_tests/test_staking_sudo.py | 40 ++++++++++++++-------------- tests/e2e_tests/test_unstaking.py | 40 ++++++++++++++-------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/e2e_tests/test_staking_sudo.py b/tests/e2e_tests/test_staking_sudo.py index 83a77d38c..6bcaa60cc 100644 --- a/tests/e2e_tests/test_staking_sudo.py +++ b/tests/e2e_tests/test_staking_sudo.py @@ -328,26 +328,26 @@ def test_staking(local_chain, wallet_setup): # Add initial stake to enable V3 for netuid_ in multiple_netuids: stake_to_enable_v3 = exec_command_alice( - command="stake", - sub_command="add", - extra_args=[ - "--netuid", - netuid_, - "--wallet-path", - wallet_path_alice, - "--wallet-name", - wallet_alice.name, - "--hotkey", - wallet_alice.hotkey_str, - "--chain", - "ws://127.0.0.1:9945", - "--amount", - "1", - "--unsafe", - "--no-prompt", - "--era", - "144", - ], + command="stake", + sub_command="add", + extra_args=[ + "--netuid", + netuid_, + "--wallet-path", + wallet_path_alice, + "--wallet-name", + wallet_alice.name, + "--hotkey", + wallet_alice.hotkey_str, + "--chain", + "ws://127.0.0.1:9945", + "--amount", + "1", + "--unsafe", + "--no-prompt", + "--era", + "144", + ], ) assert "✅ Finalized" in stake_to_enable_v3.stdout, stake_to_enable_v3.stderr diff --git a/tests/e2e_tests/test_unstaking.py b/tests/e2e_tests/test_unstaking.py index d0e9efd87..f3173b5a7 100644 --- a/tests/e2e_tests/test_unstaking.py +++ b/tests/e2e_tests/test_unstaking.py @@ -218,26 +218,26 @@ def test_unstaking(local_chain, wallet_setup): # Add initial stake to enable V3 for netuid_ in [0, 2, 3]: stake_to_enable_v3 = exec_command_bob( - command="stake", - sub_command="add", - extra_args=[ - "--netuid", - netuid_, - "--wallet-path", - wallet_path_bob, - "--wallet-name", - wallet_bob.name, - "--hotkey", - wallet_bob.hotkey_str, - "--chain", - "ws://127.0.0.1:9945", - "--amount", - "1", - "--unsafe", - "--no-prompt", - "--era", - "144", - ], + command="stake", + sub_command="add", + extra_args=[ + "--netuid", + netuid_, + "--wallet-path", + wallet_path_bob, + "--wallet-name", + wallet_bob.name, + "--hotkey", + wallet_bob.hotkey_str, + "--chain", + "ws://127.0.0.1:9945", + "--amount", + "1", + "--unsafe", + "--no-prompt", + "--era", + "144", + ], ) assert "✅ Finalized" in stake_to_enable_v3.stdout, stake_to_enable_v3.stderr From 121d459a870d2a76dbce4754412361d565e225c5 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Thu, 30 Oct 2025 20:46:05 +0200 Subject: [PATCH 11/13] Fixes duplicate param name --- bittensor_cli/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bittensor_cli/cli.py b/bittensor_cli/cli.py index 3b6096047..7fae9e844 100755 --- a/bittensor_cli/cli.py +++ b/bittensor_cli/cli.py @@ -3326,7 +3326,7 @@ def wallet_set_id( network: Optional[list[str]] = Options.network, name: str = typer.Option( "", - "--name", + "--id-name", help="The display name for the identity.", ), web_url: str = typer.Option( @@ -6427,7 +6427,7 @@ def subnets_set_identity( network: Optional[list[str]] = Options.network, netuid: int = Options.netuid, subnet_name: Optional[str] = typer.Option( - None, "--subnet-name", "--name", help="Name of the subnet" + None, "--subnet-name", "--sn-name", help="Name of the subnet" ), github_repo: Optional[str] = typer.Option( None, "--github-repo", "--repo", help="GitHub repository URL" From 41ecd6f729d51578c947537a2cfbed593b130b0a Mon Sep 17 00:00:00 2001 From: bdhimes Date: Thu, 30 Oct 2025 20:52:28 +0200 Subject: [PATCH 12/13] test fix --- tests/e2e_tests/test_wallet_interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_wallet_interactions.py b/tests/e2e_tests/test_wallet_interactions.py index 9dd3ea4f1..3b92c4965 100644 --- a/tests/e2e_tests/test_wallet_interactions.py +++ b/tests/e2e_tests/test_wallet_interactions.py @@ -421,7 +421,7 @@ def test_wallet_identities(local_chain, wallet_setup): wallet_alice.name, "--wallet-hotkey", wallet_alice.hotkey_str, - "--name", + "--id-name", alice_identity["name"], "--web-url", alice_identity["url"], From 395f0119204261ef821a4c258fe54c8e02c657ed Mon Sep 17 00:00:00 2001 From: bdhimes Date: Thu, 30 Oct 2025 21:03:13 +0200 Subject: [PATCH 13/13] Changelog + version --- CHANGELOG.md | 6 ++++++ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 885527728..ecb08197f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ # Changelog +## 9.14.3 /2025-10-30 +* Allows for installing on Py 3.14 by @thewhaleking in https://github.com/opentensor/btcli/pull/688 + * corrects `--name` param in `wallet set-identity` and `subnets set-identity` which was a duplicate param alias of `--wallet-name` + +**Full Changelog**: https://github.com/opentensor/btcli/compare/v9.14.2...v9.14.3 + ## 9.14.2 /2025-10-28 * `stake remove --all` fails when unsuccessful by @thewhaleking in https://github.com/opentensor/btcli/pull/679 * check subnet logo url by @thewhaleking in https://github.com/opentensor/btcli/pull/681 diff --git a/pyproject.toml b/pyproject.toml index 6c6f552f6..5945a9a38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "bittensor-cli" -version = "9.14.2" +version = "9.14.3" description = "Bittensor CLI" readme = "README.md" authors = [