@@ -11,9 +11,10 @@ use sp_runtime::{generic::BlockId, traits::Block as BlockT};
11
11
12
12
use pallet_cash:: {
13
13
chains:: { ChainAccount , ChainAsset } ,
14
+ portfolio:: Portfolio ,
14
15
rates:: APR ,
15
16
reason:: Reason ,
16
- types:: { AssetAmount , AssetBalance , AssetInfo } ,
17
+ types:: { AssetAmount , AssetBalance , AssetInfo , InterestRateModel , Symbol } ,
17
18
} ;
18
19
use pallet_cash_runtime_api:: CashApi as CashRuntimeApi ;
19
20
use pallet_oracle:: types:: AssetPrice ;
@@ -43,13 +44,41 @@ pub struct ApiAssetData {
43
44
price : String ,
44
45
}
45
46
47
+ #[ derive( Deserialize , Serialize , Types ) ]
48
+ pub enum ApiInterestRateModel {
49
+ Kink {
50
+ zero_rate : String ,
51
+ kink_rate : String ,
52
+ kink_utilization : String ,
53
+ full_rate : String ,
54
+ } ,
55
+ }
56
+
57
+ #[ derive( Deserialize , Serialize , Types ) ]
58
+ pub struct ApiAssetInfo {
59
+ asset : ChainAsset ,
60
+ decimals : u8 ,
61
+ liquidity_factor : String ,
62
+ rate_model : ApiInterestRateModel ,
63
+ miner_shares : String ,
64
+ supply_cap : String ,
65
+ symbol : Symbol ,
66
+ ticker : String ,
67
+ }
68
+
46
69
#[ derive( Deserialize , Serialize , Types ) ]
47
70
pub struct ApiCashData {
48
71
balance : String ,
49
72
cash_yield : String ,
50
73
price : String ,
51
74
}
52
75
76
+ #[ derive( Deserialize , Serialize , Types ) ]
77
+ pub struct ApiPortfolio {
78
+ cash : String ,
79
+ positions : Vec < ( ChainAsset , String ) > ,
80
+ }
81
+
53
82
/// Converts a runtime trap into an RPC error.
54
83
fn runtime_err ( err : impl std:: fmt:: Debug ) -> RpcError {
55
84
RpcError {
@@ -93,6 +122,25 @@ pub trait GatewayRpcApi<BlockHash> {
93
122
94
123
#[ rpc( name = "gateway_rates" ) ]
95
124
fn gateway_rates ( & self , asset : ChainAsset , at : Option < BlockHash > ) -> RpcResult < ApiRates > ;
125
+
126
+ #[ rpc( name = "gateway_assets" ) ]
127
+ fn gateway_assets ( & self , at : Option < BlockHash > ) -> RpcResult < Vec < ApiAssetInfo > > ;
128
+
129
+ #[ rpc( name = "gateway_chain_accounts" ) ]
130
+ fn chain_accounts ( & self , at : Option < BlockHash > ) -> RpcResult < Vec < ChainAccount > > ;
131
+
132
+ #[ rpc( name = "gateway_chain_account_liquidities" ) ]
133
+ fn chain_account_liquidities (
134
+ & self ,
135
+ at : Option < BlockHash > ,
136
+ ) -> RpcResult < Vec < ( ChainAccount , String ) > > ;
137
+
138
+ #[ rpc( name = "gateway_chain_account_portfolio" ) ]
139
+ fn chain_account_portfolio (
140
+ & self ,
141
+ account : ChainAccount ,
142
+ at : Option < BlockHash > ,
143
+ ) -> RpcResult < ApiPortfolio > ;
96
144
}
97
145
98
146
pub struct GatewayRpcHandler < C , B > {
@@ -226,4 +274,92 @@ where
226
274
. map_err ( chain_err) ?;
227
275
Ok ( ( borrow_rate. 0 as ApiAPR , supply_rate. 0 as ApiAPR ) ) // XXX try_into?
228
276
}
277
+
278
+ fn gateway_assets ( & self , at : Option < <B as BlockT >:: Hash > ) -> RpcResult < Vec < ApiAssetInfo > > {
279
+ let api = self . client . runtime_api ( ) ;
280
+ let at = BlockId :: hash ( at. unwrap_or_else ( || self . client . info ( ) . best_hash ) ) ;
281
+ let assets = api
282
+ . get_assets ( & at)
283
+ . map_err ( runtime_err) ?
284
+ . map_err ( chain_err) ?;
285
+
286
+ fn api_rate_model ( model : InterestRateModel ) -> ApiInterestRateModel {
287
+ match model {
288
+ InterestRateModel :: Kink {
289
+ zero_rate,
290
+ kink_rate,
291
+ kink_utilization,
292
+ full_rate,
293
+ } => ApiInterestRateModel :: Kink {
294
+ zero_rate : format ! ( "{:?}" , zero_rate. 0 ) ,
295
+ kink_rate : format ! ( "{:?}" , kink_rate. 0 ) ,
296
+ kink_utilization : format ! ( "{:?}" , kink_utilization. 0 ) ,
297
+ full_rate : format ! ( "{:?}" , full_rate. 0 ) ,
298
+ } ,
299
+ }
300
+ }
301
+
302
+ let assets_lite = assets
303
+ . iter ( )
304
+ . map ( |asset_info| ApiAssetInfo {
305
+ asset : asset_info. asset ,
306
+ decimals : asset_info. decimals ,
307
+ liquidity_factor : format ! ( "{}" , asset_info. liquidity_factor. 0 ) ,
308
+ rate_model : api_rate_model ( asset_info. rate_model ) ,
309
+ miner_shares : format ! ( "{}" , asset_info. miner_shares. 0 ) ,
310
+ supply_cap : format ! ( "{}" , asset_info. supply_cap) ,
311
+ symbol : asset_info. symbol ,
312
+ ticker : String :: from ( asset_info. ticker ) ,
313
+ } )
314
+ . collect ( ) ;
315
+
316
+ Ok ( assets_lite) // XXX try_into?
317
+ }
318
+
319
+ fn chain_accounts ( & self , at : Option < <B as BlockT >:: Hash > ) -> RpcResult < Vec < ChainAccount > > {
320
+ let api = self . client . runtime_api ( ) ;
321
+ let at = BlockId :: hash ( at. unwrap_or_else ( || self . client . info ( ) . best_hash ) ) ;
322
+ let accounts = api
323
+ . get_accounts ( & at)
324
+ . map_err ( runtime_err) ?
325
+ . map_err ( chain_err) ?;
326
+ Ok ( accounts) // XXX try_into?
327
+ }
328
+
329
+ fn chain_account_liquidities (
330
+ & self ,
331
+ at : Option < <B as BlockT >:: Hash > ,
332
+ ) -> RpcResult < Vec < ( ChainAccount , String ) > > {
333
+ let api = self . client . runtime_api ( ) ;
334
+ let at = BlockId :: hash ( at. unwrap_or_else ( || self . client . info ( ) . best_hash ) ) ;
335
+ let accounts = api
336
+ . get_accounts_liquidity ( & at)
337
+ . map_err ( runtime_err) ?
338
+ . map_err ( chain_err) ?;
339
+ Ok ( accounts) // XXX try_into?
340
+ }
341
+
342
+ fn chain_account_portfolio (
343
+ & self ,
344
+ account : ChainAccount ,
345
+ at : Option < <B as BlockT >:: Hash > ,
346
+ ) -> RpcResult < ApiPortfolio > {
347
+ let api = self . client . runtime_api ( ) ;
348
+ let at = BlockId :: hash ( at. unwrap_or_else ( || self . client . info ( ) . best_hash ) ) ;
349
+ let result: Portfolio = api
350
+ . get_portfolio ( & at, account)
351
+ . map_err ( runtime_err) ?
352
+ . map_err ( chain_err) ?;
353
+
354
+ let positions_lite = result
355
+ . positions
356
+ . iter ( )
357
+ . map ( |p| ( p. 0 . asset , format ! ( "{}" , p. 1 . value) ) )
358
+ . collect ( ) ;
359
+ print ! ( "{:?}" , positions_lite) ;
360
+ Ok ( ApiPortfolio {
361
+ cash : format ! ( "{}" , result. cash. value) ,
362
+ positions : positions_lite,
363
+ } )
364
+ }
229
365
}
0 commit comments