

const require_TypedArrayEncoder = require('../../../../../utils/TypedArrayEncoder.js');
const require_MultiBaseEncoder = require('../../../../../utils/MultiBaseEncoder.js');
require('../../../../../utils/index.js');
const require_Ed25519PublicJwk = require('../../../../kms/jwk/kty/okp/Ed25519PublicJwk.js');
const require_PublicJwk = require('../../../../kms/jwk/PublicJwk.js');
require('../../../../kms/index.js');
const require_constants = require('../../../constants.js');
const require_constants$1 = require('./constants.js');
const require_jsonld = require('../../libraries/jsonld.js');
const require_jsonldUtil = require('../../jsonldUtil.js');
const require_JwsLinkedDataSignature = require('../JwsLinkedDataSignature.js');
const require_context2020 = require('./context2020.js');

//#region src/modules/vc/data-integrity/signature-suites/ed25519/Ed25519Signature2020.ts
var Ed25519Signature2020 = class extends require_JwsLinkedDataSignature.JwsLinkedDataSignature {
	/**
	* @param {object} options - Options hashmap.
	*
	* Either a `key` OR at least one of `signer`/`verifier` is required.
	*
	* @param {object} [options.key] - An optional key object (containing an
	*   `id` property, and either `signer` or `verifier`, depending on the
	*   intended operation. Useful for when the application is managing keys
	*   itself (when using a KMS, you never have access to the private key,
	*   and so should use the `signer` param instead).
	* @param {Function} [options.signer] - Signer function that returns an
	*   object with an async sign() method. This is useful when interfacing
	*   with a KMS (since you don't get access to the private key and its
	*   `signer()`, the KMS client gives you only the signer function to use).
	* @param {Function} [options.verifier] - Verifier function that returns
	*   an object with an async `verify()` method. Useful when working with a
	*   KMS-provided verifier function.
	*
	* Advanced optional parameters and overrides.
	*
	* @param {object} [options.proof] - A JSON-LD document with options to use
	*   for the `proof` node. Any other custom fields can be provided here
	*   using a context different from security-v2).
	* @param {string|Date} [options.date] - Signing date to use if not passed.
	* @param {boolean} [options.useNativeCanonize] - Whether to use a native
	*   canonize algorithm.
	*/
	constructor(options) {
		super({
			type: "Ed25519Signature2020",
			algorithm: "EdDSA",
			LDKeyClass: options.LDKeyClass,
			contextUrl: require_constants$1.ED25519_SUITE_CONTEXT_URL_2020,
			key: options.key,
			proof: options.proof,
			date: options.date,
			useNativeCanonize: options.useNativeCanonize
		});
		this.requiredKeyType = "Ed25519VerificationKey2020";
	}
	async assertVerificationMethod(document) {
		if (!_includesCompatibleContext({ document })) throw new TypeError(`The '@context' of the verification method (key) MUST contain the context url "${this.contextUrl}".`);
		if (!_isEd2020Key(document)) {
			const verificationMethodType = require_jsonld.default.getValues(document, "type")[0];
			throw new Error(`Unsupported verification method type '${verificationMethodType}'. Verification method type MUST be 'Ed25519VerificationKey2020'.`);
		}
		if (_isEd2020Key(document) && !_includesEd2020Context(document)) throw new Error(`For verification method type 'Ed25519VerificationKey2020' the '@context' MUST contain the context url "${require_constants$1.ED25519_SUITE_CONTEXT_URL_2020}".`);
		if (document.revoked !== void 0) throw new Error("The verification method has been revoked.");
	}
	async getVerificationMethod(options) {
		let verificationMethod = await super.getVerificationMethod({
			proof: options.proof,
			documentLoader: options.documentLoader
		});
		if (_isEd2020Key(verificationMethod) && _includesEd2020Context(verificationMethod)) {
			const publicJwk = require_PublicJwk.PublicJwk.fromFingerprint(verificationMethod.publicKeyMultibase);
			if (!publicJwk.is(require_Ed25519PublicJwk.Ed25519PublicJwk)) throw new Error("Expected multibase key to be of type Ed25519.");
			verificationMethod.type = "Ed25519VerificationKey2018";
			verificationMethod = {
				...verificationMethod,
				publicKeyMultibase: void 0,
				publicKeyBase58: require_TypedArrayEncoder.TypedArrayEncoder.toBase58(publicJwk.publicKey.publicKey)
			};
		}
		return verificationMethod;
	}
	/**
	* Ensures the document to be signed contains the required signature suite
	* specific `@context`, by either adding it (if `addSuiteContext` is true),
	* or throwing an error if it's missing.
	*
	* @override
	*
	* @param {object} options - Options hashmap.
	* @param {object} options.document - JSON-LD document to be signed.
	* @param {boolean} options.addSuiteContext - Add suite context?
	*/
	ensureSuiteContext(options) {
		if (_includesCompatibleContext({ document: options.document })) return;
		super.ensureSuiteContext({
			document: options.document,
			addSuiteContext: options.addSuiteContext
		});
	}
	/**
	* Checks whether a given proof exists in the document.
	*
	* @override
	*
	* @param {object} options - Options hashmap.
	* @param {object} options.proof - A proof.
	* @param {object} options.document - A JSON-LD document.
	* @param {object} options.purpose - A jsonld-signatures ProofPurpose
	*  instance (e.g. AssertionProofPurpose, AuthenticationProofPurpose, etc).
	* @param {Function} options.documentLoader  - A secure document loader (it is
	*   recommended to use one that provides static known documents, instead of
	*   fetching from the web) for returning contexts, controller documents,
	*   keys, and other relevant URLs needed for the proof.
	*
	* @returns {Promise<boolean>} Whether a match for the proof was found.
	*/
	async matchProof(options) {
		if (!_includesCompatibleContext({ document: options.document })) return false;
		return super.matchProof({
			proof: options.proof,
			document: options.document,
			purpose: options.purpose,
			documentLoader: options.documentLoader
		});
	}
	/**
	* @param options - Options hashmap.
	* @param options.verifyData - The data to sign.
	* @param options.proof - A JSON-LD document with options to use
	*   for the `proof` node. Any other custom fields can be provided here
	*   using a context different from `security-v2`.
	*
	* @returns The proof containing the signature value.
	*/
	async sign(options) {
		if (!(this.signer && typeof this.signer.sign === "function")) throw new Error("A signer API has not been specified.");
		const signature = await this.signer.sign({ data: options.verifyData });
		const encodedSignature = require_MultiBaseEncoder.MultiBaseEncoder.encode(signature, "base58btc");
		options.proof.proofValue = encodedSignature;
		return options.proof;
	}
	/**
	* @param options - Options hashmap.
	* @param options.verifyData - The data to verify.
	* @param options.verificationMethod - A verification method.
	* @param options.proof - The proof to be verified.
	*
	* @returns Resolves with the verification result.
	*/
	async verifySignature(options) {
		if (!(options.proof.proofValue && typeof options.proof.proofValue === "string")) throw new TypeError("The proof does not include a valid \"proofValue\" property.");
		const signature = require_MultiBaseEncoder.MultiBaseEncoder.decode(options.proof.proofValue).data;
		let { verifier } = this;
		if (!verifier) verifier = (await this.LDKeyClass.from(options.verificationMethod)).verifier();
		return verifier.verify({
			data: options.verifyData,
			signature
		});
	}
};
Ed25519Signature2020.CONTEXT_URL = require_constants$1.ED25519_SUITE_CONTEXT_URL_2020;
Ed25519Signature2020.CONTEXT = require_context2020.ed25519Signature2020Context.get(require_constants$1.ED25519_SUITE_CONTEXT_URL_2020);
function _includesCompatibleContext(options) {
	const hasEd2020 = require_jsonldUtil._includesContext({
		document: options.document,
		contextUrl: require_constants$1.ED25519_SUITE_CONTEXT_URL_2020
	});
	const hasCred = require_jsonldUtil._includesContext({
		document: options.document,
		contextUrl: require_constants.CREDENTIALS_CONTEXT_V1_URL
	});
	const hasSecV2 = require_jsonldUtil._includesContext({
		document: options.document,
		contextUrl: require_constants.SECURITY_CONTEXT_URL
	});
	return hasEd2020 || hasCred || hasSecV2;
}
function _isEd2020Key(verificationMethod) {
	return require_jsonld.default.hasValue(verificationMethod, "type", "Ed25519VerificationKey2020");
}
function _includesEd2020Context(document) {
	return require_jsonldUtil._includesContext({
		document,
		contextUrl: require_constants$1.ED25519_SUITE_CONTEXT_URL_2020
	});
}

//#endregion
exports.Ed25519Signature2020 = Ed25519Signature2020;