···11+/*
22+ * clippr: a social bookmarking service for the AT Protocol
33+ * Copyright (c) 2025 clippr contributors.
44+ * SPDX-License-Identifier: AGPL-3.0-only
55+ */
66+77+import {
88+ CompositeDidDocumentResolver,
99+ DocumentNotFoundError,
1010+ FailedDocumentResolutionError,
1111+ HandleResolutionError,
1212+ ImproperDidError,
1313+ PlcDidDocumentResolver,
1414+ UnsupportedDidMethodError,
1515+ WebDidDocumentResolver,
1616+} from "@atcute/identity-resolver";
1717+1818+// Gets a DID document from a given DID. DID method agnostic.
1919+export async function getDidDocument(
2020+ did: `did:plc:${string}` | `did:web:${string}`,
2121+) {
2222+ const docResolver = new CompositeDidDocumentResolver({
2323+ methods: {
2424+ plc: new PlcDidDocumentResolver(),
2525+ web: new WebDidDocumentResolver(),
2626+ },
2727+ });
2828+2929+ let doc;
3030+ try {
3131+ doc = await docResolver.resolve(did);
3232+ } catch (err) {
3333+ if (err instanceof DocumentNotFoundError) {
3434+ throw new Error("Document not found");
3535+ }
3636+ if (err instanceof UnsupportedDidMethodError) {
3737+ throw new Error("Unsupported DID method");
3838+ }
3939+ if (err instanceof ImproperDidError) {
4040+ throw new Error("Invalid DID");
4141+ }
4242+ if (err instanceof FailedDocumentResolutionError) {
4343+ throw new Error("Failed document resolution");
4444+ }
4545+ if (err instanceof HandleResolutionError) {
4646+ throw new Error("Unknown resolution error");
4747+ }
4848+ }
4949+5050+ return doc;
5151+}
+5-38
backend/src/network/converters.ts
···44 * SPDX-License-Identifier: AGPL-3.0-only
55 */
6677-import {
88- CompositeDidDocumentResolver,
99- DocumentNotFoundError,
1010- FailedDocumentResolutionError,
1111- HandleResolutionError,
1212- ImproperDidError,
1313- PlcDidDocumentResolver,
1414- UnsupportedDidMethodError,
1515- WebDidDocumentResolver,
1616-} from "@atcute/identity-resolver";
177import { Client, simpleFetchHandler } from "@atcute/client";
88+import { getDidDocument } from "../api/did.js";
1891910/// Converts an ``At.DID`` type to a proper string, for type reasons.
2011export function convertDidToString(did: `did:${string}`): string {
···3122 }
3223}
33243434-// Get a user's handle from their DID. DID method agnostic.
2525+// Get a user's handle from their DID.
2626+//
2727+// WARNING: Handle validation is not performed and is taken from the document as-is. Fix me!
3528export async function getHandleFromDid(did: string): Promise<string> {
3636- const docResolver = new CompositeDidDocumentResolver({
3737- methods: {
3838- plc: new PlcDidDocumentResolver(),
3939- web: new WebDidDocumentResolver(),
4040- },
4141- });
4242-4343- let doc;
4444- try {
4545- doc = await docResolver.resolve(convertStringToTypedDid(did));
4646- } catch (err) {
4747- if (err instanceof DocumentNotFoundError) {
4848- throw new Error("Document not found");
4949- }
5050- if (err instanceof UnsupportedDidMethodError) {
5151- throw new Error("Unsupported did method");
5252- }
5353- if (err instanceof ImproperDidError) {
5454- throw new Error("Improper did");
5555- }
5656- if (err instanceof FailedDocumentResolutionError) {
5757- throw new Error("Failed document resolution");
5858- }
5959- if (err instanceof HandleResolutionError) {
6060- throw new Error("Generic handle resolution error");
6161- }
6262- }
2929+ const doc = await getDidDocument(convertStringToTypedDid(did));
63306431 if (!doc?.alsoKnownAs) {
6532 throw new Error("No handles found");