bittensor-cli 9.0.0rc3__py3-none-any.whl → 9.0.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.
@@ -4,12 +4,23 @@ from typing import Any, Optional
4
4
 
5
5
 
6
6
  class Constants:
7
- networks = ["local", "finney", "test", "archive", "rao", "dev", "latent-lite"]
7
+ networks = [
8
+ "local",
9
+ "finney",
10
+ "test",
11
+ "archive",
12
+ "subvortex",
13
+ "rao",
14
+ "dev",
15
+ "latent-lite",
16
+ ]
8
17
  finney_entrypoint = "wss://entrypoint-finney.opentensor.ai:443"
9
18
  finney_test_entrypoint = "wss://test.finney.opentensor.ai:443"
10
19
  archive_entrypoint = "wss://archive.chain.opentensor.ai:443"
20
+ subvortex_entrypoint = "ws://subvortex.info:9944"
21
+ local_entrypoint = "ws://127.0.0.1:9944"
11
22
  rao_entrypoint = "wss://rao.chain.opentensor.ai:443"
12
- dev_entrypoint = "wss://dev.chain.opentensor.ai:443 "
23
+ dev_entrypoint = "wss://dev.chain.opentensor.ai:443"
13
24
  local_entrypoint = "ws://127.0.0.1:9944"
14
25
  latent_lite_entrypoint = "wss://lite.sub.latent.to:443"
15
26
  network_map = {
@@ -20,6 +31,7 @@ class Constants:
20
31
  "dev": dev_entrypoint,
21
32
  "rao": rao_entrypoint,
22
33
  "latent-lite": latent_lite_entrypoint,
34
+ "subvortex": subvortex_entrypoint,
23
35
  }
24
36
  delegates_detail_url = "https://raw.githubusercontent.com/opentensor/bittensor-delegates/main/public/delegates.json"
25
37
 
@@ -100,7 +112,7 @@ class Defaults:
100
112
  }
101
113
 
102
114
  class subtensor:
103
- network = "test"
115
+ network = "finney"
104
116
  chain_endpoint = None
105
117
  _mock = False
106
118
 
@@ -631,28 +643,40 @@ NETWORK_EXPLORER_MAP = {
631
643
 
632
644
 
633
645
  HYPERPARAMS = {
634
- "serving_rate_limit": "sudo_set_serving_rate_limit",
635
- "min_difficulty": "sudo_set_min_difficulty",
636
- "max_difficulty": "sudo_set_max_difficulty",
637
- "weights_version": "sudo_set_weights_version_key",
638
- "weights_rate_limit": "sudo_set_weights_set_rate_limit",
639
- "max_weights_limit": "sudo_set_max_weight_limit",
640
- "immunity_period": "sudo_set_immunity_period",
641
- "min_allowed_weights": "sudo_set_min_allowed_weights",
642
- "activity_cutoff": "sudo_set_activity_cutoff",
643
- "network_registration_allowed": "sudo_set_network_registration_allowed",
644
- "network_pow_registration_allowed": "sudo_set_network_pow_registration_allowed",
645
- "min_burn": "sudo_set_min_burn",
646
- "max_burn": "sudo_set_max_burn",
647
- "adjustment_alpha": "sudo_set_adjustment_alpha",
648
- "rho": "sudo_set_rho",
649
- "kappa": "sudo_set_kappa",
650
- "difficulty": "sudo_set_difficulty",
651
- "bonds_moving_avg": "sudo_set_bonds_moving_average",
652
- "commit_reveal_period": "sudo_set_commit_reveal_weights_interval",
653
- "commit_reveal_weights_enabled": "sudo_set_commit_reveal_weights_enabled",
654
- "alpha_values": "sudo_set_alpha_values",
655
- "liquid_alpha_enabled": "sudo_set_liquid_alpha_enabled",
646
+ # btcli name: (subtensor method, root-only bool)
647
+ "rho": ("sudo_set_rho", False),
648
+ "kappa": ("sudo_set_kappa", False),
649
+ "immunity_period": ("sudo_set_immunity_period", False),
650
+ "min_allowed_weights": ("sudo_set_min_allowed_weights", False),
651
+ "max_weights_limit": ("sudo_set_max_weight_limit", False),
652
+ "tempo": ("sudo_set_tempo", True),
653
+ "min_difficulty": ("sudo_set_min_difficulty", False),
654
+ "max_difficulty": ("sudo_set_max_difficulty", False),
655
+ "weights_version": ("sudo_set_weights_version_key", False),
656
+ "weights_rate_limit": ("sudo_set_weights_set_rate_limit", False),
657
+ "adjustment_interval": ("sudo_set_adjustment_interval", True),
658
+ "activity_cutoff": ("sudo_set_activity_cutoff", False),
659
+ "target_regs_per_interval": ("sudo_set_target_registrations_per_interval", True),
660
+ "min_burn": ("sudo_set_min_burn", True),
661
+ "max_burn": ("sudo_set_max_burn", False),
662
+ "bonds_moving_avg": ("sudo_set_bonds_moving_average", False),
663
+ "max_regs_per_block": ("sudo_set_max_registrations_per_block", True),
664
+ "serving_rate_limit": ("sudo_set_serving_rate_limit", False),
665
+ "max_validators": ("sudo_set_max_allowed_validators", True),
666
+ "adjustment_alpha": ("sudo_set_adjustment_alpha", False),
667
+ "difficulty": ("sudo_set_difficulty", False),
668
+ "commit_reveal_period": (
669
+ "sudo_set_commit_reveal_weights_interval",
670
+ False,
671
+ ),
672
+ "commit_reveal_weights_enabled": ("sudo_set_commit_reveal_weights_enabled", False),
673
+ "alpha_values": ("sudo_set_alpha_values", False),
674
+ "liquid_alpha_enabled": ("sudo_set_liquid_alpha_enabled", False),
675
+ "network_registration_allowed": ("sudo_set_network_registration_allowed", False),
676
+ "network_pow_registration_allowed": (
677
+ "sudo_set_network_pow_registration_allowed",
678
+ False,
679
+ ),
656
680
  }
657
681
 
658
682
  # Help Panels for cli help
@@ -686,6 +710,7 @@ HELP_PANELS = {
686
710
  "INFO": "Subnet Information",
687
711
  "CREATION": "Subnet Creation & Management",
688
712
  "REGISTER": "Neuron Registration",
713
+ "IDENTITY": "Subnet Identity Management",
689
714
  },
690
715
  "WEIGHTS": {"COMMIT_REVEAL": "Commit / Reveal"},
691
716
  }
@@ -750,7 +750,9 @@ class DynamicInfo(InfoBase):
750
750
  )
751
751
  return alpha_returned, slippage, slippage_pct_float
752
752
 
753
- def alpha_to_tao_with_slippage(self, alpha: Balance) -> tuple[Balance, Balance]:
753
+ def alpha_to_tao_with_slippage(
754
+ self, alpha: Balance
755
+ ) -> tuple[Balance, Balance, float]:
754
756
  """
755
757
  Returns an estimate of how much TAO would a staker receive if they unstake their alpha using the current pool state.
756
758
  Args:
@@ -18,9 +18,7 @@ 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
- from bittensor_wallet.errors import KeyFileError
24
22
  from Crypto.Hash import keccak
25
23
  import numpy as np
26
24
  from rich.prompt import Confirm
@@ -39,6 +37,8 @@ from bittensor_cli.src.bittensor.utils import (
39
37
  get_human_readable,
40
38
  print_verbose,
41
39
  print_error,
40
+ unlock_key,
41
+ hex_to_bytes,
42
42
  )
43
43
 
44
44
  if typing.TYPE_CHECKING:
@@ -616,10 +616,7 @@ async def register_extrinsic(
616
616
  if not success:
617
617
  success, err_msg = (
618
618
  False,
619
- format_error_message(
620
- await response.error_message,
621
- substrate=subtensor.substrate,
622
- ),
619
+ format_error_message(await response.error_message),
623
620
  )
624
621
  # Look error here
625
622
  # https://github.com/opentensor/subtensor/blob/development/pallets/subtensor/src/errors.rs
@@ -697,11 +694,8 @@ async def burned_register_extrinsic(
697
694
  finalization/inclusion, the response is `True`.
698
695
  """
699
696
 
700
- try:
701
- wallet.unlock_coldkey()
702
- except KeyFileError:
703
- err_console.print("Error decrypting coldkey (possibly incorrect password)")
704
- return False
697
+ if not (unlock_status := unlock_key(wallet, print_out=False)).success:
698
+ return False, unlock_status.message
705
699
 
706
700
  with console.status(
707
701
  f":satellite: Checking Account on [bold]subnet:{netuid}[/bold]...",
@@ -796,7 +790,7 @@ async def run_faucet_extrinsic(
796
790
  tpb: int = 256,
797
791
  num_processes: Optional[int] = None,
798
792
  update_interval: Optional[int] = None,
799
- log_verbose: bool = False,
793
+ log_verbose: bool = True,
800
794
  max_successes: int = 3,
801
795
  ) -> tuple[bool, str]:
802
796
  r"""Runs a continual POW to get a faucet of TAO on the test net.
@@ -835,10 +829,8 @@ async def run_faucet_extrinsic(
835
829
  return False, "Requires torch"
836
830
 
837
831
  # Unlock coldkey
838
- try:
839
- wallet.unlock_coldkey()
840
- except KeyFileError:
841
- return False, "There was an error unlocking your coldkey"
832
+ if not (unlock_status := unlock_key(wallet, print_out=False)).success:
833
+ return False, unlock_status.message
842
834
 
843
835
  # Get previous balance.
844
836
  old_balance = await subtensor.get_balance(wallet.coldkeypub.ss58_address)
@@ -846,8 +838,12 @@ async def run_faucet_extrinsic(
846
838
  # Attempt rolling registration.
847
839
  attempts = 1
848
840
  successes = 1
841
+ pow_result: Optional[POWSolution]
849
842
  while True:
850
843
  try:
844
+ account_nonce = await subtensor.substrate.get_account_nonce(
845
+ wallet.coldkey.ss58_address
846
+ )
851
847
  pow_result = None
852
848
  while pow_result is None or await pow_result.is_stale(subtensor=subtensor):
853
849
  # Solve latest POW.
@@ -856,7 +852,7 @@ async def run_faucet_extrinsic(
856
852
  if prompt:
857
853
  err_console.print("CUDA is not available.")
858
854
  return False, "CUDA is not available."
859
- pow_result: Optional[POWSolution] = await create_pow(
855
+ pow_result = await create_pow(
860
856
  subtensor,
861
857
  wallet,
862
858
  -1,
@@ -869,7 +865,7 @@ async def run_faucet_extrinsic(
869
865
  log_verbose=log_verbose,
870
866
  )
871
867
  else:
872
- pow_result: Optional[POWSolution] = await create_pow(
868
+ pow_result = await create_pow(
873
869
  subtensor,
874
870
  wallet,
875
871
  -1,
@@ -889,7 +885,7 @@ async def run_faucet_extrinsic(
889
885
  },
890
886
  )
891
887
  extrinsic = await subtensor.substrate.create_signed_extrinsic(
892
- call=call, keypair=wallet.coldkey
888
+ call=call, keypair=wallet.coldkey, nonce=account_nonce
893
889
  )
894
890
  response = await subtensor.substrate.submit_extrinsic(
895
891
  extrinsic,
@@ -902,7 +898,7 @@ async def run_faucet_extrinsic(
902
898
  if not await response.is_success:
903
899
  err_console.print(
904
900
  f":cross_mark: [red]Failed[/red]: "
905
- f"{format_error_message(await response.error_message, subtensor.substrate)}"
901
+ f"{format_error_message(await response.error_message)}"
906
902
  )
907
903
  if attempts == max_allowed_attempts:
908
904
  raise MaxAttemptsException
@@ -974,7 +970,7 @@ async def _check_for_newest_block_and_update(
974
970
  block_number, difficulty, block_hash = await _get_block_with_retry(
975
971
  subtensor=subtensor, netuid=netuid
976
972
  )
977
- block_bytes = bytes.fromhex(block_hash[2:])
973
+ block_bytes = hex_to_bytes(block_hash)
978
974
 
979
975
  update_curr_block(
980
976
  curr_diff,
@@ -1027,6 +1023,9 @@ async def _block_solver(
1027
1023
  stop_event.clear()
1028
1024
 
1029
1025
  solution_queue = Queue()
1026
+ if cuda:
1027
+ num_processes = len(dev_id)
1028
+
1030
1029
  finished_queues = [Queue() for _ in range(num_processes)]
1031
1030
  check_block = Lock()
1032
1031
 
@@ -1036,7 +1035,6 @@ async def _block_solver(
1036
1035
 
1037
1036
  if cuda:
1038
1037
  # Create a worker per CUDA device
1039
- num_processes = len(dev_id)
1040
1038
  solvers = [
1041
1039
  _CUDASolver(
1042
1040
  i,
@@ -1079,7 +1077,7 @@ async def _block_solver(
1079
1077
  subtensor=subtensor, netuid=netuid
1080
1078
  )
1081
1079
 
1082
- block_bytes = bytes.fromhex(block_hash[2:])
1080
+ block_bytes = hex_to_bytes(block_hash)
1083
1081
  old_block_number = block_number
1084
1082
  # Set to current block
1085
1083
  _update_curr_block(
@@ -1354,11 +1352,9 @@ def _terminate_workers_and_wait_for_exit(
1354
1352
  worker.terminate()
1355
1353
 
1356
1354
 
1357
- # TODO verify this works with async
1358
- @backoff.on_exception(backoff.constant, Exception, interval=1, max_tries=3)
1359
1355
  async def _get_block_with_retry(
1360
1356
  subtensor: "SubtensorInterface", netuid: int
1361
- ) -> tuple[int, int, bytes]:
1357
+ ) -> tuple[int, int, str]:
1362
1358
  """
1363
1359
  Gets the current block number, difficulty, and block hash from the substrate node.
1364
1360
 
@@ -1370,10 +1366,9 @@ async def _get_block_with_retry(
1370
1366
  :raises Exception: If the block hash is None.
1371
1367
  :raises ValueError: If the difficulty is None.
1372
1368
  """
1373
- block_number = await subtensor.substrate.get_block_number(None)
1374
- block_hash = await subtensor.substrate.get_block_hash(
1375
- block_number
1376
- ) # TODO check if I need to do all this
1369
+ block = await subtensor.substrate.get_block()
1370
+ block_hash = block["header"]["hash"]
1371
+ block_number = block["header"]["number"]
1377
1372
  try:
1378
1373
  difficulty = (
1379
1374
  1_000_000
@@ -1746,10 +1741,7 @@ async def swap_hotkey_extrinsic(
1746
1741
  )
1747
1742
  return False
1748
1743
 
1749
- try:
1750
- wallet.unlock_coldkey()
1751
- except KeyFileError:
1752
- err_console.print("Error decrypting coldkey (possibly incorrect password)")
1744
+ if not unlock_key(wallet).success:
1753
1745
  return False
1754
1746
 
1755
1747
  if prompt:
@@ -21,7 +21,6 @@ import time
21
21
  from typing import Union, List, TYPE_CHECKING
22
22
 
23
23
  from bittensor_wallet import Wallet, Keypair
24
- from bittensor_wallet.errors import KeyFileError
25
24
  import numpy as np
26
25
  from numpy.typing import NDArray
27
26
  from rich.prompt import Confirm
@@ -37,6 +36,7 @@ from bittensor_cli.src.bittensor.utils import (
37
36
  u16_normalized_float,
38
37
  print_verbose,
39
38
  format_error_message,
39
+ unlock_key,
40
40
  )
41
41
 
42
42
  if TYPE_CHECKING:
@@ -306,10 +306,7 @@ async def root_register_extrinsic(
306
306
  the response is `True`.
307
307
  """
308
308
 
309
- try:
310
- wallet.unlock_coldkey()
311
- except KeyFileError:
312
- err_console.print("Error decrypting coldkey (possibly incorrect password)")
309
+ if not unlock_key(wallet).success:
313
310
  return False
314
311
 
315
312
  print_verbose(f"Checking if hotkey ({wallet.hotkey_str}) is registered on root")
@@ -427,10 +424,7 @@ async def set_root_weights_extrinsic(
427
424
  err_console.print("Your hotkey is not registered to the root network")
428
425
  return False
429
426
 
430
- try:
431
- wallet.unlock_coldkey()
432
- except KeyFileError:
433
- err_console.print("Error decrypting coldkey (possibly incorrect password)")
427
+ if not unlock_key(wallet).success:
434
428
  return False
435
429
 
436
430
  # First convert types.
@@ -492,11 +486,11 @@ async def set_root_weights_extrinsic(
492
486
  console.print(":white_heavy_check_mark: [green]Finalized[/green]")
493
487
  return True
494
488
  else:
495
- fmt_err = format_error_message(error_message, subtensor.substrate)
489
+ fmt_err = format_error_message(error_message)
496
490
  err_console.print(f":cross_mark: [red]Failed[/red]: {fmt_err}")
497
491
  return False
498
492
 
499
493
  except SubstrateRequestException as e:
500
- fmt_err = format_error_message(e, subtensor.substrate)
494
+ fmt_err = format_error_message(e)
501
495
  err_console.print(":cross_mark: [red]Failed[/red]: error:{}".format(fmt_err))
502
496
  return False
@@ -1,7 +1,6 @@
1
1
  import asyncio
2
2
 
3
3
  from bittensor_wallet import Wallet
4
- from bittensor_wallet.errors import KeyFileError
5
4
  from rich.prompt import Confirm
6
5
  from async_substrate_interface.errors import SubstrateRequestException
7
6
 
@@ -15,6 +14,8 @@ from bittensor_cli.src.bittensor.utils import (
15
14
  format_error_message,
16
15
  get_explorer_url_for_network,
17
16
  is_valid_bittensor_address_or_public_key,
17
+ print_error,
18
+ unlock_key,
18
19
  )
19
20
 
20
21
 
@@ -23,6 +24,7 @@ async def transfer_extrinsic(
23
24
  wallet: Wallet,
24
25
  destination: str,
25
26
  amount: Balance,
27
+ transfer_all: bool = False,
26
28
  wait_for_inclusion: bool = True,
27
29
  wait_for_finalization: bool = False,
28
30
  keep_alive: bool = True,
@@ -34,6 +36,7 @@ async def transfer_extrinsic(
34
36
  :param wallet: Bittensor wallet object to make transfer from.
35
37
  :param destination: Destination public key address (ss58_address or ed25519) of recipient.
36
38
  :param amount: Amount to stake as Bittensor balance.
39
+ :param transfer_all: Whether to transfer all funds from this wallet to the destination address.
37
40
  :param wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`,
38
41
  or returns `False` if the extrinsic fails to enter the block within the timeout.
39
42
  :param wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning
@@ -63,9 +66,9 @@ async def transfer_extrinsic(
63
66
  except SubstrateRequestException as e:
64
67
  payment_info = {"partial_fee": int(2e7)} # assume 0.02 Tao
65
68
  err_console.print(
66
- f":cross_mark: [red]Failed to get payment info[/red]:\n"
67
- f" [bold white]{format_error_message(e)}[/bold white]\n"
68
- f" Defaulting to default transfer fee: {payment_info['partial_fee']}"
69
+ f":cross_mark: [red]Failed to get payment info[/red]:[bold white]\n"
70
+ f" {format_error_message(e)}[/bold white]\n"
71
+ f" Defaulting to default transfer fee: {payment_info['partialFee']}"
69
72
  )
70
73
 
71
74
  return Balance.from_rao(payment_info["partial_fee"])
@@ -98,11 +101,7 @@ async def transfer_extrinsic(
98
101
  block_hash_ = response.block_hash
99
102
  return True, block_hash_, ""
100
103
  else:
101
- return (
102
- False,
103
- "",
104
- format_error_message(await response.error_message, subtensor.substrate),
105
- )
104
+ return False, "", format_error_message(await response.error_message)
106
105
 
107
106
  # Validate destination address.
108
107
  if not is_valid_bittensor_address_or_public_key(destination):
@@ -112,10 +111,7 @@ async def transfer_extrinsic(
112
111
  return False
113
112
  console.print(f"[dark_orange]Initiating transfer on network: {subtensor.network}")
114
113
  # Unlock wallet coldkey.
115
- try:
116
- wallet.unlock_coldkey()
117
- except KeyFileError:
118
- err_console.print("Error decrypting coldkey (possibly incorrect password)")
114
+ if not unlock_key(wallet).success:
119
115
  return False
120
116
 
121
117
  # Check balance.
@@ -139,6 +135,12 @@ async def transfer_extrinsic(
139
135
  existential_deposit = Balance(0)
140
136
 
141
137
  # Check if we have enough balance.
138
+ if transfer_all is True:
139
+ amount = account_balance - fee - existential_deposit
140
+ if amount < Balance(0):
141
+ print_error("Not enough balance to transfer")
142
+ return False
143
+
142
144
  if account_balance < (amount + fee + existential_deposit):
143
145
  err_console.print(
144
146
  ":cross_mark: [bold red]Not enough balance[/bold red]:\n\n"
@@ -402,7 +402,7 @@ class SubtensorInterface:
402
402
  netuids: Optional[list[int]] = None,
403
403
  block_hash: Optional[str] = None,
404
404
  reuse_block: bool = False,
405
- ) -> dict[str, dict[int, "Balance"]]:
405
+ ) -> dict[str, dict[int, Balance]]:
406
406
  """
407
407
  Returns the total stake held on a hotkey.
408
408
 
@@ -1064,11 +1064,9 @@ class SubtensorInterface:
1064
1064
  if await response.is_success:
1065
1065
  return True, ""
1066
1066
  else:
1067
- return False, format_error_message(
1068
- await response.error_message, substrate=self.substrate
1069
- )
1067
+ return False, format_error_message(await response.error_message)
1070
1068
  except SubstrateRequestException as e:
1071
- return False, format_error_message(e, substrate=self.substrate)
1069
+ return False, format_error_message(e)
1072
1070
 
1073
1071
  async def get_children(self, hotkey, netuid) -> tuple[bool, list, str]:
1074
1072
  """
@@ -1098,7 +1096,7 @@ class SubtensorInterface:
1098
1096
  else:
1099
1097
  return True, [], ""
1100
1098
  except SubstrateRequestException as e:
1101
- return False, [], format_error_message(e, self.substrate)
1099
+ return False, [], format_error_message(e)
1102
1100
 
1103
1101
  async def get_subnet_hyperparameters(
1104
1102
  self, netuid: int, block_hash: Optional[str] = None