

import { CredoError } from "../../../error/CredoError.mjs";
import "../../../error/index.mjs";
import { injectable } from "../../../plugins/index.mjs";
import { __decorateMetadata } from "../../../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorateMetadata.mjs";
import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.mjs";
import { asArray } from "../../../utils/array.mjs";
import { JsonTransformer } from "../../../utils/JsonTransformer.mjs";
import "../../../utils/index.mjs";
import "../../kms/index.mjs";
import { parseDid } from "../../dids/domain/parse.mjs";
import { VerificationMethod } from "../../dids/domain/verificationMethod/VerificationMethod.mjs";
import { getPublicJwkFromVerificationMethod } from "../../dids/domain/key-type/keyDidMapping.mjs";
import "../../dids/domain/key-type/index.mjs";
import { DidsApi } from "../../dids/DidsApi.mjs";
import "../../dids/index.mjs";
import jsonld_default from "./libraries/jsonld.mjs";
import { W3cJsonLdVerifiableCredential } from "./models/W3cJsonLdVerifiableCredential.mjs";
import { assertOnlyW3cJsonLdVerifiableCredentials } from "./jsonldUtil.mjs";
import vc_default from "./libraries/vc.mjs";
import { w3cDate } from "../util.mjs";
import { W3cJsonLdVerifiablePresentation } from "./models/W3cJsonLdVerifiablePresentation.mjs";
import "./models/index.mjs";
import { SignatureSuiteRegistry } from "./SignatureSuiteRegistry.mjs";
import { createKmsKeyPairClass } from "../../../crypto/KmsKeyPair.mjs";
import { W3cCredentialsModuleConfig } from "../W3cCredentialsModuleConfig.mjs";

//#region src/modules/vc/data-integrity/W3cJsonLdCredentialService.ts
var _ref, _ref2;
let W3cJsonLdCredentialService = class W3cJsonLdCredentialService$1 {
	constructor(signatureSuiteRegistry, w3cCredentialsModuleConfig) {
		this.signatureSuiteRegistry = signatureSuiteRegistry;
		this.w3cCredentialsModuleConfig = w3cCredentialsModuleConfig;
	}
	/**
	* Signs a credential
	*/
	async signCredential(agentContext, options) {
		const WalletKeyPair = createKmsKeyPairClass(agentContext);
		const signingKey = await this.getPublicJwkFromVerificationMethod(agentContext, options.verificationMethod);
		const suiteInfo = this.signatureSuiteRegistry.getByProofType(options.proofType);
		if (!this.signatureSuiteRegistry.getAllByPublicJwkType(signingKey).some(({ suiteClass }) => suiteClass === suiteInfo.suiteClass)) throw new CredoError("The key type of the verification method does not match the suite");
		const keyPair = new WalletKeyPair({
			controller: options.credential.issuerId,
			id: options.verificationMethod,
			publicJwk: signingKey
		});
		const SuiteClass = suiteInfo.suiteClass;
		const suite = new SuiteClass({
			key: keyPair,
			LDKeyClass: WalletKeyPair,
			proof: { verificationMethod: options.verificationMethod },
			useNativeCanonize: false,
			date: options.created ?? w3cDate()
		});
		try {
			const result = await vc_default.issue({
				credential: JsonTransformer.toJSON(options.credential),
				suite,
				purpose: options.proofPurpose,
				documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext)
			});
			return JsonTransformer.fromJSON(result, W3cJsonLdVerifiableCredential);
		} catch (error) {
			throw new CredoError(`Error issuing W3C JSON-LD VC. ${error.message}`, { cause: error });
		}
	}
	/**
	* Verifies the signature(s) of a credential
	*
	* @param credential the credential to be verified
	* @returns the verification result
	*/
	async verifyCredential(agentContext, options) {
		try {
			const verifyCredentialStatus = options.verifyCredentialStatus ?? true;
			const suites = this.getSignatureSuitesForCredential(agentContext, options.credential);
			const verifyOptions = {
				credential: JsonTransformer.toJSON(options.credential),
				suite: suites,
				documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext),
				checkStatus: ({ credential }) => {
					if (verifyCredentialStatus && "credentialStatus" in credential) throw new CredoError("Verifying credential status for JSON-LD credentials is currently not supported");
					return { verified: true };
				}
			};
			if (options.proofPurpose) verifyOptions.purpose = options.proofPurpose;
			const result = await vc_default.verifyCredential(verifyOptions);
			const { verified: isValid,...remainingResult } = result;
			if (!isValid) agentContext.config.logger.debug(`Credential verification failed: ${result.error?.message}`, { stack: result.error?.stack });
			return {
				isValid,
				validations: { vcJs: {
					isValid,
					...remainingResult
				} },
				error: result.error
			};
		} catch (error) {
			return {
				isValid: false,
				validations: {},
				error
			};
		}
	}
	/**
	* Signs a presentation including the credentials it includes
	*
	* @param presentation the presentation to be signed
	* @returns the signed presentation
	*/
	async signPresentation(agentContext, options) {
		const WalletKeyPair = createKmsKeyPairClass(agentContext);
		const suiteInfo = this.signatureSuiteRegistry.getByProofType(options.proofType);
		if (!suiteInfo) throw new CredoError(`The requested proofType ${options.proofType} is not supported`);
		const signingKey = await this.getPublicJwkFromVerificationMethod(agentContext, options.verificationMethod);
		if (!this.signatureSuiteRegistry.getAllByPublicJwkType(signingKey).some(({ suiteClass }) => suiteClass === suiteInfo.suiteClass)) throw new CredoError("The key type of the verification method does not match the suite");
		const verificationMethodObject = (await this.w3cCredentialsModuleConfig.documentLoader(agentContext)(options.verificationMethod)).document;
		const keyPair = new WalletKeyPair({
			controller: verificationMethodObject.controller,
			id: options.verificationMethod,
			publicJwk: signingKey
		});
		const suite = new suiteInfo.suiteClass({
			LDKeyClass: WalletKeyPair,
			proof: { verificationMethod: options.verificationMethod },
			date: (/* @__PURE__ */ new Date()).toISOString(),
			key: keyPair,
			useNativeCanonize: false
		});
		const signOptions = {
			presentation: JsonTransformer.toJSON(options.presentation),
			suite,
			challenge: options.challenge,
			domain: options.domain,
			documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext)
		};
		if (options.proofPurpose) signOptions.purpose = options.proofPurpose;
		const result = await vc_default.signPresentation(signOptions);
		return JsonTransformer.fromJSON(result, W3cJsonLdVerifiablePresentation);
	}
	/**
	* Verifies a presentation including the credentials it includes
	*
	* @param presentation the presentation to be verified
	* @returns the verification result
	*/
	async verifyPresentation(agentContext, options) {
		try {
			const WalletKeyPair = createKmsKeyPairClass(agentContext);
			let proofs = options.presentation.proof;
			if (!Array.isArray(proofs)) proofs = [proofs];
			if (options.purpose) proofs = proofs.filter((proof) => proof.proofPurpose === options.purpose.term);
			const presentationSuites = proofs.map((proof) => {
				const SuiteClass = this.signatureSuiteRegistry.getByProofType(proof.type).suiteClass;
				return new SuiteClass({
					LDKeyClass: WalletKeyPair,
					proof: { verificationMethod: proof.verificationMethod },
					date: proof.created,
					useNativeCanonize: false
				});
			});
			const credentials = asArray(options.presentation.verifiableCredential);
			assertOnlyW3cJsonLdVerifiableCredentials(credentials);
			const credentialSuites = credentials.map((credential) => this.getSignatureSuitesForCredential(agentContext, credential));
			const allSuites = presentationSuites.concat(...credentialSuites);
			const verifyOptions = {
				presentation: JsonTransformer.toJSON(options.presentation),
				suite: allSuites,
				challenge: options.challenge,
				domain: options.domain,
				documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext)
			};
			if (options.purpose) verifyOptions.presentationPurpose = options.purpose;
			const result = await vc_default.verify(verifyOptions);
			const { verified: isValid,...remainingResult } = result;
			return {
				isValid,
				validations: { vcJs: {
					isValid,
					...remainingResult
				} },
				error: result.error
			};
		} catch (error) {
			return {
				isValid: false,
				validations: {},
				error
			};
		}
	}
	getVerificationMethodTypesByProofType(proofType) {
		return this.signatureSuiteRegistry.getByProofType(proofType).verificationMethodTypes;
	}
	async getExpandedTypesForCredential(agentContext, credential) {
		const expandedTypes = (await jsonld_default.expand(JsonTransformer.toJSON(credential), { documentLoader: this.w3cCredentialsModuleConfig.documentLoader(agentContext) }))[0]["@type"];
		return asArray(expandedTypes);
	}
	async getPublicJwkFromVerificationMethod(agentContext, verificationMethod) {
		const dids = agentContext.resolve(DidsApi);
		const verificationMethodObject = await this.w3cCredentialsModuleConfig.documentLoader(agentContext)(verificationMethod);
		const verificationMethodInstance = JsonTransformer.fromJSON(verificationMethodObject.document, VerificationMethod);
		const did = parseDid(verificationMethod);
		const publicJwk = getPublicJwkFromVerificationMethod(verificationMethodInstance);
		const [didRecord] = await dids.getCreatedDids({ did: did.did });
		if (didRecord) publicJwk.keyId = didRecord.keys?.find(({ didDocumentRelativeKeyId }) => didDocumentRelativeKeyId === `#${did.fragment}`)?.kmsKeyId ?? publicJwk.legacyKeyId;
		else publicJwk.keyId = publicJwk.legacyKeyId;
		return publicJwk;
	}
	getSignatureSuitesForCredential(agentContext, credential) {
		const WalletKeyPair = createKmsKeyPairClass(agentContext);
		let proofs = credential.proof;
		if (!Array.isArray(proofs)) proofs = [proofs];
		return proofs.map((proof) => {
			const SuiteClass = this.signatureSuiteRegistry.getByProofType(proof.type)?.suiteClass;
			return new SuiteClass({
				LDKeyClass: WalletKeyPair,
				proof: { verificationMethod: proof.verificationMethod },
				date: proof.created,
				useNativeCanonize: false
			});
		});
	}
};
W3cJsonLdCredentialService = __decorate([injectable(), __decorateMetadata("design:paramtypes", [typeof (_ref = typeof SignatureSuiteRegistry !== "undefined" && SignatureSuiteRegistry) === "function" ? _ref : Object, typeof (_ref2 = typeof W3cCredentialsModuleConfig !== "undefined" && W3cCredentialsModuleConfig) === "function" ? _ref2 : Object])], W3cJsonLdCredentialService);

//#endregion
export { W3cJsonLdCredentialService };
//# sourceMappingURL=W3cJsonLdCredentialService.mjs.map