bittensor-cli 9.10.2__py3-none-any.whl → 9.11.0__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.
@@ -23,6 +23,7 @@ class Constants:
23
23
  dev_entrypoint = "wss://dev.chain.opentensor.ai:443"
24
24
  local_entrypoint = "ws://127.0.0.1:9944"
25
25
  latent_lite_entrypoint = "wss://lite.sub.latent.to:443"
26
+ lite_nodes = [finney_entrypoint, subvortex_entrypoint, latent_lite_entrypoint]
26
27
  network_map = {
27
28
  "finney": finney_entrypoint,
28
29
  "test": finney_test_entrypoint,
@@ -88,12 +89,14 @@ class Defaults:
88
89
  class config:
89
90
  base_path = "~/.bittensor"
90
91
  path = "~/.bittensor/config.yml"
92
+ debug_file_path = "~/.bittensor/debug.txt"
91
93
  dictionary = {
92
94
  "network": None,
93
95
  "wallet_path": None,
94
96
  "wallet_name": None,
95
97
  "wallet_hotkey": None,
96
98
  "use_cache": True,
99
+ "disk_cache": False,
97
100
  "metagraph_cols": {
98
101
  "UID": True,
99
102
  "GLOBAL_STAKE": True,
@@ -1,21 +1,22 @@
1
1
  import asyncio
2
2
  import os
3
+ import time
3
4
  from typing import Optional, Any, Union, TypedDict, Iterable
4
5
 
5
6
  import aiohttp
7
+ from async_substrate_interface.async_substrate import (
8
+ DiskCachedAsyncSubstrateInterface,
9
+ AsyncSubstrateInterface,
10
+ )
11
+ from async_substrate_interface.errors import SubstrateRequestException
6
12
  from async_substrate_interface.utils.storage import StorageKey
7
13
  from bittensor_wallet import Wallet
8
14
  from bittensor_wallet.bittensor_wallet import Keypair
9
15
  from bittensor_wallet.utils import SS58_FORMAT
10
16
  from scalecodec import GenericCall
11
- from async_substrate_interface.errors import SubstrateRequestException
12
17
  import typer
18
+ import websockets
13
19
 
14
-
15
- from async_substrate_interface.async_substrate import (
16
- DiskCachedAsyncSubstrateInterface,
17
- AsyncSubstrateInterface,
18
- )
19
20
  from bittensor_cli.src.bittensor.chain_data import (
20
21
  DelegateInfo,
21
22
  StakeInfo,
@@ -42,12 +43,6 @@ from bittensor_cli.src.bittensor.utils import (
42
43
  get_hotkey_pub_ss58,
43
44
  )
44
45
 
45
- SubstrateClass = (
46
- DiskCachedAsyncSubstrateInterface
47
- if os.getenv("DISK_CACHE", "0") == "1"
48
- else AsyncSubstrateInterface
49
- )
50
-
51
46
 
52
47
  class ParamWithTypes(TypedDict):
53
48
  name: str # Name of the parameter.
@@ -81,7 +76,7 @@ class SubtensorInterface:
81
76
  Thin layer for interacting with Substrate Interface. Mostly a collection of frequently-used calls.
82
77
  """
83
78
 
84
- def __init__(self, network):
79
+ def __init__(self, network, use_disk_cache: bool = False):
85
80
  if network in Constants.network_map:
86
81
  self.chain_endpoint = Constants.network_map[network]
87
82
  self.network = network
@@ -111,8 +106,12 @@ class SubtensorInterface:
111
106
  )
112
107
  self.chain_endpoint = Constants.network_map[defaults.subtensor.network]
113
108
  self.network = defaults.subtensor.network
114
-
115
- self.substrate = SubstrateClass(
109
+ substrate_class = (
110
+ DiskCachedAsyncSubstrateInterface
111
+ if (use_disk_cache or os.getenv("DISK_CACHE", "0") == "1")
112
+ else AsyncSubstrateInterface
113
+ )
114
+ self.substrate = substrate_class(
116
115
  url=self.chain_endpoint,
117
116
  ss58_format=SS58_FORMAT,
118
117
  type_registry=TYPE_REGISTRY,
@@ -1656,3 +1655,32 @@ class SubtensorInterface:
1656
1655
  map_[netuid_] = Balance.from_rao(int(current_price * 1e9))
1657
1656
 
1658
1657
  return map_
1658
+
1659
+
1660
+ async def best_connection(networks: list[str]):
1661
+ """
1662
+ Basic function to compare the latency of a given list of websocket endpoints
1663
+ Args:
1664
+ networks: list of network URIs
1665
+
1666
+ Returns:
1667
+ {network_name: [end_to_end_latency, single_request_latency, chain_head_request_latency]}
1668
+
1669
+ """
1670
+ results = {}
1671
+ for network in networks:
1672
+ try:
1673
+ t1 = time.monotonic()
1674
+ async with websockets.connect(network) as websocket:
1675
+ pong = await websocket.ping()
1676
+ latency = await pong
1677
+ pt1 = time.monotonic()
1678
+ await websocket.send(
1679
+ "{'jsonrpc': '2.0', 'method': 'chain_getHead', 'params': [], 'id': '82'}"
1680
+ )
1681
+ await websocket.recv()
1682
+ t2 = time.monotonic()
1683
+ results[network] = [t2 - t1, latency, t2 - pt1]
1684
+ except Exception as e:
1685
+ err_console.print(f"Error attempting network {network}: {e}")
1686
+ return results
@@ -269,10 +269,26 @@ def get_hotkey_wallets_for_wallet(
269
269
  except FileNotFoundError:
270
270
  hotkeys = []
271
271
  for h_name in hotkeys:
272
- hotkey_for_name = Wallet(path=str(wallet_path), name=wallet.name, hotkey=h_name)
272
+ if h_name.endswith("pub.txt"):
273
+ if h_name.split("pub.txt")[0] in hotkeys:
274
+ continue
275
+ else:
276
+ hotkey_for_name = Wallet(
277
+ path=str(wallet_path),
278
+ name=wallet.name,
279
+ hotkey=h_name.split("pub.txt")[0],
280
+ )
281
+ else:
282
+ hotkey_for_name = Wallet(
283
+ path=str(wallet_path), name=wallet.name, hotkey=h_name
284
+ )
273
285
  try:
286
+ exists = (
287
+ hotkey_for_name.hotkey_file.exists_on_device()
288
+ or hotkey_for_name.hotkeypub_file.exists_on_device()
289
+ )
274
290
  if (
275
- (exists := hotkey_for_name.hotkey_file.exists_on_device())
291
+ exists
276
292
  and not hotkey_for_name.hotkey_file.is_encrypted()
277
293
  # and hotkey_for_name.coldkeypub.ss58_address
278
294
  and get_hotkey_pub_ss58(hotkey_for_name)
@@ -361,6 +361,7 @@ async def unstake(
361
361
  )
362
362
  if json_output:
363
363
  json_console.print(json.dumps(successes))
364
+ return True
364
365
 
365
366
 
366
367
  async def unstake_all(
@@ -52,7 +52,17 @@ async def price(
52
52
 
53
53
  step = 300
54
54
  start_block = max(0, current_block - total_blocks)
55
- block_numbers = list(range(start_block, current_block + 1, step))
55
+
56
+ # snap start block down to nearest multiple of 10
57
+ start_block -= start_block % 10
58
+
59
+ block_numbers = []
60
+ for b in range(start_block, current_block + 1, step):
61
+ if b == current_block:
62
+ block_numbers.append(b) # exact current block
63
+ else:
64
+ block_numbers.append(b - (b % 5)) # snap down to multiple of 10
65
+ block_numbers = sorted(set(block_numbers))
56
66
 
57
67
  # Block hashes
58
68
  block_hash_cors = [
@@ -2448,3 +2448,71 @@ async def start_subnet(
2448
2448
  await get_start_schedule(subtensor, netuid)
2449
2449
  print_error(f":cross_mark: Failed to start subnet: {error_msg}")
2450
2450
  return False
2451
+
2452
+
2453
+ async def set_symbol(
2454
+ wallet: "Wallet",
2455
+ subtensor: "SubtensorInterface",
2456
+ netuid: int,
2457
+ symbol: str,
2458
+ prompt: bool = False,
2459
+ json_output: bool = False,
2460
+ ) -> bool:
2461
+ """
2462
+ Set a subtensor's symbol, given the netuid and symbol.
2463
+
2464
+ The symbol must be a symbol that subtensor recognizes as available
2465
+ (defined in https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/symbols.rs#L8)
2466
+ """
2467
+ if not await subtensor.subnet_exists(netuid):
2468
+ err = f"Subnet {netuid} does not exist."
2469
+ if json_output:
2470
+ json_console.print_json(data={"success": False, "message": err})
2471
+ else:
2472
+ err_console.print(err)
2473
+ return False
2474
+
2475
+ if prompt and not json_output:
2476
+ sn_info = await subtensor.subnet(netuid=netuid)
2477
+ if not Confirm.ask(
2478
+ f"Your current subnet symbol for SN{netuid} is {sn_info.symbol}. Do you want to update it to {symbol}?"
2479
+ ):
2480
+ return False
2481
+
2482
+ if not (unlock_status := unlock_key(wallet, print_out=False)).success:
2483
+ err = unlock_status.message
2484
+ if json_output:
2485
+ json_console.print_json(data={"success": False, "message": err})
2486
+ else:
2487
+ console.print(err)
2488
+ return False
2489
+
2490
+ start_call = await subtensor.substrate.compose_call(
2491
+ call_module="SubtensorModule",
2492
+ call_function="update_symbol",
2493
+ call_params={"netuid": netuid, "symbol": symbol.encode("utf-8")},
2494
+ )
2495
+
2496
+ signed_ext = await subtensor.substrate.create_signed_extrinsic(
2497
+ call=start_call,
2498
+ keypair=wallet.coldkey,
2499
+ )
2500
+
2501
+ response = await subtensor.substrate.submit_extrinsic(
2502
+ extrinsic=signed_ext,
2503
+ wait_for_inclusion=True,
2504
+ )
2505
+ if await response.is_success:
2506
+ message = f"Successfully updated SN{netuid}'s symbol to {symbol}."
2507
+ if json_output:
2508
+ json_console.print_json(data={"success": True, "message": message})
2509
+ else:
2510
+ console.print(f":white_heavy_check_mark:[dark_sea_green3] {message}\n")
2511
+ return True
2512
+ else:
2513
+ err = format_error_message(await response.error_message)
2514
+ if json_output:
2515
+ json_console.print_json(data={"success": False, "message": err})
2516
+ else:
2517
+ err_console.print(f":cross_mark: [red]Failed[/red]: {err}")
2518
+ return False
@@ -34,6 +34,7 @@ if TYPE_CHECKING:
34
34
  SubtensorInterface,
35
35
  ProposalVoteData,
36
36
  )
37
+ from scalecodec.types import GenericMetadataVersioned
37
38
 
38
39
 
39
40
  # helpers and extrinsics
@@ -91,8 +92,8 @@ def search_metadata(
91
92
  param_name: str,
92
93
  value: Union[str, bool, float, list[float]],
93
94
  netuid: int,
94
- metadata,
95
- pallet: str = DEFAULT_PALLET,
95
+ metadata: "GenericMetadataVersioned",
96
+ pallet_name: str = DEFAULT_PALLET,
96
97
  ) -> tuple[bool, Optional[dict]]:
97
98
  """
98
99
  Searches the substrate metadata AdminUtils pallet for a given parameter name. Crafts a response dict to be used
@@ -103,7 +104,7 @@ def search_metadata(
103
104
  value: the value to set the hyperparameter
104
105
  netuid: the specified netuid
105
106
  metadata: the subtensor.substrate.metadata
106
- pallet: the name of the module to use for the query. If not set, the default value is DEFAULT_PALLET
107
+ pallet_name: the name of the module to use for the query. If not set, the default value is DEFAULT_PALLET
107
108
 
108
109
  Returns:
109
110
  (success, dict of call params)
@@ -125,7 +126,7 @@ def search_metadata(
125
126
 
126
127
  call_crafter = {"netuid": netuid}
127
128
 
128
- pallet = metadata.get_metadata_pallet(pallet)
129
+ pallet = metadata.get_metadata_pallet(pallet_name)
129
130
  for call in pallet.calls:
130
131
  if call.name == param_name:
131
132
  if "netuid" not in [x.name for x in call.args]:
@@ -846,12 +846,21 @@ async def wallet_list(wallet_path: str, json_output: bool):
846
846
  data = f"[bold red]Hotkey[/bold red][green] {hkey}[/green] (?)"
847
847
  hk_data = {"name": hkey.name, "ss58_address": "?"}
848
848
  if hkey:
849
- hkey_ss58 = get_hotkey_pub_ss58(hkey)
849
+ try:
850
+ hkey_ss58 = hkey.get_hotkey().ss58_address
851
+ pub_only = False
852
+ except KeyFileError:
853
+ hkey_ss58 = hkey.get_hotkeypub().ss58_address
854
+ pub_only = True
850
855
  try:
851
856
  data = (
852
857
  f"[bold red]Hotkey[/bold red] [green]{hkey.hotkey_str}[/green] "
853
- f"ss58_address [green]{hkey_ss58}[/green]\n"
858
+ f"ss58_address [green]{hkey_ss58}[/green]"
854
859
  )
860
+ if pub_only:
861
+ data += " [blue](hotkeypub only)[/blue]\n"
862
+ else:
863
+ data += "\n"
855
864
  hk_data["name"] = hkey.hotkey_str
856
865
  hk_data["ss58_address"] = hkey_ss58
857
866
  except UnicodeDecodeError:
@@ -1836,7 +1845,7 @@ async def check_coldkey_swap(wallet: Wallet, subtensor: SubtensorInterface):
1836
1845
 
1837
1846
 
1838
1847
  async def sign(
1839
- wallet: Wallet, message: str, use_hotkey: str, json_output: bool = False
1848
+ wallet: Wallet, message: str, use_hotkey: bool, json_output: bool = False
1840
1849
  ):
1841
1850
  """Sign a message using the provided wallet or hotkey."""
1842
1851
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bittensor-cli
3
- Version: 9.10.2
3
+ Version: 9.11.0
4
4
  Summary: Bittensor CLI
5
5
  Author: bittensor.com
6
6
  Project-URL: homepage, https://github.com/opentensor/btcli
@@ -8,7 +8,7 @@ Project-URL: Repository, https://github.com/opentensor/btcli
8
8
  Requires-Python: <3.14,>=3.9
9
9
  Description-Content-Type: text/markdown
10
10
  Requires-Dist: wheel
11
- Requires-Dist: async-substrate-interface>=1.4.2
11
+ Requires-Dist: async-substrate-interface>=1.5.2
12
12
  Requires-Dist: aiohttp~=3.10.2
13
13
  Requires-Dist: backoff~=2.2.1
14
14
  Requires-Dist: GitPython>=3.0.0
@@ -168,10 +168,13 @@ You can set the commonly used values, such as your hotkey and coldkey names, the
168
168
  The default location of the config file is: `~/.bittensor/config.yml`. An example of a `config.yml` is shown below:
169
169
 
170
170
  ```yaml
171
- chain: ws://127.0.0.1:9945
172
171
  network: local
173
- no_cache: False
174
- wallet_hotkey: hotkey-user1
172
+ use_cache: true
173
+ dashboard_path: null
174
+ disk_cache: false
175
+ rate_tolerance: null
176
+ safe_staking: true
177
+ wallet_hotkey: default
175
178
  wallet_name: coldkey-user1
176
179
  wallet_path: ~/.bittensor/wallets
177
180
  metagraph_cols:
@@ -198,6 +201,29 @@ metagraph_cols:
198
201
  btcli config --help
199
202
  ```
200
203
 
204
+ ### ENV VARS
205
+ BTCLI accepts a few environment variables that can alter how it works:
206
+ - USE_TORCH (default 0): If set to 1, will use torch instead of numpy
207
+ - DISK_CACHE (default 0, also settable in config): If set to 1 (or set in config), will use disk caching for various safe-cachable substrate
208
+ calls (such as block number to block hash mapping), which can speed up subsequent calls.
209
+ - BTCLI_CONFIG_PATH (default `~/.bittensor/config.yml`): This will set the config file location, creating if it does not exist.
210
+ - BTCLI_DEBUG_FILE (default `~/.bittensor/debug.txt`): The file stores the most recent's command's debug log.
211
+
212
+ ---
213
+
214
+ ## Debugging
215
+ BTCLI will store a debug log for every command run. This file is overwritten for each new command run. The default location
216
+ of this file is `~/.bittensor/debug.txt` and can be set with the `BTCLI_DEBUG_FILE` env var (see above section).
217
+
218
+ The debug log will **NOT** contain any sensitive data (private keys), and is intended to be sent to the developers
219
+ for debugging. This file contains basic information about the command being run, the config, and the back and forth of requests and responses
220
+ to and from the chain.
221
+
222
+ If you encounter an issue, and would like to save the file somewhere it won't be overwritten, run `btcli --debug`,
223
+ and set the save file location. We recommend doing this first before anything, and then starting your debugging with
224
+ us on our [Discord](https://discord.gg/bittensor), or by opening an issue on [GitHub](https://github.com/opentensor/btcli/issues/new)
225
+ (where you can also upload your debug file).
226
+
201
227
  ---
202
228
 
203
229
  ## License
@@ -1,15 +1,15 @@
1
1
  bittensor_cli/__init__.py,sha256=Lpv4NkbAQgwrfqFOnTMuR_S-fqGdaWCSLhxnFnGTHM0,1232
2
- bittensor_cli/cli.py,sha256=-azN2PsAd-asgnAQ8ExOztwEABWWjFE34hu-95Fxz1s,240335
2
+ bittensor_cli/cli.py,sha256=as8Tgqbb_dl1eAn4pivlZfI3gFwHSV_5w4vQQouK-ME,257916
3
3
  bittensor_cli/doc_generation_helper.py,sha256=GexqjEIKulWg84hpNBEchJ840oOgOi7DWpt447nsdNI,91
4
4
  bittensor_cli/version.py,sha256=dU1xsa3mG5FPdhzvqlzDByNcCHmzcFQH3q1pQr4u76g,720
5
- bittensor_cli/src/__init__.py,sha256=n7zmldtDbvvUMehvIUE4GXQttzDCJG-4l759pBisQOA,33167
5
+ bittensor_cli/src/__init__.py,sha256=Z0IVeFmTwoHPcROLYEc4oygilbGCdxt0c8iVqn26J5A,33334
6
6
  bittensor_cli/src/bittensor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  bittensor_cli/src/bittensor/balances.py,sha256=q5KkxF8wmUguWAFddEKstfDKTxPe5ISHpT6br8x32rc,11148
8
8
  bittensor_cli/src/bittensor/chain_data.py,sha256=1noc9bqqSU866GPaaZpO5zSrMbr7Ti4czq-5vWAqrSc,44514
9
9
  bittensor_cli/src/bittensor/minigraph.py,sha256=BIzmSVLfBYiRAeGD_i1LAC8Cw7zxp38a91SIFEPMqYc,10479
10
10
  bittensor_cli/src/bittensor/networking.py,sha256=pZLMs8YXpZzDMLXWMBb_Bj6TVkm_q9khyY-lnbwVMuE,462
11
- bittensor_cli/src/bittensor/subtensor_interface.py,sha256=9XJ74DTOLHoV5qQNmkhuvbl2kiaar4p1SV7GJeZY5p8,62698
12
- bittensor_cli/src/bittensor/utils.py,sha256=b642934KEFoetDlvRk2DsHDeucAonthdcBR-EaPpKps,48754
11
+ bittensor_cli/src/bittensor/subtensor_interface.py,sha256=syqFN8KKZPipFl2x8Cnl8_QKBtCgA5bE1HvUJXpF_u8,63816
12
+ bittensor_cli/src/bittensor/utils.py,sha256=WEnWDHMH_AmgdevywPI98i8GGvGn25ogk2xc19YKMIU,49251
13
13
  bittensor_cli/src/bittensor/extrinsics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  bittensor_cli/src/bittensor/extrinsics/registration.py,sha256=Vzs0mAtQCZLNEmFReSYK13UjvCwPNrS9se7R-hjLlbc,66204
15
15
  bittensor_cli/src/bittensor/extrinsics/root.py,sha256=tOG-xSO0ihC--AhPwrhLkm1nduvHbFAObeONGSHUdJw,19218
@@ -28,9 +28,9 @@ bittensor_cli/src/bittensor/templates/view.css,sha256=OS0V_ixzdTU15FbNzpZW1m7-c6
28
28
  bittensor_cli/src/bittensor/templates/view.j2,sha256=4ux3uyqz34v9VVAX17GezuPESk4z9n5kkd9HbnTsF_Y,1101
29
29
  bittensor_cli/src/bittensor/templates/view.js,sha256=QIPnPp9SuYS9wcl7cwL8nFzd8idiDjNzrDjwwxpiVvY,45076
30
30
  bittensor_cli/src/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- bittensor_cli/src/commands/sudo.py,sha256=Bc_u4JjCLcbxDYSysfmIgYNj0GDK6eXsI-oSyWCM1Xg,34159
31
+ bittensor_cli/src/commands/sudo.py,sha256=Y8YmGAYdNMiJurpbTTlwjiRtlwYVTzJ3zMkELcIJDSo,34260
32
32
  bittensor_cli/src/commands/view.py,sha256=9lx6vfOkel8KIefUhDNaBS_j5lNR2djcRFRbK4mbnDE,12535
33
- bittensor_cli/src/commands/wallets.py,sha256=Dk-y_m__ROujvxz84NQ8PrQNlBLNgVmvDnqwVG1gjnU,76771
33
+ bittensor_cli/src/commands/wallets.py,sha256=VTeoUhVek92rcNSnBY5hmDZ8ChlXY3CFyLIsXpEhfqE,77139
34
34
  bittensor_cli/src/commands/weights.py,sha256=iZMiZM3Y_WbglJdbN6QrRHnJ0AtlCOGmSJlXTIcOa3E,16529
35
35
  bittensor_cli/src/commands/liquidity/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  bittensor_cli/src/commands/liquidity/liquidity.py,sha256=AXCjBvQb2gakP8n1z81npYkZ_QF5CQy7r82AMtQwXzk,21692
@@ -40,12 +40,12 @@ bittensor_cli/src/commands/stake/add.py,sha256=9FFC0g2NDKm3Uheh4LFvqNvz17mhXpwWF
40
40
  bittensor_cli/src/commands/stake/children_hotkeys.py,sha256=1xR1FTljjaWD_-uTopVUkM88jNaz7vWuOwydG202lLQ,31736
41
41
  bittensor_cli/src/commands/stake/list.py,sha256=tzjhiJucXgOGaw7TGt420nGosH85AEjvOimP1XXV3Xs,29038
42
42
  bittensor_cli/src/commands/stake/move.py,sha256=TqUBqYEhfDu77l8BUdZYNy1MVybcizmtUTaPPFIAvbk,35171
43
- bittensor_cli/src/commands/stake/remove.py,sha256=ANrH9VyCJqddnabXU1EbdUxh0bpwZzz3BH58MCvKqA4,51347
43
+ bittensor_cli/src/commands/stake/remove.py,sha256=O0IuU4JcSlz7DBZTMChBYzDtLYEXqAj7CnvkgHRNLwc,51363
44
44
  bittensor_cli/src/commands/subnets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
- bittensor_cli/src/commands/subnets/price.py,sha256=RzcFVqFnQV5zBekyZCMrqpydh88yWlMLm5VJNUNfQCU,25814
46
- bittensor_cli/src/commands/subnets/subnets.py,sha256=ROtNBTUuoQcinIO5l55ky28JPd1PI4IqybdIc9JTjr0,94628
47
- bittensor_cli-9.10.2.dist-info/METADATA,sha256=HiAyZUhwDKlT_dbnEBvx00phB7PanV3CYKz0KE5U7KI,7169
48
- bittensor_cli-9.10.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
- bittensor_cli-9.10.2.dist-info/entry_points.txt,sha256=hBTLGLbVxmAKy69XSKaUZvjTCmyEzDGZKq4S8UOto8I,49
50
- bittensor_cli-9.10.2.dist-info/top_level.txt,sha256=DvgvXpmTtI_Q1BbDZMlK90LFcGFCreN1daViEPV2iFw,14
51
- bittensor_cli-9.10.2.dist-info/RECORD,,
45
+ bittensor_cli/src/commands/subnets/price.py,sha256=YWwoO31LIpa9lQ_BaSD1yC68HWsiNSv8ABRvhwxrQos,26209
46
+ bittensor_cli/src/commands/subnets/subnets.py,sha256=BZwSDm9ntZ6XgVnGa1rD3f0kFeFTizJ_sMPJcSlSiP8,96983
47
+ bittensor_cli-9.11.0.dist-info/METADATA,sha256=RqnYpo5aqRjWGg9Nz13LOvyDxmlHHBnXZTXx0_Ft8jM,8794
48
+ bittensor_cli-9.11.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
+ bittensor_cli-9.11.0.dist-info/entry_points.txt,sha256=hBTLGLbVxmAKy69XSKaUZvjTCmyEzDGZKq4S8UOto8I,49
50
+ bittensor_cli-9.11.0.dist-info/top_level.txt,sha256=DvgvXpmTtI_Q1BbDZMlK90LFcGFCreN1daViEPV2iFw,14
51
+ bittensor_cli-9.11.0.dist-info/RECORD,,