Proper asset id
This commit is contained in:
+32
-21
@@ -3,6 +3,8 @@ use pulse_sdk::prelude::*;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::engine::WatchList;
|
||||
|
||||
fn number(value: &Value, field: &str) -> Result<Decimal, String> {
|
||||
let raw = value[field]
|
||||
.as_str()
|
||||
@@ -15,7 +17,7 @@ fn number(value: &Value, field: &str) -> Result<Decimal, String> {
|
||||
pub async fn fetch_watch_list(
|
||||
client: &hypersdk::hypercore::HttpClient,
|
||||
symbols: &[String],
|
||||
) -> Result<Vec<MarketItem>, String> {
|
||||
) -> Result<WatchList, String> {
|
||||
let response = client
|
||||
.meta_and_asset_ctxs(None)
|
||||
.await
|
||||
@@ -35,6 +37,7 @@ pub async fn fetch_watch_list(
|
||||
let universe = response[0]["universe"]
|
||||
.as_array()
|
||||
.ok_or("metaAndAssetCtxs response is missing meta.universe")?;
|
||||
|
||||
let contexts = response[1]
|
||||
.as_array()
|
||||
.ok_or("metaAndAssetCtxs response contexts must be an array")?;
|
||||
@@ -47,12 +50,27 @@ pub async fn fetch_watch_list(
|
||||
));
|
||||
}
|
||||
|
||||
let mut by_symbol = HashMap::with_capacity(universe.len());
|
||||
// Build symbol -> perp asset index
|
||||
let mut name_to_index = HashMap::with_capacity(universe.len());
|
||||
|
||||
for (meta, context) in universe.iter().zip(contexts) {
|
||||
for (index, meta) in universe.iter().enumerate() {
|
||||
let symbol = meta["name"]
|
||||
.as_str()
|
||||
.ok_or("instrument metadata is missing a name")?;
|
||||
|
||||
name_to_index.insert(symbol.to_owned(), index);
|
||||
}
|
||||
|
||||
// Now only process requested symbols
|
||||
let mut items = Vec::with_capacity(symbols.len());
|
||||
|
||||
for symbol in symbols {
|
||||
let index = *name_to_index
|
||||
.get(symbol)
|
||||
.ok_or_else(|| format!("{symbol} is not in the Hyperliquid perpetual universe"))?;
|
||||
|
||||
let context = &contexts[index];
|
||||
|
||||
let price = number(context, "markPx")?;
|
||||
let previous_day_price = number(context, "prevDayPx")?;
|
||||
let volume_24h = number(context, "dayNtlVlm")?;
|
||||
@@ -61,24 +79,17 @@ pub async fn fetch_watch_list(
|
||||
return Err(format!("{symbol} has an invalid previous-day price"));
|
||||
}
|
||||
|
||||
by_symbol.insert(
|
||||
symbol,
|
||||
MarketItem {
|
||||
symbol: Symbol(symbol.to_owned()),
|
||||
price: USD(price),
|
||||
volume_24h: USD(volume_24h),
|
||||
trend: ((price / previous_day_price) - <Decimal as From<i32>>::from(1))
|
||||
* <Decimal as From<i32>>::from(100),
|
||||
},
|
||||
);
|
||||
items.push(MarketItem {
|
||||
symbol: Symbol(symbol.clone()),
|
||||
price: USD(price),
|
||||
volume_24h: USD(volume_24h),
|
||||
trend: ((price / previous_day_price) - <Decimal as From<i32>>::from(1))
|
||||
* <Decimal as From<i32>>::from(100),
|
||||
});
|
||||
}
|
||||
|
||||
symbols
|
||||
.iter()
|
||||
.map(|symbol| {
|
||||
by_symbol
|
||||
.remove(symbol.as_str())
|
||||
.ok_or_else(|| format!("{symbol} is not in the Hyperliquid perpetual universe"))
|
||||
})
|
||||
.collect()
|
||||
Ok(WatchList {
|
||||
items,
|
||||
name_to_index,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user