bittensor-cli 9.0.0rc4__py3-none-any.whl → 9.0.2__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 +2 -3
- bittensor_cli/cli.py +254 -99
- bittensor_cli/src/__init__.py +50 -25
- bittensor_cli/src/bittensor/balances.py +1 -1
- bittensor_cli/src/bittensor/chain_data.py +20 -8
- bittensor_cli/src/bittensor/extrinsics/registration.py +26 -34
- bittensor_cli/src/bittensor/extrinsics/root.py +5 -11
- bittensor_cli/src/bittensor/extrinsics/transfer.py +15 -13
- bittensor_cli/src/bittensor/subtensor_interface.py +20 -20
- bittensor_cli/src/bittensor/utils.py +129 -19
- bittensor_cli/src/commands/stake/add.py +4 -8
- bittensor_cli/src/commands/stake/children_hotkeys.py +13 -19
- bittensor_cli/src/commands/stake/list.py +44 -77
- bittensor_cli/src/commands/stake/move.py +3 -3
- bittensor_cli/src/commands/stake/remove.py +216 -101
- bittensor_cli/src/commands/subnets/subnets.py +147 -5
- bittensor_cli/src/commands/sudo.py +192 -70
- bittensor_cli/src/commands/wallets.py +102 -52
- bittensor_cli/src/commands/weights.py +9 -13
- bittensor_cli/version.py +18 -0
- {bittensor_cli-9.0.0rc4.dist-info → bittensor_cli-9.0.2.dist-info}/METADATA +3 -3
- bittensor_cli-9.0.2.dist-info/RECORD +35 -0
- bittensor_cli-9.0.0rc4.dist-info/RECORD +0 -34
- {bittensor_cli-9.0.0rc4.dist-info → bittensor_cli-9.0.2.dist-info}/WHEEL +0 -0
- {bittensor_cli-9.0.0rc4.dist-info → bittensor_cli-9.0.2.dist-info}/entry_points.txt +0 -0
- {bittensor_cli-9.0.0rc4.dist-info → bittensor_cli-9.0.2.dist-info}/top_level.txt +0 -0
@@ -49,26 +49,36 @@ async def unstake(
|
|
49
49
|
f"Retrieving subnet data & identities from {subtensor.network}...",
|
50
50
|
spinner="earth",
|
51
51
|
):
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
chain_head = await subtensor.substrate.get_chain_head()
|
53
|
+
(
|
54
|
+
all_sn_dynamic_info_,
|
55
|
+
ck_hk_identities,
|
56
|
+
old_identities,
|
57
|
+
stake_infos,
|
58
|
+
) = await asyncio.gather(
|
59
|
+
subtensor.all_subnets(block_hash=chain_head),
|
60
|
+
subtensor.fetch_coldkey_hotkey_identities(block_hash=chain_head),
|
61
|
+
subtensor.get_delegate_identities(block_hash=chain_head),
|
62
|
+
subtensor.get_stake_for_coldkey(
|
63
|
+
wallet.coldkeypub.ss58_address, block_hash=chain_head
|
64
|
+
),
|
56
65
|
)
|
57
66
|
all_sn_dynamic_info = {info.netuid: info for info in all_sn_dynamic_info_}
|
58
67
|
|
59
68
|
if interactive:
|
60
69
|
hotkeys_to_unstake_from, unstake_all_from_hk = await _unstake_selection(
|
61
|
-
subtensor,
|
62
|
-
wallet,
|
63
70
|
all_sn_dynamic_info,
|
64
71
|
ck_hk_identities,
|
65
72
|
old_identities,
|
73
|
+
stake_infos,
|
66
74
|
netuid=netuid,
|
67
75
|
)
|
68
76
|
if unstake_all_from_hk:
|
69
77
|
hotkey_to_unstake_all = hotkeys_to_unstake_from[0]
|
70
78
|
unstake_all_alpha = Confirm.ask(
|
71
|
-
"\
|
79
|
+
"\nDo you want to:\n"
|
80
|
+
"[blue]Yes[/blue]: Unstake from all subnets and automatically restake to subnet 0 (root)\n"
|
81
|
+
"[blue]No[/blue]: Unstake everything (including subnet 0)",
|
72
82
|
default=True,
|
73
83
|
)
|
74
84
|
return await unstake_all(
|
@@ -96,20 +106,17 @@ async def unstake(
|
|
96
106
|
all_hotkeys=all_hotkeys,
|
97
107
|
include_hotkeys=include_hotkeys,
|
98
108
|
exclude_hotkeys=exclude_hotkeys,
|
109
|
+
stake_infos=stake_infos,
|
110
|
+
identities=ck_hk_identities,
|
111
|
+
old_identities=old_identities,
|
99
112
|
)
|
100
113
|
|
101
114
|
with console.status(
|
102
115
|
f"Retrieving stake data from {subtensor.network}...",
|
103
116
|
spinner="earth",
|
104
117
|
):
|
105
|
-
# Fetch stake balances
|
106
|
-
chain_head = await subtensor.substrate.get_chain_head()
|
107
|
-
stake_info_list = await subtensor.get_stake_for_coldkey(
|
108
|
-
coldkey_ss58=wallet.coldkeypub.ss58_address,
|
109
|
-
block_hash=chain_head,
|
110
|
-
)
|
111
118
|
stake_in_netuids = {}
|
112
|
-
for stake_info in
|
119
|
+
for stake_info in stake_infos:
|
113
120
|
if stake_info.hotkey_ss58 not in stake_in_netuids:
|
114
121
|
stake_in_netuids[stake_info.hotkey_ss58] = {}
|
115
122
|
stake_in_netuids[stake_info.hotkey_ss58][stake_info.netuid] = (
|
@@ -313,6 +320,9 @@ async def unstake_all(
|
|
313
320
|
subtensor: "SubtensorInterface",
|
314
321
|
hotkey_ss58_address: str,
|
315
322
|
unstake_all_alpha: bool = False,
|
323
|
+
all_hotkeys: bool = False,
|
324
|
+
include_hotkeys: list[str] = [],
|
325
|
+
exclude_hotkeys: list[str] = [],
|
316
326
|
prompt: bool = True,
|
317
327
|
) -> bool:
|
318
328
|
"""Unstakes all stakes from all hotkeys in all subnets."""
|
@@ -334,10 +344,27 @@ async def unstake_all(
|
|
334
344
|
subtensor.all_subnets(),
|
335
345
|
subtensor.get_balance(wallet.coldkeypub.ss58_address),
|
336
346
|
)
|
337
|
-
|
338
|
-
|
347
|
+
|
348
|
+
if all_hotkeys:
|
349
|
+
hotkeys = _get_hotkeys_to_unstake(
|
350
|
+
wallet,
|
351
|
+
hotkey_ss58_address=hotkey_ss58_address,
|
352
|
+
all_hotkeys=all_hotkeys,
|
353
|
+
include_hotkeys=include_hotkeys,
|
354
|
+
exclude_hotkeys=exclude_hotkeys,
|
355
|
+
stake_infos=stake_info,
|
356
|
+
identities=ck_hk_identities,
|
357
|
+
old_identities=old_identities,
|
358
|
+
)
|
359
|
+
elif not hotkey_ss58_address:
|
360
|
+
hotkeys = [(wallet.hotkey_str, wallet.hotkey.ss58_address)]
|
361
|
+
else:
|
362
|
+
hotkeys = [(None, hotkey_ss58_address)]
|
363
|
+
|
364
|
+
hotkey_names = {ss58: name for name, ss58 in hotkeys if name is not None}
|
365
|
+
hotkey_ss58s = [ss58 for _, ss58 in hotkeys]
|
339
366
|
stake_info = [
|
340
|
-
stake for stake in stake_info if stake.hotkey_ss58
|
367
|
+
stake for stake in stake_info if stake.hotkey_ss58 in hotkey_ss58s
|
341
368
|
]
|
342
369
|
|
343
370
|
if unstake_all_alpha:
|
@@ -403,18 +430,7 @@ async def unstake_all(
|
|
403
430
|
if stake.stake.rao == 0:
|
404
431
|
continue
|
405
432
|
|
406
|
-
|
407
|
-
if hk_identity := ck_hk_identities["hotkeys"].get(stake.hotkey_ss58):
|
408
|
-
hotkey_name = hk_identity.get("identity", {}).get(
|
409
|
-
"name", ""
|
410
|
-
) or hk_identity.get("display", "~")
|
411
|
-
hotkey_display = f"{hotkey_name}"
|
412
|
-
elif old_identity := old_identities.get(stake.hotkey_ss58):
|
413
|
-
hotkey_name = old_identity.display
|
414
|
-
hotkey_display = f"{hotkey_name}"
|
415
|
-
else:
|
416
|
-
hotkey_display = stake.hotkey_ss58
|
417
|
-
|
433
|
+
hotkey_display = hotkey_names.get(stake.hotkey_ss58, stake.hotkey_ss58)
|
418
434
|
subnet_info = all_sn_dynamic_info.get(stake.netuid)
|
419
435
|
stake_amount = stake.stake
|
420
436
|
received_amount, slippage_pct, slippage_pct_float = _calculate_slippage(
|
@@ -455,56 +471,16 @@ async def unstake_all(
|
|
455
471
|
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
456
472
|
return False
|
457
473
|
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
)
|
468
|
-
with console.status(console_status):
|
469
|
-
call_function = "unstake_all_alpha" if unstake_all_alpha else "unstake_all"
|
470
|
-
call = await subtensor.substrate.compose_call(
|
471
|
-
call_module="SubtensorModule",
|
472
|
-
call_function=call_function,
|
473
|
-
call_params={"hotkey": hotkey_ss58_address},
|
474
|
-
)
|
475
|
-
success, error_message = await subtensor.sign_and_send_extrinsic(
|
476
|
-
call=call,
|
477
|
-
wallet=wallet,
|
478
|
-
wait_for_inclusion=True,
|
479
|
-
wait_for_finalization=False,
|
480
|
-
)
|
481
|
-
|
482
|
-
if success:
|
483
|
-
success_message = (
|
484
|
-
":white_heavy_check_mark: [green]Successfully unstaked all stakes[/green]"
|
485
|
-
if not unstake_all_alpha
|
486
|
-
else ":white_heavy_check_mark: [green]Successfully unstaked all Alpha stakes[/green]"
|
487
|
-
)
|
488
|
-
console.print(success_message)
|
489
|
-
new_balance = await subtensor.get_balance(wallet.coldkeypub.ss58_address)
|
490
|
-
console.print(
|
491
|
-
f"Balance:\n [blue]{current_wallet_balance}[/blue] :arrow_right: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{new_balance}"
|
492
|
-
)
|
493
|
-
if unstake_all_alpha:
|
494
|
-
root_stake = await subtensor.get_stake(
|
495
|
-
hotkey_ss58=hotkey_ss58_address,
|
496
|
-
coldkey_ss58=wallet.coldkeypub.ss58_address,
|
497
|
-
netuid=0,
|
498
|
-
)
|
499
|
-
console.print(
|
500
|
-
f"Root Stake:\n [blue]{previous_root_stake}[/blue] :arrow_right: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{root_stake}"
|
501
|
-
)
|
502
|
-
return True
|
503
|
-
else:
|
504
|
-
err_console.print(
|
505
|
-
f":cross_mark: [red]Failed to unstake[/red]: {error_message}"
|
474
|
+
with console.status("Unstaking all stakes...") as status:
|
475
|
+
for hotkey_ss58 in hotkey_ss58s:
|
476
|
+
await _unstake_all_extrinsic(
|
477
|
+
wallet=wallet,
|
478
|
+
subtensor=subtensor,
|
479
|
+
hotkey_ss58=hotkey_ss58,
|
480
|
+
hotkey_name=hotkey_names.get(hotkey_ss58, hotkey_ss58),
|
481
|
+
unstake_all_alpha=unstake_all_alpha,
|
482
|
+
status=status,
|
506
483
|
)
|
507
|
-
return False
|
508
484
|
|
509
485
|
|
510
486
|
# Extrinsics
|
@@ -561,7 +537,7 @@ async def _unstake_extrinsic(
|
|
561
537
|
if not await response.is_success:
|
562
538
|
err_out(
|
563
539
|
f"{failure_prelude} with error: "
|
564
|
-
f"{format_error_message(await response.error_message
|
540
|
+
f"{format_error_message(await response.error_message)}"
|
565
541
|
)
|
566
542
|
return
|
567
543
|
|
@@ -666,15 +642,13 @@ async def _safe_unstake_extrinsic(
|
|
666
642
|
)
|
667
643
|
return
|
668
644
|
else:
|
669
|
-
err_out(
|
670
|
-
f"\n{failure_prelude} with error: {format_error_message(e, subtensor.substrate)}"
|
671
|
-
)
|
645
|
+
err_out(f"\n{failure_prelude} with error: {format_error_message(e)}")
|
672
646
|
return
|
673
647
|
|
674
648
|
await response.process_events()
|
675
649
|
if not await response.is_success:
|
676
650
|
err_out(
|
677
|
-
f"\n{failure_prelude} with error: {format_error_message(await response.error_message
|
651
|
+
f"\n{failure_prelude} with error: {format_error_message(await response.error_message)}"
|
678
652
|
)
|
679
653
|
return
|
680
654
|
|
@@ -709,6 +683,115 @@ async def _safe_unstake_extrinsic(
|
|
709
683
|
)
|
710
684
|
|
711
685
|
|
686
|
+
async def _unstake_all_extrinsic(
|
687
|
+
wallet: Wallet,
|
688
|
+
subtensor: "SubtensorInterface",
|
689
|
+
hotkey_ss58: str,
|
690
|
+
hotkey_name: str,
|
691
|
+
unstake_all_alpha: bool,
|
692
|
+
status=None,
|
693
|
+
) -> None:
|
694
|
+
"""Execute an unstake all extrinsic.
|
695
|
+
|
696
|
+
Args:
|
697
|
+
wallet: Wallet instance
|
698
|
+
subtensor: Subtensor interface
|
699
|
+
hotkey_ss58: Hotkey SS58 address
|
700
|
+
hotkey_name: Display name of the hotkey
|
701
|
+
unstake_all_alpha: Whether to unstake only alpha stakes
|
702
|
+
status: Optional status for console updates
|
703
|
+
"""
|
704
|
+
err_out = partial(print_error, status=status)
|
705
|
+
failure_prelude = (
|
706
|
+
f":cross_mark: [red]Failed[/red] to unstake all from {hotkey_name}"
|
707
|
+
)
|
708
|
+
|
709
|
+
if status:
|
710
|
+
status.update(
|
711
|
+
f"\n:satellite: {'Unstaking all Alpha stakes' if unstake_all_alpha else 'Unstaking all stakes'} from {hotkey_name} ..."
|
712
|
+
)
|
713
|
+
|
714
|
+
block_hash = await subtensor.substrate.get_chain_head()
|
715
|
+
if unstake_all_alpha:
|
716
|
+
previous_root_stake, current_balance = await asyncio.gather(
|
717
|
+
subtensor.get_stake(
|
718
|
+
hotkey_ss58=hotkey_ss58,
|
719
|
+
coldkey_ss58=wallet.coldkeypub.ss58_address,
|
720
|
+
netuid=0,
|
721
|
+
block_hash=block_hash,
|
722
|
+
),
|
723
|
+
subtensor.get_balance(
|
724
|
+
wallet.coldkeypub.ss58_address, block_hash=block_hash
|
725
|
+
),
|
726
|
+
)
|
727
|
+
else:
|
728
|
+
current_balance = await subtensor.get_balance(
|
729
|
+
wallet.coldkeypub.ss58_address, block_hash=block_hash
|
730
|
+
)
|
731
|
+
|
732
|
+
call_function = "unstake_all_alpha" if unstake_all_alpha else "unstake_all"
|
733
|
+
call = await subtensor.substrate.compose_call(
|
734
|
+
call_module="SubtensorModule",
|
735
|
+
call_function=call_function,
|
736
|
+
call_params={"hotkey": hotkey_ss58},
|
737
|
+
)
|
738
|
+
|
739
|
+
try:
|
740
|
+
response = await subtensor.substrate.submit_extrinsic(
|
741
|
+
extrinsic=await subtensor.substrate.create_signed_extrinsic(
|
742
|
+
call=call,
|
743
|
+
keypair=wallet.coldkey,
|
744
|
+
),
|
745
|
+
wait_for_inclusion=True,
|
746
|
+
wait_for_finalization=False,
|
747
|
+
)
|
748
|
+
await response.process_events()
|
749
|
+
|
750
|
+
if not await response.is_success:
|
751
|
+
err_out(
|
752
|
+
f"{failure_prelude} with error: "
|
753
|
+
f"{format_error_message(await response.error_message)}"
|
754
|
+
)
|
755
|
+
return
|
756
|
+
|
757
|
+
# Fetch latest balance and stake
|
758
|
+
block_hash = await subtensor.substrate.get_chain_head()
|
759
|
+
if unstake_all_alpha:
|
760
|
+
new_root_stake, new_balance = await asyncio.gather(
|
761
|
+
subtensor.get_stake(
|
762
|
+
hotkey_ss58=hotkey_ss58,
|
763
|
+
coldkey_ss58=wallet.coldkeypub.ss58_address,
|
764
|
+
netuid=0,
|
765
|
+
block_hash=block_hash,
|
766
|
+
),
|
767
|
+
subtensor.get_balance(
|
768
|
+
wallet.coldkeypub.ss58_address, block_hash=block_hash
|
769
|
+
),
|
770
|
+
)
|
771
|
+
else:
|
772
|
+
new_balance = await subtensor.get_balance(
|
773
|
+
wallet.coldkeypub.ss58_address, block_hash=block_hash
|
774
|
+
)
|
775
|
+
|
776
|
+
success_message = (
|
777
|
+
":white_heavy_check_mark: [green]Finalized: Successfully unstaked all stakes[/green]"
|
778
|
+
if not unstake_all_alpha
|
779
|
+
else ":white_heavy_check_mark: [green]Finalized: Successfully unstaked all Alpha stakes[/green]"
|
780
|
+
)
|
781
|
+
console.print(f"{success_message} from {hotkey_name}")
|
782
|
+
console.print(
|
783
|
+
f"Balance:\n [blue]{current_balance}[/blue] :arrow_right: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{new_balance}"
|
784
|
+
)
|
785
|
+
|
786
|
+
if unstake_all_alpha:
|
787
|
+
console.print(
|
788
|
+
f"Root Stake for {hotkey_name}:\n [blue]{previous_root_stake}[/blue] :arrow_right: [{COLOR_PALETTE['STAKE']['STAKE_AMOUNT']}]{new_root_stake}"
|
789
|
+
)
|
790
|
+
|
791
|
+
except Exception as e:
|
792
|
+
err_out(f"{failure_prelude} with error: {str(e)}")
|
793
|
+
|
794
|
+
|
712
795
|
# Helpers
|
713
796
|
def _calculate_slippage(subnet_info, amount: Balance) -> tuple[Balance, str, float]:
|
714
797
|
"""Calculate slippage and received amount for unstaking operation.
|
@@ -737,17 +820,12 @@ def _calculate_slippage(subnet_info, amount: Balance) -> tuple[Balance, str, flo
|
|
737
820
|
|
738
821
|
|
739
822
|
async def _unstake_selection(
|
740
|
-
subtensor: "SubtensorInterface",
|
741
|
-
wallet: Wallet,
|
742
823
|
dynamic_info,
|
743
824
|
identities,
|
744
825
|
old_identities,
|
826
|
+
stake_infos,
|
745
827
|
netuid: Optional[int] = None,
|
746
828
|
):
|
747
|
-
stake_infos = await subtensor.get_stake_for_coldkey(
|
748
|
-
coldkey_ss58=wallet.coldkeypub.ss58_address
|
749
|
-
)
|
750
|
-
|
751
829
|
if not stake_infos:
|
752
830
|
print_error("You have no stakes to unstake.")
|
753
831
|
raise typer.Exit()
|
@@ -771,16 +849,11 @@ async def _unstake_selection(
|
|
771
849
|
|
772
850
|
hotkeys_info = []
|
773
851
|
for idx, (hotkey_ss58, netuid_stakes) in enumerate(hotkey_stakes.items()):
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
hotkey_name = old_identity.display
|
780
|
-
else:
|
781
|
-
hotkey_name = "~"
|
782
|
-
# TODO: Add wallet ids here.
|
783
|
-
|
852
|
+
hotkey_name = get_hotkey_identity(
|
853
|
+
hotkey_ss58=hotkey_ss58,
|
854
|
+
identities=identities,
|
855
|
+
old_identities=old_identities,
|
856
|
+
)
|
784
857
|
hotkeys_info.append(
|
785
858
|
{
|
786
859
|
"index": idx,
|
@@ -983,6 +1056,9 @@ def _get_hotkeys_to_unstake(
|
|
983
1056
|
all_hotkeys: bool,
|
984
1057
|
include_hotkeys: list[str],
|
985
1058
|
exclude_hotkeys: list[str],
|
1059
|
+
stake_infos: list,
|
1060
|
+
identities: dict,
|
1061
|
+
old_identities: dict,
|
986
1062
|
) -> list[tuple[Optional[str], str]]:
|
987
1063
|
"""Get list of hotkeys to unstake from based on input parameters.
|
988
1064
|
|
@@ -1002,13 +1078,27 @@ def _get_hotkeys_to_unstake(
|
|
1002
1078
|
|
1003
1079
|
if all_hotkeys:
|
1004
1080
|
print_verbose("Unstaking from all hotkeys")
|
1005
|
-
all_hotkeys_
|
1006
|
-
|
1081
|
+
all_hotkeys_ = get_hotkey_wallets_for_wallet(wallet=wallet)
|
1082
|
+
wallet_hotkeys = [
|
1007
1083
|
(wallet.hotkey_str, wallet.hotkey.ss58_address)
|
1008
1084
|
for wallet in all_hotkeys_
|
1009
1085
|
if wallet.hotkey_str not in exclude_hotkeys
|
1010
1086
|
]
|
1011
1087
|
|
1088
|
+
wallet_hotkey_addresses = {addr for _, addr in wallet_hotkeys}
|
1089
|
+
chain_hotkeys = [
|
1090
|
+
(
|
1091
|
+
get_hotkey_identity(stake_info.hotkey_ss58, identities, old_identities),
|
1092
|
+
stake_info.hotkey_ss58,
|
1093
|
+
)
|
1094
|
+
for stake_info in stake_infos
|
1095
|
+
if (
|
1096
|
+
stake_info.hotkey_ss58 not in wallet_hotkey_addresses
|
1097
|
+
and stake_info.hotkey_ss58 not in exclude_hotkeys
|
1098
|
+
)
|
1099
|
+
]
|
1100
|
+
return wallet_hotkeys + chain_hotkeys
|
1101
|
+
|
1012
1102
|
if include_hotkeys:
|
1013
1103
|
print_verbose("Unstaking from included hotkeys")
|
1014
1104
|
result = []
|
@@ -1144,3 +1234,28 @@ The columns are as follows:
|
|
1144
1234
|
- [bold white]Partial unstaking[/bold white]: If True, allows unstaking up to the rate tolerance limit. If False, the entire transaction will fail if rate tolerance is exceeded.\n"""
|
1145
1235
|
|
1146
1236
|
console.print(base_description + (safe_staking_description if safe_staking else ""))
|
1237
|
+
|
1238
|
+
|
1239
|
+
def get_hotkey_identity(
|
1240
|
+
hotkey_ss58: str,
|
1241
|
+
identities: dict,
|
1242
|
+
old_identities: dict,
|
1243
|
+
) -> str:
|
1244
|
+
"""Get identity name for a hotkey from identities or old_identities.
|
1245
|
+
|
1246
|
+
Args:
|
1247
|
+
hotkey_ss58 (str): The hotkey SS58 address
|
1248
|
+
identities (dict): Current identities from fetch_coldkey_hotkey_identities
|
1249
|
+
old_identities (dict): Old identities from get_delegate_identities
|
1250
|
+
|
1251
|
+
Returns:
|
1252
|
+
str: Identity name or truncated address
|
1253
|
+
"""
|
1254
|
+
if hk_identity := identities["hotkeys"].get(hotkey_ss58):
|
1255
|
+
return hk_identity.get("identity", {}).get("name", "") or hk_identity.get(
|
1256
|
+
"display", "~"
|
1257
|
+
)
|
1258
|
+
elif old_identity := old_identities.get(hotkey_ss58):
|
1259
|
+
return old_identity.display
|
1260
|
+
else:
|
1261
|
+
return f"{hotkey_ss58[:4]}...{hotkey_ss58[-4:]}"
|
@@ -35,12 +35,13 @@ from bittensor_cli.src.bittensor.utils import (
|
|
35
35
|
update_metadata_table,
|
36
36
|
prompt_for_identity,
|
37
37
|
get_subnet_name,
|
38
|
+
unlock_key,
|
38
39
|
)
|
39
40
|
|
40
41
|
if TYPE_CHECKING:
|
41
42
|
from bittensor_cli.src.bittensor.subtensor_interface import SubtensorInterface
|
42
43
|
|
43
|
-
TAO_WEIGHT = 0.
|
44
|
+
TAO_WEIGHT = 0.18
|
44
45
|
|
45
46
|
# helpers and extrinsics
|
46
47
|
|
@@ -183,7 +184,7 @@ async def register_subnetwork_extrinsic(
|
|
183
184
|
await response.process_events()
|
184
185
|
if not await response.is_success:
|
185
186
|
err_console.print(
|
186
|
-
f":cross_mark: [red]Failed[/red]: {format_error_message(await response.error_message
|
187
|
+
f":cross_mark: [red]Failed[/red]: {format_error_message(await response.error_message)}"
|
187
188
|
)
|
188
189
|
await asyncio.sleep(0.5)
|
189
190
|
return False
|
@@ -888,8 +889,8 @@ async def show(
|
|
888
889
|
total_emission_per_block = 0
|
889
890
|
for netuid_ in range(len(all_subnets)):
|
890
891
|
subnet = all_subnets[netuid_]
|
891
|
-
emission_on_subnet = (
|
892
|
-
|
892
|
+
emission_on_subnet = root_state.emission_history[netuid_][idx] / (
|
893
|
+
subnet.tempo or 1
|
893
894
|
)
|
894
895
|
total_emission_per_block += subnet.alpha_to_tao(
|
895
896
|
Balance.from_rao(emission_on_subnet)
|
@@ -1322,7 +1323,7 @@ async def show(
|
|
1322
1323
|
return hotkey
|
1323
1324
|
else:
|
1324
1325
|
console.print(
|
1325
|
-
|
1326
|
+
"[red]Invalid UID. Please enter a valid UID from the table above[/red]"
|
1326
1327
|
)
|
1327
1328
|
except ValueError:
|
1328
1329
|
console.print("[red]Please enter a valid number[/red]")
|
@@ -2026,3 +2027,144 @@ async def metagraph_cmd(
|
|
2026
2027
|
table.add_row(*row)
|
2027
2028
|
|
2028
2029
|
console.print(table)
|
2030
|
+
|
2031
|
+
|
2032
|
+
def create_identity_table(title: str = None):
|
2033
|
+
if not title:
|
2034
|
+
title = "Subnet Identity"
|
2035
|
+
|
2036
|
+
table = Table(
|
2037
|
+
Column(
|
2038
|
+
"Item",
|
2039
|
+
justify="right",
|
2040
|
+
style=COLOR_PALETTE["GENERAL"]["SUBHEADING_MAIN"],
|
2041
|
+
no_wrap=True,
|
2042
|
+
),
|
2043
|
+
Column("Value", style=COLOR_PALETTE["GENERAL"]["SUBHEADING"]),
|
2044
|
+
title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]{title}\n",
|
2045
|
+
show_footer=True,
|
2046
|
+
show_edge=False,
|
2047
|
+
header_style="bold white",
|
2048
|
+
border_style="bright_black",
|
2049
|
+
style="bold",
|
2050
|
+
title_justify="center",
|
2051
|
+
show_lines=False,
|
2052
|
+
pad_edge=True,
|
2053
|
+
)
|
2054
|
+
return table
|
2055
|
+
|
2056
|
+
|
2057
|
+
async def set_identity(
|
2058
|
+
wallet: "Wallet",
|
2059
|
+
subtensor: "SubtensorInterface",
|
2060
|
+
netuid: int,
|
2061
|
+
subnet_identity: dict,
|
2062
|
+
prompt: bool = False,
|
2063
|
+
) -> bool:
|
2064
|
+
"""Set identity information for a subnet"""
|
2065
|
+
|
2066
|
+
if not await subtensor.subnet_exists(netuid):
|
2067
|
+
err_console.print(f"Subnet {netuid} does not exist")
|
2068
|
+
return False
|
2069
|
+
|
2070
|
+
identity_data = {
|
2071
|
+
"netuid": netuid,
|
2072
|
+
"subnet_name": subnet_identity.get("subnet_name", ""),
|
2073
|
+
"github_repo": subnet_identity.get("github_repo", ""),
|
2074
|
+
"subnet_contact": subnet_identity.get("subnet_contact", ""),
|
2075
|
+
"subnet_url": subnet_identity.get("subnet_url", ""),
|
2076
|
+
"discord": subnet_identity.get("discord", ""),
|
2077
|
+
"description": subnet_identity.get("description", ""),
|
2078
|
+
"additional": subnet_identity.get("additional", ""),
|
2079
|
+
}
|
2080
|
+
|
2081
|
+
if not unlock_key(wallet).success:
|
2082
|
+
return False
|
2083
|
+
|
2084
|
+
if prompt:
|
2085
|
+
if not Confirm.ask(
|
2086
|
+
"Are you sure you want to set subnet's identity? This is subject to a fee."
|
2087
|
+
):
|
2088
|
+
return False
|
2089
|
+
|
2090
|
+
call = await subtensor.substrate.compose_call(
|
2091
|
+
call_module="SubtensorModule",
|
2092
|
+
call_function="set_subnet_identity",
|
2093
|
+
call_params=identity_data,
|
2094
|
+
)
|
2095
|
+
|
2096
|
+
with console.status(
|
2097
|
+
" :satellite: [dark_sea_green3]Setting subnet identity on-chain...",
|
2098
|
+
spinner="earth",
|
2099
|
+
):
|
2100
|
+
success, err_msg = await subtensor.sign_and_send_extrinsic(call, wallet)
|
2101
|
+
|
2102
|
+
if not success:
|
2103
|
+
err_console.print(f"[red]:cross_mark: Failed![/red] {err_msg}")
|
2104
|
+
return False
|
2105
|
+
|
2106
|
+
console.print(
|
2107
|
+
":white_heavy_check_mark: [dark_sea_green3]Successfully set subnet identity\n"
|
2108
|
+
)
|
2109
|
+
|
2110
|
+
subnet = await subtensor.subnet(netuid)
|
2111
|
+
identity = subnet.subnet_identity if subnet else None
|
2112
|
+
|
2113
|
+
if identity:
|
2114
|
+
table = create_identity_table(title=f"New Subnet {netuid} Identity")
|
2115
|
+
table.add_row("Netuid", str(netuid))
|
2116
|
+
for key in [
|
2117
|
+
"subnet_name",
|
2118
|
+
"github_repo",
|
2119
|
+
"subnet_contact",
|
2120
|
+
"subnet_url",
|
2121
|
+
"discord",
|
2122
|
+
"description",
|
2123
|
+
"additional",
|
2124
|
+
]:
|
2125
|
+
value = getattr(identity, key, None)
|
2126
|
+
table.add_row(key, str(value) if value else "~")
|
2127
|
+
console.print(table)
|
2128
|
+
|
2129
|
+
return True
|
2130
|
+
|
2131
|
+
|
2132
|
+
async def get_identity(subtensor: "SubtensorInterface", netuid: int, title: str = None):
|
2133
|
+
"""Fetch and display existing subnet identity information."""
|
2134
|
+
if not title:
|
2135
|
+
title = "Subnet Identity"
|
2136
|
+
|
2137
|
+
if not await subtensor.subnet_exists(netuid):
|
2138
|
+
print_error(f"Subnet {netuid} does not exist.")
|
2139
|
+
raise typer.Exit()
|
2140
|
+
|
2141
|
+
with console.status(
|
2142
|
+
":satellite: [bold green]Querying subnet identity...", spinner="earth"
|
2143
|
+
):
|
2144
|
+
subnet = await subtensor.subnet(netuid)
|
2145
|
+
identity = subnet.subnet_identity if subnet else None
|
2146
|
+
|
2147
|
+
if not identity:
|
2148
|
+
err_console.print(
|
2149
|
+
f"Existing subnet identity not found"
|
2150
|
+
f" for subnet [blue]{netuid}[/blue]"
|
2151
|
+
f" on {subtensor}"
|
2152
|
+
)
|
2153
|
+
return {}
|
2154
|
+
|
2155
|
+
if identity:
|
2156
|
+
table = create_identity_table(title=f"Current Subnet {netuid} Identity")
|
2157
|
+
table.add_row("Netuid", str(netuid))
|
2158
|
+
for key in [
|
2159
|
+
"subnet_name",
|
2160
|
+
"github_repo",
|
2161
|
+
"subnet_contact",
|
2162
|
+
"subnet_url",
|
2163
|
+
"discord",
|
2164
|
+
"description",
|
2165
|
+
"additional",
|
2166
|
+
]:
|
2167
|
+
value = getattr(identity, key, None)
|
2168
|
+
table.add_row(key, str(value) if value else "~")
|
2169
|
+
console.print(table)
|
2170
|
+
return identity
|