import { __decorateMetadata } from "../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorateMetadata.mjs";
import { __decorate } from "../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.mjs";
import "../../DidCommMessage.mjs";
import { DidCommConnectionService } from "../connections/services/DidCommConnectionService.mjs";
import { DidCommMessageSender } from "../../DidCommMessageSender.mjs";
import "../connections/index.mjs";
import { getOutboundDidCommMessageContext } from "../../getDidCommOutboundMessageContext.mjs";
import { DidCommProofState } from "./models/DidCommProofState.mjs";
import { DidCommProofsModuleConfig } from "./DidCommProofsModuleConfig.mjs";
import { DidCommProofExchangeRepository } from "./repository/DidCommProofExchangeRepository.mjs";
import { AgentContext, CredoError, injectable } from "@credo-ts/core";

//#region ../didcomm/src/modules/proofs/DidCommProofsApi.ts
var _ref, _ref2, _ref3, _ref4, _ref5;
let DidCommProofsApi = class DidCommProofsApi$1 {
	constructor(messageSender, connectionService, agentContext, proofRepository, config) {
		this.messageSender = messageSender;
		this.connectionService = connectionService;
		this.proofRepository = proofRepository;
		this.agentContext = agentContext;
		this.config = config;
	}
	getProtocol(protocolVersion) {
		const proofProtocol = this.config.proofProtocols.find((protocol) => protocol.version === protocolVersion);
		if (!proofProtocol) throw new CredoError(`No proof protocol registered for protocol version ${protocolVersion}`);
		return proofProtocol;
	}
	/**
	* Initiate a new presentation exchange as prover by sending a presentation proposal message
	* to the connection with the specified connection id.
	*
	* @param options configuration to use for the proposal
	* @returns Proof exchange record associated with the sent proposal message
	*/
	async proposeProof(options) {
		const protocol = this.getProtocol(options.protocolVersion);
		const connectionRecord = await this.connectionService.getById(this.agentContext, options.connectionId);
		connectionRecord.assertReady();
		const { message, proofRecord } = await protocol.createProposal(this.agentContext, {
			connectionRecord,
			proofFormats: options.proofFormats,
			autoAcceptProof: options.autoAcceptProof,
			goalCode: options.goalCode,
			goal: options.goal,
			comment: options.comment,
			parentThreadId: options.parentThreadId
		});
		const outboundMessageContext = await getOutboundDidCommMessageContext(this.agentContext, {
			message,
			associatedRecord: proofRecord,
			connectionRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return proofRecord;
	}
	/**
	* Accept a presentation proposal as verifier (by sending a presentation request message) to the connection
	* associated with the proof record.
	*
	* @param options config object for accepting the proposal
	* @returns Proof exchange record associated with the presentation request
	*/
	async acceptProposal(options) {
		const proofRecord = await this.getById(options.proofExchangeRecordId);
		if (!proofRecord.connectionId) throw new CredoError(`No connectionId found for proof record '${proofRecord.id}'. Connection-less verification does not support presentation proposal or negotiation.`);
		const protocol = this.getProtocol(proofRecord.protocolVersion);
		const connectionRecord = await this.connectionService.getById(this.agentContext, proofRecord.connectionId);
		connectionRecord.assertReady();
		const { message } = await protocol.acceptProposal(this.agentContext, {
			proofRecord,
			proofFormats: options.proofFormats,
			goalCode: options.goalCode,
			goal: options.goal,
			willConfirm: options.willConfirm,
			comment: options.comment,
			autoAcceptProof: options.autoAcceptProof
		});
		const outboundMessageContext = await getOutboundDidCommMessageContext(this.agentContext, {
			message,
			associatedRecord: proofRecord,
			connectionRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return proofRecord;
	}
	/**
	* Answer with a new presentation request in response to received presentation proposal message
	* to the connection associated with the proof record.
	*
	* @param options multiple properties like proof record id, proof formats to accept requested credentials object
	* specifying which credentials to use for the proof
	* @returns Proof record associated with the sent request message
	*/
	async negotiateProposal(options) {
		const proofRecord = await this.getById(options.proofExchangeRecordId);
		if (!proofRecord.connectionId) throw new CredoError(`No connectionId found for proof record '${proofRecord.id}'. Connection-less verification does not support negotiation.`);
		const protocol = this.getProtocol(proofRecord.protocolVersion);
		const connectionRecord = await this.connectionService.getById(this.agentContext, proofRecord.connectionId);
		connectionRecord.assertReady();
		const { message } = await protocol.negotiateProposal(this.agentContext, {
			proofRecord,
			proofFormats: options.proofFormats,
			autoAcceptProof: options.autoAcceptProof,
			comment: options.comment,
			goalCode: options.goalCode,
			goal: options.goal,
			willConfirm: options.willConfirm
		});
		const outboundMessageContext = await getOutboundDidCommMessageContext(this.agentContext, {
			message,
			associatedRecord: proofRecord,
			connectionRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return proofRecord;
	}
	/**
	* Initiate a new presentation exchange as verifier by sending a presentation request message
	* to the connection with the specified connection id
	*
	* @param options multiple properties like connection id, protocol version, proof Formats to build the proof request
	* @returns Proof record associated with the sent request message
	*/
	async requestProof(options) {
		const connectionRecord = await this.connectionService.getById(this.agentContext, options.connectionId);
		const protocol = this.getProtocol(options.protocolVersion);
		connectionRecord.assertReady();
		const { message, proofRecord } = await protocol.createRequest(this.agentContext, {
			connectionRecord,
			proofFormats: options.proofFormats,
			autoAcceptProof: options.autoAcceptProof,
			parentThreadId: options.parentThreadId,
			comment: options.comment,
			goalCode: options.goalCode,
			goal: options.goal,
			willConfirm: options.willConfirm
		});
		const outboundMessageContext = await getOutboundDidCommMessageContext(this.agentContext, {
			message,
			associatedRecord: proofRecord,
			connectionRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return proofRecord;
	}
	/**
	* Accept a presentation request as prover (by sending a presentation message) to the connection
	* associated with the proof record.
	*
	* @param options multiple properties like proof record id, proof formats to accept requested credentials object
	* specifying which credentials to use for the proof
	* @returns Proof record associated with the sent presentation message
	*/
	async acceptRequest(options) {
		const proofRecord = await this.getById(options.proofExchangeRecordId);
		const protocol = this.getProtocol(proofRecord.protocolVersion);
		const requestMessage = await protocol.findRequestMessage(this.agentContext, proofRecord.id);
		if (!requestMessage) throw new CredoError(`No request message found for proof record with id '${proofRecord.id}'`);
		const connectionRecord = proofRecord.connectionId ? await this.connectionService.getById(this.agentContext, proofRecord.connectionId) : void 0;
		connectionRecord?.assertReady();
		const { message } = await protocol.acceptRequest(this.agentContext, {
			proofFormats: options.proofFormats,
			proofRecord,
			comment: options.comment,
			autoAcceptProof: options.autoAcceptProof,
			goalCode: options.goalCode,
			goal: options.goal
		});
		const outboundMessageContext = await getOutboundDidCommMessageContext(this.agentContext, {
			message,
			connectionRecord,
			associatedRecord: proofRecord,
			lastReceivedMessage: requestMessage
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return proofRecord;
	}
	async declineRequest(options) {
		const proofRecord = await this.getById(options.proofExchangeRecordId);
		proofRecord.assertState(DidCommProofState.RequestReceived);
		const protocol = this.getProtocol(proofRecord.protocolVersion);
		if (options.sendProblemReport) await this.sendProblemReport({
			proofExchangeRecordId: options.proofExchangeRecordId,
			description: options.problemReportDescription ?? "Request declined"
		});
		await protocol.updateState(this.agentContext, proofRecord, DidCommProofState.Declined);
		return proofRecord;
	}
	/**
	* Answer with a new presentation proposal in response to received presentation request message
	* to the connection associated with the proof record.
	*
	* @param options multiple properties like proof record id, proof format (indy/ presentation exchange)
	* to include in the message
	* @returns Proof record associated with the sent proposal message
	*/
	async negotiateRequest(options) {
		const proofRecord = await this.getById(options.proofExchangeRecordId);
		if (!proofRecord.connectionId) throw new CredoError(`No connectionId found for proof record '${proofRecord.id}'. Connection-less verification does not support presentation proposal or negotiation.`);
		const connectionRecord = await this.connectionService.getById(this.agentContext, proofRecord.connectionId);
		connectionRecord.assertReady();
		const { message } = await this.getProtocol(proofRecord.protocolVersion).negotiateRequest(this.agentContext, {
			proofRecord,
			proofFormats: options.proofFormats,
			autoAcceptProof: options.autoAcceptProof,
			goalCode: options.goalCode,
			goal: options.goal,
			comment: options.comment
		});
		const outboundMessageContext = await getOutboundDidCommMessageContext(this.agentContext, {
			message,
			connectionRecord,
			associatedRecord: proofRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return proofRecord;
	}
	/**
	* Initiate a new presentation exchange as verifier by sending an out of band presentation
	* request message
	*
	* @param options multiple properties like protocol version, proof Formats to build the proof request
	* @returns the message itself and the proof record associated with the sent request message
	*/
	async createRequest(options) {
		return await this.getProtocol(options.protocolVersion).createRequest(this.agentContext, {
			proofFormats: options.proofFormats,
			autoAcceptProof: options.autoAcceptProof,
			comment: options.comment,
			parentThreadId: options.parentThreadId,
			goalCode: options.goalCode,
			goal: options.goal,
			willConfirm: options.willConfirm
		});
	}
	/**
	* Accept a presentation as prover (by sending a presentation acknowledgement message) to the connection
	* associated with the proof record.
	*
	* @param proofExchangeRecordId The id of the proof exchange record for which to accept the presentation
	* @returns Proof record associated with the sent presentation acknowledgement message
	*
	*/
	async acceptPresentation(options) {
		const proofRecord = await this.getById(options.proofExchangeRecordId);
		const protocol = this.getProtocol(proofRecord.protocolVersion);
		const requestMessage = await protocol.findRequestMessage(this.agentContext, proofRecord.id);
		if (!requestMessage) throw new CredoError(`No request message found for proof record with id '${proofRecord.id}'`);
		const presentationMessage = await protocol.findPresentationMessage(this.agentContext, proofRecord.id);
		if (!presentationMessage) throw new CredoError(`No presentation message found for proof record with id '${proofRecord.id}'`);
		const connectionRecord = proofRecord.connectionId ? await this.connectionService.getById(this.agentContext, proofRecord.connectionId) : void 0;
		connectionRecord?.assertReady();
		const { message } = await protocol.acceptPresentation(this.agentContext, { proofRecord });
		const outboundMessageContext = await getOutboundDidCommMessageContext(this.agentContext, {
			message,
			connectionRecord,
			associatedRecord: proofRecord,
			lastSentMessage: requestMessage,
			lastReceivedMessage: presentationMessage
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return proofRecord;
	}
	/**
	* Create a {@link RetrievedCredentials} object. Given input proof request and presentation proposal,
	* use credentials in the wallet to build indy requested credentials object for input to proof creation.
	* If restrictions allow, self attested attributes will be used.
	*
	* @param options multiple properties like proof record id and optional configuration
	* @returns RequestedCredentials
	*/
	async selectCredentialsForRequest(options) {
		const proofRecord = await this.getById(options.proofExchangeRecordId);
		return this.getProtocol(proofRecord.protocolVersion).selectCredentialsForRequest(this.agentContext, {
			proofFormats: options.proofFormats,
			proofRecord
		});
	}
	/**
	* Get credentials in the wallet for a received proof request.
	*
	* @param options multiple properties like proof record id and optional configuration
	*/
	async getCredentialsForRequest(options) {
		const proofRecord = await this.getById(options.proofExchangeRecordId);
		return this.getProtocol(proofRecord.protocolVersion).getCredentialsForRequest(this.agentContext, {
			proofRecord,
			proofFormats: options.proofFormats
		});
	}
	/**
	* Send problem report message for a proof record
	*
	* @param proofExchangeRecordId  The id of the proof record for which to send problem report
	* @param message message to send
	* @returns proof record associated with the proof problem report message
	*/
	async sendProblemReport(options) {
		const proofRecord = await this.getById(options.proofExchangeRecordId);
		const protocol = this.getProtocol(proofRecord.protocolVersion);
		const requestMessage = await protocol.findRequestMessage(this.agentContext, proofRecord.id);
		const { message: problemReport } = await protocol.createProblemReport(this.agentContext, {
			proofRecord,
			description: options.description
		});
		const connectionRecord = proofRecord.connectionId ? await this.connectionService.getById(this.agentContext, proofRecord.connectionId) : void 0;
		connectionRecord?.assertReady();
		if (!connectionRecord) {
			proofRecord.assertState(DidCommProofState.RequestReceived);
			if (!requestMessage) throw new CredoError(`No request message found for proof record with id '${proofRecord.id}'`);
		}
		const outboundMessageContext = await getOutboundDidCommMessageContext(this.agentContext, {
			message: problemReport,
			connectionRecord,
			associatedRecord: proofRecord,
			lastReceivedMessage: requestMessage ?? void 0
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return proofRecord;
	}
	async getFormatData(proofExchangeRecordId) {
		const proofRecord = await this.getById(proofExchangeRecordId);
		return this.getProtocol(proofRecord.protocolVersion).getFormatData(this.agentContext, proofExchangeRecordId);
	}
	/**
	* Retrieve all proof records
	*
	* @returns List containing all proof records
	*/
	async getAll() {
		return this.proofRepository.getAll(this.agentContext);
	}
	/**
	* Retrieve all proof records by specified query params
	*
	* @returns List containing all proof records matching specified params
	*/
	findAllByQuery(query, queryOptions) {
		return this.proofRepository.findByQuery(this.agentContext, query, queryOptions);
	}
	/**
	* Retrieve a proof record by id
	*
	* @param proofExchangeRecordId The proof record id
	* @throws {RecordNotFoundError} If no record is found
	* @return The proof record
	*
	*/
	async getById(proofExchangeRecordId) {
		return await this.proofRepository.getById(this.agentContext, proofExchangeRecordId);
	}
	/**
	* Retrieve a proof record by id
	*
	* @param proofExchangeRecordId The proof record id
	* @return The proof record or null if not found
	*
	*/
	async findById(proofExchangeRecordId) {
		return await this.proofRepository.findById(this.agentContext, proofExchangeRecordId);
	}
	/**
	* Delete a proof record by id
	*
	* @param proofId the proof record id
	*/
	async deleteById(proofId, options) {
		const proofRecord = await this.getById(proofId);
		return this.getProtocol(proofRecord.protocolVersion).delete(this.agentContext, proofRecord, options);
	}
	/**
	* Retrieve a proof record by connection id and thread id
	*
	* @param connectionId The connection id
	* @param threadId The thread id
	* @throws {RecordNotFoundError} If no record is found
	* @throws {RecordDuplicateError} If multiple records are found
	* @returns The proof record
	*/
	async getByThreadAndConnectionId(threadId, connectionId) {
		return this.proofRepository.getByThreadAndConnectionId(this.agentContext, threadId, connectionId);
	}
	/**
	* Retrieve proof records by connection id and parent thread id
	*
	* @param connectionId The connection id
	* @param parentThreadId The parent thread id
	* @returns List containing all proof records matching the given query
	*/
	async getByParentThreadAndConnectionId(parentThreadId, connectionId) {
		return this.proofRepository.getByParentThreadAndConnectionId(this.agentContext, parentThreadId, connectionId);
	}
	/**
	* Update a proof record by
	*
	* @param proofRecord the proof record
	*/
	async update(proofRecord) {
		await this.proofRepository.update(this.agentContext, proofRecord);
	}
	async findProposalMessage(proofExchangeRecordId) {
		const record = await this.getById(proofExchangeRecordId);
		return this.getProtocol(record.protocolVersion).findProposalMessage(this.agentContext, proofExchangeRecordId);
	}
	async findRequestMessage(proofExchangeRecordId) {
		const record = await this.getById(proofExchangeRecordId);
		return this.getProtocol(record.protocolVersion).findRequestMessage(this.agentContext, proofExchangeRecordId);
	}
	async findPresentationMessage(proofExchangeRecordId) {
		const record = await this.getById(proofExchangeRecordId);
		return this.getProtocol(record.protocolVersion).findPresentationMessage(this.agentContext, proofExchangeRecordId);
	}
};
DidCommProofsApi = __decorate([injectable(), __decorateMetadata("design:paramtypes", [
	typeof (_ref = typeof DidCommMessageSender !== "undefined" && DidCommMessageSender) === "function" ? _ref : Object,
	typeof (_ref2 = typeof DidCommConnectionService !== "undefined" && DidCommConnectionService) === "function" ? _ref2 : Object,
	typeof (_ref3 = typeof AgentContext !== "undefined" && AgentContext) === "function" ? _ref3 : Object,
	typeof (_ref4 = typeof DidCommProofExchangeRepository !== "undefined" && DidCommProofExchangeRepository) === "function" ? _ref4 : Object,
	typeof (_ref5 = typeof DidCommProofsModuleConfig !== "undefined" && DidCommProofsModuleConfig) === "function" ? _ref5 : Object
])], DidCommProofsApi);

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