Live video on the AT Protocol
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}