const require_rolldown_runtime = require('../../../../../_virtual/rolldown_runtime.js');
const require_decorateMetadata = require('../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorateMetadata.js');
const require_decorate = require('../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js');
require('../../DidCommMessage.js');
const require_decorateParam = require('../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorateParam.js');
const require_DidCommConnectionService = require('../connections/services/DidCommConnectionService.js');
const require_DidCommMessageSender = require('../../DidCommMessageSender.js');
require('../connections/index.js');
const require_getDidCommOutboundMessageContext = require('../../getDidCommOutboundMessageContext.js');
const require_DidCommCredentialState = require('./models/DidCommCredentialState.js');
const require_DidCommCredentialsModuleConfig = require('./DidCommCredentialsModuleConfig.js');
const require_DidCommCredentialExchangeRepository = require('./repository/DidCommCredentialExchangeRepository.js');
const require_DidCommRevocationNotificationService = require('./protocol/revocation-notification/services/DidCommRevocationNotificationService.js');
require('./protocol/revocation-notification/services/index.js');
let __credo_ts_core = require("@credo-ts/core");
__credo_ts_core = require_rolldown_runtime.__toESM(__credo_ts_core);

//#region ../didcomm/src/modules/credentials/DidCommCredentialsApi.ts
var _ref, _ref2, _ref3, _ref4, _ref5, _ref6;
let DidCommCredentialsApi = class DidCommCredentialsApi$1 {
	constructor(messageSender, connectionService, agentContext, logger, credentialExchangeRepository, revocationNotificationService, config) {
		this.messageSender = messageSender;
		this.connectionService = connectionService;
		this.credentialExchangeRepository = credentialExchangeRepository;
		this.agentContext = agentContext;
		this.revocationNotificationService = revocationNotificationService;
		this.logger = logger;
		this.config = config;
	}
	getProtocol(protocolVersion) {
		const credentialProtocol = this.config.credentialProtocols.find((protocol) => protocol.version === protocolVersion);
		if (!credentialProtocol) throw new __credo_ts_core.CredoError(`No credential protocol registered for protocol version ${protocolVersion}`);
		return credentialProtocol;
	}
	/**
	* Initiate a new credential exchange as holder by sending a credential proposal message
	* to the connection with the specified connection id.
	*
	* @param options configuration to use for the proposal
	* @returns Credential exchange record associated with the sent proposal message
	*/
	async proposeCredential(options) {
		const protocol = this.getProtocol(options.protocolVersion);
		const connectionRecord = await this.connectionService.getById(this.agentContext, options.connectionId);
		connectionRecord.assertReady();
		const { credentialExchangeRecord, message } = await protocol.createProposal(this.agentContext, {
			connectionRecord,
			credentialFormats: options.credentialFormats,
			comment: options.comment,
			autoAcceptCredential: options.autoAcceptCredential,
			goalCode: options.goalCode,
			goal: options.goal
		});
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message,
			associatedRecord: credentialExchangeRecord,
			connectionRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return credentialExchangeRecord;
	}
	/**
	* Accept a credential proposal as issuer (by sending a credential offer message) to the connection
	* associated with the credential record.
	*
	* @param options config object for accepting the proposal
	* @returns Credential exchange record associated with the credential offer
	*
	*/
	async acceptProposal(options) {
		const credentialExchangeRecord = await this.getById(options.credentialExchangeRecordId);
		if (!credentialExchangeRecord.connectionId) throw new __credo_ts_core.CredoError(`No connectionId found for credential exchange record '${credentialExchangeRecord.id}'. Connection-less issuance does not support credential proposal or negotiation.`);
		const protocol = this.getProtocol(credentialExchangeRecord.protocolVersion);
		const connectionRecord = await this.connectionService.getById(this.agentContext, credentialExchangeRecord.connectionId);
		connectionRecord.assertReady();
		const { message } = await protocol.acceptProposal(this.agentContext, {
			credentialExchangeRecord,
			credentialFormats: options.credentialFormats,
			comment: options.comment,
			autoAcceptCredential: options.autoAcceptCredential,
			goalCode: options.goalCode,
			goal: options.goal
		});
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message,
			associatedRecord: credentialExchangeRecord,
			connectionRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return credentialExchangeRecord;
	}
	/**
	* Negotiate a credential proposal as issuer (by sending a credential offer message) to the connection
	* associated with the credential record.
	*
	* @param options configuration for the offer see {@link NegotiateCredentialProposalOptions}
	* @returns Credential exchange record associated with the credential offer
	*
	*/
	async negotiateProposal(options) {
		const credentialExchangeRecord = await this.getById(options.credentialExchangeRecordId);
		if (!credentialExchangeRecord.connectionId) throw new __credo_ts_core.CredoError(`No connection id for credential record ${credentialExchangeRecord.id} not found. Connection-less issuance does not support negotiation`);
		const { message } = await this.getProtocol(credentialExchangeRecord.protocolVersion).negotiateProposal(this.agentContext, {
			credentialExchangeRecord,
			credentialFormats: options.credentialFormats,
			comment: options.comment,
			autoAcceptCredential: options.autoAcceptCredential,
			goalCode: options.goalCode,
			goal: options.goal
		});
		const connectionRecord = await this.connectionService.getById(this.agentContext, credentialExchangeRecord.connectionId);
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message,
			associatedRecord: credentialExchangeRecord,
			connectionRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return credentialExchangeRecord;
	}
	/**
	* Initiate a new credential exchange as issuer by sending a credential offer message
	* to the connection with the specified connection id.
	*
	* @param options config options for the credential offer
	* @returns Credential exchange record associated with the sent credential offer message
	*/
	async offerCredential(options) {
		const connectionRecord = await this.connectionService.getById(this.agentContext, options.connectionId);
		const protocol = this.getProtocol(options.protocolVersion);
		this.logger.debug(`Got a credentialProtocol object for version ${options.protocolVersion}`);
		const { message, credentialExchangeRecord } = await protocol.createOffer(this.agentContext, {
			credentialFormats: options.credentialFormats,
			autoAcceptCredential: options.autoAcceptCredential,
			comment: options.comment,
			connectionRecord,
			goalCode: options.goalCode,
			goal: options.goal
		});
		this.logger.debug("Offer Message successfully created; message= ", message);
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message,
			associatedRecord: credentialExchangeRecord,
			connectionRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return credentialExchangeRecord;
	}
	/**
	* Accept a credential offer as holder (by sending a credential request message) to the connection
	* associated with the credential record.
	*
	* @param options The object containing config options of the offer to be accepted
	* @returns Object containing offer associated credential record
	*/
	async acceptOffer(options) {
		const credentialExchangeRecord = await this.getById(options.credentialExchangeRecordId);
		const protocol = this.getProtocol(credentialExchangeRecord.protocolVersion);
		this.logger.debug(`Got a credentialProtocol object for this version; version = ${protocol.version}`);
		const offerMessage = await protocol.findOfferMessage(this.agentContext, credentialExchangeRecord.id);
		if (!offerMessage) throw new __credo_ts_core.CredoError(`No offer message found for credential record with id '${credentialExchangeRecord.id}'`);
		const connectionRecord = credentialExchangeRecord.connectionId ? await this.connectionService.getById(this.agentContext, credentialExchangeRecord.connectionId) : void 0;
		connectionRecord?.assertReady();
		const { message } = await protocol.acceptOffer(this.agentContext, {
			credentialExchangeRecord,
			credentialFormats: options.credentialFormats,
			comment: options.comment,
			autoAcceptCredential: options.autoAcceptCredential,
			goalCode: options.goalCode,
			goal: options.goal
		});
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message,
			connectionRecord,
			associatedRecord: credentialExchangeRecord,
			lastReceivedMessage: offerMessage
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return credentialExchangeRecord;
	}
	async declineOffer(options) {
		const credentialExchangeRecord = await this.getById(options.credentialExchangeRecordId);
		credentialExchangeRecord.assertState(require_DidCommCredentialState.DidCommCredentialState.OfferReceived);
		const protocol = this.getProtocol(credentialExchangeRecord.protocolVersion);
		if (options.sendProblemReport) await this.sendProblemReport({
			credentialExchangeRecordId: options.credentialExchangeRecordId,
			description: options.problemReportDescription ?? "Offer declined"
		});
		await protocol.updateState(this.agentContext, credentialExchangeRecord, require_DidCommCredentialState.DidCommCredentialState.Declined);
		return credentialExchangeRecord;
	}
	async negotiateOffer(options) {
		const credentialExchangeRecord = await this.getById(options.credentialExchangeRecordId);
		if (!credentialExchangeRecord.connectionId) throw new __credo_ts_core.CredoError(`No connection id for credential record ${credentialExchangeRecord.id} not found. Connection-less issuance does not support negotiation`);
		const connectionRecord = await this.connectionService.getById(this.agentContext, credentialExchangeRecord.connectionId);
		connectionRecord.assertReady();
		const { message } = await this.getProtocol(credentialExchangeRecord.protocolVersion).negotiateOffer(this.agentContext, {
			credentialFormats: options.credentialFormats,
			credentialExchangeRecord,
			comment: options.comment,
			autoAcceptCredential: options.autoAcceptCredential,
			goalCode: options.goalCode,
			goal: options.goal
		});
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message,
			associatedRecord: credentialExchangeRecord,
			connectionRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return credentialExchangeRecord;
	}
	/**
	* Initiate a new credential exchange as issuer by creating a credential offer
	* not bound to any connection. The offer must be delivered out-of-band to the holder
	* @param options The credential options to use for the offer
	* @returns The credential record and credential offer message
	*/
	async createOffer(options) {
		const protocol = this.getProtocol(options.protocolVersion);
		this.logger.debug(`Got a credentialProtocol object for version ${options.protocolVersion}`);
		const { message, credentialExchangeRecord } = await protocol.createOffer(this.agentContext, {
			credentialFormats: options.credentialFormats,
			comment: options.comment,
			autoAcceptCredential: options.autoAcceptCredential,
			goalCode: options.goalCode,
			goal: options.goal
		});
		this.logger.debug("Offer Message successfully created", { message });
		return {
			message,
			credentialExchangeRecord
		};
	}
	/**
	* Accept a credential request as holder (by sending a credential request message) to the connection
	* associated with the credential record.
	*
	* @param options The object containing config options of the request
	* @returns DidCommCredentialExchangeRecord updated with information pertaining to this request
	*/
	async acceptRequest(options) {
		const credentialExchangeRecord = await this.getById(options.credentialExchangeRecordId);
		const protocol = this.getProtocol(credentialExchangeRecord.protocolVersion);
		this.logger.debug(`Got a credentialProtocol object for version ${credentialExchangeRecord.protocolVersion}`);
		const connectionRecord = credentialExchangeRecord.connectionId ? await this.connectionService.getById(this.agentContext, credentialExchangeRecord.connectionId) : void 0;
		connectionRecord?.assertReady();
		const requestMessage = await protocol.findRequestMessage(this.agentContext, credentialExchangeRecord.id);
		if (!requestMessage) throw new __credo_ts_core.CredoError(`No request message found for credential record with id '${credentialExchangeRecord.id}'`);
		const offerMessage = await protocol.findOfferMessage(this.agentContext, credentialExchangeRecord.id);
		if (!offerMessage) throw new __credo_ts_core.CredoError(`No offer message found for credential record with id '${credentialExchangeRecord.id}'`);
		const { message } = await protocol.acceptRequest(this.agentContext, {
			credentialExchangeRecord,
			credentialFormats: options.credentialFormats,
			comment: options.comment,
			autoAcceptCredential: options.autoAcceptCredential
		});
		this.logger.debug("We have a credential message (sending outbound): ", message);
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message,
			connectionRecord,
			associatedRecord: credentialExchangeRecord,
			lastReceivedMessage: requestMessage,
			lastSentMessage: offerMessage
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return credentialExchangeRecord;
	}
	/**
	* Accept a credential as holder (by sending a credential acknowledgement message) to the connection
	* associated with the credential record.
	*
	* @param credentialExchangeRecordId The id of the credential exchange record for which to accept the credential
	* @returns credential exchange record associated with the sent credential acknowledgement message
	*
	*/
	async acceptCredential(options) {
		const credentialExchangeRecord = await this.getById(options.credentialExchangeRecordId);
		const protocol = this.getProtocol(credentialExchangeRecord.protocolVersion);
		this.logger.debug(`Got a credentialProtocol object for version ${credentialExchangeRecord.protocolVersion}`);
		const connectionRecord = credentialExchangeRecord.connectionId ? await this.connectionService.getById(this.agentContext, credentialExchangeRecord.connectionId) : void 0;
		connectionRecord?.assertReady();
		if (!await protocol.findRequestMessage(this.agentContext, credentialExchangeRecord.id)) throw new __credo_ts_core.CredoError(`No request message found for credential record with id '${credentialExchangeRecord.id}'`);
		const credentialMessage = await protocol.findCredentialMessage(this.agentContext, credentialExchangeRecord.id);
		if (!credentialMessage) throw new __credo_ts_core.CredoError(`No credential message found for credential record with id '${credentialExchangeRecord.id}'`);
		const { message } = await protocol.acceptCredential(this.agentContext, { credentialExchangeRecord });
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message,
			connectionRecord,
			associatedRecord: credentialExchangeRecord,
			lastReceivedMessage: credentialMessage
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return credentialExchangeRecord;
	}
	/**
	* Send a revocation notification for a credential exchange record. Currently Revocation Notification V2 protocol is supported
	*
	* @param credentialExchangeRecordId The id of the credential record for which to send revocation notification
	*/
	async sendRevocationNotification(options) {
		const { credentialExchangeRecordId, revocationId, revocationFormat, comment, requestAck } = options;
		const credentialExchangeRecord = await this.getById(credentialExchangeRecordId);
		const { message } = await this.revocationNotificationService.v2CreateRevocationNotification({
			credentialId: revocationId,
			revocationFormat,
			comment,
			requestAck
		});
		const protocol = this.getProtocol(credentialExchangeRecord.protocolVersion);
		if (!await protocol.findRequestMessage(this.agentContext, credentialExchangeRecord.id)) throw new __credo_ts_core.CredoError(`No request message found for credential record with id '${credentialExchangeRecord.id}'`);
		if (!await protocol.findOfferMessage(this.agentContext, credentialExchangeRecord.id)) throw new __credo_ts_core.CredoError(`No offer message found for credential record with id '${credentialExchangeRecord.id}'`);
		const connectionRecord = credentialExchangeRecord.connectionId ? await this.connectionService.getById(this.agentContext, credentialExchangeRecord.connectionId) : void 0;
		connectionRecord?.assertReady();
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message,
			connectionRecord,
			associatedRecord: credentialExchangeRecord
		});
		await this.messageSender.sendMessage(outboundMessageContext);
	}
	/**
	* Send problem report message for a credential record
	* @param credentialExchangeRecordId The id of the credential exchange record for which to send problem report
	* @returns credential record associated with the credential problem report message
	*/
	async sendProblemReport(options) {
		const credentialExchangeRecord = await this.getById(options.credentialExchangeRecordId);
		const protocol = this.getProtocol(credentialExchangeRecord.protocolVersion);
		const offerMessage = await protocol.findOfferMessage(this.agentContext, credentialExchangeRecord.id);
		const { message: problemReport } = await protocol.createProblemReport(this.agentContext, {
			description: options.description,
			credentialExchangeRecord
		});
		const connectionRecord = credentialExchangeRecord.connectionId ? await this.connectionService.getById(this.agentContext, credentialExchangeRecord.connectionId) : void 0;
		connectionRecord?.assertReady();
		if (!connectionRecord) {
			credentialExchangeRecord.assertState(require_DidCommCredentialState.DidCommCredentialState.OfferReceived);
			if (!offerMessage) throw new __credo_ts_core.CredoError(`No offer message found for credential record with id '${credentialExchangeRecord.id}'`);
		}
		const outboundMessageContext = await require_getDidCommOutboundMessageContext.getOutboundDidCommMessageContext(this.agentContext, {
			message: problemReport,
			connectionRecord,
			associatedRecord: credentialExchangeRecord,
			lastReceivedMessage: offerMessage ?? void 0
		});
		await this.messageSender.sendMessage(outboundMessageContext);
		return credentialExchangeRecord;
	}
	async getFormatData(credentialRecordId) {
		const credentialExchangeRecord = await this.getById(credentialRecordId);
		return this.getProtocol(credentialExchangeRecord.protocolVersion).getFormatData(this.agentContext, credentialRecordId);
	}
	/**
	* Retrieve a credential record by id
	*
	* @param credentialRecordId The credential record id
	* @throws {RecordNotFoundError} If no record is found
	* @return The credential record
	*
	*/
	getById(credentialRecordId) {
		return this.credentialExchangeRepository.getById(this.agentContext, credentialRecordId);
	}
	/**
	* Retrieve all credential records
	*
	* @returns List containing all credential records
	*/
	getAll() {
		return this.credentialExchangeRepository.getAll(this.agentContext);
	}
	/**
	* Retrieve all credential records by specified query params
	*
	* @returns List containing all credential records matching specified query paramaters
	*/
	findAllByQuery(query, queryOptions) {
		return this.credentialExchangeRepository.findByQuery(this.agentContext, query, queryOptions);
	}
	/**
	* Find a credential record by id
	*
	* @param credentialRecordId the credential record id
	* @returns The credential record or null if not found
	*/
	findById(credentialRecordId) {
		return this.credentialExchangeRepository.findById(this.agentContext, credentialRecordId);
	}
	/**
	* Delete a credential record by id, also calls service to delete from wallet
	*
	* @param credentialId the credential record id
	* @param options the delete credential options for the delete operation
	*/
	async deleteById(credentialId, options) {
		const credentialExchangeRecord = await this.getById(credentialId);
		return this.getProtocol(credentialExchangeRecord.protocolVersion).delete(this.agentContext, credentialExchangeRecord, options);
	}
	/**
	* Update a credential exchange record
	*
	* @param credentialExchangeRecord the credential exchange record
	*/
	async update(credentialExchangeRecord) {
		await this.credentialExchangeRepository.update(this.agentContext, credentialExchangeRecord);
	}
	async findProposalMessage(credentialExchangeId) {
		return (await this.getServiceForCredentialExchangeId(credentialExchangeId)).findProposalMessage(this.agentContext, credentialExchangeId);
	}
	async findOfferMessage(credentialExchangeId) {
		return (await this.getServiceForCredentialExchangeId(credentialExchangeId)).findOfferMessage(this.agentContext, credentialExchangeId);
	}
	async findRequestMessage(credentialExchangeId) {
		return (await this.getServiceForCredentialExchangeId(credentialExchangeId)).findRequestMessage(this.agentContext, credentialExchangeId);
	}
	async findCredentialMessage(credentialExchangeId) {
		return (await this.getServiceForCredentialExchangeId(credentialExchangeId)).findCredentialMessage(this.agentContext, credentialExchangeId);
	}
	async getServiceForCredentialExchangeId(credentialExchangeId) {
		const credentialExchangeRecord = await this.getById(credentialExchangeId);
		return this.getProtocol(credentialExchangeRecord.protocolVersion);
	}
};
DidCommCredentialsApi = require_decorate.__decorate([
	(0, __credo_ts_core.injectable)(),
	require_decorateParam.__decorateParam(3, (0, __credo_ts_core.inject)(__credo_ts_core.InjectionSymbols.Logger)),
	require_decorateMetadata.__decorateMetadata("design:paramtypes", [
		typeof (_ref = typeof require_DidCommMessageSender.DidCommMessageSender !== "undefined" && require_DidCommMessageSender.DidCommMessageSender) === "function" ? _ref : Object,
		typeof (_ref2 = typeof require_DidCommConnectionService.DidCommConnectionService !== "undefined" && require_DidCommConnectionService.DidCommConnectionService) === "function" ? _ref2 : Object,
		typeof (_ref3 = typeof __credo_ts_core.AgentContext !== "undefined" && __credo_ts_core.AgentContext) === "function" ? _ref3 : Object,
		Object,
		typeof (_ref4 = typeof require_DidCommCredentialExchangeRepository.DidCommCredentialExchangeRepository !== "undefined" && require_DidCommCredentialExchangeRepository.DidCommCredentialExchangeRepository) === "function" ? _ref4 : Object,
		typeof (_ref5 = typeof require_DidCommRevocationNotificationService.DidCommRevocationNotificationService !== "undefined" && require_DidCommRevocationNotificationService.DidCommRevocationNotificationService) === "function" ? _ref5 : Object,
		typeof (_ref6 = typeof require_DidCommCredentialsModuleConfig.DidCommCredentialsModuleConfig !== "undefined" && require_DidCommCredentialsModuleConfig.DidCommCredentialsModuleConfig) === "function" ? _ref6 : Object
	])
], DidCommCredentialsApi);

//#endregion
Object.defineProperty(exports, 'DidCommCredentialsApi', {
  enumerable: true,
  get: function () {
    return DidCommCredentialsApi;
  }
});