+31
-5
crates/atproto-client/src/record_resolver.rs
+31
-5
crates/atproto-client/src/record_resolver.rs
···
1
//! Helpers for resolving AT Protocol records referenced by URI.
2
3
use std::str::FromStr;
4
5
use anyhow::{Result, anyhow, bail};
6
use async_trait::async_trait;
7
use atproto_record::aturi::ATURI;
8
9
use crate::{
···
24
}
25
26
/// Resolver that fetches records using public XRPC endpoints.
27
#[derive(Clone)]
28
pub struct HttpRecordResolver {
29
http_client: reqwest::Client,
30
-
base_url: String,
31
}
32
33
impl HttpRecordResolver {
34
-
/// Create a new resolver using the provided HTTP client and PDS base URL.
35
-
pub fn new(http_client: reqwest::Client, base_url: impl Into<String>) -> Self {
36
Self {
37
http_client,
38
-
base_url: base_url.into(),
39
}
40
}
41
}
···
47
T: serde::de::DeserializeOwned + Send,
48
{
49
let parsed = ATURI::from_str(aturi).map_err(|error| anyhow!(error))?;
50
let auth = Auth::None;
51
52
let response = get_record(
53
&self.http_client,
54
&auth,
55
-
&self.base_url,
56
&parsed.authority,
57
&parsed.collection,
58
&parsed.record_key,
···
1
//! Helpers for resolving AT Protocol records referenced by URI.
2
3
use std::str::FromStr;
4
+
use std::sync::Arc;
5
6
use anyhow::{Result, anyhow, bail};
7
use async_trait::async_trait;
8
+
use atproto_identity::traits::IdentityResolver;
9
use atproto_record::aturi::ATURI;
10
11
use crate::{
···
26
}
27
28
/// Resolver that fetches records using public XRPC endpoints.
29
+
///
30
+
/// Uses an identity resolver to dynamically determine the PDS endpoint for each record.
31
#[derive(Clone)]
32
pub struct HttpRecordResolver {
33
http_client: reqwest::Client,
34
+
identity_resolver: Arc<dyn IdentityResolver>,
35
}
36
37
impl HttpRecordResolver {
38
+
/// Create a new resolver using the provided HTTP client and identity resolver.
39
+
///
40
+
/// The identity resolver is used to dynamically determine the PDS endpoint for each record
41
+
/// based on the authority (DID or handle) in the AT URI.
42
+
pub fn new(
43
+
http_client: reqwest::Client,
44
+
identity_resolver: Arc<dyn IdentityResolver>,
45
+
) -> Self {
46
Self {
47
http_client,
48
+
identity_resolver,
49
}
50
}
51
}
···
57
T: serde::de::DeserializeOwned + Send,
58
{
59
let parsed = ATURI::from_str(aturi).map_err(|error| anyhow!(error))?;
60
+
61
+
// Resolve the authority (DID or handle) to get the DID document
62
+
let document = self
63
+
.identity_resolver
64
+
.resolve(&parsed.authority)
65
+
.await
66
+
.map_err(|error| {
67
+
anyhow!("Failed to resolve identity for {}: {}", parsed.authority, error)
68
+
})?;
69
+
70
+
// Extract PDS endpoint from the DID document
71
+
let pds_endpoints = document.pds_endpoints();
72
+
let base_url = pds_endpoints
73
+
.first()
74
+
.ok_or_else(|| anyhow!("No PDS endpoint found for {}", parsed.authority))?;
75
+
76
let auth = Auth::None;
77
78
let response = get_record(
79
&self.http_client,
80
&auth,
81
+
base_url,
82
&parsed.authority,
83
&parsed.collection,
84
&parsed.record_key,