From 1170e2f093ec2a2f70a56eda22d3721c6063ddc4 Mon Sep 17 00:00:00 2001 From: goncalo-frade-iohk <87179681+goncalo-frade-iohk@users.noreply.github.com> Date: Mon, 19 Dec 2022 12:43:09 +0000 Subject: [PATCH] feat(mercury): forward messaging to mediator (#264) * feat(mercury): forward messaging to mediator * Update mercury/mercury-library/agent-didcommx/src/main/scala/io/iohk/atala/mercury/MessagingService.scala Co-authored-by: Yurii Shynbuiev - IOHK <102033808+yshyn-iohk@users.noreply.github.com> Co-authored-by: Fabio Pinheiro Co-authored-by: Yurii Shynbuiev - IOHK <102033808+yshyn-iohk@users.noreply.github.com> --- .../iohk/atala/mercury/MessagingService.scala | 57 +++++++++++++++---- .../mercury/model/AttachmentDescriptor.scala | 9 +++ 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/mercury/mercury-library/agent-didcommx/src/main/scala/io/iohk/atala/mercury/MessagingService.scala b/mercury/mercury-library/agent-didcommx/src/main/scala/io/iohk/atala/mercury/MessagingService.scala index 60aed93aed..b5664f75c6 100644 --- a/mercury/mercury-library/agent-didcommx/src/main/scala/io/iohk/atala/mercury/MessagingService.scala +++ b/mercury/mercury-library/agent-didcommx/src/main/scala/io/iohk/atala/mercury/MessagingService.scala @@ -3,8 +3,13 @@ package io.iohk.atala.mercury import scala.jdk.CollectionConverters.* import zio._ +import io.circe._ +import io.circe.Json._ +import io.circe.parser._ +import io.circe.JsonObject import io.iohk.atala.mercury.model._ import io.iohk.atala.mercury.model.error._ +import io.iohk.atala.mercury.protocol.routing._ import io.iohk.atala.resolvers.DIDResolver import org.didcommx.didcomm.common.VerificationMethodType import org.didcommx.didcomm.common.VerificationMaterialFormat @@ -14,6 +19,31 @@ case class ServiceEndpoint(uri: HttpOrDID, accept: Option[Seq[String]], routingK object MessagingService { + def isForwardMessage[Service <: DidComm, Resolver <: DIDResolver]( + didCommService: Service, + resolver: Resolver, + didCommServiceEndpoint: ServiceEndpoint, + message: Message, + encrypted: EncryptedMessage): ZIO[Any, Throwable, EncryptedMessage] = { + if (didCommServiceEndpoint.uri.startsWith("did:")) { +for { + _ <- Console.printLine("RoutingDID:" + DidId(didCommServiceEndpoint.uri)) + forwardMessage <- didCommService.packEncrypted( + ForwardMessage( + from = message.from.get, + to = DidId(didCommServiceEndpoint.uri), + expires_time = None, + body = ForwardBody(next = message.to.head), // TODO check msg header + attachments = Seq(AttachmentDescriptor.buildJsonAttachment(payload = encrypted.asJson)), + ).asMessage, + to = DidId(didCommServiceEndpoint.uri) + ) +} yield forwardMesage + } else { + ZIO.succeed(encrypted) + } +} + /** Encrypt and send a Message via HTTP * * TODO Move this method to another model @@ -30,11 +60,10 @@ object MessagingService { case head +: tail => // TODO support for multiple destinations ZIO.fail(new RuntimeException("TODO multiple destinations")) } + _ <- Console.printLine("Encrypted Message") + encryptedMessage <- didCommService.packEncrypted(msg, to = msg.to.head) // TODO head - encryptedForwardMessage <- didCommService.packEncryptedForward(msg, to = msg.to.head) // TODO head - jsonString = encryptedForwardMessage.string - - didCommService <- resolver + didCommServiceUrl <- resolver .didCommServices(sendToDID) /* Seq[DIDCommService] */ .flatMap { case Seq() => @@ -57,14 +86,18 @@ object MessagingService { ) ) } - serviceEndpoint <- - if (didCommService.uri.startsWith("did:")) - resolver - .didCommServices(DidId(didCommService.uri)) - .map(_.toSeq.head.getServiceEndpoint()) // TODO this is not safe and also need to be recursive - else ZIO.succeed(didCommService.uri) - - _ <- Console.printLine("Sending to " + serviceEndpoint) + _ <- Console.printLine("Forward message") + sendMsg = isForwardMessage(didCommService, resolver, didCommServiceUrl, msg, encryptedMessage) + jsonString <- sendMsg.map(_.string) + + serviceEndpoint <- if (didCommServiceUrl.uri.startsWith("did:")) + resolver + .didCommServices(DidId(didCommServiceUrl.uri)) + .map(_.toSeq.head.getServiceEndpoint()) // TODO this is not safe and also need to be recursive + else ZIO.succeed(didCommServiceUrl.uri) + + _ <- Console.printLine("Sending to" + serviceEndpoint) + res <- HttpClient.postDIDComm(serviceEndpoint, jsonString) } yield (res) }.catchAll { case ex => diff --git a/mercury/mercury-library/models/src/main/scala/io/iohk/atala/mercury/model/AttachmentDescriptor.scala b/mercury/mercury-library/models/src/main/scala/io/iohk/atala/mercury/model/AttachmentDescriptor.scala index a6031e4725..d7b676521b 100644 --- a/mercury/mercury-library/models/src/main/scala/io/iohk/atala/mercury/model/AttachmentDescriptor.scala +++ b/mercury/mercury-library/models/src/main/scala/io/iohk/atala/mercury/model/AttachmentDescriptor.scala @@ -111,6 +111,15 @@ object AttachmentDescriptor { AttachmentDescriptor(id, mediaType, Base64(encoded)) // use JsonData or Base64 by default? } + def buildJsonAttachment[A]( + id: String = java.util.UUID.randomUUID.toString, + payload: A, + mediaType: Option[String] = Some("application/json") + )(using Encoder[A]): AttachmentDescriptor = { + val jsonObject = payload.asJson.asObject.getOrElse(JsonObject.empty) + AttachmentDescriptor(id, mediaType, JsonData(jsonObject)) // use JsonData or Base64 by default? + } + given attachmentDescriptorEncoderV1: Encoder[AttachmentDescriptor] = (a: AttachmentDescriptor) => { Json.obj( "@id" -> a.id.asJson,