at main 4.6 kB view raw
1<script lang="ts"> 2 import { api } from '$lib/api'; 3 import { processIndexedEntryLog } from '@atcute/did-plc'; 4 import { 5 CompositeHandleResolver, 6 DohJsonHandleResolver, 7 WellKnownHandleResolver, 8 DidNotFoundError, 9 InvalidResolvedHandleError, 10 AmbiguousHandleError, 11 FailedHandleResolutionError, 12 HandleResolutionError 13 } from '@atcute/identity-resolver'; 14 import AuditLog from '../components/AuditLog.svelte'; 15 16 let didInput = ''; 17 let loading = false; 18 let result: any = null; 19 let auditLogData: { canonical: any[], nullified: any[] } | null = null; 20 let error = ''; 21 let resolvedDid = ''; 22 23 const handleResolver = new CompositeHandleResolver({ 24 strategy: 'race', 25 methods: { 26 dns: new DohJsonHandleResolver({ dohUrl: 'https://mozilla.cloudflare-dns.com/dns-query' }), 27 http: new WellKnownHandleResolver(), 28 }, 29 }); 30 31 function isDid(input: string): boolean { 32 return input.startsWith('did:plc:'); 33 } 34 35 async function resolveInputToDid(input: string): Promise<string> { 36 const trimmedInput = input.trim(); 37 38 if (isDid(trimmedInput)) { 39 return trimmedInput; 40 } 41 42 try { 43 const resolvedHandle = await handleResolver.resolve(trimmedInput); 44 return resolvedHandle; 45 } catch (err) { 46 if (err instanceof DidNotFoundError) { 47 throw new Error("Handle not found - DID not found for this handle"); 48 } 49 if (err instanceof InvalidResolvedHandleError) { 50 throw new Error("Invalid handle format"); 51 } 52 if (err instanceof AmbiguousHandleError) { 53 throw new Error("Ambiguous handle - multiple DIDs found"); 54 } 55 if (err instanceof FailedHandleResolutionError) { 56 throw new Error("Failed to resolve handle"); 57 } 58 if (err instanceof HandleResolutionError) { 59 throw new Error("Error resolving handle"); 60 } 61 throw new Error(`Handle resolution failed: ${err.message}`); 62 } 63 } 64 65 async function searchDID() { 66 if (!didInput.trim()) return; 67 68 loading = true; 69 error = ''; 70 result = null; 71 auditLogData = null; 72 resolvedDid = ''; 73 74 try { 75 const did = await resolveInputToDid(didInput); 76 resolvedDid = did; 77 78 const log = await api.fetchDidAuditLog(resolvedDid); 79 auditLogData = await processIndexedEntryLog(resolvedDid, log); 80 81 result = await api.fetchDidDocument(resolvedDid); 82 } catch (err: any) { 83 error = err.message; 84 } finally { 85 loading = false; 86 } 87 } 88</script> 89 90<div class="min-h-screen bg-gray-50 dark:bg-gray-900 p-8"> 91 <div class="max-w-4xl mx-auto"> 92 <div class="flex justify-between items-center mb-8"> 93 <h1 class="text-4xl font-bold text-gray-900 dark:text-white text-center flex-1"> 94 PLC Directory 95 </h1> 96 </div> 97 98 <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-6 transition-colors"> 99 <div class="flex gap-4"> 100 <input 101 bind:value={didInput} 102 type="text" 103 placeholder="Enter DID (did:plc:...) or handle (user.bsky.social)" 104 class="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 105 bg-white dark:bg-gray-700 text-gray-900 dark:text-white 106 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 107 placeholder-gray-500 dark:placeholder-gray-400 transition-colors" 108 disabled={loading} 109 /> 110 <button 111 on:click={searchDID} 112 disabled={loading || !didInput.trim()} 113 class="px-6 py-2 bg-blue-600 hover:bg-blue-700 dark:bg-blue-700 dark:hover:bg-blue-600 114 text-white rounded-md disabled:opacity-50 transition-colors" 115 > 116 {loading ? 'Searching...' : 'Search'} 117 </button> 118 </div> 119 120 {#if error} 121 <div class="mt-4 p-4 bg-red-50 dark:bg-red-900/50 border border-red-200 dark:border-red-800 rounded-md transition-colors"> 122 <p class="text-red-800 dark:text-red-200">{error}</p> 123 </div> 124 {/if} 125 </div> 126 127 <div class="mb-6"> 128 <AuditLog auditData={auditLogData} /> 129 </div> 130 131 {#if result} 132 <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 transition-colors"> 133 <h2 class="text-2xl font-semibold mb-4 text-gray-900 dark:text-white">DID Document</h2> 134<pre class="bg-gray-100 dark:bg-gray-700 text-gray-900 dark:text-gray-100 135 p-4 rounded-md overflow-x-auto text-sm transition-colors"><code>{JSON.stringify(result, null, 2)}</code></pre> 136 </div> 137 {/if} 138 </div> 139</div>