diff --git a/crates/jacquard-identity/src/lib.rs b/crates/jacquard-identity/src/lib.rs index 9c41f8020..4f2d5041b 100644 --- a/crates/jacquard-identity/src/lib.rs +++ b/crates/jacquard-identity/src/lib.rs @@ -378,9 +378,13 @@ impl IdentityResolver for JacquardResolver { } DidStep::PlcHttp if s.starts_with("did:plc:") => { let url = match &self.opts.plc_source { - PlcSource::PlcDirectory { base } => base.join(did.as_str())?, + PlcSource::PlcDirectory { base } => { + // this is odd, the join screws up with the plc directory but NOT slingshot + Url::parse(&format!("{}{}", base, did.as_str())).expect("Invalid URL") + } PlcSource::Slingshot { base } => base.join(did.as_str())?, }; + println!("Fetching DID document from {}", url); if let Ok((buf, status)) = self.get_json_bytes(url).await { return Ok(DidDocResponse { buffer: buf, diff --git a/crates/jacquard-identity/src/resolver.rs b/crates/jacquard-identity/src/resolver.rs index d6edf888f..b97d60332 100644 --- a/crates/jacquard-identity/src/resolver.rs +++ b/crates/jacquard-identity/src/resolver.rs @@ -36,22 +36,37 @@ use url::Url; #[allow(missing_docs)] pub enum IdentityError { #[error("unsupported DID method: {0}")] - #[diagnostic(code(jacquard_identity::unsupported_did_method), help("supported DID methods: did:web, did:plc"))] + #[diagnostic( + code(jacquard_identity::unsupported_did_method), + help("supported DID methods: did:web, did:plc") + )] UnsupportedDidMethod(String), #[error("invalid well-known atproto-did content")] - #[diagnostic(code(jacquard_identity::invalid_well_known), help("expected first non-empty line to be a DID"))] + #[diagnostic( + code(jacquard_identity::invalid_well_known), + help("expected first non-empty line to be a DID") + )] InvalidWellKnown, #[error("missing PDS endpoint in DID document")] #[diagnostic(code(jacquard_identity::missing_pds_endpoint))] MissingPdsEndpoint, #[error("HTTP error: {0}")] - #[diagnostic(code(jacquard_identity::http), help("check network connectivity and TLS configuration"))] + #[diagnostic( + code(jacquard_identity::http), + help("check network connectivity and TLS configuration") + )] Http(#[from] TransportError), #[error("HTTP status {0}")] - #[diagnostic(code(jacquard_identity::http_status), help("verify well-known paths or PDS XRPC endpoints"))] + #[diagnostic( + code(jacquard_identity::http_status), + help("verify well-known paths or PDS XRPC endpoints") + )] HttpStatus(StatusCode), #[error("XRPC error: {0}")] - #[diagnostic(code(jacquard_identity::xrpc), help("enable PDS fallback or public resolver if needed"))] + #[diagnostic( + code(jacquard_identity::xrpc), + help("enable PDS fallback or public resolver if needed") + )] Xrpc(String), #[error("URL parse error: {0}")] #[diagnostic(code(jacquard_identity::url))] @@ -64,14 +79,20 @@ pub enum IdentityError { #[diagnostic(code(jacquard_identity::serde))] Serde(#[from] serde_json::Error), #[error("invalid DID document: {0}")] - #[diagnostic(code(jacquard_identity::invalid_doc), help("validate keys and services; ensure AtprotoPersonalDataServer service exists"))] + #[diagnostic( + code(jacquard_identity::invalid_doc), + help("validate keys and services; ensure AtprotoPersonalDataServer service exists") + )] InvalidDoc(String), #[error(transparent)] #[diagnostic(code(jacquard_identity::data))] Data(#[from] AtDataError), /// DID document id did not match requested DID; includes the fetched document #[error("DID doc id mismatch")] - #[diagnostic(code(jacquard_identity::doc_id_mismatch), help("document id differs from requested DID; do not trust this document"))] + #[diagnostic( + code(jacquard_identity::doc_id_mismatch), + help("document id differs from requested DID; do not trust this document") + )] DocIdMismatch { expected: Did<'static>, doc: DidDocument<'static>, diff --git a/crates/jacquard/src/client/credential_session.rs b/crates/jacquard/src/client/credential_session.rs index a82d3e954..b818199d5 100644 --- a/crates/jacquard/src/client/credential_session.rs +++ b/crates/jacquard/src/client/credential_session.rs @@ -403,22 +403,15 @@ where // Under Tokio, use `block_in_place` to make a blocking RwLock read safe. if tokio::runtime::Handle::try_current().is_ok() { tokio::task::block_in_place(|| { - self.endpoint - .blocking_read() - .clone() - .unwrap_or( - Url::parse("https://public.bsky.app") - .expect("public appview should be valid url"), - ) - }) - } else { - self.endpoint - .blocking_read() - .clone() - .unwrap_or( + self.endpoint.blocking_read().clone().unwrap_or( Url::parse("https://public.bsky.app") .expect("public appview should be valid url"), ) + }) + } else { + self.endpoint.blocking_read().clone().unwrap_or( + Url::parse("https://public.bsky.app").expect("public appview should be valid url"), + ) } } async fn send( diff --git a/crates/jacquard/src/main.rs b/crates/jacquard/src/main.rs index 93aacf10c..599fc0f19 100644 --- a/crates/jacquard/src/main.rs +++ b/crates/jacquard/src/main.rs @@ -1,12 +1,12 @@ -use std::sync::Arc; use clap::Parser; use jacquard::CowStr; use jacquard::api::app_bsky::feed::get_timeline::GetTimeline; use jacquard::client::credential_session::{CredentialSession, SessionKey}; use jacquard::client::{AtpSession, MemorySessionStore}; -use jacquard::identity::PublicResolver as JacquardResolver; use jacquard::types::xrpc::XrpcClient; +use jacquard_identity::slingshot_resolver_default; use miette::IntoDiagnostic; +use std::sync::Arc; #[derive(Parser, Debug)] #[command(author, version, about = "Jacquard - AT Protocol client demo")] @@ -24,14 +24,19 @@ async fn main() -> miette::Result<()> { let args = Args::parse(); // Resolver + in-memory store - let resolver = Arc::new(JacquardResolver::default()); + let resolver = Arc::new(slingshot_resolver_default()); let store: Arc> = Arc::new(Default::default()); let client = Arc::new(resolver.clone()); let session = CredentialSession::new(store, client); - // Login; resolves PDS from handle/DID automatically. Persisted under (did, "session"). let _ = session - .login(args.username.clone(), args.password.clone(), None, None, None) + .login( + args.username.clone(), + args.password.clone(), + None, + None, + None, + ) .await .into_diagnostic()?;