···11from aiodns import DNSResolver, error as dns_error
22from aiohttp.client import ClientSession
33+from asyncio import tasks
34from os import getenv
45from re import match as regex_match
56from typing import Any
···35363637 if is_valid_handle(query):
3738 handle = query.lower()
3838- did = await resolve_did_from_handle(handle, didkv)
3939+ did = await resolve_did_from_handle(client, handle, didkv)
3940 if not did:
4041 return None
4142 doc = await resolve_doc_from_did(client, did)
···5455 handle = handle_from_doc(doc)
5556 if not handle:
5657 return None
5757- if await resolve_did_from_handle(handle, didkv) != did:
5858+ if await resolve_did_from_handle(client, handle, didkv) != did:
5859 return None
5960 return (did, handle, doc)
6061···737474757576async def resolve_did_from_handle(
7777+ client: ClientSession,
7678 handle: str,
7779 kv: KV = nokv,
7880 reload: bool = False,
7981) -> str | None:
8080- """Returns the DID for a given handle"""
8282+ """Returns the DID for a given handle."""
81838284 if not is_valid_handle(handle):
8385 return None
···8688 if did is not None and not reload:
8789 return did
88908989- resolver = DNSResolver()
9090- try:
9191- result = await resolver.query(f"_atproto.{handle}", "TXT")
9292- except dns_error.DNSError:
9393- return None
9191+ did = await _resolve_did_from_handle_dns(handle)
9292+ if did is None:
9393+ did = await _resolve_did_from_handle_wk(client, handle)
9494+9595+ if did is not None and is_valid_did(did):
9696+ kv.set(handle, value=did)
9797+ return did
9898+9999+ return None
100100+101101+102102+async def _resolve_did_from_handle_wk(client: ClientSession, handle: str) -> str | None:
103103+ """Resolve the DID for a given handle via .well-known"""
104104+105105+ url = f"https://{handle}/.well-known/atproto-did"
106106+ response = await client.get(url)
107107+ if response.ok:
108108+ return await response.text()
109109+ return None
110110+111111+112112+async def _resolve_did_from_handle_dns(handle: str) -> str | None:
113113+ """Resolve the DID for a given handle via DNS."""
114114+115115+ async with DNSResolver() as resolver:
116116+ try:
117117+ result = await resolver.query(f"_atproto.{handle}", "TXT")
118118+ except dns_error.DNSError:
119119+ return None
9412095121 for record in result:
9696- value = str(record.text).replace('"', "")
122122+ value = str(record.text).strip('"')
97123 if value.startswith("did="):
98124 did = value[4:]
99125 if is_valid_did(did):
100100- kv.set(handle, value=did)
101126 return did
102127103128 return None