use crate::error::HermesError;
use crate::models::price_feeds::PriceFeed;
use crate::models::price_updates::{PriceUpdatesResponse};
use crate::models::publisher_stake_caps::PublisherStakeCapsResponse;
use crate::models::twap::TwapResponse;
use reqwest::{Client, StatusCode};
use std::fmt::Debug;
#[derive(Clone, Debug)]
pub struct HermesClient {
base_url: String,
http_client: Client,
}
impl HermesClient {
pub fn new<S: Into<String>>(base_url: S) -> Self {
HermesClient {
base_url: base_url.into(),
http_client: Client::new(),
}
}
pub async fn get_price_feeds(
&self,
query: Option<&str>,
asset_type: Option<&str>,
) -> Result<Vec<PriceFeed>, HermesError> {
let url = format!("{}/v2/price_feeds", self.base_url);
let mut request = self.http_client.get(&url);
if let Some(q) = query {
request = request.query(&[("query", q)]);
}
if let Some(a) = asset_type {
request = request.query(&[("asset_type", a)]);
}
let resp = request.send().await?;
if resp.status().is_success() {
let result = resp.json::<Vec<PriceFeed>>().await?;
Ok(result)
} else {
let status = resp.status();
let body = resp.text().await.unwrap_or_default();
Err(HermesError::ResponseError { status, body })
}
}
pub async fn get_latest_price_updates(
&self,
ids: &[&str],
encoding: Option<&str>, parsed: Option<bool>, ignore_invalid_price_ids: Option<bool>, ) -> Result<PriceUpdatesResponse, HermesError> {
let url = format!("{}/v2/updates/price/latest", self.base_url);
let mut request = self.http_client.get(&url);
for id in ids {
request = request.query(&[("ids[]", *id)]);
}
if let Some(enc) = encoding {
request = request.query(&[("encoding", enc)]);
}
if let Some(p) = parsed {
request = request.query(&[("parsed", p.to_string())]);
}
if let Some(i) = ignore_invalid_price_ids {
request = request.query(&[("ignore_invalid_price_ids", i.to_string())]);
}
let resp = request.send().await?;
match resp.status() {
StatusCode::OK => {
let result = resp.json::<PriceUpdatesResponse>().await?;
Ok(result)
}
code => {
let text = resp.text().await.unwrap_or_default();
Err(HermesError::ResponseError {
status: code,
body: text,
})
}
}
}
pub async fn get_price_updates_by_time(
&self,
publish_time: i64,
ids: &[&str],
encoding: Option<&str>,
parsed: Option<bool>,
ignore_invalid_price_ids: Option<bool>,
) -> Result<PriceUpdatesResponse, HermesError> {
let url = format!("{}/v2/updates/price/{}", self.base_url, publish_time);
let mut request = self.http_client.get(&url);
for id in ids {
request = request.query(&[("ids[]", *id)]);
}
if let Some(enc) = encoding {
request = request.query(&[("encoding", enc)]);
}
if let Some(p) = parsed {
request = request.query(&[("parsed", p.to_string())]);
}
if let Some(i) = ignore_invalid_price_ids {
request = request.query(&[("ignore_invalid_price_ids", i.to_string())]);
}
let resp = request.send().await?;
match resp.status() {
StatusCode::OK => {
let result = resp.json::<PriceUpdatesResponse>().await?;
Ok(result)
}
code => {
let text = resp.text().await.unwrap_or_default();
Err(HermesError::ResponseError {
status: code,
body: text,
})
}
}
}
pub async fn get_publisher_stake_caps(
&self,
encoding: Option<&str>,
parsed: Option<bool>,
) -> Result<PublisherStakeCapsResponse, HermesError> {
let url = format!("{}/v2/updates/publisher_stake_caps/latest", self.base_url);
let mut request = self.http_client.get(&url);
if let Some(enc) = encoding {
request = request.query(&[("encoding", enc)]);
}
if let Some(p) = parsed {
request = request.query(&[("parsed", p.to_string())]);
}
let resp = request.send().await?;
match resp.status() {
StatusCode::OK => {
let result = resp.json::<PublisherStakeCapsResponse>().await?;
Ok(result)
}
code => {
let text = resp.text().await.unwrap_or_default();
Err(HermesError::ResponseError {
status: code,
body: text,
})
}
}
}
pub async fn get_twap_latest(
&self,
window_seconds: u64,
ids: &[&str],
encoding: Option<&str>,
parsed: Option<bool>,
ignore_invalid_price_ids: Option<bool>,
) -> Result<TwapResponse, HermesError> {
let url = format!(
"{}/v2/updates/twap/{}/latest",
self.base_url, window_seconds
);
let mut request = self.http_client.get(&url);
for id in ids {
request = request.query(&[("ids[]", *id)]);
}
if let Some(enc) = encoding {
request = request.query(&[("encoding", enc)]);
}
if let Some(p) = parsed {
request = request.query(&[("parsed", p.to_string())]);
}
if let Some(i) = ignore_invalid_price_ids {
request = request.query(&[("ignore_invalid_price_ids", i.to_string())]);
}
let resp = request.send().await?;
match resp.status() {
StatusCode::OK => {
let result = resp.json::<TwapResponse>().await?;
Ok(result)
}
code => {
let text = resp.text().await.unwrap_or_default();
Err(HermesError::ResponseError {
status: code,
body: text,
})
}
}
}
}