1- use crate :: models:: balance:: { DelegationBalance , Validator } ;
1+ use crate :: models:: balance:: { DelegationBalance , StakeBalance , Validator } ;
22use num_bigint:: BigUint ;
33use number_formatter:: BigNumberFormatter ;
44use primitives:: { Asset , Chain , DelegationBase , DelegationState , DelegationValidator } ;
5- use std:: str:: FromStr ;
65
76pub fn map_staking_validators ( validators : Vec < Validator > , chain : Chain , apy : Option < f64 > ) -> Vec < DelegationValidator > {
87 let calculated_apy = apy. unwrap_or_else ( || Validator :: max_apr ( validators. clone ( ) ) ) ;
9- validators
8+ let mut result : Vec < DelegationValidator > = validators
109 . into_iter ( )
1110 . map ( |x| DelegationValidator :: stake ( chain, x. validator_address ( ) , x. name , x. is_active , x. commission , calculated_apy) )
12- . collect ( )
11+ . collect ( ) ;
12+
13+ result. push ( DelegationValidator :: system ( chain) ) ;
14+
15+ result
1316}
1417
15- pub fn map_staking_delegations ( delegations : Vec < DelegationBalance > , chain : Chain ) -> Vec < DelegationBase > {
18+ pub fn map_staking_delegations ( delegations : Vec < DelegationBalance > , stake_balance : StakeBalance , chain : Chain ) -> Vec < DelegationBase > {
1619 let native_decimals = Asset :: from_chain ( chain) . decimals as u32 ;
17- delegations
20+ let mut result : Vec < DelegationBase > = delegations
1821 . into_iter ( )
19- . map ( |x| {
20- let balance = BigNumberFormatter :: value_from_amount ( & x. amount . to_string ( ) , native_decimals)
21- . ok ( )
22- . and_then ( |s| BigUint :: from_str ( & s) . ok ( ) )
23- . unwrap_or_default ( ) ;
24- DelegationBase {
25- asset_id : chain. as_asset_id ( ) ,
26- state : DelegationState :: Active ,
27- balance,
28- shares : BigUint :: from ( 0u32 ) ,
29- rewards : BigUint :: from ( 0u32 ) ,
30- completion_date : None ,
31- delegation_id : x. validator_address ( ) ,
32- validator_id : x. validator_address ( ) ,
33- }
22+ . map ( |x| DelegationBase {
23+ asset_id : chain. as_asset_id ( ) ,
24+ state : DelegationState :: Active ,
25+ balance : BigNumberFormatter :: value_from_amount_biguint ( & x. amount , native_decimals) . unwrap_or_default ( ) ,
26+ shares : BigUint :: from ( 0u32 ) ,
27+ rewards : BigUint :: from ( 0u32 ) ,
28+ completion_date : None ,
29+ delegation_id : x. validator_address ( ) ,
30+ validator_id : x. validator_address ( ) ,
3431 } )
35- . collect ( )
32+ . collect ( ) ;
33+
34+ let pending = BigNumberFormatter :: value_from_amount_biguint ( & stake_balance. total_pending_withdrawal , native_decimals) . unwrap_or_default ( ) ;
35+ if pending > BigUint :: from ( 0u32 ) {
36+ result. push ( DelegationBase {
37+ asset_id : chain. as_asset_id ( ) ,
38+ state : DelegationState :: Pending ,
39+ balance : pending,
40+ shares : BigUint :: from ( 0u32 ) ,
41+ rewards : BigUint :: from ( 0u32 ) ,
42+ completion_date : None ,
43+ delegation_id : DelegationValidator :: SYSTEM_ID . to_string ( ) ,
44+ validator_id : DelegationValidator :: SYSTEM_ID . to_string ( ) ,
45+ } ) ;
46+ }
47+
48+ result
3649}
3750
3851#[ cfg( test) ]
@@ -41,6 +54,14 @@ mod tests {
4154 use crate :: models:: balance:: ValidatorStats ;
4255 use primitives:: { Chain , DelegationState } ;
4356
57+ fn stake_balance ( total_pending_withdrawal : & str ) -> StakeBalance {
58+ StakeBalance {
59+ delegated : "0" . to_string ( ) ,
60+ undelegated : "0" . to_string ( ) ,
61+ total_pending_withdrawal : total_pending_withdrawal. to_string ( ) ,
62+ }
63+ }
64+
4465 #[ test]
4566 fn test_map_staking_validators ( ) {
4667 let validators = vec ! [ Validator {
@@ -52,13 +73,18 @@ mod tests {
5273 } ] ;
5374
5475 let result = map_staking_validators ( validators, Chain :: HyperCore , None ) ;
55- assert_eq ! ( result. len( ) , 1 ) ;
76+ assert_eq ! ( result. len( ) , 2 ) ;
5677 assert_eq ! ( result[ 0 ] . name, "Test Validator" ) ;
5778 assert_eq ! ( result[ 0 ] . id, "0x5aC99df645F3414876C816Caa18b2d234024b487" ) ;
5879 assert_eq ! ( result[ 0 ] . chain, Chain :: HyperCore ) ;
5980 assert ! ( result[ 0 ] . is_active) ;
6081 assert_eq ! ( result[ 0 ] . commission, 5.0 ) ;
61- assert_eq ! ( result[ 0 ] . apr, 15.0 ) ; // max_apr * 100
82+ assert_eq ! ( result[ 0 ] . apr, 15.0 ) ;
83+
84+ let system = & result[ 1 ] ;
85+ assert_eq ! ( system. id, DelegationValidator :: SYSTEM_ID ) ;
86+ assert_eq ! ( system. name, DelegationValidator :: SYSTEM_NAME ) ;
87+ assert ! ( system. is_active) ;
6288 }
6389
6490 #[ test]
@@ -72,15 +98,16 @@ mod tests {
7298 } ] ;
7399
74100 let result = map_staking_validators ( validators, Chain :: HyperCore , Some ( 10.0 ) ) ;
75- assert_eq ! ( result. len( ) , 1 ) ;
76- assert_eq ! ( result[ 0 ] . apr, 10.0 ) ; // Uses provided APY
101+ assert_eq ! ( result. len( ) , 2 ) ;
102+ assert_eq ! ( result[ 0 ] . apr, 10.0 ) ;
103+ assert_eq ! ( result[ 1 ] . id, DelegationValidator :: SYSTEM_ID ) ;
77104 }
78105
79106 #[ test]
80107 fn test_map_staking_delegations ( ) {
81108 let delegations: Vec < DelegationBalance > = serde_json:: from_str ( include_str ! ( "../../testdata/staking_delegations.json" ) ) . unwrap ( ) ;
82109
83- let result = map_staking_delegations ( delegations, Chain :: HyperCore ) ;
110+ let result = map_staking_delegations ( delegations, stake_balance ( "0" ) , Chain :: HyperCore ) ;
84111
85112 assert_eq ! ( result. len( ) , 2 ) ;
86113
@@ -89,7 +116,7 @@ mod tests {
89116 assert_eq ! ( delegation1. validator_id, "0x5aC99df645F3414876C816Caa18b2d234024b487" ) ;
90117 assert_eq ! ( delegation1. delegation_id, "0x5aC99df645F3414876C816Caa18b2d234024b487" ) ;
91118 assert_eq ! ( delegation1. balance. to_string( ) , "271936493373" ) ;
92- assert ! ( matches! ( delegation1. state, DelegationState :: Active ) ) ;
119+ assert_eq ! ( delegation1. state, DelegationState :: Active ) ;
93120 assert_eq ! ( delegation1. shares, num_bigint:: BigUint :: from( 0u32 ) ) ;
94121 assert_eq ! ( delegation1. rewards, num_bigint:: BigUint :: from( 0u32 ) ) ;
95122 assert ! ( delegation1. completion_date. is_none( ) ) ;
@@ -98,4 +125,23 @@ mod tests {
98125 assert_eq ! ( delegation2. validator_id, "0xaBCDefF4b3727B83A23697500EEf089020DF2cD2" ) ;
99126 assert_eq ! ( delegation2. balance. to_string( ) , "1814578086" ) ;
100127 }
128+
129+ #[ test]
130+ fn test_map_staking_delegations_pending_withdrawal ( ) {
131+ let result = map_staking_delegations ( vec ! [ ] , stake_balance ( "0.015" ) , Chain :: HyperCore ) ;
132+
133+ assert_eq ! ( result. len( ) , 1 ) ;
134+ let pending = & result[ 0 ] ;
135+ assert_eq ! ( pending. state, DelegationState :: Pending ) ;
136+ assert_eq ! ( pending. validator_id, DelegationValidator :: SYSTEM_ID ) ;
137+ assert_eq ! ( pending. balance. to_string( ) , "1500000" ) ;
138+ assert ! ( pending. completion_date. is_none( ) ) ;
139+ }
140+
141+ #[ test]
142+ fn test_map_staking_delegations_no_pending_withdrawal ( ) {
143+ let result = map_staking_delegations ( vec ! [ ] , stake_balance ( "0" ) , Chain :: HyperCore ) ;
144+
145+ assert ! ( result. is_empty( ) ) ;
146+ }
101147}
0 commit comments