use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; /// HTTP client for communicating with the onis appview API. #[derive(Clone)] pub struct AppviewClient { /// Underlying HTTP client. client: reqwest::Client, /// Base URL of the appview, e.g. `"http://localhost:3000"`. base_url: String, } /// A zone that is due for re-verification, returned by the appview stale zones endpoint. #[derive(Debug, Deserialize)] pub struct StaleZoneEntry { /// Domain name of the zone. pub zone: String, /// DID of the zone owner. pub did: String, /// Current verification status. pub verified: bool, /// Unix timestamp when the zone was first seen. pub first_seen: i64, /// Unix timestamp of the last successful verification, if any. pub last_verified: Option, } /// Wire format for the `GET /v1/zones/stale` response. #[derive(Debug, Deserialize)] struct StaleZonesResponse { /// List of zones needing re-verification. zones: Vec, } /// Request body for `PUT /v1/verification`. #[derive(Serialize)] struct VerificationBody { /// Domain name of the zone. zone: String, /// DID of the zone owner. did: String, /// Whether the zone passed delegation verification. verified: bool, } impl AppviewClient { pub fn new(base_url: String) -> Self { Self { client: reqwest::Client::new(), base_url, } } pub async fn get_stale_zones(&self, checked_before: i64) -> Result> { let url = format!( "{}/v1/zones/stale?checked_before={}", self.base_url, checked_before ); let body: StaleZonesResponse = self .client .get(&url) .send() .await .context("failed to fetch stale zones")? .error_for_status() .context("stale zones request failed")? .json() .await .context("failed to deserialize stale zones response")?; Ok(body.zones) } pub async fn set_verification(&self, zone: &str, did: &str, verified: bool) -> Result<()> { let url = format!("{}/v1/verification", self.base_url); self.client .put(&url) .json(&VerificationBody { zone: zone.to_string(), did: did.to_string(), verified, }) .send() .await .context("failed to set verification")? .error_for_status() .with_context(|| format!("set verification for {zone} failed"))?; Ok(()) } }