QuickDID is a high-performance AT Protocol identity resolution service written in Rust. It provides handle-to-DID resolution with Redis-backed caching and queue processing.
···1+//! Base handle resolver implementation.
2+//!
3+//! This module provides the fundamental handle resolution implementation that
4+//! performs actual DNS and HTTP lookups to resolve AT Protocol handles to DIDs.
5+6+use super::errors::HandleResolverError;
7+use super::traits::HandleResolver;
8+use async_trait::async_trait;
9+use atproto_identity::resolve::{DnsResolver, resolve_subject};
10+use reqwest::Client;
11+use std::sync::Arc;
12+13+/// Base handle resolver that performs actual resolution via DNS and HTTP.
14+///
15+/// This resolver implements the core AT Protocol handle resolution logic:
16+/// 1. DNS TXT record lookup for `_atproto.{handle}`
17+/// 2. HTTP well-known endpoint query at `https://{handle}/.well-known/atproto-did`
18+/// 3. DID document retrieval from PLC directory or web DIDs
19+///
20+/// # Example
21+///
22+/// ```no_run
23+/// use std::sync::Arc;
24+/// use reqwest::Client;
25+/// use atproto_identity::resolve::HickoryDnsResolver;
26+/// use quickdid::handle_resolver::{BaseHandleResolver, HandleResolver};
27+///
28+/// # async fn example() {
29+/// let dns_resolver = Arc::new(HickoryDnsResolver::create_resolver(&[]));
30+/// let http_client = Client::new();
31+///
32+/// let resolver = BaseHandleResolver {
33+/// dns_resolver,
34+/// http_client,
35+/// plc_hostname: "plc.directory".to_string(),
36+/// };
37+///
38+/// let did = resolver.resolve("alice.bsky.social").await.unwrap();
39+/// # }
40+/// ```
41+pub struct BaseHandleResolver {
42+ /// DNS resolver for handle-to-DID resolution via TXT records.
43+ pub dns_resolver: Arc<dyn DnsResolver>,
44+45+ /// HTTP client for DID document retrieval and well-known endpoint queries.
46+ pub http_client: Client,
47+48+ /// Hostname of the PLC directory server for `did:plc` resolution.
49+ pub plc_hostname: String,
50+}
51+52+#[async_trait]
53+impl HandleResolver for BaseHandleResolver {
54+ async fn resolve(&self, s: &str) -> Result<String, HandleResolverError> {
55+ resolve_subject(&self.http_client, &*self.dns_resolver, s)
56+ .await
57+ .map_err(|e| HandleResolverError::ResolutionFailed(e.to_string()))
58+ }
59+}
+26
src/handle_resolver/errors.rs
···00000000000000000000000000
···1+//! Error types for handle resolution operations.
2+//!
3+//! This module defines all error types used throughout the handle resolver components,
4+//! following the QuickDID error format conventions.
5+6+use thiserror::Error;
7+8+/// Errors that can occur during handle resolution
9+#[derive(Error, Debug)]
10+pub enum HandleResolverError {
11+ /// Failed to resolve subject through DNS or HTTP
12+ #[error("error-quickdid-resolve-1 Failed to resolve subject: {0}")]
13+ ResolutionFailed(String),
14+15+ /// Handle not found in cache with specific error message
16+ #[error("error-quickdid-resolve-2 Handle not found (cached): {0}")]
17+ HandleNotFoundCached(String),
18+19+ /// Handle not found in cache (generic)
20+ #[error("error-quickdid-resolve-3 Handle not found (cached)")]
21+ HandleNotFound,
22+23+ /// Mock resolver failure for testing
24+ #[error("error-quickdid-resolve-4 Mock resolution failure")]
25+ MockResolutionFailure,
26+}