tangled.org trending bluesky account
1#[allow(dead_code)]
2use atrium_identity::handle::DnsTxtResolver;
3use reqwest::Client;
4use serde::{Deserialize, Serialize};
5use std::sync::Arc;
6
7/// Setup for dns resolver for the handle resolver
8pub struct ApiDNSTxtResolver {
9 client: Arc<Client>,
10}
11
12impl Default for ApiDNSTxtResolver {
13 fn default() -> Self {
14 Self {
15 client: Arc::new(Client::new()),
16 }
17 }
18}
19
20// curl --http2 --header "accept: application/dns-json" "https://one.one.one.one/dns-query?name=_atproto.baileytownsend.dev&type=TXT"
21impl DnsTxtResolver for ApiDNSTxtResolver {
22 async fn resolve(
23 &self,
24 query: &str,
25 ) -> core::result::Result<Vec<String>, Box<dyn std::error::Error + Send + Sync + 'static>> {
26 let request_url = format!(
27 "https://one.one.one.one/dns-query?name={}&type=TXT",
28 query.to_lowercase()
29 );
30
31 let resp = self
32 .client
33 .get(request_url)
34 .header("accept", "application/dns-json")
35 .send()
36 .await?;
37 if !resp.status().is_success() {
38 return Err(format!("HTTP request failed with status: {}", resp.status()).into());
39 }
40
41 let resp: DnsResponse = resp
42 .json()
43 .await
44 .map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync + 'static>)?;
45
46 let response_data = resp
47 .Answer
48 .iter()
49 .map(|a| a.data.clone().replace("\"", ""))
50 .collect::<Vec<String>>();
51 Ok(response_data)
52 }
53}
54
55#[derive(Debug, Serialize, Deserialize)]
56#[allow(non_snake_case)]
57pub struct DnsResponse {
58 pub Status: i32,
59 pub TC: bool,
60 pub RD: bool,
61 pub RA: bool,
62 pub AD: bool,
63 pub CD: bool,
64 pub Question: Vec<Question>,
65 pub Answer: Vec<Answer>,
66}
67
68#[derive(Debug, Serialize, Deserialize)]
69pub struct Question {
70 pub name: String,
71 #[serde(rename = "type")]
72 pub type_: i32,
73}
74
75#[derive(Debug, Serialize, Deserialize)]
76#[allow(non_snake_case)]
77pub struct Answer {
78 pub name: String,
79 #[serde(rename = "type")]
80 pub type_: i32,
81 pub TTL: i32,
82 pub data: String,
83}