powerpointproto slides.waow.tech
slides
at main 111 lines 3.4 kB view raw
1import { Client } from "@atcute/client"; 2import { 3 CompositeDidDocumentResolver, 4 CompositeHandleResolver, 5 DohJsonHandleResolver, 6 PlcDidDocumentResolver, 7 AtprotoWebDidDocumentResolver, 8 WellKnownHandleResolver, 9} from "@atcute/identity-resolver"; 10import { 11 configureOAuth, 12 defaultIdentityResolver, 13 OAuthUserAgent, 14} from "@atcute/oauth-browser-client"; 15 16export const didDocumentResolver = new CompositeDidDocumentResolver({ 17 methods: { 18 plc: new PlcDidDocumentResolver(), 19 web: new AtprotoWebDidDocumentResolver(), 20 }, 21}); 22 23export const handleResolver = new CompositeHandleResolver({ 24 strategy: "dns-first", 25 methods: { 26 dns: new DohJsonHandleResolver({ dohUrl: "https://dns.google/resolve?" }), 27 http: new WellKnownHandleResolver(), 28 }, 29}); 30 31const OAUTH_CLIENT_ID = import.meta.env.VITE_OAUTH_CLIENT_ID; 32const OAUTH_REDIRECT_URI = import.meta.env.VITE_OAUTH_REDIRECT_URI; 33 34if (typeof window !== "undefined") { 35 configureOAuth({ 36 metadata: { 37 client_id: OAUTH_CLIENT_ID, 38 redirect_uri: OAUTH_REDIRECT_URI, 39 }, 40 identityResolver: defaultIdentityResolver({ 41 handleResolver, 42 didDocumentResolver, 43 }), 44 }); 45} 46 47// module-level state 48export let agent: OAuthUserAgent | null = null; 49export let currentDid: string | null = null; 50 51export const setAgent = (a: OAuthUserAgent | null) => { agent = a; }; 52export const setCurrentDid = (did: string | null) => { currentDid = did; }; 53export const getAgent = () => agent; 54export const getCurrentDid = () => currentDid; 55 56// eslint-disable-next-line @typescript-eslint/no-explicit-any 57export const getRpc = (): any => { 58 if (!agent) throw new Error("not logged in"); 59 return new Client({ handler: agent }); 60}; 61 62export const getPdsUrl = (): string | null => { 63 if (!agent) return null; 64 // eslint-disable-next-line @typescript-eslint/no-explicit-any 65 const session = (agent as any).session; 66 return session?.info?.aud || null; 67}; 68 69// handle resolution 70const handleCache = new Map<string, string>(); 71 72export const resolveHandle = async (did: string): Promise<string> => { 73 if (handleCache.has(did)) return handleCache.get(did)!; 74 try { 75 const res = await fetch(`https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${did}`); 76 if (res.ok) { 77 const data = await res.json(); 78 if (data.handle) { 79 handleCache.set(did, data.handle); 80 return data.handle; 81 } 82 } 83 } catch { /* ignore */ } 84 return did; 85}; 86 87// PDS URL resolution from DID document 88const pdsCache = new Map<string, string>(); 89 90export const resolvePdsUrl = async (did: string): Promise<string> => { 91 if (pdsCache.has(did)) return pdsCache.get(did)!; 92 try { 93 // eslint-disable-next-line @typescript-eslint/no-explicit-any 94 const doc = await didDocumentResolver.resolve(did as any); 95 const pds = doc.service?.find(s => s.id === "#atproto_pds"); 96 if (pds && typeof pds.serviceEndpoint === "string") { 97 pdsCache.set(did, pds.serviceEndpoint); 98 return pds.serviceEndpoint; 99 } 100 } catch { /* ignore */ } 101 return "https://bsky.social"; 102}; 103 104// public API fetch (no auth required) 105export const publicFetch = async (pdsUrl: string, method: string, params: Record<string, string>) => { 106 const url = new URL(`/xrpc/${method}`, pdsUrl); 107 Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v)); 108 const res = await fetch(url.toString()); 109 if (!res.ok) return null; 110 return res.json(); 111};