

import { CredoError } from "../../../error/CredoError.mjs";
import "../../../error/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 { TypedArrayEncoder } from "../../../utils/TypedArrayEncoder.mjs";
import { JsonTransformer } from "../../../utils/JsonTransformer.mjs";
import { IsStringOrStringArray } from "../../../utils/transformers.mjs";
import "../../../utils/index.mjs";
import { X25519PublicJwk } from "../../kms/jwk/kty/okp/X25519PublicJwk.mjs";
import { Ed25519PublicJwk } from "../../kms/jwk/kty/okp/Ed25519PublicJwk.mjs";
import { PublicJwk } from "../../kms/jwk/PublicJwk.mjs";
import "../../kms/index.mjs";
import { VerificationMethod } from "./verificationMethod/VerificationMethod.mjs";
import { IsStringOrVerificationMethod, VerificationMethodTransformer } from "./verificationMethod/VerificationMethodTransformer.mjs";
import "./verificationMethod/index.mjs";
import { getPublicJwkFromVerificationMethod } from "./key-type/keyDidMapping.mjs";
import { findMatchingEd25519Key } from "../findMatchingEd25519Key.mjs";
import "./key-type/index.mjs";
import { DidCommV1Service } from "./service/DidCommV1Service.mjs";
import { IndyAgentService } from "./service/IndyAgentService.mjs";
import { ServiceTransformer } from "./service/ServiceTransformer.mjs";
import "./service/index.mjs";
import { Expose, Type } from "class-transformer";
import { IsArray, IsOptional, IsString, ValidateNested } from "class-validator";

//#region src/modules/dids/domain/DidDocument.ts
var _ref, _ref2, _ref3, _ref4, _ref5;
var DidDocument = class DidDocument {
	constructor(options) {
		this.context = ["https://www.w3.org/ns/did/v1"];
		if (options) {
			this.context = options.context ?? this.context;
			this.id = options.id;
			this.alsoKnownAs = options.alsoKnownAs;
			this.controller = options.controller;
			this.verificationMethod = options.verificationMethod;
			this.service = options.service;
			this.authentication = options.authentication;
			this.assertionMethod = options.assertionMethod;
			this.keyAgreement = options.keyAgreement;
			this.capabilityInvocation = options.capabilityInvocation;
			this.capabilityDelegation = options.capabilityDelegation;
		}
	}
	dereferenceVerificationMethod(keyId) {
		const verificationMethod = this.verificationMethod?.find((key) => key.id.endsWith(keyId));
		if (!verificationMethod) throw new CredoError(`Unable to locate verification method with id '${keyId}'`);
		return verificationMethod;
	}
	dereferenceKey(keyId, allowedPurposes) {
		const purposes = allowedPurposes ?? [
			"authentication",
			"keyAgreement",
			"assertionMethod",
			"capabilityInvocation",
			"capabilityDelegation",
			"verificationMethod"
		];
		for (const purpose of purposes) for (const key of this[purpose] ?? []) {
			if (typeof key === "string" && key.endsWith(keyId)) return this.dereferenceVerificationMethod(key);
			if (typeof key !== "string" && key.id.endsWith(keyId)) return key;
		}
		throw new CredoError(`Unable to locate verification method with id '${keyId}' in purposes ${purposes}`);
	}
	findVerificationMethodByPublicKey(publicJwk, allowedPurposes) {
		const purposes = allowedPurposes ?? [
			"authentication",
			"keyAgreement",
			"assertionMethod",
			"capabilityInvocation",
			"capabilityDelegation",
			"verificationMethod"
		];
		for (const purpose of purposes) for (const key of this[purpose] ?? []) {
			const verificationMethod = typeof key === "string" ? this.dereferenceVerificationMethod(key) : key;
			if (getPublicJwkFromVerificationMethod(verificationMethod).equals(publicJwk)) return verificationMethod;
		}
		throw new CredoError(`Unable to locate verification method with public key ${publicJwk.jwkTypehumanDescription} in purposes ${purposes}`);
	}
	/**
	* Returns all of the service endpoints matching the given type.
	*
	* @param type The type of service(s) to query.
	*/
	getServicesByType(type) {
		return this.service?.filter((service) => service.type === type) ?? [];
	}
	/**
	* Returns all of the service endpoints matching the given class
	*
	* @param classType The class to query services.
	*/
	getServicesByClassType(classType) {
		return this.service?.filter((service) => service instanceof classType) ?? [];
	}
	/**
	* Get all DIDComm services ordered by priority descending. This means the highest
	* priority will be the first entry.
	*/
	get didCommServices() {
		const didCommServiceTypes = [IndyAgentService.type, DidCommV1Service.type];
		return (this.service?.filter((service) => didCommServiceTypes.includes(service.type)) ?? []).sort((a, b) => a.priority - b.priority);
	}
	get recipientKeys() {
		return this.getRecipientKeysWithVerificationMethod({ mapX25519ToEd25519: false }).map(({ publicJwk }) => publicJwk);
	}
	/**
	* Returns the recipient keys with their verification method matches
	*
	* We should probably deprecate recipientKeys in favour of this one
	*/
	getRecipientKeysWithVerificationMethod({ mapX25519ToEd25519 }) {
		const recipientKeys = [];
		const seenVerificationMethodIds = [];
		for (const service of this.didCommServices) if (service.type === IndyAgentService.type) for (const publicKeyBase58 of service.recipientKeys) {
			const publicJwk = PublicJwk.fromPublicKey({
				kty: "OKP",
				crv: "Ed25519",
				publicKey: TypedArrayEncoder.fromBase58(publicKeyBase58)
			});
			const verificationMethod = [...this.verificationMethod ?? [], ...this.authentication ?? []].map((v) => typeof v === "string" ? this.dereferenceVerificationMethod(v) : v).find((v) => {
				return getPublicJwkFromVerificationMethod(v).equals(publicJwk);
			});
			if (!verificationMethod) throw new CredoError("Could not find verification method for IndyAgentService recipient key");
			if (seenVerificationMethodIds.includes(verificationMethod.id)) continue;
			recipientKeys.push({
				publicJwk,
				verificationMethod
			});
		}
		else if (service.type === DidCommV1Service.type) for (const recipientKey of service.recipientKeys) {
			const verificationMethod = this.dereferenceKey(recipientKey, ["authentication", "keyAgreement"]);
			if (seenVerificationMethodIds.includes(verificationMethod.id)) continue;
			const publicJwk = getPublicJwkFromVerificationMethod(verificationMethod);
			if (!publicJwk.is(Ed25519PublicJwk, X25519PublicJwk)) throw new CredoError("Expected either Ed25519PublicJwk or X25519PublicJwk for DidcommV1Service recipient key");
			recipientKeys.push({
				publicJwk,
				verificationMethod
			});
		}
		if (!mapX25519ToEd25519) return recipientKeys;
		return recipientKeys.map(({ publicJwk, verificationMethod }) => {
			if (publicJwk.is(Ed25519PublicJwk)) return {
				publicJwk,
				verificationMethod
			};
			const matchingEd25519Key = findMatchingEd25519Key(publicJwk, this);
			if (!matchingEd25519Key) throw new CredoError(`Unable to find matching Ed25519 key for X25519 verification method with id ${verificationMethod.id}`);
			return matchingEd25519Key;
		});
	}
	toJSON() {
		return JsonTransformer.toJSON(this);
	}
	static fromJSON(didDocument) {
		return JsonTransformer.fromJSON(didDocument, DidDocument);
	}
};
__decorate([
	Expose({ name: "@context" }),
	IsStringOrStringArray(),
	__decorateMetadata("design:type", Object)
], DidDocument.prototype, "context", void 0);
__decorate([IsString(), __decorateMetadata("design:type", String)], DidDocument.prototype, "id", void 0);
__decorate([
	IsArray(),
	IsString({ each: true }),
	IsOptional(),
	__decorateMetadata("design:type", Array)
], DidDocument.prototype, "alsoKnownAs", void 0);
__decorate([
	IsStringOrStringArray(),
	IsOptional(),
	__decorateMetadata("design:type", Object)
], DidDocument.prototype, "controller", void 0);
__decorate([
	IsArray(),
	ValidateNested({ each: true }),
	Type(() => VerificationMethod),
	IsOptional(),
	__decorateMetadata("design:type", Array)
], DidDocument.prototype, "verificationMethod", void 0);
__decorate([
	IsArray(),
	ServiceTransformer(),
	IsOptional(),
	__decorateMetadata("design:type", Array)
], DidDocument.prototype, "service", void 0);
__decorate([
	IsArray(),
	VerificationMethodTransformer(),
	IsStringOrVerificationMethod({ each: true }),
	IsOptional(),
	__decorateMetadata("design:type", typeof (_ref = typeof Array !== "undefined" && Array) === "function" ? _ref : Object)
], DidDocument.prototype, "authentication", void 0);
__decorate([
	IsArray(),
	VerificationMethodTransformer(),
	IsStringOrVerificationMethod({ each: true }),
	IsOptional(),
	__decorateMetadata("design:type", typeof (_ref2 = typeof Array !== "undefined" && Array) === "function" ? _ref2 : Object)
], DidDocument.prototype, "assertionMethod", void 0);
__decorate([
	IsArray(),
	VerificationMethodTransformer(),
	IsStringOrVerificationMethod({ each: true }),
	IsOptional(),
	__decorateMetadata("design:type", typeof (_ref3 = typeof Array !== "undefined" && Array) === "function" ? _ref3 : Object)
], DidDocument.prototype, "keyAgreement", void 0);
__decorate([
	IsArray(),
	VerificationMethodTransformer(),
	IsStringOrVerificationMethod({ each: true }),
	IsOptional(),
	__decorateMetadata("design:type", typeof (_ref4 = typeof Array !== "undefined" && Array) === "function" ? _ref4 : Object)
], DidDocument.prototype, "capabilityInvocation", void 0);
__decorate([
	IsArray(),
	VerificationMethodTransformer(),
	IsStringOrVerificationMethod({ each: true }),
	IsOptional(),
	__decorateMetadata("design:type", typeof (_ref5 = typeof Array !== "undefined" && Array) === "function" ? _ref5 : Object)
], DidDocument.prototype, "capabilityDelegation", void 0);
/**
* Extracting the verification method for signature type
* @param type Signature type
* @param didDocument DidDocument
* @returns verification method
*/
async function findVerificationMethodByKeyType(keyType, didDocument) {
	for (const purpose of [
		"verificationMethod",
		"authentication",
		"keyAgreement",
		"assertionMethod",
		"capabilityInvocation",
		"capabilityDelegation"
	]) {
		const key = didDocument[purpose];
		if (Array.isArray(key)) {
			for (const method of key) if (typeof method !== "string") {
				if (method.type === keyType) return method;
			}
		}
	}
	return null;
}

//#endregion
export { DidDocument, findVerificationMethodByKeyType };
//# sourceMappingURL=DidDocument.mjs.map