A social knowledge tool for researchers built on ATProto
1import { Result, ok, err } from 'src/shared/core/Result';
2import { IIdentityResolutionService } from 'src/modules/atproto/domain/services/IIdentityResolutionService';
3import { DID } from 'src/modules/atproto/domain/DID';
4import { DIDOrHandle } from 'src/modules/atproto/domain/DIDOrHandle';
5import { Handle } from 'src/modules/atproto/domain/Handle';
6
7export class FakeIdentityResolutionService
8 implements IIdentityResolutionService
9{
10 private handleToDIDMap: Map<string, string> = new Map();
11 private didToHandleMap: Map<string, string> = new Map();
12 private shouldFail = false;
13
14 async resolveToDID(identifier: DIDOrHandle): Promise<Result<DID>> {
15 if (this.shouldFail) {
16 return err(new Error('Identity resolution service failed'));
17 }
18
19 try {
20 // If it's already a DID, return it directly
21 if (identifier.isDID) {
22 const did = identifier.getDID();
23 if (!did) {
24 return err(new Error('Invalid DID in identifier'));
25 }
26 return ok(did);
27 }
28
29 // If it's a handle, resolve it to a DID
30 const handle = identifier.getHandle();
31 if (!handle) {
32 return err(new Error('Invalid handle in identifier'));
33 }
34
35 // Check if we have a mapping for this handle
36 const mappedDID = this.handleToDIDMap.get(handle.value);
37 if (!mappedDID) {
38 return err(new Error(`Handle not found: ${handle.value}`));
39 }
40
41 // Create and return the DID
42 const didResult = DID.create(mappedDID);
43 if (didResult.isErr()) {
44 return err(
45 new Error(`Invalid DID in mapping: ${didResult.error.message}`),
46 );
47 }
48
49 return ok(didResult.value);
50 } catch (error) {
51 return err(
52 new Error(
53 `Error resolving identifier to DID: ${error instanceof Error ? error.message : String(error)}`,
54 ),
55 );
56 }
57 }
58
59 async resolveToHandle(identifier: DIDOrHandle): Promise<Result<Handle>> {
60 if (this.shouldFail) {
61 return err(new Error('Identity resolution service failed'));
62 }
63
64 try {
65 // If it's already a handle, return it directly
66 if (identifier.isHandle) {
67 const handle = identifier.getHandle();
68 if (!handle) {
69 return err(new Error('Invalid handle in identifier'));
70 }
71 return ok(handle);
72 }
73
74 // If it's a DID, resolve it to a handle
75 const did = identifier.getDID();
76 if (!did) {
77 return err(new Error('Invalid DID in identifier'));
78 }
79
80 // Check if we have a mapping for this DID
81 const mappedHandle = this.didToHandleMap.get(did.value);
82 if (!mappedHandle) {
83 return err(new Error(`DID not found: ${did.value}`));
84 }
85
86 // Create and return the Handle
87 const handleResult = Handle.create(mappedHandle);
88 if (handleResult.isErr()) {
89 return err(
90 new Error(`Invalid handle in mapping: ${handleResult.error.message}`),
91 );
92 }
93
94 return ok(handleResult.value);
95 } catch (error) {
96 return err(
97 new Error(
98 `Error resolving identifier to handle: ${error instanceof Error ? error.message : String(error)}`,
99 ),
100 );
101 }
102 }
103
104 // Test helper methods
105 addHandleMapping(handle: string, did: string): void {
106 this.handleToDIDMap.set(handle, did);
107 this.didToHandleMap.set(did, handle);
108 }
109
110 setShouldFail(shouldFail: boolean): void {
111 this.shouldFail = shouldFail;
112 }
113
114 clear(): void {
115 this.handleToDIDMap.clear();
116 this.didToHandleMap.clear();
117 this.shouldFail = false;
118 }
119}