{"version":3,"file":"SdJwtVcService.mjs","names":[],"sources":["../../../src/modules/sd-jwt-vc/SdJwtVcService.ts"],"sourcesContent":["import type { NonEmptyArray } from '@animo-id/pex'\nimport type { SDJwt } from '@sd-jwt/core'\nimport { decodeSdJwtSync } from '@sd-jwt/decode'\nimport { selectDisclosures } from '@sd-jwt/present'\nimport { SDJwtVcInstance, type VcTFetcher } from '@sd-jwt/sd-jwt-vc'\nimport type { DisclosureFrame, PresentationFrame } from '@sd-jwt/types'\nimport { AgentContext } from '../../agent'\nimport { Hasher, JwtPayload } from '../../crypto'\nimport { CredoError } from '../../error'\nimport { X509Service } from '../../modules/x509/X509Service'\nimport { injectable } from '../../plugins'\nimport type { Query, QueryOptions } from '../../storage/StorageService'\nimport type { JsonObject } from '../../types'\nimport { dateToSeconds, IntegrityVerifier, nowInSeconds, TypedArrayEncoder } from '../../utils'\nimport { getDomainFromUrl } from '../../utils/domain'\nimport { fetchWithTimeout } from '../../utils/fetch'\nimport { getPublicJwkFromVerificationMethod, parseDid } from '../dids'\nimport { KeyManagementApi, PublicJwk } from '../kms'\nimport { ClaimFormat } from '../vc/index'\nimport { type EncodedX509Certificate, X509Certificate, X509ModuleConfig } from '../x509'\nimport { decodeSdJwtVc, sdJwtVcHasher } from './decodeSdJwtVc'\nimport { buildDisclosureFrameForPayload } from './disclosureFrame'\nimport { SdJwtVcRecord, SdJwtVcRepository } from './repository'\nimport { SdJwtVcError } from './SdJwtVcError'\nimport { SdJwtVcModuleConfig } from './SdJwtVcModuleConfig'\nimport type {\n  SdJwtVcHeader,\n  SdJwtVcHolderBinding,\n  SdJwtVcIssuer,\n  SdJwtVcPayload,\n  SdJwtVcPresentOptions,\n  SdJwtVcSignOptions,\n  SdJwtVcStoreOptions,\n  SdJwtVcVerifyOptions,\n} from './SdJwtVcOptions'\nimport type { SdJwtVcTypeMetadata } from './typeMetadata'\nimport {\n  extractKeyFromHolderBinding,\n  getSdJwtSigner,\n  getSdJwtVerifier,\n  parseHolderBindingFromCredential,\n  resolveDidUrl,\n  resolveSigningPublicJwkFromDidUrl,\n} from './utils'\n\ntype SdJwtVcConfig = SDJwtVcInstance['userConfig']\n\nexport interface SdJwtVc<\n  Header extends SdJwtVcHeader = SdJwtVcHeader,\n  Payload extends SdJwtVcPayload = SdJwtVcPayload,\n> {\n  /**\n   * claim format is convenience method added to all credential instances\n   */\n  claimFormat: ClaimFormat.SdJwtDc\n  /**\n   * encoded is convenience method added to all credential instances\n   */\n  encoded: string\n  compact: string\n  header: Header\n\n  /**\n   * The holder of the credential\n   */\n  holder: SdJwtVcHolderBinding | undefined\n\n  // TODO: payload type here is a lie, as it is the signed payload (so fields replaced with _sd)\n  payload: Payload\n  prettyClaims: Payload\n\n  kbJwt?: {\n    header: Record<string, unknown>\n    payload: Record<string, unknown>\n  }\n\n  /**\n   * The key id in the KMS bound to this SD-JWT VC, used for presentations.\n   *\n   * This will only be set on the holder side if defined on the SdJwtVcRecord\n   */\n  kmsKeyId?: string\n\n  /**\n   * The merged/resolved type metadata of the SD-JWT VC.\n   */\n  typeMetadata?: SdJwtVcTypeMetadata\n}\n\nexport interface VerificationResult {\n  isValid: boolean\n  isValidJwtPayload?: boolean\n  isSignatureValid?: boolean\n  isStatusValid?: boolean\n  isNotBeforeValid?: boolean\n  isExpiryTimeValid?: boolean\n  areRequiredClaimsIncluded?: boolean\n  isKeyBindingValid?: boolean\n  containsExpectedKeyBinding?: boolean\n  containsRequiredVcProperties?: boolean\n}\n\n/**\n * @internal\n */\n@injectable()\nexport class SdJwtVcService {\n  public constructor(private sdJwtVcRepository: SdJwtVcRepository) {}\n\n  public async sign<Payload extends SdJwtVcPayload>(\n    agentContext: AgentContext,\n    options: SdJwtVcSignOptions<Payload>\n  ): Promise<SdJwtVc> {\n    const { payload, disclosureFrame, hashingAlgorithm } = options\n\n    // default is sha-256\n    if (hashingAlgorithm && hashingAlgorithm !== 'sha-256') {\n      throw new SdJwtVcError(`Unsupported hashing algorithm used: ${hashingAlgorithm}`)\n    }\n\n    const issuer = await this.extractKeyFromIssuer(agentContext, options.issuer, true)\n\n    // holer binding is optional\n    const holderBinding = options.holder ? await extractKeyFromHolderBinding(agentContext, options.holder) : undefined\n\n    const header = {\n      alg: issuer.alg,\n      typ: options.headerType ?? 'dc+sd-jwt',\n      kid: issuer.kid,\n      x5c: issuer.x5c?.map((cert) => cert.toString('base64')),\n    } as const\n\n    const sdJwt = new SDJwtVcInstance({\n      ...this.getBaseSdJwtConfig(agentContext),\n      signer: getSdJwtSigner(agentContext, issuer.publicJwk),\n      hashAlg: 'sha-256',\n      signAlg: issuer.alg,\n    })\n\n    if (!payload.vct || typeof payload.vct !== 'string') {\n      throw new SdJwtVcError(\"Missing required parameter 'vct'\")\n    }\n\n    const compact = await sdJwt.issue(\n      {\n        ...payload,\n        cnf: holderBinding?.cnf,\n        iss: issuer.iss,\n        iat: nowInSeconds(),\n        vct: payload.vct,\n      },\n      disclosureFrame as DisclosureFrame<Payload>,\n      { header }\n    )\n\n    const prettyClaims = (await sdJwt.getClaims(compact)) as Payload\n    const decoded = await sdJwt.decode(compact)\n    const sdJwtPayload = decoded.jwt?.payload as Payload | undefined\n    if (!sdJwtPayload) {\n      throw new SdJwtVcError('Invalid sd-jwt-vc state.')\n    }\n\n    return {\n      compact,\n      prettyClaims,\n      header: header,\n      holder: options.holder,\n      payload: sdJwtPayload,\n      claimFormat: ClaimFormat.SdJwtDc,\n      encoded: compact,\n    } satisfies SdJwtVc<typeof header, Payload>\n  }\n\n  public fromCompact<Header extends SdJwtVcHeader = SdJwtVcHeader, Payload extends SdJwtVcPayload = SdJwtVcPayload>(\n    compactSdJwtVc: string,\n    typeMetadata?: SdJwtVcTypeMetadata\n  ): SdJwtVc<Header, Payload> {\n    return decodeSdJwtVc(compactSdJwtVc, typeMetadata)\n  }\n\n  public applyDisclosuresForPayload(compactSdJwtVc: string, requestedPayload: JsonObject): SdJwtVc {\n    const decoded = decodeSdJwtSync(compactSdJwtVc, Hasher.hash)\n    const presentationFrame = buildDisclosureFrameForPayload(requestedPayload) ?? {}\n\n    if (decoded.kbJwt) {\n      throw new SdJwtVcError('Cannot apply limit disclosure on an sd-jwt with key binding jwt')\n    }\n\n    const requiredDisclosures = selectDisclosures(\n      decoded.jwt.payload,\n      // Map to sd-jwt disclosure format\n      decoded.disclosures.map((d) => ({\n        digest: d.digestSync({ alg: 'sha-256', hasher: Hasher.hash }),\n        encoded: d.encode(),\n        key: d.key,\n        salt: d.salt,\n        value: d.value,\n      })),\n      presentationFrame as { [key: string]: boolean }\n    )\n    const [jwt] = compactSdJwtVc.split('~')\n    const disclosuresString =\n      requiredDisclosures.length > 0 ? `${requiredDisclosures.map((d) => d.encoded).join('~')}~` : ''\n    const sdJwt = `${jwt}~${disclosuresString}`\n    const disclosedDecoded = decodeSdJwtVc(sdJwt)\n    return disclosedDecoded\n  }\n\n  public async present<Payload extends SdJwtVcPayload = SdJwtVcPayload>(\n    agentContext: AgentContext,\n    { sdJwtVc, presentationFrame, verifierMetadata, additionalPayload }: SdJwtVcPresentOptions<Payload>\n  ): Promise<string> {\n    const sdjwt = new SDJwtVcInstance(this.getBaseSdJwtConfig(agentContext))\n    const compactSdJwtVc = typeof sdJwtVc === 'string' ? sdJwtVc : sdJwtVc.compact\n    const sdJwtVcInstance = await sdjwt.decode(compactSdJwtVc)\n\n    const holderBinding = parseHolderBindingFromCredential(sdJwtVcInstance.jwt?.payload)\n    if (!holderBinding && verifierMetadata) {\n      throw new SdJwtVcError(\"Verifier metadata provided, but credential has no 'cnf' claim to create a KB-JWT from\")\n    }\n\n    const holder = holderBinding\n      ? await extractKeyFromHolderBinding(agentContext, holderBinding, {\n          forSigning: true,\n          jwkKeyId: typeof sdJwtVc !== 'string' ? sdJwtVc.kmsKeyId : undefined,\n        })\n      : undefined\n    sdjwt.config({\n      kbSigner: holder ? getSdJwtSigner(agentContext, holder.publicJwk) : undefined,\n      kbSignAlg: holder?.alg,\n    })\n\n    const compactDerivedSdJwtVc = await sdjwt.present(compactSdJwtVc, presentationFrame as PresentationFrame<Payload>, {\n      kb: verifierMetadata\n        ? {\n            payload: {\n              iat: verifierMetadata.issuedAt,\n              nonce: verifierMetadata.nonce,\n              aud: verifierMetadata.audience,\n              ...additionalPayload,\n            },\n          }\n        : undefined,\n    })\n\n    return compactDerivedSdJwtVc\n  }\n\n  private assertValidX5cJwtIssuer(\n    agentContext: AgentContext,\n    iss: string | undefined,\n    leafCertificate: X509Certificate\n  ) {\n    // No 'iss' is allowed for X509\n    if (!iss) return\n\n    // If iss is present it MUST be an HTTPS url\n    if (!iss.startsWith('https://') && !(iss.startsWith('http://') && agentContext.config.allowInsecureHttpUrls)) {\n      throw new SdJwtVcError('The X509 certificate issuer must be a HTTPS URI.')\n    }\n\n    if (!leafCertificate.sanUriNames?.includes(iss) && !leafCertificate.sanDnsNames?.includes(getDomainFromUrl(iss))) {\n      throw new SdJwtVcError(\n        `The 'iss' claim in the payload does not match a 'SAN-URI' name and the domain extracted from the HTTPS URI does not match a 'SAN-DNS' name in the x5c certificate. Either remove the 'iss' claim or make it match with at least one SAN-URI or DNS-URI entry`\n      )\n    }\n  }\n\n  public async verify<Header extends SdJwtVcHeader = SdJwtVcHeader, Payload extends SdJwtVcPayload = SdJwtVcPayload>(\n    agentContext: AgentContext,\n    { compactSdJwtVc, keyBinding, requiredClaimKeys, fetchTypeMetadata, trustedCertificates, now }: SdJwtVcVerifyOptions\n  ): Promise<\n    | {\n        isValid: true\n        sdJwtVc: SdJwtVc<Header, Payload>\n        /**\n         * The full type metadata chain, can be used for further processing the type metadata.\n         *\n         * Only populated if `fetchTypeMetadata` is set to true, and the resolver returned a type\n         * metadata document.\n         */\n        typeMetadataChain?: NonEmptyArray<SdJwtVcTypeMetadata>\n      }\n    | { isValid: false; sdJwtVc?: SdJwtVc<Header, Payload>; error: Error }\n  > {\n    const sdjwt = new SDJwtVcInstance({\n      ...this.getBaseSdJwtConfig(agentContext),\n      // We manually fetch later\n      loadTypeMetadataFormat: false,\n    })\n    let sdJwtVc: SDJwt<Header, Payload>\n    let holderBinding: SdJwtVcHolderBinding | undefined\n\n    try {\n      sdJwtVc = (await sdjwt.decode(compactSdJwtVc)) as SDJwt<Header, Payload>\n      if (!sdJwtVc.jwt) throw new CredoError('Invalid sd-jwt-vc')\n      holderBinding = parseHolderBindingFromCredential(sdJwtVc.jwt.payload) ?? undefined\n    } catch (error) {\n      return {\n        isValid: false,\n        error,\n      }\n    }\n\n    const returnSdJwtVc: SdJwtVc<Header, Payload> = {\n      payload: sdJwtVc.jwt.payload as Payload,\n      header: sdJwtVc.jwt.header as Header,\n      compact: compactSdJwtVc,\n      prettyClaims: await sdJwtVc.getClaims(sdJwtVcHasher),\n      holder: holderBinding,\n\n      kbJwt: sdJwtVc.kbJwt\n        ? {\n            payload: sdJwtVc.kbJwt.payload as Record<string, unknown>,\n            header: sdJwtVc.kbJwt.header as Record<string, unknown>,\n          }\n        : undefined,\n      claimFormat: ClaimFormat.SdJwtDc,\n      encoded: compactSdJwtVc,\n    } satisfies SdJwtVc<Header, Payload>\n\n    let typeMetadataChain: NonEmptyArray<SdJwtVcTypeMetadata> | undefined\n    try {\n      const credentialIssuer = await this.parseIssuerFromCredential(\n        agentContext,\n        sdJwtVc,\n        returnSdJwtVc,\n        trustedCertificates\n      )\n      const issuer = await this.extractKeyFromIssuer(agentContext, credentialIssuer)\n      const holder = returnSdJwtVc.holder\n        ? await extractKeyFromHolderBinding(agentContext, returnSdJwtVc.holder)\n        : undefined\n\n      sdjwt.config({\n        verifier: getSdJwtVerifier(agentContext, issuer.publicJwk),\n        kbVerifier: holder ? getSdJwtVerifier(agentContext, holder.publicJwk) : undefined,\n      })\n\n      try {\n        await sdjwt.verify(compactSdJwtVc, {\n          requiredClaimKeys: requiredClaimKeys ? [...requiredClaimKeys, 'vct'] : ['vct'],\n          keyBindingNonce: keyBinding?.nonce,\n          currentDate: dateToSeconds(now ?? new Date()),\n          skewSeconds: agentContext.config.validitySkewSeconds,\n        })\n      } catch (error) {\n        return {\n          error,\n          isValid: false,\n          sdJwtVc: returnSdJwtVc,\n        }\n      }\n\n      if (sdJwtVc.jwt.header?.typ !== 'vc+sd-jwt' && sdJwtVc.jwt.header?.typ !== 'dc+sd-jwt') {\n        return {\n          error: new SdJwtVcError(`SD-JWT VC header 'typ' must be 'dc+sd-jwt' or 'vc+sd-jwt'`),\n          isValid: false,\n          sdJwtVc: returnSdJwtVc,\n        }\n      }\n\n      try {\n        JwtPayload.fromJson(returnSdJwtVc.payload).validate({\n          now: dateToSeconds(now ?? new Date()),\n          skewSeconds: agentContext.config.validitySkewSeconds,\n        })\n      } catch (error) {\n        return {\n          error,\n          isValid: false,\n          sdJwtVc: returnSdJwtVc,\n        }\n      }\n\n      // If keyBinding is present, verify the key binding\n      try {\n        if (keyBinding) {\n          if (!sdJwtVc.kbJwt || !sdJwtVc.kbJwt.payload) {\n            throw new SdJwtVcError('Keybinding is required for verification of the sd-jwt-vc')\n          }\n\n          // Assert `aud` and `nonce` claims\n          if (sdJwtVc.kbJwt.payload.aud !== keyBinding.audience) {\n            throw new SdJwtVcError('The key binding JWT does not contain the expected audience')\n          }\n\n          if (sdJwtVc.kbJwt.payload.nonce !== keyBinding.nonce) {\n            throw new SdJwtVcError('The key binding JWT does not contain the expected nonce')\n          }\n        }\n      } catch (error) {\n        return {\n          error,\n          isValid: false,\n          sdJwtVc: returnSdJwtVc,\n        }\n      }\n\n      if (fetchTypeMetadata) {\n        // We allow vct without type metadata for now (and don't fail if the retrieval fails)\n        // Integrity check must pass though.\n        const resolvedTypeMetadata = await this.fetchTypeMetadata(agentContext, returnSdJwtVc, {\n          throwErrorOnFetchError: false,\n          throwErrorOnUnsupportedVctValue: false,\n        })\n\n        returnSdJwtVc.typeMetadata = resolvedTypeMetadata?.mergedTypeMetadata\n        typeMetadataChain = resolvedTypeMetadata?.typeMetadataChain\n      }\n    } catch (error) {\n      return {\n        isValid: false,\n        error,\n        sdJwtVc: returnSdJwtVc,\n      }\n    }\n\n    return {\n      isValid: true,\n      sdJwtVc: returnSdJwtVc,\n      typeMetadataChain,\n    }\n  }\n\n  /**\n   * Resolve the type metadata for an SD-JWT instance.\n   *\n   * This method resolves the `vct` value, and any `extends` values.\n   */\n  public async fetchTypeMetadata(\n    agentContext: AgentContext,\n    sdJwtVc: SdJwtVc,\n    {\n      throwErrorOnFetchError = true,\n      throwErrorOnUnsupportedVctValue = true,\n    }: { throwErrorOnFetchError?: boolean; throwErrorOnUnsupportedVctValue?: boolean } = {}\n  ) {\n    const sdjwt = new SDJwtVcInstance({\n      ...this.getBaseSdJwtConfig(agentContext),\n      vctFetcher: this.getVctFetcher(agentContext, {\n        baseVct: sdJwtVc.payload.vct,\n        throwErrorOnFetchError,\n        throwErrorOnUnsupportedVctValue,\n      }),\n    })\n\n    const typeMetadata = await sdjwt.getVct(sdJwtVc.compact)\n    return typeMetadata\n  }\n\n  public async store(agentContext: AgentContext, options: SdJwtVcStoreOptions) {\n    await this.sdJwtVcRepository.save(agentContext, options.record)\n    return options.record\n  }\n\n  public async getById(agentContext: AgentContext, id: string): Promise<SdJwtVcRecord> {\n    return await this.sdJwtVcRepository.getById(agentContext, id)\n  }\n\n  public async getAll(agentContext: AgentContext): Promise<Array<SdJwtVcRecord>> {\n    return await this.sdJwtVcRepository.getAll(agentContext)\n  }\n\n  public async findByQuery(\n    agentContext: AgentContext,\n    query: Query<SdJwtVcRecord>,\n    queryOptions?: QueryOptions\n  ): Promise<Array<SdJwtVcRecord>> {\n    return await this.sdJwtVcRepository.findByQuery(agentContext, query, queryOptions)\n  }\n\n  public async deleteById(agentContext: AgentContext, id: string) {\n    await this.sdJwtVcRepository.deleteById(agentContext, id)\n  }\n\n  public async update(agentContext: AgentContext, sdJwtVcRecord: SdJwtVcRecord) {\n    await this.sdJwtVcRepository.update(agentContext, sdJwtVcRecord)\n  }\n\n  private async extractKeyFromIssuer(agentContext: AgentContext, issuer: SdJwtVcIssuer, forSigning = false) {\n    if (issuer.method === 'did') {\n      const parsedDid = parseDid(issuer.didUrl)\n      if (!parsedDid.fragment) {\n        throw new SdJwtVcError(\n          `didUrl '${issuer.didUrl}' does not contain a '#'. Unable to derive key from did document`\n        )\n      }\n\n      let publicJwk: PublicJwk\n      if (forSigning) {\n        publicJwk = await resolveSigningPublicJwkFromDidUrl(agentContext, issuer.didUrl)\n      } else {\n        const { verificationMethod } = await resolveDidUrl(agentContext, issuer.didUrl)\n        publicJwk = getPublicJwkFromVerificationMethod(verificationMethod)\n      }\n\n      const supportedSignatureAlgorithms = publicJwk.supportedSignatureAlgorithms\n      if (supportedSignatureAlgorithms.length === 0) {\n        throw new SdJwtVcError(\n          `No supported JWA signature algorithms found for key ${publicJwk.jwkTypeHumanDescription}`\n        )\n      }\n      const alg = supportedSignatureAlgorithms[0]\n\n      return {\n        alg,\n        publicJwk,\n        iss: parsedDid.did,\n        kid: `#${parsedDid.fragment}`,\n      }\n    }\n\n    if (issuer.method === 'x5c') {\n      const leafCertificate = issuer.x5c[0]\n      if (!leafCertificate) {\n        throw new SdJwtVcError(\"Empty 'x5c' array provided\")\n      }\n\n      if (forSigning && !leafCertificate.publicJwk.hasKeyId) {\n        throw new SdJwtVcError(\"Expected leaf certificate in 'x5c' array to have a key id configured.\")\n      }\n\n      const publicJwk = leafCertificate.publicJwk\n      const supportedSignatureAlgorithms = publicJwk.supportedSignatureAlgorithms\n      if (supportedSignatureAlgorithms.length === 0) {\n        throw new SdJwtVcError(\n          `No supported JWA signature algorithms found for key ${publicJwk.jwkTypeHumanDescription}`\n        )\n      }\n      const alg = supportedSignatureAlgorithms[0]\n\n      this.assertValidX5cJwtIssuer(agentContext, issuer.issuer, leafCertificate)\n\n      return {\n        publicJwk,\n        iss: issuer.issuer,\n        x5c: issuer.x5c,\n        alg,\n      }\n    }\n\n    throw new SdJwtVcError(\"Unsupported credential issuer. Only 'did' and 'x5c' is supported at the moment.\")\n  }\n\n  private async parseIssuerFromCredential<Header extends SdJwtVcHeader, Payload extends SdJwtVcPayload>(\n    agentContext: AgentContext,\n    sdJwtVc: SDJwt<Header, Payload>,\n    credoSdJwtVc: SdJwtVc<Header, Payload>,\n    _trustedCertificates?: EncodedX509Certificate[]\n  ): Promise<SdJwtVcIssuer> {\n    const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n    if (!sdJwtVc.jwt?.payload) {\n      throw new SdJwtVcError('Credential not exist')\n    }\n\n    const iss = sdJwtVc.jwt.payload.iss as string | undefined\n\n    if (sdJwtVc.jwt.header?.x5c) {\n      if (!Array.isArray(sdJwtVc.jwt.header.x5c)) {\n        throw new SdJwtVcError('Invalid x5c header in credential. Not an array.')\n      }\n      if (sdJwtVc.jwt.header.x5c.length === 0) {\n        throw new SdJwtVcError('Invalid x5c header in credential. Empty array.')\n      }\n      if (sdJwtVc.jwt.header.x5c.some((x5c) => typeof x5c !== 'string')) {\n        throw new SdJwtVcError('Invalid x5c header in credential. Not an array of strings.')\n      }\n\n      let trustedCertificates = _trustedCertificates\n      const certificateChain = sdJwtVc.jwt.header.x5c.map((cert) => X509Certificate.fromEncodedCertificate(cert))\n\n      if (!trustedCertificates) {\n        trustedCertificates =\n          (await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n            certificateChain,\n            verification: {\n              type: 'credential',\n              credential: credoSdJwtVc,\n            },\n          })) ?? x509Config.trustedCertificates\n      }\n\n      if (!trustedCertificates) {\n        throw new SdJwtVcError(\n          'No trusted certificates configured for X509 certificate chain validation. Issuer cannot be verified.'\n        )\n      }\n\n      await X509Service.validateCertificateChain(agentContext, {\n        certificateChain: sdJwtVc.jwt.header.x5c,\n        trustedCertificates,\n      })\n\n      return {\n        method: 'x5c',\n        x5c: certificateChain,\n        issuer: iss,\n      }\n    }\n\n    if (iss?.startsWith('did:')) {\n      // If `did` is used, we require a relative KID to be present to identify\n      // the key used by issuer to sign the sd-jwt-vc\n\n      if (!sdJwtVc.jwt?.header) {\n        throw new SdJwtVcError('Credential does not contain a header')\n      }\n\n      if (!sdJwtVc.jwt.header.kid) {\n        throw new SdJwtVcError('Credential does not contain a kid in the header')\n      }\n\n      const issuerKid = sdJwtVc.jwt.header.kid as string\n\n      let didUrl: string\n      if (issuerKid.startsWith('#')) {\n        didUrl = `${iss}${issuerKid}`\n      } else if (issuerKid.startsWith('did:')) {\n        const didFromKid = parseDid(issuerKid)\n        if (didFromKid.did !== iss) {\n          throw new SdJwtVcError(\n            `kid in header is an absolute DID URL, but the did (${didFromKid.did}) does not match with the 'iss' did (${iss})`\n          )\n        }\n\n        didUrl = issuerKid\n      } else {\n        throw new SdJwtVcError(\n          'Invalid issuer kid for did. Only absolute or relative (starting with #) did urls are supported.'\n        )\n      }\n\n      return {\n        method: 'did',\n        didUrl,\n      }\n    }\n\n    throw new SdJwtVcError('Unsupported signing method for SD-JWT VC. Only did and x5c are supported at the moment.')\n  }\n\n  private getBaseSdJwtConfig(agentContext: AgentContext): SdJwtVcConfig {\n    const kms = agentContext.resolve(KeyManagementApi)\n\n    return {\n      hasher: sdJwtVcHasher,\n      statusListFetcher: this.getStatusListFetcher(agentContext),\n      saltGenerator: (length) => TypedArrayEncoder.toBase64Url(kms.randomBytes({ length })).slice(0, length),\n    }\n  }\n\n  private getStatusListFetcher(agentContext: AgentContext) {\n    return async (uri: string) => {\n      const response = await fetchWithTimeout(agentContext.config.agentDependencies.fetch, uri, {\n        headers: {\n          Accept: 'application/statuslist+jwt',\n        },\n      })\n\n      if (!response.ok) {\n        throw new CredoError(\n          `Received invalid response with status ${\n            response.status\n          } when fetching status list from ${uri}. ${await response.text()}`\n        )\n      }\n\n      return await response.text()\n    }\n  }\n\n  private getVctFetcher(\n    agentContext: AgentContext,\n    {\n      baseVct,\n      throwErrorOnFetchError = true,\n      throwErrorOnUnsupportedVctValue = true,\n    }: { baseVct: string; throwErrorOnFetchError?: boolean; throwErrorOnUnsupportedVctValue?: boolean }\n  ): VcTFetcher {\n    const sdJwtVcConfig = agentContext.dependencyManager.resolve(SdJwtVcModuleConfig)\n    return async (uri: string, integrity) => {\n      if (sdJwtVcConfig.customTypeMetadataResolver) {\n        const customTypeMetadata = await sdJwtVcConfig.customTypeMetadataResolver(uri, integrity, {\n          isExtendedVct: uri !== baseVct,\n          defaultResolver: (userOverrideOptions) =>\n            this.httpsTypeMetadataResolver(agentContext, uri, integrity, {\n              throwErrorOnFetchError: userOverrideOptions.throwErrorOnFetchError ?? throwErrorOnFetchError,\n              throwErrorOnUnsupportedVctValue:\n                userOverrideOptions.throwErrorOnUnsupportedVctValue ?? throwErrorOnUnsupportedVctValue,\n              isExtendedVct: uri !== baseVct,\n            }),\n        })\n\n        return customTypeMetadata as SdJwtVcTypeMetadata | undefined\n      }\n\n      if (!uri.startsWith('https://')) {\n        if (!throwErrorOnUnsupportedVctValue) return undefined\n        throw new SdJwtVcError(\n          `Unable to resolve type metadata for vct '${uri}'. Only https supported and no 'customTypeMetadataResolver' provided in agent config.`\n        )\n      }\n\n      const defaultTypeMetadata = await this.httpsTypeMetadataResolver(agentContext, uri, integrity, {\n        throwErrorOnFetchError,\n        throwErrorOnUnsupportedVctValue,\n        isExtendedVct: uri !== baseVct,\n      })\n      return defaultTypeMetadata as SdJwtVcTypeMetadata | undefined\n    }\n  }\n\n  private async httpsTypeMetadataResolver(\n    agentContext: AgentContext,\n    vct: string,\n    integrity: string | undefined,\n    {\n      throwErrorOnFetchError,\n      throwErrorOnUnsupportedVctValue,\n      isExtendedVct,\n    }: { throwErrorOnFetchError: boolean; throwErrorOnUnsupportedVctValue: boolean; isExtendedVct?: boolean }\n  ) {\n    if (!vct.startsWith('https://')) {\n      if (!throwErrorOnUnsupportedVctValue) return undefined\n      throw new SdJwtVcError(\n        `Unable to resolve type metadata for vct '${vct}'. Only https supported for default resolver`\n      )\n    }\n    let firstError: Error | undefined\n\n    // Fist try the new type metadata URL\n    // We add a catch, so that if e.g. the request fails due to CORS (which throws an error\n    // we will still continue trying the legacy url)\n    const firstResponse = await fetchWithTimeout(agentContext.config.agentDependencies.fetch, vct).catch((error) => {\n      firstError = error\n      return undefined\n    })\n    let response = firstResponse\n\n    // If the response is not ok, try the legacy URL (will be removed in 0.7)\n    if (!response || !response?.ok) {\n      // modify the uri based on https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-04.html#section-6.3.1\n      const vctElements = vct.split('/')\n      vctElements.splice(3, 0, '.well-known/vct')\n      const legacyVctUrl = vctElements.join('/')\n\n      response = await fetchWithTimeout(agentContext.config.agentDependencies.fetch, legacyVctUrl).catch(\n        () => undefined\n      )\n    }\n\n    if (!response?.ok) {\n      if (!throwErrorOnFetchError) return undefined\n\n      if (firstResponse) {\n        throw new SdJwtVcError(\n          `Unable to resolve type metadata vct '${vct}'. Fetch returned a non-successful ${firstResponse.status} response. ${await firstResponse.text()}.`,\n          { cause: firstError }\n        )\n      } else {\n        throw new SdJwtVcError(\n          `Unable to resolve type metadata vct '${vct}'. Fetch returned a non-successful response.`,\n          { cause: firstError }\n        )\n      }\n    }\n\n    const typeMetadata = (await response.clone().json()) as Record<string, unknown>\n    if (integrity) {\n      if (typeof integrity !== 'string') {\n        throw new SdJwtVcError(\n          `Found '${isExtendedVct ? 'extends' : 'vct'}#integrity' with value '${integrity}' but value was not of type 'string'.`\n        )\n      }\n\n      IntegrityVerifier.verifyIntegrity(new Uint8Array(await response.arrayBuffer()), integrity)\n    }\n\n    return typeMetadata\n  }\n}\n"],"mappings":"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"}