···
const [loading, setLoading] = useState(false);
const [results, setResults] = useState<BenchmarkResult[]>([]);
+
const resolveHandle = async (handle: string): Promise<string | null> => {
+
const response = await fetch(
+
`https://quickdid.smokesignal.tools/xrpc/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}`
+
const data = await response.json();
+
toast.error(`Unable to resolve handle: ${data.message || "Invalid handle"}`);
+
toast.error("Failed to resolve handle");
const handleBenchmark = async () => {
+
toast.error("Please enter a DID or handle");
···
+
let resolvedDid = did.trim();
+
// If input doesn't start with "did:plc", treat it as a handle
+
if (!resolvedDid.startsWith("did:plc")) {
+
const resolved = await resolveHandle(resolvedDid);
+
resolvedDid = resolved;
+
toast.success(`Resolved to ${resolvedDid}`);
+
const benchmarkResults = await benchmarkAllMirrors(mirrors, resolvedDid);
setResults(benchmarkResults);
const successCount = benchmarkResults.filter(r => r.status === "success").length;
···
<div className="space-y-4">
<label htmlFor="did-input" className="block text-sm font-medium mb-2">
<div className="flex gap-3">
+
placeholder="did:plc:example123... or handle.bsky.social"
onChange={(e) => setDid(e.target.value)}
onKeyPress={handleKeyPress}
···
<div className="bg-muted/30 border border-border rounded-lg p-6">
<h3 className="font-semibold mb-2">How to use:</h3>
<ol className="list-decimal list-inside space-y-1 text-sm text-muted-foreground">
+
<li>Enter an ATProto DID or handle (e.g., did:plc:z72i7hdynmk6r22z27h6tvur or handle.bsky.social)</li>
<li>Click "Run Benchmark" or press Enter</li>
<li>View response times and status for each mirror</li>