{"version":3,"file":"DidsApi.mjs","names":[],"sources":["../../../src/modules/dids/DidsApi.ts"],"sourcesContent":["import { parseDid } from '@sphereon/ssi-types'\nimport { AgentContext } from '../../agent'\nimport { CredoError, RecordNotFoundError } from '../../error'\nimport { injectable } from '../../plugins'\nimport { KeyManagementApi } from '../kms'\nimport type { ImportDidOptions } from './DidsApiOptions'\nimport { DidsModuleConfig } from './DidsModuleConfig'\nimport { type DidPurpose, getPublicJwkFromVerificationMethod } from './domain'\nimport { getAlternativeDidsForPeerDid, isValidPeerDid } from './methods'\nimport { DidRecord, DidRepository } from './repository'\nimport { DidRegistrarService, DidResolverService } from './services'\nimport type {\n  DidCreateOptions,\n  DidCreateResult,\n  DidDeactivateOptions,\n  DidDeactivateResult,\n  DidResolutionOptions,\n  DidUpdateOptions,\n  DidUpdateResult,\n} from './types'\n\n@injectable()\nexport class DidsApi {\n  public config: DidsModuleConfig\n\n  private didResolverService: DidResolverService\n  private didRegistrarService: DidRegistrarService\n  private didRepository: DidRepository\n  private agentContext: AgentContext\n\n  public constructor(\n    didResolverService: DidResolverService,\n    didRegistrarService: DidRegistrarService,\n    didRepository: DidRepository,\n    agentContext: AgentContext,\n    config: DidsModuleConfig,\n    _keyManagement: KeyManagementApi\n  ) {\n    this.didResolverService = didResolverService\n    this.didRegistrarService = didRegistrarService\n    this.didRepository = didRepository\n    this.agentContext = agentContext\n    this.config = config\n  }\n\n  /**\n   * Resolve a did to a did document.\n   *\n   * Follows the interface as defined in https://w3c-ccg.github.io/did-resolution/\n   */\n  public resolve(didUrl: string, options?: DidResolutionOptions) {\n    return this.didResolverService.resolve(this.agentContext, didUrl, options)\n  }\n\n  /**\n   * Create, register and store a did and did document.\n   *\n   * Follows the interface as defined in https://identity.foundation/did-registration\n   */\n  public create<CreateOptions extends DidCreateOptions = DidCreateOptions>(\n    options: CreateOptions\n  ): Promise<DidCreateResult> {\n    return this.didRegistrarService.create<CreateOptions>(this.agentContext, options)\n  }\n\n  /**\n   * Update an existing did document.\n   *\n   * Follows the interface as defined in https://identity.foundation/did-registration\n   */\n  public update<UpdateOptions extends DidUpdateOptions = DidUpdateOptions>(\n    options: UpdateOptions\n  ): Promise<DidUpdateResult> {\n    return this.didRegistrarService.update(this.agentContext, options)\n  }\n\n  /**\n   * Deactivate an existing did.\n   *\n   * Follows the interface as defined in https://identity.foundation/did-registration\n   */\n  public deactivate<DeactivateOptions extends DidDeactivateOptions = DidDeactivateOptions>(\n    options: DeactivateOptions\n  ): Promise<DidDeactivateResult> {\n    return this.didRegistrarService.deactivate(this.agentContext, options)\n  }\n\n  /**\n   * Resolve a did to a did document. This won't return the associated metadata as defined\n   * in the did resolution specification, and will throw an error if the did document could not\n   * be resolved.\n   */\n  public resolveDidDocument(didUrl: string) {\n    return this.didResolverService.resolveDidDocument(this.agentContext, didUrl)\n  }\n\n  /**\n   * Get a list of all dids created by the agent. This will return a list of {@link DidRecord} objects.\n   * Each document will have an id property with the value of the did. Optionally, it will contain a did document,\n   * but this is only for documents that can't be resolved from the did itself or remotely.\n   *\n   * You can call `${@link DidsModule.resolve} to resolve the did document based on the did itself.\n   */\n  public getCreatedDids({ method, did }: { method?: string; did?: string } = {}) {\n    return this.didRepository.getCreatedDids(this.agentContext, { method, did })\n  }\n\n  /**\n   * Import an existing did that was created outside of the DidsApi. This will create a `DidRecord` for the did\n   * and will allow the did to be used in other parts of the agent. If you need to create a new did document,\n   * you can use the {@link DidsApi.create} method to create and register the did.\n   *\n   * If no `didDocument` is provided, the did document will be resolved using the did resolver. You can optionally provide a list\n   * of private key buffer with the respective private key bytes. These keys will be stored in the wallet, and allows you to use the\n   * did for other operations. Providing keys that already exist in the wallet is allowed, and those keys will be skipped from being\n   * added to the wallet.\n   *\n   * By default, this method will throw an error if the did already exists in the wallet. You can override this behavior by setting\n   * the `overwrite` option to `true`. This will update the did document in the record, and allows you to update the did over time.\n   */\n  public async import({ did, didDocument, keys = [], overwrite }: ImportDidOptions) {\n    if (didDocument && didDocument.id !== did) {\n      throw new CredoError(`Did document id ${didDocument.id} does not match did ${did}`)\n    }\n\n    const existingDidRecord = await this.didRepository.findCreatedDid(this.agentContext, did)\n    if (existingDidRecord && !overwrite) {\n      throw new CredoError(\n        `A created did ${did} already exists. If you want to override the existing did, set the 'overwrite' option to update the did.`\n      )\n    }\n\n    if (!didDocument) {\n      didDocument = await this.resolveDidDocument(did)\n    }\n\n    for (const key of keys) {\n      // Make sure the keys exists in the did document\n      didDocument.dereferenceKey(key.didDocumentRelativeKeyId)\n    }\n\n    // Update existing did record\n    if (existingDidRecord) {\n      existingDidRecord.didDocument = didDocument\n      existingDidRecord.keys = keys\n      existingDidRecord.setTags({\n        alternativeDids: isValidPeerDid(didDocument.id) ? getAlternativeDidsForPeerDid(did) : undefined,\n      })\n\n      await this.didRepository.update(this.agentContext, existingDidRecord)\n      return\n    }\n\n    // Create new did record\n    await this.didRepository.storeCreatedDid(this.agentContext, {\n      did,\n      didDocument,\n      keys,\n      tags: {\n        alternativeDids: isValidPeerDid(didDocument.id) ? getAlternativeDidsForPeerDid(did) : undefined,\n      },\n    })\n  }\n\n  public async resolveCreatedDidDocumentWithKeys(did: string) {\n    const [didRecord] = await this.didRepository.getCreatedDids(this.agentContext, { did })\n\n    if (!didRecord) {\n      throw new RecordNotFoundError(`Created did '${did}' not found`, { recordType: DidRecord.type })\n    }\n\n    if (didRecord.didDocument) {\n      return {\n        keys: didRecord.keys,\n        didDocument: didRecord.didDocument,\n      }\n    }\n\n    // TODO: we should somehow store the did document on the record if the did method allows it\n    // E.g. for did:key we don't want to store it, but if we still have a did:indy record we do want to store it\n    // If the did document is not stored on the did record, we resolve it\n    const didDocument = await this.didResolverService.resolveDidDocument(this.agentContext, didRecord.did)\n\n    return {\n      keys: didRecord.keys,\n      didDocument,\n    }\n  }\n\n  public async resolveVerificationMethodFromCreatedDidRecord(\n    didUrl: string,\n    allowedPurposes?: Array<DidPurpose | 'verificationMethod'>\n  ) {\n    const parsedDid = parseDid(didUrl)\n    const { didDocument, keys } = await this.resolveCreatedDidDocumentWithKeys(parsedDid.did)\n\n    const verificationMethod = didDocument.dereferenceKey(didUrl, allowedPurposes)\n    const publicJwk = getPublicJwkFromVerificationMethod(verificationMethod)\n    publicJwk.keyId =\n      keys?.find(({ didDocumentRelativeKeyId }) => verificationMethod.id.endsWith(didDocumentRelativeKeyId))\n        ?.kmsKeyId ?? publicJwk.legacyKeyId\n\n    return {\n      verificationMethod,\n      publicJwk,\n    }\n  }\n\n  public get supportedResolverMethods() {\n    return this.didResolverService.supportedMethods\n  }\n\n  public get supportedRegistrarMethods() {\n    return this.didRegistrarService.supportedMethods\n  }\n}\n"],"mappings":"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"}