use jacquard::deps::fluent_uri::Uri; use jacquard::types::string::AtIdentifier; use jacquard::types::string::RecordKey; use jacquard::xrpc::XrpcExt; use jacquard_api::com_atproto::repo::get_record::GetRecord; use jacquard_identity::JacquardResolver; use jacquard_identity::resolver::IdentityResolver; use std::str::FromStr; use crate::store::{self, DidDocRecord}; pub async fn get_did_doc( resolver: JacquardResolver, pool: &sqlx::SqlitePool, raw_did: &String, ) -> anyhow::Result { match store::get_did_doc_by_did(pool, raw_did).await { Some(doc) => return Ok(doc), _ => {} }; let at_id = AtIdentifier::from_str(raw_did).map_err(|err| { println!("parsing did {err}"); err })?; let did = match at_id { AtIdentifier::Did(did) => did, AtIdentifier::Handle(h) => resolver.resolve_handle(&h).await.map_err(|err| { println!("error resolving handle: {err}"); err })?, }; let did_doc_resp = resolver.resolve_did_doc(&did).await.map_err(|err| { println!("fetching did doc:{err}"); err })?; let did_doc = did_doc_resp.parse().map_err(|err| { println!("parsing did doc:{err}"); err })?; let handle = did_doc .handles() .get(0) .cloned() .ok_or_else(|| anyhow::Error::msg("could not find handle in did doc"))?; let pds_endpoint = did_doc.pds_endpoint().ok_or_else(|| { println!("no pds endpoint found in did doc...."); anyhow::Error::msg("no pds endpoint found in did doc") })?; let did_doc_record = store::DidDocRecord { did: did.to_string(), handle: handle.to_string(), pds_endpoint: pds_endpoint.to_string(), }; store::insert_did_doc_record(pool, &did_doc_record).await; Ok(did_doc_record) } pub async fn get_profile_from_pds( pool: sqlx::SqlitePool, did: String, pds_endpoint: String, ) -> anyhow::Result<()> { match store::get_profile_blob_did(&pool, &did).await { Some(_) => return Ok(()), _ => {} }; let rkey = RecordKey::from_str(&"self".to_string()).map_err(|err| err)?; let req = GetRecord::new() .repo(did.clone()) .collection("app.bsky.actor.profile".to_string()) .rkey(rkey) .build(); let http = reqwest::Client::new(); let base = Uri::parse(pds_endpoint) .to_owned() .map_err(|err| anyhow::Error::msg(err.1))?; let response = http.xrpc(base.to_owned()).send(&req).await?; let record = response.into_output()?; let raw_json = serde_json::to_vec(&record.value)?; store::insert_profile(&pool, did.clone(), raw_json).await; Ok(()) }