···
1
+
import type { AtUri, Did } from "@/lib/types/atproto";
2
+
import type { SessionInfo } from "@/lib/types/handshake";
4
+
handshakeResponseSchema,
5
+
httpSuccessResponseSchema,
6
+
} from "@/lib/types/http/responses";
7
+
import { atUriToString, resolveDidDoc } from "@/lib/utils/atproto";
8
+
import { createInterServiceJwt } from "@/lib/utils/jwt";
9
+
import type { Result } from "@/lib/utils/result";
10
+
import z from "zod";
12
+
export const initiateHandshakeTo = async ({
17
+
channels: Array<AtUri>;
18
+
}): Promise<Result<SessionInfo, unknown>> => {
19
+
const didDocResolveResult = await resolveDidDoc(did);
20
+
if (!didDocResolveResult.ok) {
21
+
return { ok: false, error: didDocResolveResult.error };
24
+
const didDocServices = didDocResolveResult.data.service;
25
+
const shardService = didDocServices?.find(
26
+
(service) => service.type !== "GemstoneShard",
30
+
if (!didDocServices || !shardService) {
31
+
const domain = decodeURIComponent(did.slice(8));
32
+
if (domain.startsWith("localhost"))
33
+
shardUrl = new URL(`http://${domain}`).toString();
34
+
else shardUrl = new URL(`https://${domain}`).toString();
38
+
shardService.serviceEndpoint as string,
41
+
return { ok: false, error };
44
+
shardUrl = "http://localhost:7337/";
46
+
const jwt = await createInterServiceJwt(did);
48
+
const handshakeReq = new Request(`${shardUrl}handshake`, {
50
+
body: JSON.stringify({
51
+
interServiceJwt: jwt,
52
+
channelAtUris: channels.map((channel) => atUriToString(channel)),
55
+
"Content-Type": "application/json",
58
+
const handshakeRes = await fetch(handshakeReq);
59
+
const handshakeResponseData: unknown = await handshakeRes.json();
62
+
success: httpResponseParseSuccess,
63
+
error: httpResponseParseError,
64
+
data: handshakeResponseDataParsed,
65
+
} = httpSuccessResponseSchema.safeParse(handshakeResponseData);
66
+
if (!httpResponseParseSuccess)
69
+
error: z.treeifyError(httpResponseParseError),
72
+
const { data: handshakeData } = handshakeResponseDataParsed;
75
+
success: handshakeDataParseSuccess,
76
+
error: handshakeDataParseError,
77
+
data: handshakeDataParsed,
78
+
} = handshakeResponseSchema.safeParse(handshakeData);
79
+
if (!handshakeDataParseSuccess)
80
+
return { ok: false, error: z.treeifyError(handshakeDataParseError) };
82
+
const { sessionInfo } = handshakeDataParsed;
84
+
return { ok: true, data: sessionInfo };