bittensor-cli 9.1.4__py3-none-any.whl → 9.3.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 +525 -131
- bittensor_cli/src/__init__.py +444 -465
- bittensor_cli/src/bittensor/chain_data.py +6 -2
- bittensor_cli/src/bittensor/extrinsics/registration.py +47 -23
- bittensor_cli/src/bittensor/extrinsics/root.py +10 -11
- bittensor_cli/src/bittensor/extrinsics/transfer.py +5 -3
- bittensor_cli/src/bittensor/subtensor_interface.py +125 -5
- bittensor_cli/src/bittensor/utils.py +4 -1
- bittensor_cli/src/commands/stake/add.py +169 -108
- bittensor_cli/src/commands/stake/children_hotkeys.py +120 -79
- bittensor_cli/src/commands/stake/list.py +54 -20
- bittensor_cli/src/commands/stake/move.py +58 -18
- bittensor_cli/src/commands/stake/remove.py +174 -92
- bittensor_cli/src/commands/subnets/price.py +11 -9
- bittensor_cli/src/commands/subnets/subnets.py +223 -80
- bittensor_cli/src/commands/sudo.py +76 -22
- bittensor_cli/src/commands/wallets.py +656 -40
- bittensor_cli/src/commands/weights.py +21 -11
- bittensor_cli/version.py +2 -1
- {bittensor_cli-9.1.4.dist-info → bittensor_cli-9.3.0.dist-info}/METADATA +30 -11
- bittensor_cli-9.3.0.dist-info/RECORD +35 -0
- {bittensor_cli-9.1.4.dist-info → bittensor_cli-9.3.0.dist-info}/WHEEL +1 -1
- bittensor_cli-9.1.4.dist-info/RECORD +0 -35
- {bittensor_cli-9.1.4.dist-info → bittensor_cli-9.3.0.dist-info}/entry_points.txt +0 -0
- {bittensor_cli-9.1.4.dist-info → bittensor_cli-9.3.0.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,9 @@
|
|
1
1
|
import asyncio
|
2
|
+
import json
|
2
3
|
from typing import Optional
|
3
4
|
|
4
5
|
from bittensor_wallet import Wallet
|
5
|
-
from rich.prompt import Confirm,
|
6
|
+
from rich.prompt import Confirm, IntPrompt, FloatPrompt
|
6
7
|
from rich.table import Table
|
7
8
|
from rich.text import Text
|
8
9
|
from async_substrate_interface.errors import SubstrateRequestException
|
@@ -19,6 +20,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
19
20
|
is_valid_ss58_address,
|
20
21
|
format_error_message,
|
21
22
|
unlock_key,
|
23
|
+
json_console,
|
22
24
|
)
|
23
25
|
|
24
26
|
|
@@ -28,24 +30,22 @@ async def get_childkey_completion_block(
|
|
28
30
|
"""
|
29
31
|
Calculates the block at which the childkey set request will complete
|
30
32
|
"""
|
33
|
+
bh = await subtensor.substrate.get_chain_head()
|
31
34
|
blocks_since_last_step_query = subtensor.query(
|
32
|
-
"SubtensorModule",
|
33
|
-
"BlocksSinceLastStep",
|
34
|
-
params=[netuid],
|
35
|
+
"SubtensorModule", "BlocksSinceLastStep", params=[netuid], block_hash=bh
|
35
36
|
)
|
36
37
|
tempo_query = subtensor.get_hyperparameter(
|
37
|
-
param_name="Tempo",
|
38
|
-
netuid=netuid,
|
38
|
+
param_name="Tempo", netuid=netuid, block_hash=bh
|
39
39
|
)
|
40
40
|
block_number, blocks_since_last_step, tempo = await asyncio.gather(
|
41
|
-
subtensor.substrate.get_block_number(),
|
41
|
+
subtensor.substrate.get_block_number(block_hash=bh),
|
42
42
|
blocks_since_last_step_query,
|
43
43
|
tempo_query,
|
44
44
|
)
|
45
|
-
cooldown = block_number +
|
45
|
+
cooldown = block_number + 7200
|
46
46
|
blocks_left_in_tempo = tempo - blocks_since_last_step
|
47
47
|
next_tempo = block_number + blocks_left_in_tempo
|
48
|
-
next_epoch_after_cooldown = (cooldown - next_tempo) % tempo + cooldown
|
48
|
+
next_epoch_after_cooldown = (cooldown - next_tempo) % (tempo + 1) + cooldown
|
49
49
|
return block_number, next_epoch_after_cooldown
|
50
50
|
|
51
51
|
|
@@ -84,7 +84,7 @@ async def set_children_extrinsic(
|
|
84
84
|
if prompt:
|
85
85
|
if all_revoked:
|
86
86
|
if not Confirm.ask(
|
87
|
-
f"Do you want to revoke all children hotkeys for hotkey {hotkey}?"
|
87
|
+
f"Do you want to revoke all children hotkeys for hotkey {hotkey} on netuid {netuid}?"
|
88
88
|
):
|
89
89
|
return False, "Operation Cancelled"
|
90
90
|
else:
|
@@ -134,17 +134,9 @@ async def set_children_extrinsic(
|
|
134
134
|
console.print(":white_heavy_check_mark: [green]Included[/green]")
|
135
135
|
if wait_for_finalization:
|
136
136
|
console.print(":white_heavy_check_mark: [green]Finalized[/green]")
|
137
|
-
# bittensor.logging.success(
|
138
|
-
# prefix=operation,
|
139
|
-
# suffix="<green>Finalized: </green>" + str(success),
|
140
|
-
# )
|
141
137
|
return True, f"Successfully {operation.lower()} and Finalized."
|
142
138
|
else:
|
143
139
|
err_console.print(f":cross_mark: [red]Failed[/red]: {error_message}")
|
144
|
-
# bittensor.logging.warning(
|
145
|
-
# prefix=operation,
|
146
|
-
# suffix="<red>Failed: </red>" + str(error_message),
|
147
|
-
# )
|
148
140
|
return False, error_message
|
149
141
|
|
150
142
|
|
@@ -503,6 +495,7 @@ async def set_children(
|
|
503
495
|
wait_for_inclusion: bool = True,
|
504
496
|
wait_for_finalization: bool = True,
|
505
497
|
prompt: bool = True,
|
498
|
+
json_output: bool = False,
|
506
499
|
):
|
507
500
|
"""Set children hotkeys."""
|
508
501
|
# Validate children SS58 addresses
|
@@ -523,6 +516,7 @@ async def set_children(
|
|
523
516
|
f"Proposed sum of proportions is {total_proposed}."
|
524
517
|
)
|
525
518
|
children_with_proportions = list(zip(proportions, children))
|
519
|
+
successes = {}
|
526
520
|
if netuid is not None:
|
527
521
|
success, message = await set_children_extrinsic(
|
528
522
|
subtensor=subtensor,
|
@@ -534,12 +528,20 @@ async def set_children(
|
|
534
528
|
wait_for_inclusion=wait_for_inclusion,
|
535
529
|
wait_for_finalization=wait_for_finalization,
|
536
530
|
)
|
531
|
+
successes[netuid] = {
|
532
|
+
"success": success,
|
533
|
+
"error": message,
|
534
|
+
"completion_block": None,
|
535
|
+
"set_block": None,
|
536
|
+
}
|
537
537
|
# Result
|
538
538
|
if success:
|
539
539
|
if wait_for_inclusion and wait_for_finalization:
|
540
540
|
current_block, completion_block = await get_childkey_completion_block(
|
541
541
|
subtensor, netuid
|
542
542
|
)
|
543
|
+
successes[netuid]["completion_block"] = completion_block
|
544
|
+
successes[netuid]["set_block"] = current_block
|
543
545
|
console.print(
|
544
546
|
f"Your childkey request has been submitted. It will be completed around block {completion_block}. "
|
545
547
|
f"The current block is {current_block}"
|
@@ -558,7 +560,7 @@ async def set_children(
|
|
558
560
|
if netuid_ == 0: # dont include root network
|
559
561
|
continue
|
560
562
|
console.print(f"Setting children on netuid {netuid_}.")
|
561
|
-
await set_children_extrinsic(
|
563
|
+
success, message = await set_children_extrinsic(
|
562
564
|
subtensor=subtensor,
|
563
565
|
wallet=wallet,
|
564
566
|
netuid=netuid_,
|
@@ -571,6 +573,12 @@ async def set_children(
|
|
571
573
|
current_block, completion_block = await get_childkey_completion_block(
|
572
574
|
subtensor, netuid_
|
573
575
|
)
|
576
|
+
successes[netuid_] = {
|
577
|
+
"success": success,
|
578
|
+
"error": message,
|
579
|
+
"completion_block": completion_block,
|
580
|
+
"set_block": current_block,
|
581
|
+
}
|
574
582
|
console.print(
|
575
583
|
f"Your childkey request for netuid {netuid_} has been submitted. It will be completed around "
|
576
584
|
f"block {completion_block}. The current block is {current_block}."
|
@@ -578,6 +586,8 @@ async def set_children(
|
|
578
586
|
console.print(
|
579
587
|
":white_heavy_check_mark: [green]Sent set children request for all subnets.[/green]"
|
580
588
|
)
|
589
|
+
if json_output:
|
590
|
+
json_console.print(json.dumps(successes))
|
581
591
|
|
582
592
|
|
583
593
|
async def revoke_children(
|
@@ -587,11 +597,13 @@ async def revoke_children(
|
|
587
597
|
wait_for_inclusion: bool = True,
|
588
598
|
wait_for_finalization: bool = True,
|
589
599
|
prompt: bool = True,
|
600
|
+
json_output: bool = False,
|
590
601
|
):
|
591
602
|
"""
|
592
603
|
Revokes the children hotkeys associated with a given network identifier (netuid).
|
593
604
|
"""
|
594
|
-
|
605
|
+
dict_output = {}
|
606
|
+
if netuid is not None:
|
595
607
|
success, message = await set_children_extrinsic(
|
596
608
|
subtensor=subtensor,
|
597
609
|
wallet=wallet,
|
@@ -602,13 +614,23 @@ async def revoke_children(
|
|
602
614
|
wait_for_inclusion=wait_for_inclusion,
|
603
615
|
wait_for_finalization=wait_for_finalization,
|
604
616
|
)
|
617
|
+
dict_output[netuid] = {
|
618
|
+
"success": success,
|
619
|
+
"error": message,
|
620
|
+
"set_block": None,
|
621
|
+
"completion_block": None,
|
622
|
+
}
|
605
623
|
|
606
624
|
# Result
|
607
625
|
if success:
|
608
|
-
|
609
|
-
|
626
|
+
current_block, completion_block = await get_childkey_completion_block(
|
627
|
+
subtensor, netuid
|
628
|
+
)
|
629
|
+
dict_output[netuid]["completion_block"] = completion_block
|
630
|
+
dict_output[netuid]["set_block"] = current_block
|
610
631
|
console.print(
|
611
|
-
":white_heavy_check_mark:
|
632
|
+
f":white_heavy_check_mark: Your childkey revocation request for netuid {netuid} has been submitted. "
|
633
|
+
f"It will be completed around block {completion_block}. The current block is {current_block}"
|
612
634
|
)
|
613
635
|
else:
|
614
636
|
console.print(
|
@@ -617,11 +639,11 @@ async def revoke_children(
|
|
617
639
|
else:
|
618
640
|
# revoke children from ALL netuids
|
619
641
|
netuids = await subtensor.get_all_subnet_netuids()
|
620
|
-
for
|
621
|
-
if
|
642
|
+
for netuid_ in netuids:
|
643
|
+
if netuid_ == 0: # dont include root network
|
622
644
|
continue
|
623
|
-
console.print(f"Revoking children from netuid {
|
624
|
-
await set_children_extrinsic(
|
645
|
+
console.print(f"Revoking children from netuid {netuid_}.")
|
646
|
+
success, message = await set_children_extrinsic(
|
625
647
|
subtensor=subtensor,
|
626
648
|
wallet=wallet,
|
627
649
|
netuid=netuid,
|
@@ -631,9 +653,29 @@ async def revoke_children(
|
|
631
653
|
wait_for_inclusion=True,
|
632
654
|
wait_for_finalization=False,
|
633
655
|
)
|
634
|
-
|
635
|
-
|
636
|
-
|
656
|
+
dict_output[netuid_] = {
|
657
|
+
"success": success,
|
658
|
+
"error": message,
|
659
|
+
"set_block": None,
|
660
|
+
"completion_block": None,
|
661
|
+
}
|
662
|
+
if success:
|
663
|
+
current_block, completion_block = await get_childkey_completion_block(
|
664
|
+
subtensor, netuid_
|
665
|
+
)
|
666
|
+
dict_output[netuid_]["completion_block"] = completion_block
|
667
|
+
dict_output[netuid_]["set_block"] = current_block
|
668
|
+
console.print(
|
669
|
+
f":white_heavy_check_mark: Your childkey revocation request for netuid {netuid_} has been "
|
670
|
+
f"submitted. It will be completed around block {completion_block}. The current block "
|
671
|
+
f"is {current_block}"
|
672
|
+
)
|
673
|
+
else:
|
674
|
+
err_console.print(
|
675
|
+
f"Childkey revocation failed for netuid {netuid_}: {message}."
|
676
|
+
)
|
677
|
+
if json_output:
|
678
|
+
json_console.print(json.dumps(dict_output))
|
637
679
|
|
638
680
|
|
639
681
|
async def childkey_take(
|
@@ -645,8 +687,13 @@ async def childkey_take(
|
|
645
687
|
wait_for_inclusion: bool = True,
|
646
688
|
wait_for_finalization: bool = True,
|
647
689
|
prompt: bool = True,
|
648
|
-
):
|
649
|
-
"""
|
690
|
+
) -> list[tuple[Optional[int], bool]]:
|
691
|
+
"""
|
692
|
+
Get or Set childkey take.
|
693
|
+
|
694
|
+
Returns:
|
695
|
+
List of (netuid, success) for specified netuid (or all) and their success in setting take
|
696
|
+
"""
|
650
697
|
|
651
698
|
def validate_take_value(take_value: float) -> bool:
|
652
699
|
if not (0 <= take_value <= 0.18):
|
@@ -656,20 +703,7 @@ async def childkey_take(
|
|
656
703
|
return False
|
657
704
|
return True
|
658
705
|
|
659
|
-
def
|
660
|
-
"""Print table with netuids and Takes"""
|
661
|
-
table = Table(
|
662
|
-
title=f"Current Child Takes for [bright_magenta]{ss58}[/bright_magenta]"
|
663
|
-
)
|
664
|
-
table.add_column("Netuid", justify="center", style="cyan")
|
665
|
-
table.add_column("Take (%)", justify="right", style="magenta")
|
666
|
-
|
667
|
-
for take_netuid, take_value in takes:
|
668
|
-
table.add_row(str(take_netuid), f"{take_value:.2f}%")
|
669
|
-
|
670
|
-
console.print(table)
|
671
|
-
|
672
|
-
async def display_chk_take(ss58, take_netuid):
|
706
|
+
async def display_chk_take(ss58, take_netuid) -> float:
|
673
707
|
"""Print single key take for hotkey and netuid"""
|
674
708
|
chk_take = await get_childkey_take(
|
675
709
|
subtensor=subtensor, netuid=take_netuid, hotkey=ss58
|
@@ -680,6 +714,7 @@ async def childkey_take(
|
|
680
714
|
console.print(
|
681
715
|
f"Child take for {ss58} is: {chk_take * 100:.2f}% on netuid {take_netuid}."
|
682
716
|
)
|
717
|
+
return chk_take
|
683
718
|
|
684
719
|
async def chk_all_subnets(ss58):
|
685
720
|
"""Aggregate data for childkey take from all subnets"""
|
@@ -694,10 +729,18 @@ async def childkey_take(
|
|
694
729
|
if curr_take is not None:
|
695
730
|
take_value = u16_to_float(curr_take)
|
696
731
|
takes.append((subnet, take_value * 100))
|
732
|
+
table = Table(
|
733
|
+
title=f"Current Child Takes for [bright_magenta]{ss58}[/bright_magenta]"
|
734
|
+
)
|
735
|
+
table.add_column("Netuid", justify="center", style="cyan")
|
736
|
+
table.add_column("Take (%)", justify="right", style="magenta")
|
697
737
|
|
698
|
-
|
738
|
+
for take_netuid, take_value in takes:
|
739
|
+
table.add_row(str(take_netuid), f"{take_value:.2f}%")
|
740
|
+
|
741
|
+
console.print(table)
|
699
742
|
|
700
|
-
async def set_chk_take_subnet(subnet, chk_take):
|
743
|
+
async def set_chk_take_subnet(subnet: int, chk_take: float) -> bool:
|
701
744
|
"""Set the childkey take for a single subnet"""
|
702
745
|
success, message = await set_childkey_take_extrinsic(
|
703
746
|
subtensor=subtensor,
|
@@ -715,13 +758,17 @@ async def childkey_take(
|
|
715
758
|
console.print(
|
716
759
|
f"The childkey take for {wallet.hotkey.ss58_address} is now set to {take * 100:.2f}%."
|
717
760
|
)
|
761
|
+
return True
|
718
762
|
else:
|
719
763
|
console.print(
|
720
764
|
f":cross_mark:[red] Unable to set childkey take.[/red] {message}"
|
721
765
|
)
|
766
|
+
return False
|
722
767
|
|
723
768
|
# Print childkey take for other user and return (dont offer to change take rate)
|
724
|
-
if hotkey
|
769
|
+
if not hotkey or hotkey == wallet.hotkey.ss58_address:
|
770
|
+
hotkey = wallet.hotkey.ss58_address
|
771
|
+
if hotkey != wallet.hotkey.ss58_address or not take:
|
725
772
|
# display childkey take for other users
|
726
773
|
if netuid:
|
727
774
|
await display_chk_take(hotkey, netuid)
|
@@ -729,70 +776,64 @@ async def childkey_take(
|
|
729
776
|
console.print(
|
730
777
|
f"Hotkey {hotkey} not associated with wallet {wallet.name}."
|
731
778
|
)
|
732
|
-
|
779
|
+
return [(netuid, False)]
|
733
780
|
else:
|
734
|
-
# show
|
781
|
+
# show child hotkey take on all subnets
|
735
782
|
await chk_all_subnets(hotkey)
|
736
783
|
if take:
|
737
784
|
console.print(
|
738
785
|
f"Hotkey {hotkey} not associated with wallet {wallet.name}."
|
739
786
|
)
|
740
|
-
|
787
|
+
return [(netuid, False)]
|
741
788
|
|
742
789
|
# Validate child SS58 addresses
|
743
790
|
if not take:
|
744
|
-
# print current Take, ask if change
|
745
|
-
if netuid:
|
746
|
-
await display_chk_take(wallet.hotkey.ss58_address, netuid)
|
747
|
-
else:
|
748
|
-
# print take from all netuids
|
749
|
-
await chk_all_subnets(wallet.hotkey.ss58_address)
|
750
|
-
|
751
791
|
if not Confirm.ask("Would you like to change the child take?"):
|
752
|
-
return
|
753
|
-
|
754
|
-
|
755
|
-
new_take_value =
|
756
|
-
|
757
|
-
return
|
758
|
-
except ValueError:
|
759
|
-
err_console.print(
|
760
|
-
":cross_mark:[red] Invalid input. Please enter a number between 0 and 0.18.[/red]"
|
792
|
+
return [(netuid, False)]
|
793
|
+
new_take_value = -1.0
|
794
|
+
while not validate_take_value(new_take_value):
|
795
|
+
new_take_value = FloatPrompt.ask(
|
796
|
+
"Enter the new take value (between 0 and 0.18)"
|
761
797
|
)
|
762
|
-
return
|
763
798
|
take = new_take_value
|
764
799
|
else:
|
765
800
|
if not validate_take_value(take):
|
766
|
-
return
|
801
|
+
return [(netuid, False)]
|
767
802
|
|
768
803
|
if netuid:
|
769
|
-
await set_chk_take_subnet(subnet=netuid, chk_take=take)
|
770
|
-
return
|
804
|
+
return [(netuid, await set_chk_take_subnet(subnet=netuid, chk_take=take))]
|
771
805
|
else:
|
772
806
|
new_take_netuids = IntPrompt.ask(
|
773
807
|
"Enter netuid (leave blank for all)", default=None, show_default=True
|
774
808
|
)
|
775
809
|
|
776
810
|
if new_take_netuids:
|
777
|
-
|
778
|
-
|
811
|
+
return [
|
812
|
+
(
|
813
|
+
new_take_netuids,
|
814
|
+
await set_chk_take_subnet(subnet=new_take_netuids, chk_take=take),
|
815
|
+
)
|
816
|
+
]
|
779
817
|
|
780
818
|
else:
|
781
819
|
netuids = await subtensor.get_all_subnet_netuids()
|
782
|
-
|
783
|
-
|
820
|
+
output_list = []
|
821
|
+
for netuid_ in netuids:
|
822
|
+
if netuid_ == 0:
|
784
823
|
continue
|
785
|
-
console.print(f"Sending to netuid {
|
786
|
-
await set_childkey_take_extrinsic(
|
824
|
+
console.print(f"Sending to netuid {netuid_} take of {take * 100:.2f}%")
|
825
|
+
result = await set_childkey_take_extrinsic(
|
787
826
|
subtensor=subtensor,
|
788
827
|
wallet=wallet,
|
789
|
-
netuid=
|
828
|
+
netuid=netuid_,
|
790
829
|
hotkey=wallet.hotkey.ss58_address,
|
791
830
|
take=take,
|
792
831
|
prompt=prompt,
|
793
832
|
wait_for_inclusion=True,
|
794
833
|
wait_for_finalization=False,
|
795
834
|
)
|
835
|
+
output_list.append((netuid_, result))
|
796
836
|
console.print(
|
797
837
|
f":white_heavy_check_mark: [green]Sent childkey take of {take * 100:.2f}% to all subnets.[/green]"
|
798
838
|
)
|
839
|
+
return output_list
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import asyncio
|
2
|
-
|
2
|
+
import json
|
3
|
+
from collections import defaultdict
|
3
4
|
from typing import TYPE_CHECKING, Optional
|
4
5
|
|
5
6
|
from bittensor_wallet import Wallet
|
@@ -18,6 +19,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
18
19
|
print_error,
|
19
20
|
millify_tao,
|
20
21
|
get_subnet_name,
|
22
|
+
json_console,
|
21
23
|
)
|
22
24
|
|
23
25
|
if TYPE_CHECKING:
|
@@ -31,6 +33,7 @@ async def stake_list(
|
|
31
33
|
live: bool = False,
|
32
34
|
verbose: bool = False,
|
33
35
|
prompt: bool = False,
|
36
|
+
json_output: bool = False,
|
34
37
|
):
|
35
38
|
coldkey_address = coldkey_ss58 if coldkey_ss58 else wallet.coldkeypub.ss58_address
|
36
39
|
|
@@ -152,6 +155,7 @@ async def stake_list(
|
|
152
155
|
reverse=True,
|
153
156
|
)
|
154
157
|
sorted_substakes = root_stakes + other_stakes
|
158
|
+
substakes_values = []
|
155
159
|
for substake_ in sorted_substakes:
|
156
160
|
netuid = substake_.netuid
|
157
161
|
pool = dynamic_info[netuid]
|
@@ -195,7 +199,8 @@ async def stake_list(
|
|
195
199
|
if not verbose
|
196
200
|
else f"{substake_.stake.tao:,.4f}"
|
197
201
|
)
|
198
|
-
|
202
|
+
subnet_name = get_subnet_name(dynamic_info[netuid])
|
203
|
+
subnet_name_cell = f"[{COLOR_PALETTE['GENERAL']['SYMBOL']}]{symbol if netuid != 0 else 'τ'}[/{COLOR_PALETTE['GENERAL']['SYMBOL']}] {subnet_name}"
|
199
204
|
|
200
205
|
rows.append(
|
201
206
|
[
|
@@ -220,13 +225,28 @@ async def stake_list(
|
|
220
225
|
str(Balance.from_tao(per_block_tao_emission)),
|
221
226
|
]
|
222
227
|
)
|
228
|
+
substakes_values.append(
|
229
|
+
{
|
230
|
+
"netuid": netuid,
|
231
|
+
"subnet_name": subnet_name,
|
232
|
+
"value": tao_value_.tao,
|
233
|
+
"stake_value": substake_.stake.tao,
|
234
|
+
"rate": pool.price.tao,
|
235
|
+
"swap_value": swap_value,
|
236
|
+
"registered": True if substake_.is_registered else False,
|
237
|
+
"emission": {
|
238
|
+
"alpha": per_block_emission,
|
239
|
+
"tao": per_block_tao_emission,
|
240
|
+
},
|
241
|
+
}
|
242
|
+
)
|
223
243
|
created_table = define_table(
|
224
244
|
name_, rows, total_tao_value_, total_swapped_tao_value_
|
225
245
|
)
|
226
246
|
for row in rows:
|
227
247
|
created_table.add_row(*row)
|
228
248
|
console.print(created_table)
|
229
|
-
return total_tao_value_, total_swapped_tao_value_
|
249
|
+
return total_tao_value_, total_swapped_tao_value_, substakes_values
|
230
250
|
|
231
251
|
def create_live_table(
|
232
252
|
substakes: list,
|
@@ -409,22 +429,23 @@ async def stake_list(
|
|
409
429
|
# Main execution
|
410
430
|
block_hash = await subtensor.substrate.get_chain_head()
|
411
431
|
(
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
432
|
+
(
|
433
|
+
sub_stakes,
|
434
|
+
registered_delegate_info,
|
435
|
+
dynamic_info,
|
436
|
+
),
|
437
|
+
balance,
|
438
|
+
) = await asyncio.gather(
|
439
|
+
get_stake_data(block_hash),
|
440
|
+
subtensor.get_balance(coldkey_address, block_hash=block_hash),
|
441
|
+
)
|
417
442
|
|
418
443
|
# Iterate over substakes and aggregate them by hotkey.
|
419
|
-
hotkeys_to_substakes: dict[str, list[StakeInfo]] =
|
444
|
+
hotkeys_to_substakes: dict[str, list[StakeInfo]] = defaultdict(list)
|
420
445
|
|
421
446
|
for substake in sub_stakes:
|
422
|
-
|
423
|
-
|
424
|
-
continue
|
425
|
-
if hotkey not in hotkeys_to_substakes:
|
426
|
-
hotkeys_to_substakes[hotkey] = []
|
427
|
-
hotkeys_to_substakes[hotkey].append(substake)
|
447
|
+
if substake.stake.rao != 0:
|
448
|
+
hotkeys_to_substakes[substake.hotkey_ss58].append(substake)
|
428
449
|
|
429
450
|
if not hotkeys_to_substakes:
|
430
451
|
print_error(f"No stakes found for coldkey ss58: ({coldkey_address})")
|
@@ -534,15 +555,24 @@ async def stake_list(
|
|
534
555
|
num_hotkeys = len(hotkeys_to_substakes)
|
535
556
|
all_hks_swapped_tao_value = Balance(0)
|
536
557
|
all_hks_tao_value = Balance(0)
|
537
|
-
|
558
|
+
dict_output = {
|
559
|
+
"stake_info": {},
|
560
|
+
"coldkey_address": coldkey_address,
|
561
|
+
"network": subtensor.network,
|
562
|
+
"free_balance": 0.0,
|
563
|
+
"total_tao_value": 0.0,
|
564
|
+
"total_swapped_tao_value": 0.0,
|
565
|
+
}
|
566
|
+
for hotkey, substakes in hotkeys_to_substakes.items():
|
538
567
|
counter += 1
|
539
|
-
tao_value, swapped_tao_value = create_table(
|
540
|
-
hotkey,
|
568
|
+
tao_value, swapped_tao_value, substake_values_ = create_table(
|
569
|
+
hotkey, substakes
|
541
570
|
)
|
571
|
+
dict_output["stake_info"][hotkey] = substake_values_
|
542
572
|
all_hks_tao_value += tao_value
|
543
573
|
all_hks_swapped_tao_value += swapped_tao_value
|
544
574
|
|
545
|
-
if num_hotkeys > 1 and counter < num_hotkeys and prompt:
|
575
|
+
if num_hotkeys > 1 and counter < num_hotkeys and prompt and not json_output:
|
546
576
|
console.print("\nPress Enter to continue to the next hotkey...")
|
547
577
|
input()
|
548
578
|
|
@@ -556,7 +586,6 @@ async def stake_list(
|
|
556
586
|
if not verbose
|
557
587
|
else all_hks_swapped_tao_value
|
558
588
|
)
|
559
|
-
|
560
589
|
console.print("\n\n")
|
561
590
|
console.print(
|
562
591
|
f"Wallet:\n"
|
@@ -565,6 +594,11 @@ async def stake_list(
|
|
565
594
|
f" Total TAO Value ({Balance.unit}): [{COLOR_PALETTE['GENERAL']['BALANCE']}]{total_tao_value}[/{COLOR_PALETTE['GENERAL']['BALANCE']}]\n"
|
566
595
|
f" Total TAO Swapped Value ({Balance.unit}): [{COLOR_PALETTE['GENERAL']['BALANCE']}]{total_swapped_tao_value}[/{COLOR_PALETTE['GENERAL']['BALANCE']}]"
|
567
596
|
)
|
597
|
+
dict_output["free_balance"] = balance.tao
|
598
|
+
dict_output["total_tao_value"] = all_hks_tao_value.tao
|
599
|
+
dict_output["total_swapped_tao_value"] = all_hks_swapped_tao_value.tao
|
600
|
+
if json_output:
|
601
|
+
json_console.print(json.dumps(dict_output))
|
568
602
|
if not sub_stakes:
|
569
603
|
console.print(
|
570
604
|
f"\n[blue]No stakes found for coldkey ss58: ({coldkey_address})"
|