atprotocol stickers
1import { OAuthUserAgent, getSession, deleteStoredSession, listStoredSessions } from '@atcute/oauth-browser-client';
2import type { Session } from '@atcute/oauth-browser-client';
3import { getHandleFromDid } from './atproto.js';
4
5export interface AuthState {
6 agent: OAuthUserAgent | null;
7 did: string | null;
8 handle: string | null;
9 pds: string | null;
10 loading: boolean;
11 error: string | null;
12}
13
14function createAuth() {
15 let state = $state<AuthState>({
16 agent: null,
17 did: null,
18 handle: null,
19 pds: null,
20 loading: false,
21 error: null
22 });
23
24 return {
25 get agent() { return state.agent; },
26 get did() { return state.did; },
27 get handle() { return state.handle; },
28 get pds() { return state.pds; },
29 get loading() { return state.loading; },
30 get error() { return state.error; },
31 get isLoggedIn() { return state.agent !== null; },
32
33 async tryRestoreSession() {
34 state.loading = true;
35 state.error = null;
36 try {
37 const sessions = listStoredSessions();
38 if (sessions.length > 0) {
39 const did = sessions[0];
40 const session = await getSession(did, { allowStale: true });
41 const agent = new OAuthUserAgent(session);
42 state.agent = agent;
43 state.did = session.info.sub;
44 state.pds = session.info.aud;
45 // Resolve handle in the background — don't block session restore
46 getHandleFromDid(session.info.sub).then((h) => {
47 if (h) state.handle = h;
48 }).catch(() => {});
49 }
50 } catch (_) {
51 state.agent = null;
52 state.did = null;
53 state.handle = null;
54 state.pds = null;
55 } finally {
56 state.loading = false;
57 }
58 },
59
60 setFromSession(session: Session) {
61 const agent = new OAuthUserAgent(session);
62 state.agent = agent;
63 state.did = session.info.sub;
64 state.pds = session.info.aud;
65 },
66
67 setHandle(handle: string) {
68 state.handle = handle;
69 },
70
71 async signOut() {
72 if (state.agent) {
73 try {
74 await state.agent.signOut();
75 } catch (_) {}
76 }
77 if (state.did) {
78 try {
79 deleteStoredSession(state.did as `did:${string}:${string}`);
80 } catch (_) {}
81 }
82 state.agent = null;
83 state.did = null;
84 state.handle = null;
85 state.pds = null;
86 }
87 };
88}
89
90export const auth = createAuth();