@credo-ts/core
Version:
<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1
482 lines (481 loc) • 23.7 kB
JavaScript
import { CredoError } from "../../error/CredoError.mjs";
import "../../error/index.mjs";
import { TypedArrayEncoder } from "../../utils/TypedArrayEncoder.mjs";
import { IntegrityVerifier } from "../../utils/IntegrityVerifier.mjs";
import { JsonEncoder } from "../../utils/JsonEncoder.mjs";
import { dateToSeconds, nowInSeconds } from "../../utils/timestamp.mjs";
import "../../utils/index.mjs";
import { JwtPayload } from "../../crypto/jose/jwt/JwtPayload.mjs";
import { injectable } from "../../plugins/index.mjs";
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.mjs";
import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.mjs";
import "../../agent/index.mjs";
import { PublicJwk } from "../kms/jwk/PublicJwk.mjs";
import { KeyManagementApi } from "../kms/KeyManagementApi.mjs";
import "../kms/index.mjs";
import { legacyTrustedCertificatesToTrustedIssuers } from "../x509/utils/convertLegacyTrustedCertificates.mjs";
import { X509Certificate } from "../x509/X509Certificate.mjs";
import { X509ModuleConfig } from "../x509/X509ModuleConfig.mjs";
import { fetchWithTimeout } from "../../utils/fetch.mjs";
import { X509Service } from "../x509/X509Service.mjs";
import { parseDid } from "../dids/domain/parse.mjs";
import { getPublicJwkFromVerificationMethod } from "../dids/domain/key-type/keyDidMapping.mjs";
import "../dids/index.mjs";
import { TrustedIssuerContext } from "../../agent/TrustedIssuerContext.mjs";
import "../vc/models/ClaimFormat.mjs";
import "../../crypto/index.mjs";
import { SdJwtVcError } from "./SdJwtVcError.mjs";
import { extractKeyFromHolderBinding, getSdJwtHashingAlgorithm, getSdJwtSigner, getSdJwtVerifier, parseHolderBindingFromCredential, parseIssuerFromCredential, resolveDidUrl, resolveSigningPublicJwkFromDidUrl, setJwkAlgFromJwtHeader } from "./utils.mjs";
import { applyDisclosuresForPaths, applyDisclosuresForPayload } from "./disclosureFrame.mjs";
import "../vc/index.mjs";
import "../x509/index.mjs";
import { decodeSdJwtVc, sdJwtVcHasher } from "./decodeSdJwtVc.mjs";
import { SdJwtVcRepository } from "./repository/SdJwtVcRepository.mjs";
import "./repository/index.mjs";
import { getDomainFromUrl } from "../../utils/domain.mjs";
import { SdJwtVcModuleConfig } from "./SdJwtVcModuleConfig.mjs";
import { SDJwtVcInstance } from "@sd-jwt/sd-jwt-vc";
//#region src/modules/sd-jwt-vc/SdJwtVcService.ts
let SdJwtVcService = class SdJwtVcService {
constructor(sdJwtVcRepository) {
this.sdJwtVcRepository = sdJwtVcRepository;
}
async sign(agentContext, options) {
const { payload, disclosureFrame, hashingAlgorithm } = options;
const issuer = await this.extractKeyFromIssuer(agentContext, options.issuer, true);
const holderBinding = options.holder ? await extractKeyFromHolderBinding(agentContext, options.holder) : void 0;
const header = {
alg: issuer.alg,
typ: options.headerType ?? "dc+sd-jwt",
kid: issuer.kid,
x5c: issuer.x5c?.map((cert) => cert.toString("base64"))
};
issuer.publicJwk.alg = issuer.alg;
const sdJwt = new SDJwtVcInstance({
...this.getBaseSdJwtConfig(agentContext),
signer: getSdJwtSigner(agentContext, issuer.publicJwk),
hashAlg: getSdJwtHashingAlgorithm(hashingAlgorithm),
signAlg: issuer.alg
});
if (!payload.vct || typeof payload.vct !== "string") throw new SdJwtVcError("Missing required parameter 'vct'");
const { iat: payloadIat, ...payloadWithoutIat } = payload;
const compact = await sdJwt.issue({
...payloadWithoutIat,
cnf: holderBinding?.cnf,
iss: issuer.iss,
...payloadIat === null ? {} : { iat: payloadIat ?? nowInSeconds() },
vct: payload.vct
}, disclosureFrame, { header });
const prettyClaims = await sdJwt.getClaims(compact);
const sdJwtPayload = (await sdJwt.decode(compact)).jwt?.payload;
if (!sdJwtPayload) throw new SdJwtVcError("Invalid sd-jwt-vc state.");
return {
compact,
prettyClaims,
header,
issuer: options.issuer,
holder: options.holder,
payload: sdJwtPayload,
claimFormat: "dc+sd-jwt",
encoded: compact
};
}
fromCompact(compactSdJwtVc, typeMetadata) {
return decodeSdJwtVc(compactSdJwtVc, typeMetadata);
}
/**
* @deprecated use `applyDisclosuresForPaths` instead
*/
applyDisclosuresForPayload(compactSdJwtVc, requestedPayload) {
const sdJwt = applyDisclosuresForPayload(compactSdJwtVc, requestedPayload);
return decodeSdJwtVc(sdJwt);
}
applyDisclosuresForPaths(compactSdJwtVc, disclosedPaths) {
const { compact } = applyDisclosuresForPaths(compactSdJwtVc, disclosedPaths);
return decodeSdJwtVc(compact);
}
async present(agentContext, { sdJwtVc, presentationFrame, verifierMetadata, additionalPayload }) {
const sdjwt = new SDJwtVcInstance(this.getBaseSdJwtConfig(agentContext));
const compactSdJwtVc = typeof sdJwtVc === "string" ? sdJwtVc : sdJwtVc.compact;
const sdJwtVcInstance = await sdjwt.decode(compactSdJwtVc);
const holderBinding = parseHolderBindingFromCredential(sdJwtVcInstance.jwt?.payload);
if (!holderBinding && verifierMetadata) throw new SdJwtVcError("Verifier metadata provided, but credential has no 'cnf' claim to create a KB-JWT from");
const holder = holderBinding ? await extractKeyFromHolderBinding(agentContext, holderBinding, {
forSigning: true,
jwkKeyId: typeof sdJwtVc !== "string" ? sdJwtVc.kmsKeyId : void 0
}) : void 0;
if (holder) holder.publicJwk.alg = holder.alg;
sdjwt.config({
kbSigner: holder ? getSdJwtSigner(agentContext, holder.publicJwk) : void 0,
kbSignAlg: holder?.alg
});
return await sdjwt.present(compactSdJwtVc, presentationFrame, { kb: verifierMetadata ? { payload: {
iat: verifierMetadata.issuedAt,
nonce: verifierMetadata.nonce,
aud: verifierMetadata.audience,
...additionalPayload
} } : void 0 });
}
assertValidX5cJwtIssuer(agentContext, iss, leafCertificate) {
if (!iss) return;
if (!iss.startsWith("https://") && !(iss.startsWith("http://") && agentContext.config.allowInsecureHttpUrls)) throw new SdJwtVcError("The X509 certificate issuer must be a HTTPS URI.");
if (!leafCertificate.sanUriNames?.includes(iss) && !leafCertificate.sanDnsNames?.includes(getDomainFromUrl(iss))) throw new SdJwtVcError(`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`);
}
async verify(agentContext, { compactSdJwtVc, keyBinding, requiredClaimKeys, fetchTypeMetadata, trustedCertificates, trustedIssuers: _trustedIssuers, disableStatusValidation, verifyCredentialStatus, now }) {
const sdjwt = new SDJwtVcInstance({
...this.getBaseSdJwtConfig(agentContext),
loadTypeMetadataFormat: false
});
let sdJwtVc;
let holderBinding;
let issuer;
let trustedIssuers = _trustedIssuers;
if (trustedCertificates) trustedIssuers = [...trustedIssuers ?? [], ...legacyTrustedCertificatesToTrustedIssuers(trustedCertificates)];
try {
sdJwtVc = await sdjwt.decode(compactSdJwtVc);
if (!sdJwtVc.jwt) throw new CredoError("Invalid sd-jwt-vc");
holderBinding = parseHolderBindingFromCredential(sdJwtVc.jwt.payload) ?? void 0;
issuer = parseIssuerFromCredential(sdJwtVc.jwt.header, sdJwtVc.jwt.payload);
} catch (error) {
return {
isValid: false,
error
};
}
const returnSdJwtVc = {
payload: sdJwtVc.jwt.payload,
header: sdJwtVc.jwt.header,
compact: compactSdJwtVc,
prettyClaims: await sdJwtVc.getClaims(sdJwtVcHasher),
holder: holderBinding,
issuer,
kbJwt: sdJwtVc.kbJwt ? {
payload: sdJwtVc.kbJwt.payload,
header: sdJwtVc.kbJwt.header
} : void 0,
claimFormat: "dc+sd-jwt",
encoded: compactSdJwtVc
};
let typeMetadataChain;
try {
const { trustedIssuer } = await this.verifyIssuer(agentContext, returnSdJwtVc, trustedIssuers);
const issuerWithKey = await this.extractKeyFromIssuer(agentContext, issuer);
const holder = returnSdJwtVc.holder ? await extractKeyFromHolderBinding(agentContext, returnSdJwtVc.holder) : void 0;
const statusValidationDisabled = disableStatusValidation === true || verifyCredentialStatus === false;
setJwkAlgFromJwtHeader(issuerWithKey.publicJwk, sdJwtVc.jwt.header?.alg);
if (holder && sdJwtVc.kbJwt) setJwkAlgFromJwtHeader(holder.publicJwk, sdJwtVc.kbJwt.header?.alg);
sdjwt.config({
verifier: getSdJwtVerifier(agentContext, issuerWithKey.publicJwk),
kbVerifier: holder ? getSdJwtVerifier(agentContext, holder.publicJwk) : void 0,
statusVerifier: this.getStatusVerifier(agentContext, {
matchedTrustedIssuer: trustedIssuer,
credentialIssuerKey: issuerWithKey.publicJwk,
credentialIssuerCertificateChain: issuer.method === "x5c" ? issuer.x5c : void 0
})
});
try {
await sdjwt.verify(compactSdJwtVc, {
requiredClaimKeys: requiredClaimKeys ? [...requiredClaimKeys, "vct"] : ["vct"],
keyBindingNonce: keyBinding?.nonce,
currentDate: dateToSeconds(now ?? /* @__PURE__ */ new Date()),
skewSeconds: agentContext.config.validitySkewSeconds,
disableStatusVerification: statusValidationDisabled
});
} catch (error) {
return {
error,
isValid: false,
sdJwtVc: returnSdJwtVc
};
}
if (sdJwtVc.jwt.header?.typ !== "vc+sd-jwt" && sdJwtVc.jwt.header?.typ !== "dc+sd-jwt") return {
error: new SdJwtVcError(`SD-JWT VC header 'typ' must be 'dc+sd-jwt' or 'vc+sd-jwt'`),
isValid: false,
sdJwtVc: returnSdJwtVc
};
try {
JwtPayload.fromJson(returnSdJwtVc.payload).validate({
now: dateToSeconds(now ?? /* @__PURE__ */ new Date()),
skewSeconds: agentContext.config.validitySkewSeconds
});
} catch (error) {
return {
error,
isValid: false,
sdJwtVc: returnSdJwtVc
};
}
try {
if (keyBinding) {
if (!sdJwtVc.kbJwt?.payload) throw new SdJwtVcError("Keybinding is required for verification of the sd-jwt-vc");
if (sdJwtVc.kbJwt.payload.aud !== keyBinding.audience) throw new SdJwtVcError("The key binding JWT does not contain the expected audience");
if (sdJwtVc.kbJwt.payload.nonce !== keyBinding.nonce) throw new SdJwtVcError("The key binding JWT does not contain the expected nonce");
}
} catch (error) {
return {
error,
isValid: false,
sdJwtVc: returnSdJwtVc
};
}
if (fetchTypeMetadata) {
const resolvedTypeMetadata = await this.fetchTypeMetadata(agentContext, returnSdJwtVc, {
throwErrorOnFetchError: false,
throwErrorOnUnsupportedVctValue: false
});
returnSdJwtVc.typeMetadata = resolvedTypeMetadata?.mergedTypeMetadata;
typeMetadataChain = resolvedTypeMetadata?.typeMetadataChain;
}
} catch (error) {
return {
isValid: false,
error,
sdJwtVc: returnSdJwtVc
};
}
return {
isValid: true,
sdJwtVc: returnSdJwtVc,
typeMetadataChain
};
}
/**
* Resolve the type metadata for an SD-JWT instance.
*
* This method resolves the `vct` value, and any `extends` values.
*/
async fetchTypeMetadata(agentContext, sdJwtVc, { throwErrorOnFetchError = true, throwErrorOnUnsupportedVctValue = true } = {}) {
return await new SDJwtVcInstance({
...this.getBaseSdJwtConfig(agentContext),
vctFetcher: this.getVctFetcher(agentContext, {
baseVct: sdJwtVc.payload.vct,
throwErrorOnFetchError,
throwErrorOnUnsupportedVctValue
})
}).getVct(sdJwtVc.compact);
}
async store(agentContext, options) {
await this.sdJwtVcRepository.save(agentContext, options.record);
return options.record;
}
async getById(agentContext, id) {
return await this.sdJwtVcRepository.getById(agentContext, id);
}
async getAll(agentContext) {
return await this.sdJwtVcRepository.getAll(agentContext);
}
async findByQuery(agentContext, query, queryOptions) {
return await this.sdJwtVcRepository.findByQuery(agentContext, query, queryOptions);
}
async deleteById(agentContext, id) {
await this.sdJwtVcRepository.deleteById(agentContext, id);
}
async update(agentContext, sdJwtVcRecord) {
await this.sdJwtVcRepository.update(agentContext, sdJwtVcRecord);
}
async extractKeyFromIssuer(agentContext, issuer, forSigning = false) {
if (issuer.method === "did") {
const parsedDid = parseDid(issuer.didUrl);
if (!parsedDid.fragment) throw new SdJwtVcError(`didUrl '${issuer.didUrl}' does not contain a '#'. Unable to derive key from did document`);
let publicJwk;
if (forSigning) publicJwk = await resolveSigningPublicJwkFromDidUrl(agentContext, issuer.didUrl);
else {
const { verificationMethod } = await resolveDidUrl(agentContext, issuer.didUrl);
publicJwk = getPublicJwkFromVerificationMethod(verificationMethod);
}
const supportedSignatureAlgorithms = publicJwk.supportedSignatureAlgorithms;
if (supportedSignatureAlgorithms.length === 0) throw new SdJwtVcError(`No supported JWA signature algorithms found for key ${publicJwk.jwkTypeHumanDescription}`);
return {
alg: supportedSignatureAlgorithms[0],
publicJwk,
iss: parsedDid.did,
kid: `#${parsedDid.fragment}`
};
}
if (issuer.method === "x5c") {
const leafCertificate = issuer.x5c[0];
if (!leafCertificate) throw new SdJwtVcError("Empty 'x5c' array provided");
if (forSigning && !leafCertificate.publicJwk.hasKeyId) throw new SdJwtVcError("Expected leaf certificate in 'x5c' array to have a key id configured.");
const publicJwk = leafCertificate.publicJwk;
const supportedSignatureAlgorithms = publicJwk.supportedSignatureAlgorithms;
if (supportedSignatureAlgorithms.length === 0) throw new SdJwtVcError(`No supported JWA signature algorithms found for key ${publicJwk.jwkTypeHumanDescription}`);
const alg = supportedSignatureAlgorithms[0];
this.assertValidX5cJwtIssuer(agentContext, issuer.issuer, leafCertificate);
return {
publicJwk,
iss: issuer.issuer,
x5c: issuer.x5c,
alg
};
}
throw new SdJwtVcError("Unsupported credential issuer. Only 'did' and 'x5c' is supported at the moment.");
}
async verifyIssuer(agentContext, sdJwtVc, trustedIssuers) {
const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig);
const issuer = sdJwtVc.issuer;
if (!issuer) throw new SdJwtVcError("Unsupported signing method for SD-JWT VC. Only did and x5c are supported at the moment.");
if (issuer.method === "x5c") {
let x509Issuers = trustedIssuers?.filter((t) => t.method === "x509");
const context = {
verification: {
type: "credential",
credential: sdJwtVc
},
signer: {
certificateChain: issuer.x5c,
method: "x509"
}
};
if (!x509Issuers) x509Issuers = (await TrustedIssuerContext.getTrustedIssuersForVerification(agentContext, context))?.trustedIssuers;
if (!x509Issuers) {
const legacyTrustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {
certificateChain: issuer.x5c,
verification: {
type: "credential",
credential: sdJwtVc
}
}) ?? x509Config.trustedCertificates;
if (legacyTrustedCertificates) x509Issuers = legacyTrustedCertificatesToTrustedIssuers(legacyTrustedCertificates);
}
if (!x509Issuers) throw new SdJwtVcError("No trusted certificates configured for X509 certificate chain validation. Issuer cannot be verified.");
return await TrustedIssuerContext.ensureTrustedSigner(agentContext, context, x509Issuers);
}
if (issuer.method === "did") return await TrustedIssuerContext.ensureTrustedSigner(agentContext, {
verification: {
type: "credential",
credential: sdJwtVc
},
signer: {
didUrl: issuer.didUrl,
method: "did"
}
}, trustedIssuers);
throw new SdJwtVcError("Unsupported signing method for SD-JWT VC. Only did and x5c are supported at the moment.");
}
getBaseSdJwtConfig(agentContext) {
const kms = agentContext.resolve(KeyManagementApi);
return {
hasher: sdJwtVcHasher,
statusListFetcher: this.getStatusListFetcher(agentContext),
saltGenerator: (length) => TypedArrayEncoder.toBase64Url(kms.randomBytes({ length })).slice(0, length)
};
}
getStatusListFetcher(agentContext) {
return async (uri) => {
const response = await fetchWithTimeout(agentContext.config.agentDependencies.fetch, uri, { headers: { Accept: "application/statuslist+jwt" } });
if (!response.ok) throw new CredoError(`Received invalid response with status ${response.status} when fetching status list from ${uri}. ${await response.text()}`);
return await response.text();
};
}
/**
* Builds a `Verifier` for the status list JWT signature, gated by the trusted issuer that was matched
* for the credential issuer (the status list signer is not always the credential issuer).
*
* The library's `Verifier` only receives the unsigned token (`<header>.<payload>`) and the signature,
* so the status list JWT's own header (`x5c`/`kid`) is recovered by decoding the first segment.
*/
getStatusVerifier(agentContext, { matchedTrustedIssuer, credentialIssuerKey, credentialIssuerCertificateChain }) {
return async (data, signatureBase64Url) => {
let header;
try {
header = JsonEncoder.fromBase64Url(data.split(".")[0]);
} catch (error) {
throw new SdJwtVcError("Unable to decode the status list JWT header to extract the status list signer.", { cause: error });
}
if (!matchedTrustedIssuer) {
const signerJwk = PublicJwk.fromUnknown(credentialIssuerKey.toJson());
setJwkAlgFromJwtHeader(signerJwk, header.alg);
return getSdJwtVerifier(agentContext, signerJwk)(data, signatureBase64Url);
}
if (matchedTrustedIssuer.method === "x509") {
if (!credentialIssuerCertificateChain) throw new SdJwtVcError("Missing credential issuer certificate chain for x509 status list verification.");
const hasDedicatedStatusCertificates = matchedTrustedIssuer.status !== void 0;
const statusCertificates = matchedTrustedIssuer.status ?? matchedTrustedIssuer.issuance;
if (!header.x5c?.length) throw new SdJwtVcError("Unable to extract the status list signer: the status list JWT has no x5c header.");
if (statusCertificates.length === 0) throw new SdJwtVcError("No trusted status list certificates configured for the trusted issuer. The status list signer cannot be verified.");
try {
await X509Service.validateCertificateChain(agentContext, {
certificateChain: header.x5c,
trustedCertificates: statusCertificates
});
} catch (error) {
throw new SdJwtVcError("The status list certificate chain could not be validated against the trusted status certificates.", { cause: error });
}
const statusListChain = header.x5c.map((certificate) => X509Certificate.fromEncodedCertificate(certificate));
const chainMatchesCredentialIssuer = statusListChain.length === credentialIssuerCertificateChain.length && statusListChain.every((certificate, index) => certificate.equal(credentialIssuerCertificateChain[index]));
if (!hasDedicatedStatusCertificates && !chainMatchesCredentialIssuer) throw new SdJwtVcError("The status list signer chain does not match the credential issuer chain, and no dedicated trusted status certificates were configured for the trusted issuer.");
const signerJwk = statusListChain[0].publicJwk;
setJwkAlgFromJwtHeader(signerJwk, header.alg);
return getSdJwtVerifier(agentContext, signerJwk)(data, signatureBase64Url);
}
let statusListIssuerDid;
try {
statusListIssuerDid = JsonEncoder.fromBase64Url(data.split(".")[1]).iss;
} catch (error) {
throw new SdJwtVcError("Unable to decode the status list JWT payload to extract the status list signer.", { cause: error });
}
if (typeof statusListIssuerDid !== "string") throw new SdJwtVcError("Unable to extract the status list signer: the status list JWT payload has no `iss`.");
if (parseDid(statusListIssuerDid).did !== parseDid(matchedTrustedIssuer.issuance).did) throw new SdJwtVcError(`The status list signer did '${parseDid(statusListIssuerDid).did}' does not match the trusted issuer did.`);
const didUrl = header.kid?.startsWith("#") ? `${statusListIssuerDid}${header.kid}` : header.kid;
if (!didUrl) throw new SdJwtVcError("Unable to resolve the status list signer: the status list JWT has no `kid` header.");
const { verificationMethod } = await resolveDidUrl(agentContext, didUrl);
const publicJwk = getPublicJwkFromVerificationMethod(verificationMethod);
setJwkAlgFromJwtHeader(publicJwk, header.alg);
return getSdJwtVerifier(agentContext, publicJwk)(data, signatureBase64Url);
};
}
getVctFetcher(agentContext, { baseVct, throwErrorOnFetchError = true, throwErrorOnUnsupportedVctValue = true }) {
const sdJwtVcConfig = agentContext.dependencyManager.resolve(SdJwtVcModuleConfig);
return async (uri, integrity) => {
if (sdJwtVcConfig.customTypeMetadataResolver) return await sdJwtVcConfig.customTypeMetadataResolver(uri, integrity, {
isExtendedVct: uri !== baseVct,
defaultResolver: (userOverrideOptions) => this.httpsTypeMetadataResolver(agentContext, uri, integrity, {
throwErrorOnFetchError: userOverrideOptions.throwErrorOnFetchError ?? throwErrorOnFetchError,
throwErrorOnUnsupportedVctValue: userOverrideOptions.throwErrorOnUnsupportedVctValue ?? throwErrorOnUnsupportedVctValue,
isExtendedVct: uri !== baseVct
})
});
if (!uri.startsWith("https://")) {
if (!throwErrorOnUnsupportedVctValue) return void 0;
throw new SdJwtVcError(`Unable to resolve type metadata for vct '${uri}'. Only https supported and no 'customTypeMetadataResolver' provided in agent config.`);
}
return await this.httpsTypeMetadataResolver(agentContext, uri, integrity, {
throwErrorOnFetchError,
throwErrorOnUnsupportedVctValue,
isExtendedVct: uri !== baseVct
});
};
}
async httpsTypeMetadataResolver(agentContext, vct, integrity, { throwErrorOnFetchError, throwErrorOnUnsupportedVctValue, isExtendedVct }) {
if (!vct.startsWith("https://")) {
if (!throwErrorOnUnsupportedVctValue) return void 0;
throw new SdJwtVcError(`Unable to resolve type metadata for vct '${vct}'. Only https supported for default resolver`);
}
let firstError;
const firstResponse = await fetchWithTimeout(agentContext.config.agentDependencies.fetch, vct).catch((error) => {
firstError = error;
});
let response = firstResponse;
if (!response?.ok) {
const vctElements = vct.split("/");
vctElements.splice(3, 0, ".well-known/vct");
const legacyVctUrl = vctElements.join("/");
response = await fetchWithTimeout(agentContext.config.agentDependencies.fetch, legacyVctUrl).catch(() => void 0);
}
if (!response?.ok) {
if (!throwErrorOnFetchError) return void 0;
if (firstResponse) throw new SdJwtVcError(`Unable to resolve type metadata vct '${vct}'. Fetch returned a non-successful ${firstResponse.status} response. ${await firstResponse.text()}.`, { cause: firstError });
else throw new SdJwtVcError(`Unable to resolve type metadata vct '${vct}'. Fetch returned a non-successful response.`, { cause: firstError });
}
const typeMetadata = await response.clone().json();
if (integrity) {
if (typeof integrity !== "string") throw new SdJwtVcError(`Found '${isExtendedVct ? "extends" : "vct"}#integrity' with value '${integrity}' but value was not of type 'string'.`);
IntegrityVerifier.verifyIntegrity(new Uint8Array(await response.arrayBuffer()), integrity);
}
return typeMetadata;
}
};
SdJwtVcService = __decorate([injectable(), __decorateMetadata("design:paramtypes", [typeof SdJwtVcRepository === "undefined" ? Object : SdJwtVcRepository])], SdJwtVcService);
//#endregion
export { SdJwtVcService };
//# sourceMappingURL=SdJwtVcService.mjs.map