use crate::handle_response;
use essential_node_types::Block;
use essential_types::{convert::bytes_from_word, ContentAddress, Key, Value, Word};
use reqwest::{Client, ClientBuilder};
use std::ops::Range;
#[derive(Clone)]
pub struct EssentialNodeClient {
client: Client,
url: reqwest::Url,
}
impl EssentialNodeClient {
pub fn new(addr: String) -> anyhow::Result<Self> {
let client = ClientBuilder::new().http2_prior_knowledge().build()?;
let url = reqwest::Url::parse(&addr)?;
Ok(Self { client, url })
}
pub async fn list_blocks(&self, range: Range<Word>) -> anyhow::Result<Vec<Block>> {
let url = self.url.join(&format!(
"/list-blocks?start={}&end={}",
range.start, range.end
))?;
let response = handle_response(self.client.get(url).send().await?).await?;
Ok(response.json::<Vec<Block>>().await?)
}
pub async fn query_state(
&self,
contract_ca: ContentAddress,
key: Key,
) -> anyhow::Result<Option<Value>> {
let key_bytes: Vec<_> = key.iter().copied().flat_map(bytes_from_word).collect();
let key = hex::encode(&key_bytes);
let url = self
.url
.join(&format!("/query-state/{contract_ca}/{key}"))?;
let response = handle_response(self.client.get(url).send().await?).await?;
Ok(response.json::<Option<Value>>().await?)
}
}