mod debug;
mod transport;
use eyre::Result;
pub struct Client {
http: reqwest::Client,
base_url: String,
api_key: Option<String>,
}
#[allow(dead_code)]
impl Client {
pub fn new(base_url: &str, api_key: Option<String>) -> Self {
Self {
http: reqwest::Client::new(),
base_url: base_url.trim_end_matches('/').to_string(),
api_key,
}
}
pub fn api_key(&self) -> Option<String> {
self.api_key.clone()
}
pub async fn quote(&self, body: &serde_json::Value) -> Result<serde_json::Value> {
self.post(crate::routes::QUOTE, body).await
}
pub async fn health(&self) -> Result<serde_json::Value> {
self.get(crate::routes::HEALTH).await
}
pub async fn tokens(&self) -> Result<serde_json::Value> {
self.get(crate::routes::TOKENS).await
}
pub async fn pool(&self, chain_id: u64, address: &str) -> Result<serde_json::Value> {
self.get(&crate::routes::pool(chain_id, address)).await
}
pub async fn challenge(&self, address: &str) -> Result<serde_json::Value> {
self.post(
crate::routes::AUTH_CHALLENGE,
&serde_json::json!({ "address": address }),
)
.await
}
pub async fn register(
&self,
address: &str,
nonce: &str,
signature: &str,
) -> Result<serde_json::Value> {
self.post(
crate::routes::AUTH_REGISTER,
&serde_json::json!({
"address": address,
"nonce": nonce,
"signature": signature,
}),
)
.await
}
pub async fn key_info(&self) -> Result<serde_json::Value> {
self.get(crate::routes::AUTH_KEY_INFO).await
}
pub async fn pricing(&self) -> Result<serde_json::Value> {
self.get(crate::routes::AUTH_PRICING).await
}
pub async fn claim_quota(&self, chain_id: u64, tx_hash: &str) -> Result<serde_json::Value> {
self.post(
crate::routes::AUTH_QUOTA_CLAIM,
&serde_json::json!({
"chain_id": chain_id,
"tx_hash": tx_hash,
}),
)
.await
}
pub async fn status(&self) -> Result<serde_json::Value> {
self.get(crate::routes::STATUS).await
}
pub async fn discovery_stats(&self) -> Result<serde_json::Value> {
self.get("/admin/discovery-stats").await
}
pub async fn discover_slot(&self, token: &str, chain: &str) -> Result<serde_json::Value> {
let mut url = format!("{}{}", self.base_url, crate::routes::DISCOVER_SLOT);
let mut params = vec![format!("token={token}")];
if !chain.is_empty() {
params.push(format!("chain={chain}"));
}
if !params.is_empty() {
url = format!("{url}?{}", params.join("&"));
}
self.get_raw(&url).await
}
pub async fn pair_stats(
&self,
chain_id: Option<u64>,
sort_by: Option<&str>,
limit: Option<u32>,
) -> Result<serde_json::Value> {
let mut url = format!("{}{}", self.base_url, crate::routes::STATS_PAIRS);
let mut params = vec![];
if let Some(c) = chain_id {
params.push(format!("chain_id={c}"));
}
if let Some(s) = sort_by {
params.push(format!("sort_by={s}"));
}
if let Some(l) = limit {
params.push(format!("limit={l}"));
}
if !params.is_empty() {
url = format!("{url}?{}", params.join("&"));
}
self.get_raw(&url).await
}
pub async fn graph_summary(&self, chain_id: u64) -> Result<serde_json::Value> {
self.get(&crate::routes::graph_summary(chain_id)).await
}
pub async fn graph_token(&self, chain_id: u64, token: &str) -> Result<serde_json::Value> {
self.get(&crate::routes::graph_token(chain_id, token))
.await
}
pub async fn token_pools(&self, chain_id: u64, token: &str) -> Result<serde_json::Value> {
self.get(&crate::routes::token_pools(chain_id, token))
.await
}
pub async fn diagnose_pair(
&self,
chain_id: u64,
token_a: &str,
token_b: &str,
) -> Result<serde_json::Value> {
self.get(&crate::routes::diagnose_pair(chain_id, token_a, token_b))
.await
}
pub async fn sync_audit(&self, chain_id: u64) -> Result<serde_json::Value> {
self.get(&crate::routes::sync_audit(chain_id)).await
}
pub async fn sync_health(&self, chain_id: u64) -> Result<serde_json::Value> {
self.get(&crate::routes::sync_health(chain_id)).await
}
pub async fn webhook_config(&self, chain_id: u64) -> Result<serde_json::Value> {
self.get(&format!("/api/debug/webhook_config/{chain_id}"))
.await
}
pub async fn pool_audit(&self, chain_id: u64) -> Result<serde_json::Value> {
self.get(&crate::routes::pool_audit(chain_id)).await
}
pub async fn verify_quote(
&self,
chain_id: u64,
body: &serde_json::Value,
) -> Result<serde_json::Value> {
self.post(&crate::routes::verify_quote(chain_id), body)
.await
}
pub async fn exotic_parity(
&self,
chain_id: u64,
body: &serde_json::Value,
) -> Result<serde_json::Value> {
self.post(&crate::routes::exotic_parity(chain_id), body)
.await
}
pub async fn quote_breakdown(
&self,
chain_id: u64,
body: &serde_json::Value,
) -> Result<serde_json::Value> {
self.post(&format!("/api/debug/quote_breakdown/{chain_id}"), body)
.await
}
pub async fn quote_debug(
&self,
chain_id: u64,
token_in: &str,
token_out: &str,
amount_in: &str,
) -> Result<serde_json::Value> {
self.get(&crate::routes::quote_debug(
chain_id, token_in, token_out, amount_in,
))
.await
}
pub async fn rpc_stats(&self) -> Result<serde_json::Value> {
self.get(crate::routes::STATS_RPC).await
}
pub async fn warming_candidates(
&self,
chain_id: Option<u64>,
limit: Option<u32>,
) -> Result<serde_json::Value> {
let mut url = format!("{}{}", self.base_url, crate::routes::STATS_WARMING);
let mut params = vec![];
if let Some(c) = chain_id {
params.push(format!("chain_id={c}"));
}
if let Some(l) = limit {
params.push(format!("limit={l}"));
}
if !params.is_empty() {
url = format!("{url}?{}", params.join("&"));
}
self.get_raw(&url).await
}
pub async fn set_log_level(&self, filter: &str) -> Result<serde_json::Value> {
self.post(
crate::routes::LOG_LEVEL,
&serde_json::json!({ "filter": filter }),
)
.await
}
pub async fn issue_key(&self, body: &serde_json::Value) -> Result<serde_json::Value> {
self.post(crate::routes::ADMIN_KEYS_ISSUE, body).await
}
pub async fn list_keys(&self) -> Result<serde_json::Value> {
self.get(crate::routes::ADMIN_KEYS).await
}
pub async fn revoke_key(&self, key: &str) -> Result<()> {
self.post_status(
&crate::routes::admin_key_action(key, "revoke"),
&serde_json::json!({}),
)
.await
}
pub async fn activate_key(&self, key: &str) -> Result<()> {
self.post_status(
&crate::routes::admin_key_action(key, "activate"),
&serde_json::json!({}),
)
.await
}
pub async fn delete_key(&self, key: &str) -> Result<()> {
self.post_status(
&crate::routes::admin_key_action(key, "delete"),
&serde_json::json!({}),
)
.await
}
}