1
1
from dataclasses import dataclass
2
- from typing import Any , Optional
2
+ from typing import Optional
3
3
4
4
from bittensor .core .chain_data .info_base import InfoBase
5
5
from bittensor .core .chain_data .utils import decode_account_id
8
8
9
9
10
10
@dataclass
11
- class DelegateInfo (InfoBase ):
12
- """
13
- Dataclass for delegate information. For a lighter version of this class, see ``DelegateInfoLite``.
11
+ class DelegateInfoBase (InfoBase ):
12
+ """Base class containing common delegate information fields.
14
13
15
- Args:
16
- hotkey_ss58 (str): Hotkey of the delegate for which the information is being fetched.
17
- total_stake (int): Total stake of the delegate.
18
- nominators (list[tuple[str, int]]): List of nominators of the delegate and their stake.
14
+ Attributes:
15
+ hotkey_ss58 (str): Hotkey of delegate.
16
+ owner_ss58 (str): Coldkey of owner.
19
17
take (float): Take of the delegate as a percentage.
20
- owner_ss58 (str): Coldkey of the owner.
21
- registrations (list[int]): List of subnets that the delegate is registered on.
22
18
validator_permits (list[int]): List of subnets that the delegate is allowed to validate on.
23
- return_per_1000 (int): Return per 1000 TAO, for the delegate over a day.
24
- total_daily_return (int): Total daily return of the delegate.
19
+ registrations (list[int]): List of subnets that the delegate is registered on.
20
+ return_per_1000 (Balance): Return per 1000 tao of the delegate over a day.
21
+ total_daily_return (Balance): Total daily return of the delegate.
25
22
"""
26
23
27
24
hotkey_ss58 : str # Hotkey of delegate
28
- total_stake : Balance # Total stake of the delegate
29
- nominators : list [
30
- tuple [str , Balance ]
31
- ] # List of nominators of the delegate and their stake
32
25
owner_ss58 : str # Coldkey of owner
33
26
take : float # Take of the delegate as a percentage
34
27
validator_permits : list [
@@ -38,35 +31,87 @@ class DelegateInfo(InfoBase):
38
31
return_per_1000 : Balance # Return per 1000 tao of the delegate over a day
39
32
total_daily_return : Balance # Total daily return of the delegate
40
33
34
+
35
+ @dataclass
36
+ class DelegateInfo (DelegateInfoBase ):
37
+ """
38
+ Dataclass for delegate information.
39
+
40
+ Additional Attributes:
41
+ total_stake (dict[int, Balance]): Total stake of the delegate mapped by netuid.
42
+ nominators (dict[str, dict[int, Balance]]): Mapping of nominator SS58 addresses to their stakes per subnet.
43
+ """
44
+
45
+ total_stake : dict [int , Balance ] # Total stake of the delegate by netuid and stake
46
+ nominators : dict [
47
+ str , dict [int , Balance ]
48
+ ] # Mapping of nominator addresses to their stakes per subnet
49
+
41
50
@classmethod
42
51
def _from_dict (cls , decoded : dict ) -> Optional ["DelegateInfo" ]:
43
- """Returns a DelegateInfo object from decoded chain data."""
44
- nominators = [
45
- (decode_account_id (x ), Balance .from_rao (y ))
46
- for x , y in decoded ["nominators" ]
47
- ]
48
- total_stake = sum ((x [1 ] for x in nominators )) if nominators else Balance (0 )
49
-
50
- return DelegateInfo (
51
- hotkey_ss58 = decode_account_id (decoded ["delegate_ss58" ]),
52
+ hotkey = decode_account_id (decoded .get ("delegate_ss58" ))
53
+ owner = decode_account_id (decoded .get ("owner_ss58" ))
54
+
55
+ nominators = {}
56
+ total_stake_by_netuid = {}
57
+
58
+ for raw_nominator , raw_stakes in decoded .get ("nominators" , []):
59
+ nominator_ss58 = decode_account_id (raw_nominator )
60
+ stakes = {
61
+ int (netuid ): Balance .from_rao (stake_amt ).set_unit (int (netuid ))
62
+ for (netuid , stake_amt ) in raw_stakes
63
+ }
64
+ nominators [nominator_ss58 ] = stakes
65
+
66
+ for netuid , stake in stakes .items ():
67
+ if netuid not in total_stake_by_netuid :
68
+ total_stake_by_netuid [netuid ] = Balance (0 ).set_unit (netuid )
69
+ total_stake_by_netuid [netuid ] += stake
70
+
71
+ return cls (
72
+ hotkey_ss58 = hotkey ,
73
+ total_stake = total_stake_by_netuid ,
52
74
nominators = nominators ,
53
- owner_ss58 = decode_account_id (decoded ["owner_ss58" ]),
54
- registrations = decoded ["registrations" ],
55
- return_per_1000 = Balance .from_rao (decoded ["return_per_1000" ]),
56
- take = u16_normalized_float (decoded ["take" ]),
57
- total_daily_return = Balance .from_rao (decoded ["total_daily_return" ]),
58
- total_stake = total_stake ,
59
- validator_permits = decoded ["validator_permits" ],
75
+ owner_ss58 = owner ,
76
+ take = u16_normalized_float (decoded .get ("take" )),
77
+ validator_permits = list (decoded .get ("validator_permits" , [])),
78
+ registrations = list (decoded .get ("registrations" , [])),
79
+ return_per_1000 = Balance .from_rao (decoded .get ("return_per_1000" )),
80
+ total_daily_return = Balance .from_rao (decoded .get ("total_daily_return" )),
60
81
)
61
82
83
+
84
+ @dataclass
85
+ class DelegatedInfo (DelegateInfoBase ):
86
+ """
87
+ Dataclass for delegated information. This class represents a delegate's information
88
+ specific to a particular subnet.
89
+
90
+ Additional Attributes:
91
+ netuid (int): Network ID of the subnet.
92
+ stake (Balance): Stake amount for this specific delegation.
93
+ """
94
+
95
+ netuid : int
96
+ stake : Balance
97
+
62
98
@classmethod
63
- def delegated_list_from_dicts (
64
- cls , delegates : list [Any ]
65
- ) -> list [tuple ["DelegateInfo" , Balance ]]:
66
- return [
67
- (
68
- DelegateInfo .from_dict (delegate ),
69
- Balance .from_rao (balance ),
70
- )
71
- for delegate , balance in delegates
72
- ]
99
+ def _from_dict (
100
+ cls , decoded : tuple [dict , tuple [int , int ]]
101
+ ) -> Optional ["DelegatedInfo" ]:
102
+ delegate_info , (netuid , stake ) = decoded
103
+ hotkey = decode_account_id (delegate_info .get ("delegate_ss58" ))
104
+ owner = decode_account_id (delegate_info .get ("owner_ss58" ))
105
+ return cls (
106
+ hotkey_ss58 = hotkey ,
107
+ owner_ss58 = owner ,
108
+ take = u16_normalized_float (delegate_info .get ("take" )),
109
+ validator_permits = list (delegate_info .get ("validator_permits" , [])),
110
+ registrations = list (delegate_info .get ("registrations" , [])),
111
+ return_per_1000 = Balance .from_rao (delegate_info .get ("return_per_1000" )),
112
+ total_daily_return = Balance .from_rao (
113
+ delegate_info .get ("total_daily_return" )
114
+ ),
115
+ netuid = int (netuid ),
116
+ stake = Balance .from_rao (int (stake )).set_unit (int (netuid )),
117
+ )
0 commit comments