A better Rust ATProto crate
at main 3.0 kB view raw
1use clap::Parser; 2use jacquard::client::BasicClient; 3use jacquard::types::string::Handle; 4use jacquard_identity::resolver::IdentityResolver; 5use miette::IntoDiagnostic; 6 7#[derive(Parser, Debug)] 8#[command(author, version, about = "Resolve a handle to its DID document")] 9struct Args { 10 /// Handle to resolve (e.g., alice.bsky.social) 11 #[arg(default_value = "pfrazee.com")] 12 handle: String, 13} 14 15#[tokio::main] 16async fn main() -> miette::Result<()> { 17 let args = Args::parse(); 18 19 // Parse the handle 20 let handle = Handle::new(&args.handle)?; 21 22 // Create an unauthenticated client with identity resolver 23 let client = BasicClient::unauthenticated(); 24 25 // Resolve handle to DID 26 println!("Resolving handle: {}", handle); 27 let did = client 28 .resolve_handle(&handle) 29 .await 30 .map_err(|e| miette::miette!("Failed to resolve handle: {}", e))?; 31 32 println!("DID: {}\n", did); 33 34 // Resolve DID document 35 let doc_response = client 36 .resolve_did_doc(&did) 37 .await 38 .map_err(|e| miette::miette!("Failed to resolve DID document: {}", e))?; 39 40 let doc = doc_response 41 .parse() 42 .map_err(|e| miette::miette!("Failed to parse DID document: {}", e))?; 43 44 println!("DID Document:"); 45 println!("ID: {}", doc.id); 46 47 if let Some(aka) = &doc.also_known_as { 48 if !aka.is_empty() { 49 println!("\nAlso Known As:"); 50 for handle in aka { 51 println!(" - {}", handle); 52 } 53 } 54 } 55 56 if let Some(verification_methods) = &doc.verification_method { 57 println!("\nVerification Methods:"); 58 for method in verification_methods { 59 println!(" ID: {}", method.id); 60 println!(" Type: {}", method.r#type); 61 if let Some(controller) = &method.controller { 62 println!(" Controller: {}", controller); 63 } 64 if let Some(key) = &method.public_key_multibase { 65 println!(" Public Key (multibase): {}", key); 66 } 67 if !method.extra_data.is_empty() { 68 println!(" Extra fields: {:?}", method.extra_data); 69 } 70 println!(); 71 } 72 } 73 74 if let Some(services) = &doc.service { 75 println!("Services:"); 76 for service in services { 77 println!(" ID: {}", service.id); 78 println!(" Type: {}", service.r#type); 79 if let Some(endpoint) = &service.service_endpoint { 80 println!(" Endpoint: {:?}", endpoint); 81 } 82 if !service.extra_data.is_empty() { 83 println!(" Extra fields: {:?}", service.extra_data); 84 } 85 println!(); 86 } 87 } 88 89 if !doc.extra_data.is_empty() { 90 for (key, value) in &doc.extra_data { 91 println!( 92 "{}: {}", 93 key, 94 serde_json::to_string_pretty(value).into_diagnostic()? 95 ); 96 } 97 } 98 99 Ok(()) 100}