Skip to content

Commit

Permalink
feat(mercury): forward messaging to mediator (#264)
Browse files Browse the repository at this point in the history
* 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 <fabiomgpinheiro@gmail.com>
Co-authored-by: Yurii Shynbuiev - IOHK <102033808+yshyn-iohk@users.noreply.github.com>
  • Loading branch information
3 people committed Dec 19, 2022
1 parent c4af22b commit 1170e2f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 12 deletions.
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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() =>
Expand All @@ -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 =>
Expand Down
Expand Up @@ -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,
Expand Down

0 comments on commit 1170e2f

Please sign in to comment.