Scratch space for learning atproto app development
1import { IdResolver, DidDocument, CacheResult } from '@atproto/identity' 2import type { Database } from '#/db' 3 4const HOUR = 60e3 * 60 5const DAY = HOUR * 24 6 7export function createResolver(db: Database) { 8 const resolver = new IdResolver({ 9 didCache: { 10 async cacheDid(did: string, doc: DidDocument): Promise<void> { 11 await db 12 .insertInto('did_cache') 13 .values({ 14 did, 15 doc: JSON.stringify(doc), 16 updatedAt: new Date().toISOString(), 17 }) 18 .onConflict((oc) => 19 oc.column('did').doUpdateSet({ 20 doc: JSON.stringify(doc), 21 updatedAt: new Date().toISOString(), 22 }) 23 ) 24 .execute() 25 }, 26 27 async checkCache(did: string): Promise<CacheResult | null> { 28 const row = await db 29 .selectFrom('did_cache') 30 .selectAll() 31 .where('did', '=', did) 32 .executeTakeFirst() 33 if (!row) return null 34 const now = Date.now() 35 const updatedAt = +new Date(row.updatedAt) 36 return { 37 did, 38 doc: JSON.parse(row.doc), 39 updatedAt, 40 stale: now > updatedAt + HOUR, 41 expired: now > updatedAt + DAY, 42 } 43 }, 44 45 async refreshCache( 46 did: string, 47 getDoc: () => Promise<DidDocument | null> 48 ): Promise<void> { 49 const doc = await getDoc() 50 if (doc) { 51 await this.cacheDid(did, doc) 52 } 53 }, 54 55 async clearEntry(did: string): Promise<void> { 56 await db.deleteFrom('did_cache').where('did', '=', did).execute() 57 }, 58 59 async clear(): Promise<void> { 60 await db.deleteFrom('did_cache').execute() 61 }, 62 }, 63 }) 64 65 return { 66 async resolveDidToHandle(did: string): Promise<string> { 67 const didDoc = await resolver.did.resolveAtprotoData(did) 68 const resolvedHandle = await resolver.handle.resolve(didDoc.handle) 69 if (resolvedHandle === did) { 70 return didDoc.handle 71 } 72 return did 73 }, 74 75 async resolveDidsToHandles( 76 dids: string[] 77 ): Promise<Record<string, string>> { 78 const didHandleMap: Record<string, string> = {} 79 const resolves = await Promise.all( 80 dids.map((did) => this.resolveDidToHandle(did).catch((_) => did)) 81 ) 82 for (let i = 0; i < dids.length; i++) { 83 didHandleMap[dids[i]] = resolves[i] 84 } 85 return didHandleMap 86 }, 87 } 88}