bittensor-cli 8.2.0rc12__py3-none-any.whl → 8.2.0rc14__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 +1 -1
- bittensor_cli/cli.py +406 -26
- bittensor_cli/src/__init__.py +1 -0
- bittensor_cli/src/bittensor/balances.py +29 -1
- bittensor_cli/src/bittensor/chain_data.py +13 -2
- bittensor_cli/src/bittensor/subtensor_interface.py +63 -77
- bittensor_cli/src/bittensor/utils.py +25 -5
- bittensor_cli/src/commands/stake/move.py +992 -0
- bittensor_cli/src/commands/stake/stake.py +20 -1134
- bittensor_cli/src/commands/subnets/__init__.py +0 -0
- bittensor_cli/src/commands/subnets/price.py +867 -0
- bittensor_cli/src/commands/{subnets.py → subnets/subnets.py} +13 -122
- bittensor_cli/src/commands/sudo.py +1 -2
- bittensor_cli/src/commands/wallets.py +9 -59
- {bittensor_cli-8.2.0rc12.dist-info → bittensor_cli-8.2.0rc14.dist-info}/METADATA +3 -1
- bittensor_cli-8.2.0rc14.dist-info/RECORD +33 -0
- bittensor_cli-8.2.0rc12.dist-info/RECORD +0 -30
- {bittensor_cli-8.2.0rc12.dist-info → bittensor_cli-8.2.0rc14.dist-info}/WHEEL +0 -0
- {bittensor_cli-8.2.0rc12.dist-info → bittensor_cli-8.2.0rc14.dist-info}/entry_points.txt +0 -0
- {bittensor_cli-8.2.0rc12.dist-info → bittensor_cli-8.2.0rc14.dist-info}/top_level.txt +0 -0
@@ -29,7 +29,7 @@ from bittensor_cli.src.bittensor.chain_data import (
|
|
29
29
|
DynamicInfo,
|
30
30
|
)
|
31
31
|
from bittensor_cli.src import DelegatesDetails
|
32
|
-
from bittensor_cli.src.bittensor.balances import Balance
|
32
|
+
from bittensor_cli.src.bittensor.balances import Balance, FixedPoint, fixed_to_float
|
33
33
|
from bittensor_cli.src import Constants, defaults, TYPE_REGISTRY
|
34
34
|
from bittensor_cli.src.bittensor.utils import (
|
35
35
|
ss58_to_vec_u8,
|
@@ -227,7 +227,7 @@ class SubtensorInterface:
|
|
227
227
|
else:
|
228
228
|
return []
|
229
229
|
|
230
|
-
async def
|
230
|
+
async def get_stake_for_coldkey(
|
231
231
|
self,
|
232
232
|
coldkey_ss58: str,
|
233
233
|
block_hash: Optional[str] = None,
|
@@ -264,25 +264,61 @@ class SubtensorInterface:
|
|
264
264
|
except ValueError:
|
265
265
|
bytes_result = bytes.fromhex(hex_bytes_result)
|
266
266
|
|
267
|
-
|
267
|
+
stakes = StakeInfo.list_from_vec_u8(bytes_result)
|
268
|
+
return [stake for stake in stakes if stake.stake > 0]
|
268
269
|
|
269
270
|
async def get_stake_for_coldkey_and_hotkey(
|
270
|
-
self,
|
271
|
+
self,
|
272
|
+
hotkey_ss58: str,
|
273
|
+
coldkey_ss58: str,
|
274
|
+
netuid: Optional[int] = None,
|
275
|
+
block_hash: Optional[str] = None,
|
271
276
|
) -> Balance:
|
272
277
|
"""
|
273
|
-
|
274
|
-
|
275
|
-
:
|
276
|
-
|
277
|
-
|
278
|
+
Returns the stake under a coldkey - hotkey pairing.
|
279
|
+
|
280
|
+
Args:
|
281
|
+
hotkey_ss58 (str): The SS58 address of the hotkey.
|
282
|
+
coldkey_ss58 (str): The SS58 address of the coldkey.
|
283
|
+
netuid (Optional[int]): The subnet ID to filter by. If provided, only returns stake for this specific subnet.
|
284
|
+
block_hash (Optional[str]): The block hash at which to query the stake information.
|
285
|
+
|
286
|
+
Returns:
|
287
|
+
Balance: The stake under the coldkey - hotkey pairing.
|
278
288
|
"""
|
279
|
-
|
289
|
+
alpha_shares = await self.substrate.query(
|
290
|
+
module="SubtensorModule",
|
291
|
+
storage_function="Alpha",
|
292
|
+
params=[hotkey_ss58, coldkey_ss58, netuid],
|
293
|
+
block_hash=block_hash,
|
294
|
+
)
|
295
|
+
|
296
|
+
hotkey_alpha = await self.substrate.query(
|
280
297
|
module="SubtensorModule",
|
281
|
-
storage_function="
|
282
|
-
params=[hotkey_ss58,
|
298
|
+
storage_function="TotalHotkeyAlpha",
|
299
|
+
params=[hotkey_ss58, netuid],
|
283
300
|
block_hash=block_hash,
|
284
301
|
)
|
285
|
-
|
302
|
+
|
303
|
+
hotkey_shares = await self.substrate.query(
|
304
|
+
module="SubtensorModule",
|
305
|
+
storage_function="TotalHotkeyShares",
|
306
|
+
params=[hotkey_ss58, netuid],
|
307
|
+
block_hash=block_hash,
|
308
|
+
)
|
309
|
+
|
310
|
+
alpha_shares_as_float = fixed_to_float(alpha_shares or 0)
|
311
|
+
hotkey_shares_as_float = fixed_to_float(hotkey_shares or 0)
|
312
|
+
|
313
|
+
if hotkey_shares_as_float == 0:
|
314
|
+
return Balance.from_rao(0).set_unit(netuid=netuid)
|
315
|
+
|
316
|
+
stake = alpha_shares_as_float / hotkey_shares_as_float * (hotkey_alpha or 0)
|
317
|
+
|
318
|
+
return Balance.from_rao(int(stake)).set_unit(netuid=netuid)
|
319
|
+
|
320
|
+
# Alias
|
321
|
+
get_stake = get_stake_for_coldkey_and_hotkey
|
286
322
|
|
287
323
|
async def query_runtime_api(
|
288
324
|
self,
|
@@ -384,11 +420,11 @@ class SubtensorInterface:
|
|
384
420
|
|
385
421
|
:return: {address: Balance objects}
|
386
422
|
"""
|
387
|
-
sub_stakes = await self.
|
423
|
+
sub_stakes = await self.get_stake_for_coldkeys(
|
388
424
|
ss58_addresses, block_hash=block_hash
|
389
425
|
)
|
390
426
|
# Token pricing info
|
391
|
-
dynamic_info = await self.
|
427
|
+
dynamic_info = await self.all_subnets()
|
392
428
|
|
393
429
|
results = {}
|
394
430
|
for ss58, stake_info_list in sub_stakes.items():
|
@@ -1256,27 +1292,6 @@ class SubtensorInterface:
|
|
1256
1292
|
|
1257
1293
|
return DelegateInfoLite.list_from_vec_u8(result) # TODO this won't work yet
|
1258
1294
|
|
1259
|
-
async def get_subnet_dynamic_info(
|
1260
|
-
self, netuid: int, block_hash: Optional[str] = None
|
1261
|
-
) -> "DynamicInfo":
|
1262
|
-
hex_bytes_result = await self.query_runtime_api(
|
1263
|
-
runtime_api="SubnetInfoRuntimeApi",
|
1264
|
-
method="get_dynamic_info",
|
1265
|
-
params=[netuid],
|
1266
|
-
block_hash=block_hash,
|
1267
|
-
)
|
1268
|
-
|
1269
|
-
if hex_bytes_result is None:
|
1270
|
-
return None
|
1271
|
-
|
1272
|
-
if hex_bytes_result.startswith("0x"):
|
1273
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
1274
|
-
else:
|
1275
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
1276
|
-
|
1277
|
-
subnets = DynamicInfo.from_vec_u8(bytes_result)
|
1278
|
-
return subnets
|
1279
|
-
|
1280
1295
|
async def get_stake_for_coldkey_and_hotkey_on_netuid(
|
1281
1296
|
self,
|
1282
1297
|
hotkey_ss58: str,
|
@@ -1354,7 +1369,7 @@ class SubtensorInterface:
|
|
1354
1369
|
results[hotkey_ss58][netuid] = value
|
1355
1370
|
return results
|
1356
1371
|
|
1357
|
-
async def
|
1372
|
+
async def get_stake_for_coldkeys(
|
1358
1373
|
self, coldkey_ss58_list: list[str], block_hash: Optional[str] = None
|
1359
1374
|
) -> Optional[dict[str, list[StakeInfo]]]:
|
1360
1375
|
"""
|
@@ -1392,7 +1407,9 @@ class SubtensorInterface:
|
|
1392
1407
|
|
1393
1408
|
return StakeInfo.list_of_tuple_from_vec_u8(bytes_result) # type: ignore
|
1394
1409
|
|
1395
|
-
async def
|
1410
|
+
async def all_subnets(
|
1411
|
+
self, block_hash: Optional[str] = None
|
1412
|
+
) -> list["DynamicInfo"]:
|
1396
1413
|
query = await self.substrate.runtime_call(
|
1397
1414
|
"SubnetInfoRuntimeApi",
|
1398
1415
|
"get_all_dynamic_info",
|
@@ -1401,47 +1418,16 @@ class SubtensorInterface:
|
|
1401
1418
|
subnets = DynamicInfo.list_from_vec_u8(bytes.fromhex(query.decode()[2:]))
|
1402
1419
|
return subnets
|
1403
1420
|
|
1404
|
-
async def
|
1405
|
-
self,
|
1406
|
-
):
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
params=[netuid
|
1421
|
+
async def subnet(
|
1422
|
+
self, netuid: int, block_hash: Optional[str] = None
|
1423
|
+
) -> "DynamicInfo":
|
1424
|
+
query = await self.substrate.runtime_call(
|
1425
|
+
"SubnetInfoRuntimeApi",
|
1426
|
+
"get_dynamic_info",
|
1427
|
+
params=[netuid],
|
1411
1428
|
block_hash=block_hash,
|
1412
1429
|
)
|
1413
|
-
return
|
1414
|
-
netuid: u64_normalized_float(weight) for (netuid, weight) in result.items()
|
1415
|
-
}
|
1416
|
-
|
1417
|
-
async def get_subnet_tao(
|
1418
|
-
self, netuid: Optional[int] = None, block_hash: Optional[str] = None
|
1419
|
-
) -> dict[int, Balance]:
|
1420
|
-
"""
|
1421
|
-
Retrieves the total TAO for one or all subnets.
|
1422
|
-
|
1423
|
-
Args:
|
1424
|
-
netuid: Optional specific netuid to query. If None, returns data for all subnets.
|
1425
|
-
block_hash: Optional block hash to query at.
|
1426
|
-
|
1427
|
-
Returns:
|
1428
|
-
Dictionary mapping netuid to its total TAO balance
|
1429
|
-
"""
|
1430
|
-
if netuid is not None:
|
1431
|
-
result = await self.substrate.query(
|
1432
|
-
module="SubtensorModule",
|
1433
|
-
storage_function="SubnetTAO",
|
1434
|
-
params=[netuid],
|
1435
|
-
block_hash=block_hash,
|
1436
|
-
)
|
1437
|
-
return {netuid: Balance.from_rao(result or 0)}
|
1438
|
-
else:
|
1439
|
-
results = await self.substrate.query_map(
|
1440
|
-
module="SubtensorModule",
|
1441
|
-
storage_function="SubnetTAO",
|
1442
|
-
block_hash=block_hash,
|
1443
|
-
)
|
1444
|
-
return {netuid: Balance.from_rao(tao or 0) async for netuid, tao in results}
|
1430
|
+
return DynamicInfo.from_vec_u8(bytes.fromhex(query.decode()[2:]))
|
1445
1431
|
|
1446
1432
|
async def get_owned_hotkeys(
|
1447
1433
|
self,
|
@@ -2,6 +2,7 @@ import ast
|
|
2
2
|
import math
|
3
3
|
import os
|
4
4
|
import sqlite3
|
5
|
+
import platform
|
5
6
|
import webbrowser
|
6
7
|
import sys
|
7
8
|
from pathlib import Path
|
@@ -1202,17 +1203,36 @@ def is_valid_contact(contact: str) -> bool:
|
|
1202
1203
|
|
1203
1204
|
def get_subnet_name(subnet_info) -> str:
|
1204
1205
|
"""Get the subnet name, prioritizing subnet_identity.subnet_name over subnet.subnet_name.
|
1205
|
-
|
1206
|
+
|
1206
1207
|
Args:
|
1207
1208
|
subnet: The subnet dynamic info
|
1208
|
-
|
1209
|
+
|
1209
1210
|
Returns:
|
1210
1211
|
str: The subnet name or empty string if no name is found
|
1211
1212
|
"""
|
1212
1213
|
return (
|
1213
1214
|
subnet_info.subnet_identity.subnet_name
|
1214
|
-
if hasattr(subnet_info,
|
1215
|
-
and subnet_info.subnet_identity is not None
|
1215
|
+
if hasattr(subnet_info, "subnet_identity")
|
1216
|
+
and subnet_info.subnet_identity is not None
|
1216
1217
|
and subnet_info.subnet_identity.subnet_name is not None
|
1217
1218
|
else (subnet_info.subnet_name if subnet_info.subnet_name is not None else "")
|
1218
|
-
)
|
1219
|
+
)
|
1220
|
+
|
1221
|
+
|
1222
|
+
def print_linux_dependency_message():
|
1223
|
+
"""Prints the WebKit dependency message for Linux systems."""
|
1224
|
+
console.print("[red]This command requires WebKit dependencies on Linux.[/red]")
|
1225
|
+
console.print(
|
1226
|
+
"\nPlease install the required packages using one of the following commands based on your distribution:"
|
1227
|
+
)
|
1228
|
+
console.print("\nArch Linux / Manjaro:")
|
1229
|
+
console.print("[green]sudo pacman -S webkit2gtk[/green]")
|
1230
|
+
console.print("\nDebian / Ubuntu:")
|
1231
|
+
console.print("[green]sudo apt install libwebkit2gtk-4.0-dev[/green]")
|
1232
|
+
console.print("\nFedora / CentOS / AlmaLinux:")
|
1233
|
+
console.print("[green]sudo dnf install gtk3-devel webkit2gtk3-devel[/green]")
|
1234
|
+
|
1235
|
+
|
1236
|
+
def is_linux():
|
1237
|
+
"""Returns True if the operating system is Linux."""
|
1238
|
+
return platform.system().lower() == "linux"
|