From c68145aa291332571b286d9bc9406432207e3278 Mon Sep 17 00:00:00 2001 From: Ariel Gentile Date: Thu, 24 Nov 2022 17:59:22 -0500 Subject: [PATCH] feat!: add AgentMessageSentEvent and associate records to outbound messages (#1099) Signed-off-by: Ariel Gentile --- packages/action-menu/src/ActionMenuApi.ts | 29 +- packages/core/src/agent/Dispatcher.ts | 45 ++- packages/core/src/agent/Events.ts | 10 + packages/core/src/agent/Handler.ts | 5 +- packages/core/src/agent/MessageReceiver.ts | 9 +- packages/core/src/agent/MessageSender.ts | 168 ++++++--- .../src/agent/__tests__/MessageSender.test.ts | 335 ++++++++++++++---- packages/core/src/agent/helpers.ts | 34 -- .../agent/models/OutboundMessageContext.ts | 76 ++++ .../agent/models/OutboundMessageSendStatus.ts | 6 + packages/core/src/agent/models/index.ts | 2 + .../core/src/error/MessageSendingError.ts | 11 +- packages/core/src/index.ts | 1 - .../basic-messages/BasicMessagesApi.ts | 11 +- .../__tests__/basic-messages.e2e.test.ts | 12 +- .../src/modules/connections/ConnectionsApi.ts | 38 +- .../handlers/ConnectionRequestHandler.ts | 8 +- .../handlers/ConnectionResponseHandler.ts | 4 +- .../handlers/DidExchangeRequestHandler.ts | 8 +- .../handlers/DidExchangeResponseHandler.ts | 26 +- .../connections/services/TrustPingService.ts | 6 +- .../src/modules/credentials/CredentialsApi.ts | 122 +++++-- .../v1/handlers/V1IssueCredentialHandler.ts | 18 +- .../v1/handlers/V1OfferCredentialHandler.ts | 18 +- .../v1/handlers/V1ProposeCredentialHandler.ts | 8 +- .../v1/handlers/V1RequestCredentialHandler.ts | 18 +- .../v2/handlers/V2IssueCredentialHandler.ts | 18 +- .../v2/handlers/V2OfferCredentialHandler.ts | 18 +- .../v2/handlers/V2ProposeCredentialHandler.ts | 8 +- .../v2/handlers/V2RequestCredentialHandler.ts | 18 +- .../discover-features/DiscoverFeaturesApi.ts | 16 +- .../v1/handlers/V1QueryMessageHandler.ts | 7 +- .../v2/handlers/V2QueriesMessageHandler.ts | 7 +- packages/core/src/modules/oob/OutOfBandApi.ts | 9 +- .../oob/handlers/HandshakeReuseHandler.ts | 7 +- packages/core/src/modules/proofs/ProofsApi.ts | 82 +++-- .../v1/handlers/V1PresentationHandler.ts | 18 +- .../handlers/V1ProposePresentationHandler.ts | 8 +- .../handlers/V1RequestPresentationHandler.ts | 18 +- .../v2/handlers/V2PresentationHandler.ts | 18 +- .../handlers/V2ProposePresentationHandler.ts | 8 +- .../handlers/V2RequestPresentationHandler.ts | 18 +- .../core/src/modules/routing/MediatorApi.ts | 10 +- .../core/src/modules/routing/RecipientApi.ts | 65 ++-- .../routing/handlers/KeylistUpdateHandler.ts | 7 +- .../handlers/MediationRequestHandler.ts | 8 +- .../pickup/v1/MessagePickupService.ts | 4 +- .../pickup/v2/V2MessagePickupService.ts | 10 +- .../v2/handlers/MessageDeliveryHandler.ts | 7 +- .../pickup/v2/handlers/StatusHandler.ts | 7 +- .../services/MediationRecipientService.ts | 12 +- .../__tests__/V2MessagePickupService.test.ts | 68 ++-- packages/core/src/types.ts | 14 - .../core/tests/multi-protocol-version.test.ts | 10 +- .../question-answer/src/QuestionAnswerApi.ts | 20 +- samples/extension-module/dummy/DummyApi.ts | 21 +- .../dummy/handlers/DummyRequestHandler.ts | 4 +- 57 files changed, 1082 insertions(+), 491 deletions(-) delete mode 100644 packages/core/src/agent/helpers.ts create mode 100644 packages/core/src/agent/models/OutboundMessageContext.ts create mode 100644 packages/core/src/agent/models/OutboundMessageSendStatus.ts diff --git a/packages/action-menu/src/ActionMenuApi.ts b/packages/action-menu/src/ActionMenuApi.ts index 6efd081e9a..c8569894c7 100644 --- a/packages/action-menu/src/ActionMenuApi.ts +++ b/packages/action-menu/src/ActionMenuApi.ts @@ -12,7 +12,7 @@ import { ConnectionService, Dispatcher, MessageSender, - createOutboundMessage, + OutboundMessageContext, injectable, } from '@aries-framework/core' @@ -59,8 +59,13 @@ export class ActionMenuApi { connection, }) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: record, + }) + + await this.messageSender.sendMessage(outboundMessageContext) return record } @@ -80,8 +85,13 @@ export class ActionMenuApi { menu: options.menu, }) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: record, + }) + + await this.messageSender.sendMessage(outboundMessageContext) return record } @@ -109,8 +119,13 @@ export class ActionMenuApi { performedAction: options.performedAction, }) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: record, + }) + + await this.messageSender.sendMessage(outboundMessageContext) return record } diff --git a/packages/core/src/agent/Dispatcher.ts b/packages/core/src/agent/Dispatcher.ts index e55a324f85..acc6bd9a05 100644 --- a/packages/core/src/agent/Dispatcher.ts +++ b/packages/core/src/agent/Dispatcher.ts @@ -1,4 +1,3 @@ -import type { OutboundMessage, OutboundServiceMessage } from '../types' import type { AgentMessage } from './AgentMessage' import type { AgentMessageProcessedEvent } from './Events' import type { Handler } from './Handler' @@ -14,7 +13,7 @@ import { ProblemReportMessage } from './../modules/problem-reports/messages/Prob import { EventEmitter } from './EventEmitter' import { AgentEventTypes } from './Events' import { MessageSender } from './MessageSender' -import { isOutboundServiceMessage } from './helpers' +import { OutboundMessageContext } from './models' @injectable() class Dispatcher { @@ -38,14 +37,14 @@ class Dispatcher { } public async dispatch(messageContext: InboundMessageContext): Promise { - const message = messageContext.message + const { agentContext, connection, senderKey, recipientKey, message } = messageContext const handler = this.getHandlerForType(message.type) if (!handler) { throw new AriesFrameworkError(`No handler for message type "${message.type}" found`) } - let outboundMessage: OutboundMessage | OutboundServiceMessage | void + let outboundMessage: OutboundMessageContext | void try { outboundMessage = await handler.handle(messageContext) @@ -54,43 +53,39 @@ class Dispatcher { if (problemReportMessage instanceof ProblemReportMessage && messageContext.connection) { problemReportMessage.setThread({ - threadId: messageContext.message.threadId, + threadId: message.threadId, }) - outboundMessage = { - payload: problemReportMessage, + outboundMessage = new OutboundMessageContext(problemReportMessage, { + agentContext, connection: messageContext.connection, - } + }) } else { this.logger.error(`Error handling message with type ${message.type}`, { message: message.toJSON(), error, - senderKey: messageContext.senderKey?.fingerprint, - recipientKey: messageContext.recipientKey?.fingerprint, - connectionId: messageContext.connection?.id, + senderKey: senderKey?.fingerprint, + recipientKey: recipientKey?.fingerprint, + connectionId: connection?.id, }) throw error } } - if (outboundMessage && isOutboundServiceMessage(outboundMessage)) { - await this.messageSender.sendMessageToService(messageContext.agentContext, { - message: outboundMessage.payload, - service: outboundMessage.service, - senderKey: outboundMessage.senderKey, - returnRoute: true, - }) - } else if (outboundMessage) { - outboundMessage.sessionId = messageContext.sessionId - await this.messageSender.sendMessage(messageContext.agentContext, outboundMessage) + if (outboundMessage) { + if (outboundMessage.isOutboundServiceMessage()) { + await this.messageSender.sendMessageToService(outboundMessage) + } else { + outboundMessage.sessionId = messageContext.sessionId + await this.messageSender.sendMessage(outboundMessage) + } } - // Emit event that allows to hook into received messages - this.eventEmitter.emit(messageContext.agentContext, { + this.eventEmitter.emit(agentContext, { type: AgentEventTypes.AgentMessageProcessed, payload: { - message: messageContext.message, - connection: messageContext.connection, + message, + connection, }, }) } diff --git a/packages/core/src/agent/Events.ts b/packages/core/src/agent/Events.ts index 3688479795..4e7bb4b076 100644 --- a/packages/core/src/agent/Events.ts +++ b/packages/core/src/agent/Events.ts @@ -1,5 +1,6 @@ import type { ConnectionRecord } from '../modules/connections' import type { AgentMessage } from './AgentMessage' +import type { OutboundMessageContext, OutboundMessageSendStatus } from './models' import type { Observable } from 'rxjs' import { filter } from 'rxjs' @@ -13,6 +14,7 @@ export function filterContextCorrelationId(contextCorrelationId: string) { export enum AgentEventTypes { AgentMessageReceived = 'AgentMessageReceived', AgentMessageProcessed = 'AgentMessageProcessed', + AgentMessageSent = 'AgentMessageSent', } export interface EventMetadata { @@ -41,3 +43,11 @@ export interface AgentMessageProcessedEvent extends BaseEvent { connection?: ConnectionRecord } } + +export interface AgentMessageSentEvent extends BaseEvent { + type: typeof AgentEventTypes.AgentMessageSent + payload: { + message: OutboundMessageContext + status: OutboundMessageSendStatus + } +} diff --git a/packages/core/src/agent/Handler.ts b/packages/core/src/agent/Handler.ts index 7a43bbbbbe..e736aad3da 100644 --- a/packages/core/src/agent/Handler.ts +++ b/packages/core/src/agent/Handler.ts @@ -1,11 +1,10 @@ -import type { OutboundMessage, OutboundServiceMessage } from '../types' import type { ConstructableAgentMessage } from './AgentMessage' -import type { InboundMessageContext } from './models/InboundMessageContext' +import type { InboundMessageContext, OutboundMessageContext } from './models' export interface Handler { readonly supportedMessages: readonly ConstructableAgentMessage[] - handle(messageContext: InboundMessageContext): Promise + handle(messageContext: InboundMessageContext): Promise } /** diff --git a/packages/core/src/agent/MessageReceiver.ts b/packages/core/src/agent/MessageReceiver.ts index 88b052cc42..2c94f6596f 100644 --- a/packages/core/src/agent/MessageReceiver.ts +++ b/packages/core/src/agent/MessageReceiver.ts @@ -21,8 +21,7 @@ import { EnvelopeService } from './EnvelopeService' import { MessageSender } from './MessageSender' import { TransportService } from './TransportService' import { AgentContextProvider } from './context' -import { createOutboundMessage } from './helpers' -import { InboundMessageContext } from './models/InboundMessageContext' +import { InboundMessageContext, OutboundMessageContext } from './models' @injectable() export class MessageReceiver { @@ -277,9 +276,9 @@ export class MessageReceiver { problemReportMessage.setThread({ threadId: plaintextMessage['@id'], }) - const outboundMessage = createOutboundMessage(connection, problemReportMessage) - if (outboundMessage) { - await this.messageSender.sendMessage(agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(problemReportMessage, { agentContext, connection }) + if (outboundMessageContext) { + await this.messageSender.sendMessage(outboundMessageContext) } } } diff --git a/packages/core/src/agent/MessageSender.ts b/packages/core/src/agent/MessageSender.ts index bbbcb1be8f..ac9ac731a2 100644 --- a/packages/core/src/agent/MessageSender.ts +++ b/packages/core/src/agent/MessageSender.ts @@ -1,12 +1,12 @@ -import type { Key } from '../crypto' import type { ConnectionRecord } from '../modules/connections' import type { ResolvedDidCommService } from '../modules/didcomm' import type { DidDocument } from '../modules/dids' import type { OutOfBandRecord } from '../modules/oob/repository' import type { OutboundTransport } from '../transport/OutboundTransport' -import type { OutboundMessage, OutboundPackage, EncryptedMessage } from '../types' +import type { OutboundPackage, EncryptedMessage } from '../types' import type { AgentMessage } from './AgentMessage' import type { EnvelopeKeys } from './EnvelopeService' +import type { AgentMessageSentEvent } from './Events' import type { TransportSession } from './TransportService' import type { AgentContext } from './context' @@ -18,14 +18,16 @@ import { DidCommDocumentService } from '../modules/didcomm' import { getKeyDidMappingByVerificationMethod } from '../modules/dids/domain/key-type' import { didKeyToInstanceOfKey } from '../modules/dids/helpers' import { DidResolverService } from '../modules/dids/services/DidResolverService' -import { OutOfBandRepository } from '../modules/oob/repository' import { inject, injectable } from '../plugins' import { MessageRepository } from '../storage/MessageRepository' import { MessageValidator } from '../utils/MessageValidator' import { getProtocolScheme } from '../utils/uri' import { EnvelopeService } from './EnvelopeService' +import { EventEmitter } from './EventEmitter' +import { AgentEventTypes } from './Events' import { TransportService } from './TransportService' +import { OutboundMessageContext, OutboundMessageSendStatus } from './models' export interface TransportPriorityOptions { schemes: string[] @@ -40,7 +42,7 @@ export class MessageSender { private logger: Logger private didResolverService: DidResolverService private didCommDocumentService: DidCommDocumentService - private outOfBandRepository: OutOfBandRepository + private eventEmitter: EventEmitter public readonly outboundTransports: OutboundTransport[] = [] public constructor( @@ -50,7 +52,7 @@ export class MessageSender { @inject(InjectionSymbols.Logger) logger: Logger, didResolverService: DidResolverService, didCommDocumentService: DidCommDocumentService, - outOfBandRepository: OutOfBandRepository + eventEmitter: EventEmitter ) { this.envelopeService = envelopeService this.transportService = transportService @@ -58,7 +60,7 @@ export class MessageSender { this.logger = logger this.didResolverService = didResolverService this.didCommDocumentService = didCommDocumentService - this.outOfBandRepository = outOfBandRepository + this.eventEmitter = eventEmitter this.outboundTransports = [] } @@ -178,17 +180,24 @@ export class MessageSender { } public async sendMessage( - agentContext: AgentContext, - outboundMessage: OutboundMessage, + outboundMessageContext: OutboundMessageContext, options?: { transportPriority?: TransportPriorityOptions } ) { - const { connection, outOfBand, sessionId, payload } = outboundMessage + const { agentContext, connection, outOfBand, sessionId, message } = outboundMessageContext const errors: Error[] = [] + if (!connection) { + this.logger.error('Outbound message has no associated connection') + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.Undeliverable) + throw new MessageSendingError('Outbound message has no associated connection', { + outboundMessageContext, + }) + } + this.logger.debug('Send outbound message', { - message: payload, + message, connectionId: connection.id, }) @@ -202,10 +211,11 @@ export class MessageSender { session = this.transportService.findSessionByConnectionId(connection.id) } - if (session?.inboundMessage?.hasReturnRouting(payload.threadId)) { - this.logger.debug(`Found session with return routing for message '${payload.id}' (connection '${connection.id}'`) + if (session?.inboundMessage?.hasReturnRouting(message.threadId)) { + this.logger.debug(`Found session with return routing for message '${message.id}' (connection '${connection.id}'`) try { - await this.sendMessageToSession(agentContext, session, payload) + await this.sendMessageToSession(agentContext, session, message) + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.SentToSession) return } catch (error) { errors.push(error) @@ -214,22 +224,46 @@ export class MessageSender { } // Retrieve DIDComm services - const { services, queueService } = await this.retrieveServicesByConnection( - agentContext, - connection, - options?.transportPriority, - outOfBand - ) + let services: ResolvedDidCommService[] = [] + let queueService: ResolvedDidCommService | undefined + + try { + ;({ services, queueService } = await this.retrieveServicesByConnection( + agentContext, + connection, + options?.transportPriority, + outOfBand + )) + } catch (error) { + this.logger.error(`Unable to retrieve services for connection '${connection.id}`) + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.Undeliverable) + throw new MessageSendingError(`Unable to retrieve services for connection '${connection.id}`, { + outboundMessageContext, + cause: error, + }) + } if (!connection.did) { this.logger.error(`Unable to send message using connection '${connection.id}' that doesn't have a did`) + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.Undeliverable) throw new MessageSendingError( `Unable to send message using connection '${connection.id}' that doesn't have a did`, - { outboundMessage } + { outboundMessageContext } ) } - const ourDidDocument = await this.didResolverService.resolveDidDocument(agentContext, connection.did) + let ourDidDocument: DidDocument + try { + ourDidDocument = await this.didResolverService.resolveDidDocument(agentContext, connection.did) + } catch (error) { + this.logger.error(`Unable to resolve DID Document for '${connection.did}`) + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.Undeliverable) + throw new MessageSendingError(`Unable to resolve DID Document for '${connection.did}`, { + outboundMessageContext, + cause: error, + }) + } + const ourAuthenticationKeys = getAuthenticationKeys(ourDidDocument) // TODO We're selecting just the first authentication key. Is it ok? @@ -244,19 +278,24 @@ export class MessageSender { const [firstOurAuthenticationKey] = ourAuthenticationKeys // If the returnRoute is already set we won't override it. This allows to set the returnRoute manually if this is desired. const shouldAddReturnRoute = - payload.transport?.returnRoute === undefined && !this.transportService.hasInboundEndpoint(ourDidDocument) + message.transport?.returnRoute === undefined && !this.transportService.hasInboundEndpoint(ourDidDocument) // Loop trough all available services and try to send the message for await (const service of services) { try { // Enable return routing if the our did document does not have any inbound endpoint for given sender key - await this.sendMessageToService(agentContext, { - message: payload, - service, - senderKey: firstOurAuthenticationKey, - returnRoute: shouldAddReturnRoute, - connectionId: connection.id, - }) + await this.sendToService( + new OutboundMessageContext(message, { + agentContext, + serviceParams: { + service, + senderKey: firstOurAuthenticationKey, + returnRoute: shouldAddReturnRoute, + }, + connection, + }) + ) + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.SentToTransport) return } catch (error) { errors.push(error) @@ -281,39 +320,57 @@ export class MessageSender { senderKey: firstOurAuthenticationKey, } - const encryptedMessage = await this.envelopeService.packMessage(agentContext, payload, keys) + const encryptedMessage = await this.envelopeService.packMessage(agentContext, message, keys) await this.messageRepository.add(connection.id, encryptedMessage) + + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.QueuedForPickup) + return } // Message is undeliverable this.logger.error(`Message is undeliverable to connection ${connection.id} (${connection.theirLabel})`, { - message: payload, + message, errors, connection, }) + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.Undeliverable) + throw new MessageSendingError( `Message is undeliverable to connection ${connection.id} (${connection.theirLabel})`, - { outboundMessage } + { outboundMessageContext } ) } - public async sendMessageToService( - agentContext: AgentContext, - { - message, - service, - senderKey, - returnRoute, - connectionId, - }: { - message: AgentMessage - service: ResolvedDidCommService - senderKey: Key - returnRoute?: boolean - connectionId?: string + public async sendMessageToService(outboundMessageContext: OutboundMessageContext) { + try { + await this.sendToService(outboundMessageContext) + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.SentToTransport) + } catch (error) { + this.logger.error( + `Message is undeliverable to service with id ${outboundMessageContext.serviceParams?.service.id}: ${error.message}`, + { + message: outboundMessageContext.message, + error, + } + ) + this.emitMessageSentEvent(outboundMessageContext, OutboundMessageSendStatus.Undeliverable) + + throw new MessageSendingError( + `Message is undeliverable to service with id ${outboundMessageContext.serviceParams?.service.id}: ${error.message}`, + { outboundMessageContext } + ) } - ) { + } + + private async sendToService(outboundMessageContext: OutboundMessageContext) { + const { agentContext, message, serviceParams, connection } = outboundMessageContext + + if (!serviceParams) { + throw new AriesFrameworkError('No service parameters found in outbound message context') + } + const { service, senderKey, returnRoute } = serviceParams + if (this.outboundTransports.length === 0) { throw new AriesFrameworkError('Agent has no outbound transport!') } @@ -350,7 +407,7 @@ export class MessageSender { const outboundPackage = await this.packMessage(agentContext, { message, keys, endpoint: service.serviceEndpoint }) outboundPackage.endpoint = service.serviceEndpoint - outboundPackage.connectionId = connectionId + outboundPackage.connectionId = connection?.id for (const transport of this.outboundTransports) { const protocolScheme = getProtocolScheme(service.serviceEndpoint) if (!protocolScheme) { @@ -360,7 +417,9 @@ export class MessageSender { return } } - throw new AriesFrameworkError(`Unable to send message to service: ${service.serviceEndpoint}`) + throw new MessageSendingError(`Unable to send message to service: ${service.serviceEndpoint}`, { + outboundMessageContext, + }) } private async retrieveServicesByConnection( @@ -427,6 +486,17 @@ export class MessageSender { ) return { services, queueService } } + + private emitMessageSentEvent(outboundMessageContext: OutboundMessageContext, status: OutboundMessageSendStatus) { + const { agentContext } = outboundMessageContext + this.eventEmitter.emit(agentContext, { + type: AgentEventTypes.AgentMessageSent, + payload: { + message: outboundMessageContext, + status, + }, + }) + } } export function isDidCommTransportQueue(serviceEndpoint: string): serviceEndpoint is typeof DID_COMM_TRANSPORT_QUEUE { diff --git a/packages/core/src/agent/__tests__/MessageSender.test.ts b/packages/core/src/agent/__tests__/MessageSender.test.ts index 7776df1ea8..35d566c3b0 100644 --- a/packages/core/src/agent/__tests__/MessageSender.test.ts +++ b/packages/core/src/agent/__tests__/MessageSender.test.ts @@ -1,12 +1,22 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ import type { ConnectionRecord } from '../../modules/connections' import type { ResolvedDidCommService } from '../../modules/didcomm' import type { DidDocumentService } from '../../modules/dids' import type { MessageRepository } from '../../storage/MessageRepository' import type { OutboundTransport } from '../../transport' -import type { OutboundMessage, EncryptedMessage } from '../../types' +import type { EncryptedMessage } from '../../types' +import type { AgentMessageSentEvent } from '../Events' + +import { Subject } from 'rxjs' import { TestMessage } from '../../../tests/TestMessage' -import { getAgentConfig, getAgentContext, getMockConnection, mockFunction } from '../../../tests/helpers' +import { + agentDependencies, + getAgentConfig, + getAgentContext, + getMockConnection, + mockFunction, +} from '../../../tests/helpers' import testLogger from '../../../tests/logger' import { Key, KeyType } from '../../crypto' import { ReturnRouteTypes } from '../../decorators/transport/TransportDecorator' @@ -14,12 +24,13 @@ import { DidCommDocumentService } from '../../modules/didcomm' import { DidResolverService, DidDocument, VerificationMethod } from '../../modules/dids' import { DidCommV1Service } from '../../modules/dids/domain/service/DidCommV1Service' import { verkeyToInstanceOfKey } from '../../modules/dids/helpers' -import { OutOfBandRepository } from '../../modules/oob' import { InMemoryMessageRepository } from '../../storage/InMemoryMessageRepository' import { EnvelopeService as EnvelopeServiceImpl } from '../EnvelopeService' +import { EventEmitter } from '../EventEmitter' +import { AgentEventTypes } from '../Events' import { MessageSender } from '../MessageSender' import { TransportService } from '../TransportService' -import { createOutboundMessage } from '../helpers' +import { OutboundMessageContext, OutboundMessageSendStatus } from '../models' import { DummyTransportSession } from './stubs' @@ -27,14 +38,12 @@ jest.mock('../TransportService') jest.mock('../EnvelopeService') jest.mock('../../modules/dids/services/DidResolverService') jest.mock('../../modules/didcomm/services/DidCommDocumentService') -jest.mock('../../modules/oob/repository/OutOfBandRepository') const logger = testLogger const TransportServiceMock = TransportService as jest.MockedClass const DidResolverServiceMock = DidResolverService as jest.Mock const DidCommDocumentServiceMock = DidCommDocumentService as jest.Mock -const OutOfBandRepositoryMock = OutOfBandRepository as jest.Mock class DummyHttpOutboundTransport implements OutboundTransport { public start(): Promise { @@ -83,7 +92,7 @@ describe('MessageSender', () => { const didResolverService = new DidResolverServiceMock() const didCommDocumentService = new DidCommDocumentServiceMock() - const outOfBandRepository = new OutOfBandRepositoryMock() + const eventEmitter = new EventEmitter(agentDependencies, new Subject()) const didResolverServiceResolveMock = mockFunction(didResolverService.resolveDidDocument) const didResolverServiceResolveDidServicesMock = mockFunction(didCommDocumentService.resolveServicesFromDid) @@ -125,15 +134,18 @@ describe('MessageSender', () => { let outboundTransport: OutboundTransport let messageRepository: MessageRepository let connection: ConnectionRecord - let outboundMessage: OutboundMessage + let outboundMessageContext: OutboundMessageContext const agentConfig = getAgentConfig('MessageSender') const agentContext = getAgentContext() + const eventListenerMock = jest.fn() describe('sendMessage', () => { beforeEach(() => { TransportServiceMock.mockClear() DidResolverServiceMock.mockClear() + eventEmitter.on(AgentEventTypes.AgentMessageSent, eventListenerMock) + outboundTransport = new DummyHttpOutboundTransport() messageRepository = new InMemoryMessageRepository(agentConfig.logger) messageSender = new MessageSender( @@ -143,7 +155,7 @@ describe('MessageSender', () => { logger, didResolverService, didCommDocumentService, - outOfBandRepository + eventEmitter ) connection = getMockConnection({ id: 'test-123', @@ -151,7 +163,7 @@ describe('MessageSender', () => { theirDid: 'did:peer:1theirdid', theirLabel: 'Test 123', }) - outboundMessage = createOutboundMessage(connection, new TestMessage()) + outboundMessageContext = new OutboundMessageContext(new TestMessage(), { agentContext, connection }) envelopeServicePackMessageMock.mockReturnValue(Promise.resolve(encryptedMessage)) transportServiceHasInboundEndpoint.mockReturnValue(true) @@ -167,13 +179,25 @@ describe('MessageSender', () => { }) afterEach(() => { + eventEmitter.off(AgentEventTypes.AgentMessageSent, eventListenerMock) + jest.resetAllMocks() }) test('throw error when there is no outbound transport', async () => { - await expect(messageSender.sendMessage(agentContext, outboundMessage)).rejects.toThrow( + await expect(messageSender.sendMessage(outboundMessageContext)).rejects.toThrow( /Message is undeliverable to connection/ ) + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.Undeliverable, + }, + }) }) test('throw error when there is no service or queue', async () => { @@ -182,9 +206,19 @@ describe('MessageSender', () => { didResolverServiceResolveMock.mockResolvedValue(getMockDidDocument({ service: [] })) didResolverServiceResolveDidServicesMock.mockResolvedValue([]) - await expect(messageSender.sendMessage(agentContext, outboundMessage)).rejects.toThrow( + await expect(messageSender.sendMessage(outboundMessageContext)).rejects.toThrow( `Message is undeliverable to connection test-123 (Test 123)` ) + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.Undeliverable, + }, + }) }) test('call send message when session send method fails', async () => { @@ -195,7 +229,18 @@ describe('MessageSender', () => { messageSender.registerOutboundTransport(outboundTransport) const sendMessageSpy = jest.spyOn(outboundTransport, 'sendMessage') - await messageSender.sendMessage(agentContext, outboundMessage) + await messageSender.sendMessage(outboundMessageContext) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.SentToTransport, + }, + }) expect(sendMessageSpy).toHaveBeenCalledWith({ connectionId: 'test-123', @@ -211,7 +256,18 @@ describe('MessageSender', () => { const sendMessageSpy = jest.spyOn(outboundTransport, 'sendMessage') - await messageSender.sendMessage(agentContext, outboundMessage) + await messageSender.sendMessage(outboundMessageContext) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.SentToTransport, + }, + }) expect(didResolverServiceResolveDidServicesMock).toHaveBeenCalledWith(agentContext, connection.theirDid) expect(sendMessageSpy).toHaveBeenCalledWith({ @@ -230,9 +286,20 @@ describe('MessageSender', () => { new Error(`Unable to resolve did document for did '${connection.theirDid}': notFound`) ) - await expect(messageSender.sendMessage(agentContext, outboundMessage)).rejects.toThrowError( - `Unable to resolve did document for did '${connection.theirDid}': notFound` + await expect(messageSender.sendMessage(outboundMessageContext)).rejects.toThrowError( + `Unable to resolve DID Document for '${connection.did}` ) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.Undeliverable, + }, + }) }) test('call send message when session send method fails with missing keys', async () => { @@ -242,7 +309,18 @@ describe('MessageSender', () => { messageSender.registerOutboundTransport(outboundTransport) const sendMessageSpy = jest.spyOn(outboundTransport, 'sendMessage') - await messageSender.sendMessage(agentContext, outboundMessage) + await messageSender.sendMessage(outboundMessageContext) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.SentToTransport, + }, + }) expect(sendMessageSpy).toHaveBeenCalledWith({ connectionId: 'test-123', @@ -259,7 +337,24 @@ describe('MessageSender', () => { const sendMessageSpy = jest.spyOn(outboundTransport, 'sendMessage') const sendMessageToServiceSpy = jest.spyOn(messageSender, 'sendMessageToService') - await messageSender.sendMessage(agentContext, { ...outboundMessage, sessionId: 'session-123' }) + const contextWithSessionId = new OutboundMessageContext(outboundMessageContext.message, { + agentContext: outboundMessageContext.agentContext, + connection: outboundMessageContext.connection, + sessionId: 'session-123', + }) + + await messageSender.sendMessage(contextWithSessionId) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: contextWithSessionId, + status: OutboundMessageSendStatus.SentToSession, + }, + }) expect(session.send).toHaveBeenCalledTimes(1) expect(session.send).toHaveBeenNthCalledWith(1, encryptedMessage) @@ -271,64 +366,119 @@ describe('MessageSender', () => { test('call send message on session when there is a session for a given connection', async () => { messageSender.registerOutboundTransport(outboundTransport) const sendMessageSpy = jest.spyOn(outboundTransport, 'sendMessage') - const sendMessageToServiceSpy = jest.spyOn(messageSender, 'sendMessageToService') + //@ts-ignore + const sendToServiceSpy = jest.spyOn(messageSender, 'sendToService') - await messageSender.sendMessage(agentContext, outboundMessage) + await messageSender.sendMessage(outboundMessageContext) - const [[, sendMessage]] = sendMessageToServiceSpy.mock.calls + //@ts-ignore + const [[sendMessage]] = sendToServiceSpy.mock.calls + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.SentToTransport, + }, + }) expect(sendMessage).toMatchObject({ - connectionId: 'test-123', - message: outboundMessage.payload, - returnRoute: false, - service: { - serviceEndpoint: firstDidCommService.serviceEndpoint, + connection: { + id: 'test-123', + }, + message: outboundMessageContext.message, + serviceParams: { + returnRoute: false, + service: { + serviceEndpoint: firstDidCommService.serviceEndpoint, + }, }, }) - expect(sendMessage.senderKey.publicKeyBase58).toEqual('EoGusetSxDJktp493VCyh981nUnzMamTRjvBaHZAy68d') - expect(sendMessage.service.recipientKeys.map((key) => key.publicKeyBase58)).toEqual([ + //@ts-ignore + expect(sendMessage.serviceParams.senderKey.publicKeyBase58).toEqual( + 'EoGusetSxDJktp493VCyh981nUnzMamTRjvBaHZAy68d' + ) + + //@ts-ignore + expect(sendMessage.serviceParams.service.recipientKeys.map((key) => key.publicKeyBase58)).toEqual([ 'EoGusetSxDJktp493VCyh981nUnzMamTRjvBaHZAy68d', ]) - expect(sendMessageToServiceSpy).toHaveBeenCalledTimes(1) + expect(sendToServiceSpy).toHaveBeenCalledTimes(1) expect(sendMessageSpy).toHaveBeenCalledTimes(1) }) - test('calls sendMessageToService with payload and endpoint from second DidComm service when the first fails', async () => { + test('calls sendToService with payload and endpoint from second DidComm service when the first fails', async () => { messageSender.registerOutboundTransport(outboundTransport) const sendMessageSpy = jest.spyOn(outboundTransport, 'sendMessage') - const sendMessageToServiceSpy = jest.spyOn(messageSender, 'sendMessageToService') + //@ts-ignore + const sendToServiceSpy = jest.spyOn(messageSender, 'sendToService') // Simulate the case when the first call fails sendMessageSpy.mockRejectedValueOnce(new Error()) - await messageSender.sendMessage(agentContext, outboundMessage) + await messageSender.sendMessage(outboundMessageContext) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.SentToTransport, + }, + }) + + //@ts-ignore + const [, [sendMessage]] = sendToServiceSpy.mock.calls - const [, [, sendMessage]] = sendMessageToServiceSpy.mock.calls expect(sendMessage).toMatchObject({ - connectionId: 'test-123', - message: outboundMessage.payload, - returnRoute: false, - service: { - serviceEndpoint: secondDidCommService.serviceEndpoint, + agentContext, + connection: { + id: 'test-123', + }, + message: outboundMessageContext.message, + serviceParams: { + returnRoute: false, + service: { + serviceEndpoint: secondDidCommService.serviceEndpoint, + }, }, }) - expect(sendMessage.senderKey.publicKeyBase58).toEqual('EoGusetSxDJktp493VCyh981nUnzMamTRjvBaHZAy68d') - expect(sendMessage.service.recipientKeys.map((key) => key.publicKeyBase58)).toEqual([ + //@ts-ignore + expect(sendMessage.serviceParams.senderKey.publicKeyBase58).toEqual( + 'EoGusetSxDJktp493VCyh981nUnzMamTRjvBaHZAy68d' + ) + //@ts-ignore + expect(sendMessage.serviceParams.service.recipientKeys.map((key) => key.publicKeyBase58)).toEqual([ 'EoGusetSxDJktp493VCyh981nUnzMamTRjvBaHZAy68d', ]) - expect(sendMessageToServiceSpy).toHaveBeenCalledTimes(2) + expect(sendToServiceSpy).toHaveBeenCalledTimes(2) expect(sendMessageSpy).toHaveBeenCalledTimes(2) }) test('throw error when message endpoint is not supported by outbound transport schemes', async () => { messageSender.registerOutboundTransport(new DummyWsOutboundTransport()) - await expect(messageSender.sendMessage(agentContext, outboundMessage)).rejects.toThrow( + await expect(messageSender.sendMessage(outboundMessageContext)).rejects.toThrow( /Message is undeliverable to connection/ ) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.Undeliverable, + }, + }) }) }) @@ -350,34 +500,66 @@ describe('MessageSender', () => { logger, didResolverService, didCommDocumentService, - outOfBandRepository + eventEmitter ) + eventEmitter.on(AgentEventTypes.AgentMessageSent, eventListenerMock) + envelopeServicePackMessageMock.mockReturnValue(Promise.resolve(encryptedMessage)) }) afterEach(() => { jest.resetAllMocks() + eventEmitter.off(AgentEventTypes.AgentMessageSent, eventListenerMock) }) test('throws error when there is no outbound transport', async () => { - await expect( - messageSender.sendMessageToService(agentContext, { - message: new TestMessage(), + outboundMessageContext = new OutboundMessageContext(new TestMessage(), { + agentContext, + serviceParams: { senderKey, service, - }) - ).rejects.toThrow(`Agent has no outbound transport!`) + }, + }) + await expect(messageSender.sendMessageToService(outboundMessageContext)).rejects.toThrow( + `Agent has no outbound transport!` + ) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.Undeliverable, + }, + }) }) test('calls send message with payload and endpoint from DIDComm service', async () => { messageSender.registerOutboundTransport(outboundTransport) const sendMessageSpy = jest.spyOn(outboundTransport, 'sendMessage') - await messageSender.sendMessageToService(agentContext, { - message: new TestMessage(), - senderKey, - service, + outboundMessageContext = new OutboundMessageContext(new TestMessage(), { + agentContext, + serviceParams: { + senderKey, + service, + }, + }) + + await messageSender.sendMessageToService(outboundMessageContext) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.SentToTransport, + }, }) expect(sendMessageSpy).toHaveBeenCalledWith({ @@ -395,10 +577,25 @@ describe('MessageSender', () => { const message = new TestMessage() message.setReturnRouting(ReturnRouteTypes.all) - await messageSender.sendMessageToService(agentContext, { - message, - senderKey, - service, + outboundMessageContext = new OutboundMessageContext(message, { + agentContext, + serviceParams: { + senderKey, + service, + }, + }) + + await messageSender.sendMessageToService(outboundMessageContext) + + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.SentToTransport, + }, }) expect(sendMessageSpy).toHaveBeenCalledWith({ @@ -411,13 +608,27 @@ describe('MessageSender', () => { test('throw error when message endpoint is not supported by outbound transport schemes', async () => { messageSender.registerOutboundTransport(new DummyWsOutboundTransport()) - await expect( - messageSender.sendMessageToService(agentContext, { - message: new TestMessage(), + outboundMessageContext = new OutboundMessageContext(new TestMessage(), { + agentContext, + serviceParams: { senderKey, service, - }) - ).rejects.toThrow(/Unable to send message to service/) + }, + }) + + await expect(messageSender.sendMessageToService(outboundMessageContext)).rejects.toThrow( + /Unable to send message to service/ + ) + expect(eventListenerMock).toHaveBeenCalledWith({ + type: AgentEventTypes.AgentMessageSent, + metadata: { + contextCorrelationId: 'mock', + }, + payload: { + message: outboundMessageContext, + status: OutboundMessageSendStatus.Undeliverable, + }, + }) }) }) @@ -432,7 +643,7 @@ describe('MessageSender', () => { logger, didResolverService, didCommDocumentService, - outOfBandRepository + eventEmitter ) connection = getMockConnection() diff --git a/packages/core/src/agent/helpers.ts b/packages/core/src/agent/helpers.ts deleted file mode 100644 index fcfb906220..0000000000 --- a/packages/core/src/agent/helpers.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { Key } from '../crypto' -import type { ConnectionRecord } from '../modules/connections' -import type { ResolvedDidCommService } from '../modules/didcomm' -import type { OutOfBandRecord } from '../modules/oob/repository' -import type { OutboundMessage, OutboundServiceMessage } from '../types' -import type { AgentMessage } from './AgentMessage' - -export function createOutboundMessage( - connection: ConnectionRecord, - payload: T, - outOfBand?: OutOfBandRecord -): OutboundMessage { - return { - connection, - outOfBand, - payload, - } -} - -export function createOutboundServiceMessage(options: { - payload: T - service: ResolvedDidCommService - senderKey: Key -}): OutboundServiceMessage { - return options -} - -export function isOutboundServiceMessage( - message: OutboundMessage | OutboundServiceMessage -): message is OutboundServiceMessage { - const service = (message as OutboundServiceMessage).service - - return service !== undefined -} diff --git a/packages/core/src/agent/models/OutboundMessageContext.ts b/packages/core/src/agent/models/OutboundMessageContext.ts new file mode 100644 index 0000000000..e61929a47d --- /dev/null +++ b/packages/core/src/agent/models/OutboundMessageContext.ts @@ -0,0 +1,76 @@ +import type { Key } from '../../crypto' +import type { ConnectionRecord } from '../../modules/connections' +import type { ResolvedDidCommService } from '../../modules/didcomm' +import type { OutOfBandRecord } from '../../modules/oob' +import type { BaseRecord } from '../../storage/BaseRecord' +import type { AgentMessage } from '../AgentMessage' +import type { AgentContext } from '../context' + +import { AriesFrameworkError } from '../../error' + +export interface ServiceMessageParams { + senderKey: Key + service: ResolvedDidCommService + returnRoute?: boolean +} + +export interface OutboundMessageContextParams { + agentContext: AgentContext + associatedRecord?: BaseRecord + connection?: ConnectionRecord + serviceParams?: ServiceMessageParams + outOfBand?: OutOfBandRecord + sessionId?: string +} + +export class OutboundMessageContext { + public message: T + public connection?: ConnectionRecord + public serviceParams?: ServiceMessageParams + public outOfBand?: OutOfBandRecord + public associatedRecord?: BaseRecord + public sessionId?: string + public readonly agentContext: AgentContext + + public constructor(message: T, context: OutboundMessageContextParams) { + this.message = message + this.connection = context.connection + this.sessionId = context.sessionId + this.outOfBand = context.outOfBand + this.serviceParams = context.serviceParams + this.associatedRecord = context.associatedRecord + this.agentContext = context.agentContext + } + + /** + * Assert the outbound message has a ready connection associated with it. + * + * @throws {AriesFrameworkError} if there is no connection or the connection is not ready + */ + public assertReadyConnection(): ConnectionRecord { + if (!this.connection) { + throw new AriesFrameworkError(`No connection associated with outgoing message ${this.message.type}`) + } + + // Make sure connection is ready + this.connection.assertReady() + + return this.connection + } + + public isOutboundServiceMessage(): boolean { + return this.serviceParams?.service !== undefined + } + + public toJSON() { + return { + message: this.message, + outOfBand: this.outOfBand, + associatedRecord: this.associatedRecord, + sessionId: this.sessionId, + serviceParams: this.serviceParams, + agentContext: this.agentContext.toJSON(), + connection: this.connection, + } + } +} diff --git a/packages/core/src/agent/models/OutboundMessageSendStatus.ts b/packages/core/src/agent/models/OutboundMessageSendStatus.ts new file mode 100644 index 0000000000..6fdb4f7f68 --- /dev/null +++ b/packages/core/src/agent/models/OutboundMessageSendStatus.ts @@ -0,0 +1,6 @@ +export enum OutboundMessageSendStatus { + SentToSession = 'SentToSession', + SentToTransport = 'SentToTransport', + QueuedForPickup = 'QueuedForPickup', + Undeliverable = 'Undeliverable', +} diff --git a/packages/core/src/agent/models/index.ts b/packages/core/src/agent/models/index.ts index 3a9ffdf3ca..1383036898 100644 --- a/packages/core/src/agent/models/index.ts +++ b/packages/core/src/agent/models/index.ts @@ -1,2 +1,4 @@ export * from './features' export * from './InboundMessageContext' +export * from './OutboundMessageContext' +export * from './OutboundMessageSendStatus' diff --git a/packages/core/src/error/MessageSendingError.ts b/packages/core/src/error/MessageSendingError.ts index 6ebc95a23d..6d0ddc46aa 100644 --- a/packages/core/src/error/MessageSendingError.ts +++ b/packages/core/src/error/MessageSendingError.ts @@ -1,11 +1,14 @@ -import type { OutboundMessage } from '../types' +import type { OutboundMessageContext } from '../agent/models' import { AriesFrameworkError } from './AriesFrameworkError' export class MessageSendingError extends AriesFrameworkError { - public outboundMessage: OutboundMessage - public constructor(message: string, { outboundMessage, cause }: { outboundMessage: OutboundMessage; cause?: Error }) { + public outboundMessageContext: OutboundMessageContext + public constructor( + message: string, + { outboundMessageContext, cause }: { outboundMessageContext: OutboundMessageContext; cause?: Error } + ) { super(message, { cause }) - this.outboundMessage = outboundMessage + this.outboundMessageContext = outboundMessageContext } } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 355383f062..1003c073b5 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -10,7 +10,6 @@ export { EventEmitter } from './agent/EventEmitter' export { FeatureRegistry } from './agent/FeatureRegistry' export { Handler, HandlerInboundMessage } from './agent/Handler' export * from './agent/models' -export * from './agent/helpers' export { AgentConfig } from './agent/AgentConfig' export { AgentMessage } from './agent/AgentMessage' export { Dispatcher } from './agent/Dispatcher' diff --git a/packages/core/src/modules/basic-messages/BasicMessagesApi.ts b/packages/core/src/modules/basic-messages/BasicMessagesApi.ts index fbebfc30c2..17bb32d080 100644 --- a/packages/core/src/modules/basic-messages/BasicMessagesApi.ts +++ b/packages/core/src/modules/basic-messages/BasicMessagesApi.ts @@ -4,7 +4,7 @@ import type { BasicMessageRecord } from './repository/BasicMessageRecord' import { AgentContext } from '../../agent' import { Dispatcher } from '../../agent/Dispatcher' import { MessageSender } from '../../agent/MessageSender' -import { createOutboundMessage } from '../../agent/helpers' +import { OutboundMessageContext } from '../../agent/models' import { injectable } from '../../plugins' import { ConnectionService } from '../connections' @@ -49,10 +49,13 @@ export class BasicMessagesApi { message, connection ) - const outboundMessage = createOutboundMessage(connection, basicMessage) - outboundMessage.associatedRecord = basicMessageRecord + const outboundMessageContext = new OutboundMessageContext(basicMessage, { + agentContext: this.agentContext, + connection, + associatedRecord: basicMessageRecord, + }) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + await this.messageSender.sendMessage(outboundMessageContext) return basicMessageRecord } diff --git a/packages/core/src/modules/basic-messages/__tests__/basic-messages.e2e.test.ts b/packages/core/src/modules/basic-messages/__tests__/basic-messages.e2e.test.ts index 4f3b7205f1..e4e2d0dd17 100644 --- a/packages/core/src/modules/basic-messages/__tests__/basic-messages.e2e.test.ts +++ b/packages/core/src/modules/basic-messages/__tests__/basic-messages.e2e.test.ts @@ -91,18 +91,20 @@ describe('Basic Messages E2E', () => { `Message is undeliverable to connection ${aliceConnection.id} (${aliceConnection.theirLabel})` ) testLogger.test('Error thrown includes the outbound message and recently created record id') - expect(thrownError.outboundMessage.associatedRecord).toBeInstanceOf(BasicMessageRecord) - expect(thrownError.outboundMessage.payload).toBeInstanceOf(BasicMessage) - expect((thrownError.outboundMessage.payload as BasicMessage).content).toBe('Hello undeliverable') + expect(thrownError.outboundMessageContext.associatedRecord).toBeInstanceOf(BasicMessageRecord) + expect(thrownError.outboundMessageContext.message).toBeInstanceOf(BasicMessage) + expect((thrownError.outboundMessageContext.message as BasicMessage).content).toBe('Hello undeliverable') testLogger.test('Created record can be found and deleted by id') - const storedRecord = await aliceAgent.basicMessages.getById(thrownError.outboundMessage.associatedRecord!.id) + const storedRecord = await aliceAgent.basicMessages.getById( + thrownError.outboundMessageContext.associatedRecord!.id + ) expect(storedRecord).toBeInstanceOf(BasicMessageRecord) expect(storedRecord.content).toBe('Hello undeliverable') await aliceAgent.basicMessages.deleteById(storedRecord.id) await expect( - aliceAgent.basicMessages.getById(thrownError.outboundMessage.associatedRecord!.id) + aliceAgent.basicMessages.getById(thrownError.outboundMessageContext.associatedRecord!.id) ).rejects.toThrowError(RecordNotFoundError) } spy.mockClear() diff --git a/packages/core/src/modules/connections/ConnectionsApi.ts b/packages/core/src/modules/connections/ConnectionsApi.ts index 1b4207be31..a384132463 100644 --- a/packages/core/src/modules/connections/ConnectionsApi.ts +++ b/packages/core/src/modules/connections/ConnectionsApi.ts @@ -7,7 +7,7 @@ import type { Routing } from './services' import { AgentContext } from '../../agent' import { Dispatcher } from '../../agent/Dispatcher' import { MessageSender } from '../../agent/MessageSender' -import { createOutboundMessage } from '../../agent/helpers' +import { OutboundMessageContext } from '../../agent/models' import { ReturnRouteTypes } from '../../decorators/transport/TransportDecorator' import { AriesFrameworkError } from '../../error' import { injectable } from '../../plugins' @@ -114,8 +114,12 @@ export class ConnectionsApi { } const { message, connectionRecord } = result - const outboundMessage = createOutboundMessage(connectionRecord, message, outOfBandRecord) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection: connectionRecord, + outOfBand: outOfBandRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return connectionRecord } @@ -140,24 +144,30 @@ export class ConnectionsApi { throw new AriesFrameworkError(`Out-of-band record ${connectionRecord.outOfBandId} not found.`) } - let outboundMessage + let outboundMessageContext if (connectionRecord.protocol === HandshakeProtocol.DidExchange) { const message = await this.didExchangeProtocol.createResponse( this.agentContext, connectionRecord, outOfBandRecord ) - outboundMessage = createOutboundMessage(connectionRecord, message) + outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection: connectionRecord, + }) } else { const { message } = await this.connectionService.createResponse( this.agentContext, connectionRecord, outOfBandRecord ) - outboundMessage = createOutboundMessage(connectionRecord, message) + outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection: connectionRecord, + }) } - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + await this.messageSender.sendMessage(outboundMessageContext) return connectionRecord } @@ -171,7 +181,7 @@ export class ConnectionsApi { public async acceptResponse(connectionId: string): Promise { const connectionRecord = await this.connectionService.getById(this.agentContext, connectionId) - let outboundMessage + let outboundMessageContext if (connectionRecord.protocol === HandshakeProtocol.DidExchange) { if (!connectionRecord.outOfBandId) { throw new AriesFrameworkError(`Connection ${connectionRecord.id} does not have outOfBandId!`) @@ -190,7 +200,10 @@ export class ConnectionsApi { // Disable return routing as we don't want to receive a response for this message over the same channel // This has led to long timeouts as not all clients actually close an http socket if there is no response message message.setReturnRouting(ReturnRouteTypes.none) - outboundMessage = createOutboundMessage(connectionRecord, message) + outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection: connectionRecord, + }) } else { const { message } = await this.connectionService.createTrustPing(this.agentContext, connectionRecord, { responseRequested: false, @@ -198,10 +211,13 @@ export class ConnectionsApi { // Disable return routing as we don't want to receive a response for this message over the same channel // This has led to long timeouts as not all clients actually close an http socket if there is no response message message.setReturnRouting(ReturnRouteTypes.none) - outboundMessage = createOutboundMessage(connectionRecord, message) + outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection: connectionRecord, + }) } - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + await this.messageSender.sendMessage(outboundMessageContext) return connectionRecord } diff --git a/packages/core/src/modules/connections/handlers/ConnectionRequestHandler.ts b/packages/core/src/modules/connections/handlers/ConnectionRequestHandler.ts index 1291546616..77056ed0fd 100644 --- a/packages/core/src/modules/connections/handlers/ConnectionRequestHandler.ts +++ b/packages/core/src/modules/connections/handlers/ConnectionRequestHandler.ts @@ -5,7 +5,7 @@ import type { RoutingService } from '../../routing/services/RoutingService' import type { ConnectionsModuleConfig } from '../ConnectionsModuleConfig' import type { ConnectionService } from '../services/ConnectionService' -import { createOutboundMessage } from '../../../agent/helpers' +import { OutboundMessageContext } from '../../../agent/models' import { AriesFrameworkError } from '../../../error/AriesFrameworkError' import { ConnectionRequestMessage } from '../messages' @@ -69,7 +69,11 @@ export class ConnectionRequestHandler implements Handler { outOfBandRecord, routing ) - return createOutboundMessage(connectionRecord, message, outOfBandRecord) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: connectionRecord, + outOfBand: outOfBandRecord, + }) } } } diff --git a/packages/core/src/modules/connections/handlers/ConnectionResponseHandler.ts b/packages/core/src/modules/connections/handlers/ConnectionResponseHandler.ts index 9e28621fb0..28794676c6 100644 --- a/packages/core/src/modules/connections/handlers/ConnectionResponseHandler.ts +++ b/packages/core/src/modules/connections/handlers/ConnectionResponseHandler.ts @@ -4,7 +4,7 @@ import type { OutOfBandService } from '../../oob/OutOfBandService' import type { ConnectionsModuleConfig } from '../ConnectionsModuleConfig' import type { ConnectionService } from '../services/ConnectionService' -import { createOutboundMessage } from '../../../agent/helpers' +import { OutboundMessageContext } from '../../../agent/models' import { ReturnRouteTypes } from '../../../decorators/transport/TransportDecorator' import { AriesFrameworkError } from '../../../error' import { ConnectionResponseMessage } from '../messages' @@ -83,7 +83,7 @@ export class ConnectionResponseHandler implements Handler { // Disable return routing as we don't want to receive a response for this message over the same channel // This has led to long timeouts as not all clients actually close an http socket if there is no response message message.setReturnRouting(ReturnRouteTypes.none) - return createOutboundMessage(connection, message) + return new OutboundMessageContext(message, { agentContext: messageContext.agentContext, connection }) } } } diff --git a/packages/core/src/modules/connections/handlers/DidExchangeRequestHandler.ts b/packages/core/src/modules/connections/handlers/DidExchangeRequestHandler.ts index f9d46cec7b..309d351726 100644 --- a/packages/core/src/modules/connections/handlers/DidExchangeRequestHandler.ts +++ b/packages/core/src/modules/connections/handlers/DidExchangeRequestHandler.ts @@ -5,7 +5,7 @@ import type { RoutingService } from '../../routing/services/RoutingService' import type { ConnectionsModuleConfig } from '../ConnectionsModuleConfig' import type { DidExchangeProtocol } from '../DidExchangeProtocol' -import { createOutboundMessage } from '../../../agent/helpers' +import { OutboundMessageContext } from '../../../agent/models' import { AriesFrameworkError } from '../../../error/AriesFrameworkError' import { OutOfBandState } from '../../oob/domain/OutOfBandState' import { DidExchangeRequestMessage } from '../messages' @@ -85,7 +85,11 @@ export class DidExchangeRequestHandler implements Handler { outOfBandRecord, routing ) - return createOutboundMessage(connectionRecord, message, outOfBandRecord) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: connectionRecord, + outOfBand: outOfBandRecord, + }) } } } diff --git a/packages/core/src/modules/connections/handlers/DidExchangeResponseHandler.ts b/packages/core/src/modules/connections/handlers/DidExchangeResponseHandler.ts index f2b40697ea..3f71f85251 100644 --- a/packages/core/src/modules/connections/handlers/DidExchangeResponseHandler.ts +++ b/packages/core/src/modules/connections/handlers/DidExchangeResponseHandler.ts @@ -5,7 +5,7 @@ import type { ConnectionsModuleConfig } from '../ConnectionsModuleConfig' import type { DidExchangeProtocol } from '../DidExchangeProtocol' import type { ConnectionService } from '../services' -import { createOutboundMessage } from '../../../agent/helpers' +import { OutboundMessageContext } from '../../../agent/models' import { ReturnRouteTypes } from '../../../decorators/transport/TransportDecorator' import { AriesFrameworkError } from '../../../error' import { OutOfBandState } from '../../oob/domain/OutOfBandState' @@ -35,13 +35,13 @@ export class DidExchangeResponseHandler implements Handler { } public async handle(messageContext: HandlerInboundMessage) { - const { recipientKey, senderKey, message } = messageContext + const { agentContext, recipientKey, senderKey, message } = messageContext if (!recipientKey || !senderKey) { throw new AriesFrameworkError('Unable to process connection response without sender key or recipient key') } - const connectionRecord = await this.connectionService.getByThreadId(messageContext.agentContext, message.threadId) + const connectionRecord = await this.connectionService.getByThreadId(agentContext, message.threadId) if (!connectionRecord) { throw new AriesFrameworkError(`Connection for thread ID ${message.threadId} not found!`) } @@ -50,10 +50,7 @@ export class DidExchangeResponseHandler implements Handler { throw new AriesFrameworkError(`Connection record ${connectionRecord.id} has no 'did'`) } - const ourDidDocument = await this.didResolverService.resolveDidDocument( - messageContext.agentContext, - connectionRecord.did - ) + const ourDidDocument = await this.didResolverService.resolveDidDocument(agentContext, connectionRecord.did) if (!ourDidDocument) { throw new AriesFrameworkError(`Did document for did ${connectionRecord.did} was not resolved`) } @@ -77,10 +74,7 @@ export class DidExchangeResponseHandler implements Handler { throw new AriesFrameworkError(`Connection ${connectionRecord.id} does not have outOfBandId!`) } - const outOfBandRecord = await this.outOfBandService.findById( - messageContext.agentContext, - connectionRecord.outOfBandId - ) + const outOfBandRecord = await this.outOfBandService.findById(agentContext, connectionRecord.outOfBandId) if (!outOfBandRecord) { throw new AriesFrameworkError( @@ -103,19 +97,15 @@ export class DidExchangeResponseHandler implements Handler { // In AATH we have a separate step to send the complete. So for now we'll only do it // if auto accept is enabled if (connection.autoAcceptConnection ?? this.connectionsModuleConfig.autoAcceptConnections) { - const message = await this.didExchangeProtocol.createComplete( - messageContext.agentContext, - connection, - outOfBandRecord - ) + const message = await this.didExchangeProtocol.createComplete(agentContext, connection, outOfBandRecord) // Disable return routing as we don't want to receive a response for this message over the same channel // This has led to long timeouts as not all clients actually close an http socket if there is no response message message.setReturnRouting(ReturnRouteTypes.none) if (!outOfBandRecord.reusable) { - await this.outOfBandService.updateState(messageContext.agentContext, outOfBandRecord, OutOfBandState.Done) + await this.outOfBandService.updateState(agentContext, outOfBandRecord, OutOfBandState.Done) } - return createOutboundMessage(connection, message) + return new OutboundMessageContext(message, { agentContext, connection }) } } } diff --git a/packages/core/src/modules/connections/services/TrustPingService.ts b/packages/core/src/modules/connections/services/TrustPingService.ts index 1b6a9bbdf2..17032e089e 100644 --- a/packages/core/src/modules/connections/services/TrustPingService.ts +++ b/packages/core/src/modules/connections/services/TrustPingService.ts @@ -2,19 +2,19 @@ import type { InboundMessageContext } from '../../../agent/models/InboundMessage import type { TrustPingMessage } from '../messages' import type { ConnectionRecord } from '../repository/ConnectionRecord' -import { createOutboundMessage } from '../../../agent/helpers' +import { OutboundMessageContext } from '../../../agent/models' import { injectable } from '../../../plugins' import { TrustPingResponseMessage } from '../messages' @injectable() export class TrustPingService { - public processPing({ message }: InboundMessageContext, connection: ConnectionRecord) { + public processPing({ message, agentContext }: InboundMessageContext, connection: ConnectionRecord) { if (message.responseRequested) { const response = new TrustPingResponseMessage({ threadId: message.id, }) - return createOutboundMessage(connection, response) + return new OutboundMessageContext(response, { agentContext, connection }) } } diff --git a/packages/core/src/modules/credentials/CredentialsApi.ts b/packages/core/src/modules/credentials/CredentialsApi.ts index 419f6cfc67..3eefc4857a 100644 --- a/packages/core/src/modules/credentials/CredentialsApi.ts +++ b/packages/core/src/modules/credentials/CredentialsApi.ts @@ -27,7 +27,7 @@ import type { CredentialService } from './services/CredentialService' import { AgentContext } from '../../agent' import { MessageSender } from '../../agent/MessageSender' -import { createOutboundMessage } from '../../agent/helpers' +import { OutboundMessageContext } from '../../agent/models' import { InjectionSymbols } from '../../constants' import { ServiceDecorator } from '../../decorators/service/ServiceDecorator' import { AriesFrameworkError } from '../../error' @@ -181,10 +181,14 @@ export class CredentialsApi< this.logger.debug('We have a message (sending outbound): ', message) // send the message here - const outbound = createOutboundMessage(connection, message) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: credentialRecord, + }) this.logger.debug('In proposeCredential: Send Proposal to Issuer') - await this.messageSender.sendMessage(this.agentContext, outbound) + await this.messageSender.sendMessage(outboundMessageContext) return credentialRecord } @@ -218,8 +222,12 @@ export class CredentialsApi< // send the message const connection = await this.connectionService.getById(this.agentContext, credentialRecord.connectionId) - const outbound = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outbound) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: credentialRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return credentialRecord } @@ -252,8 +260,12 @@ export class CredentialsApi< }) const connection = await this.connectionService.getById(this.agentContext, credentialRecord.connectionId) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: credentialRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return credentialRecord } @@ -279,8 +291,12 @@ export class CredentialsApi< }) this.logger.debug('Offer Message successfully created; message= ', message) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: credentialRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return credentialRecord } @@ -311,8 +327,12 @@ export class CredentialsApi< autoAcceptCredential: options.autoAcceptCredential, }) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: credentialRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return credentialRecord } @@ -342,12 +362,16 @@ export class CredentialsApi< associatedRecordId: credentialRecord.id, }) - await this.messageSender.sendMessageToService(this.agentContext, { - message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], - returnRoute: true, - }) + await this.messageSender.sendMessageToService( + new OutboundMessageContext(message, { + agentContext: this.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + returnRoute: true, + }, + }) + ) return credentialRecord } @@ -388,8 +412,12 @@ export class CredentialsApi< } const connection = await this.connectionService.getById(this.agentContext, credentialRecord.connectionId) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: credentialRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return credentialRecord } @@ -447,8 +475,12 @@ export class CredentialsApi< // Use connection if present if (credentialRecord.connectionId) { const connection = await this.connectionService.getById(this.agentContext, credentialRecord.connectionId) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: credentialRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return credentialRecord } @@ -464,12 +496,16 @@ export class CredentialsApi< associatedRecordId: credentialRecord.id, }) - await this.messageSender.sendMessageToService(this.agentContext, { - message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], - returnRoute: true, - }) + await this.messageSender.sendMessageToService( + new OutboundMessageContext(message, { + agentContext: this.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + returnRoute: true, + }, + }) + ) return credentialRecord } @@ -506,9 +542,13 @@ export class CredentialsApi< if (credentialRecord.connectionId) { const connection = await this.connectionService.getById(this.agentContext, credentialRecord.connectionId) - const outboundMessage = createOutboundMessage(connection, message) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: credentialRecord, + }) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + await this.messageSender.sendMessage(outboundMessageContext) return credentialRecord } @@ -517,12 +557,16 @@ export class CredentialsApi< const recipientService = credentialMessage.service const ourService = requestMessage.service - await this.messageSender.sendMessageToService(this.agentContext, { - message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], - returnRoute: true, - }) + await this.messageSender.sendMessageToService( + new OutboundMessageContext(message, { + agentContext: this.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + returnRoute: true, + }, + }) + ) return credentialRecord } @@ -552,8 +596,12 @@ export class CredentialsApi< problemReportMessage.setThread({ threadId: credentialRecord.threadId, }) - const outboundMessage = createOutboundMessage(connection, problemReportMessage) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(problemReportMessage, { + agentContext: this.agentContext, + connection, + associatedRecord: credentialRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return credentialRecord } diff --git a/packages/core/src/modules/credentials/protocol/v1/handlers/V1IssueCredentialHandler.ts b/packages/core/src/modules/credentials/protocol/v1/handlers/V1IssueCredentialHandler.ts index c8b986d97e..e30f82e101 100644 --- a/packages/core/src/modules/credentials/protocol/v1/handlers/V1IssueCredentialHandler.ts +++ b/packages/core/src/modules/credentials/protocol/v1/handlers/V1IssueCredentialHandler.ts @@ -4,7 +4,7 @@ import type { DidCommMessageRepository } from '../../../../../storage' import type { CredentialExchangeRecord } from '../../../repository/CredentialExchangeRecord' import type { V1CredentialService } from '../V1CredentialService' -import { createOutboundMessage, createOutboundServiceMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { V1IssueCredentialMessage, V1RequestCredentialMessage } from '../messages' export class V1IssueCredentialHandler implements Handler { @@ -51,15 +51,21 @@ export class V1IssueCredentialHandler implements Handler { }) if (messageContext.connection) { - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: credentialRecord, + }) } else if (messageContext.message.service && requestMessage.service) { const recipientService = messageContext.message.service const ourService = requestMessage.service - return createOutboundServiceMessage({ - payload: message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + }, }) } diff --git a/packages/core/src/modules/credentials/protocol/v1/handlers/V1OfferCredentialHandler.ts b/packages/core/src/modules/credentials/protocol/v1/handlers/V1OfferCredentialHandler.ts index 510c5de434..bb85fd199a 100644 --- a/packages/core/src/modules/credentials/protocol/v1/handlers/V1OfferCredentialHandler.ts +++ b/packages/core/src/modules/credentials/protocol/v1/handlers/V1OfferCredentialHandler.ts @@ -5,7 +5,7 @@ import type { RoutingService } from '../../../../routing/services/RoutingService import type { CredentialExchangeRecord } from '../../../repository/CredentialExchangeRecord' import type { V1CredentialService } from '../V1CredentialService' -import { createOutboundMessage, createOutboundServiceMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { ServiceDecorator } from '../../../../../decorators/service/ServiceDecorator' import { DidCommMessageRole } from '../../../../../storage' import { V1OfferCredentialMessage } from '../messages' @@ -50,7 +50,11 @@ export class V1OfferCredentialHandler implements Handler { if (messageContext.connection) { const { message } = await this.credentialService.acceptOffer(messageContext.agentContext, { credentialRecord }) - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: credentialRecord, + }) } else if (messageContext.message.service) { const routing = await this.routingService.getRouting(messageContext.agentContext) const ourService = new ServiceDecorator({ @@ -77,10 +81,12 @@ export class V1OfferCredentialHandler implements Handler { associatedRecordId: credentialRecord.id, }) - return createOutboundServiceMessage({ - payload: message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + }, }) } diff --git a/packages/core/src/modules/credentials/protocol/v1/handlers/V1ProposeCredentialHandler.ts b/packages/core/src/modules/credentials/protocol/v1/handlers/V1ProposeCredentialHandler.ts index 05dc7371af..f427a97670 100644 --- a/packages/core/src/modules/credentials/protocol/v1/handlers/V1ProposeCredentialHandler.ts +++ b/packages/core/src/modules/credentials/protocol/v1/handlers/V1ProposeCredentialHandler.ts @@ -3,7 +3,7 @@ import type { Logger } from '../../../../../logger' import type { CredentialExchangeRecord } from '../../../repository/CredentialExchangeRecord' import type { V1CredentialService } from '../V1CredentialService' -import { createOutboundMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { V1ProposeCredentialMessage } from '../messages' export class V1ProposeCredentialHandler implements Handler { @@ -47,6 +47,10 @@ export class V1ProposeCredentialHandler implements Handler { credentialRecord, }) - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: credentialRecord, + }) } } diff --git a/packages/core/src/modules/credentials/protocol/v1/handlers/V1RequestCredentialHandler.ts b/packages/core/src/modules/credentials/protocol/v1/handlers/V1RequestCredentialHandler.ts index f155001022..ba85e05ae8 100644 --- a/packages/core/src/modules/credentials/protocol/v1/handlers/V1RequestCredentialHandler.ts +++ b/packages/core/src/modules/credentials/protocol/v1/handlers/V1RequestCredentialHandler.ts @@ -4,7 +4,7 @@ import type { DidCommMessageRepository } from '../../../../../storage' import type { CredentialExchangeRecord } from '../../../repository/CredentialExchangeRecord' import type { V1CredentialService } from '../V1CredentialService' -import { createOutboundMessage, createOutboundServiceMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { DidCommMessageRole } from '../../../../../storage' import { V1RequestCredentialMessage } from '../messages' @@ -50,7 +50,11 @@ export class V1RequestCredentialHandler implements Handler { }) if (messageContext.connection) { - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: credentialRecord, + }) } else if (messageContext.message.service && offerMessage?.service) { const recipientService = messageContext.message.service const ourService = offerMessage.service @@ -64,10 +68,12 @@ export class V1RequestCredentialHandler implements Handler { associatedRecordId: credentialRecord.id, }) - return createOutboundServiceMessage({ - payload: message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + }, }) } diff --git a/packages/core/src/modules/credentials/protocol/v2/handlers/V2IssueCredentialHandler.ts b/packages/core/src/modules/credentials/protocol/v2/handlers/V2IssueCredentialHandler.ts index 8f1db634e9..308be12bc1 100644 --- a/packages/core/src/modules/credentials/protocol/v2/handlers/V2IssueCredentialHandler.ts +++ b/packages/core/src/modules/credentials/protocol/v2/handlers/V2IssueCredentialHandler.ts @@ -5,7 +5,7 @@ import type { DidCommMessageRepository } from '../../../../../storage' import type { CredentialExchangeRecord } from '../../../repository/CredentialExchangeRecord' import type { V2CredentialService } from '../V2CredentialService' -import { createOutboundMessage, createOutboundServiceMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { V2IssueCredentialMessage } from '../messages/V2IssueCredentialMessage' import { V2RequestCredentialMessage } from '../messages/V2RequestCredentialMessage' @@ -54,15 +54,21 @@ export class V2IssueCredentialHandler implements Handler { credentialRecord, }) if (messageContext.connection) { - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: credentialRecord, + }) } else if (requestMessage?.service && messageContext.message.service) { const recipientService = messageContext.message.service const ourService = requestMessage.service - return createOutboundServiceMessage({ - payload: message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + }, }) } diff --git a/packages/core/src/modules/credentials/protocol/v2/handlers/V2OfferCredentialHandler.ts b/packages/core/src/modules/credentials/protocol/v2/handlers/V2OfferCredentialHandler.ts index 095a5a5a0f..d1d4248661 100644 --- a/packages/core/src/modules/credentials/protocol/v2/handlers/V2OfferCredentialHandler.ts +++ b/packages/core/src/modules/credentials/protocol/v2/handlers/V2OfferCredentialHandler.ts @@ -6,7 +6,7 @@ import type { RoutingService } from '../../../../routing/services/RoutingService import type { CredentialExchangeRecord } from '../../../repository/CredentialExchangeRecord' import type { V2CredentialService } from '../V2CredentialService' -import { createOutboundMessage, createOutboundServiceMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { ServiceDecorator } from '../../../../../decorators/service/ServiceDecorator' import { DidCommMessageRole } from '../../../../../storage' import { V2OfferCredentialMessage } from '../messages/V2OfferCredentialMessage' @@ -54,7 +54,11 @@ export class V2OfferCredentialHandler implements Handler { const { message } = await this.credentialService.acceptOffer(messageContext.agentContext, { credentialRecord, }) - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: credentialRecord, + }) } else if (offerMessage?.service) { const routing = await this.routingService.getRouting(messageContext.agentContext) const ourService = new ServiceDecorator({ @@ -77,10 +81,12 @@ export class V2OfferCredentialHandler implements Handler { associatedRecordId: credentialRecord.id, }) - return createOutboundServiceMessage({ - payload: message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + }, }) } diff --git a/packages/core/src/modules/credentials/protocol/v2/handlers/V2ProposeCredentialHandler.ts b/packages/core/src/modules/credentials/protocol/v2/handlers/V2ProposeCredentialHandler.ts index c005480617..d536303a33 100644 --- a/packages/core/src/modules/credentials/protocol/v2/handlers/V2ProposeCredentialHandler.ts +++ b/packages/core/src/modules/credentials/protocol/v2/handlers/V2ProposeCredentialHandler.ts @@ -4,7 +4,7 @@ import type { Logger } from '../../../../../logger' import type { CredentialExchangeRecord } from '../../../repository/CredentialExchangeRecord' import type { V2CredentialService } from '../V2CredentialService' -import { createOutboundMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { V2ProposeCredentialMessage } from '../messages/V2ProposeCredentialMessage' export class V2ProposeCredentialHandler implements Handler { @@ -44,6 +44,10 @@ export class V2ProposeCredentialHandler implements Handler { const { message } = await this.credentialService.acceptProposal(messageContext.agentContext, { credentialRecord }) - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: credentialRecord, + }) } } diff --git a/packages/core/src/modules/credentials/protocol/v2/handlers/V2RequestCredentialHandler.ts b/packages/core/src/modules/credentials/protocol/v2/handlers/V2RequestCredentialHandler.ts index e30286f988..72b436174d 100644 --- a/packages/core/src/modules/credentials/protocol/v2/handlers/V2RequestCredentialHandler.ts +++ b/packages/core/src/modules/credentials/protocol/v2/handlers/V2RequestCredentialHandler.ts @@ -5,7 +5,7 @@ import type { DidCommMessageRepository } from '../../../../../storage' import type { CredentialExchangeRecord } from '../../../repository' import type { V2CredentialService } from '../V2CredentialService' -import { createOutboundMessage, createOutboundServiceMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { DidCommMessageRole } from '../../../../../storage' import { V2OfferCredentialMessage } from '../messages/V2OfferCredentialMessage' import { V2RequestCredentialMessage } from '../messages/V2RequestCredentialMessage' @@ -56,7 +56,11 @@ export class V2RequestCredentialHandler implements Handler { }) if (messageContext.connection) { - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: credentialRecord, + }) } else if (messageContext.message.service && offerMessage?.service) { const recipientService = messageContext.message.service const ourService = offerMessage.service @@ -69,10 +73,12 @@ export class V2RequestCredentialHandler implements Handler { role: DidCommMessageRole.Sender, }) - return createOutboundServiceMessage({ - payload: message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + }, }) } diff --git a/packages/core/src/modules/discover-features/DiscoverFeaturesApi.ts b/packages/core/src/modules/discover-features/DiscoverFeaturesApi.ts index faa198b1de..94e376f08d 100644 --- a/packages/core/src/modules/discover-features/DiscoverFeaturesApi.ts +++ b/packages/core/src/modules/discover-features/DiscoverFeaturesApi.ts @@ -13,7 +13,7 @@ import { catchError, filter, map, takeUntil, timeout } from 'rxjs/operators' import { AgentContext } from '../../agent' import { EventEmitter } from '../../agent/EventEmitter' import { MessageSender } from '../../agent/MessageSender' -import { createOutboundMessage } from '../../agent/helpers' +import { OutboundMessageContext } from '../../agent/models' import { InjectionSymbols } from '../../constants' import { AriesFrameworkError } from '../../error' import { inject, injectable } from '../../plugins' @@ -103,7 +103,10 @@ export class DiscoverFeaturesApi< comment: options.comment, }) - const outbound = createOutboundMessage(connection, queryMessage) + const outboundMessageContext = new OutboundMessageContext(queryMessage, { + agentContext: this.agentContext, + connection, + }) const replaySubject = new ReplaySubject(1) if (options.awaitDisclosures) { @@ -125,7 +128,7 @@ export class DiscoverFeaturesApi< .subscribe(replaySubject) } - await this.messageSender.sendMessage(this.agentContext, outbound) + await this.messageSender.sendMessage(outboundMessageContext) return { features: options.awaitDisclosures ? await firstValueFrom(replaySubject) : undefined } } @@ -151,7 +154,10 @@ export class DiscoverFeaturesApi< threadId: options.threadId, }) - const outbound = createOutboundMessage(connection, disclosuresMessage) - await this.messageSender.sendMessage(this.agentContext, outbound) + const outboundMessageContext = new OutboundMessageContext(disclosuresMessage, { + agentContext: this.agentContext, + connection, + }) + await this.messageSender.sendMessage(outboundMessageContext) } } diff --git a/packages/core/src/modules/discover-features/protocol/v1/handlers/V1QueryMessageHandler.ts b/packages/core/src/modules/discover-features/protocol/v1/handlers/V1QueryMessageHandler.ts index 3ef5a66231..9a5bacf74c 100644 --- a/packages/core/src/modules/discover-features/protocol/v1/handlers/V1QueryMessageHandler.ts +++ b/packages/core/src/modules/discover-features/protocol/v1/handlers/V1QueryMessageHandler.ts @@ -1,7 +1,7 @@ import type { Handler, HandlerInboundMessage } from '../../../../../agent/Handler' import type { V1DiscoverFeaturesService } from '../V1DiscoverFeaturesService' -import { createOutboundMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { V1QueryMessage } from '../messages' export class V1QueryMessageHandler implements Handler { @@ -18,7 +18,10 @@ export class V1QueryMessageHandler implements Handler { const discloseMessage = await this.discoverFeaturesService.processQuery(inboundMessage) if (discloseMessage) { - return createOutboundMessage(connection, discloseMessage.message) + return new OutboundMessageContext(discloseMessage.message, { + agentContext: inboundMessage.agentContext, + connection, + }) } } } diff --git a/packages/core/src/modules/discover-features/protocol/v2/handlers/V2QueriesMessageHandler.ts b/packages/core/src/modules/discover-features/protocol/v2/handlers/V2QueriesMessageHandler.ts index d637bf2bc7..8664dd2240 100644 --- a/packages/core/src/modules/discover-features/protocol/v2/handlers/V2QueriesMessageHandler.ts +++ b/packages/core/src/modules/discover-features/protocol/v2/handlers/V2QueriesMessageHandler.ts @@ -1,7 +1,7 @@ import type { Handler, HandlerInboundMessage } from '../../../../../agent/Handler' import type { V2DiscoverFeaturesService } from '../V2DiscoverFeaturesService' -import { createOutboundMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { V2QueriesMessage } from '../messages' export class V2QueriesMessageHandler implements Handler { @@ -18,7 +18,10 @@ export class V2QueriesMessageHandler implements Handler { const discloseMessage = await this.discoverFeaturesService.processQuery(inboundMessage) if (discloseMessage) { - return createOutboundMessage(connection, discloseMessage.message) + return new OutboundMessageContext(discloseMessage.message, { + agentContext: inboundMessage.agentContext, + connection, + }) } } } diff --git a/packages/core/src/modules/oob/OutOfBandApi.ts b/packages/core/src/modules/oob/OutOfBandApi.ts index a23c163b42..f66ad984d3 100644 --- a/packages/core/src/modules/oob/OutOfBandApi.ts +++ b/packages/core/src/modules/oob/OutOfBandApi.ts @@ -14,7 +14,7 @@ import { Dispatcher } from '../../agent/Dispatcher' import { EventEmitter } from '../../agent/EventEmitter' import { filterContextCorrelationId, AgentEventTypes } from '../../agent/Events' import { MessageSender } from '../../agent/MessageSender' -import { createOutboundMessage } from '../../agent/helpers' +import { OutboundMessageContext } from '../../agent/models' import { InjectionSymbols } from '../../constants' import { ServiceDecorator } from '../../decorators/service/ServiceDecorator' import { AriesFrameworkError } from '../../error' @@ -748,8 +748,11 @@ export class OutOfBandApi { ) ) - const outbound = createOutboundMessage(connectionRecord, reuseMessage) - await this.messageSender.sendMessage(this.agentContext, outbound) + const outboundMessageContext = new OutboundMessageContext(reuseMessage, { + agentContext: this.agentContext, + connection: connectionRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return reuseAcceptedEventPromise } diff --git a/packages/core/src/modules/oob/handlers/HandshakeReuseHandler.ts b/packages/core/src/modules/oob/handlers/HandshakeReuseHandler.ts index 632eddd96a..43ec159d2e 100644 --- a/packages/core/src/modules/oob/handlers/HandshakeReuseHandler.ts +++ b/packages/core/src/modules/oob/handlers/HandshakeReuseHandler.ts @@ -2,7 +2,7 @@ import type { Handler } from '../../../agent/Handler' import type { InboundMessageContext } from '../../../agent/models/InboundMessageContext' import type { OutOfBandService } from '../OutOfBandService' -import { createOutboundMessage } from '../../../agent/helpers' +import { OutboundMessageContext } from '../../../agent/models' import { HandshakeReuseMessage } from '../messages/HandshakeReuseMessage' export class HandshakeReuseHandler implements Handler { @@ -17,6 +17,9 @@ export class HandshakeReuseHandler implements Handler { const connectionRecord = messageContext.assertReadyConnection() const handshakeReuseAcceptedMessage = await this.outOfBandService.processHandshakeReuse(messageContext) - return createOutboundMessage(connectionRecord, handshakeReuseAcceptedMessage) + return new OutboundMessageContext(handshakeReuseAcceptedMessage, { + agentContext: messageContext.agentContext, + connection: connectionRecord, + }) } } diff --git a/packages/core/src/modules/proofs/ProofsApi.ts b/packages/core/src/modules/proofs/ProofsApi.ts index 3e337b7ee8..1bec0aec43 100644 --- a/packages/core/src/modules/proofs/ProofsApi.ts +++ b/packages/core/src/modules/proofs/ProofsApi.ts @@ -37,7 +37,7 @@ import { AgentConfig } from '../../agent/AgentConfig' import { Dispatcher } from '../../agent/Dispatcher' import { MessageSender } from '../../agent/MessageSender' import { AgentContext } from '../../agent/context/AgentContext' -import { createOutboundMessage } from '../../agent/helpers' +import { OutboundMessageContext } from '../../agent/models' import { InjectionSymbols } from '../../constants' import { ServiceDecorator } from '../../decorators/service/ServiceDecorator' import { AriesFrameworkError } from '../../error' @@ -185,8 +185,12 @@ export class ProofsApi< const { message, proofRecord } = await service.createProposal(this.agentContext, proposalOptions) - const outbound = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outbound) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: proofRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return proofRecord } @@ -234,8 +238,12 @@ export class ProofsApi< const { message } = await service.createRequestAsResponse(this.agentContext, requestOptions) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: proofRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return proofRecord } @@ -264,8 +272,12 @@ export class ProofsApi< } const { message, proofRecord } = await service.createRequest(this.agentContext, createProofRequest) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: proofRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return proofRecord } @@ -301,8 +313,12 @@ export class ProofsApi< // Assert connection.assertReady() - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: proofRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) return proofRecord } @@ -327,12 +343,16 @@ export class ProofsApi< role: DidCommMessageRole.Sender, }) - await this.messageSender.sendMessageToService(this.agentContext, { - message, - service: recipientService.resolvedDidCommService, - senderKey: message.service.resolvedDidCommService.recipientKeys[0], - returnRoute: true, - }) + await this.messageSender.sendMessageToService( + new OutboundMessageContext(message, { + agentContext: this.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: message.service.resolvedDidCommService.recipientKeys[0], + returnRoute: true, + }, + }) + ) return proofRecord } @@ -405,20 +425,28 @@ export class ProofsApi< // Assert connection.assertReady() - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { + agentContext: this.agentContext, + connection, + associatedRecord: proofRecord, + }) + await this.messageSender.sendMessage(outboundMessageContext) } // Use ~service decorator otherwise else if (requestMessage?.service && presentationMessage?.service) { const recipientService = presentationMessage?.service const ourService = requestMessage.service - await this.messageSender.sendMessageToService(this.agentContext, { - message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], - returnRoute: true, - }) + await this.messageSender.sendMessageToService( + new OutboundMessageContext(message, { + agentContext: this.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + returnRoute: true, + }, + }) + ) } // Cannot send message without credentialId or ~service decorator else { @@ -497,8 +525,12 @@ export class ProofsApi< description: message, }) - const outboundMessage = createOutboundMessage(connection, problemReport) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(problemReport, { + agentContext: this.agentContext, + connection, + associatedRecord: record, + }) + await this.messageSender.sendMessage(outboundMessageContext) return record } diff --git a/packages/core/src/modules/proofs/protocol/v1/handlers/V1PresentationHandler.ts b/packages/core/src/modules/proofs/protocol/v1/handlers/V1PresentationHandler.ts index c55e644b44..c3fcd713d2 100644 --- a/packages/core/src/modules/proofs/protocol/v1/handlers/V1PresentationHandler.ts +++ b/packages/core/src/modules/proofs/protocol/v1/handlers/V1PresentationHandler.ts @@ -5,7 +5,7 @@ import type { ProofResponseCoordinator } from '../../../ProofResponseCoordinator import type { ProofExchangeRecord } from '../../../repository' import type { V1ProofService } from '../V1ProofService' -import { createOutboundMessage, createOutboundServiceMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { V1PresentationMessage, V1RequestPresentationMessage } from '../messages' export class V1PresentationHandler implements Handler { @@ -55,15 +55,21 @@ export class V1PresentationHandler implements Handler { }) if (messageContext.connection) { - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: proofRecord, + }) } else if (requestMessage?.service && presentationMessage?.service) { const recipientService = presentationMessage?.service const ourService = requestMessage?.service - return createOutboundServiceMessage({ - payload: message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + }, }) } diff --git a/packages/core/src/modules/proofs/protocol/v1/handlers/V1ProposePresentationHandler.ts b/packages/core/src/modules/proofs/protocol/v1/handlers/V1ProposePresentationHandler.ts index 4a9fe4b104..4e9d437669 100644 --- a/packages/core/src/modules/proofs/protocol/v1/handlers/V1ProposePresentationHandler.ts +++ b/packages/core/src/modules/proofs/protocol/v1/handlers/V1ProposePresentationHandler.ts @@ -8,7 +8,7 @@ import type { ProofRequestFromProposalOptions } from '../../../models/ProofServi import type { ProofExchangeRecord } from '../../../repository/ProofExchangeRecord' import type { V1ProofService } from '../V1ProofService' -import { createOutboundMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { AriesFrameworkError } from '../../../../../error' import { V1ProposePresentationMessage } from '../messages' @@ -99,6 +99,10 @@ export class V1ProposePresentationHandler implements Handler { willConfirm: true, }) - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: proofRecord, + }) } } diff --git a/packages/core/src/modules/proofs/protocol/v1/handlers/V1RequestPresentationHandler.ts b/packages/core/src/modules/proofs/protocol/v1/handlers/V1RequestPresentationHandler.ts index 5f7e72e7e8..5a0455baba 100644 --- a/packages/core/src/modules/proofs/protocol/v1/handlers/V1RequestPresentationHandler.ts +++ b/packages/core/src/modules/proofs/protocol/v1/handlers/V1RequestPresentationHandler.ts @@ -11,7 +11,7 @@ import type { import type { ProofExchangeRecord } from '../../../repository/ProofExchangeRecord' import type { V1ProofService } from '../V1ProofService' -import { createOutboundMessage, createOutboundServiceMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { ServiceDecorator } from '../../../../../decorators/service/ServiceDecorator' import { AriesFrameworkError } from '../../../../../error' import { DidCommMessageRole } from '../../../../../storage' @@ -96,7 +96,11 @@ export class V1RequestPresentationHandler implements Handler { }) if (messageContext.connection) { - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: proofRecord, + }) } else if (requestMessage.service) { const routing = await this.routingService.getRouting(messageContext.agentContext) message.service = new ServiceDecorator({ @@ -111,10 +115,12 @@ export class V1RequestPresentationHandler implements Handler { associatedRecordId: proofRecord.id, role: DidCommMessageRole.Sender, }) - return createOutboundServiceMessage({ - payload: message, - service: recipientService.resolvedDidCommService, - senderKey: message.service.resolvedDidCommService.recipientKeys[0], + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: message.service.resolvedDidCommService.recipientKeys[0], + }, }) } diff --git a/packages/core/src/modules/proofs/protocol/v2/handlers/V2PresentationHandler.ts b/packages/core/src/modules/proofs/protocol/v2/handlers/V2PresentationHandler.ts index c9723d8555..c812b6e8bd 100644 --- a/packages/core/src/modules/proofs/protocol/v2/handlers/V2PresentationHandler.ts +++ b/packages/core/src/modules/proofs/protocol/v2/handlers/V2PresentationHandler.ts @@ -5,7 +5,7 @@ import type { ProofResponseCoordinator } from '../../../ProofResponseCoordinator import type { ProofExchangeRecord } from '../../../repository' import type { V2ProofService } from '../V2ProofService' -import { createOutboundMessage, createOutboundServiceMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { V2PresentationMessage, V2RequestPresentationMessage } from '../messages' export class V2PresentationHandler implements Handler { @@ -55,15 +55,21 @@ export class V2PresentationHandler implements Handler { }) if (messageContext.connection) { - return createOutboundMessage(messageContext.connection, message) + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: messageContext.connection, + associatedRecord: proofRecord, + }) } else if (requestMessage?.service && presentationMessage?.service) { const recipientService = presentationMessage?.service const ourService = requestMessage?.service - return createOutboundServiceMessage({ - payload: message, - service: recipientService.resolvedDidCommService, - senderKey: ourService.resolvedDidCommService.recipientKeys[0], + return new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + serviceParams: { + service: recipientService.resolvedDidCommService, + senderKey: ourService.resolvedDidCommService.recipientKeys[0], + }, }) } diff --git a/packages/core/src/modules/proofs/protocol/v2/handlers/V2ProposePresentationHandler.ts b/packages/core/src/modules/proofs/protocol/v2/handlers/V2ProposePresentationHandler.ts index e3ddafe295..e822ed7a32 100644 --- a/packages/core/src/modules/proofs/protocol/v2/handlers/V2ProposePresentationHandler.ts +++ b/packages/core/src/modules/proofs/protocol/v2/handlers/V2ProposePresentationHandler.ts @@ -11,7 +11,7 @@ import type { import type { ProofExchangeRecord } from '../../../repository/ProofExchangeRecord' import type { V2ProofService } from '../V2ProofService' -import { createOutboundMessage } from '../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../agent/models' import { AriesFrameworkError } from '../../../../../error/AriesFrameworkError' import { V2ProposalPresentationMessage } from '../messages/V2ProposalPresentationMessage' @@ -90,6 +90,10 @@ export class V2ProposePresentationHandler 0 ? new MessageDeliveryMessage({ threadId: messageContext.message.threadId, @@ -93,7 +93,7 @@ export class V2MessagePickupService { messageCount: 0, }) - return createOutboundMessage(connection, outboundMessage) + return new OutboundMessageContext(outboundMessageContext, { agentContext: messageContext.agentContext, connection }) } public async processMessagesReceived(messageContext: InboundMessageContext) { @@ -113,7 +113,7 @@ export class V2MessagePickupService { messageCount: await this.messageRepository.getAvailableMessageCount(connection.id), }) - return createOutboundMessage(connection, statusMessage) + return new OutboundMessageContext(statusMessage, { agentContext: messageContext.agentContext, connection }) } protected registerHandlers() { diff --git a/packages/core/src/modules/routing/protocol/pickup/v2/handlers/MessageDeliveryHandler.ts b/packages/core/src/modules/routing/protocol/pickup/v2/handlers/MessageDeliveryHandler.ts index 07b01a3d7f..fb9db1d25b 100644 --- a/packages/core/src/modules/routing/protocol/pickup/v2/handlers/MessageDeliveryHandler.ts +++ b/packages/core/src/modules/routing/protocol/pickup/v2/handlers/MessageDeliveryHandler.ts @@ -2,7 +2,7 @@ import type { Handler } from '../../../../../../agent/Handler' import type { InboundMessageContext } from '../../../../../../agent/models/InboundMessageContext' import type { MediationRecipientService } from '../../../../services' -import { createOutboundMessage } from '../../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../../agent/models' import { MessageDeliveryMessage } from '../messages/MessageDeliveryMessage' export class MessageDeliveryHandler implements Handler { @@ -18,7 +18,10 @@ export class MessageDeliveryHandler implements Handler { const deliveryReceivedMessage = await this.mediationRecipientService.processDelivery(messageContext) if (deliveryReceivedMessage) { - return createOutboundMessage(connection, deliveryReceivedMessage) + return new OutboundMessageContext(deliveryReceivedMessage, { + agentContext: messageContext.agentContext, + connection, + }) } } } diff --git a/packages/core/src/modules/routing/protocol/pickup/v2/handlers/StatusHandler.ts b/packages/core/src/modules/routing/protocol/pickup/v2/handlers/StatusHandler.ts index 08e4278c61..163f1a9c4f 100644 --- a/packages/core/src/modules/routing/protocol/pickup/v2/handlers/StatusHandler.ts +++ b/packages/core/src/modules/routing/protocol/pickup/v2/handlers/StatusHandler.ts @@ -2,7 +2,7 @@ import type { Handler } from '../../../../../../agent/Handler' import type { InboundMessageContext } from '../../../../../../agent/models/InboundMessageContext' import type { MediationRecipientService } from '../../../../services' -import { createOutboundMessage } from '../../../../../../agent/helpers' +import { OutboundMessageContext } from '../../../../../../agent/models' import { StatusMessage } from '../messages' export class StatusHandler implements Handler { @@ -18,7 +18,10 @@ export class StatusHandler implements Handler { const deliveryRequestMessage = await this.mediatorRecipientService.processStatus(messageContext) if (deliveryRequestMessage) { - return createOutboundMessage(connection, deliveryRequestMessage) + return new OutboundMessageContext(deliveryRequestMessage, { + agentContext: messageContext.agentContext, + connection, + }) } } } diff --git a/packages/core/src/modules/routing/services/MediationRecipientService.ts b/packages/core/src/modules/routing/services/MediationRecipientService.ts index b62db55446..f05f66e20f 100644 --- a/packages/core/src/modules/routing/services/MediationRecipientService.ts +++ b/packages/core/src/modules/routing/services/MediationRecipientService.ts @@ -17,7 +17,7 @@ import { filter, first, timeout } from 'rxjs/operators' import { EventEmitter } from '../../../agent/EventEmitter' import { filterContextCorrelationId, AgentEventTypes } from '../../../agent/Events' import { MessageSender } from '../../../agent/MessageSender' -import { createOutboundMessage } from '../../../agent/helpers' +import { OutboundMessageContext } from '../../../agent/models' import { Key, KeyType } from '../../../crypto' import { AriesFrameworkError } from '../../../error' import { injectable } from '../../../plugins' @@ -209,8 +209,8 @@ export class MediationRecipientService { ) .subscribe(subject) - const outboundMessage = createOutboundMessage(connection, message) - await this.messageSender.sendMessage(agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(message, { agentContext, connection }) + await this.messageSender.sendMessage(outboundMessageContext) const keylistUpdate = await firstValueFrom(subject) return keylistUpdate.payload.mediationRecord @@ -297,8 +297,10 @@ export class MediationRecipientService { const websocketSchemes = ['ws', 'wss'] await this.messageSender.sendMessage( - messageContext.agentContext, - createOutboundMessage(connectionRecord, message), + new OutboundMessageContext(message, { + agentContext: messageContext.agentContext, + connection: connectionRecord, + }), { transportPriority: { schemes: websocketSchemes, diff --git a/packages/core/src/modules/routing/services/__tests__/V2MessagePickupService.test.ts b/packages/core/src/modules/routing/services/__tests__/V2MessagePickupService.test.ts index e72ce7c425..53012f73b0 100644 --- a/packages/core/src/modules/routing/services/__tests__/V2MessagePickupService.test.ts +++ b/packages/core/src/modules/routing/services/__tests__/V2MessagePickupService.test.ts @@ -60,17 +60,17 @@ describe('V2MessagePickupService', () => { const messageContext = new InboundMessageContext(statusRequest, { connection: mockConnection, agentContext }) - const { connection, payload } = await pickupService.processStatusRequest(messageContext) + const { connection, message } = await pickupService.processStatusRequest(messageContext) expect(connection).toEqual(mockConnection) - expect(payload).toEqual( + expect(message).toEqual( new StatusMessage({ - id: payload.id, + id: message.id, threadId: statusRequest.threadId, messageCount: 0, }) ) - expect(messageRepository.getAvailableMessageCount).toHaveBeenCalledWith(connection.id) + expect(messageRepository.getAvailableMessageCount).toHaveBeenCalledWith(mockConnection.id) }) test('multiple messages in queue', async () => { @@ -79,17 +79,17 @@ describe('V2MessagePickupService', () => { const messageContext = new InboundMessageContext(statusRequest, { connection: mockConnection, agentContext }) - const { connection, payload } = await pickupService.processStatusRequest(messageContext) + const { connection, message } = await pickupService.processStatusRequest(messageContext) expect(connection).toEqual(mockConnection) - expect(payload).toEqual( + expect(message).toEqual( new StatusMessage({ - id: payload.id, + id: message.id, threadId: statusRequest.threadId, messageCount: 5, }) ) - expect(messageRepository.getAvailableMessageCount).toHaveBeenCalledWith(connection.id) + expect(messageRepository.getAvailableMessageCount).toHaveBeenCalledWith(mockConnection.id) }) test('status request specifying recipient key', async () => { @@ -115,17 +115,17 @@ describe('V2MessagePickupService', () => { const messageContext = new InboundMessageContext(deliveryRequest, { connection: mockConnection, agentContext }) - const { connection, payload } = await pickupService.processDeliveryRequest(messageContext) + const { connection, message } = await pickupService.processDeliveryRequest(messageContext) expect(connection).toEqual(mockConnection) - expect(payload).toEqual( + expect(message).toEqual( new StatusMessage({ - id: payload.id, + id: message.id, threadId: deliveryRequest.threadId, messageCount: 0, }) ) - expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(connection.id, 10, true) + expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(mockConnection.id, 10, true) }) test('less messages in queue than limit', async () => { @@ -135,13 +135,13 @@ describe('V2MessagePickupService', () => { const messageContext = new InboundMessageContext(deliveryRequest, { connection: mockConnection, agentContext }) - const { connection, payload } = await pickupService.processDeliveryRequest(messageContext) + const { connection, message } = await pickupService.processDeliveryRequest(messageContext) expect(connection).toEqual(mockConnection) - expect(payload).toBeInstanceOf(MessageDeliveryMessage) - expect(payload.threadId).toEqual(deliveryRequest.threadId) - expect(payload.appendedAttachments?.length).toEqual(3) - expect(payload.appendedAttachments).toEqual( + expect(message).toBeInstanceOf(MessageDeliveryMessage) + expect(message.threadId).toEqual(deliveryRequest.threadId) + expect(message.appendedAttachments?.length).toEqual(3) + expect(message.appendedAttachments).toEqual( expect.arrayContaining( queuedMessages.map((msg) => expect.objectContaining({ @@ -152,7 +152,7 @@ describe('V2MessagePickupService', () => { ) ) ) - expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(connection.id, 10, true) + expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(mockConnection.id, 10, true) }) test('more messages in queue than limit', async () => { @@ -162,13 +162,13 @@ describe('V2MessagePickupService', () => { const messageContext = new InboundMessageContext(deliveryRequest, { connection: mockConnection, agentContext }) - const { connection, payload } = await pickupService.processDeliveryRequest(messageContext) + const { connection, message } = await pickupService.processDeliveryRequest(messageContext) expect(connection).toEqual(mockConnection) - expect(payload).toBeInstanceOf(MessageDeliveryMessage) - expect(payload.threadId).toEqual(deliveryRequest.threadId) - expect(payload.appendedAttachments?.length).toEqual(2) - expect(payload.appendedAttachments).toEqual( + expect(message).toBeInstanceOf(MessageDeliveryMessage) + expect(message.threadId).toEqual(deliveryRequest.threadId) + expect(message.appendedAttachments?.length).toEqual(2) + expect(message.appendedAttachments).toEqual( expect.arrayContaining( queuedMessages.slice(0, 2).map((msg) => expect.objectContaining({ @@ -179,7 +179,7 @@ describe('V2MessagePickupService', () => { ) ) ) - expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(connection.id, 2, true) + expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(mockConnection.id, 2, true) }) test('delivery request specifying recipient key', async () => { @@ -209,18 +209,18 @@ describe('V2MessagePickupService', () => { const messageContext = new InboundMessageContext(messagesReceived, { connection: mockConnection, agentContext }) - const { connection, payload } = await pickupService.processMessagesReceived(messageContext) + const { connection, message } = await pickupService.processMessagesReceived(messageContext) expect(connection).toEqual(mockConnection) - expect(payload).toEqual( + expect(message).toEqual( new StatusMessage({ - id: payload.id, + id: message.id, threadId: messagesReceived.threadId, messageCount: 4, }) ) - expect(messageRepository.getAvailableMessageCount).toHaveBeenCalledWith(connection.id) - expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(connection.id, 2) + expect(messageRepository.getAvailableMessageCount).toHaveBeenCalledWith(mockConnection.id) + expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(mockConnection.id, 2) }) test('all messages have been received', async () => { @@ -233,19 +233,19 @@ describe('V2MessagePickupService', () => { const messageContext = new InboundMessageContext(messagesReceived, { connection: mockConnection, agentContext }) - const { connection, payload } = await pickupService.processMessagesReceived(messageContext) + const { connection, message } = await pickupService.processMessagesReceived(messageContext) expect(connection).toEqual(mockConnection) - expect(payload).toEqual( + expect(message).toEqual( new StatusMessage({ - id: payload.id, + id: message.id, threadId: messagesReceived.threadId, messageCount: 0, }) ) - expect(messageRepository.getAvailableMessageCount).toHaveBeenCalledWith(connection.id) - expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(connection.id, 2) + expect(messageRepository.getAvailableMessageCount).toHaveBeenCalledWith(mockConnection.id) + expect(messageRepository.takeFromQueue).toHaveBeenCalledWith(mockConnection.id, 2) }) }) }) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 9e886472df..6d409b000e 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -94,20 +94,6 @@ export interface PlaintextMessage { [key: string]: unknown } -export interface OutboundMessage { - payload: T - connection: ConnectionRecord - sessionId?: string - outOfBand?: OutOfBandRecord - associatedRecord?: BaseRecord -} - -export interface OutboundServiceMessage { - payload: T - service: ResolvedDidCommService - senderKey: Key -} - export interface OutboundPackage { payload: EncryptedMessage responseRequested?: boolean diff --git a/packages/core/tests/multi-protocol-version.test.ts b/packages/core/tests/multi-protocol-version.test.ts index 83dc39986a..07b7b057f0 100644 --- a/packages/core/tests/multi-protocol-version.test.ts +++ b/packages/core/tests/multi-protocol-version.test.ts @@ -8,7 +8,7 @@ import { SubjectOutboundTransport } from '../../../tests/transport/SubjectOutbou import { parseMessageType, MessageSender, Dispatcher, AgentMessage, IsValidMessageType } from '../src' import { Agent } from '../src/agent/Agent' import { AgentEventTypes } from '../src/agent/Events' -import { createOutboundMessage } from '../src/agent/helpers' +import { OutboundMessageContext } from '../src/agent/models' import { getAgentOptions } from './helpers' @@ -84,7 +84,9 @@ describe('multi version protocols', () => { ) ) - await bobMessageSender.sendMessage(bobAgent.context, createOutboundMessage(bobConnection, new TestMessageV11())) + await bobMessageSender.sendMessage( + new OutboundMessageContext(new TestMessageV11(), { agentContext: bobAgent.context, connection: bobConnection }) + ) // Wait for the agent message processed event to be called await agentMessageV11ProcessedPromise @@ -99,7 +101,9 @@ describe('multi version protocols', () => { ) ) - await bobMessageSender.sendMessage(bobAgent.context, createOutboundMessage(bobConnection, new TestMessageV15())) + await bobMessageSender.sendMessage( + new OutboundMessageContext(new TestMessageV15(), { agentContext: bobAgent.context, connection: bobConnection }) + ) await agentMessageV15ProcessedPromise expect(mockHandle).toHaveBeenCalledTimes(2) diff --git a/packages/question-answer/src/QuestionAnswerApi.ts b/packages/question-answer/src/QuestionAnswerApi.ts index 52167ebf95..777e3ff12f 100644 --- a/packages/question-answer/src/QuestionAnswerApi.ts +++ b/packages/question-answer/src/QuestionAnswerApi.ts @@ -4,7 +4,7 @@ import type { Query } from '@aries-framework/core' import { AgentContext, ConnectionService, - createOutboundMessage, + OutboundMessageContext, Dispatcher, injectable, MessageSender, @@ -63,8 +63,13 @@ export class QuestionAnswerApi { detail: config?.detail, } ) - const outboundMessage = createOutboundMessage(connection, questionMessage) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(questionMessage, { + agentContext: this.agentContext, + connection, + associatedRecord: questionAnswerRecord, + }) + + await this.messageSender.sendMessage(outboundMessageContext) return questionAnswerRecord } @@ -87,8 +92,13 @@ export class QuestionAnswerApi { const connection = await this.connectionService.getById(this.agentContext, questionRecord.connectionId) - const outboundMessage = createOutboundMessage(connection, answerMessage) - await this.messageSender.sendMessage(this.agentContext, outboundMessage) + const outboundMessageContext = new OutboundMessageContext(answerMessage, { + agentContext: this.agentContext, + connection, + associatedRecord: questionAnswerRecord, + }) + + await this.messageSender.sendMessage(outboundMessageContext) return questionAnswerRecord } diff --git a/samples/extension-module/dummy/DummyApi.ts b/samples/extension-module/dummy/DummyApi.ts index eeb50b469b..dded85085f 100644 --- a/samples/extension-module/dummy/DummyApi.ts +++ b/samples/extension-module/dummy/DummyApi.ts @@ -1,7 +1,14 @@ import type { DummyRecord } from './repository/DummyRecord' import type { Query } from '@aries-framework/core' -import { AgentContext, ConnectionService, Dispatcher, injectable, MessageSender } from '@aries-framework/core' +import { + OutboundMessageContext, + AgentContext, + ConnectionService, + Dispatcher, + injectable, + MessageSender, +} from '@aries-framework/core' import { DummyRequestHandler, DummyResponseHandler } from './handlers' import { DummyState } from './repository' @@ -37,9 +44,11 @@ export class DummyApi { */ public async request(connectionId: string) { const connection = await this.connectionService.getById(this.agentContext, connectionId) - const { record, message: payload } = await this.dummyService.createRequest(this.agentContext, connection) + const { record, message } = await this.dummyService.createRequest(this.agentContext, connection) - await this.messageSender.sendMessage(this.agentContext, { connection, payload }) + await this.messageSender.sendMessage( + new OutboundMessageContext(message, { agentContext: this.agentContext, connection }) + ) await this.dummyService.updateState(this.agentContext, record, DummyState.RequestSent) @@ -56,9 +65,11 @@ export class DummyApi { const record = await this.dummyService.getById(this.agentContext, dummyId) const connection = await this.connectionService.getById(this.agentContext, record.connectionId) - const payload = await this.dummyService.createResponse(this.agentContext, record) + const message = await this.dummyService.createResponse(this.agentContext, record) - await this.messageSender.sendMessage(this.agentContext, { connection, payload }) + await this.messageSender.sendMessage( + new OutboundMessageContext(message, { agentContext: this.agentContext, connection, associatedRecord: record }) + ) await this.dummyService.updateState(this.agentContext, record, DummyState.ResponseSent) diff --git a/samples/extension-module/dummy/handlers/DummyRequestHandler.ts b/samples/extension-module/dummy/handlers/DummyRequestHandler.ts index ef5d5471ec..7b0de4ea72 100644 --- a/samples/extension-module/dummy/handlers/DummyRequestHandler.ts +++ b/samples/extension-module/dummy/handlers/DummyRequestHandler.ts @@ -1,7 +1,7 @@ import type { DummyService } from '../services' import type { Handler, HandlerInboundMessage } from '@aries-framework/core' -import { createOutboundMessage } from '@aries-framework/core' +import { OutboundMessageContext } from '@aries-framework/core' import { DummyRequestMessage } from '../messages' @@ -18,7 +18,7 @@ export class DummyRequestHandler implements Handler { const responseMessage = await this.dummyService.processRequest(inboundMessage) if (responseMessage) { - return createOutboundMessage(connection, responseMessage) + return new OutboundMessageContext(responseMessage, { agentContext: inboundMessage.agentContext, connection }) } } }