Live video on the AT Protocol
at next 61 lines 1.6 kB view raw
1export interface DIDDocument { 2 id: string; 3 service?: Array<{ 4 id: string; 5 type?: string; 6 serviceEndpoint?: string; 7 }>; 8 [key: string]: any; 9} 10 11export async function resolveDIDDocument(did: string): Promise<DIDDocument> { 12 let didDocUrl: string; 13 14 if (did.startsWith("did:web:")) { 15 // For did:web, construct the URL directly 16 const domain = did.replace("did:web:", "").replace(/:/g, "/"); 17 didDocUrl = `https://${domain}/.well-known/did.json`; 18 } else if (did.startsWith("did:plc:")) { 19 // For did:plc, use plc.directory 20 didDocUrl = `https://plc.directory/${did}`; 21 } else { 22 throw new Error(`Unsupported DID method: ${did}`); 23 } 24 25 const response = await fetch(didDocUrl); 26 if (!response.ok) { 27 throw new Error( 28 `Failed to resolve DID document for ${did}: ${response.status}`, 29 ); 30 } 31 32 return response.json(); 33} 34 35export function getPDSServiceEndpoint(didDoc: DIDDocument): string { 36 const pdsService = didDoc.service?.find((s) => s.id === "#atproto_pds"); 37 38 if (!pdsService?.serviceEndpoint) { 39 throw new Error("No PDS service endpoint found in DID document"); 40 } 41 42 return pdsService.serviceEndpoint; 43} 44 45export async function getBlob( 46 did: string, 47 cid: string, 48 didDoc?: DIDDocument, 49): Promise<Blob> { 50 const doc = didDoc || (await resolveDIDDocument(did)); 51 const pdsEndpoint = getPDSServiceEndpoint(doc); 52 53 const blobUrl = `${pdsEndpoint}/xrpc/com.atproto.sync.getBlob?did=${did}&cid=${cid}`; 54 55 const response = await fetch(blobUrl); 56 if (!response.ok) { 57 throw new Error(`Failed to fetch blob: ${response.status}`); 58 } 59 60 return response.blob(); 61}