import { NodeOAuthClient, NodeSavedSession, NodeSavedState } from "@atproto/oauth-client-node"; const APP_URL = process.env.NEXT_PUBLIC_APP_URL; if (!APP_URL) { throw new Error( "NEXT_PUBLIC_APP_URL is not set. This is required for OAuth configuration." ); } const sessionStore = new Map(); const stateStore = new Map(); export const atprotoClient = new NodeOAuthClient({ clientMetadata: { application_type: "web", client_id: `${APP_URL}/api/auth/atproto/client-metadata.json`, client_name: "scrobbleToBio", dpop_bound_access_tokens: true, grant_types: ["authorization_code", "refresh_token"], redirect_uris: [`${APP_URL}/api/auth/atproto/callback`], response_types: ["code"], scope: "atproto transition:generic", token_endpoint_auth_method: "none" }, handleResolver: "https://bsky.social/xrpc/com.atproto.identity.resolveHandle", sessionStore: { async del(sub: string): Promise { sessionStore.delete(sub); }, async get(sub: string): Promise { return sessionStore.get(sub); }, async set(sub: string, session: NodeSavedSession): Promise { sessionStore.set(sub, session); } }, stateStore: { async del(key: string): Promise { stateStore.delete(key); }, async get(key: string): Promise { return stateStore.get(key); }, async set(key: string, internalState: NodeSavedState): Promise { stateStore.set(key, internalState); } } });