Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 38 additions & 16 deletions packages/frontpage/lib/data/atproto/did.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { cache } from "react";
import { z } from "zod";
import { PlcDidDocumentResolver } from "@atcute/identity-resolver";
import type { DidDocument } from "@atcute/identity";
import {
CompositeDidDocumentResolver,
PlcDidDocumentResolver,
WebDidDocumentResolver,
} from "@atcute/identity-resolver";
import { type DidDocument, isAtprotoDid } from "@atcute/identity";
import { FRONTPAGE_APPVIEW_USER_AGENT } from "@/lib/constants";

type Brand<K, T> = K & { __brand: T };
export type DID = Brand<`did:plc:${string}`, "DID">;
export type DID = Brand<`did:${"plc" | "web"}:${string}`, "DID">;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have the template literal type the brand has less value, but it's still nice to have because it's much easier to trace where exactly DID values are being created. Compared to just the template literal where any line of code can just do

`did:web:example.com` as const

And that is now a value assignable to something that accepts a DID.


export function isDid(s: string): s is DID {
// We don't support did:web yet
return s.startsWith("did:plc:");
return isAtprotoDid(s);
}
Comment thread
tom-sherman marked this conversation as resolved.

export const didSchema = z.string().refine((s) => isDid(s), {
Expand All @@ -23,19 +26,38 @@ export function parseDid(s: string): DID | null {
return s;
}

const didResolver = new PlcDidDocumentResolver({
apiUrl: process.env.PLC_DIRECTORY_URL ?? "https://plc.directory",
fetch: (request) =>
fetch(request, {
headers: {
"User-Agent": FRONTPAGE_APPVIEW_USER_AGENT,
},
next: {
// TODO: Also revalidate this when we receive an identity change event
// That would allow us to extend the revalidation time to 1 day
revalidate: 60 * 60, // 1 hour
const didResolver = new CompositeDidDocumentResolver({
methods: {
plc: new PlcDidDocumentResolver({
apiUrl: process.env.PLC_DIRECTORY_URL ?? "https://plc.directory",
fetch: (request) =>
fetch(request, {
headers: {
"User-Agent": FRONTPAGE_APPVIEW_USER_AGENT,
},
next: {
// TODO: Also revalidate this when we receive an identity change event
// That would allow us to extend the revalidation time to 1 day
revalidate: 60 * 60, // 1 hour
},
}),
}),

web: new WebDidDocumentResolver({
fetch: (request) => {
const signal = AbortSignal.timeout(1500);
Comment thread
tom-sherman marked this conversation as resolved.
return fetch(request, {
headers: {
"User-Agent": FRONTPAGE_APPVIEW_USER_AGENT,
},
signal,
next: {
revalidate: 60 * 60, // 1 hour
},
});
},
}),
},
});

export const getDidDoc = cache(async (did: DID): Promise<DidDocument> => {
Expand Down
Loading