Graphical PDS migrator for AT Protocol
at main 2.6 kB view raw
1import { IdResolver } from "npm:@atproto/identity"; 2import { Did } from "npm:@atproto/api"; 3 4interface AtprotoData { 5 did: string; 6 signingKey: string; 7 handle: string; 8 pds: string; 9} 10 11interface DidService { 12 id: string; 13 type: string; 14 serviceEndpoint: string; 15} 16 17/** 18 * ID resolver instance. 19 */ 20const idResolver = createIdResolver(); 21export const resolver = createBidirectionalResolver(idResolver); 22 23/** 24 * Create the ID resolver. 25 * @returns The ID resolver 26 */ 27export function createIdResolver() { 28 return new IdResolver({ 29 plcUrl: Deno.env.get("PLC_URL") ?? "https://plc.directory", 30 }); 31} 32 33/** 34 * The bidirectional resolver. 35 * @interface 36 */ 37export interface BidirectionalResolver { 38 resolveDidToHandle(did: string): Promise<string>; 39 resolveDidsToHandles(dids: string[]): Promise<Record<string, string>>; 40 resolveDidToPdsUrl(did: string): Promise<string | undefined>; 41} 42 43/** 44 * Create the bidirectional resolver. 45 * @param resolver - The ID resolver 46 * @returns The bidirectional resolver 47 */ 48export function createBidirectionalResolver(resolver: IdResolver) { 49 return { 50 async resolveDidToHandle(did: string): Promise<string> { 51 const didDoc = await resolver.did.resolveAtprotoData(did) as AtprotoData; 52 const resolvedHandle = await resolver.handle.resolve(didDoc.handle); 53 if (resolvedHandle === did) { 54 return didDoc.handle; 55 } 56 return did; 57 }, 58 59 async resolveHandleToDid(handle: string) { 60 return await resolver.handle.resolve(handle) as Did; 61 }, 62 63 async resolveDidToPdsUrl(did: string): Promise<string | undefined> { 64 try { 65 // First try the standard resolution 66 const didDoc = await resolver.did.resolveAtprotoData( 67 did, 68 ) as AtprotoData; 69 if (didDoc.pds) { 70 return didDoc.pds; 71 } else { 72 const forcedDidDoc = await resolver.did.resolveAtprotoData( 73 did, 74 true, 75 ); 76 if (forcedDidDoc.pds) { 77 return forcedDidDoc.pds; 78 } 79 } 80 } catch (err) { 81 console.error("Error resolving PDS URL:", err); 82 return undefined; 83 } 84 }, 85 86 async resolveDidsToHandles( 87 dids: string[], 88 ): Promise<Record<string, string>> { 89 const didHandleMap: Record<string, string> = {}; 90 const resolves = await Promise.all( 91 dids.map((did) => this.resolveDidToHandle(did).catch((_) => did)), 92 ); 93 for (let i = 0; i < dids.length; i++) { 94 didHandleMap[dids[i]] = resolves[i]; 95 } 96 return didHandleMap; 97 }, 98 }; 99}