2023-03-13 09:51:30 -07:00
|
|
|
use crate::server_error::ServerError;
|
|
|
|
use openbook_candles::{
|
2023-03-13 14:18:18 -07:00
|
|
|
database::fetch::{
|
|
|
|
fetch_top_traders_by_base_volume_from, fetch_top_traders_by_quote_volume_from,
|
|
|
|
},
|
|
|
|
structs::trader::{calculate_trader_volume, Trader, TraderResponse, VolumeType},
|
2023-03-13 09:51:30 -07:00
|
|
|
utils::{to_timestampz, WebContext},
|
|
|
|
};
|
|
|
|
use {
|
|
|
|
actix_web::{get, web, HttpResponse},
|
|
|
|
serde::Deserialize,
|
|
|
|
};
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
2023-05-07 14:43:55 -07:00
|
|
|
pub struct TraderParams {
|
2023-03-13 09:51:30 -07:00
|
|
|
pub market_name: String,
|
|
|
|
pub from: u64,
|
|
|
|
pub to: u64,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/traders/base-volume")]
|
|
|
|
pub async fn get_top_traders_by_base_volume(
|
2023-05-07 14:43:55 -07:00
|
|
|
info: web::Query<TraderParams>,
|
2023-03-13 09:51:30 -07:00
|
|
|
context: web::Data<WebContext>,
|
|
|
|
) -> Result<HttpResponse, ServerError> {
|
|
|
|
let selected_market = context.markets.iter().find(|x| x.name == info.market_name);
|
|
|
|
if selected_market.is_none() {
|
|
|
|
return Err(ServerError::MarketNotFound);
|
|
|
|
}
|
|
|
|
let selected_market = selected_market.unwrap();
|
|
|
|
let from = to_timestampz(info.from);
|
|
|
|
let to = to_timestampz(info.to);
|
|
|
|
|
2023-05-14 01:09:12 -07:00
|
|
|
let raw_traders = match fetch_top_traders_by_base_volume_from(
|
|
|
|
&context.pool,
|
|
|
|
&selected_market.address,
|
|
|
|
from,
|
|
|
|
to,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
{
|
|
|
|
Ok(c) => c,
|
|
|
|
Err(_) => return Err(ServerError::DbQueryError),
|
|
|
|
};
|
2023-03-13 09:51:30 -07:00
|
|
|
|
|
|
|
let traders = raw_traders
|
|
|
|
.into_iter()
|
|
|
|
.map(|t| calculate_trader_volume(t, selected_market.base_decimals))
|
|
|
|
.collect::<Vec<Trader>>();
|
|
|
|
|
2023-03-13 14:18:18 -07:00
|
|
|
let response = TraderResponse {
|
|
|
|
start_time: info.from,
|
|
|
|
end_time: info.to,
|
2023-05-19 17:16:37 -07:00
|
|
|
traders,
|
2023-03-13 14:18:18 -07:00
|
|
|
volume_type: VolumeType::Base.to_string(),
|
|
|
|
};
|
|
|
|
Ok(HttpResponse::Ok().json(response))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/traders/quote-volume")]
|
|
|
|
pub async fn get_top_traders_by_quote_volume(
|
2023-05-07 14:43:55 -07:00
|
|
|
info: web::Query<TraderParams>,
|
2023-03-13 14:18:18 -07:00
|
|
|
context: web::Data<WebContext>,
|
|
|
|
) -> Result<HttpResponse, ServerError> {
|
|
|
|
let selected_market = context.markets.iter().find(|x| x.name == info.market_name);
|
|
|
|
if selected_market.is_none() {
|
|
|
|
return Err(ServerError::MarketNotFound);
|
|
|
|
}
|
|
|
|
let selected_market = selected_market.unwrap();
|
|
|
|
let from = to_timestampz(info.from);
|
|
|
|
let to = to_timestampz(info.to);
|
|
|
|
|
2023-05-14 01:09:12 -07:00
|
|
|
let raw_traders = match fetch_top_traders_by_quote_volume_from(
|
|
|
|
&context.pool,
|
|
|
|
&selected_market.address,
|
|
|
|
from,
|
|
|
|
to,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
{
|
|
|
|
Ok(c) => c,
|
|
|
|
Err(_) => return Err(ServerError::DbQueryError),
|
|
|
|
};
|
2023-03-13 14:18:18 -07:00
|
|
|
|
|
|
|
let traders = raw_traders
|
|
|
|
.into_iter()
|
|
|
|
.map(|t| calculate_trader_volume(t, selected_market.quote_decimals))
|
|
|
|
.collect::<Vec<Trader>>();
|
|
|
|
|
|
|
|
let response = TraderResponse {
|
|
|
|
start_time: info.from,
|
|
|
|
end_time: info.to,
|
2023-05-19 17:16:37 -07:00
|
|
|
traders,
|
2023-03-13 14:18:18 -07:00
|
|
|
volume_type: VolumeType::Quote.to_string(),
|
|
|
|
};
|
|
|
|
Ok(HttpResponse::Ok().json(response))
|
2023-03-13 09:51:30 -07:00
|
|
|
}
|