diff --git a/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.service.ts b/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.service.ts index 8c92094f8027661c2b4d0b86ae8c1a0831dce147..103f0c2ba80d4795a13fe4d0de965991cc2ae266 100644 --- a/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.service.ts +++ b/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.service.ts @@ -34,11 +34,15 @@ import { Injectable } from '@nestjs/common'; import { logger } from '@ocm/shared'; import { GenericRecordTokens, MetadataTokens } from '../../common/constants.js'; +import { AgentService } from '../agent.service.js'; import { WithTenantService } from '../withTenantService.js'; @Injectable() export class AnonCredsCredentialsService { - public constructor(private withTenantService: WithTenantService) {} + public constructor( + private withTenantService: WithTenantService, + private agentService: AgentService, + ) {} public async getAll({ tenantId, @@ -215,36 +219,50 @@ export class AnonCredsCredentialsService { const revocationRegistryIndex = await this.getNextRevocationIdx(t); - const acceptOfferListener: Promise<CredentialExchangeRecord> = - new Promise((resolve) => - t.events.on<CredentialStateChangedEvent>( - CredentialEventTypes.CredentialStateChanged, - async ({ payload: { credentialRecord } }) => { - const connection = connections.find( - (c) => c.id === credentialRecord.connectionId, - ); - - const withSelf = connection?.metadata.get<{ withSelf: boolean }>( - MetadataTokens.CONNECTION_METADATA_KEY, - ); - - const isWithSelf = withSelf?.withSelf ?? false; - - if ( - credentialRecord.state === CredentialState.OfferReceived && - isWithSelf - ) { - resolve( - await t.credentials.acceptOffer({ - credentialRecordId: credentialRecord.id, - }), - ); - } - }, - ), + const acceptOfferListener = new Promise((resolve) => { + this.agentService.agent.events.on<CredentialStateChangedEvent>( + CredentialEventTypes.CredentialStateChanged, + async ({ payload: { credentialRecord } }) => { + const { connectionId } = credentialRecord; + if ( + !connectionId || + credentialRecord.state !== CredentialState.OfferReceived + ) { + return; + } + + const connectionRecord = await t.connections.getById(connectionId); + + const metadata = connectionRecord.metadata.get<{ + withSelf: boolean; + }>(MetadataTokens.CONNECTION_METADATA_KEY); + + if (!metadata || metadata.withSelf === false) return; + + await t.credentials.acceptOffer({ + credentialRecordId: credentialRecord.id, + autoAcceptCredential: AutoAcceptCredential.Always, + }); + + resolve(connectionRecord); + }, ); + }); - await t.credentials.offerCredential({ + const waitUntilDone = new Promise<CredentialExchangeRecord>((resolve) => + this.agentService.agent.events.on<CredentialStateChangedEvent>( + CredentialEventTypes.CredentialStateChanged, + ({ payload: { credentialRecord } }) => { + if ( + credentialRecord.state === CredentialState.Done || + credentialRecord.state === CredentialState.CredentialIssued + ) + resolve(credentialRecord); + }, + ), + ); + + void t.credentials.offerCredential({ protocolVersion: 'v2', autoAcceptCredential: AutoAcceptCredential.Always, connectionId: connection.id, @@ -258,7 +276,9 @@ export class AnonCredsCredentialsService { }, }); - return acceptOfferListener; + await acceptOfferListener; + + return waitUntilDone; }); } diff --git a/apps/ssi-abstraction/src/agent/connections/connections.service.ts b/apps/ssi-abstraction/src/agent/connections/connections.service.ts index 7ee1261a4e037a81b21b9f722ac33f4d8f3912b5..7981414335eaa5fc2b92e32b2ae2e11582048e21 100644 --- a/apps/ssi-abstraction/src/agent/connections/connections.service.ts +++ b/apps/ssi-abstraction/src/agent/connections/connections.service.ts @@ -152,6 +152,7 @@ export class ConnectionsService { trusted: true, withSelf: true, }); + const connRepo = t.dependencyManager.resolve(ConnectionRepository); await connRepo.update(t.context, connectionRecord); }