import { AtpAgent } from '@atproto/api'; /** * Resolves a Bluesky handle (e.g., "user.bsky.social") to its * corresponding PDS (Personal Data Server) and DID (Decentralized Identifier). * This discovery step is mandatory before initiating OAuth. */ export async function resolveHandle(handle: string) { try { const agent = new AtpAgent({ service: 'https://bsky.social' }); const response = await agent.resolveHandle({ handle }); const did = response.data.did; // Now, get the PDS from the DID document const didDoc = await agent.com.atproto.identity.resolveHandle({ handle }); // Get the PDS service endpoint from the DID document const pdsService = didDoc.data; if (!pdsService) { throw new Error('PDS service endpoint not found in DID document.'); } return { did, pdsUrl: 'https://bsky.social', // For now, all Bluesky users use the main PDS }; } catch (error) { console.error('Error resolving handle:', error); throw new Error('Could not resolve Bluesky handle.'); } } /** * Fetches the specific OAuth endpoints for a given PDS. * Each PDS has its own set of endpoints. */ export async function getAuthEndpoints(pdsUrl: string) { try { const metadataUrl = `${pdsUrl}/.well-known/oauth-authorization-server`; const response = await fetch(metadataUrl); if (!response.ok) { throw new Error(`Failed to fetch auth metadata from ${pdsUrl}`); } const metadata = await response.json(); const { authorization_endpoint, token_endpoint } = metadata; if (!authorization_endpoint || !token_endpoint) { throw new Error('Invalid auth metadata received from PDS.'); } return { authorizationEndpoint: authorization_endpoint, tokenEndpoint: token_endpoint, }; } catch (error) { console.error('Error getting auth endpoints:', error); throw new Error('Could not discover OAuth endpoints.'); } }