{"version":3,"file":"DcqlService.mjs","names":["getDcqlVcPresentationsToCreate"],"sources":["../../../src/modules/dcql/DcqlService.ts"],"sourcesContent":["import {\n  DcqlCredential,\n  DcqlCredentialQuery,\n  DcqlMdocCredential,\n  DcqlPresentationResult,\n  DcqlQuery,\n  DcqlSdJwtVcCredential,\n  DcqlW3cVcCredential,\n} from 'dcql'\nimport type { AgentContext } from '../../agent'\nimport { injectable } from '../../plugins'\nimport { isNonEmptyArray, type JsonObject, type JsonValue, mapNonEmptyArray } from '../../types'\nimport { asArray, TypedArrayEncoder } from '../../utils'\nimport {\n  CredentialMultiInstanceUseMode,\n  canUseInstanceFromCredentialRecord,\n  useInstanceFromCredentialRecord,\n} from '../../utils/credentialUse'\nimport { DidsApi, getPublicJwkFromVerificationMethod, VerificationMethod } from '../dids'\nimport type { VerifiableCredential, VerifiablePresentation } from '../dif-presentation-exchange/index'\nimport {\n  Mdoc,\n  MdocApi,\n  MdocDeviceResponse,\n  type MdocNameSpaces,\n  MdocRecord,\n  type MdocSessionTranscriptOptions,\n} from '../mdoc'\nimport { SdJwtVcApi, SdJwtVcRecord, SdJwtVcService } from '../sd-jwt-vc'\nimport { buildDisclosureFrameForPayload } from '../sd-jwt-vc/disclosureFrame'\nimport {\n  ClaimFormat,\n  SignatureSuiteRegistry,\n  W3cCredentialRecord,\n  W3cCredentialRepository,\n  W3cCredentialService,\n  W3cJsonLdCredentialService,\n  W3cJsonLdVerifiableCredential,\n  W3cPresentation,\n  W3cV2CredentialRecord,\n  W3cV2CredentialRepository,\n  W3cV2CredentialService,\n  W3cV2EnvelopedVerifiableCredential,\n  W3cV2Presentation,\n} from '../vc'\nimport { purposes } from '../vc/data-integrity/libraries/jsonld-signatures'\nimport { W3cV2SdJwtCredentialService, W3cV2SdJwtVerifiableCredential } from '../vc/sd-jwt-vc'\nimport { X509Certificate } from '../x509'\nimport { DcqlError } from './DcqlError'\nimport type {\n  DcqlCredentialsForRequest,\n  DcqlEncodedPresentations,\n  DcqlFailedCredential,\n  DcqlPresentation,\n  DcqlQueryResult,\n  DcqlValidCredential,\n} from './models'\nimport { dcqlGetPresentationsToCreate as getDcqlVcPresentationsToCreate } from './utils'\n\nexport interface DcqlSelectCredentialsForRequestOptions {\n  /**\n   * The usage mode to apply to the credentials when selecting credentials.\n   *\n   * If and usage mode is selected that require a new instance to be used, and there's no\n   * new instances available, an error will be thrown.\n   *\n   * It does not actually select the credential from the record yet, it just filters\n   *  out records that don't match the filter.\n   */\n  useMode?: CredentialMultiInstanceUseMode\n}\n\n@injectable()\nexport class DcqlService {\n  /**\n   * Queries the wallet for credentials that match the given dcql query. This only does an initial query based on the\n   * schema of the input descriptors. It does not do any further filtering based on the constraints in the input descriptors.\n   */\n  private async queryCredentialsForDcqlQuery(\n    agentContext: AgentContext,\n    dcqlQuery: DcqlQuery\n  ): Promise<Array<SdJwtVcRecord | W3cCredentialRecord | W3cV2CredentialRecord | MdocRecord>> {\n    const formats = new Set(dcqlQuery.credentials.map((c) => c.format))\n    const allRecords: Array<SdJwtVcRecord | W3cCredentialRecord | W3cV2CredentialRecord | MdocRecord> = []\n\n    const mdocDoctypes = dcqlQuery.credentials\n      .filter((credentialQuery) => credentialQuery.format === 'mso_mdoc')\n      .map((c) => c.meta?.doctype_value)\n\n    const mdocApi = this.getMdocApi(agentContext)\n    if (mdocDoctypes.every((doctype) => doctype !== undefined)) {\n      const mdocRecords = await mdocApi.findAllByQuery({\n        $or: mdocDoctypes.map((docType) => ({\n          docType: docType,\n        })),\n      })\n      allRecords.push(...mdocRecords)\n    } else if (formats.has('mso_mdoc')) {\n      const mdocRecords = await mdocApi.getAll()\n      allRecords.push(...mdocRecords)\n    }\n\n    const sdJwts = dcqlQuery.credentials.filter(\n      (credentialQuery): credentialQuery is DcqlCredentialQuery.SdJwtVc =>\n        (credentialQuery.format === 'vc+sd-jwt' && !(credentialQuery.meta && 'type_values' in credentialQuery.meta)) ||\n        credentialQuery.format === 'dc+sd-jwt'\n    )\n\n    const sdJwtVctValues = sdJwts.flatMap((c) => c.meta?.vct_values)\n\n    const sdJwtVcApi = this.getSdJwtVcApi(agentContext)\n    if (sdJwtVctValues.every((vct) => vct !== undefined)) {\n      const sdjwtVcRecords = await sdJwtVcApi.findAllByQuery({\n        $or: [\n          // Look for direct vct match\n          ...sdJwtVctValues.map((vct) => ({\n            vct,\n          })),\n          // Or an extended vct value\n          ...sdJwtVctValues.map((vct) => ({\n            extendedVctValues: [vct],\n          })),\n        ],\n      })\n      allRecords.push(...sdjwtVcRecords)\n    } else if (sdJwts.length > 0) {\n      const sdJwtVcRecords = await sdJwtVcApi.getAll()\n      allRecords.push(...sdJwtVcRecords)\n    }\n\n    const w3cCredentialRepository = agentContext.dependencyManager.resolve(W3cCredentialRepository)\n    if (formats.has('jwt_vc_json')) {\n      const w3cRecords = await w3cCredentialRepository.findByQuery(agentContext, {\n        claimFormat: ClaimFormat.JwtVc,\n\n        // For jwt_vc_json we query the non-expanded types\n        $or: dcqlQuery.credentials\n          .flatMap((c) => (c.format === 'jwt_vc_json' ? c.meta.type_values : []))\n          .map((typeValues) => ({\n            types: typeValues,\n          })),\n      })\n      allRecords.push(...w3cRecords)\n    }\n\n    if (formats.has('ldp_vc')) {\n      const w3cRecords = await w3cCredentialRepository.findByQuery(agentContext, {\n        claimFormat: ClaimFormat.LdpVc,\n\n        // For LDP_VC we query the expanded types\n        $or: dcqlQuery.credentials\n          .flatMap((c) => (c.format === 'jwt_vc_json' ? c.meta.type_values : []))\n          .map((typeValues) => ({\n            expandedTypes: typeValues,\n          })),\n      })\n      allRecords.push(...w3cRecords)\n    }\n\n    const w3cSdJwts = dcqlQuery.credentials.filter(\n      (credentialQuery): credentialQuery is DcqlCredentialQuery.W3cVc & { format: 'vc+sd-jwt' } =>\n        credentialQuery.format === 'vc+sd-jwt' && !!credentialQuery.meta && 'type_values' in credentialQuery.meta\n    )\n\n    if (w3cSdJwts.length > 0) {\n      const w3cV2CredentialRepository = agentContext.dependencyManager.resolve(W3cV2CredentialRepository)\n\n      const w3cV2Records = await w3cV2CredentialRepository.findByQuery(agentContext, {\n        claimFormat: ClaimFormat.SdJwtW3cVc,\n        $or: dcqlQuery.credentials\n          .flatMap((c) => (c.format === 'vc+sd-jwt' && c.meta && 'type_values' in c.meta ? c.meta.type_values : []))\n          .map((typeValues) => ({\n            types: typeValues,\n          })),\n      })\n\n      allRecords.push(...w3cV2Records)\n    }\n\n    return allRecords\n  }\n\n  private getAuthorityForCredential(\n    credential: VerifiableCredential | W3cV2EnvelopedVerifiableCredential\n  ): DcqlCredential['authority'] {\n    if (credential.claimFormat === ClaimFormat.SdJwtDc) {\n      const akiValues = (credential.header.x5c as string[] | undefined)\n        ?.map((c) => {\n          const akiHex = X509Certificate.fromEncodedCertificate(c).authorityKeyIdentifier\n          return akiHex ? TypedArrayEncoder.toBase64Url(TypedArrayEncoder.fromHex(akiHex)) : undefined\n        })\n        .filter((aki) => aki !== undefined)\n\n      return akiValues && isNonEmptyArray(akiValues)\n        ? ({\n            type: 'aki',\n            values: akiValues,\n          } as const)\n        : undefined\n    }\n\n    if (credential.claimFormat === ClaimFormat.MsoMdoc) {\n      const akiValues = credential.issuerSignedCertificateChain\n        .map((c) => {\n          const akiHex = X509Certificate.fromRawCertificate(c).authorityKeyIdentifier\n          return akiHex ? TypedArrayEncoder.toBase64Url(TypedArrayEncoder.fromHex(akiHex)) : undefined\n        })\n        .filter((aki) => aki !== undefined)\n\n      return akiValues && isNonEmptyArray(akiValues)\n        ? ({\n            type: 'aki',\n            values: akiValues,\n          } as const)\n        : undefined\n    }\n\n    return undefined\n  }\n\n  public async getDcqlCredentialRepresentation(\n    agentContext: AgentContext,\n    presentation: VerifiablePresentation,\n    queryCredential: DcqlQuery['credentials'][number]\n  ): Promise<DcqlCredential> {\n    // SD-JWT credential can be used as both dc+sd-jwt and vc+sd-jwt\n    // At some point we might want to look at the header value of the sd-jwt (vc+sd-jwt vc dc+sd-jwt)\n    if (presentation.claimFormat === ClaimFormat.SdJwtDc) {\n      const requestedVcts = queryCredential.format === 'dc+sd-jwt' ? queryCredential.meta?.vct_values : undefined\n\n      let presentationVctValues = [presentation.payload.vct]\n      // FIXME: we should probably add an option whether to resolve VCT if we didn't get a direct hit\n      if (!requestedVcts?.includes(presentation.payload.vct)) {\n        const typeMetadataChain = await agentContext\n          .resolve(SdJwtVcService)\n          .fetchTypeMetadata(agentContext, presentation, {\n            throwErrorOnFetchError: false,\n            throwErrorOnUnsupportedVctValue: false,\n          })\n\n        if (typeMetadataChain) {\n          presentationVctValues = typeMetadataChain?.vctValues\n        }\n      }\n\n      return {\n        credential_format: queryCredential.format === 'dc+sd-jwt' ? 'dc+sd-jwt' : 'vc+sd-jwt',\n        authority: this.getAuthorityForCredential(presentation),\n        cryptographic_holder_binding: true,\n        vct:\n          presentationVctValues.find((presentationVctValue) => requestedVcts?.includes(presentationVctValue)) ??\n          presentation.payload.vct,\n        claims: presentation.prettyClaims as DcqlSdJwtVcCredential.Claims,\n      } satisfies DcqlSdJwtVcCredential\n    }\n    if (presentation.claimFormat === ClaimFormat.MsoMdoc) {\n      if (!presentation.deviceResponse.documents || presentation.deviceResponse.documents.length !== 1) {\n        throw new DcqlError('MDOC presentations must contain exactly one document')\n      }\n\n      return {\n        cryptographic_holder_binding: true,\n        credential_format: 'mso_mdoc',\n        authority: this.getAuthorityForCredential(new Mdoc(presentation.deviceResponse.documents[0].issuerSigned)),\n        doctype: presentation.deviceResponse.documents[0].docType,\n        namespaces: Object.entries(\n          Object.fromEntries(presentation.deviceResponse.documents[0].issuerSigned.issuerNamespaces.issuerNamespaces)\n        ).reduce(\n          (prev, [key, value]) => ({\n            // biome-ignore lint/performance/noAccumulatingSpread: time complexity not relevant here\n            ...prev,\n            [key]: value.reduce<Record<string, unknown>>(\n              // biome-ignore lint/performance/noAccumulatingSpread: time complexity not relevant here\n              (prev, curr) => ({ ...prev, [curr.elementIdentifier]: curr.elementValue }),\n              {}\n            ),\n          }),\n          {}\n        ),\n      } satisfies DcqlMdocCredential\n    }\n    if (presentation.claimFormat === ClaimFormat.JwtVp) {\n      const vc = Array.isArray(presentation.verifiableCredential)\n        ? presentation.verifiableCredential[0]\n        : presentation.verifiableCredential\n\n      return {\n        cryptographic_holder_binding: true,\n        credential_format: 'jwt_vc_json',\n        authority: this.getAuthorityForCredential(vc),\n        claims: vc.jsonCredential as { [key: string]: JsonValue },\n        type: vc.type,\n      } satisfies DcqlW3cVcCredential\n    }\n    if (presentation.claimFormat === ClaimFormat.LdpVp) {\n      const vc = Array.isArray(presentation.verifiableCredential)\n        ? (presentation.verifiableCredential[0] as W3cJsonLdVerifiableCredential)\n        : (presentation.verifiableCredential as W3cJsonLdVerifiableCredential)\n\n      const w3cJsonLdCredentialService = agentContext.dependencyManager.resolve(W3cJsonLdCredentialService)\n      const expandedTypes = await w3cJsonLdCredentialService.getExpandedTypesForCredential(agentContext, vc)\n\n      return {\n        cryptographic_holder_binding: true,\n        credential_format: 'ldp_vc',\n        authority: this.getAuthorityForCredential(vc),\n        claims: vc.jsonCredential as DcqlW3cVcCredential.Claims,\n        type: expandedTypes,\n      } satisfies DcqlW3cVcCredential\n    }\n    if (presentation.claimFormat === ClaimFormat.SdJwtW3cVp) {\n      const envelopedVc = Array.isArray(presentation.resolvedPresentation.verifiableCredential)\n        ? presentation.resolvedPresentation.verifiableCredential[0]\n        : presentation.resolvedPresentation.verifiableCredential\n\n      return {\n        cryptographic_holder_binding: true,\n        credential_format: 'vc+sd-jwt',\n        authority: this.getAuthorityForCredential(envelopedVc),\n        type: asArray(envelopedVc.resolvedCredential.type),\n        claims: envelopedVc.resolvedCredential.toJSON() as { [key: string]: JsonValue },\n      } satisfies DcqlW3cVcCredential\n    }\n\n    throw new DcqlError('Unsupported claim format for presentation')\n  }\n\n  public async getCredentialsForRequest(agentContext: AgentContext, dcqlQuery: DcqlQuery): Promise<DcqlQueryResult> {\n    const credentialRecords = await this.queryCredentialsForDcqlQuery(agentContext, dcqlQuery)\n    const credentialRecordsWithFormatDuplicates: typeof credentialRecords = []\n    const parsedQuery = DcqlQuery.parse(dcqlQuery)\n\n    const dcqlCredentials: DcqlCredential[] = credentialRecords.flatMap((record): DcqlCredential | DcqlCredential[] => {\n      if (record.type === 'MdocRecord') {\n        credentialRecordsWithFormatDuplicates.push(record)\n\n        // We always extract the first mdoc for querying\n        const mdoc = record.firstCredential\n\n        return {\n          authority: this.getAuthorityForCredential(mdoc),\n          credential_format: 'mso_mdoc',\n          doctype: mdoc.docType,\n          namespaces: mdoc.issuerSignedNamespaces,\n          cryptographic_holder_binding: true,\n        } satisfies DcqlCredential\n      }\n\n      if (record.type === 'SdJwtVcRecord') {\n        const sdJwtVc = record.firstCredential\n        const claims = sdJwtVc.prettyClaims as DcqlSdJwtVcCredential.Claims\n\n        // To keep correct mapping of input credential index, we add it multiple times here:\n        // - for dc+sd-jwt and vc+sd-jwt\n        // - for each extended VCT (until we have multi-vct support in DCQL)\n        credentialRecordsWithFormatDuplicates.push(\n          record,\n          record,\n          ...record.extendedVctValues.map(() => record),\n          ...record.extendedVctValues.map(() => record)\n        )\n\n        return [\n          {\n            authority: this.getAuthorityForCredential(sdJwtVc),\n            credential_format: 'dc+sd-jwt',\n            vct: record.getTags().vct,\n            claims,\n            cryptographic_holder_binding: true,\n          } satisfies DcqlSdJwtVcCredential,\n          ...record.extendedVctValues.map(\n            (extendedVctValue) =>\n              ({\n                authority: this.getAuthorityForCredential(sdJwtVc),\n                credential_format: 'dc+sd-jwt',\n                vct: extendedVctValue,\n                claims,\n                cryptographic_holder_binding: true,\n              }) satisfies DcqlSdJwtVcCredential\n          ),\n          {\n            authority: this.getAuthorityForCredential(sdJwtVc),\n            credential_format: 'vc+sd-jwt',\n            vct: record.getTags().vct,\n            claims,\n            cryptographic_holder_binding: true,\n          } satisfies DcqlSdJwtVcCredential,\n          ...record.extendedVctValues.map(\n            (extendedVctValue) =>\n              ({\n                authority: this.getAuthorityForCredential(sdJwtVc),\n                credential_format: 'vc+sd-jwt',\n                vct: extendedVctValue,\n                claims,\n                cryptographic_holder_binding: true,\n              }) satisfies DcqlSdJwtVcCredential\n          ),\n        ] satisfies DcqlSdJwtVcCredential[]\n      }\n\n      if (record.type === 'W3cCredentialRecord') {\n        const firstCredential = record.firstCredential\n        credentialRecordsWithFormatDuplicates.push(record)\n        if (firstCredential.claimFormat === ClaimFormat.LdpVc) {\n          return {\n            credential_format: 'ldp_vc',\n            authority: this.getAuthorityForCredential(firstCredential),\n            type: record.getTags().expandedTypes ?? [],\n            claims: firstCredential.jsonCredential as DcqlW3cVcCredential.Claims,\n            cryptographic_holder_binding: true,\n          } satisfies DcqlW3cVcCredential\n        }\n\n        return {\n          credential_format: 'jwt_vc_json',\n          authority: this.getAuthorityForCredential(firstCredential),\n          type: firstCredential.type,\n          claims: firstCredential.jsonCredential as DcqlW3cVcCredential.Claims,\n          cryptographic_holder_binding: true,\n        } satisfies DcqlW3cVcCredential\n      }\n\n      if (record.type === 'W3cV2CredentialRecord') {\n        credentialRecordsWithFormatDuplicates.push(record)\n        const firstCredential = record.firstCredential\n\n        return {\n          credential_format: 'vc+sd-jwt',\n          authority: this.getAuthorityForCredential(firstCredential),\n          type: asArray(firstCredential.resolvedCredential.type),\n          claims: firstCredential.resolvedCredential.toJSON() as DcqlW3cVcCredential.Claims,\n          cryptographic_holder_binding: true,\n        } satisfies DcqlW3cVcCredential\n      }\n\n      throw new DcqlError('Unsupported record type')\n    })\n\n    const queryResult = DcqlQuery.query(parsedQuery, dcqlCredentials)\n\n    const matchesWithRecord = Object.fromEntries(\n      Object.entries(queryResult.credential_matches).map(([credential_query_id, result]) => {\n        const failedCredentials = result.failed_credentials\n          ? mapNonEmptyArray(result.failed_credentials, (credential) => {\n              const record = credentialRecordsWithFormatDuplicates[credential.input_credential_index]\n              const updatedCredential: DcqlFailedCredential = {\n                ...credential,\n                record,\n                claims: credential.claims.success\n                  ? {\n                      ...credential.claims,\n                      success: true,\n                      valid_claim_sets: mapNonEmptyArray(credential.claims.valid_claim_sets, (claimSet) => ({\n                        ...claimSet,\n                        ...(record.type === 'SdJwtVcRecord'\n                          ? // NOTE: we cast from SdJwtVcPayload (which is Record<string, unknown> to { [key: string]: JsonValue })\n                            // Otherwise TypeScript explains, but I'm not sure why Record<string, unknown> wouldn't be applicable to { [key: string]: JsonValue }\n                            {\n                              output: agentContext.dependencyManager\n                                .resolve(SdJwtVcService)\n                                .applyDisclosuresForPayload(record.encoded, claimSet.output as JsonObject)\n                                .prettyClaims as { [key: string]: JsonValue },\n                            }\n                          : record.type === 'W3cV2CredentialRecord' &&\n                              record.firstCredential instanceof W3cV2SdJwtVerifiableCredential\n                            ? {\n                                output: agentContext.dependencyManager\n                                  .resolve(SdJwtVcService)\n                                  .applyDisclosuresForPayload(\n                                    record.firstCredential.encoded,\n                                    claimSet.output as JsonObject\n                                  ).prettyClaims as { [key: string]: JsonValue },\n                              }\n                            : {}),\n                      })),\n                    }\n                  : credential.claims,\n              }\n              return updatedCredential\n            })\n          : undefined\n\n        // If not success, valid_credentials will be undefined, so we only have to map failed_credentials\n        if (!result.success) {\n          return [\n            credential_query_id,\n            {\n              ...result,\n              failed_credentials: failedCredentials,\n            },\n          ]\n        }\n\n        return [\n          credential_query_id,\n          {\n            ...result,\n            failed_credentials: failedCredentials,\n            valid_credentials: mapNonEmptyArray(result.valid_credentials, (credential) => {\n              const record = credentialRecordsWithFormatDuplicates[credential.input_credential_index]\n              const updatedCredential: DcqlValidCredential = {\n                ...credential,\n                record,\n                claims: {\n                  ...credential.claims,\n                  valid_claim_sets: mapNonEmptyArray(credential.claims.valid_claim_sets, (claimSet) => ({\n                    ...claimSet,\n                    ...(record.type === 'SdJwtVcRecord'\n                      ? // NOTE: we cast from SdJwtVcPayload (which is Record<string, unknown> to { [key: string]: JsonValue })\n                        // Otherwise TypeScript explains, but I'm not sure why Record<string, unknown> wouldn't be applicable to { [key: string]: JsonValue }\n                        {\n                          output: agentContext.dependencyManager\n                            .resolve(SdJwtVcService)\n                            .applyDisclosuresForPayload(record.encoded, claimSet.output as JsonObject).prettyClaims as {\n                            [key: string]: JsonValue\n                          },\n                        }\n                      : record.type === 'W3cV2CredentialRecord' &&\n                          record.firstCredential instanceof W3cV2SdJwtVerifiableCredential\n                        ? {\n                            output: agentContext.dependencyManager\n                              .resolve(SdJwtVcService)\n                              .applyDisclosuresForPayload(record.firstCredential.encoded, claimSet.output as JsonObject)\n                              .prettyClaims as { [key: string]: JsonValue },\n                          }\n                        : {}),\n                  })),\n                },\n              }\n              return updatedCredential\n            }),\n          },\n        ]\n      })\n    )\n\n    return {\n      ...queryResult,\n      credential_matches: matchesWithRecord,\n    }\n  }\n\n  public async assertValidDcqlPresentation(\n    agentContext: AgentContext,\n    dcqlPresentation: DcqlPresentation,\n    dcqlQuery: DcqlQuery\n  ) {\n    const internalDcqlPresentation = Object.fromEntries(\n      await Promise.all(\n        Object.entries(dcqlPresentation).map(async ([credentialId, presentations]) => {\n          const queryCredential = dcqlQuery.credentials.find((c) => c.id === credentialId)\n          if (!queryCredential) {\n            throw new DcqlError(\n              `DCQL presentation contains presentation entry for credential id '${credentialId}', but this id is not present in the DCQL query`\n            )\n          }\n\n          return [\n            credentialId,\n            await Promise.all(\n              presentations.map((presentation) =>\n                this.getDcqlCredentialRepresentation(agentContext, presentation, queryCredential)\n              )\n            ),\n          ]\n        })\n      )\n    )\n\n    const presentationResult = DcqlPresentationResult.fromDcqlPresentation(internalDcqlPresentation, { dcqlQuery })\n\n    if (!presentationResult.can_be_satisfied) {\n      throw new DcqlError('Presentations do not satisfy the DCQL query.', {\n        additionalMessages: Object.entries(presentationResult.credential_matches ?? {})\n          .flatMap(([queryId, match]) =>\n            match.success\n              ? undefined\n              : !match.failed_credentials\n                ? `Unable to match query credential '${queryId}'. No prsentations provided`\n                : match.failed_credentials.map(\n                    (failedCredential) =>\n                      `Presentation at index ${failedCredential.input_credential_index} does not match query credential '${queryId}'. ${JSON.stringify(\n                        {\n                          ...(failedCredential.claims.success\n                            ? {}\n                            : { claims: failedCredential.claims.failed_claim_sets.map((cs) => cs.issues) }),\n                          ...(failedCredential.trusted_authorities.success\n                            ? {}\n                            : {\n                                trusted_authorities:\n                                  failedCredential.trusted_authorities.failed_trusted_authorities.map(\n                                    (ta) => ta.issues\n                                  ),\n                              }),\n                          ...(failedCredential.meta.success ? {} : { meta: failedCredential.meta.issues }),\n                        },\n                        null,\n                        2\n                      )}`\n                  )\n          )\n          .filter((message) => message !== undefined),\n      })\n    }\n\n    return presentationResult\n  }\n\n  private dcqlCredentialForRequestForValidCredential(validCredential: DcqlValidCredential) {\n    if (validCredential.record.type === 'MdocRecord') {\n      return {\n        claimFormat: ClaimFormat.MsoMdoc,\n        credentialRecord: validCredential.record,\n        disclosedPayload: validCredential.claims.valid_claim_sets[0].output as MdocNameSpaces,\n      } as const\n    }\n    if (validCredential.record.type === 'SdJwtVcRecord') {\n      return {\n        claimFormat: ClaimFormat.SdJwtDc,\n        credentialRecord: validCredential.record,\n        disclosedPayload: validCredential.claims.valid_claim_sets[0].output as JsonObject,\n      } as const\n    }\n\n    if (validCredential.record.type === 'W3cCredentialRecord') {\n      return {\n        claimFormat: validCredential.record.firstCredential.claimFormat,\n        credentialRecord: validCredential.record,\n        disclosedPayload: validCredential.record.firstCredential.jsonCredential as JsonObject,\n      } as const\n    }\n\n    if (validCredential.record.type === 'W3cV2CredentialRecord') {\n      return {\n        claimFormat: validCredential.record.firstCredential.claimFormat,\n        credentialRecord: validCredential.record,\n        disclosedPayload: validCredential.claims.valid_claim_sets[0].output as JsonObject,\n      } as const\n    }\n\n    throw new DcqlError('Unsupported record type for DCQL')\n  }\n\n  /**\n   * Selects the credentials to use based on the output from `getCredentialsForRequest`\n   * Use this method if you don't want to manually select the credentials yourself.\n   */\n  public selectCredentialsForRequest(\n    dcqlQueryResult: DcqlQueryResult,\n    { useMode = CredentialMultiInstanceUseMode.NewOrFirst }: DcqlSelectCredentialsForRequestOptions = {}\n  ): DcqlCredentialsForRequest {\n    if (!dcqlQueryResult.can_be_satisfied) {\n      throw new DcqlError(\n        'Cannot select the credentials for the dcql query presentation if the request cannot be satisfied'\n      )\n    }\n\n    const credentials: DcqlCredentialsForRequest = {}\n\n    if (dcqlQueryResult.credential_sets) {\n      credentialSetLoop: for (const credentialSet of dcqlQueryResult.credential_sets) {\n        // undefined defaults to true\n        if (credentialSet.required === false) continue\n        const fullfillableOptions = credentialSet.matching_options\n\n        if (!fullfillableOptions) {\n          throw new DcqlError('Invalid dcql query result. No option is fullfillable')\n        }\n\n        for (const fullfillableOption of fullfillableOptions) {\n          const optionMatches = fullfillableOption.map((credentialQueryId) => {\n            const credentialMatch = dcqlQueryResult.credential_matches[credentialQueryId]\n            if (!credentialMatch.success) return undefined\n            const match = credentialMatch.valid_credentials.find((match: DcqlValidCredential) =>\n              canUseInstanceFromCredentialRecord({ credentialRecord: match.record, useMode })\n            )\n\n            if (!match) return undefined\n            return {\n              match,\n              credentialQueryId,\n            }\n          })\n\n          if (optionMatches.every((c) => c !== undefined)) {\n            for (const { match, credentialQueryId } of optionMatches) {\n              credentials[credentialQueryId] = [this.dcqlCredentialForRequestForValidCredential(match)]\n            }\n\n            continue credentialSetLoop\n          }\n        }\n\n        throw new DcqlError(\n          'Unable to select credentials for credential set. No new credential instance available on any of the available credentials.'\n        )\n      }\n    } else {\n      for (const credentialQuery of dcqlQueryResult.credentials) {\n        const credentialMatch = dcqlQueryResult.credential_matches[credentialQuery.id]\n        if (!credentialMatch.success) {\n          throw new DcqlError(\n            `Invalid dcql query result for credential query id '${credentialQuery.id}'. Cannot auto-select credentials`\n          )\n        }\n\n        const credential = credentialMatch.valid_credentials.find((match: DcqlValidCredential) =>\n          canUseInstanceFromCredentialRecord({ credentialRecord: match.record, useMode })\n        )\n        if (!credential) {\n          throw new DcqlError(\n            `Unable to select credential for credential query id '${credentialQuery.id}'. No new credential instance available on any of the available credentials.`\n          )\n        }\n\n        credentials[credentialQuery.id] = [this.dcqlCredentialForRequestForValidCredential(credential)]\n      }\n    }\n\n    return credentials\n  }\n\n  public validateDcqlQuery(dcqlQuery: DcqlQuery | DcqlQuery.Input | unknown): DcqlQuery {\n    const parsed = DcqlQuery.parse(dcqlQuery as DcqlQuery)\n    DcqlQuery.validate(parsed)\n    return parsed\n  }\n\n  public async createPresentation(\n    agentContext: AgentContext,\n    options: {\n      credentialQueryToCredential: DcqlCredentialsForRequest\n      challenge: string\n      domain?: string\n      mdocSessionTranscript?: MdocSessionTranscriptOptions\n    }\n  ): Promise<{\n    dcqlPresentation: DcqlPresentation\n    encodedDcqlPresentation: DcqlEncodedPresentations\n  }> {\n    const { domain, challenge, mdocSessionTranscript } = options\n\n    const dcqlPresentation: DcqlPresentation = {}\n    const encodedDcqlPresentation: DcqlEncodedPresentations = {}\n    const vcPresentationsToCreate = getDcqlVcPresentationsToCreate(options.credentialQueryToCredential)\n\n    for (const [credentialQueryId, presentationsToCreate] of Object.entries(vcPresentationsToCreate)) {\n      for (const presentationToCreate of presentationsToCreate) {\n        let createdPresentation: VerifiablePresentation\n        let encodedCreatedPresentation: string | Record<string, unknown>\n\n        if (presentationToCreate.claimFormat === ClaimFormat.MsoMdoc) {\n          const mdocRecord = presentationToCreate.credentialRecord\n          if (!mdocSessionTranscript) {\n            throw new DcqlError('Missing mdoc session transcript options for creating MDOC presentation.')\n          }\n\n          const { credentialInstance } = await useInstanceFromCredentialRecord({\n            agentContext,\n            useMode: presentationToCreate.useMode,\n            credentialRecord: mdocRecord,\n          })\n\n          const deviceResponse = await MdocDeviceResponse.createDeviceResponse(agentContext, {\n            mdocs: [credentialInstance],\n            documentRequests: [\n              {\n                docType: mdocRecord.getTags().docType,\n                nameSpaces: Object.fromEntries(\n                  Object.entries(presentationToCreate.disclosedPayload).map(([key, value]) => {\n                    // FIXME: we need the DCQL query here to get the intent_to_retain from query (currently hardcoded to false)\n                    return [key, Object.fromEntries(Object.entries(value).map(([key]) => [key, false]))]\n                  })\n                ),\n              },\n            ],\n            sessionTranscriptOptions: mdocSessionTranscript,\n          })\n          const deviceResponseBase64Url = deviceResponse.encoded\n\n          encodedCreatedPresentation = deviceResponseBase64Url\n          createdPresentation = MdocDeviceResponse.fromBase64Url(deviceResponseBase64Url)\n        } else if (presentationToCreate.claimFormat === ClaimFormat.SdJwtDc) {\n          const presentationFrame = buildDisclosureFrameForPayload(presentationToCreate.disclosedPayload)\n\n          if (!domain) {\n            throw new DcqlError('Missing domain property for creating SdJwtVc presentation.')\n          }\n\n          const { credentialInstance } = await useInstanceFromCredentialRecord({\n            agentContext,\n            useMode: presentationToCreate.useMode,\n            credentialRecord: presentationToCreate.credentialRecord,\n          })\n\n          const sdJwtVcApi = this.getSdJwtVcApi(agentContext)\n          const presentation = await sdJwtVcApi.present({\n            sdJwtVc: credentialInstance,\n            presentationFrame,\n            verifierMetadata: {\n              audience: domain,\n              nonce: challenge,\n              issuedAt: Math.floor(Date.now() / 1000),\n            },\n            additionalPayload: presentationToCreate.additionalPayload,\n          })\n\n          encodedCreatedPresentation = presentation\n          createdPresentation = sdJwtVcApi.fromCompact(presentation)\n        } else if (presentationToCreate.claimFormat === ClaimFormat.JwtVp) {\n          const { credentialInstance } = await useInstanceFromCredentialRecord({\n            agentContext,\n            useMode: presentationToCreate.useMode,\n            credentialRecord: presentationToCreate.credentialRecord,\n          })\n\n          if (!credentialInstance.credentialSubjectIds[0]) {\n            throw new DcqlError('Cannot create presentation for credentials without subject id')\n          }\n\n          // Determine a suitable verification method for the presentation\n          const verificationMethod = await this.getVerificationMethodForSubjectId(\n            agentContext,\n            credentialInstance.credentialSubjectIds[0]\n          )\n\n          const w3cCredentialService = agentContext.resolve(W3cCredentialService)\n          const w3cPresentation = new W3cPresentation({\n            verifiableCredential: [credentialInstance],\n            holder: verificationMethod.controller,\n          })\n\n          const publicJwk = getPublicJwkFromVerificationMethod(verificationMethod)\n\n          const signedPresentation = await w3cCredentialService.signPresentation<ClaimFormat.JwtVp>(agentContext, {\n            format: ClaimFormat.JwtVp,\n            alg: publicJwk.signatureAlgorithm,\n            verificationMethod: verificationMethod.id,\n            presentation: w3cPresentation,\n            challenge,\n            domain,\n          })\n\n          encodedCreatedPresentation = signedPresentation.encoded\n          createdPresentation = signedPresentation\n        } else if (presentationToCreate.claimFormat === ClaimFormat.LdpVp) {\n          const { credentialInstance } = await useInstanceFromCredentialRecord({\n            agentContext,\n            useMode: presentationToCreate.useMode,\n            credentialRecord: presentationToCreate.credentialRecord,\n          })\n\n          if (!credentialInstance.credentialSubjectIds[0]) {\n            throw new DcqlError('Cannot create presentation for credentials without subject id')\n          }\n\n          // Determine a suitable verification method for the presentation\n          const verificationMethod = await this.getVerificationMethodForSubjectId(\n            agentContext,\n            credentialInstance.credentialSubjectIds[0]\n          )\n\n          const w3cCredentialService = agentContext.resolve(W3cCredentialService)\n          const w3cPresentation = new W3cPresentation({\n            verifiableCredential: [credentialInstance],\n            holder: verificationMethod.controller,\n          })\n\n          const signedPresentation = await w3cCredentialService.signPresentation(agentContext, {\n            format: ClaimFormat.LdpVp,\n            // TODO: we should move the check for which proof to use for a presentation to earlier\n            // as then we know when determining which VPs to submit already if the proof types are supported\n            // by the verifier, and we can then just add this to the vpToCreate interface\n            proofType: this.getProofTypeForLdpVc(agentContext, verificationMethod),\n            proofPurpose: new purposes.AuthenticationProofPurpose({ challenge, domain }),\n            verificationMethod: verificationMethod.id,\n            presentation: w3cPresentation,\n            challenge,\n            domain,\n          })\n\n          encodedCreatedPresentation = signedPresentation.encoded\n          createdPresentation = signedPresentation\n        } else if (presentationToCreate.claimFormat === ClaimFormat.JwtW3cVp) {\n          const w3cV2CredentialService = agentContext.resolve(W3cV2CredentialService)\n          const w3cV2Presentation = new W3cV2Presentation({\n            holder: presentationToCreate.credentialRecord.firstCredential.resolvedCredential.credentialSubjectIds[0],\n            verifiableCredential: [\n              W3cV2EnvelopedVerifiableCredential.fromVerifiableCredential(\n                presentationToCreate.credentialRecord.firstCredential\n              ),\n            ],\n          })\n\n          const signedPresentation = await w3cV2CredentialService.signPresentation<ClaimFormat.JwtW3cVp>(agentContext, {\n            format: ClaimFormat.JwtW3cVp,\n            presentation: w3cV2Presentation,\n            challenge,\n            domain,\n          })\n\n          encodedCreatedPresentation = signedPresentation.encoded\n          createdPresentation = signedPresentation\n        } else if (presentationToCreate.claimFormat === ClaimFormat.SdJwtW3cVp) {\n          const presentationFrame = buildDisclosureFrameForPayload(presentationToCreate.disclosedPayload)\n          if (!domain) {\n            throw new DcqlError('Missing domain property for creating SdJwtVc presentation.')\n          }\n\n          const w3cV2SdJwtCredentialService = agentContext.resolve(W3cV2SdJwtCredentialService)\n          const sdJwtVc = await w3cV2SdJwtCredentialService.present(agentContext, {\n            credential: presentationToCreate.credentialRecord.firstCredential.encoded,\n            presentationFrame,\n          })\n\n          const w3cV2CredentialService = agentContext.resolve(W3cV2CredentialService)\n          const w3cV2Presentation = new W3cV2Presentation({\n            holder: presentationToCreate.credentialRecord.firstCredential.resolvedCredential.credentialSchemaIds[0],\n            verifiableCredential: [W3cV2EnvelopedVerifiableCredential.fromVerifiableCredential(sdJwtVc)],\n          })\n\n          const signedPresentation = await w3cV2CredentialService.signPresentation<ClaimFormat.SdJwtW3cVp>(\n            agentContext,\n            {\n              format: ClaimFormat.SdJwtW3cVp,\n              presentation: w3cV2Presentation,\n              challenge,\n              domain,\n            }\n          )\n\n          encodedCreatedPresentation = signedPresentation.encoded\n          createdPresentation = signedPresentation\n        } else {\n          throw new DcqlError('Unsupported presentation format.')\n        }\n\n        if (!dcqlPresentation[credentialQueryId]) {\n          dcqlPresentation[credentialQueryId] = [createdPresentation]\n        } else {\n          dcqlPresentation[credentialQueryId].push(createdPresentation)\n        }\n\n        if (!encodedDcqlPresentation[credentialQueryId]) {\n          encodedDcqlPresentation[credentialQueryId] = [encodedCreatedPresentation]\n        } else {\n          encodedDcqlPresentation[credentialQueryId].push(encodedCreatedPresentation)\n        }\n      }\n    }\n\n    return {\n      dcqlPresentation,\n      encodedDcqlPresentation,\n    }\n  }\n\n  private getSdJwtVcApi(agentContext: AgentContext) {\n    return agentContext.dependencyManager.resolve(SdJwtVcApi)\n  }\n\n  private getMdocApi(agentContext: AgentContext) {\n    return agentContext.dependencyManager.resolve(MdocApi)\n  }\n\n  private async getVerificationMethodForSubjectId(agentContext: AgentContext, subjectId: string) {\n    const didsApi = agentContext.dependencyManager.resolve(DidsApi)\n\n    if (!subjectId.startsWith('did:')) {\n      throw new DcqlError(`Only dids are supported as credentialSubject id. ${subjectId} is not a valid did`)\n    }\n\n    const didDocument = await didsApi.resolveDidDocument(subjectId)\n\n    if (!didDocument.authentication || didDocument.authentication.length === 0) {\n      throw new DcqlError(`No authentication verificationMethods found for did ${subjectId} in did document`)\n    }\n\n    // the signature suite to use for the presentation is dependant on the credentials we share.\n    // 1. Get the verification method for this given proof purpose in this DID document\n    let [verificationMethod] = didDocument.authentication\n    if (typeof verificationMethod === 'string') {\n      verificationMethod = didDocument.dereferenceKey(verificationMethod, ['authentication'])\n    }\n\n    return verificationMethod\n  }\n\n  // FIXME: We need to take into account OpenID4VP metadata (probably providing supported/allowed algs to the DCQL create presentation method)\n  private getProofTypeForLdpVc(agentContext: AgentContext, verificationMethod: VerificationMethod) {\n    // For each of the supported algs, find the key types, then find the proof types\n    const signatureSuiteRegistry = agentContext.dependencyManager.resolve(SignatureSuiteRegistry)\n\n    const publicJwk = getPublicJwkFromVerificationMethod(verificationMethod)\n    const supportedSignatureSuites = signatureSuiteRegistry.getAllByPublicJwkType(publicJwk)\n    if (supportedSignatureSuites.length === 0) {\n      throw new DcqlError(\n        `Couldn't find a supported signature suite for the given jwk ${publicJwk.jwkTypeHumanDescription}`\n      )\n    }\n\n    return supportedSignatureSuites[0].proofType\n  }\n}\n"],"mappings":"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"}