bittensor-cli 8.3.1__py3-none-any.whl → 8.4.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
bittensor_cli/__init__.py CHANGED
@@ -18,6 +18,6 @@
18
18
  from .cli import CLIManager
19
19
 
20
20
 
21
- __version__ = "8.3.1"
21
+ __version__ = "8.4.1"
22
22
 
23
23
  __all__ = ["CLIManager", "__version__"]
bittensor_cli/cli.py CHANGED
@@ -58,7 +58,7 @@ except ImportError:
58
58
  pass
59
59
 
60
60
 
61
- __version__ = "8.3.1"
61
+ __version__ = "8.4.1"
62
62
 
63
63
 
64
64
  _core_version = re.match(r"^\d+\.\d+\.\d+", __version__).group(0)
@@ -127,8 +127,6 @@ class Options:
127
127
  use_password = typer.Option(
128
128
  True,
129
129
  help="Set this to `True` to protect the generated Bittensor key with a password.",
130
- is_flag=True,
131
- flag_value=False,
132
130
  )
133
131
  public_hex_key = typer.Option(None, help="The public key in hex format.")
134
132
  ss58_address = typer.Option(
@@ -1843,8 +1841,6 @@ class CLIManager:
1843
1841
  use_password: bool = typer.Option(
1844
1842
  False, # Overriden to False
1845
1843
  help="Set to 'True' to protect the generated Bittensor key with a password.",
1846
- is_flag=True,
1847
- flag_value=True,
1848
1844
  ),
1849
1845
  quiet: bool = Options.quiet,
1850
1846
  verbose: bool = Options.verbose,
@@ -1901,8 +1897,6 @@ class CLIManager:
1901
1897
  use_password: bool = typer.Option(
1902
1898
  False, # Overriden to False
1903
1899
  help="Set to 'True' to protect the generated Bittensor key with a password.",
1904
- is_flag=True,
1905
- flag_value=True,
1906
1900
  ),
1907
1901
  quiet: bool = Options.quiet,
1908
1902
  verbose: bool = Options.verbose,
@@ -3665,7 +3659,7 @@ class CLIManager:
3665
3659
  prompt: bool = Options.prompt,
3666
3660
  ):
3667
3661
  """
3668
- Set child hotkeys on specified subnets.
3662
+ Set child hotkeys on a specified subnet (or all). Overrides currently set children.
3669
3663
 
3670
3664
  Users can specify the 'proportion' to delegate to child hotkeys (ss58 address). The sum of proportions cannot be greater than 1.
3671
3665
 
@@ -3750,7 +3744,7 @@ class CLIManager:
3750
3744
  prompt: bool = Options.prompt,
3751
3745
  ):
3752
3746
  """
3753
- Remove all children hotkeys on a specified subnet.
3747
+ Remove all children hotkeys on a specified subnet (or all).
3754
3748
 
3755
3749
  This command is used to remove delegated authority from all child hotkeys, removing their position and influence on the subnet.
3756
3750
 
@@ -3890,12 +3884,12 @@ class CLIManager:
3890
3884
  """
3891
3885
  self.verbosity_handler(quiet, verbose)
3892
3886
 
3893
- hyperparams = self._run_command(
3894
- sudo.get_hyperparameters(self.initialize_chain(network), netuid)
3895
- )
3896
-
3897
- if not hyperparams:
3898
- raise typer.Exit()
3887
+ if not param_name or not param_value:
3888
+ hyperparams = self._run_command(
3889
+ sudo.get_hyperparameters(self.initialize_chain(network), netuid)
3890
+ )
3891
+ if not hyperparams:
3892
+ raise typer.Exit()
3899
3893
 
3900
3894
  if not param_name:
3901
3895
  hyperparam_list = [field.name for field in fields(SubnetHyperparameters)]
@@ -3910,6 +3904,16 @@ class CLIManager:
3910
3904
  )
3911
3905
  param_name = hyperparam_list[choice - 1]
3912
3906
 
3907
+ if param_name in ["alpha_high", "alpha_low"]:
3908
+ param_name = "alpha_values"
3909
+ low_val = FloatPrompt.ask(
3910
+ "Enter the new value for [dark_orange]alpha_low[/dark_orange]"
3911
+ )
3912
+ high_val = FloatPrompt.ask(
3913
+ "Enter the new value for [dark_orange]alpha_high[/dark_orange]"
3914
+ )
3915
+ param_value = f"{low_val},{high_val}"
3916
+
3913
3917
  if not param_value:
3914
3918
  param_value = Prompt.ask(
3915
3919
  f"Enter the new value for [dark_orange]{param_name}[/dark_orange] in the VALUE column format"
@@ -318,28 +318,36 @@ NETWORK_EXPLORER_MAP = {
318
318
 
319
319
 
320
320
  HYPERPARAMS = {
321
- "serving_rate_limit": "sudo_set_serving_rate_limit",
322
- "min_difficulty": "sudo_set_min_difficulty",
323
- "max_difficulty": "sudo_set_max_difficulty",
324
- "weights_version": "sudo_set_weights_version_key",
325
- "weights_rate_limit": "sudo_set_weights_set_rate_limit",
326
- "max_weight_limit": "sudo_set_max_weight_limit",
327
- "immunity_period": "sudo_set_immunity_period",
328
- "min_allowed_weights": "sudo_set_min_allowed_weights",
329
- "activity_cutoff": "sudo_set_activity_cutoff",
330
- "network_registration_allowed": "sudo_set_network_registration_allowed",
331
- "network_pow_registration_allowed": "sudo_set_network_pow_registration_allowed",
332
- "min_burn": "sudo_set_min_burn",
333
- "max_burn": "sudo_set_max_burn",
334
- "adjustment_alpha": "sudo_set_adjustment_alpha",
335
- "rho": "sudo_set_rho",
336
- "kappa": "sudo_set_kappa",
337
- "difficulty": "sudo_set_difficulty",
338
- "bonds_moving_avg": "sudo_set_bonds_moving_average",
339
- "commit_reveal_weights_interval": "sudo_set_commit_reveal_weights_interval",
340
- "commit_reveal_weights_enabled": "sudo_set_commit_reveal_weights_enabled",
341
- "alpha_values": "sudo_set_alpha_values",
342
- "liquid_alpha_enabled": "sudo_set_liquid_alpha_enabled",
321
+ # btcli name: (subtensor method, sudo bool)
322
+ "rho": ("sudo_set_rho", False),
323
+ "kappa": ("sudo_set_kappa", False),
324
+ "immunity_period": ("sudo_set_immunity_period", False),
325
+ "min_allowed_weights": ("sudo_set_min_allowed_weights", False),
326
+ "max_weights_limit": ("sudo_set_max_weight_limit", False),
327
+ "tempo": ("sudo_set_tempo", True),
328
+ "min_difficulty": ("sudo_set_min_difficulty", False),
329
+ "max_difficulty": ("sudo_set_max_difficulty", False),
330
+ "weights_version": ("sudo_set_weights_version_key", False),
331
+ "weights_rate_limit": ("sudo_set_weights_set_rate_limit", False),
332
+ "adjustment_interval": ("sudo_set_adjustment_interval", True),
333
+ "activity_cutoff": ("sudo_set_activity_cutoff", False),
334
+ "target_regs_per_interval": ("sudo_set_target_registrations_per_interval", True),
335
+ "min_burn": ("sudo_set_min_burn", False),
336
+ "max_burn": ("sudo_set_max_burn", False),
337
+ "bonds_moving_avg": ("sudo_set_bonds_moving_average", False),
338
+ "max_regs_per_block": ("sudo_set_max_registrations_per_block", True),
339
+ "serving_rate_limit": ("sudo_set_serving_rate_limit", False),
340
+ "max_validators": ("sudo_set_max_allowed_validators", True),
341
+ "adjustment_alpha": ("sudo_set_adjustment_alpha", False),
342
+ "difficulty": ("sudo_set_difficulty", False),
343
+ "commit_reveal_weights_interval": (
344
+ "sudo_set_commit_reveal_weights_interval",
345
+ False,
346
+ ),
347
+ "commit_reveal_weights_enabled": ("sudo_set_commit_reveal_weights_enabled", False),
348
+ "alpha_values": ("sudo_set_alpha_values", False),
349
+ "liquid_alpha_enabled": ("sudo_set_liquid_alpha_enabled", False),
350
+ "registration_allowed": ("sudo_set_network_registration_allowed", False),
343
351
  }
344
352
 
345
353
  # Help Panels for cli help
@@ -4,12 +4,11 @@ import random
4
4
  from collections import defaultdict
5
5
  from dataclasses import dataclass
6
6
  from hashlib import blake2b
7
- from typing import Optional, Any, Union, Callable, Awaitable, cast
7
+ from typing import Optional, Any, Union, Callable, Awaitable, cast, TYPE_CHECKING
8
8
 
9
9
  from async_property import async_property
10
10
  from bt_decode import PortableRegistry, decode as decode_by_type_string, MetadataV15
11
11
  from bittensor_wallet import Keypair
12
- from packaging import version
13
12
  from scalecodec import GenericExtrinsic
14
13
  from scalecodec.base import ScaleBytes, ScaleType, RuntimeConfigurationObject
15
14
  from scalecodec.type_registry import load_type_registry_preset
@@ -20,7 +19,13 @@ from substrateinterface.exceptions import (
20
19
  BlockNotFound,
21
20
  )
22
21
  from substrateinterface.storage import StorageKey
23
- import websockets
22
+ from websockets.asyncio.client import connect
23
+ from websockets.exceptions import ConnectionClosed
24
+
25
+ from bittensor_cli.src.bittensor.utils import hex_to_bytes
26
+
27
+ if TYPE_CHECKING:
28
+ from websockets.asyncio.client import ClientConnection
24
29
 
25
30
  ResultHandler = Callable[[dict, Any], Awaitable[tuple[dict, bool]]]
26
31
 
@@ -434,7 +439,7 @@ class RuntimeCache:
434
439
  self.block_hashes[block_hash] = runtime
435
440
 
436
441
  def retrieve(
437
- self, block: Optional[int], block_hash: Optional[str]
442
+ self, block: Optional[int] = None, block_hash: Optional[str] = None
438
443
  ) -> Optional["Runtime"]:
439
444
  if block is not None:
440
445
  return self.blocks.get(block)
@@ -625,7 +630,7 @@ class Websocket:
625
630
  # TODO allow setting max concurrent connections and rpc subscriptions per connection
626
631
  # TODO reconnection logic
627
632
  self.ws_url = ws_url
628
- self.ws: Optional[websockets.WebSocketClientProtocol] = None
633
+ self.ws: Optional["ClientConnection"] = None
629
634
  self.id = 0
630
635
  self.max_subscriptions = max_subscriptions
631
636
  self.max_connections = max_connections
@@ -647,15 +652,12 @@ class Websocket:
647
652
  self._exit_task.cancel()
648
653
  if not self._initialized:
649
654
  self._initialized = True
650
- await self._connect()
655
+ self.ws = await asyncio.wait_for(
656
+ connect(self.ws_url, **self._options), timeout=10
657
+ )
651
658
  self._receiving_task = asyncio.create_task(self._start_receiving())
652
659
  return self
653
660
 
654
- async def _connect(self):
655
- self.ws = await asyncio.wait_for(
656
- websockets.connect(self.ws_url, **self._options), timeout=10
657
- )
658
-
659
661
  async def __aexit__(self, exc_type, exc_val, exc_tb):
660
662
  async with self._lock:
661
663
  self._in_use -= 1
@@ -696,9 +698,7 @@ class Websocket:
696
698
 
697
699
  async def _recv(self) -> None:
698
700
  try:
699
- response = json.loads(
700
- await cast(websockets.WebSocketClientProtocol, self.ws).recv()
701
- )
701
+ response = json.loads(await self.ws.recv())
702
702
  async with self._lock:
703
703
  self._open_subscriptions -= 1
704
704
  if "id" in response:
@@ -707,7 +707,7 @@ class Websocket:
707
707
  self._received[response["params"]["subscription"]] = response
708
708
  else:
709
709
  raise KeyError(response)
710
- except websockets.ConnectionClosed:
710
+ except ConnectionClosed:
711
711
  raise
712
712
  except KeyError as e:
713
713
  raise e
@@ -718,7 +718,7 @@ class Websocket:
718
718
  await self._recv()
719
719
  except asyncio.CancelledError:
720
720
  pass
721
- except websockets.ConnectionClosed:
721
+ except ConnectionClosed:
722
722
  # TODO try reconnect, but only if it's needed
723
723
  raise
724
724
 
@@ -735,7 +735,7 @@ class Websocket:
735
735
  try:
736
736
  await self.ws.send(json.dumps({**payload, **{"id": original_id}}))
737
737
  return original_id
738
- except websockets.ConnectionClosed:
738
+ except ConnectionClosed:
739
739
  raise
740
740
 
741
741
  async def retrieve(self, item_id: int) -> Optional[dict]:
@@ -772,13 +772,13 @@ class AsyncSubstrateInterface:
772
772
  """
773
773
  self.chain_endpoint = chain_endpoint
774
774
  self.__chain = chain_name
775
- options = {
776
- "max_size": 2**32,
777
- "write_limit": 2**16,
778
- }
779
- if version.parse(websockets.__version__) < version.parse("14.0"):
780
- options.update({"read_limit": 2**16})
781
- self.ws = Websocket(chain_endpoint, options=options)
775
+ self.ws = Websocket(
776
+ chain_endpoint,
777
+ options={
778
+ "max_size": 2**32,
779
+ "write_limit": 2**16,
780
+ },
781
+ )
782
782
  self._lock = asyncio.Lock()
783
783
  self.last_block_hash: Optional[str] = None
784
784
  self.config = {
@@ -1135,7 +1135,7 @@ class AsyncSubstrateInterface:
1135
1135
  -------
1136
1136
  StorageKey
1137
1137
  """
1138
- runtime = await self.init_runtime(block_hash=block_hash)
1138
+ await self.init_runtime(block_hash=block_hash)
1139
1139
 
1140
1140
  return StorageKey.create_from_storage_function(
1141
1141
  pallet,
@@ -1555,7 +1555,7 @@ class AsyncSubstrateInterface:
1555
1555
  self,
1556
1556
  response: dict,
1557
1557
  subscription_id: Union[int, str],
1558
- value_scale_type: Optional[str],
1558
+ value_scale_type: Optional[str] = None,
1559
1559
  storage_item: Optional[ScaleType] = None,
1560
1560
  runtime: Optional[Runtime] = None,
1561
1561
  result_handler: Optional[ResultHandler] = None,
@@ -1769,7 +1769,6 @@ class AsyncSubstrateInterface:
1769
1769
  call_params = {}
1770
1770
 
1771
1771
  await self.init_runtime(block_hash=block_hash)
1772
-
1773
1772
  call = self.runtime_config.create_scale_object(
1774
1773
  type_string="Call", metadata=self.metadata
1775
1774
  )
@@ -2087,7 +2086,8 @@ class AsyncSubstrateInterface:
2087
2086
 
2088
2087
  :return: The signed Extrinsic
2089
2088
  """
2090
- await self.init_runtime()
2089
+ if not self.metadata:
2090
+ await self.init_runtime()
2091
2091
 
2092
2092
  # Check requirements
2093
2093
  if not isinstance(call, GenericCall):
@@ -2140,7 +2140,6 @@ class AsyncSubstrateInterface:
2140
2140
  extrinsic = self.runtime_config.create_scale_object(
2141
2141
  type_string="Extrinsic", metadata=self.metadata
2142
2142
  )
2143
-
2144
2143
  value = {
2145
2144
  "account_id": f"0x{keypair.public_key.hex()}",
2146
2145
  "signature": f"0x{signature.hex()}",
@@ -2158,9 +2157,7 @@ class AsyncSubstrateInterface:
2158
2157
  signature_cls = self.runtime_config.get_decoder_class("ExtrinsicSignature")
2159
2158
  if issubclass(signature_cls, self.runtime_config.get_decoder_class("Enum")):
2160
2159
  value["signature_version"] = signature_version
2161
-
2162
2160
  extrinsic.encode(value)
2163
-
2164
2161
  return extrinsic
2165
2162
 
2166
2163
  async def get_chain_finalised_head(self):
@@ -2564,10 +2561,7 @@ class AsyncSubstrateInterface:
2564
2561
  item_key = None
2565
2562
 
2566
2563
  try:
2567
- try:
2568
- item_bytes = bytes.fromhex(item[1][2:])
2569
- except ValueError:
2570
- item_bytes = bytes.fromhex(item[1])
2564
+ item_bytes = hex_to_bytes(item[1])
2571
2565
 
2572
2566
  item_value = await self.decode_scale(
2573
2567
  type_string=value_type,
@@ -18,7 +18,6 @@ import typing
18
18
  from typing import Optional
19
19
  import subprocess
20
20
 
21
- import backoff
22
21
  from bittensor_wallet import Wallet
23
22
  from Crypto.Hash import keccak
24
23
  import numpy as np
@@ -37,6 +36,7 @@ from bittensor_cli.src.bittensor.utils import (
37
36
  print_verbose,
38
37
  print_error,
39
38
  unlock_key,
39
+ hex_to_bytes,
40
40
  )
41
41
 
42
42
  if typing.TYPE_CHECKING:
@@ -618,10 +618,7 @@ async def register_extrinsic(
618
618
  if not success:
619
619
  success, err_msg = (
620
620
  False,
621
- format_error_message(
622
- await response.error_message,
623
- substrate=subtensor.substrate,
624
- ),
621
+ format_error_message(await response.error_message),
625
622
  )
626
623
  # Look error here
627
624
  # https://github.com/opentensor/subtensor/blob/development/pallets/subtensor/src/errors.rs
@@ -687,7 +684,7 @@ async def run_faucet_extrinsic(
687
684
  tpb: int = 256,
688
685
  num_processes: Optional[int] = None,
689
686
  update_interval: Optional[int] = None,
690
- log_verbose: bool = False,
687
+ log_verbose: bool = True,
691
688
  max_successes: int = 3,
692
689
  ) -> tuple[bool, str]:
693
690
  r"""Runs a continual POW to get a faucet of TAO on the test net.
@@ -735,8 +732,12 @@ async def run_faucet_extrinsic(
735
732
  # Attempt rolling registration.
736
733
  attempts = 1
737
734
  successes = 1
735
+ pow_result: Optional[POWSolution]
738
736
  while True:
739
737
  try:
738
+ account_nonce = await subtensor.substrate.get_account_nonce(
739
+ wallet.coldkey.ss58_address
740
+ )
740
741
  pow_result = None
741
742
  while pow_result is None or await pow_result.is_stale(subtensor=subtensor):
742
743
  # Solve latest POW.
@@ -745,7 +746,7 @@ async def run_faucet_extrinsic(
745
746
  if prompt:
746
747
  err_console.print("CUDA is not available.")
747
748
  return False, "CUDA is not available."
748
- pow_result: Optional[POWSolution] = await create_pow(
749
+ pow_result = await create_pow(
749
750
  subtensor,
750
751
  wallet,
751
752
  -1,
@@ -758,7 +759,7 @@ async def run_faucet_extrinsic(
758
759
  log_verbose=log_verbose,
759
760
  )
760
761
  else:
761
- pow_result: Optional[POWSolution] = await create_pow(
762
+ pow_result = await create_pow(
762
763
  subtensor,
763
764
  wallet,
764
765
  -1,
@@ -778,7 +779,7 @@ async def run_faucet_extrinsic(
778
779
  },
779
780
  )
780
781
  extrinsic = await subtensor.substrate.create_signed_extrinsic(
781
- call=call, keypair=wallet.coldkey
782
+ call=call, keypair=wallet.coldkey, nonce=account_nonce
782
783
  )
783
784
  response = await subtensor.substrate.submit_extrinsic(
784
785
  extrinsic,
@@ -791,7 +792,7 @@ async def run_faucet_extrinsic(
791
792
  if not await response.is_success:
792
793
  err_console.print(
793
794
  f":cross_mark: [red]Failed[/red]: "
794
- f"{format_error_message(await response.error_message, subtensor.substrate)}"
795
+ f"{format_error_message(await response.error_message)}"
795
796
  )
796
797
  if attempts == max_allowed_attempts:
797
798
  raise MaxAttemptsException
@@ -863,7 +864,7 @@ async def _check_for_newest_block_and_update(
863
864
  block_number, difficulty, block_hash = await _get_block_with_retry(
864
865
  subtensor=subtensor, netuid=netuid
865
866
  )
866
- block_bytes = bytes.fromhex(block_hash[2:])
867
+ block_bytes = hex_to_bytes(block_hash)
867
868
 
868
869
  update_curr_block(
869
870
  curr_diff,
@@ -970,7 +971,7 @@ async def _block_solver(
970
971
  subtensor=subtensor, netuid=netuid
971
972
  )
972
973
 
973
- block_bytes = bytes.fromhex(block_hash[2:])
974
+ block_bytes = hex_to_bytes(block_hash)
974
975
  old_block_number = block_number
975
976
  # Set to current block
976
977
  _update_curr_block(
@@ -1245,11 +1246,9 @@ def _terminate_workers_and_wait_for_exit(
1245
1246
  worker.terminate()
1246
1247
 
1247
1248
 
1248
- # TODO verify this works with async
1249
- @backoff.on_exception(backoff.constant, Exception, interval=1, max_tries=3)
1250
1249
  async def _get_block_with_retry(
1251
1250
  subtensor: "SubtensorInterface", netuid: int
1252
- ) -> tuple[int, int, bytes]:
1251
+ ) -> tuple[int, int, str]:
1253
1252
  """
1254
1253
  Gets the current block number, difficulty, and block hash from the substrate node.
1255
1254
 
@@ -1261,10 +1260,9 @@ async def _get_block_with_retry(
1261
1260
  :raises Exception: If the block hash is None.
1262
1261
  :raises ValueError: If the difficulty is None.
1263
1262
  """
1264
- block_number = await subtensor.substrate.get_block_number(None)
1265
- block_hash = await subtensor.substrate.get_block_hash(
1266
- block_number
1267
- ) # TODO check if I need to do all this
1263
+ block = await subtensor.substrate.get_block()
1264
+ block_hash = block["header"]["hash"]
1265
+ block_number = block["header"]["number"]
1268
1266
  try:
1269
1267
  difficulty = (
1270
1268
  1_000_000
@@ -486,11 +486,11 @@ async def set_root_weights_extrinsic(
486
486
  console.print(":white_heavy_check_mark: [green]Finalized[/green]")
487
487
  return True
488
488
  else:
489
- fmt_err = format_error_message(error_message, subtensor.substrate)
489
+ fmt_err = format_error_message(error_message)
490
490
  err_console.print(f":cross_mark: [red]Failed[/red]: {fmt_err}")
491
491
  return False
492
492
 
493
493
  except SubstrateRequestException as e:
494
- fmt_err = format_error_message(e, subtensor.substrate)
494
+ fmt_err = format_error_message(e)
495
495
  err_console.print(":cross_mark: [red]Failed[/red]: error:{}".format(fmt_err))
496
496
  return False
@@ -67,7 +67,7 @@ async def transfer_extrinsic(
67
67
  payment_info = {"partialFee": int(2e7)} # assume 0.02 Tao
68
68
  err_console.print(
69
69
  f":cross_mark: [red]Failed to get payment info[/red]:[bold white]\n"
70
- f" {format_error_message(e, subtensor.substrate)}[/bold white]\n"
70
+ f" {format_error_message(e)}[/bold white]\n"
71
71
  f" Defaulting to default transfer fee: {payment_info['partialFee']}"
72
72
  )
73
73
 
@@ -104,7 +104,7 @@ async def transfer_extrinsic(
104
104
  return (
105
105
  False,
106
106
  "",
107
- format_error_message(await response.error_message, subtensor.substrate),
107
+ format_error_message(await response.error_message),
108
108
  )
109
109
 
110
110
  # Validate destination address.
@@ -35,6 +35,7 @@ from bittensor_cli.src.bittensor.utils import (
35
35
  err_console,
36
36
  decode_hex_identity_dict,
37
37
  validate_chain_endpoint,
38
+ hex_to_bytes,
38
39
  )
39
40
 
40
41
 
@@ -213,12 +214,7 @@ class SubtensorInterface:
213
214
  block_hash=block_hash,
214
215
  )
215
216
  if hex_bytes_result is not None:
216
- try:
217
- bytes_result = bytes.fromhex(hex_bytes_result[2:])
218
- except ValueError:
219
- bytes_result = bytes.fromhex(hex_bytes_result)
220
-
221
- return DelegateInfo.list_from_vec_u8(bytes_result)
217
+ return DelegateInfo.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
222
218
  else:
223
219
  return []
224
220
 
@@ -254,12 +250,7 @@ class SubtensorInterface:
254
250
  if hex_bytes_result is None:
255
251
  return []
256
252
 
257
- try:
258
- bytes_result = bytes.fromhex(hex_bytes_result[2:])
259
- except ValueError:
260
- bytes_result = bytes.fromhex(hex_bytes_result)
261
-
262
- return StakeInfo.list_from_vec_u8(bytes_result)
253
+ return StakeInfo.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
263
254
 
264
255
  async def get_stake_for_coldkey_and_hotkey(
265
256
  self, hotkey_ss58: str, coldkey_ss58: str, block_hash: Optional[str]
@@ -654,12 +645,7 @@ class SubtensorInterface:
654
645
  if hex_bytes_result is None:
655
646
  return []
656
647
 
657
- try:
658
- bytes_result = bytes.fromhex(hex_bytes_result[2:])
659
- except ValueError:
660
- bytes_result = bytes.fromhex(hex_bytes_result)
661
-
662
- return NeuronInfoLite.list_from_vec_u8(bytes_result)
648
+ return NeuronInfoLite.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
663
649
 
664
650
  async def neuron_for_uid(
665
651
  self, uid: Optional[int], netuid: int, block_hash: Optional[str] = None
@@ -927,11 +913,9 @@ class SubtensorInterface:
927
913
  if await response.is_success:
928
914
  return True, ""
929
915
  else:
930
- return False, format_error_message(
931
- await response.error_message, substrate=self.substrate
932
- )
916
+ return False, format_error_message(await response.error_message)
933
917
  except SubstrateRequestException as e:
934
- return False, format_error_message(e, substrate=self.substrate)
918
+ return False, format_error_message(e)
935
919
 
936
920
  async def get_children(self, hotkey, netuid) -> tuple[bool, list, str]:
937
921
  """
@@ -961,7 +945,7 @@ class SubtensorInterface:
961
945
  else:
962
946
  return True, [], ""
963
947
  except SubstrateRequestException as e:
964
- return False, [], format_error_message(e, self.substrate)
948
+ return False, [], format_error_message(e)
965
949
 
966
950
  async def get_subnet_hyperparameters(
967
951
  self, netuid: int, block_hash: Optional[str] = None
@@ -988,12 +972,7 @@ class SubtensorInterface:
988
972
  if hex_bytes_result is None:
989
973
  return []
990
974
 
991
- if hex_bytes_result.startswith("0x"):
992
- bytes_result = bytes.fromhex(hex_bytes_result[2:])
993
- else:
994
- bytes_result = bytes.fromhex(hex_bytes_result)
995
-
996
- return SubnetHyperparameters.from_vec_u8(bytes_result)
975
+ return SubnetHyperparameters.from_vec_u8(hex_to_bytes(hex_bytes_result))
997
976
 
998
977
  async def get_vote_data(
999
978
  self,
@@ -458,16 +458,13 @@ def get_explorer_url_for_network(
458
458
  return explorer_urls
459
459
 
460
460
 
461
- def format_error_message(
462
- error_message: Union[dict, Exception], substrate: "AsyncSubstrateInterface"
463
- ) -> str:
461
+ def format_error_message(error_message: Union[dict, Exception]) -> str:
464
462
  """
465
463
  Formats an error message from the Subtensor error information for use in extrinsics.
466
464
 
467
465
  Args:
468
466
  error_message: A dictionary containing the error information from Subtensor, or a SubstrateRequestException
469
467
  containing dictionary literal args.
470
- substrate: The initialised SubstrateInterface object to use.
471
468
 
472
469
  Returns:
473
470
  str: A formatted error message string.
@@ -509,22 +506,8 @@ def format_error_message(
509
506
  err_data = error_message.get("data", "")
510
507
 
511
508
  # subtensor custom error marker
512
- if err_data.startswith("Custom error:") and substrate:
513
- if substrate.metadata:
514
- try:
515
- pallet = substrate.metadata.get_metadata_pallet(
516
- "SubtensorModule"
517
- )
518
- error_index = int(err_data.split("Custom error:")[-1])
519
-
520
- error_dict = pallet.errors[error_index].value
521
- err_type = error_dict.get("message", err_type)
522
- err_docs = error_dict.get("docs", [])
523
- err_description = err_docs[0] if err_docs else err_description
524
- except (AttributeError, IndexError):
525
- err_console.print(
526
- "Substrate pallets data unavailable. This is usually caused by an uninitialized substrate."
527
- )
509
+ if err_data.startswith("Custom error:"):
510
+ err_description = f"{err_data} | Please consult https://docs.bittensor.com/subtensor-nodes/subtensor-error-messages"
528
511
  else:
529
512
  err_description = err_data
530
513
 
@@ -538,7 +521,7 @@ def format_error_message(
538
521
  err_docs = error_message.get("docs", [err_description])
539
522
  err_description = err_docs[0] if err_docs else err_description
540
523
 
541
- return f"Subtensor returned `{err_name}({err_type})` error. This means: '{err_description}'."
524
+ return f"Subtensor returned `{err_name}({err_type})` error. This means: `{err_description}`."
542
525
 
543
526
 
544
527
  def convert_blocks_to_time(blocks: int, block_time: int = 12) -> tuple[int, int, int]:
@@ -581,7 +564,7 @@ def decode_hex_identity_dict(info_dictionary) -> dict[str, Any]:
581
564
  def get_decoded(data: str) -> str:
582
565
  """Decodes a hex-encoded string."""
583
566
  try:
584
- return bytes.fromhex(data[2:]).decode()
567
+ return hex_to_bytes(data).decode()
585
568
  except UnicodeDecodeError:
586
569
  print(f"Could not decode: {key}: {item}")
587
570
 
@@ -1016,3 +999,14 @@ def unlock_key(
1016
999
  if print_out:
1017
1000
  err_console.print(f":cross_mark: [red]{err_msg}[/red]")
1018
1001
  return UnlockStatus(False, err_msg)
1002
+
1003
+
1004
+ def hex_to_bytes(hex_str: str) -> bytes:
1005
+ """
1006
+ Converts a hex-encoded string into bytes. Handles 0x-prefixed and non-prefixed hex-encoded strings.
1007
+ """
1008
+ if hex_str.startswith("0x"):
1009
+ bytes_result = bytes.fromhex(hex_str[2:])
1010
+ else:
1011
+ bytes_result = bytes.fromhex(hex_str)
1012
+ return bytes_result
@@ -866,11 +866,13 @@ async def get_weights(
866
866
 
867
867
  uid_to_weights[uid][netuid] = normalized_weight
868
868
  rows: list[list[str]] = []
869
+ sorted_netuids: list = list(netuids)
870
+ sorted_netuids.sort()
869
871
  for uid in uid_to_weights:
870
872
  row = [str(uid)]
871
873
 
872
874
  uid_weights = uid_to_weights[uid]
873
- for netuid in netuids:
875
+ for netuid in sorted_netuids:
874
876
  if netuid in uid_weights:
875
877
  row.append("{:0.2f}%".format(uid_weights[netuid] * 100))
876
878
  else:
@@ -879,24 +881,23 @@ async def get_weights(
879
881
 
880
882
  if not no_cache:
881
883
  db_cols = [("UID", "INTEGER")]
882
- for netuid in netuids:
884
+ for netuid in sorted_netuids:
883
885
  db_cols.append((f"_{netuid}", "TEXT"))
884
886
  create_table("rootgetweights", db_cols, rows)
885
- netuids = list(netuids)
886
887
  update_metadata_table(
887
888
  "rootgetweights",
888
- {"rows": json.dumps(rows), "netuids": json.dumps(netuids)},
889
+ {"rows": json.dumps(rows), "netuids": json.dumps(sorted_netuids)},
889
890
  )
890
891
  else:
891
892
  metadata = get_metadata_table("rootgetweights")
892
893
  rows = json.loads(metadata["rows"])
893
- netuids = json.loads(metadata["netuids"])
894
+ sorted_netuids = json.loads(metadata["netuids"])
894
895
 
895
896
  _min_lim = limit_min_col if limit_min_col is not None else 0
896
- _max_lim = limit_max_col + 1 if limit_max_col is not None else len(netuids)
897
- _max_lim = min(_max_lim, len(netuids))
897
+ _max_lim = limit_max_col + 1 if limit_max_col is not None else len(sorted_netuids)
898
+ _max_lim = min(_max_lim, len(sorted_netuids))
898
899
 
899
- if _min_lim is not None and _min_lim > len(netuids):
900
+ if _min_lim is not None and _min_lim > len(sorted_netuids):
900
901
  err_console.print("Minimum limit greater than number of netuids")
901
902
  return
902
903
 
@@ -915,8 +916,7 @@ async def get_weights(
915
916
  style="rgb(50,163,219)",
916
917
  no_wrap=True,
917
918
  )
918
- netuids = list(netuids)
919
- for netuid in netuids[_min_lim:_max_lim]:
919
+ for netuid in sorted_netuids[_min_lim:_max_lim]:
920
920
  table.add_column(
921
921
  f"[white]{netuid}",
922
922
  header_style="overline white",
@@ -939,7 +939,7 @@ async def get_weights(
939
939
 
940
940
  else:
941
941
  html_cols = [{"title": "UID", "field": "UID"}]
942
- for netuid in netuids[_min_lim:_max_lim]:
942
+ for netuid in sorted_netuids[_min_lim:_max_lim]:
943
943
  html_cols.append({"title": str(netuid), "field": f"_{netuid}"})
944
944
  render_table(
945
945
  "rootgetweights",
@@ -208,7 +208,7 @@ async def set_childkey_take_extrinsic(
208
208
  except SubstrateRequestException as e:
209
209
  return (
210
210
  False,
211
- f"Exception occurred while setting childkey take: {format_error_message(e, subtensor.substrate)}",
211
+ f"Exception occurred while setting childkey take: {format_error_message(e)}",
212
212
  )
213
213
 
214
214
 
@@ -232,9 +232,7 @@ async def get_childkey_take(subtensor, hotkey: str, netuid: int) -> Optional[int
232
232
  return int(childkey_take_.value)
233
233
 
234
234
  except SubstrateRequestException as e:
235
- err_console.print(
236
- f"Error querying ChildKeys: {format_error_message(e, subtensor.substrate)}"
237
- )
235
+ err_console.print(f"Error querying ChildKeys: {format_error_message(e)}")
238
236
  return None
239
237
 
240
238
 
@@ -28,6 +28,7 @@ from bittensor_cli.src.bittensor.utils import (
28
28
  render_table,
29
29
  update_metadata_table,
30
30
  unlock_key,
31
+ hex_to_bytes,
31
32
  )
32
33
 
33
34
  if TYPE_CHECKING:
@@ -127,7 +128,7 @@ async def register_subnetwork_extrinsic(
127
128
  await response.process_events()
128
129
  if not await response.is_success:
129
130
  err_console.print(
130
- f":cross_mark: [red]Failed[/red]: {format_error_message(await response.error_message, substrate)}"
131
+ f":cross_mark: [red]Failed[/red]: {format_error_message(await response.error_message)}"
131
132
  )
132
133
  await asyncio.sleep(0.5)
133
134
  return False
@@ -155,12 +156,8 @@ async def subnets_list(
155
156
  hex_bytes_result = await subtensor.query_runtime_api(
156
157
  runtime_api="SubnetInfoRuntimeApi", method="get_subnets_info", params=[]
157
158
  )
158
- try:
159
- bytes_result = bytes.fromhex(hex_bytes_result[2:])
160
- except ValueError:
161
- bytes_result = bytes.fromhex(hex_bytes_result)
162
159
 
163
- return SubnetInfo.list_from_vec_u8(bytes_result)
160
+ return SubnetInfo.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
164
161
 
165
162
  if not reuse_last:
166
163
  subnets: list[SubnetInfo]
@@ -104,7 +104,7 @@ async def set_hyperparameter_extrinsic(
104
104
  if not unlock_key(wallet).success:
105
105
  return False
106
106
 
107
- extrinsic = HYPERPARAMS.get(parameter)
107
+ extrinsic, sudo_ = HYPERPARAMS.get(parameter, ("", False))
108
108
  if extrinsic is None:
109
109
  err_console.print(":cross_mark: [red]Invalid hyperparameter specified.[/red]")
110
110
  return False
@@ -144,11 +144,17 @@ async def set_hyperparameter_extrinsic(
144
144
  call_params[str(value_argument["name"])] = value
145
145
 
146
146
  # create extrinsic call
147
- call = await substrate.compose_call(
147
+ call_ = await substrate.compose_call(
148
148
  call_module="AdminUtils",
149
149
  call_function=extrinsic,
150
150
  call_params=call_params,
151
151
  )
152
+ if sudo_:
153
+ call = await substrate.compose_call(
154
+ call_module="Sudo", call_function="sudo", call_params={"call": call_}
155
+ )
156
+ else:
157
+ call = call_
152
158
  success, err_msg = await subtensor.sign_and_send_extrinsic(
153
159
  call, wallet, wait_for_inclusion, wait_for_finalization
154
160
  )
@@ -178,19 +184,20 @@ async def sudo_set_hyperparameter(
178
184
 
179
185
  normalized_value: Union[str, bool]
180
186
  if param_name in [
181
- "network_registration_allowed",
187
+ "registration_allowed",
182
188
  "network_pow_registration_allowed",
183
189
  "commit_reveal_weights_enabled",
184
190
  "liquid_alpha_enabled",
185
191
  ]:
186
- normalized_value = param_value.lower() in ["true", "1"]
192
+ normalized_value = param_value.lower() in ["true", "True", "1"]
187
193
  else:
188
194
  normalized_value = param_value
189
195
 
190
196
  is_allowed_value, value = allowed_value(param_name, normalized_value)
191
197
  if not is_allowed_value:
192
198
  err_console.print(
193
- f"Hyperparameter {param_name} value is not within bounds. Value is {normalized_value} but must be {value}"
199
+ f"Hyperparameter [dark_orange]{param_name}[/dark_orange] value is not within bounds. "
200
+ f"Value is {normalized_value} but must be {value}"
194
201
  )
195
202
  return
196
203
 
@@ -15,23 +15,19 @@ from bittensor_wallet.keyfile import Keyfile
15
15
  from fuzzywuzzy import fuzz
16
16
  from rich import box
17
17
  from rich.align import Align
18
- from rich.prompt import Confirm, Prompt
18
+ from rich.prompt import Confirm
19
19
  from rich.table import Column, Table
20
20
  from rich.tree import Tree
21
21
  from rich.padding import Padding
22
22
  from rich.prompt import IntPrompt
23
- from scalecodec import ScaleBytes
24
- import scalecodec
25
23
  import typer
26
24
 
27
- from bittensor_cli.src import TYPE_REGISTRY
28
25
  from bittensor_cli.src.bittensor import utils
29
26
  from bittensor_cli.src.bittensor.balances import Balance
30
27
  from bittensor_cli.src.bittensor.chain_data import (
31
28
  DelegateInfo,
32
29
  NeuronInfoLite,
33
30
  StakeInfo,
34
- custom_rpc_type_registry,
35
31
  decode_account_id,
36
32
  )
37
33
  from bittensor_cli.src.bittensor.extrinsics.registration import (
@@ -46,7 +42,6 @@ from bittensor_cli.src.bittensor.utils import (
46
42
  RAO_PER_TAO,
47
43
  console,
48
44
  convert_blocks_to_time,
49
- decode_scale_bytes,
50
45
  err_console,
51
46
  print_error,
52
47
  print_verbose,
@@ -56,6 +51,7 @@ from bittensor_cli.src.bittensor.utils import (
56
51
  validate_coldkey_presence,
57
52
  retry_prompt,
58
53
  unlock_key,
54
+ hex_to_bytes,
59
55
  )
60
56
 
61
57
 
@@ -660,8 +656,13 @@ async def overview(
660
656
  neurons
661
657
  )
662
658
 
659
+ has_alerts = False
663
660
  alerts_table = Table(show_header=True, header_style="bold magenta")
664
661
  alerts_table.add_column("🥩 alert!")
662
+ alerts_table.add_row(
663
+ "[bold]Detected the following stake(s) associated with coldkey(s) that are not linked to any local hotkeys:[/bold]"
664
+ )
665
+ alerts_table.add_row("")
665
666
 
666
667
  coldkeys_to_check = []
667
668
  ck_stakes = await subtensor.get_total_stake_for_coldkey(
@@ -684,12 +685,23 @@ async def overview(
684
685
  if difference == 0:
685
686
  continue # We have all our stake registered.
686
687
 
688
+ has_alerts = True
687
689
  coldkeys_to_check.append(coldkey_wallet)
688
690
  alerts_table.add_row(
689
- "Found [light_goldenrod2]{}[/light_goldenrod2] stake with coldkey [bright_magenta]{}[/bright_magenta] that is not registered.".format(
690
- abs(difference), coldkey_wallet.coldkeypub.ss58_address
691
+ "[light_goldenrod2]{}[/light_goldenrod2] stake associated with coldkey [bright_magenta]{}[/bright_magenta] (ss58: [bright_magenta]{}[/bright_magenta])".format(
692
+ abs(difference),
693
+ coldkey_wallet.name,
694
+ coldkey_wallet.coldkeypub.ss58_address,
691
695
  )
692
696
  )
697
+ if has_alerts:
698
+ alerts_table.add_row("")
699
+ alerts_table.add_row(
700
+ "[bold yellow]Note:[/bold yellow] This stake might be delegated, staked to another user's hotkey, or associated with a hotkey not present in your wallet."
701
+ )
702
+ alerts_table.add_row(
703
+ "You can find out more by executing `[bold]btcli wallet inspect[/bold]` command."
704
+ )
693
705
 
694
706
  if coldkeys_to_check:
695
707
  # We have some stake that is not with a registered hotkey.
@@ -743,7 +755,7 @@ async def overview(
743
755
  grid = Table.grid(pad_edge=True)
744
756
 
745
757
  # If there are any alerts, add them to the grid
746
- if len(alerts_table.rows) > 0:
758
+ if has_alerts:
747
759
  grid.add_row(alerts_table)
748
760
 
749
761
  # Add title
@@ -1176,7 +1188,7 @@ def _process_neurons_for_netuids(
1176
1188
  :return: netuids mapped to decoded neurons
1177
1189
  """
1178
1190
  all_results = [
1179
- (netuid, NeuronInfoLite.list_from_vec_u8(bytes.fromhex(result[2:])))
1191
+ (netuid, NeuronInfoLite.list_from_vec_u8(hex_to_bytes(result)))
1180
1192
  if result
1181
1193
  else (netuid, [])
1182
1194
  for netuid, result in netuids_with_all_neurons_hex_bytes
@@ -134,9 +134,7 @@ class SetWeightsExtrinsic:
134
134
  try:
135
135
  success, message = await self.do_commit_weights(commit_hash=commit_hash)
136
136
  except SubstrateRequestException as e:
137
- err_console.print(
138
- f"Error committing weights: {format_error_message(e, self.subtensor.substrate)}"
139
- )
137
+ err_console.print(f"Error committing weights: {format_error_message(e)}")
140
138
  # bittensor.logging.error(f"Error committing weights: {e}")
141
139
  success = False
142
140
  message = "No attempt made. Perhaps it is too soon to commit weights!"
@@ -257,7 +255,7 @@ class SetWeightsExtrinsic:
257
255
  wait_for_finalization=self.wait_for_finalization,
258
256
  )
259
257
  except SubstrateRequestException as e:
260
- return False, format_error_message(e, self.subtensor.substrate)
258
+ return False, format_error_message(e)
261
259
  # We only wait here if we expect finalization.
262
260
  if not self.wait_for_finalization and not self.wait_for_inclusion:
263
261
  return True, "Not waiting for finalization or inclusion."
@@ -266,9 +264,7 @@ class SetWeightsExtrinsic:
266
264
  if await response.is_success:
267
265
  return True, "Successfully set weights."
268
266
  else:
269
- return False, format_error_message(
270
- await response.error_message, self.subtensor.substrate
271
- )
267
+ return False, format_error_message(await response.error_message)
272
268
 
273
269
  with console.status(
274
270
  f":satellite: Setting weights on [white]{self.subtensor.network}[/white] ..."
@@ -314,7 +310,7 @@ class SetWeightsExtrinsic:
314
310
  wait_for_finalization=self.wait_for_finalization,
315
311
  )
316
312
  except SubstrateRequestException as e:
317
- return False, format_error_message(e, self.subtensor.substrate)
313
+ return False, format_error_message(e)
318
314
 
319
315
  if not self.wait_for_finalization and not self.wait_for_inclusion:
320
316
  success, error_message = True, ""
@@ -326,9 +322,7 @@ class SetWeightsExtrinsic:
326
322
  else:
327
323
  success, error_message = (
328
324
  False,
329
- format_error_message(
330
- await response.error_message, self.subtensor.substrate
331
- ),
325
+ format_error_message(await response.error_message),
332
326
  )
333
327
 
334
328
  if success:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bittensor-cli
3
- Version: 8.3.1
3
+ Version: 8.4.1
4
4
  Summary: Bittensor CLI
5
5
  Home-page: https://github.com/opentensor/btcli
6
6
  Author: bittensor.com
@@ -32,7 +32,6 @@ Requires-Dist: fuzzywuzzy~=0.18.0
32
32
  Requires-Dist: netaddr~=1.3.0
33
33
  Requires-Dist: numpy>=2.0.1
34
34
  Requires-Dist: Jinja2
35
- Requires-Dist: packaging
36
35
  Requires-Dist: pycryptodome
37
36
  Requires-Dist: PyYAML~=6.0.1
38
37
  Requires-Dist: pytest
@@ -41,9 +40,9 @@ Requires-Dist: rich~=13.7
41
40
  Requires-Dist: scalecodec==1.2.11
42
41
  Requires-Dist: substrate-interface~=1.7.9
43
42
  Requires-Dist: typer~=0.12
44
- Requires-Dist: websockets>=12.0
45
- Requires-Dist: bittensor-wallet>=2.1.0
46
- Requires-Dist: bt-decode==0.2.0a0
43
+ Requires-Dist: websockets>=14.1
44
+ Requires-Dist: bittensor-wallet>=2.1.3
45
+ Requires-Dist: bt-decode==0.4.0
47
46
  Provides-Extra: cuda
48
47
  Requires-Dist: cubit>=1.1.0; extra == "cuda"
49
48
  Requires-Dist: torch; extra == "cuda"
@@ -0,0 +1,31 @@
1
+ bittensor_cli/__init__.py,sha256=j3n_j0nQ-fdPqYmNd-D4fMTInfnsFcsaKeltpG2vMk0,1217
2
+ bittensor_cli/cli.py,sha256=mpkvwSy-YpJN9HZGTetA-5m441p3DxvjrwH9nuOqzOA,170143
3
+ bittensor_cli/doc_generation_helper.py,sha256=GexqjEIKulWg84hpNBEchJ840oOgOi7DWpt447nsdNI,91
4
+ bittensor_cli/src/__init__.py,sha256=LpTjd5p40H08K4IbyJCNdLJhEcb8NuWXOwl5kSNYwjI,12355
5
+ bittensor_cli/src/bittensor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ bittensor_cli/src/bittensor/async_substrate_interface.py,sha256=o7Pe_Nxsys8aPm_xsih2xR8ArhZrUu9yYobf8qBvT5s,103185
7
+ bittensor_cli/src/bittensor/balances.py,sha256=102mg1iiliLSLx-EocQseWGHiWzRqcBBM-MRoObOdKo,10075
8
+ bittensor_cli/src/bittensor/chain_data.py,sha256=IsHWjmhJbTvud2i3IM1sfmBHP82VxNHC1iFDAtlLgXc,26490
9
+ bittensor_cli/src/bittensor/minigraph.py,sha256=17AjEA75MO7ez_NekOJSaAz6ARjPt99QG_7E1RJ_u_k,8891
10
+ bittensor_cli/src/bittensor/networking.py,sha256=pZLMs8YXpZzDMLXWMBb_Bj6TVkm_q9khyY-lnbwVMuE,462
11
+ bittensor_cli/src/bittensor/subtensor_interface.py,sha256=JPlA39oHf1k3ltrgDKeiAnBqF51oJnn-s3EO5y1WbAY,42669
12
+ bittensor_cli/src/bittensor/utils.py,sha256=cQK2tU06OYAbedqVi3M9Nw6S2DujyyO7qHB-uAVkmDE,34686
13
+ bittensor_cli/src/bittensor/extrinsics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ bittensor_cli/src/bittensor/extrinsics/registration.py,sha256=Ieh8Wo9u7km0A_1FhEdKluozcFZB0VCs1sFEQc0faQA,58851
15
+ bittensor_cli/src/bittensor/extrinsics/root.py,sha256=hajvQOA3GyBsFKu7ifa69096dSP6NwBXmKm8HKLRVzs,19079
16
+ bittensor_cli/src/bittensor/extrinsics/transfer.py,sha256=I0XXmLI8rTxb4kUqws0J-PPcdg38TeV8AeyIVQT-TOU,8644
17
+ bittensor_cli/src/bittensor/templates/table.j2,sha256=P2EFiksnO1cQsB8zjK6hVJwUryHTsLslzRE0YtobAV8,10601
18
+ bittensor_cli/src/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ bittensor_cli/src/commands/root.py,sha256=28mHTMkZe0X-62Sg6o9dG82m1bx5IAG9eXk9ZBr3Jjo,62256
20
+ bittensor_cli/src/commands/subnets.py,sha256=riR41_ajUVWlDoaTUQahPzZswtY2h72pMK0rNuPj2SM,33164
21
+ bittensor_cli/src/commands/sudo.py,sha256=bP9t0QpXmqHnscEvCFHgJ4a7vETyqG1Kuc2CIVQ5qus,8436
22
+ bittensor_cli/src/commands/wallets.py,sha256=BuPJiEDOpHuGRx3zekU2QkFQjFpCUP-Kdk4opS5YfWo,60678
23
+ bittensor_cli/src/commands/weights.py,sha256=XHn0MLYUcEUtOkA_soIBJ5rqkpIliUVnyc4nzdPQslw,16276
24
+ bittensor_cli/src/commands/stake/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ bittensor_cli/src/commands/stake/children_hotkeys.py,sha256=IG2-WLW4ErueeM-EHbWJHY2IueEMz-wPOaAbMVbwRcc,28542
26
+ bittensor_cli/src/commands/stake/stake.py,sha256=7TyFtL5wnXvGvD-GckNrNTRdcu3RewAfx_JfEekugFU,56147
27
+ bittensor_cli-8.4.1.dist-info/METADATA,sha256=VGBdVENpJOnWPnrBvCWFe_nsdWJpql6aEmammdNVyZ0,6786
28
+ bittensor_cli-8.4.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
29
+ bittensor_cli-8.4.1.dist-info/entry_points.txt,sha256=hBTLGLbVxmAKy69XSKaUZvjTCmyEzDGZKq4S8UOto8I,49
30
+ bittensor_cli-8.4.1.dist-info/top_level.txt,sha256=DvgvXpmTtI_Q1BbDZMlK90LFcGFCreN1daViEPV2iFw,14
31
+ bittensor_cli-8.4.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.45.0)
2
+ Generator: bdist_wheel (0.45.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,31 +0,0 @@
1
- bittensor_cli/__init__.py,sha256=yocN6uqpsPRC1tYESgUAxLcB-JDVYswhljK3KdC2DUA,1217
2
- bittensor_cli/cli.py,sha256=ew32_K2VZ4-l6DsETJV6mjLpGBAa-VTUhx_8mBTG6vM,169772
3
- bittensor_cli/doc_generation_helper.py,sha256=GexqjEIKulWg84hpNBEchJ840oOgOi7DWpt447nsdNI,91
4
- bittensor_cli/src/__init__.py,sha256=9hFSqapIynZbrjc9YHl2wARkPdk4pV5P5zLSvn-EbqM,11856
5
- bittensor_cli/src/bittensor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- bittensor_cli/src/bittensor/async_substrate_interface.py,sha256=eXF5IxHMKJNNPzw_JdfhDiijghBQzOhEnk2i5F2L1OQ,103367
7
- bittensor_cli/src/bittensor/balances.py,sha256=102mg1iiliLSLx-EocQseWGHiWzRqcBBM-MRoObOdKo,10075
8
- bittensor_cli/src/bittensor/chain_data.py,sha256=IsHWjmhJbTvud2i3IM1sfmBHP82VxNHC1iFDAtlLgXc,26490
9
- bittensor_cli/src/bittensor/minigraph.py,sha256=17AjEA75MO7ez_NekOJSaAz6ARjPt99QG_7E1RJ_u_k,8891
10
- bittensor_cli/src/bittensor/networking.py,sha256=pZLMs8YXpZzDMLXWMBb_Bj6TVkm_q9khyY-lnbwVMuE,462
11
- bittensor_cli/src/bittensor/subtensor_interface.py,sha256=cwbRhS5qV0Jmref5Qe7rsuDy8ssrRqdObKHvaeGeoOc,43373
12
- bittensor_cli/src/bittensor/utils.py,sha256=_uJ7aiYJL6r-Cgyc0NDWBHVkdeyaGbFRYH7PABeM-iM,35184
13
- bittensor_cli/src/bittensor/extrinsics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- bittensor_cli/src/bittensor/extrinsics/registration.py,sha256=O3ikqyEbosvp3e9vCpMQ7cfjVdd6R4uiPYkXkiawxI4,59045
15
- bittensor_cli/src/bittensor/extrinsics/root.py,sha256=huycqHbSTFBNIhQ846MuBqwBEtQCSVDW3y3yPAqPzeU,19121
16
- bittensor_cli/src/bittensor/extrinsics/transfer.py,sha256=yC5oKgoKAXszMzfrof3GbeGppESUMgSqJFFGOMMALuc,8686
17
- bittensor_cli/src/bittensor/templates/table.j2,sha256=P2EFiksnO1cQsB8zjK6hVJwUryHTsLslzRE0YtobAV8,10601
18
- bittensor_cli/src/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- bittensor_cli/src/commands/root.py,sha256=hohGfh7w9Lu7z264rbmFkwRCStyZrtdBZVMt20RwiqA,62186
20
- bittensor_cli/src/commands/subnets.py,sha256=zlnWU-wmJ2GvhM1T3EN9nO_uzjHBai73i48NXGp9P94,33301
21
- bittensor_cli/src/commands/sudo.py,sha256=tIkrqUpn-xpbrRLr3jBmjNauP8NKbLloRg37p65llNM,8166
22
- bittensor_cli/src/commands/wallets.py,sha256=CCY9rz623ob-JcGU9pJxYwstMvlH8jdMc-sa7J-5XsU,60057
23
- bittensor_cli/src/commands/weights.py,sha256=UHakAMTNqRkg_fkiyebbZAT9T3UEf93MmdbFgPSbqUw,16520
24
- bittensor_cli/src/commands/stake/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- bittensor_cli/src/commands/stake/children_hotkeys.py,sha256=j239HdawvHp9rTbIx9MI9v9hkaKbA5OaN_cIQISkHdw,28606
26
- bittensor_cli/src/commands/stake/stake.py,sha256=7TyFtL5wnXvGvD-GckNrNTRdcu3RewAfx_JfEekugFU,56147
27
- bittensor_cli-8.3.1.dist-info/METADATA,sha256=KBU7oULNqbxQySkMNj3aWwUkVJPsZwgT_JqoIOcg_cY,6813
28
- bittensor_cli-8.3.1.dist-info/WHEEL,sha256=bFJAMchF8aTQGUgMZzHJyDDMPTO3ToJ7x23SLJa1SVo,92
29
- bittensor_cli-8.3.1.dist-info/entry_points.txt,sha256=hBTLGLbVxmAKy69XSKaUZvjTCmyEzDGZKq4S8UOto8I,49
30
- bittensor_cli-8.3.1.dist-info/top_level.txt,sha256=DvgvXpmTtI_Q1BbDZMlK90LFcGFCreN1daViEPV2iFw,14
31
- bittensor_cli-8.3.1.dist-info/RECORD,,