@dwn-protocol/id-sdk
Version:
SDK for accessing the features and capabilities
107 lines (95 loc) • 3.48 kB
text/typescript
import type {
DidResolverCache,
DidMethodResolver,
DidResolutionResult,
DidResolutionOptions,
} from './types.js';
import { parseDid } from './utils.js';
import { DidResolverCacheNoop } from './resolver-cache-noop.js';
export type DidResolverOptions = {
didResolvers: DidMethodResolver[];
cache?: DidResolverCache;
}
/**
* The `DidResolver` class is responsible for resolving DIDs to DID documents.
* It uses method resolvers to resolve DIDs of different methods and a cache
* to store resolved DID documents.
*/
export class DidResolver {
/**
* A cache for storing resolved DID documents.
*/
private cache: DidResolverCache;
/**
* A map to store method resolvers against method names.
*/
private didResolvers: Map<string, DidMethodResolver> = new Map();
/**
* Constructs a new `DidResolver`.
*
* @param options - The options for constructing the `DidResolver`.
* @param options.didResolvers - An array of `DidMethodResolver` instances.
* @param options.cache - Optional. A cache for storing resolved DID documents. If not provided, a no-operation cache is used.
*/
constructor(options: DidResolverOptions) {
this.cache = options.cache || DidResolverCacheNoop;
for (const resolver of options.didResolvers) {
this.didResolvers.set(resolver.methodName, resolver);
}
}
/**
* Resolves a DID to a DID Resolution Result.
* If the DID Resolution Result is present in the cache, it returns the cached
* result. Otherwise, it uses the appropriate method resolver to resolve
* the DID, stores the resolution result in the cache, and returns the
* resolultion result.
*
* Note: The method signature for resolve() in this implementation must match
* the `DidResolver` implementation in
* {@link https://github.com/@dwn-protocol/id | @dwn-protocol/id} so that
* IDDwn apps and the underlying DWN instance can share the same DID
* resolution cache.
*
* @param didUrl - The DID or DID URL to resolve.
* @returns A promise that resolves to the DID Resolution Result.
*/
async resolve(didUrl: string, resolutionOptions?: DidResolutionOptions): Promise<DidResolutionResult> {
const parsedDid = parseDid({ didUrl });
if (!parsedDid) {
return {
'@context' : 'https://w3id.org/did-resolution/v1',
didDocument : undefined,
didDocumentMetadata : {},
didResolutionMetadata : {
contentType : 'application/did+json',
error : 'invalidDid',
errorMessage : `Cannot parse DID: ${didUrl}`
}
};
}
const resolver = this.didResolvers.get(parsedDid.method);
if (!resolver) {
return {
'@context' : 'https://w3id.org/did-resolution/v1',
didDocument : undefined,
didDocumentMetadata : {},
didResolutionMetadata : {
contentType : 'application/did+json',
error : 'methodNotSupported',
errorMessage : `Method not supported: ${parsedDid.method}`
}
};
}
const cachedResolutionResult = await this.cache.get(parsedDid.did);
if (cachedResolutionResult) {
return cachedResolutionResult;
} else {
const resolutionResult = await resolver.resolve({
didUrl: parsedDid.did,
resolutionOptions
});
await this.cache.set(parsedDid.did, resolutionResult);
return resolutionResult;
}
}
}