bittensor-cli 9.0.3__py3-none-any.whl → 9.1.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.
- bittensor_cli/cli.py +43 -7
- bittensor_cli/src/__init__.py +3 -0
- bittensor_cli/src/bittensor/balances.py +5 -6
- bittensor_cli/src/bittensor/chain_data.py +287 -25
- bittensor_cli/src/bittensor/subtensor_interface.py +33 -0
- bittensor_cli/src/bittensor/utils.py +13 -2
- bittensor_cli/src/commands/stake/move.py +4 -4
- bittensor_cli/src/commands/view.py +2876 -0
- bittensor_cli/version.py +1 -1
- {bittensor_cli-9.0.3.dist-info → bittensor_cli-9.1.0.dist-info}/METADATA +1 -1
- {bittensor_cli-9.0.3.dist-info → bittensor_cli-9.1.0.dist-info}/RECORD +14 -13
- {bittensor_cli-9.0.3.dist-info → bittensor_cli-9.1.0.dist-info}/WHEEL +0 -0
- {bittensor_cli-9.0.3.dist-info → bittensor_cli-9.1.0.dist-info}/entry_points.txt +0 -0
- {bittensor_cli-9.0.3.dist-info → bittensor_cli-9.1.0.dist-info}/top_level.txt +0 -0
bittensor_cli/cli.py
CHANGED
@@ -32,7 +32,7 @@ from bittensor_cli.version import __version__, __version_as_int__
|
|
32
32
|
from bittensor_cli.src.bittensor import utils
|
33
33
|
from bittensor_cli.src.bittensor.balances import Balance
|
34
34
|
from async_substrate_interface.errors import SubstrateRequestException
|
35
|
-
from bittensor_cli.src.commands import sudo, wallets
|
35
|
+
from bittensor_cli.src.commands import sudo, wallets, view
|
36
36
|
from bittensor_cli.src.commands import weights as weights_cmds
|
37
37
|
from bittensor_cli.src.commands.subnets import price, subnets
|
38
38
|
from bittensor_cli.src.commands.stake import (
|
@@ -193,8 +193,7 @@ class Options:
|
|
193
193
|
)
|
194
194
|
wait_for_finalization = typer.Option(
|
195
195
|
True,
|
196
|
-
help="If `True`, waits until the transaction is finalized "
|
197
|
-
"on the blockchain.",
|
196
|
+
help="If `True`, waits until the transaction is finalized on the blockchain.",
|
198
197
|
)
|
199
198
|
prompt = typer.Option(
|
200
199
|
True,
|
@@ -513,6 +512,7 @@ class CLIManager:
|
|
513
512
|
subnets_app: typer.Typer
|
514
513
|
weights_app: typer.Typer
|
515
514
|
utils_app = typer.Typer(epilog=_epilog)
|
515
|
+
view_app: typer.Typer
|
516
516
|
asyncio_runner = asyncio
|
517
517
|
|
518
518
|
def __init__(self):
|
@@ -562,6 +562,7 @@ class CLIManager:
|
|
562
562
|
self.sudo_app = typer.Typer(epilog=_epilog)
|
563
563
|
self.subnets_app = typer.Typer(epilog=_epilog)
|
564
564
|
self.weights_app = typer.Typer(epilog=_epilog)
|
565
|
+
self.view_app = typer.Typer(epilog=_epilog)
|
565
566
|
|
566
567
|
# config alias
|
567
568
|
self.app.add_typer(
|
@@ -639,6 +640,14 @@ class CLIManager:
|
|
639
640
|
self.utils_app, name="utils", no_args_is_help=True, hidden=True
|
640
641
|
)
|
641
642
|
|
643
|
+
# view app
|
644
|
+
self.app.add_typer(
|
645
|
+
self.view_app,
|
646
|
+
name="view",
|
647
|
+
short_help="HTML view commands",
|
648
|
+
no_args_is_help=True,
|
649
|
+
)
|
650
|
+
|
642
651
|
# config commands
|
643
652
|
self.config_app.command("set")(self.set_config)
|
644
653
|
self.config_app.command("get")(self.get_config)
|
@@ -806,6 +815,11 @@ class CLIManager:
|
|
806
815
|
"commit", rich_help_panel=HELP_PANELS["WEIGHTS"]["COMMIT_REVEAL"]
|
807
816
|
)(self.weights_commit)
|
808
817
|
|
818
|
+
# view commands
|
819
|
+
self.view_app.command(
|
820
|
+
"dashboard", rich_help_panel=HELP_PANELS["VIEW"]["DASHBOARD"]
|
821
|
+
)(self.view_dashboard)
|
822
|
+
|
809
823
|
# Sub command aliases
|
810
824
|
# Weights
|
811
825
|
self.wallet_app.command(
|
@@ -1336,7 +1350,7 @@ class CLIManager:
|
|
1336
1350
|
if value in Constants.networks:
|
1337
1351
|
value = value + f" ({Constants.network_map[value]})"
|
1338
1352
|
if key == "rate_tolerance":
|
1339
|
-
value = f"{value} ({value*100}%)" if value is not None else "None"
|
1353
|
+
value = f"{value} ({value * 100}%)" if value is not None else "None"
|
1340
1354
|
|
1341
1355
|
elif key in deprecated_configs:
|
1342
1356
|
continue
|
@@ -1365,19 +1379,19 @@ class CLIManager:
|
|
1365
1379
|
"""
|
1366
1380
|
if rate_tolerance is not None:
|
1367
1381
|
console.print(
|
1368
|
-
f"[dim][blue]Rate tolerance[/blue]: [bold cyan]{rate_tolerance} ({rate_tolerance*100}%)[/bold cyan]."
|
1382
|
+
f"[dim][blue]Rate tolerance[/blue]: [bold cyan]{rate_tolerance} ({rate_tolerance * 100}%)[/bold cyan]."
|
1369
1383
|
)
|
1370
1384
|
return rate_tolerance
|
1371
1385
|
elif self.config.get("rate_tolerance") is not None:
|
1372
1386
|
config_slippage = self.config["rate_tolerance"]
|
1373
1387
|
console.print(
|
1374
|
-
f"[dim][blue]Rate tolerance[/blue]: [bold cyan]{config_slippage} ({config_slippage*100}%)[/bold cyan] (from config)."
|
1388
|
+
f"[dim][blue]Rate tolerance[/blue]: [bold cyan]{config_slippage} ({config_slippage * 100}%)[/bold cyan] (from config)."
|
1375
1389
|
)
|
1376
1390
|
return config_slippage
|
1377
1391
|
else:
|
1378
1392
|
console.print(
|
1379
1393
|
"[dim][blue]Rate tolerance[/blue]: "
|
1380
|
-
+ f"[bold cyan]{defaults.rate_tolerance} ({defaults.rate_tolerance*100}%)[/bold cyan] "
|
1394
|
+
+ f"[bold cyan]{defaults.rate_tolerance} ({defaults.rate_tolerance * 100}%)[/bold cyan] "
|
1381
1395
|
+ "by default. Set this using "
|
1382
1396
|
+ "[dark_sea_green3 italic]`btcli config set`[/dark_sea_green3 italic] "
|
1383
1397
|
+ "or "
|
@@ -5071,6 +5085,28 @@ class CLIManager:
|
|
5071
5085
|
)
|
5072
5086
|
)
|
5073
5087
|
|
5088
|
+
def view_dashboard(
|
5089
|
+
self,
|
5090
|
+
network: Optional[list[str]] = Options.network,
|
5091
|
+
wallet_name: str = Options.wallet_name,
|
5092
|
+
wallet_path: str = Options.wallet_path,
|
5093
|
+
wallet_hotkey: str = Options.wallet_hotkey,
|
5094
|
+
quiet: bool = Options.quiet,
|
5095
|
+
verbose: bool = Options.verbose,
|
5096
|
+
):
|
5097
|
+
"""
|
5098
|
+
Display html dashboard with subnets list, stake, and neuron information.
|
5099
|
+
"""
|
5100
|
+
self.verbosity_handler(quiet, verbose)
|
5101
|
+
if is_linux():
|
5102
|
+
print_linux_dependency_message()
|
5103
|
+
wallet = self.wallet_ask(
|
5104
|
+
wallet_name, wallet_path, wallet_hotkey, ask_for=[WO.NAME, WO.PATH]
|
5105
|
+
)
|
5106
|
+
return self._run_command(
|
5107
|
+
view.display_network_dashboard(wallet, self.initialize_chain(network))
|
5108
|
+
)
|
5109
|
+
|
5074
5110
|
@staticmethod
|
5075
5111
|
@utils_app.command("convert")
|
5076
5112
|
def convert(
|
bittensor_cli/src/__init__.py
CHANGED
@@ -297,17 +297,16 @@ class Balance:
|
|
297
297
|
return self
|
298
298
|
|
299
299
|
|
300
|
-
def fixed_to_float(fixed:
|
301
|
-
#
|
300
|
+
def fixed_to_float(fixed, frac_bits: int = 64, total_bits: int = 128) -> float:
|
301
|
+
# By default, this is a U64F64
|
302
302
|
# which is 64 bits of integer and 64 bits of fractional
|
303
|
-
# uint_bits = 64
|
304
|
-
frac_bits = 64
|
305
303
|
|
306
304
|
data: int = fixed["bits"]
|
307
305
|
|
308
|
-
#
|
309
|
-
integer_part = data >> frac_bits
|
306
|
+
# Logical and to get the fractional part; remaining is the integer part
|
310
307
|
fractional_part = data & (2**frac_bits - 1)
|
308
|
+
# Shift to get the integer part from the remaining bits
|
309
|
+
integer_part = data >> (total_bits - frac_bits)
|
311
310
|
|
312
311
|
frac_float = fractional_part / (2**frac_bits)
|
313
312
|
|
@@ -6,11 +6,12 @@ from typing import Optional, Any, Union
|
|
6
6
|
import netaddr
|
7
7
|
from scalecodec.utils.ss58 import ss58_encode
|
8
8
|
|
9
|
-
from bittensor_cli.src.bittensor.balances import Balance
|
9
|
+
from bittensor_cli.src.bittensor.balances import Balance, fixed_to_float
|
10
10
|
from bittensor_cli.src.bittensor.networking import int_to_ip
|
11
11
|
from bittensor_cli.src.bittensor.utils import (
|
12
12
|
SS58_FORMAT,
|
13
|
-
u16_normalized_float,
|
13
|
+
u16_normalized_float as u16tf,
|
14
|
+
u64_normalized_float as u64tf,
|
14
15
|
decode_account_id,
|
15
16
|
)
|
16
17
|
|
@@ -57,6 +58,31 @@ def process_stake_data(stake_data, netuid):
|
|
57
58
|
return decoded_stake_data
|
58
59
|
|
59
60
|
|
61
|
+
def _tbwu(val: int, netuid: Optional[int] = 0) -> Balance:
|
62
|
+
"""Returns a Balance object from a value and unit."""
|
63
|
+
return Balance.from_rao(val).set_unit(netuid)
|
64
|
+
|
65
|
+
|
66
|
+
def _chr_str(codes: tuple[int]) -> str:
|
67
|
+
"""Converts a tuple of integer Unicode code points into a string."""
|
68
|
+
return "".join(map(chr, codes))
|
69
|
+
|
70
|
+
|
71
|
+
def process_nested(data: Union[tuple, dict], chr_transform):
|
72
|
+
"""Processes nested data structures by applying a transformation function to their elements."""
|
73
|
+
if isinstance(data, (list, tuple)):
|
74
|
+
if len(data) > 0 and isinstance(data[0], dict):
|
75
|
+
return [
|
76
|
+
{k: chr_transform(v) for k, v in item.items()}
|
77
|
+
if item is not None
|
78
|
+
else None
|
79
|
+
for item in data
|
80
|
+
]
|
81
|
+
return {}
|
82
|
+
elif isinstance(data, dict):
|
83
|
+
return {k: chr_transform(v) for k, v in data.items()}
|
84
|
+
|
85
|
+
|
60
86
|
@dataclass
|
61
87
|
class AxonInfo:
|
62
88
|
version: int
|
@@ -312,13 +338,13 @@ class NeuronInfo(InfoBase):
|
|
312
338
|
stake=total_stake,
|
313
339
|
stake_dict=stake_dict,
|
314
340
|
total_stake=total_stake,
|
315
|
-
rank=
|
341
|
+
rank=u16tf(decoded.get("rank")),
|
316
342
|
emission=decoded.get("emission") / 1e9,
|
317
|
-
incentive=
|
318
|
-
consensus=
|
319
|
-
trust=
|
320
|
-
validator_trust=
|
321
|
-
dividends=
|
343
|
+
incentive=u16tf(decoded.get("incentive")),
|
344
|
+
consensus=u16tf(decoded.get("consensus")),
|
345
|
+
trust=u16tf(decoded.get("trust")),
|
346
|
+
validator_trust=u16tf(decoded.get("validator_trust")),
|
347
|
+
dividends=u16tf(decoded.get("dividends")),
|
322
348
|
last_update=decoded.get("last_update"),
|
323
349
|
validator_permit=decoded.get("validator_permit"),
|
324
350
|
weights=[[e[0], e[1]] for e in decoded.get("weights")],
|
@@ -426,22 +452,22 @@ class NeuronInfoLite(InfoBase):
|
|
426
452
|
coldkey=coldkey,
|
427
453
|
),
|
428
454
|
coldkey=coldkey,
|
429
|
-
consensus=
|
430
|
-
dividends=
|
455
|
+
consensus=u16tf(consensus),
|
456
|
+
dividends=u16tf(dividends),
|
431
457
|
emission=emission / 1e9,
|
432
458
|
hotkey=hotkey,
|
433
|
-
incentive=
|
459
|
+
incentive=u16tf(incentive),
|
434
460
|
last_update=last_update,
|
435
461
|
netuid=netuid,
|
436
462
|
pruning_score=pruning_score,
|
437
|
-
rank=
|
463
|
+
rank=u16tf(rank),
|
438
464
|
stake_dict=stake_dict,
|
439
465
|
stake=stake,
|
440
466
|
total_stake=stake,
|
441
|
-
trust=
|
467
|
+
trust=u16tf(trust),
|
442
468
|
uid=uid,
|
443
469
|
validator_permit=validator_permit,
|
444
|
-
validator_trust=
|
470
|
+
validator_trust=u16tf(validator_trust),
|
445
471
|
)
|
446
472
|
|
447
473
|
return neuron
|
@@ -492,7 +518,7 @@ class DelegateInfo(InfoBase):
|
|
492
518
|
total_stake=total_stake,
|
493
519
|
nominators=nominators,
|
494
520
|
owner_ss58=owner,
|
495
|
-
take=
|
521
|
+
take=u16tf(decoded.get("take")),
|
496
522
|
validator_permits=decoded.get("validator_permits"),
|
497
523
|
registrations=decoded.get("registrations"),
|
498
524
|
return_per_1000=Balance.from_rao(decoded.get("return_per_1000")),
|
@@ -528,7 +554,7 @@ class DelegateInfoLite(InfoBase):
|
|
528
554
|
if decoded_take == 65535:
|
529
555
|
fixed_take = None
|
530
556
|
else:
|
531
|
-
fixed_take =
|
557
|
+
fixed_take = u16tf(decoded_take)
|
532
558
|
|
533
559
|
return cls(
|
534
560
|
hotkey_ss58=ss58_encode(decoded.get("delegate_ss58"), SS58_FORMAT),
|
@@ -581,7 +607,7 @@ class SubnetInfo(InfoBase):
|
|
581
607
|
tempo=decoded.get("tempo"),
|
582
608
|
modality=decoded.get("network_modality"),
|
583
609
|
connection_requirements={
|
584
|
-
str(int(netuid)):
|
610
|
+
str(int(netuid)): u16tf(int(req))
|
585
611
|
for (netuid, req) in decoded.get("network_connect")
|
586
612
|
},
|
587
613
|
emission_value=decoded.get("emission_value"),
|
@@ -844,19 +870,17 @@ class SubnetState(InfoBase):
|
|
844
870
|
coldkeys=[decode_account_id(val) for val in decoded.get("coldkeys")],
|
845
871
|
active=decoded.get("active"),
|
846
872
|
validator_permit=decoded.get("validator_permit"),
|
847
|
-
pruning_score=[
|
848
|
-
u16_normalized_float(val) for val in decoded.get("pruning_score")
|
849
|
-
],
|
873
|
+
pruning_score=[u16tf(val) for val in decoded.get("pruning_score")],
|
850
874
|
last_update=decoded.get("last_update"),
|
851
875
|
emission=[
|
852
876
|
Balance.from_rao(val).set_unit(netuid)
|
853
877
|
for val in decoded.get("emission")
|
854
878
|
],
|
855
|
-
dividends=[
|
856
|
-
incentives=[
|
857
|
-
consensus=[
|
858
|
-
trust=[
|
859
|
-
rank=[
|
879
|
+
dividends=[u16tf(val) for val in decoded.get("dividends")],
|
880
|
+
incentives=[u16tf(val) for val in decoded.get("incentives")],
|
881
|
+
consensus=[u16tf(val) for val in decoded.get("consensus")],
|
882
|
+
trust=[u16tf(val) for val in decoded.get("trust")],
|
883
|
+
rank=[u16tf(val) for val in decoded.get("rank")],
|
860
884
|
block_at_registration=decoded.get("block_at_registration"),
|
861
885
|
alpha_stake=[
|
862
886
|
Balance.from_rao(val).set_unit(netuid)
|
@@ -871,3 +895,241 @@ class SubnetState(InfoBase):
|
|
871
895
|
],
|
872
896
|
emission_history=decoded.get("emission_history"),
|
873
897
|
)
|
898
|
+
|
899
|
+
|
900
|
+
@dataclass
|
901
|
+
class ChainIdentity(InfoBase):
|
902
|
+
"""Dataclass for chain identity information."""
|
903
|
+
|
904
|
+
name: str
|
905
|
+
url: str
|
906
|
+
github: str
|
907
|
+
image: str
|
908
|
+
discord: str
|
909
|
+
description: str
|
910
|
+
additional: str
|
911
|
+
|
912
|
+
@classmethod
|
913
|
+
def _from_dict(cls, decoded: dict) -> "ChainIdentity":
|
914
|
+
"""Returns a ChainIdentity object from decoded chain data."""
|
915
|
+
return cls(
|
916
|
+
name=decoded["name"],
|
917
|
+
url=decoded["url"],
|
918
|
+
github=decoded["github_repo"],
|
919
|
+
image=decoded["image"],
|
920
|
+
discord=decoded["discord"],
|
921
|
+
description=decoded["description"],
|
922
|
+
additional=decoded["additional"],
|
923
|
+
)
|
924
|
+
|
925
|
+
|
926
|
+
@dataclass
|
927
|
+
class MetagraphInfo(InfoBase):
|
928
|
+
# Subnet index
|
929
|
+
netuid: int
|
930
|
+
|
931
|
+
# Name and symbol
|
932
|
+
name: str
|
933
|
+
symbol: str
|
934
|
+
identity: Optional[SubnetIdentity]
|
935
|
+
network_registered_at: int
|
936
|
+
|
937
|
+
# Keys for owner.
|
938
|
+
owner_hotkey: str # hotkey
|
939
|
+
owner_coldkey: str # coldkey
|
940
|
+
|
941
|
+
# Tempo terms.
|
942
|
+
block: int # block at call.
|
943
|
+
tempo: int # epoch tempo
|
944
|
+
last_step: int
|
945
|
+
blocks_since_last_step: int
|
946
|
+
|
947
|
+
# Subnet emission terms
|
948
|
+
subnet_emission: Balance # subnet emission via tao
|
949
|
+
alpha_in: Balance # amount of alpha in reserve
|
950
|
+
alpha_out: Balance # amount of alpha outstanding
|
951
|
+
tao_in: Balance # amount of tao injected per block
|
952
|
+
alpha_out_emission: Balance # amount injected in alpha reserves per block
|
953
|
+
alpha_in_emission: Balance # amount injected outstanding per block
|
954
|
+
tao_in_emission: Balance # amount of tao injected per block
|
955
|
+
pending_alpha_emission: Balance # pending alpha to be distributed
|
956
|
+
pending_root_emission: Balance # pending tao for root divs to be distributed
|
957
|
+
subnet_volume: Balance # volume of the subnet in TAO
|
958
|
+
moving_price: Balance # subnet moving price.
|
959
|
+
|
960
|
+
# Hparams for epoch
|
961
|
+
rho: int # subnet rho param
|
962
|
+
kappa: float # subnet kappa param
|
963
|
+
|
964
|
+
# Validator params
|
965
|
+
min_allowed_weights: float # min allowed weights per val
|
966
|
+
max_weights_limit: float # max allowed weights per val
|
967
|
+
weights_version: int # allowed weights version
|
968
|
+
weights_rate_limit: int # rate limit on weights.
|
969
|
+
activity_cutoff: int # validator weights cut off period in blocks
|
970
|
+
max_validators: int # max allowed validators.
|
971
|
+
|
972
|
+
# Registration
|
973
|
+
num_uids: int
|
974
|
+
max_uids: int
|
975
|
+
burn: Balance # current burn cost.
|
976
|
+
difficulty: float # current difficulty.
|
977
|
+
registration_allowed: bool # allows registrations.
|
978
|
+
pow_registration_allowed: bool # pow registration enabled.
|
979
|
+
immunity_period: int # subnet miner immunity period
|
980
|
+
min_difficulty: float # min pow difficulty
|
981
|
+
max_difficulty: float # max pow difficulty
|
982
|
+
min_burn: Balance # min tao burn
|
983
|
+
max_burn: Balance # max tao burn
|
984
|
+
adjustment_alpha: float # adjustment speed for registration params.
|
985
|
+
adjustment_interval: int # pow and burn adjustment interval
|
986
|
+
target_regs_per_interval: int # target registrations per interval
|
987
|
+
max_regs_per_block: int # max registrations per block.
|
988
|
+
serving_rate_limit: int # axon serving rate limit
|
989
|
+
|
990
|
+
# CR
|
991
|
+
commit_reveal_weights_enabled: bool # Is CR enabled.
|
992
|
+
commit_reveal_period: int # Commit reveal interval
|
993
|
+
|
994
|
+
# Bonds
|
995
|
+
liquid_alpha_enabled: bool # Bonds liquid enabled.
|
996
|
+
alpha_high: float # Alpha param high
|
997
|
+
alpha_low: float # Alpha param low
|
998
|
+
bonds_moving_avg: float # Bonds moving avg
|
999
|
+
|
1000
|
+
# Metagraph info.
|
1001
|
+
hotkeys: list[str] # hotkey per UID
|
1002
|
+
coldkeys: list[str] # coldkey per UID
|
1003
|
+
identities: list[Optional[ChainIdentity]] # coldkeys identities
|
1004
|
+
axons: list[AxonInfo] # UID axons.
|
1005
|
+
active: list[bool] # Active per UID
|
1006
|
+
validator_permit: list[bool] # Val permit per UID
|
1007
|
+
pruning_score: list[float] # Pruning per UID
|
1008
|
+
last_update: list[int] # Last update per UID
|
1009
|
+
emission: list[Balance] # Emission per UID
|
1010
|
+
dividends: list[float] # Dividends per UID
|
1011
|
+
incentives: list[float] # Mining incentives per UID
|
1012
|
+
consensus: list[float] # Consensus per UID
|
1013
|
+
trust: list[float] # Trust per UID
|
1014
|
+
rank: list[float] # Rank per UID
|
1015
|
+
block_at_registration: list[int] # Reg block per UID
|
1016
|
+
alpha_stake: list[Balance] # Alpha staked per UID
|
1017
|
+
tao_stake: list[Balance] # TAO staked per UID
|
1018
|
+
total_stake: list[Balance] # Total stake per UID
|
1019
|
+
|
1020
|
+
# Dividend break down.
|
1021
|
+
tao_dividends_per_hotkey: list[
|
1022
|
+
tuple[str, Balance]
|
1023
|
+
] # List of dividend payouts in tao via root.
|
1024
|
+
alpha_dividends_per_hotkey: list[
|
1025
|
+
tuple[str, Balance]
|
1026
|
+
] # List of dividend payout in alpha via subnet.
|
1027
|
+
|
1028
|
+
@classmethod
|
1029
|
+
def _fix_decoded(cls, decoded: dict) -> "MetagraphInfo":
|
1030
|
+
"""Returns a MetagraphInfo object from decoded chain data."""
|
1031
|
+
# Subnet index
|
1032
|
+
_netuid = decoded["netuid"]
|
1033
|
+
|
1034
|
+
# Name and symbol
|
1035
|
+
decoded.update({"name": bytes(decoded.get("name")).decode()})
|
1036
|
+
decoded.update({"symbol": bytes(decoded.get("symbol")).decode()})
|
1037
|
+
for key in ["identities", "identity"]:
|
1038
|
+
raw_data = decoded.get(key)
|
1039
|
+
processed = process_nested(raw_data, _chr_str)
|
1040
|
+
decoded.update({key: processed})
|
1041
|
+
|
1042
|
+
return cls(
|
1043
|
+
# Subnet index
|
1044
|
+
netuid=_netuid,
|
1045
|
+
# Name and symbol
|
1046
|
+
name=decoded["name"],
|
1047
|
+
symbol=decoded["symbol"],
|
1048
|
+
identity=decoded["identity"],
|
1049
|
+
network_registered_at=decoded["network_registered_at"],
|
1050
|
+
# Keys for owner.
|
1051
|
+
owner_hotkey=decoded["owner_hotkey"],
|
1052
|
+
owner_coldkey=decoded["owner_coldkey"],
|
1053
|
+
# Tempo terms.
|
1054
|
+
block=decoded["block"],
|
1055
|
+
tempo=decoded["tempo"],
|
1056
|
+
last_step=decoded["last_step"],
|
1057
|
+
blocks_since_last_step=decoded["blocks_since_last_step"],
|
1058
|
+
# Subnet emission terms
|
1059
|
+
subnet_emission=_tbwu(decoded["subnet_emission"]),
|
1060
|
+
alpha_in=_tbwu(decoded["alpha_in"], _netuid),
|
1061
|
+
alpha_out=_tbwu(decoded["alpha_out"], _netuid),
|
1062
|
+
tao_in=_tbwu(decoded["tao_in"]),
|
1063
|
+
alpha_out_emission=_tbwu(decoded["alpha_out_emission"], _netuid),
|
1064
|
+
alpha_in_emission=_tbwu(decoded["alpha_in_emission"], _netuid),
|
1065
|
+
tao_in_emission=_tbwu(decoded["tao_in_emission"]),
|
1066
|
+
pending_alpha_emission=_tbwu(decoded["pending_alpha_emission"], _netuid),
|
1067
|
+
pending_root_emission=_tbwu(decoded["pending_root_emission"]),
|
1068
|
+
subnet_volume=_tbwu(decoded["subnet_volume"], _netuid),
|
1069
|
+
moving_price=Balance.from_tao(
|
1070
|
+
fixed_to_float(decoded.get("moving_price"), 32)
|
1071
|
+
),
|
1072
|
+
# Hparams for epoch
|
1073
|
+
rho=decoded["rho"],
|
1074
|
+
kappa=decoded["kappa"],
|
1075
|
+
# Validator params
|
1076
|
+
min_allowed_weights=u16tf(decoded["min_allowed_weights"]),
|
1077
|
+
max_weights_limit=u16tf(decoded["max_weights_limit"]),
|
1078
|
+
weights_version=decoded["weights_version"],
|
1079
|
+
weights_rate_limit=decoded["weights_rate_limit"],
|
1080
|
+
activity_cutoff=decoded["activity_cutoff"],
|
1081
|
+
max_validators=decoded["max_validators"],
|
1082
|
+
# Registration
|
1083
|
+
num_uids=decoded["num_uids"],
|
1084
|
+
max_uids=decoded["max_uids"],
|
1085
|
+
burn=_tbwu(decoded["burn"]),
|
1086
|
+
difficulty=u64tf(decoded["difficulty"]),
|
1087
|
+
registration_allowed=decoded["registration_allowed"],
|
1088
|
+
pow_registration_allowed=decoded["pow_registration_allowed"],
|
1089
|
+
immunity_period=decoded["immunity_period"],
|
1090
|
+
min_difficulty=u64tf(decoded["min_difficulty"]),
|
1091
|
+
max_difficulty=u64tf(decoded["max_difficulty"]),
|
1092
|
+
min_burn=_tbwu(decoded["min_burn"]),
|
1093
|
+
max_burn=_tbwu(decoded["max_burn"]),
|
1094
|
+
adjustment_alpha=u64tf(decoded["adjustment_alpha"]),
|
1095
|
+
adjustment_interval=decoded["adjustment_interval"],
|
1096
|
+
target_regs_per_interval=decoded["target_regs_per_interval"],
|
1097
|
+
max_regs_per_block=decoded["max_regs_per_block"],
|
1098
|
+
serving_rate_limit=decoded["serving_rate_limit"],
|
1099
|
+
# CR
|
1100
|
+
commit_reveal_weights_enabled=decoded["commit_reveal_weights_enabled"],
|
1101
|
+
commit_reveal_period=decoded["commit_reveal_period"],
|
1102
|
+
# Bonds
|
1103
|
+
liquid_alpha_enabled=decoded["liquid_alpha_enabled"],
|
1104
|
+
alpha_high=u16tf(decoded["alpha_high"]),
|
1105
|
+
alpha_low=u16tf(decoded["alpha_low"]),
|
1106
|
+
bonds_moving_avg=u64tf(decoded["bonds_moving_avg"]),
|
1107
|
+
# Metagraph info.
|
1108
|
+
hotkeys=[decode_account_id(ck) for ck in decoded.get("hotkeys", [])],
|
1109
|
+
coldkeys=[decode_account_id(hk) for hk in decoded.get("coldkeys", [])],
|
1110
|
+
identities=decoded["identities"],
|
1111
|
+
axons=decoded.get("axons", []),
|
1112
|
+
active=decoded["active"],
|
1113
|
+
validator_permit=decoded["validator_permit"],
|
1114
|
+
pruning_score=[u16tf(ps) for ps in decoded.get("pruning_score", [])],
|
1115
|
+
last_update=decoded["last_update"],
|
1116
|
+
emission=[_tbwu(em, _netuid) for em in decoded.get("emission", [])],
|
1117
|
+
dividends=[u16tf(dv) for dv in decoded.get("dividends", [])],
|
1118
|
+
incentives=[u16tf(ic) for ic in decoded.get("incentives", [])],
|
1119
|
+
consensus=[u16tf(cs) for cs in decoded.get("consensus", [])],
|
1120
|
+
trust=[u16tf(tr) for tr in decoded.get("trust", [])],
|
1121
|
+
rank=[u16tf(rk) for rk in decoded.get("rank", [])],
|
1122
|
+
block_at_registration=decoded["block_at_registration"],
|
1123
|
+
alpha_stake=[_tbwu(ast, _netuid) for ast in decoded["alpha_stake"]],
|
1124
|
+
tao_stake=[_tbwu(ts) for ts in decoded["tao_stake"]],
|
1125
|
+
total_stake=[_tbwu(ts, _netuid) for ts in decoded["total_stake"]],
|
1126
|
+
# Dividend break down
|
1127
|
+
tao_dividends_per_hotkey=[
|
1128
|
+
(decode_account_id(alpha[0]), _tbwu(alpha[1]))
|
1129
|
+
for alpha in decoded["tao_dividends_per_hotkey"]
|
1130
|
+
],
|
1131
|
+
alpha_dividends_per_hotkey=[
|
1132
|
+
(decode_account_id(adphk[0]), _tbwu(adphk[1], _netuid))
|
1133
|
+
for adphk in decoded["alpha_dividends_per_hotkey"]
|
1134
|
+
],
|
1135
|
+
)
|
@@ -20,6 +20,7 @@ from bittensor_cli.src.bittensor.chain_data import (
|
|
20
20
|
decode_hex_identity,
|
21
21
|
DynamicInfo,
|
22
22
|
SubnetState,
|
23
|
+
MetagraphInfo,
|
23
24
|
)
|
24
25
|
from bittensor_cli.src import DelegatesDetails
|
25
26
|
from bittensor_cli.src.bittensor.balances import Balance, fixed_to_float
|
@@ -1252,6 +1253,38 @@ class SubtensorInterface:
|
|
1252
1253
|
else:
|
1253
1254
|
return Balance.from_rao(_result).set_unit(int(netuid))
|
1254
1255
|
|
1256
|
+
async def get_metagraph_info(
|
1257
|
+
self, netuid: int, block_hash: Optional[str] = None
|
1258
|
+
) -> Optional[MetagraphInfo]:
|
1259
|
+
hex_bytes_result = await self.query_runtime_api(
|
1260
|
+
runtime_api="SubnetInfoRuntimeApi",
|
1261
|
+
method="get_metagraph",
|
1262
|
+
params=[netuid],
|
1263
|
+
block_hash=block_hash,
|
1264
|
+
)
|
1265
|
+
|
1266
|
+
if hex_bytes_result is None:
|
1267
|
+
return None
|
1268
|
+
|
1269
|
+
try:
|
1270
|
+
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
1271
|
+
except ValueError:
|
1272
|
+
bytes_result = bytes.fromhex(hex_bytes_result)
|
1273
|
+
|
1274
|
+
return MetagraphInfo.from_any(bytes_result)
|
1275
|
+
|
1276
|
+
async def get_all_metagraphs_info(
|
1277
|
+
self, block_hash: Optional[str] = None
|
1278
|
+
) -> list[MetagraphInfo]:
|
1279
|
+
hex_bytes_result = await self.query_runtime_api(
|
1280
|
+
runtime_api="SubnetInfoRuntimeApi",
|
1281
|
+
method="get_all_metagraphs",
|
1282
|
+
params=[],
|
1283
|
+
block_hash=block_hash,
|
1284
|
+
)
|
1285
|
+
|
1286
|
+
return MetagraphInfo.list_from_any(hex_bytes_result)
|
1287
|
+
|
1255
1288
|
async def multi_get_stake_for_coldkey_and_hotkey_on_netuid(
|
1256
1289
|
self,
|
1257
1290
|
hotkey_ss58s: list[str],
|
@@ -1279,14 +1279,25 @@ def print_linux_dependency_message():
|
|
1279
1279
|
"""Prints the WebKit dependency message for Linux systems."""
|
1280
1280
|
console.print("[red]This command requires WebKit dependencies on Linux.[/red]")
|
1281
1281
|
console.print(
|
1282
|
-
"\nPlease
|
1282
|
+
"\nPlease make sure these packages are installed on your system for PyWry to work:"
|
1283
1283
|
)
|
1284
1284
|
console.print("\nArch Linux / Manjaro:")
|
1285
1285
|
console.print("[green]sudo pacman -S webkit2gtk[/green]")
|
1286
1286
|
console.print("\nDebian / Ubuntu:")
|
1287
1287
|
console.print("[green]sudo apt install libwebkit2gtk-4.0-dev[/green]")
|
1288
|
+
console.print("\nNote for Ubuntu 24.04+ & Debian 13+:")
|
1289
|
+
console.print("You may need these additional steps to install libwebkit2gtk:")
|
1290
|
+
console.print(
|
1291
|
+
"\tCreate a new source file with: [green]sudo vim /etc/apt/sources.list.d/jammy-temp.list[/green]"
|
1292
|
+
)
|
1293
|
+
console.print(
|
1294
|
+
"\tAdd this into the file and save: [green]deb http://archive.ubuntu.com/ubuntu jammy main universe[/green]"
|
1295
|
+
)
|
1296
|
+
console.print(
|
1297
|
+
"\tUpdate the repository and install the webkit dependency: [green]sudo apt update && sudo apt install libwebkit2gtk-4.0-dev[/green]"
|
1298
|
+
)
|
1288
1299
|
console.print("\nFedora / CentOS / AlmaLinux:")
|
1289
|
-
console.print("[green]sudo dnf install gtk3-devel webkit2gtk3-devel[/green]")
|
1300
|
+
console.print("[green]sudo dnf install gtk3-devel webkit2gtk3-devel[/green]\n\n")
|
1290
1301
|
|
1291
1302
|
|
1292
1303
|
def is_linux():
|
@@ -335,8 +335,7 @@ async def stake_move_selection(
|
|
335
335
|
|
336
336
|
|
337
337
|
async def stake_transfer_selection(
|
338
|
-
wallet: Wallet,
|
339
|
-
subtensor: "SubtensorInterface",
|
338
|
+
wallet: Wallet, subtensor: "SubtensorInterface", origin_hotkey: str
|
340
339
|
):
|
341
340
|
"""Selection interface for transferring stakes."""
|
342
341
|
(
|
@@ -353,7 +352,7 @@ async def stake_transfer_selection(
|
|
353
352
|
|
354
353
|
available_stakes = {}
|
355
354
|
for stake in stakes:
|
356
|
-
if stake.stake.tao > 0 and stake.hotkey_ss58 ==
|
355
|
+
if stake.stake.tao > 0 and stake.hotkey_ss58 == origin_hotkey:
|
357
356
|
available_stakes[stake.netuid] = {
|
358
357
|
"hotkey_ss58": stake.hotkey_ss58,
|
359
358
|
"stake": stake.stake,
|
@@ -718,8 +717,9 @@ async def transfer_stake(
|
|
718
717
|
Returns:
|
719
718
|
bool: True if transfer was successful, False otherwise.
|
720
719
|
"""
|
720
|
+
origin_hotkey = origin_hotkey or wallet.hotkey.ss58_address
|
721
721
|
if interactive_selection:
|
722
|
-
selection = await stake_transfer_selection(wallet, subtensor)
|
722
|
+
selection = await stake_transfer_selection(wallet, subtensor, origin_hotkey)
|
723
723
|
origin_netuid = selection["origin_netuid"]
|
724
724
|
amount = selection["amount"]
|
725
725
|
dest_netuid = selection["destination_netuid"]
|