
          const { Temporal } = require("@js-temporal/polyfill");
          const { URLPattern } = require("urlpattern-polyfill");
        
const require_chunk = require('./chunk-DqRYRqnO.cjs');
const require_lookup = require('./lookup-DdOtSFct.cjs');
const require_actor = require('./actor-BLBfgCFC.cjs');
const require_http = require('./http-ClCl_dis.cjs');
const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
const jsonld = require_chunk.__toESM(require("jsonld"));
const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
const byte_encodings_hex = require_chunk.__toESM(require("byte-encodings/hex"));
const byte_encodings_base64 = require_chunk.__toESM(require("byte-encodings/base64"));
const json_canon = require_chunk.__toESM(require("json-canon"));

//#region src/sig/ld.ts
const logger$1 = (0, __logtape_logtape.getLogger)([
	"fedify",
	"sig",
	"ld"
]);
/**
* Attaches a LD signature to the given JSON-LD document.
* @param jsonLd The JSON-LD document to attach the signature to.  It is not
*               modified.
* @param signature The signature to attach.
* @returns The JSON-LD document with the attached signature.
* @throws {TypeError} If the input document is not a valid JSON-LD document.
* @since 1.0.0
*/
function attachSignature(jsonLd, signature) {
	if (typeof jsonLd !== "object" || jsonLd == null) throw new TypeError("Failed to attach signature; invalid JSON-LD document.");
	return {
		...jsonLd,
		signature
	};
}
/**
* Creates a LD signature for the given JSON-LD document.
* @param jsonLd The JSON-LD document to sign.
* @param privateKey The private key to sign the document.
* @param keyId The ID of the public key that corresponds to the private key.
* @param options Additional options for creating the signature.
*                See also {@link CreateSignatureOptions}.
* @return The created signature.
* @throws {TypeError} If the private key is invalid or unsupported.
* @since 1.0.0
*/
async function createSignature(jsonLd, privateKey, keyId, { contextLoader, created } = {}) {
	require_http.validateCryptoKey(privateKey, "private");
	if (privateKey.algorithm.name !== "RSASSA-PKCS1-v1_5") throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
	const options = {
		"@context": "https://w3id.org/identity/v1",
		creator: keyId.href,
		created: created?.toString() ?? (/* @__PURE__ */ new Date()).toISOString()
	};
	const optionsHash = await hashJsonLd(options, contextLoader);
	const docHash = await hashJsonLd(jsonLd, contextLoader);
	const message = optionsHash + docHash;
	const encoder = new TextEncoder();
	const messageBytes = encoder.encode(message);
	const signature = await crypto.subtle.sign("RSASSA-PKCS1-v1_5", privateKey, messageBytes);
	return {
		...options,
		type: "RsaSignature2017",
		signatureValue: (0, byte_encodings_base64.encodeBase64)(signature)
	};
}
/**
* Signs the given JSON-LD document with the private key and returns the signed
* JSON-LD document.
* @param jsonLd The JSON-LD document to sign.
* @param privateKey The private key to sign the document.
* @param keyId The key ID to use in the signature.  It will be used by the
*              verifier to fetch the corresponding public key.
* @param options Additional options for signing the document.
*                See also {@link SignJsonLdOptions}.
* @returns The signed JSON-LD document.
* @throws {TypeError} If the private key is invalid or unsupported.
* @since 1.0.0
*/
async function signJsonLd(jsonLd, privateKey, keyId, options) {
	const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
	const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
	return await tracer.startActiveSpan("ld_signatures.sign", { attributes: { "ld_signatures.key_id": keyId.href } }, async (span) => {
		try {
			const signature = await createSignature(jsonLd, privateKey, keyId, options);
			if (span.isRecording()) {
				span.setAttribute("ld_signatures.type", signature.type);
				span.setAttribute("ld_signatures.signature", (0, byte_encodings_hex.encodeHex)((0, byte_encodings_base64.decodeBase64)(signature.signatureValue)));
			}
			return attachSignature(jsonLd, signature);
		} catch (error) {
			span.setStatus({
				code: __opentelemetry_api.SpanStatusCode.ERROR,
				message: String(error)
			});
			throw error;
		} finally {
			span.end();
		}
	});
}
/**
* Checks if the given JSON-LD document has a Linked Data Signature.
* @param jsonLd The JSON-LD document to check.
* @returns `true` if the document has a signature; `false` otherwise.
* @since 1.0.0
*/
function hasSignature(jsonLd) {
	if (typeof jsonLd !== "object" || jsonLd == null) return false;
	if ("signature" in jsonLd) {
		const signature = jsonLd.signature;
		if (typeof signature !== "object" || signature == null) return false;
		return "type" in signature && signature.type === "RsaSignature2017" && "creator" in signature && typeof signature.creator === "string" && "created" in signature && typeof signature.created === "string" && "signatureValue" in signature && typeof signature.signatureValue === "string";
	}
	return false;
}
/**
* Detaches Linked Data Signatures from the given JSON-LD document.
* @param jsonLd The JSON-LD document to modify.
* @returns The modified JSON-LD document.  If the input document does not
*          contain a signature, the original document is returned.
* @since 1.0.0
*/
function detachSignature(jsonLd) {
	if (typeof jsonLd !== "object" || jsonLd == null) return jsonLd;
	const doc = { ...jsonLd };
	delete doc.signature;
	return doc;
}
/**
* Verifies Linked Data Signatures of the given JSON-LD document.
* @param jsonLd The JSON-LD document to verify.
* @param options Options for verifying the signature.
* @returns The public key that signed the document or `null` if the signature
*          is invalid or the key is not found.
* @since 1.0.0
*/
async function verifySignature(jsonLd, options = {}) {
	if (!hasSignature(jsonLd)) return null;
	const sig = jsonLd.signature;
	let signature;
	try {
		signature = (0, byte_encodings_base64.decodeBase64)(sig.signatureValue);
	} catch (error) {
		logger$1.debug("Failed to verify; invalid base64 signatureValue: {signatureValue}", {
			...sig,
			error
		});
		return null;
	}
	const { key, cached } = await require_http.fetchKey(new URL(sig.creator), require_actor.CryptographicKey, options);
	if (key == null) return null;
	const sigOpts = {
		...sig,
		"@context": "https://w3id.org/identity/v1"
	};
	delete sigOpts.type;
	delete sigOpts.id;
	delete sigOpts.signatureValue;
	let sigOptsHash;
	try {
		sigOptsHash = await hashJsonLd(sigOpts, options.contextLoader);
	} catch (error) {
		logger$1.warn("Failed to verify; failed to hash the signature options: {signatureOptions}\n{error}", {
			signatureOptions: sigOpts,
			error
		});
		return null;
	}
	const document = { ...jsonLd };
	delete document.signature;
	let docHash;
	try {
		docHash = await hashJsonLd(document, options.contextLoader);
	} catch (error) {
		logger$1.warn("Failed to verify; failed to hash the document: {document}\n{error}", {
			document,
			error
		});
		return null;
	}
	const encoder = new TextEncoder();
	const message = sigOptsHash + docHash;
	const messageBytes = encoder.encode(message);
	const verified = await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature.slice(), messageBytes);
	if (verified) return key;
	if (cached) {
		logger$1.debug("Failed to verify with the cached key {keyId}; signature {signatureValue} is invalid.  Retrying with the freshly fetched key...", {
			keyId: sig.creator,
			...sig
		});
		const { key: key$1 } = await require_http.fetchKey(new URL(sig.creator), require_actor.CryptographicKey, {
			...options,
			keyCache: {
				get: () => Promise.resolve(void 0),
				set: async (keyId, key$2) => await options.keyCache?.set(keyId, key$2)
			}
		});
		if (key$1 == null) return null;
		const verified$1 = await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key$1.publicKey, signature.slice(), messageBytes);
		return verified$1 ? key$1 : null;
	}
	logger$1.debug("Failed to verify with the fetched key {keyId}; signature {signatureValue} is invalid.  Check if the key is correct or if the signed message is correct.  The message to sign is:\n{message}", {
		keyId: sig.creator,
		...sig,
		message
	});
	return null;
}
/**
* Verify the authenticity of the given JSON-LD document using Linked Data
* Signatures.  If the document is signed, this function verifies the signature
* and checks if the document is attributed to the owner of the public key.
* If the document is not signed, this function returns `false`.
* @param jsonLd The JSON-LD document to verify.
* @param options Options for verifying the document.
* @returns `true` if the document is authentic; `false` otherwise.
*/
async function verifyJsonLd(jsonLd, options = {}) {
	const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
	const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
	return await tracer.startActiveSpan("ld_signatures.verify", async (span) => {
		try {
			const object = await require_actor.Object.fromJsonLd(jsonLd, options);
			if (object.id != null) span.setAttribute("activitypub.object.id", object.id.href);
			span.setAttribute("activitypub.object.type", require_actor.getTypeId(object).href);
			if (typeof jsonLd === "object" && jsonLd != null && "signature" in jsonLd && typeof jsonLd.signature === "object" && jsonLd.signature != null) {
				if ("creator" in jsonLd.signature && typeof jsonLd.signature.creator === "string") span.setAttribute("ld_signatures.key_id", jsonLd.signature.creator);
				if ("signatureValue" in jsonLd.signature && typeof jsonLd.signature.signatureValue === "string") span.setAttribute("ld_signatures.signature", jsonLd.signature.signatureValue);
				if ("type" in jsonLd.signature && typeof jsonLd.signature.type === "string") span.setAttribute("ld_signatures.type", jsonLd.signature.type);
			}
			const attributions = new Set(object.attributionIds.map((uri) => uri.href));
			if (object instanceof require_actor.Activity) for (const uri of object.actorIds) attributions.add(uri.href);
			const key = await verifySignature(jsonLd, options);
			if (key == null) return false;
			if (key.ownerId == null) {
				logger$1.debug("Key {keyId} has no owner.", { keyId: key.id?.href });
				return false;
			}
			attributions.delete(key.ownerId.href);
			if (attributions.size > 0) {
				logger$1.debug("Some attributions are not authenticated by the Linked Data Signatures: {attributions}.", { attributions: [...attributions] });
				return false;
			}
			return true;
		} catch (error) {
			span.setStatus({
				code: __opentelemetry_api.SpanStatusCode.ERROR,
				message: String(error)
			});
			throw error;
		} finally {
			span.end();
		}
	});
}
async function hashJsonLd(jsonLd, contextLoader) {
	const canon = await jsonld.default.canonize(jsonLd, {
		format: "application/n-quads",
		documentLoader: contextLoader ?? (0, __fedify_vocab_runtime.getDocumentLoader)()
	});
	const encoder = new TextEncoder();
	const hash = await crypto.subtle.digest("SHA-256", encoder.encode(canon));
	return (0, byte_encodings_hex.encodeHex)(hash);
}

//#endregion
//#region src/sig/owner.ts
/**
* Checks if the actor of the given activity owns the specified key.
* @param activity The activity to check.
* @param key The public key to check.
* @param options Options for checking the key ownership.
* @returns Whether the actor is the owner of the key.
*/
async function doesActorOwnKey(activity, key, options) {
	const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
	const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
	return await tracer.startActiveSpan("activitypub.verify_key_ownership", {
		kind: __opentelemetry_api.SpanKind.INTERNAL,
		attributes: {
			"activitypub.actor.id": activity.actorId?.href ?? "",
			"activitypub.key.id": key.id?.href ?? ""
		}
	}, async (span) => {
		try {
			if (key.ownerId != null) {
				const owns = key.ownerId.href === activity.actorId?.href;
				span.setAttribute("activitypub.key_ownership.verified", owns);
				span.setAttribute("activitypub.key_ownership.method", "owner_id");
				return owns;
			}
			const actor = await activity.getActor(options);
			if (actor == null || !require_actor.isActor(actor)) {
				span.setAttribute("activitypub.key_ownership.verified", false);
				span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
				return false;
			}
			for (const publicKeyId of actor.publicKeyIds) if (key.id != null && publicKeyId.href === key.id.href) {
				span.setAttribute("activitypub.key_ownership.verified", true);
				span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
				return true;
			}
			span.setAttribute("activitypub.key_ownership.verified", false);
			span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
			return false;
		} catch (error) {
			span.recordException(error);
			span.setStatus({
				code: __opentelemetry_api.SpanStatusCode.ERROR,
				message: String(error)
			});
			throw error;
		} finally {
			span.end();
		}
	});
}
/**
* Gets the actor that owns the specified key.  Returns `null` if the key has no
* known owner.
*
* @param keyId The ID of the key to check, or the key itself.
* @param options Options for getting the key owner.
* @returns The actor that owns the key, or `null` if the key has no known
*          owner.
* @since 0.7.0
*/
async function getKeyOwner(keyId, options) {
	const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
	const documentLoader = options.documentLoader ?? (0, __fedify_vocab_runtime.getDocumentLoader)();
	const contextLoader = options.contextLoader ?? (0, __fedify_vocab_runtime.getDocumentLoader)();
	let object;
	if (keyId instanceof require_actor.CryptographicKey) {
		object = keyId;
		if (object.id == null) return null;
		keyId = object.id;
	} else {
		let keyDoc;
		try {
			const { document } = await documentLoader(keyId.href);
			keyDoc = document;
		} catch (_) {
			return null;
		}
		try {
			object = await require_actor.Object.fromJsonLd(keyDoc, {
				documentLoader,
				contextLoader,
				tracerProvider
			});
		} catch (e) {
			if (!(e instanceof TypeError)) throw e;
			try {
				object = await require_actor.CryptographicKey.fromJsonLd(keyDoc, {
					documentLoader,
					contextLoader,
					tracerProvider
				});
			} catch (e$1) {
				if (e$1 instanceof TypeError) return null;
				throw e$1;
			}
		}
	}
	let owner = null;
	if (object instanceof require_actor.CryptographicKey) {
		if (object.ownerId == null) return null;
		owner = await object.getOwner({
			documentLoader,
			contextLoader,
			tracerProvider
		});
	} else if (require_actor.isActor(object)) owner = object;
	else return null;
	if (owner == null) return null;
	for (const kid of owner.publicKeyIds) if (kid.href === keyId.href) return owner;
	return null;
}

//#endregion
//#region src/sig/proof.ts
const logger = (0, __logtape_logtape.getLogger)([
	"fedify",
	"sig",
	"proof"
]);
/**
* Creates a proof for the given object.
* @param object The object to create a proof for.
* @param privateKey The private key to sign the proof with.
* @param keyId The key ID to use in the proof. It will be used by the verifier.
* @param options Additional options.  See also {@link CreateProofOptions}.
* @returns The created proof.
* @throws {TypeError} If the private key is invalid or unsupported.
* @since 0.10.0
*/
async function createProof(object, privateKey, keyId, { contextLoader, context, created } = {}) {
	require_http.validateCryptoKey(privateKey, "private");
	if (privateKey.algorithm.name !== "Ed25519") throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
	const objectWithoutProofs = object.clone({ proofs: [] });
	const compactMsg = await objectWithoutProofs.toJsonLd({
		format: "compact",
		contextLoader,
		context
	});
	const msgCanon = (0, json_canon.default)(compactMsg);
	const encoder = new TextEncoder();
	const msgBytes = encoder.encode(msgCanon);
	const msgDigest = await crypto.subtle.digest("SHA-256", msgBytes);
	created ??= Temporal.Now.instant();
	const proofConfig = {
		"@context": compactMsg["@context"],
		type: "DataIntegrityProof",
		cryptosuite: "eddsa-jcs-2022",
		verificationMethod: keyId.href,
		proofPurpose: "assertionMethod",
		created: created.toString()
	};
	const proofCanon = (0, json_canon.default)(proofConfig);
	const proofBytes = encoder.encode(proofCanon);
	const proofDigest = await crypto.subtle.digest("SHA-256", proofBytes);
	const digest = new Uint8Array(proofDigest.byteLength + msgDigest.byteLength);
	digest.set(new Uint8Array(proofDigest), 0);
	digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
	const sig = await crypto.subtle.sign("Ed25519", privateKey, digest);
	return new require_actor.DataIntegrityProof({
		cryptosuite: "eddsa-jcs-2022",
		verificationMethod: keyId,
		proofPurpose: "assertionMethod",
		created: created ?? Temporal.Now.instant(),
		proofValue: new Uint8Array(sig)
	});
}
/**
* Signs the given object with the private key and returns the signed object.
* @param object The object to create a proof for.
* @param privateKey The private key to sign the proof with.
* @param keyId The key ID to use in the proof. It will be used by the verifier.
* @param options Additional options.  See also {@link SignObjectOptions}.
* @returns The signed object.
* @throws {TypeError} If the private key is invalid or unsupported.
* @since 0.10.0
*/
async function signObject(object, privateKey, keyId, options = {}) {
	const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
	const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
	return await tracer.startActiveSpan("object_integrity_proofs.sign", { attributes: { "activitypub.object.type": require_actor.getTypeId(object).href } }, async (span) => {
		try {
			if (object.id != null) span.setAttribute("activitypub.object.id", object.id.href);
			const existingProofs = [];
			for await (const proof$1 of object.getProofs(options)) existingProofs.push(proof$1);
			const proof = await createProof(object, privateKey, keyId, options);
			if (span.isRecording()) {
				if (proof.cryptosuite != null) span.setAttribute("object_integrity_proofs.cryptosuite", proof.cryptosuite);
				if (proof.verificationMethodId != null) span.setAttribute("object_integrity_proofs.key_id", proof.verificationMethodId.href);
				if (proof.proofValue != null) span.setAttribute("object_integrity_proofs.signature", (0, byte_encodings_hex.encodeHex)(proof.proofValue));
			}
			return object.clone({ proofs: [...existingProofs, proof] });
		} catch (error) {
			span.setStatus({
				code: __opentelemetry_api.SpanStatusCode.ERROR,
				message: String(error)
			});
			throw error;
		} finally {
			span.end();
		}
	});
}
/**
* Verifies the given proof for the object.
* @param jsonLd The JSON-LD object to verify the proof for.  If it contains
*               any proofs, they will be ignored.
* @param proof The proof to verify.
* @param options Additional options.  See also {@link VerifyProofOptions}.
* @returns The public key that was used to sign the proof, or `null` if the
*          proof is invalid.
* @since 0.10.0
*/
async function verifyProof(jsonLd, proof, options = {}) {
	const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
	const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
	return await tracer.startActiveSpan("object_integrity_proofs.verify", async (span) => {
		if (span.isRecording()) {
			if (proof.cryptosuite != null) span.setAttribute("object_integrity_proofs.cryptosuite", proof.cryptosuite);
			if (proof.verificationMethodId != null) span.setAttribute("object_integrity_proofs.key_id", proof.verificationMethodId.href);
			if (proof.proofValue != null) span.setAttribute("object_integrity_proofs.signature", (0, byte_encodings_hex.encodeHex)(proof.proofValue));
		}
		try {
			const key = await verifyProofInternal(jsonLd, proof, options);
			if (key == null) span.setStatus({ code: __opentelemetry_api.SpanStatusCode.ERROR });
			return key;
		} catch (error) {
			span.setStatus({
				code: __opentelemetry_api.SpanStatusCode.ERROR,
				message: String(error)
			});
			throw error;
		} finally {
			span.end();
		}
	});
}
async function verifyProofInternal(jsonLd, proof, options) {
	if (typeof jsonLd !== "object" || proof.cryptosuite !== "eddsa-jcs-2022" || proof.verificationMethodId == null || proof.proofPurpose !== "assertionMethod" || proof.proofValue == null || proof.created == null) return null;
	const publicKeyPromise = require_http.fetchKey(proof.verificationMethodId, require_actor.Multikey, options);
	const proofConfig = {
		"@context": jsonLd["@context"],
		type: "DataIntegrityProof",
		cryptosuite: proof.cryptosuite,
		verificationMethod: proof.verificationMethodId.href,
		proofPurpose: proof.proofPurpose,
		created: proof.created.toString()
	};
	const proofCanon = (0, json_canon.default)(proofConfig);
	const encoder = new TextEncoder();
	const proofBytes = encoder.encode(proofCanon);
	const proofDigest = await crypto.subtle.digest("SHA-256", proofBytes);
	const msg = { ...jsonLd };
	if ("proof" in msg) delete msg.proof;
	const msgCanon = (0, json_canon.default)(msg);
	const msgBytes = encoder.encode(msgCanon);
	const msgDigest = await crypto.subtle.digest("SHA-256", msgBytes);
	const digest = new Uint8Array(proofDigest.byteLength + msgDigest.byteLength);
	digest.set(new Uint8Array(proofDigest), 0);
	digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
	let fetchedKey;
	try {
		fetchedKey = await publicKeyPromise;
	} catch (error) {
		logger.debug("Failed to get the key (verificationMethod) for the proof:\n{proof}", {
			proof,
			keyId: proof.verificationMethodId.href,
			error
		});
		return null;
	}
	const publicKey = fetchedKey.key;
	if (publicKey == null) {
		logger.debug("Failed to get the key (verificationMethod) for the proof:\n{proof}", {
			proof,
			keyId: proof.verificationMethodId.href
		});
		return null;
	}
	if (publicKey.publicKey.algorithm.name !== "Ed25519") {
		if (fetchedKey.cached) {
			logger.debug("The cached key (verificationMethod) for the proof is not a valid Ed25519 key:\n{keyId}; retrying with the freshly fetched key...", {
				proof,
				keyId: proof.verificationMethodId.href
			});
			return await verifyProof(jsonLd, proof, {
				...options,
				keyCache: {
					get: () => Promise.resolve(null),
					set: async (keyId, key) => await options.keyCache?.set(keyId, key)
				}
			});
		}
		logger.debug("The fetched key (verificationMethod) for the proof is not a valid Ed25519 key:\n{keyId}", {
			proof,
			keyId: proof.verificationMethodId.href
		});
		return null;
	}
	const verified = await crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue.slice(), digest);
	if (!verified) {
		if (fetchedKey.cached) {
			logger.debug("Failed to verify the proof with the cached key {keyId}; retrying with the freshly fetched key...", {
				keyId: proof.verificationMethodId.href,
				proof
			});
			return await verifyProof(jsonLd, proof, {
				...options,
				keyCache: {
					get: () => Promise.resolve(void 0),
					set: async (keyId, key) => await options.keyCache?.set(keyId, key)
				}
			});
		}
		logger.debug("Failed to verify the proof with the fetched key {keyId}:\n{proof}", {
			keyId: proof.verificationMethodId.href,
			proof
		});
		return null;
	}
	return publicKey;
}
/**
* Verifies the given object.  It will verify all the proofs in the object,
* and succeed only if all the proofs are valid and all attributions and
* actors are authenticated by the proofs.
* @template T The type of the object to verify.
* @param cls The class of the object to verify.  It must be a subclass of
*            the {@link Object}.
* @param jsonLd The JSON-LD object to verify.  It's assumed that the object
*               is a compacted JSON-LD representation of a `T` with `@context`.
* @param options Additional options.  See also {@link VerifyObjectOptions}.
* @returns The object if it's verified, or `null` if it's not.
* @throws {TypeError} If the object is invalid or unsupported.
* @since 0.10.0
*/
async function verifyObject(cls, jsonLd, options = {}) {
	const logger$2 = (0, __logtape_logtape.getLogger)([
		"fedify",
		"sig",
		"proof"
	]);
	const object = await cls.fromJsonLd(jsonLd, options);
	const attributions = new Set(object.attributionIds.map((uri) => uri.href));
	if (object instanceof require_actor.Activity) for (const uri of object.actorIds) attributions.add(uri.href);
	for await (const proof of object.getProofs(options)) {
		const key = await verifyProof(jsonLd, proof, options);
		if (key === null) return null;
		if (key.controllerId == null) {
			logger$2.debug("Key {keyId} does not have a controller.", { keyId: key.id?.href });
			continue;
		}
		attributions.delete(key.controllerId.href);
	}
	if (attributions.size > 0) {
		logger$2.debug("Some attributions are not authenticated by the proofs: {attributions}.", { attributions: [...attributions] });
		return null;
	}
	return object;
}

//#endregion
Object.defineProperty(exports, 'attachSignature', {
  enumerable: true,
  get: function () {
    return attachSignature;
  }
});
Object.defineProperty(exports, 'createProof', {
  enumerable: true,
  get: function () {
    return createProof;
  }
});
Object.defineProperty(exports, 'createSignature', {
  enumerable: true,
  get: function () {
    return createSignature;
  }
});
Object.defineProperty(exports, 'detachSignature', {
  enumerable: true,
  get: function () {
    return detachSignature;
  }
});
Object.defineProperty(exports, 'doesActorOwnKey', {
  enumerable: true,
  get: function () {
    return doesActorOwnKey;
  }
});
Object.defineProperty(exports, 'getKeyOwner', {
  enumerable: true,
  get: function () {
    return getKeyOwner;
  }
});
Object.defineProperty(exports, 'hasSignature', {
  enumerable: true,
  get: function () {
    return hasSignature;
  }
});
Object.defineProperty(exports, 'signJsonLd', {
  enumerable: true,
  get: function () {
    return signJsonLd;
  }
});
Object.defineProperty(exports, 'signObject', {
  enumerable: true,
  get: function () {
    return signObject;
  }
});
Object.defineProperty(exports, 'verifyJsonLd', {
  enumerable: true,
  get: function () {
    return verifyJsonLd;
  }
});
Object.defineProperty(exports, 'verifyObject', {
  enumerable: true,
  get: function () {
    return verifyObject;
  }
});
Object.defineProperty(exports, 'verifyProof', {
  enumerable: true,
  get: function () {
    return verifyProof;
  }
});
Object.defineProperty(exports, 'verifySignature', {
  enumerable: true,
  get: function () {
    return verifySignature;
  }
});