pub mod schema;
use reqwest::{self, Client};
use std::{collections::HashMap, time::Duration};
use url::Url;
static API_BASE_URL: &str = "https://ordiscan.com/v1";
type Result<T> = std::result::Result<T, OrdiscanError>;
#[derive(Debug, thiserror::Error)]
pub enum OrdiscanError {
#[error("api error")]
RequestError(#[from] reqwest::Error),
}
pub struct Ordiscan {
client: reqwest::Client,
api_key: String,
}
#[derive(Debug)]
pub struct GetListOfInscriptionParams<'a> {
pub address: Option<&'a str>,
pub content_type: Option<&'a str>,
pub sort: Sort,
pub after_number: Option<usize>,
pub before_number: Option<usize>,
}
#[derive(Debug)]
pub struct GetInscriptionInfoParams<'a> {
pub id: Option<&'a str>,
pub number: Option<usize>,
}
#[derive(Debug)]
pub enum Sort {
InscriptionNumberDesc,
InscriptionNumberAsc,
}
impl Sort {
pub fn as_str(&self) -> &'static str {
match self {
Sort::InscriptionNumberDesc => "inscription_number_desc", Sort::InscriptionNumberAsc => "inscription_number_asc",
}
}
}
impl<'a> Ordiscan {
pub fn new(key: String) -> reqwest::Result<Self> {
let client = Client::builder().timeout(Duration::from_secs(10)).build()?;
let api_key: String = key;
Ok(Self { client, api_key })
}
pub async fn get_inscription_info(
&self,
params: GetInscriptionInfoParams<'a>,
) -> Result<schema::InscriptionInfo> {
let header = format!("Bearer {}", self.api_key);
let mut url = Url::parse(format!("{}/inscription", API_BASE_URL).as_str()).unwrap();
if params.id.is_none() & params.number.is_none()
|| params.id.is_some() & params.number.is_some()
{
panic!("please supply either id or number")
}
if params.id.is_some() {
url.query_pairs_mut().append_pair("id", params.id.unwrap());
}
if params.number.is_some() {
url
.query_pairs_mut()
.append_pair("number", params.number.unwrap().to_string().as_str());
}
let data = self
.client
.get(url.to_string())
.header("Authorization", &header)
.send()
.await?
.json::<HashMap<String, schema::InscriptionInfo>>()
.await?;
Ok(data.get("data").unwrap().to_owned())
}
pub async fn get_list_of_inscriptions(
&self,
params: GetListOfInscriptionParams<'a>,
) -> Result<Vec<schema::InscriptionInfo>> {
let header = format!("Bearer {}", self.api_key);
let mut url = Url::parse(
format!(
"{}/inscriptions?sort={}",
API_BASE_URL,
params.sort.as_str()
)
.as_str(),
)
.unwrap();
if params.address.is_some() {
url
.query_pairs_mut()
.append_pair("address", params.address.unwrap());
}
if params.content_type.is_some() {
url
.query_pairs_mut()
.append_pair("content_type", params.content_type.unwrap());
}
if params.after_number.is_some() {
url.query_pairs_mut().append_pair(
"afterNumber",
params.after_number.unwrap().to_string().as_str(),
);
}
if params.before_number.is_some() {
url.query_pairs_mut().append_pair(
"beforeNumber",
params.before_number.unwrap().to_string().as_str(),
);
}
let data = self
.client
.get(url.to_string())
.header("Authorization", &header)
.send()
.await?
.json::<HashMap<String, Vec<schema::InscriptionInfo>>>()
.await?;
Ok(data.get("data").unwrap().to_vec())
}
pub async fn get_address_activity(&self, address: &str) -> Result<Vec<schema::AddressActivity>> {
let api_url = format!("{}/activity?address={}", API_BASE_URL, address);
let header = format!("Bearer {}", self.api_key);
let data = self
.client
.get(&api_url)
.header("Authorization", &header)
.send()
.await?
.json::<HashMap<String, Vec<schema::AddressActivity>>>()
.await?;
Ok(data.get("data").unwrap().to_vec())
}
}