const PDS_SERVICE_ID = "#atproto_pds"; async function getServiceEndpointFromDidDoc(didDoc) { const service = didDoc.service.find((s) => s.id === PDS_SERVICE_ID); if (!service) { throw new Error( `No PDS service found in DID doc ${JSON.stringify(didDoc)}` ); } return service.serviceEndpoint; } export async function resolveHandle(handle) { const params = new URLSearchParams({ handle, }); const res = await fetch( "https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?" + params.toString() ); const data = await res.json(); return data.did; } async function resolveDid(did) { if (did.startsWith("did:plc:")) { const res = await fetch(`https://plc.directory/${encodeURIComponent(did)}`); const didDoc = await res.json(); return didDoc; } else if (did.startsWith("did:web:")) { const website = did.split(":")[2]; const res = await fetch(`https://${website}/.well-known/did.json`); const didDoc = await res.json(); return didDoc; } else { throw new Error(`Unsupported DID: ${did}`); } } async function getServiceEndpointForDid(did) { const didDoc = await resolveDid(did); return getServiceEndpointFromDidDoc(didDoc); } export async function listRecords({ did, collection }) { const serviceEndpoint = await getServiceEndpointForDid(did); let cursor = ""; const records = []; do { const res = await fetch( `${serviceEndpoint}/xrpc/com.atproto.repo.listRecords?repo=${did}&collection=${collection}&limit=100&cursor=${cursor}` ); const data = await res.json(); const recordsWithAuthor = data.records.map((record) => { return { ...record, author: did, }; }); records.push(...recordsWithAuthor); cursor = data.cursor; } while (cursor); return records; }