A React component library for rendering common AT Protocol records for applications such as Bluesky and Leaflet.
1import { useEffect, useState } from 'react';
2import { useAtProto } from '../providers/AtProtoProvider';
3
4/**
5 * Resolves a handle to its DID, or returns the DID immediately when provided.
6 *
7 * @param handleOrDid - Bluesky handle or DID string.
8 * @returns {{ did: string | undefined; error: Error | undefined; loading: boolean }} Object containing the resolved DID, error (if any), and loading state.
9 */
10export function useDidResolution(handleOrDid: string | undefined) {
11 const { resolver } = useAtProto();
12 const [did, setDid] = useState<string | undefined>();
13 const [handle, setHandle] = useState<string | undefined>();
14 const [error, setError] = useState<Error | undefined>();
15 const [loading, setLoading] = useState(false);
16
17 useEffect(() => {
18 let cancelled = false;
19 const reset = () => {
20 setDid(undefined);
21 setHandle(undefined);
22 setError(undefined);
23 setLoading(false);
24 };
25 if (!handleOrDid) {
26 reset();
27 return () => { cancelled = true; };
28 }
29 const input = handleOrDid.trim();
30 if (!input) {
31 reset();
32 return () => { cancelled = true; };
33 }
34 setLoading(true);
35 setError(undefined);
36
37 (async () => {
38 try {
39 if (input.startsWith('did:')) {
40 if (!cancelled) {
41 setDid(input);
42 }
43 try {
44 const doc = await resolver.resolveDidDoc(input);
45 const aka = doc.alsoKnownAs?.find(a => a.startsWith('at://'));
46 const derivedHandle = aka ? aka.replace('at://', '') : undefined;
47 if (!cancelled) setHandle(derivedHandle);
48 } catch {
49 if (!cancelled) setHandle(undefined);
50 }
51 } else {
52 const resolvedDid = await resolver.resolveHandle(input);
53 if (!cancelled) {
54 setDid(resolvedDid);
55 setHandle(input.toLowerCase());
56 }
57 }
58 } catch (e) {
59 if (!cancelled) {
60 setDid(undefined);
61 setHandle(undefined);
62 setError(e as Error);
63 }
64 } finally {
65 if (!cancelled) setLoading(false);
66 }
67 })();
68
69 return () => { cancelled = true; };
70 }, [handleOrDid, resolver]);
71
72 return { did, handle, error, loading };
73}