A decentralized music tracking and discovery platform built on AT Protocol 馃幍
rocksky.app
spotify
atproto
lastfm
musicbrainz
scrobbling
listenbrainz
1import { Agent, AtpAgent } from "@atproto/api";
2import type { NodeOAuthClient } from "@atproto/oauth-client-node";
3import { consola } from "consola";
4import extractPdsFromDid from "./extractPdsFromDid";
5import { ctx } from "context";
6
7export async function createAgent(
8 oauthClient: NodeOAuthClient,
9 did: string,
10): Promise<Agent | null> {
11 let agent: Agent | null = null;
12 let retry = 0;
13 do {
14 try {
15 const result = await ctx.sqliteDb
16 .selectFrom("auth_session")
17 .selectAll()
18 .where("key", "=", `atp:${did}`)
19 .executeTakeFirst();
20 if (result) {
21 let pds = await ctx.redis.get(`pds:${did}`);
22 if (!pds) {
23 pds = await extractPdsFromDid(did);
24 await ctx.redis.setEx(`pds:${did}`, 60 * 15, pds);
25 }
26 const atpAgent = new AtpAgent({
27 service: new URL(pds),
28 });
29
30 try {
31 await atpAgent.resumeSession(JSON.parse(result.session));
32 } catch (e) {
33 consola.info("Error resuming session");
34 consola.info(did);
35 consola.info(e);
36 await ctx.sqliteDb
37 .deleteFrom("auth_session")
38 .where("key", "=", `atp:${did}`)
39 .execute();
40 }
41
42 return atpAgent;
43 }
44 const oauthSession = await oauthClient.restore(did);
45 agent = oauthSession ? new Agent(oauthSession) : null;
46 if (agent === null) {
47 await new Promise((r) => setTimeout(r, 1000));
48 retry += 1;
49 }
50 } catch (e) {
51 consola.info("Error creating agent");
52 consola.info(did);
53 consola.info(e);
54 await new Promise((r) => setTimeout(r, 1000));
55 retry += 1;
56 }
57 } while (agent === null && retry < 5);
58
59 return agent;
60}