10
10
import plotly .graph_objects as go
11
11
12
12
from bittensor_cli .src import COLOR_PALETTE
13
+ from bittensor_cli .src .bittensor .chain_data import DynamicInfo
13
14
from bittensor_cli .src .bittensor .utils import (
14
15
console ,
15
16
err_console ,
@@ -28,6 +29,7 @@ async def price(
28
29
netuids : list [int ],
29
30
all_netuids : bool = False ,
30
31
interval_hours : int = 4 ,
32
+ current_only : bool = False ,
31
33
html_output : bool = False ,
32
34
log_scale : bool = False ,
33
35
json_output : bool = False ,
@@ -41,45 +43,93 @@ async def price(
41
43
blocks_per_hour = int (3600 / 12 ) # ~300 blocks per hour
42
44
total_blocks = blocks_per_hour * interval_hours
43
45
44
- with console .status (":chart_increasing: Fetching historical price data..." ):
45
- current_block_hash = await subtensor .substrate .get_chain_head ()
46
- current_block = await subtensor .substrate .get_block_number (current_block_hash )
46
+ if not current_only :
47
+ with console .status (":chart_increasing: Fetching historical price data..." ):
48
+ current_block_hash = await subtensor .substrate .get_chain_head ()
49
+ current_block = await subtensor .substrate .get_block_number (
50
+ current_block_hash
51
+ )
47
52
48
- step = 300
49
- start_block = max (0 , current_block - total_blocks )
50
- block_numbers = list (range (start_block , current_block + 1 , step ))
53
+ step = 300
54
+ start_block = max (0 , current_block - total_blocks )
55
+ block_numbers = list (range (start_block , current_block + 1 , step ))
51
56
52
- # Block hashes
53
- block_hash_cors = [
54
- subtensor .substrate .get_block_hash (bn ) for bn in block_numbers
55
- ]
56
- block_hashes = await asyncio .gather (* block_hash_cors )
57
+ # Block hashes
58
+ block_hash_cors = [
59
+ subtensor .substrate .get_block_hash (bn ) for bn in block_numbers
60
+ ]
61
+ block_hashes = await asyncio .gather (* block_hash_cors )
57
62
58
- # We fetch all subnets when there is more than one netuid
59
- if all_netuids or len (netuids ) > 1 :
60
- subnet_info_cors = [subtensor .all_subnets (bh ) for bh in block_hashes ]
61
- else :
62
- # If there is only one netuid, we fetch the subnet info for that netuid
63
- netuid = netuids [0 ]
64
- subnet_info_cors = [subtensor .subnet (netuid , bh ) for bh in block_hashes ]
65
- all_subnet_infos = await asyncio .gather (* subnet_info_cors )
63
+ # We fetch all subnets when there is more than one netuid
64
+ if all_netuids or len (netuids ) > 1 :
65
+ subnet_info_cors = [subtensor .all_subnets (bh ) for bh in block_hashes ]
66
+ else :
67
+ # If there is only one netuid, we fetch the subnet info for that netuid
68
+ netuid = netuids [0 ]
69
+ subnet_info_cors = [subtensor .subnet (netuid , bh ) for bh in block_hashes ]
70
+ all_subnet_infos = await asyncio .gather (* subnet_info_cors )
66
71
67
72
subnet_data = _process_subnet_data (
68
73
block_numbers , all_subnet_infos , netuids , all_netuids
69
74
)
75
+ if not subnet_data :
76
+ err_console .print ("[red]No valid price data found for any subnet[/red]" )
77
+ return
70
78
71
- if not subnet_data :
72
- err_console .print ("[red]No valid price data found for any subnet[/red]" )
73
- return
74
-
75
- if html_output :
76
- await _generate_html_output (
77
- subnet_data , block_numbers , interval_hours , log_scale
79
+ if html_output :
80
+ await _generate_html_output (
81
+ subnet_data , block_numbers , interval_hours , log_scale
82
+ )
83
+ elif json_output :
84
+ json_console .print (json .dumps (_generate_json_output (subnet_data )))
85
+ else :
86
+ _generate_cli_output (subnet_data , block_numbers , interval_hours , log_scale )
87
+ else :
88
+ with console .status ("Fetching current price data..." ):
89
+ if all_netuids or len (netuids ) > 1 :
90
+ all_subnet_info = await subtensor .all_subnets ()
91
+ else :
92
+ all_subnet_info = [await subtensor .subnet (netuid = netuids [0 ])]
93
+ subnet_data = _process_current_subnet_data (
94
+ all_subnet_info , netuids , all_netuids
78
95
)
79
- elif json_output :
80
- json_console .print (json .dumps (_generate_json_output (subnet_data )))
96
+ _generate_cli_output_current (subnet_data )
97
+
98
+
99
+ def _process_current_subnet_data (subnet_infos : list [DynamicInfo ], netuids , all_netuids ):
100
+ subnet_data = {}
101
+ if all_netuids or len (netuids ) > 1 :
102
+ # Most recent data for statistics
103
+ for subnet_info in subnet_infos :
104
+ stats = {
105
+ "current_price" : subnet_info .price ,
106
+ "supply" : subnet_info .alpha_in .tao + subnet_info .alpha_out .tao ,
107
+ "market_cap" : subnet_info .price .tao
108
+ * (subnet_info .alpha_in .tao + subnet_info .alpha_out .tao ),
109
+ "emission" : subnet_info .emission .tao ,
110
+ "stake" : subnet_info .alpha_out .tao ,
111
+ "symbol" : subnet_info .symbol ,
112
+ "name" : get_subnet_name (subnet_info ),
113
+ }
114
+ subnet_data [subnet_info .netuid ] = {
115
+ "stats" : stats ,
116
+ }
81
117
else :
82
- _generate_cli_output (subnet_data , block_numbers , interval_hours , log_scale )
118
+ subnet_info = subnet_infos [0 ]
119
+ stats = {
120
+ "current_price" : subnet_info .price ,
121
+ "supply" : subnet_info .alpha_in .tao + subnet_info .alpha_out .tao ,
122
+ "market_cap" : subnet_info .price .tao
123
+ * (subnet_info .alpha_in .tao + subnet_info .alpha_out .tao ),
124
+ "emission" : subnet_info .emission .tao ,
125
+ "stake" : subnet_info .alpha_out .tao ,
126
+ "symbol" : subnet_info .symbol ,
127
+ "name" : get_subnet_name (subnet_info ),
128
+ }
129
+ subnet_data [subnet_info .netuid ] = {
130
+ "stats" : stats ,
131
+ }
132
+ return subnet_data
83
133
84
134
85
135
def _process_subnet_data (block_numbers , all_subnet_infos , netuids , all_netuids ):
@@ -626,3 +676,46 @@ def color_label(text):
626
676
)
627
677
628
678
console .print (stats_text )
679
+
680
+
681
+ def _generate_cli_output_current (subnet_data ):
682
+ for netuid , data in subnet_data .items ():
683
+ stats = data ["stats" ]
684
+
685
+ if netuid != 0 :
686
+ console .print (
687
+ f"\n [{ COLOR_PALETTE .G .SYM } ]Subnet { netuid } - { stats ['symbol' ]} "
688
+ f"[cyan]{ stats ['name' ]} [/cyan][/{ COLOR_PALETTE .G .SYM } ]\n "
689
+ f"Current: [blue]{ stats ['current_price' ].tao :.6f} { stats ['symbol' ]} [/blue]\n "
690
+ )
691
+ else :
692
+ console .print (
693
+ f"\n [{ COLOR_PALETTE .G .SYM } ]Subnet { netuid } - { stats ['symbol' ]} "
694
+ f"[cyan]{ stats ['name' ]} [/cyan][/{ COLOR_PALETTE .G .SYM } ]\n "
695
+ f"Current: [blue]{ stats ['symbol' ]} { stats ['current_price' ].tao :.6f} [/blue]\n "
696
+ )
697
+
698
+ if netuid != 0 :
699
+ stats_text = (
700
+ "\n Latest stats:\n "
701
+ f"Supply: [{ COLOR_PALETTE .P .ALPHA_IN } ]"
702
+ f"{ stats ['supply' ]:,.2f} { stats ['symbol' ]} [/{ COLOR_PALETTE .P .ALPHA_IN } ]\n "
703
+ f"Market Cap: [steel_blue3]{ stats ['market_cap' ]:,.2f} { stats ['symbol' ]} / 21M[/steel_blue3]\n "
704
+ f"Emission: [{ COLOR_PALETTE .P .EMISSION } ]"
705
+ f"{ stats ['emission' ]:,.2f} { stats ['symbol' ]} [/{ COLOR_PALETTE .P .EMISSION } ]\n "
706
+ f"Stake: [{ COLOR_PALETTE .S .TAO } ]"
707
+ f"{ stats ['stake' ]:,.2f} { stats ['symbol' ]} [/{ COLOR_PALETTE .S .TAO } ]"
708
+ )
709
+ else :
710
+ stats_text = (
711
+ "\n Latest stats:\n "
712
+ f"Supply: [{ COLOR_PALETTE .P .ALPHA_IN } ]"
713
+ f"{ stats ['symbol' ]} { stats ['supply' ]:,.2f} [/{ COLOR_PALETTE .P .ALPHA_IN } ]\n "
714
+ f"Market Cap: [steel_blue3]{ stats ['symbol' ]} { stats ['market_cap' ]:,.2f} / 21M[/steel_blue3]\n "
715
+ f"Emission: [{ COLOR_PALETTE .P .EMISSION } ]"
716
+ f"{ stats ['symbol' ]} { stats ['emission' ]:,.2f} [/{ COLOR_PALETTE .P .EMISSION } ]\n "
717
+ f"Stake: [{ COLOR_PALETTE .S .TAO } ]"
718
+ f"{ stats ['symbol' ]} { stats ['stake' ]:,.2f} [/{ COLOR_PALETTE .S .TAO } ]"
719
+ )
720
+
721
+ console .print (stats_text )
0 commit comments