bittensor-cli 9.20.0__tar.gz → 9.20.1__tar.gz

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.
Files changed (67) hide show
  1. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/PKG-INFO +2 -2
  2. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/cli.py +48 -32
  3. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/__init__.py +0 -43
  4. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/registration.py +5 -3
  5. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/transfer.py +2 -2
  6. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/subtensor_interface.py +32 -51
  7. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/utils.py +18 -0
  8. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/add.py +9 -4
  9. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/auto_staking.py +6 -30
  10. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/list.py +14 -20
  11. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/move.py +71 -56
  12. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/remove.py +7 -26
  13. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/wizard.py +6 -15
  14. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/subnets/subnets.py +3 -28
  15. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/sudo.py +20 -22
  16. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/view.py +17 -26
  17. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/wallets.py +223 -115
  18. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/pyproject.toml +2 -2
  19. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/README.md +0 -0
  20. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/__init__.py +0 -0
  21. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/doc_generation_helper.py +0 -0
  22. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/__init__.py +0 -0
  23. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/balances.py +0 -0
  24. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/chain_data.py +0 -0
  25. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/__init__.py +0 -0
  26. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/mev_shield.py +0 -0
  27. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/root.py +0 -0
  28. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/extrinsics/serving.py +0 -0
  29. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/minigraph.py +0 -0
  30. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/networking.py +0 -0
  31. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/main-filters.j2 +0 -0
  32. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/main-header.j2 +0 -0
  33. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/neuron-details.j2 +0 -0
  34. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/price-multi.j2 +0 -0
  35. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/price-single.j2 +0 -0
  36. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/subnet-details-header.j2 +0 -0
  37. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/subnet-details.j2 +0 -0
  38. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/subnet-metrics.j2 +0 -0
  39. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/subnets-table.j2 +0 -0
  40. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/table.j2 +0 -0
  41. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/view.css +0 -0
  42. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/view.j2 +0 -0
  43. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/bittensor/templates/view.js +0 -0
  44. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/__init__.py +0 -0
  45. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/axon/__init__.py +0 -0
  46. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/axon/axon.py +0 -0
  47. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/__init__.py +0 -0
  48. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/contribute.py +0 -0
  49. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/contributors.py +0 -0
  50. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/create.py +0 -0
  51. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/dissolve.py +0 -0
  52. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/refund.py +0 -0
  53. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/update.py +0 -0
  54. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/utils.py +0 -0
  55. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/crowd/view.py +0 -0
  56. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/liquidity/__init__.py +0 -0
  57. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/liquidity/liquidity.py +0 -0
  58. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/liquidity/utils.py +0 -0
  59. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/proxy.py +0 -0
  60. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/__init__.py +0 -0
  61. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/children_hotkeys.py +0 -0
  62. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/stake/claim.py +0 -0
  63. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/subnets/__init__.py +0 -0
  64. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/subnets/mechanisms.py +0 -0
  65. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/subnets/price.py +0 -0
  66. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/src/commands/weights.py +0 -0
  67. {bittensor_cli-9.20.0 → bittensor_cli-9.20.1}/bittensor_cli/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bittensor-cli
3
- Version: 9.20.0
3
+ Version: 9.20.1
4
4
  Summary: Bittensor CLI
5
5
  Author: bittensor.com
6
6
  Requires-Python: >=3.10
@@ -19,7 +19,7 @@ Classifier: Topic :: Scientific/Engineering :: Mathematics
19
19
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
20
  Classifier: Topic :: Utilities
21
21
  Requires-Dist: wheel
22
- Requires-Dist: async-substrate-interface>=1.6.2
22
+ Requires-Dist: async-substrate-interface>=1.6.2,<2.0.0
23
23
  Requires-Dist: aiohttp~=3.13
24
24
  Requires-Dist: backoff~=2.2.1
25
25
  Requires-Dist: bittensor-drand>=1.3.0
@@ -2913,7 +2913,17 @@ class CLIManager:
2913
2913
  ),
2914
2914
  wallet_name: str = Options.wallet_name,
2915
2915
  wallet_path: str = Options.wallet_path,
2916
- wallet_hotkey: str = Options.wallet_hotkey,
2916
+ wallet_hotkey: str = Options.edit_help(
2917
+ "wallet_hotkey",
2918
+ help_text="Deprecated option, "
2919
+ "preserved for backwards compatibility to not break workflows which utilise it.",
2920
+ ),
2921
+ ss58_address: Optional[str] = typer.Option(
2922
+ None,
2923
+ "--ss58-address",
2924
+ "--ss58",
2925
+ help="SS58 address of the coldkey to inspect. Allows inspecting any coldkey without a local wallet file.",
2926
+ ),
2917
2927
  network: Optional[list[str]] = Options.network,
2918
2928
  netuids: str = Options.netuids,
2919
2929
  quiet: bool = Options.quiet,
@@ -2921,9 +2931,11 @@ class CLIManager:
2921
2931
  json_output: bool = Options.json_output,
2922
2932
  ):
2923
2933
  """
2924
- Displays the details of the user's wallet pairs (coldkey, hotkey) on the Bittensor network.
2934
+ Displays the details of the user's wallet (coldkey) on the Bittensor network.
2925
2935
 
2926
- The output is presented as a table with the below columns:
2936
+ The output is presented as two separate tables:
2937
+
2938
+ [bold]Coldkey Overview[/bold]:
2927
2939
 
2928
2940
  - [blue bold]Coldkey[/blue bold]: The coldkey associated with the user's wallet.
2929
2941
 
@@ -2931,14 +2943,22 @@ class CLIManager:
2931
2943
 
2932
2944
  - [blue bold]Delegate[/blue bold]: The name of the delegate to which the coldkey has staked TAO.
2933
2945
 
2934
- - [blue bold]Stake[/blue bold]: The amount of stake held by both the coldkey and hotkey.
2946
+ - [blue bold]Stake[/blue bold]: The amount of stake delegated.
2935
2947
 
2936
- - [blue bold]Emission[/blue bold]: The emission or rewards earned from staking.
2948
+ - [blue bold]Emission[/blue bold]: The daily emission earned from delegation.
2949
+
2950
+ [bold]Hotkey Details[/bold]:
2937
2951
 
2938
- - [blue bold]Netuid[/blue bold]: The network unique identifier of the subnet where the hotkey is active (i.e., validating).
2952
+ - [blue bold]Coldkey[/blue bold]: The parent coldkey of the hotkey.
2953
+
2954
+ - [blue bold]Netuid[/blue bold]: The network unique identifier of the subnet where the hotkey is active.
2939
2955
 
2940
2956
  - [blue bold]Hotkey[/blue bold]: The hotkey associated with the neuron on the network.
2941
2957
 
2958
+ - [blue bold]Stake[/blue bold]: The amount of stake held by the hotkey.
2959
+
2960
+ - [blue bold]Emission[/blue bold]: The emission or rewards earned from staking.
2961
+
2942
2962
  USAGE
2943
2963
 
2944
2964
  This command can be used to inspect a single wallet or all the wallets located at a specified path. It is useful for a comprehensive overview of a user's participation and performance in the Bittensor network.
@@ -2949,10 +2969,10 @@ class CLIManager:
2949
2969
 
2950
2970
  [green]$[/green] btcli wallet inspect --all -n 1 -n 2 -n 3
2951
2971
 
2972
+ [green]$[/green] btcli wallet inspect --ss58-address 5FHneW46...
2973
+
2952
2974
  [bold]Note[/bold]: The `inspect` command is for displaying information only and does not perform any transactions or state changes on the blockchain. It is intended to be used with Bittensor CLI and not as a standalone function in user code.
2953
2975
  """
2954
- print_error("This command is disabled on the 'rao' network.")
2955
- raise typer.Exit()
2956
2976
  self.verbosity_handler(quiet, verbose, json_output, False)
2957
2977
 
2958
2978
  if netuids:
@@ -2962,18 +2982,28 @@ class CLIManager:
2962
2982
  "Netuids must be a comma-separated list of ints, e.g., `--netuids 1,2,3,4`.",
2963
2983
  )
2964
2984
 
2985
+ if ss58_address:
2986
+ return self._run_command(
2987
+ wallets.inspect(
2988
+ None,
2989
+ self.initialize_chain(network),
2990
+ netuids_filter=netuids,
2991
+ all_wallets=False,
2992
+ ss58_address=ss58_address,
2993
+ )
2994
+ )
2995
+
2965
2996
  # if all-wallets is entered, ask for path
2966
2997
  ask_for = [WO.NAME, WO.PATH] if not all_wallets else [WO.PATH]
2967
2998
  validate = WV.WALLET if not all_wallets else WV.NONE
2968
2999
  wallet = self.wallet_ask(
2969
- wallet_name, wallet_path, wallet_hotkey, ask_for=ask_for, validate=validate
3000
+ wallet_name, wallet_path, None, ask_for=ask_for, validate=validate
2970
3001
  )
2971
3002
 
2972
- self.initialize_chain(network)
2973
3003
  return self._run_command(
2974
3004
  wallets.inspect(
2975
3005
  wallet,
2976
- self.subtensor,
3006
+ self.initialize_chain(network),
2977
3007
  netuids_filter=netuids,
2978
3008
  all_wallets=all_wallets,
2979
3009
  )
@@ -5482,33 +5512,20 @@ class CLIManager:
5482
5512
  console.print(
5483
5513
  "[dim]This command moves stake from one hotkey to another hotkey while keeping the same coldkey.[/dim]"
5484
5514
  )
5515
+ interactive_selection = False
5485
5516
  if not destination_hotkey:
5486
5517
  dest_wallet_or_ss58 = Prompt.ask(
5487
- "Enter the [blue]destination wallet[/blue] where destination hotkey is located or "
5488
- "[blue]ss58 address[/blue]"
5518
+ "Enter the [blue]ss58 address[/blue] of the hotkey to move the stake to, leave blank for other options"
5489
5519
  )
5490
5520
  if is_valid_ss58_address(dest_wallet_or_ss58):
5491
5521
  destination_hotkey = dest_wallet_or_ss58
5522
+ elif dest_wallet_or_ss58.strip() == "":
5523
+ interactive_selection = True
5492
5524
  else:
5493
- dest_wallet = self.wallet_ask(
5494
- dest_wallet_or_ss58,
5495
- wallet_path,
5496
- None,
5497
- ask_for=[WO.NAME, WO.PATH],
5498
- validate=WV.WALLET,
5499
- )
5500
- destination_hotkey = Prompt.ask(
5501
- "Enter the [blue]destination hotkey[/blue] name",
5502
- default=dest_wallet.hotkey_str,
5503
- )
5504
- destination_wallet = self.wallet_ask(
5505
- dest_wallet_or_ss58,
5506
- wallet_path,
5507
- destination_hotkey,
5508
- ask_for=[WO.NAME, WO.PATH, WO.HOTKEY],
5509
- validate=WV.WALLET_AND_HOTKEY,
5525
+ print_error(
5526
+ "Invalid destination hotkey ss58 address. Please enter a valid ss58 address."
5510
5527
  )
5511
- destination_hotkey = get_hotkey_pub_ss58(destination_wallet)
5528
+ raise typer.Exit()
5512
5529
  else:
5513
5530
  if is_valid_ss58_address(destination_hotkey):
5514
5531
  destination_hotkey = destination_hotkey
@@ -5527,7 +5544,6 @@ class CLIManager:
5527
5544
  wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH]
5528
5545
  )
5529
5546
 
5530
- interactive_selection = False
5531
5547
  if not wallet_hotkey:
5532
5548
  origin_hotkey = Prompt.ask(
5533
5549
  "Enter the [blue]origin hotkey[/blue] name or "
@@ -1,6 +1,4 @@
1
1
  from enum import Enum
2
- from dataclasses import dataclass
3
- from typing import Any, Optional
4
2
 
5
3
 
6
4
  class Constants:
@@ -37,47 +35,6 @@ class Constants:
37
35
  delegates_detail_url = "https://raw.githubusercontent.com/opentensor/bittensor-delegates/main/public/delegates.json"
38
36
 
39
37
 
40
- @dataclass
41
- class DelegatesDetails:
42
- display: str
43
- additional: list[tuple[str, str]]
44
- web: str
45
- legal: Optional[str] = None
46
- riot: Optional[str] = None
47
- email: Optional[str] = None
48
- pgp_fingerprint: Optional[str] = None
49
- image: Optional[str] = None
50
- twitter: Optional[str] = None
51
-
52
- @classmethod
53
- def from_chain_data(cls, data: dict[str, Any]) -> "DelegatesDetails":
54
- def decode(key: str, default=""):
55
- try:
56
- if isinstance(data.get(key), dict):
57
- value = next(data.get(key).values())
58
- return bytes(value[0]).decode("utf-8")
59
- elif isinstance(data.get(key), int):
60
- return data.get(key)
61
- elif isinstance(data.get(key), tuple):
62
- return bytes(data.get(key)[0]).decode("utf-8")
63
- else:
64
- return default
65
- except (UnicodeDecodeError, TypeError):
66
- return default
67
-
68
- return cls(
69
- display=decode("display"),
70
- additional=decode("additional", []),
71
- web=decode("web"),
72
- legal=decode("legal"),
73
- riot=decode("riot"),
74
- email=decode("email"),
75
- pgp_fingerprint=decode("pgp_fingerprint", None),
76
- image=decode("image"),
77
- twitter=decode("twitter"),
78
- )
79
-
80
-
81
38
  class Defaults:
82
39
  netuid = 1
83
40
  rate_tolerance = 0.005
@@ -708,11 +708,13 @@ async def burned_register_extrinsic(
708
708
  f":satellite: Checking Account on [bold]subnet:{netuid}[/bold]...",
709
709
  spinner="aesthetic",
710
710
  ) as status:
711
+ block_hash = await subtensor.substrate.get_chain_head()
711
712
  my_uid = await subtensor.query(
712
- "SubtensorModule", "Uids", [netuid, get_hotkey_pub_ss58(wallet)]
713
+ module="SubtensorModule",
714
+ storage_function="Uids",
715
+ params=[netuid, get_hotkey_pub_ss58(wallet)],
716
+ block_hash=block_hash,
713
717
  )
714
- block_hash = await subtensor.substrate.get_chain_head()
715
-
716
718
  print_verbose("Checking if already registered", status)
717
719
  neuron = await subtensor.neuron_for_uid(
718
720
  uid=my_uid, netuid=netuid, block_hash=block_hash
@@ -156,10 +156,10 @@ async def transfer_extrinsic(
156
156
  f" would bring you under the existential deposit: [bright_cyan]{existential_deposit}[/bright_cyan].\n"
157
157
  )
158
158
  return False, None
159
- if account_balance < amount and allow_death:
159
+ if proxy_balance < amount and allow_death:
160
160
  print_error(
161
161
  "[bold red]Not enough balance[/bold red]:\n\n"
162
- f" balance: [bright_red]{account_balance}[/bright_red]\n"
162
+ f" balance: [bright_red]{proxy_balance}[/bright_red]\n"
163
163
  f" amount: [bright_red]{amount}[/bright_red]\n"
164
164
  )
165
165
  return False, None
@@ -32,7 +32,6 @@ from bittensor_cli.src.bittensor.chain_data import (
32
32
  CrowdloanData,
33
33
  ColdkeySwapAnnouncementInfo,
34
34
  )
35
- from bittensor_cli.src import DelegatesDetails
36
35
  from bittensor_cli.src.bittensor.balances import Balance, fixed_to_float
37
36
  from bittensor_cli.src import Constants, defaults, TYPE_REGISTRY
38
37
  from bittensor_cli.src.bittensor.extrinsics.mev_shield import encrypt_extrinsic
@@ -40,7 +39,6 @@ from bittensor_cli.src.bittensor.utils import (
40
39
  format_error_message,
41
40
  console,
42
41
  print_error,
43
- decode_hex_identity_dict,
44
42
  validate_chain_endpoint,
45
43
  u16_normalized_float,
46
44
  MEV_SHIELD_PUBLIC_KEY_SIZE,
@@ -229,9 +227,11 @@ class SubtensorInterface:
229
227
  storage_function="NetworksAdded",
230
228
  block_hash=block_hash,
231
229
  reuse_block_hash=True,
230
+ fully_exhaust=True,
231
+ page_size=200,
232
232
  )
233
233
  res = []
234
- async for netuid, exists in result:
234
+ for netuid, exists in result.records:
235
235
  if exists.value:
236
236
  res.append(netuid)
237
237
  return res
@@ -283,14 +283,14 @@ class SubtensorInterface:
283
283
  params=[coldkey_ss58],
284
284
  block_hash=block_hash,
285
285
  reuse_block_hash=reuse_block,
286
+ fully_exhaust=True,
287
+ page_size=200,
286
288
  )
287
-
288
289
  destinations: dict[int, str] = {}
289
- async for netuid, destination in query:
290
+ for netuid, destination in query.records:
290
291
  hotkey_ss58 = decode_account_id(destination.value[0])
291
292
  if hotkey_ss58:
292
293
  destinations[int(netuid)] = hotkey_ss58
293
-
294
294
  return destinations
295
295
 
296
296
  async def get_stake_for_coldkey_and_hotkey(
@@ -573,9 +573,11 @@ class SubtensorInterface:
573
573
  params=[hotkey_ss58],
574
574
  block_hash=block_hash,
575
575
  reuse_block_hash=reuse_block,
576
+ fully_exhaust=True,
577
+ page_size=200,
576
578
  )
577
579
  res = []
578
- async for record in result:
580
+ for record in result.records:
579
581
  if record[1].value:
580
582
  res.append(record[0])
581
583
  return res
@@ -1449,9 +1451,11 @@ class SubtensorInterface:
1449
1451
  storage_function="MechanismCountCurrent",
1450
1452
  params=[],
1451
1453
  block_hash=block_hash,
1454
+ fully_exhaust=True,
1455
+ page_size=200,
1452
1456
  )
1453
1457
  res = {}
1454
- async for netuid, count in results:
1458
+ for netuid, count in results.records:
1455
1459
  res[int(netuid)] = int(count.value)
1456
1460
  return res
1457
1461
 
@@ -1512,39 +1516,6 @@ class SubtensorInterface:
1512
1516
  else:
1513
1517
  return ProposalVoteData(vote_data)
1514
1518
 
1515
- async def get_delegate_identities(
1516
- self, block_hash: Optional[str] = None
1517
- ) -> dict[str, DelegatesDetails]:
1518
- """
1519
- Fetches delegates identities from the chain and GitHub. Preference is given to chain data, and missing info
1520
- is filled-in by the info from GitHub. At some point, we want to totally move away from fetching this info
1521
- from GitHub, but chain data is still limited in that regard.
1522
-
1523
- :param block_hash: the hash of the blockchain block for the query
1524
-
1525
- :return: {ss58: DelegatesDetails, ...}
1526
-
1527
- """
1528
- identities_info = await self.substrate.query_map(
1529
- module="Registry",
1530
- storage_function="IdentityOf",
1531
- block_hash=block_hash,
1532
- )
1533
-
1534
- all_delegates_details = {}
1535
- async for ss58_address, identity in identities_info:
1536
- all_delegates_details.update(
1537
- {
1538
- decode_account_id(
1539
- ss58_address[0]
1540
- ): DelegatesDetails.from_chain_data(
1541
- decode_hex_identity_dict(identity.value["info"])
1542
- )
1543
- }
1544
- )
1545
-
1546
- return all_delegates_details
1547
-
1548
1519
  async def get_mechagraph_info(
1549
1520
  self, netuid: int, mech_id: int, block_hash: Optional[str] = None
1550
1521
  ) -> Optional[MetagraphInfo]:
@@ -1868,10 +1839,12 @@ class SubtensorInterface:
1868
1839
  storage_function="ColdkeySwapAnnouncements",
1869
1840
  block_hash=block_hash,
1870
1841
  reuse_block_hash=reuse_block,
1842
+ fully_exhaust=True,
1843
+ page_size=200,
1871
1844
  )
1872
1845
 
1873
1846
  announcements = []
1874
- async for ss58, data in result:
1847
+ for ss58, data in result.records:
1875
1848
  coldkey = decode_account_id(ss58)
1876
1849
  announcements.append(
1877
1850
  ColdkeySwapAnnouncementInfo._fix_decoded(coldkey, data)
@@ -1926,10 +1899,12 @@ class SubtensorInterface:
1926
1899
  storage_function="ColdkeySwapDisputes",
1927
1900
  block_hash=block_hash,
1928
1901
  reuse_block_hash=reuse_block,
1902
+ fully_exhaust=True,
1903
+ page_size=200,
1929
1904
  )
1930
1905
 
1931
1906
  disputes: list[tuple[str, int]] = []
1932
- async for ss58, data in result:
1907
+ for ss58, data in result.records:
1933
1908
  coldkey = decode_account_id(ss58)
1934
1909
  disputes.append((coldkey, data.value))
1935
1910
  return disputes
@@ -1984,7 +1959,7 @@ class SubtensorInterface:
1984
1959
  fully_exhaust=True,
1985
1960
  )
1986
1961
  crowdloans = {}
1987
- async for fund_id, fund_info in crowdloans_data:
1962
+ for fund_id, fund_info in crowdloans_data.records:
1988
1963
  decoded_call = await self._decode_inline_call(
1989
1964
  fund_info["call"],
1990
1965
  block_hash=block_hash,
@@ -2085,7 +2060,7 @@ class SubtensorInterface:
2085
2060
  )
2086
2061
 
2087
2062
  contributor_contributions = {}
2088
- async for contributor_key, contribution_amount in contributors_data:
2063
+ for contributor_key, contribution_amount in contributors_data.records:
2089
2064
  try:
2090
2065
  contributor_address = decode_account_id(contributor_key[0])
2091
2066
  contribution_balance = Balance.from_rao(contribution_amount.value)
@@ -2239,10 +2214,12 @@ class SubtensorInterface:
2239
2214
  params=[],
2240
2215
  block_hash=block_hash,
2241
2216
  reuse_block_hash=reuse_block,
2217
+ fully_exhaust=True,
2218
+ page_size=1_000,
2242
2219
  )
2243
2220
 
2244
2221
  root_claim_types = {}
2245
- async for coldkey, claim_type_data in result:
2222
+ for coldkey, claim_type_data in result.records:
2246
2223
  coldkey_ss58 = decode_account_id(coldkey[0])
2247
2224
 
2248
2225
  claim_type_key = next(iter(claim_type_data.value.keys()))
@@ -2338,9 +2315,11 @@ class SubtensorInterface:
2338
2315
  params=[hotkey_ss58, coldkey_ss58],
2339
2316
  block_hash=block_hash,
2340
2317
  reuse_block_hash=reuse_block,
2318
+ fully_exhaust=True,
2319
+ page_size=200,
2341
2320
  )
2342
2321
  total_claimed = {}
2343
- async for netuid, claimed in query:
2322
+ for netuid, claimed in query.records:
2344
2323
  total_claimed[netuid] = Balance.from_rao(claimed.value).set_unit(
2345
2324
  netuid=netuid
2346
2325
  )
@@ -2579,7 +2558,7 @@ class SubtensorInterface:
2579
2558
  return Balance.from_rao(int(current_price * 1e9))
2580
2559
 
2581
2560
  async def get_subnet_prices(
2582
- self, block_hash: Optional[str] = None, page_size: int = 100
2561
+ self, block_hash: Optional[str] = None, page_size: int = 200
2583
2562
  ) -> dict[int, Balance]:
2584
2563
  """
2585
2564
  Gets the current Alpha prices in TAO for all subnets.
@@ -2594,10 +2573,11 @@ class SubtensorInterface:
2594
2573
  storage_function="AlphaSqrtPrice",
2595
2574
  page_size=page_size,
2596
2575
  block_hash=block_hash,
2576
+ fully_exhaust=True,
2597
2577
  )
2598
2578
 
2599
2579
  map_ = {}
2600
- async for netuid_, current_sqrt_price in query:
2580
+ for netuid_, current_sqrt_price in query.records:
2601
2581
  current_sqrt_price_ = fixed_to_float(current_sqrt_price.value)
2602
2582
  current_price = current_sqrt_price_**2
2603
2583
  map_[netuid_] = Balance.from_rao(int(current_price * 1e9))
@@ -2607,7 +2587,7 @@ class SubtensorInterface:
2607
2587
  async def get_all_subnet_ema_tao_inflow(
2608
2588
  self,
2609
2589
  block_hash: Optional[str] = None,
2610
- page_size: int = 100,
2590
+ page_size: int = 200,
2611
2591
  ) -> dict[int, Balance]:
2612
2592
  """
2613
2593
  Query EMA TAO inflow for all subnets.
@@ -2627,9 +2607,10 @@ class SubtensorInterface:
2627
2607
  storage_function="SubnetEmaTaoFlow",
2628
2608
  page_size=page_size,
2629
2609
  block_hash=block_hash,
2610
+ fully_exhaust=True,
2630
2611
  )
2631
2612
  ema_map = {}
2632
- async for netuid, value in query:
2613
+ for netuid, value in query.records:
2633
2614
  if not value:
2634
2615
  ema_map[netuid] = Balance.from_rao(0)
2635
2616
  else:
@@ -147,6 +147,24 @@ def create_table(*columns, title: str = "", **overrides) -> Table:
147
147
  return Table(*columns, **config)
148
148
 
149
149
 
150
+ def get_hotkey_identity_name(
151
+ identities: dict[str, Any], hotkey_ss58: str
152
+ ) -> Optional[str]:
153
+ """Return a hotkey display name from the V2 identity map, if present."""
154
+ hotkey_identity = identities.get("hotkeys", {}).get(hotkey_ss58, {})
155
+ identity_data = hotkey_identity.get("identity", {})
156
+ return identity_data.get("name") or identity_data.get("display") or None
157
+
158
+
159
+ def get_coldkey_identity_name(
160
+ identities: dict[str, Any], coldkey_ss58: str
161
+ ) -> Optional[str]:
162
+ """Return a coldkey display name from the V2 identity map, if present."""
163
+ coldkey_identity = identities.get("coldkeys", {}).get(coldkey_ss58, {})
164
+ identity_data = coldkey_identity.get("identity", {})
165
+ return identity_data.get("name") or identity_data.get("display") or None
166
+
167
+
150
168
  jinja_env = Environment(
151
169
  loader=PackageLoader("bittensor_cli", "src/bittensor/templates"),
152
170
  autoescape=select_autoescape(),
@@ -391,14 +391,14 @@ async def stake_add(
391
391
 
392
392
  # Temporary workaround - calculations without slippage
393
393
  current_price_float = float(subnet_info.price.tao)
394
- rate = 1.0 / current_price_float
394
+ rate = _safe_inverse_rate(current_price_float)
395
395
 
396
396
  # If we are staking safe, add price tolerance
397
397
  if safe_staking:
398
398
  if subnet_info.is_dynamic:
399
399
  price_with_tolerance = current_price_float * (1 + rate_tolerance)
400
- _rate_with_tolerance = (
401
- 1.0 / price_with_tolerance
400
+ _rate_with_tolerance = _safe_inverse_rate(
401
+ price_with_tolerance
402
402
  ) # Rate only for display
403
403
  rate_with_tolerance = f"{_rate_with_tolerance:.4f}"
404
404
  price_with_tolerance = Balance.from_tao(
@@ -849,6 +849,11 @@ The columns are as follows:
849
849
  console.print(base_description + (safe_staking_description if safe_staking else ""))
850
850
 
851
851
 
852
+ def _safe_inverse_rate(value: float) -> float:
853
+ """Returns the inverse of a positive rate, otherwise zero."""
854
+ return 1.0 / value if value > 0 else 0.0
855
+
856
+
852
857
  def _calculate_slippage(
853
858
  subnet_info, amount: Balance, stake_fee: Balance
854
859
  ) -> tuple[Balance, str, float, str]:
@@ -882,7 +887,7 @@ def _calculate_slippage(
882
887
  total_slippage = ideal_amount - received_amount
883
888
  slippage_pct_float = 100 * (total_slippage.tao / ideal_amount.tao)
884
889
  slippage_str = f"{slippage_pct_float:.4f} %"
885
- rate = f"{(1 / subnet_info.price.tao or 1):.4f}"
890
+ rate = f"{_safe_inverse_rate(float(subnet_info.price.tao)):.4f}"
886
891
  else:
887
892
  # TODO: Fix this. Slippage is always zero for static networks.
888
893
  slippage_pct_float = (
@@ -17,6 +17,8 @@ from bittensor_cli.src.bittensor.utils import (
17
17
  print_error,
18
18
  unlock_key,
19
19
  print_extrinsic_id,
20
+ get_hotkey_identity_name,
21
+ get_coldkey_identity_name,
20
22
  )
21
23
 
22
24
  if TYPE_CHECKING:
@@ -45,7 +47,6 @@ async def show_auto_stake_destinations(
45
47
  subnet_info,
46
48
  auto_destinations,
47
49
  identities,
48
- delegate_identities,
49
50
  ) = await asyncio.gather(
50
51
  subtensor.all_subnets(block_hash=chain_head),
51
52
  subtensor.get_auto_stake_destinations(
@@ -54,36 +55,21 @@ async def show_auto_stake_destinations(
54
55
  reuse_block=True,
55
56
  ),
56
57
  subtensor.fetch_coldkey_hotkey_identities(block_hash=chain_head),
57
- subtensor.get_delegate_identities(block_hash=chain_head),
58
58
  )
59
59
 
60
60
  subnet_map = {info.netuid: info for info in subnet_info}
61
61
  auto_destinations = auto_destinations or {}
62
62
  identities = identities or {}
63
- delegate_identities = delegate_identities or {}
64
- hotkey_identities = identities.get("hotkeys", {})
65
63
 
66
64
  def resolve_identity(hotkey: str) -> Optional[str]:
67
65
  if not hotkey:
68
66
  return None
69
67
 
70
- identity_entry = hotkey_identities.get(hotkey, {}).get("identity")
71
- if identity_entry:
72
- display_name = identity_entry.get("name") or identity_entry.get("display")
73
- if display_name:
74
- return display_name
75
-
76
- delegate_info = delegate_identities.get(hotkey)
77
- if delegate_info and getattr(delegate_info, "display", ""):
78
- return delegate_info.display
79
-
80
- return None
68
+ return get_hotkey_identity_name(identities, hotkey)
81
69
 
82
70
  coldkey_display = wallet_name
83
71
  if not coldkey_display:
84
- coldkey_identity = identities.get("coldkeys", {}).get(coldkey_ss58, {})
85
- if identity_data := coldkey_identity.get("identity"):
86
- coldkey_display = identity_data.get("name") or identity_data.get("display")
72
+ coldkey_display = get_coldkey_identity_name(identities, coldkey_ss58)
87
73
  if not coldkey_display:
88
74
  coldkey_display = f"{coldkey_ss58[:6]}...{coldkey_ss58[-6:]}"
89
75
 
@@ -183,10 +169,9 @@ async def set_auto_stake_destination(
183
169
 
184
170
  try:
185
171
  chain_head = await subtensor.substrate.get_chain_head()
186
- subnet_info, identities, delegate_identities = await asyncio.gather(
172
+ subnet_info, identities = await asyncio.gather(
187
173
  subtensor.subnet(netuid, block_hash=chain_head),
188
174
  subtensor.fetch_coldkey_hotkey_identities(block_hash=chain_head),
189
- subtensor.get_delegate_identities(block_hash=chain_head),
190
175
  )
191
176
  except ValueError:
192
177
  print_error(f"Subnet with netuid {netuid} does not exist")
@@ -194,17 +179,8 @@ async def set_auto_stake_destination(
194
179
 
195
180
  hotkey_identity = ""
196
181
  identities = identities or {}
197
- delegate_identities = delegate_identities or {}
198
182
 
199
- hotkey_identity_entry = identities.get("hotkeys", {}).get(hotkey_ss58, {})
200
- if identity_data := hotkey_identity_entry.get("identity"):
201
- hotkey_identity = (
202
- identity_data.get("name") or identity_data.get("display") or ""
203
- )
204
- if not hotkey_identity:
205
- delegate_info = delegate_identities.get(hotkey_ss58)
206
- if delegate_info and getattr(delegate_info, "display", ""):
207
- hotkey_identity = delegate_info.display
183
+ hotkey_identity = get_hotkey_identity_name(identities, hotkey_ss58) or ""
208
184
 
209
185
  if prompt_user and not json_output:
210
186
  table = create_table(