From fd5dccd0b40c8b9806d0c91b3c06e5b7d83aef46 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 13:43:31 +0100 Subject: [PATCH 01/22] feat: migrate mercury 'models' Signed-off-by: Benjamin Voiturier --- .../mercury/model/AttachmentDescriptor.scala | 98 ++++++++++--------- .../identus/mercury/model/DidId.scala | 9 +- .../mercury/model/EncryptedMessage.scala | 16 +-- .../identus/mercury/model/Message.scala | 14 +-- 4 files changed, 67 insertions(+), 70 deletions(-) diff --git a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/AttachmentDescriptor.scala b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/AttachmentDescriptor.scala index db10c4c3a2..2cf47e581d 100644 --- a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/AttachmentDescriptor.scala +++ b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/AttachmentDescriptor.scala @@ -1,9 +1,8 @@ package org.hyperledger.identus.mercury.model -import cats.syntax.functor.* -import io.circe.{Decoder, Encoder, Json, JsonObject} -import io.circe.generic.semiauto.* -import io.circe.syntax.* +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} +import zio.json.ast.Json +import zio.json.internal.Write import java.util.Base64 as JBase64 @@ -14,57 +13,59 @@ sealed trait AttachmentData final case class Header(kid: String) object Header { - given Encoder[Header] = deriveEncoder[Header] - - given Decoder[Header] = deriveDecoder[Header] + given JsonEncoder[Header] = DeriveJsonEncoder.gen + given JsonDecoder[Header] = DeriveJsonDecoder.gen } + final case class Jws(header: Header, `protected`: String, signature: String) object Jws { - given Encoder[Jws] = deriveEncoder[Jws] - - given Decoder[Jws] = deriveDecoder[Jws] + given JsonEncoder[Jws] = DeriveJsonEncoder.gen + given JsonDecoder[Jws] = DeriveJsonDecoder.gen } + final case class JwsData(base64: String, jws: Jws) extends AttachmentData object JwsData { - given Encoder[JwsData] = deriveEncoder[JwsData] - - given Decoder[JwsData] = deriveDecoder[JwsData] + given JsonEncoder[JwsData] = DeriveJsonEncoder.gen + given JsonDecoder[JwsData] = DeriveJsonDecoder.gen } + final case class Base64(base64: String) extends AttachmentData object Base64 { - given Encoder[Base64] = deriveEncoder[Base64] - given Decoder[Base64] = deriveDecoder[Base64] + given JsonEncoder[Base64] = DeriveJsonEncoder.gen + given JsonDecoder[Base64] = DeriveJsonDecoder.gen } final case class LinkData(links: Seq[String], hash: String) extends AttachmentData object LinkData { - given Encoder[LinkData] = deriveEncoder[LinkData] - given Decoder[LinkData] = deriveDecoder[LinkData] + given JsonEncoder[LinkData] = DeriveJsonEncoder.gen + given JsonDecoder[LinkData] = DeriveJsonDecoder.gen } -final case class JsonData(json: JsonObject) extends AttachmentData +final case class JsonData(json: Json.Obj) extends AttachmentData object JsonData { - given Encoder[JsonData] = deriveEncoder[JsonData] - given Decoder[JsonData] = deriveDecoder[JsonData] + given JsonEncoder[JsonData] = DeriveJsonEncoder.gen + given JsonDecoder[JsonData] = DeriveJsonDecoder.gen } + object AttachmentData { - // given Encoder[AttachmentData] = deriveEncoder[AttachmentData] - given Encoder[AttachmentData] = (a: AttachmentData) => { + given JsonEncoder[AttachmentData] = (a: AttachmentData, indent: Option[Int], out: Write) => { a match - case data @ JsonData(_) => data.asJson - case data @ Base64(_) => data.asJson - case data @ JwsData(_, _) => data.asJson - case data @ LinkData(_, _) => data.asJson + case data @ JwsData(_, _) => JsonEncoder[JwsData].unsafeEncode(data, indent, out) + case data @ Base64(_) => JsonEncoder[Base64].unsafeEncode(data, indent, out) + case data @ LinkData(_, _) => JsonEncoder[LinkData].unsafeEncode(data, indent, out) + case data @ JsonData(_) => JsonEncoder[JsonData].unsafeEncode(data, indent, out) + } + given JsonDecoder[AttachmentData] = JsonDecoder[Json].mapOrFail { json => + json + .as[JwsData] + .orElse(json.as[Base64]) + .orElse(json.as[LinkData]) + .orElse(json.as[JsonData]) + .left + .map(error => s"Failed to decode AttachmentData: $error") } - - given Decoder[AttachmentData] = List[Decoder[AttachmentData]]( - Decoder[JsonData].widen, - Decoder[Base64].widen, - Decoder[JwsData].widen, - Decoder[LinkData].widen - ).reduceLeft(_ or _) } /** https://identity.foundation/didcomm-messaging/spec/#attachments @@ -119,21 +120,26 @@ object AttachmentDescriptor { payload: A, mediaType: Option[String] = Some("application/json"), format: Option[String] = None, - )(using Encoder[A]): AttachmentDescriptor = { - val jsonObject = payload.asJson.asObject.getOrElse(JsonObject.empty) + )(using JsonEncoder[A]): AttachmentDescriptor = { + val jsonObject = payload.toJsonAST.toOption.flatMap(_.asObject).getOrElse(Json.Obj()) AttachmentDescriptor(id, mediaType, JsonData(jsonObject), format = format) // use JsonData or Base64 by default? } - given attachmentDescriptorEncoderV1: Encoder[AttachmentDescriptor] = (a: AttachmentDescriptor) => { - Json.obj( - "@id" -> a.id.asJson, - "mime_type" -> a.media_type.asJson, - "data" -> a.data.asJson - ) - } - - given attachmentDescriptorEncoderV2: Encoder[AttachmentDescriptor] = deriveEncoder[AttachmentDescriptor] - - given Decoder[AttachmentDescriptor] = deriveDecoder[AttachmentDescriptor] + given attachmentDescriptorEncoderV1: JsonEncoder[AttachmentDescriptor] = + (a: AttachmentDescriptor, indent: Option[Int], out: Write) => { + out.write("{") + out.write("\"@id\":") + JsonEncoder[String].unsafeEncode(a.id, indent, out) + a.media_type.foreach { mt => + out.write(",\"mime_type\":") + JsonEncoder[String].unsafeEncode(mt, indent, out) + } + out.write(",\"data\":") + JsonEncoder[AttachmentData].unsafeEncode(a.data, indent, out) + out.write("}") + } + + given attachmentDescriptorEncoderV2: JsonEncoder[AttachmentDescriptor] = DeriveJsonEncoder.gen + given JsonDecoder[AttachmentDescriptor] = DeriveJsonDecoder.gen } diff --git a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/DidId.scala b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/DidId.scala index 3100bc481c..e7842b43a1 100644 --- a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/DidId.scala +++ b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/DidId.scala @@ -1,12 +1,9 @@ package org.hyperledger.identus.mercury.model -import io.circe.* -import io.circe.generic.semiauto.* - -import scala.util.Try +import zio.json.{JsonDecoder, JsonEncoder} final case class DidId(value: String) object DidId { - given encoder: Encoder[DidId] = Encoder.encodeString.contramap[DidId](_.value) - given decoder: Decoder[DidId] = Decoder.decodeString.emapTry { str => Try(DidId(str)) } + given encoder: JsonEncoder[DidId] = JsonEncoder[String].contramap(_.value) + given decoder: JsonDecoder[DidId] = JsonDecoder[String].map(str => DidId(str)) } diff --git a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/EncryptedMessage.scala b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/EncryptedMessage.scala index 4796544b0e..323a377d0f 100644 --- a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/EncryptedMessage.scala +++ b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/EncryptedMessage.scala @@ -1,24 +1,18 @@ package org.hyperledger.identus.mercury.model -import io.circe.* -import io.circe.parser.* +import zio.json.ast.Json +import zio.json.EncoderOps import java.util.Base64 trait EncryptedMessage { // (private val msg: PackEncryptedResult) { def string: String // = msg.getPackedMessage def base64: String = Base64.getUrlEncoder.encodeToString(string.getBytes) - def asJson: JsonObject = { - parse(string) + def asJson: Json.Obj = { + string.toJsonAST .flatMap(o => o.asObject match - case None => - Left( - ParsingFailure( - "Expecting the Json to be a Json Object", - RuntimeException(s"Expecting Json Object got '$o'") - ) - ) + case None => Left(RuntimeException(s"Expecting Json Object got '$o'")) case Some(value) => Right(value) ) .getOrElse(UnexpectedCodeExecutionPath) diff --git a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/Message.scala b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/Message.scala index ecd1fbae50..6384216742 100644 --- a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/Message.scala +++ b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/Message.scala @@ -1,7 +1,7 @@ package org.hyperledger.identus.mercury.model -import io.circe.* -import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} +import zio.json.ast.Json import java.time.{LocalDateTime, ZoneOffset} import scala.jdk.CollectionConverters.* @@ -11,8 +11,8 @@ case class Message( `type`: PIURI, from: Option[DidId], to: Seq[DidId], - body: JsonObject = JsonObject.empty, - id: String = java.util.UUID.randomUUID.toString(), + body: Json.Obj = Json.Obj(), + id: String = java.util.UUID.randomUUID.toString, createdTime: Option[Long] = Some(LocalDateTime.now().toEpochSecond(ZoneOffset.of("Z"))), expiresTimePlus: Option[Long] = Some(1000), attachments: Option[Seq[AttachmentDescriptor]] = None, // id -> data (data is also a json) @@ -25,9 +25,9 @@ case class Message( } object Message { - given Encoder[Message] = { + given JsonEncoder[Message] = { import AttachmentDescriptor.attachmentDescriptorEncoderV2 - deriveEncoder[Message] + DeriveJsonEncoder.gen } - given Decoder[Message] = deriveDecoder[Message] + given JsonDecoder[Message] = DeriveJsonDecoder.gen } From 2cd97c5a2bbeaf63a467c52c2613bebe16b28372 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 13:51:18 +0100 Subject: [PATCH 02/22] feat: migrate protocol-connection Signed-off-by: Benjamin Voiturier --- .../connection/ConnectionRequest.scala | 21 +++++++++---------- .../connection/ConnectionResponse.scala | 19 ++++++++--------- .../protocol/connection/ConnectionSpec.scala | 11 +++++----- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/mercury/protocol-connection/src/main/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionRequest.scala b/mercury/protocol-connection/src/main/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionRequest.scala index 4909f266d1..98f54227d3 100644 --- a/mercury/protocol-connection/src/main/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionRequest.scala +++ b/mercury/protocol-connection/src/main/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionRequest.scala @@ -1,10 +1,9 @@ package org.hyperledger.identus.mercury.protocol.connection -import io.circe.{Decoder, Encoder} -import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} -import io.circe.syntax.* -import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, Message, PIURI} +import org.hyperledger.identus.mercury.model.{DidId, Message, PIURI} import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} +import zio.json.ast.Json object ConnectionRequest { def `type`: PIURI = "https://atalaprism.io/mercury/connections/1.0/request" @@ -16,12 +15,12 @@ object ConnectionRequest { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen[Body] + given JsonDecoder[Body] = DeriveJsonDecoder.gen[Body] } - given Encoder[ConnectionRequest] = deriveEncoder[ConnectionRequest] - given Decoder[ConnectionRequest] = deriveDecoder[ConnectionRequest] + given JsonEncoder[ConnectionRequest] = DeriveJsonEncoder.gen[ConnectionRequest] + given JsonDecoder[ConnectionRequest] = DeriveJsonDecoder.gen[ConnectionRequest] /** Utility method to start a ConnectionRequest for the scenario where he has an OOB Invitation * @@ -48,10 +47,10 @@ object ConnectionRequest { piuri <- if (message.`type` == ConnectionRequest.`type`) Right(message.`type`) else Left(s"Message MUST be of the type '${ConnectionRequest.`type`}' instead of '${message.`type`}'") - body <- message.body.asJson + body <- message.body .as[ConnectionRequest.Body] .left - .map(ex => "Fail to parse the body of the ConnectionRequest because: " + ex.message) + .map(err => "Fail to parse the body of the ConnectionRequest because: " + err) ret <- message.to match case Seq(onlyOneRecipient) => message.from match @@ -91,6 +90,6 @@ final case class ConnectionRequest( to = Seq(this.to), thid = this.thid, pthid = this.pthid, - body = this.body.asJson.asObject.get, + body = this.body.toJsonAST.toOption.flatMap(_.asObject).getOrElse(Json.Obj()), ) } diff --git a/mercury/protocol-connection/src/main/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionResponse.scala b/mercury/protocol-connection/src/main/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionResponse.scala index 47bfc906b8..f92d662ceb 100644 --- a/mercury/protocol-connection/src/main/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionResponse.scala +++ b/mercury/protocol-connection/src/main/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionResponse.scala @@ -1,9 +1,8 @@ package org.hyperledger.identus.mercury.protocol.connection -import io.circe.{Decoder, Encoder} -import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{DidId, Message, PIURI} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} +import zio.json.ast.Json object ConnectionResponse { def `type`: PIURI = "https://atalaprism.io/mercury/connections/1.0/response" @@ -15,8 +14,8 @@ object ConnectionResponse { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def makeResponseFromRequest(msg: Message): Either[String, ConnectionResponse] = @@ -44,10 +43,10 @@ object ConnectionResponse { piuri <- if (message.`type` == ConnectionResponse.`type`) Right(message.`type`) else Left(s"Message MUST be of the type '${ConnectionResponse.`type`}' instead of '${message.`type`}'") - body <- message.body.asJson + body <- message.body .as[ConnectionResponse.Body] .left - .map(ex => "Fail to parse the body of the ConnectionResponse because: " + ex.message) + .map(err => "Fail to parse the body of the ConnectionResponse because: " + err) ret <- message.to match case Seq(inviter) => // is from only one inviter message.from match @@ -67,8 +66,8 @@ object ConnectionResponse { case _ => Left("The inviter (recipient) is ambiguous. Message need to have only 1 recipient") } yield ret - given Encoder[ConnectionResponse] = deriveEncoder[ConnectionResponse] - given Decoder[ConnectionResponse] = deriveDecoder[ConnectionResponse] + given JsonEncoder[ConnectionResponse] = DeriveJsonEncoder.gen + given JsonDecoder[ConnectionResponse] = DeriveJsonDecoder.gen } final case class ConnectionResponse( @@ -89,6 +88,6 @@ final case class ConnectionResponse( to = Seq(this.to), thid = this.thid, pthid = this.pthid, - body = this.body.asJson.asObject.get, + body = this.body.toJsonAST.toOption.flatMap(_.asObject).getOrElse(Json.Obj()), ) } diff --git a/mercury/protocol-connection/src/test/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionSpec.scala b/mercury/protocol-connection/src/test/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionSpec.scala index d1b1b0a5e1..ba5db11099 100644 --- a/mercury/protocol-connection/src/test/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionSpec.scala +++ b/mercury/protocol-connection/src/test/scala/org/hyperledger/identus/mercury/protocol/connection/ConnectionSpec.scala @@ -1,9 +1,8 @@ package org.hyperledger.identus.mercury.protocol.connection -import io.circe.* -import io.circe.parser.* import munit.* import org.hyperledger.identus.mercury.model.{DidId, Message} +import zio.json.DecoderOps /** protocolConnection/testOnly org.hyperledger.identus.mercury.protocol.connection.CoordinateMediationSpec */ class CoordinateMediationSpec extends ZSuite { @@ -19,10 +18,10 @@ class CoordinateMediationSpec extends ZSuite { | "from" : "did:test:alice", | "to" : ["did:test:bob"] |}""".stripMargin - val aux = parse(connectionRequest) - .flatMap(_.as[Message]) // Message + val aux = connectionRequest + .fromJson[Message] .left - .map(ex => fail(ex.getMessage())) // fail / get error + .map(err => fail(err)) // fail / get error .flatMap(e => ConnectionRequest.fromMessage(e)) assertEquals( aux, @@ -73,7 +72,7 @@ class CoordinateMediationSpec extends ZSuite { |}""".stripMargin assertEquals( - parse(connectionRequest).flatMap(_.as[ConnectionResponse]), + connectionRequest.fromJson[ConnectionResponse], Right(obj) ) } From 704cdfbdbd131dfe6a16d3fbc4a77b411331fc4b Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 14:25:20 +0100 Subject: [PATCH 03/22] feat: migrate protocol-invitation Signed-off-by: Benjamin Voiturier --- .../protocol/invitation/OutOfBand.scala | 9 ++-- .../protocol/invitation/ServiceType.scala | 27 +++++------- .../protocol/invitation/v1/Invitation.scala | 43 +++++++++++-------- .../protocol/invitation/v2/Invitation.scala | 17 ++++---- .../invitation/v1/InvitationV1Spec.scala | 13 +++--- .../invitation/v2/OutOfBandSpec.scala | 1 - 6 files changed, 53 insertions(+), 57 deletions(-) diff --git a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/OutOfBand.scala b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/OutOfBand.scala index 2df0414da2..10a9b2e04a 100644 --- a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/OutOfBand.scala +++ b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/OutOfBand.scala @@ -1,8 +1,7 @@ package org.hyperledger.identus.mercury.protocol.invitation -import io.circe.* -import io.circe.parser.* import org.hyperledger.identus.mercury.protocol.invitation.v2.* +import zio.json.DecoderOps import java.net.{URI, URL} import java.util as ju @@ -18,10 +17,10 @@ object OutOfBand { String(decoder.decode(e)) } - def parseInvitation(url: String): Either[io.circe.Error | RuntimeException, Invitation] = + def parseInvitation(url: String): Either[String | RuntimeException, Invitation] = parseLink(url) match { - case Some(e) => parse(e).flatMap(_.as[Invitation]) - case None => Left(new RuntimeException("Expeting a url!")) + case Some(e) => e.fromJson[Invitation] + case None => Left(new RuntimeException("Expecting a url!")) } } diff --git a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/ServiceType.scala b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/ServiceType.scala index 9b6fba8406..008227c0a5 100644 --- a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/ServiceType.scala +++ b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/ServiceType.scala @@ -1,23 +1,16 @@ package org.hyperledger.identus.mercury.protocol.invitation -import cats.implicits.* -import io.circe.{Decoder, Encoder} -import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} -import io.circe.syntax.* +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} +import zio.json.internal.Write sealed trait ServiceType object ServiceType { - - given Encoder[ServiceType] = (a: ServiceType) => { + given JsonEncoder[ServiceType] = (a: ServiceType, indent: Option[Int], out: Write) => { a match - case data @ Did(_) => data.did.asJson - case data @ Service(_, _, _, _, _) => data.asJson + case data @ Did(did) => JsonEncoder[String].unsafeEncode(did, indent, out) + case data @ Service(_, _, _, _, _) => JsonEncoder[Service].unsafeEncode(data, indent, out) } - - given Decoder[ServiceType] = List[Decoder[ServiceType]]( - Decoder[Did].widen, - Decoder[Service].widen, - ).reduceLeft(_ or _) + given JsonDecoder[ServiceType] = DeriveJsonDecoder.gen } /** Service block @@ -38,13 +31,13 @@ case class Service( ) extends ServiceType object Service { - given Encoder[Service] = deriveEncoder[Service] - given Decoder[Service] = deriveDecoder[Service] + given JsonEncoder[Service] = DeriveJsonEncoder.gen + given JsonDecoder[Service] = DeriveJsonDecoder.gen } case class Did(did: String) extends ServiceType object Did { - given Encoder[Did] = deriveEncoder[Did] - given Decoder[Did] = deriveDecoder[Did] + given JsonEncoder[Did] = DeriveJsonEncoder.gen + given JsonDecoder[Did] = DeriveJsonDecoder.gen } diff --git a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v1/Invitation.scala b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v1/Invitation.scala index 568d60ed1f..61bdf89b18 100644 --- a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v1/Invitation.scala +++ b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v1/Invitation.scala @@ -1,15 +1,14 @@ package org.hyperledger.identus.mercury.protocol.invitation.v1 -import io.circe.{Decoder, Encoder, Json} -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, PIURI} import org.hyperledger.identus.mercury.model.AttachmentDescriptor.attachmentDescriptorEncoderV1 import org.hyperledger.identus.mercury.protocol.invitation.ServiceType +import zio.json.{DeriveJsonDecoder, JsonDecoder, JsonEncoder} +import zio.json.internal.Write /** Out-Of-Band invitation Example + * * @see * https://github.com/hyperledger/aries-rfcs/tree/main/features/0434-outofband - * * @param `id` * @param label * @param goal @@ -32,17 +31,27 @@ final case class Invitation( } object Invitation { - given Encoder[Invitation] = (entity: Invitation) => - Json.obj( - "@id" -> Json.fromString(entity.`@id`), - "@type" -> Json.fromString(entity.`@type`), - "label" -> Json.fromString(entity.label), - "goal" -> Json.fromString(entity.goal), - "goal_code" -> Json.fromString(entity.goal_code), - "accept" -> entity.accept.asJson, - "handshake_protocols" -> entity.handshake_protocols.asJson, - "requests~attach" -> entity.`requests~attach`.asJson, - "services" -> entity.services.asJson - ) - given Decoder[Invitation] = deriveDecoder[Invitation] + given JsonEncoder[Invitation] = (i: Invitation, indent: Option[Int], out: Write) => { + out.write("{") + out.write("\"@id\":") + JsonEncoder[String].unsafeEncode(i.`@id`, indent, out) + out.write(",\"@type\":") + JsonEncoder[String].unsafeEncode(i.`@type`, indent, out) + out.write(",\"label\":") + JsonEncoder[String].unsafeEncode(i.label, indent, out) + out.write(",\"goal\":") + JsonEncoder[String].unsafeEncode(i.goal, indent, out) + out.write(",\"goal_code\":") + JsonEncoder[String].unsafeEncode(i.goal_code, indent, out) + out.write(",\"accept\":") + JsonEncoder[Seq[String]].unsafeEncode(i.accept, indent, out) + out.write(",\"handshake_protocols\":") + JsonEncoder[Seq[String]].unsafeEncode(i.handshake_protocols, indent, out) + out.write(",\"requests~attach\":") + JsonEncoder[Seq[AttachmentDescriptor]].unsafeEncode(i.`requests~attach`, indent, out) + out.write(",\"services\":") + JsonEncoder[Seq[ServiceType]].unsafeEncode(i.services, indent, out) + out.write("}") + } + given JsonDecoder[Invitation] = DeriveJsonDecoder.gen } diff --git a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/Invitation.scala b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/Invitation.scala index c774bd54e4..e44c2b64ab 100644 --- a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/Invitation.scala +++ b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/Invitation.scala @@ -1,11 +1,11 @@ package org.hyperledger.identus.mercury.protocol.invitation.v2 -import io.circe.{Decoder, Encoder} -import io.circe.generic.semiauto.* -import io.circe.syntax.* + import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, PIURI} import org.hyperledger.identus.mercury.model.AttachmentDescriptor.attachmentDescriptorEncoderV2 +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} /** Out-Of-Band invitation + * * @see * https://identity.foundation/didcomm-messaging/spec/#invitation */ @@ -19,7 +19,7 @@ final case class Invitation( expires_time: Option[Long] = None, ) { assert(`type` == "https://didcomm.org/out-of-band/2.0/invitation") - def toBase64: String = java.util.Base64.getUrlEncoder.encodeToString(this.asJson.deepDropNullValues.noSpaces.getBytes) + def toBase64: String = java.util.Base64.getUrlEncoder.encodeToString(this.toJson.getBytes) } object Invitation { @@ -31,13 +31,12 @@ object Invitation { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def `type`: PIURI = "https://didcomm.org/out-of-band/2.0/invitation" - given Encoder[Invitation] = deriveEncoder[Invitation] - given Decoder[Invitation] = deriveDecoder[Invitation] + given JsonEncoder[Invitation] = DeriveJsonEncoder.gen + given JsonDecoder[Invitation] = DeriveJsonDecoder.gen } diff --git a/mercury/protocol-invitation/src/test/scala/org/hyperledger/identus/mercury/protocol/invitation/v1/InvitationV1Spec.scala b/mercury/protocol-invitation/src/test/scala/org/hyperledger/identus/mercury/protocol/invitation/v1/InvitationV1Spec.scala index df35d5f0ae..145ac68667 100644 --- a/mercury/protocol-invitation/src/test/scala/org/hyperledger/identus/mercury/protocol/invitation/v1/InvitationV1Spec.scala +++ b/mercury/protocol-invitation/src/test/scala/org/hyperledger/identus/mercury/protocol/invitation/v1/InvitationV1Spec.scala @@ -1,11 +1,10 @@ package org.hyperledger.identus.mercury.protocol.invitation.v1 -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Json import munit.* import org.hyperledger.identus.mercury.model.AttachmentDescriptor import org.hyperledger.identus.mercury.protocol.invitation.* +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json class InvitationV1Spec extends ZSuite { @@ -13,7 +12,7 @@ class InvitationV1Spec extends ZSuite { val payload = "attachmentData" val payloadBase64 = java.util.Base64.getUrlEncoder.encodeToString(payload.getBytes) - val expectedJson = parse(s"""{ + val expectedJson = s"""{ | "@id": "f3375429-b116-4224-b55f-563d7ef461f1", | "@type": "https://didcomm.org/out-of-band/2.0/invitation", | "label": "Faber College", @@ -34,7 +33,7 @@ class InvitationV1Spec extends ZSuite { | } | ], | "services": ["did:sov:LjgpST2rjsoxYegQDRm7EL"] - |}""".stripMargin).getOrElse(Json.Null) + |}""".stripMargin.fromJson[Json] val did = Did("did:sov:LjgpST2rjsoxYegQDRm7EL") val accepts = Seq("didcomm/aip2;env=rfc587", "didcomm/aip2;env=rfc19") @@ -53,9 +52,7 @@ class InvitationV1Spec extends ZSuite { `requests~attach` = Seq(attachmentDescriptor), services = Seq(did) ) - val result = invitation.asJson.deepDropNullValues - - println(result) + val result = invitation.toJsonAST assertEquals(result, expectedJson) } } diff --git a/mercury/protocol-invitation/src/test/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/OutOfBandSpec.scala b/mercury/protocol-invitation/src/test/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/OutOfBandSpec.scala index 60d0cec95c..3fa664e202 100644 --- a/mercury/protocol-invitation/src/test/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/OutOfBandSpec.scala +++ b/mercury/protocol-invitation/src/test/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/OutOfBandSpec.scala @@ -2,7 +2,6 @@ package org.hyperledger.identus.mercury.protocol.invitation.v2 import munit.* import org.hyperledger.identus.mercury.model.DidId -import org.hyperledger.identus.mercury.protocol.invitation.v2.* import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation.Body import org.hyperledger.identus.mercury.protocol.invitation.OutOfBand class OutOfBandSpec extends FunSuite { From 62484b9d0726054c04cf7f23ee150b8673653231 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 15:10:51 +0100 Subject: [PATCH 04/22] feat: migrate protocol-present-proof Signed-off-by: Benjamin Voiturier --- .../presentproof/PresentFormats.scala | 21 +++++------------- .../protocol/presentproof/Presentation.scala | 22 +++++++++---------- .../protocol/presentproof/ProofType.scala | 7 +++--- .../presentproof/ProposePresentation.scala | 18 +++++++-------- .../presentproof/RequestPresentation.scala | 18 ++++++--------- .../presentproof/PresentationSpec.scala | 13 +++++------ .../ProposePresentationProofSpec.scala | 13 +++++------ .../RequestPresentationSpec.scala | 13 +++++------ 8 files changed, 52 insertions(+), 73 deletions(-) diff --git a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentFormats.scala b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentFormats.scala index c7dda85da6..b17e76932c 100644 --- a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentFormats.scala +++ b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentFormats.scala @@ -1,7 +1,5 @@ package org.hyperledger.identus.mercury.protocol.presentproof -import io.circe.{Decoder, Encoder} -import io.circe.generic.semiauto.* import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} /* @@ -55,8 +53,8 @@ enum PresentCredentialProposeFormat(val name: String) { } object PresentCredentialProposeFormat { - given Encoder[PresentCredentialProposeFormat] = deriveEncoder[PresentCredentialProposeFormat] - given Decoder[PresentCredentialProposeFormat] = deriveDecoder[PresentCredentialProposeFormat] + given JsonEncoder[PresentCredentialProposeFormat] = DeriveJsonEncoder.gen + given JsonDecoder[PresentCredentialProposeFormat] = DeriveJsonDecoder.gen } /** Present Request: @@ -79,15 +77,8 @@ enum PresentCredentialRequestFormat(val name: String) { } object PresentCredentialRequestFormat { - given Encoder[PresentCredentialRequestFormat] = deriveEncoder[PresentCredentialRequestFormat] - given Decoder[PresentCredentialRequestFormat] = deriveDecoder[PresentCredentialRequestFormat] - - given JsonEncoder[PresentCredentialRequestFormat] = - DeriveJsonEncoder.gen[PresentCredentialRequestFormat] - - given JsonDecoder[PresentCredentialRequestFormat] = - DeriveJsonDecoder.gen[PresentCredentialRequestFormat] - + given JsonEncoder[PresentCredentialRequestFormat] = DeriveJsonEncoder.gen + given JsonDecoder[PresentCredentialRequestFormat] = DeriveJsonDecoder.gen } /** Present Credential: @@ -111,6 +102,6 @@ enum PresentCredentialFormat(val name: String) { } object PresentCredentialFormat { - given Encoder[PresentCredentialFormat] = deriveEncoder[PresentCredentialFormat] - given Decoder[PresentCredentialFormat] = deriveDecoder[PresentCredentialFormat] + given JsonEncoder[PresentCredentialFormat] = DeriveJsonEncoder.gen + given JsonDecoder[PresentCredentialFormat] = DeriveJsonDecoder.gen } diff --git a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/Presentation.scala b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/Presentation.scala index 4cfa7db744..5954e4bdaf 100644 --- a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/Presentation.scala +++ b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/Presentation.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.mercury.protocol.presentproof -import io.circe.{Decoder, Encoder} -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, Message, PIURI} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} /** @param attach_id * @param format @@ -16,8 +14,8 @@ import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, Messa final case class PresentationFormat(attach_id: String, format: String) object PresentationFormat { - given Encoder[PresentationFormat] = deriveEncoder[PresentationFormat] - given Decoder[PresentationFormat] = deriveDecoder[PresentationFormat] + given JsonEncoder[PresentationFormat] = DeriveJsonEncoder.gen + given JsonDecoder[PresentationFormat] = DeriveJsonDecoder.gen } /** ALL parameterS are DIDCOMMV2 format and naming conventions and follows the protocol @@ -30,7 +28,7 @@ object PresentationFormat { * @param attachments */ final case class Presentation( - id: String = java.util.UUID.randomUUID.toString(), + id: String = java.util.UUID.randomUUID.toString, `type`: PIURI = Presentation.`type`, body: Presentation.Body, attachments: Seq[AttachmentDescriptor] = Seq.empty[AttachmentDescriptor], @@ -46,7 +44,7 @@ final case class Presentation( from = Some(this.from), to = Seq(this.to), thid = this.thid, - body = this.body.asJson.asObject.get, // TODO get + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, // TODO get attachments = Some(this.attachments) ) } @@ -56,8 +54,8 @@ object Presentation { def `type`: PIURI = "https://didcomm.atalaprism.io/present-proof/3.0/presentation" import AttachmentDescriptor.attachmentDescriptorEncoderV2 - given Encoder[Presentation] = deriveEncoder[Presentation] - given Decoder[Presentation] = deriveDecoder[Presentation] + given JsonEncoder[Presentation] = DeriveJsonEncoder.gen + given JsonDecoder[Presentation] = DeriveJsonDecoder.gen /** @param goal_code * @param comment @@ -69,8 +67,8 @@ object Presentation { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def makePresentationFromRequest(msg: Message): Presentation = { // TODO change msg: Message to RequestCredential @@ -92,7 +90,7 @@ object Presentation { } def readFromMessage(message: Message): Presentation = { - val body = message.body.asJson.as[Presentation.Body].toOption.get // TODO get + val body = message.body.as[Presentation.Body].toOption.get // TODO get Presentation( id = message.id, `type` = message.piuri, diff --git a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProofType.scala b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProofType.scala index 94d342e0bc..b72db01b1d 100644 --- a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProofType.scala +++ b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProofType.scala @@ -1,8 +1,7 @@ package org.hyperledger.identus.mercury.protocol.presentproof -import io.circe.* -import io.circe.generic.semiauto.* import org.hyperledger.identus.mercury.model.DidId +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} case class ProofType( schema: String, // Schema ID EX: https://schema.org/Person @@ -10,6 +9,6 @@ case class ProofType( trustIssuers: Option[Seq[DidId]] // ["did:prism:123321123"] ) object ProofType { - given Encoder[ProofType] = deriveEncoder[ProofType] - given Decoder[ProofType] = deriveDecoder[ProofType] + given JsonEncoder[ProofType] = DeriveJsonEncoder.gen + given JsonDecoder[ProofType] = DeriveJsonDecoder.gen } diff --git a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProposePresentation.scala b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProposePresentation.scala index 2172186118..29294a87b6 100644 --- a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProposePresentation.scala +++ b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProposePresentation.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.mercury.protocol.presentproof -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.* +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} /** ALL parameterS are DIDCOMMV2 format and naming conventions and follows the protocol * @see @@ -15,7 +13,7 @@ import org.hyperledger.identus.mercury.model.* * @param attachments */ final case class ProposePresentation( - id: String = java.util.UUID.randomUUID.toString(), + id: String = java.util.UUID.randomUUID.toString, `type`: PIURI = ProposePresentation.`type`, body: ProposePresentation.Body, attachments: Seq[AttachmentDescriptor] = Seq.empty[AttachmentDescriptor], @@ -31,7 +29,7 @@ final case class ProposePresentation( from = Some(this.from), to = Seq(this.to), thid = this.thid, - body = this.body.asJson.asObject.get, // TODO get + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, // TODO get attachments = Some(this.attachments) ) } @@ -41,8 +39,8 @@ object ProposePresentation { def `type`: PIURI = "https://didcomm.atalaprism.io/present-proof/3.0/propose-presentation" import AttachmentDescriptor.attachmentDescriptorEncoderV2 - given Encoder[ProposePresentation] = deriveEncoder[ProposePresentation] - given Decoder[ProposePresentation] = deriveDecoder[ProposePresentation] + given JsonEncoder[ProposePresentation] = DeriveJsonEncoder.gen + given JsonDecoder[ProposePresentation] = DeriveJsonDecoder.gen /** @param goal_code * @param comment @@ -56,12 +54,12 @@ object ProposePresentation { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def readFromMessage(message: Message): ProposePresentation = { - val body = message.body.asJson.as[ProposePresentation.Body].toOption.get // TODO get + val body = message.body.as[ProposePresentation.Body].toOption.get // TODO get ProposePresentation( id = message.id, diff --git a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/RequestPresentation.scala b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/RequestPresentation.scala index 1548d08800..33b04ca2cc 100644 --- a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/RequestPresentation.scala +++ b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/RequestPresentation.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.mercury.protocol.presentproof -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.* +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} final case class RequestPresentation( id: String = java.util.UUID.randomUUID.toString(), @@ -22,17 +20,15 @@ final case class RequestPresentation( from = this.from, to = this.to.toSeq, thid = this.thid, - body = this.body.asJson.asObject.get, // TODO get + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, // TODO get attachments = Some(this.attachments), ) } object RequestPresentation { import AttachmentDescriptor.attachmentDescriptorEncoderV2 - - given Encoder[RequestPresentation] = deriveEncoder[RequestPresentation] - - given Decoder[RequestPresentation] = deriveDecoder[RequestPresentation] + given JsonEncoder[RequestPresentation] = DeriveJsonEncoder.gen + given JsonDecoder[RequestPresentation] = DeriveJsonDecoder.gen // def `type`: PIURI = "https://didcomm.org/present-proof/3.0/request-presentation" def `type`: PIURI = "https://didcomm.atalaprism.io/present-proof/3.0/request-presentation" @@ -48,8 +44,8 @@ object RequestPresentation { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def makePresentProofRequest(msg: Message): RequestPresentation = { @@ -71,7 +67,7 @@ object RequestPresentation { } def readFromMessage(message: Message): RequestPresentation = - val body = message.body.asJson.as[RequestPresentation.Body].toOption.get // TODO get + val body = message.body.as[RequestPresentation.Body].toOption.get // TODO get RequestPresentation( id = message.id, diff --git a/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentationSpec.scala b/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentationSpec.scala index 284dbeccf9..7786dff1f4 100644 --- a/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentationSpec.scala +++ b/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentationSpec.scala @@ -1,11 +1,10 @@ package org.hyperledger.identus.mercury.protocol.presentproof -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Json import munit.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, LinkData} import org.hyperledger.identus.mercury.model.AttachmentDescriptor.attachmentDescriptorEncoderV2 +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json class PresentationSpec extends ZSuite { @@ -14,16 +13,16 @@ class PresentationSpec extends ZSuite { val body = Presentation.Body(goal_code = Some("Presentation")) val attachmentDescriptor = AttachmentDescriptor("1", Some("application/json"), LinkData(links = Seq("http://test"), hash = "1234")) - val attachmentDescriptorJson = attachmentDescriptor.asJson.deepDropNullValues.noSpaces + val attachmentDescriptorJson = attachmentDescriptor.toJson - val expectedProposalJson = parse(s"""{ + val expectedProposalJson = s"""{ | "id": "061bf917-2cbe-460b-8d12-b1a9609505c2", | "type": "https://didcomm.atalaprism.io/present-proof/3.0/presentation", | "body": {"goal_code": "Presentation"}, | "attachments": [$attachmentDescriptorJson], | "to" : "did:prism:test123", | "from" : "did:prism:test123" - |}""".stripMargin).getOrElse(Json.Null) + |}""".stripMargin.fromJson[Json] val presentation = Presentation( id = "061bf917-2cbe-460b-8d12-b1a9609505c2", @@ -33,7 +32,7 @@ class PresentationSpec extends ZSuite { from = DidId("did:prism:test123") ) - val result = presentation.asJson.deepDropNullValues + val result = presentation.toJsonAST assertEquals(result, expectedProposalJson) } } diff --git a/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProposePresentationProofSpec.scala b/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProposePresentationProofSpec.scala index 6fd9d05eb9..0472be05f8 100644 --- a/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProposePresentationProofSpec.scala +++ b/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/ProposePresentationProofSpec.scala @@ -1,11 +1,10 @@ package org.hyperledger.identus.mercury.protocol.presentproof -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Json import munit.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, LinkData} import org.hyperledger.identus.mercury.model.AttachmentDescriptor.attachmentDescriptorEncoderV2 +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json class ProposePresentationSpec extends ZSuite { @@ -14,9 +13,9 @@ class ProposePresentationSpec extends ZSuite { val body = ProposePresentation.Body(goal_code = Some("Propose Presentation")) val attachmentDescriptor = AttachmentDescriptor("1", Some("application/json"), LinkData(links = Seq("http://test"), hash = "1234")) - val attachmentDescriptorJson = attachmentDescriptor.asJson.deepDropNullValues.noSpaces + val attachmentDescriptorJson = attachmentDescriptor.toJson - val expectedProposalJson = parse(s"""{ + val expectedProposalJson = s"""{ | "id": "061bf917-2cbe-460b-8d12-b1a9609505c2", | "type": "https://didcomm.atalaprism.io/present-proof/3.0/propose-presentation", | "body": { @@ -26,7 +25,7 @@ class ProposePresentationSpec extends ZSuite { | "attachments":[$attachmentDescriptorJson], | "to" : "did:prism:test123", | "from" : "did:prism:test123" - |}""".stripMargin).getOrElse(Json.Null) + |}""".stripMargin.fromJson[Json] val proposePresentation = ProposePresentation( id = "061bf917-2cbe-460b-8d12-b1a9609505c2", @@ -36,7 +35,7 @@ class ProposePresentationSpec extends ZSuite { from = DidId("did:prism:test123"), ) - val result = proposePresentation.asJson.deepDropNullValues + val result = proposePresentation.toJsonAST assertEquals(result, expectedProposalJson) } } diff --git a/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/RequestPresentationSpec.scala b/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/RequestPresentationSpec.scala index a647cd96c4..8e0fc83d30 100644 --- a/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/RequestPresentationSpec.scala +++ b/mercury/protocol-present-proof/src/test/scala/org/hyperledger/identus/mercury/protocol/presentproof/RequestPresentationSpec.scala @@ -1,11 +1,10 @@ package org.hyperledger.identus.mercury.protocol.presentproof -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Json import munit.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, LinkData} import org.hyperledger.identus.mercury.model.AttachmentDescriptor.attachmentDescriptorEncoderV2 +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json class RequestCredentialSpec extends ZSuite { @@ -14,9 +13,9 @@ class RequestCredentialSpec extends ZSuite { val body = RequestPresentation.Body(goal_code = Some("Propose Presentation")) val attachmentDescriptor = AttachmentDescriptor("1", Some("application/json"), LinkData(links = Seq("http://test"), hash = "1234")) - val attachmentDescriptorJson = attachmentDescriptor.asJson.deepDropNullValues.noSpaces + val attachmentDescriptorJson = attachmentDescriptor.toJson - val expectedProposalJson = parse(s"""{ + val expectedProposalJson = s"""{ | "id": "061bf917-2cbe-460b-8d12-b1a9609505c2", | "type": "https://didcomm.atalaprism.io/present-proof/3.0/request-presentation", | "body": @@ -28,7 +27,7 @@ class RequestCredentialSpec extends ZSuite { | "attachments": [$attachmentDescriptorJson], | "from" : "did:prism:test123", | "to" : "did:prism:test123" - |}""".stripMargin).getOrElse(Json.Null) + |}""".stripMargin.fromJson[Json] val requestPresentation = RequestPresentation( id = "061bf917-2cbe-460b-8d12-b1a9609505c2", @@ -38,7 +37,7 @@ class RequestCredentialSpec extends ZSuite { from = Some(DidId("did:prism:test123")), ) - val result = requestPresentation.asJson.deepDropNullValues + val result = requestPresentation.toJsonAST assertEquals(result, expectedProposalJson) } } From aec20407fcad444281832b3d64dc06f5942ede2b Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 15:46:08 +0100 Subject: [PATCH 05/22] feat: migrate protocol-report-problem Signed-off-by: Benjamin Voiturier --- .../reportproblem/v2/ReportProblem.scala | 22 ++++----- .../reportproblem/v2/ReportProblemSpec.scala | 45 +++++++++++-------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/mercury/protocol-report-problem/src/main/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblem.scala b/mercury/protocol-report-problem/src/main/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblem.scala index 22e64637ef..3b9ec654dd 100644 --- a/mercury/protocol-report-problem/src/main/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblem.scala +++ b/mercury/protocol-report-problem/src/main/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblem.scala @@ -1,9 +1,8 @@ package org.hyperledger.identus.mercury.protocol.reportproblem.v2 -import io.circe.* -import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{DidId, Message, PIURI} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} +import zio.json.internal.Write object ReportProblem { /** {{{ @@ -32,8 +31,8 @@ object ReportProblem { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def build( @@ -47,11 +46,11 @@ object ReportProblem { ReportProblem(from = fromDID, to = toDID, pthid = Some(pthid), body = body) } - given Encoder[ReportProblem] = deriveEncoder[ReportProblem] - given Decoder[ReportProblem] = deriveDecoder[ReportProblem] + given JsonEncoder[ReportProblem] = DeriveJsonEncoder.gen + given JsonDecoder[ReportProblem] = DeriveJsonDecoder.gen def fromMessage(message: Message): ReportProblem = - val body = message.body.asJson.as[ReportProblem.Body].toOption.get // TODO get + val body = message.body.as[ReportProblem.Body].toOption.get // TODO get ReportProblem( id = message.id, `type` = message.piuri, @@ -81,8 +80,9 @@ object ProblemCode { assert(true) // TODO regex to check value value } - given Encoder[ProblemCode] = Encoder.encodeString.contramap(identity) - given Decoder[ProblemCode] = Decoder.decodeString.map(ProblemCode(_)) + given JsonEncoder[ProblemCode] = (a: ProblemCode, indent: Option[Int], out: Write) => + JsonEncoder.string.unsafeEncode(a, indent, out) + given JsonDecoder[ProblemCode] = JsonDecoder.string.map(ProblemCode(_)) } @@ -226,7 +226,7 @@ final case class ReportProblem( to = Seq(this.to), thid = this.thid, pthid = this.pthid, - body = this.body.asJson.asObject.get, + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, ack = ack ) } diff --git a/mercury/protocol-report-problem/src/test/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblemSpec.scala b/mercury/protocol-report-problem/src/test/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblemSpec.scala index a2e55809eb..cc9b97505d 100644 --- a/mercury/protocol-report-problem/src/test/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblemSpec.scala +++ b/mercury/protocol-report-problem/src/test/scala/org/hyperledger/identus/mercury/protocol/reportproblem/v2/ReportProblemSpec.scala @@ -1,11 +1,9 @@ package org.hyperledger.identus.mercury.protocol.reportproblem.v2 -import io.circe.* -import io.circe.parser.* -import io.circe.syntax.* import munit.* import org.hyperledger.identus.mercury.model.DidId -import org.hyperledger.identus.mercury.protocol.reportproblem.v2.* +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.{Json, JsonCursor} class ReportProblemSpec extends ZSuite { test("ReportProblem") { @@ -30,7 +28,7 @@ class ReportProblemSpec extends ZSuite { body = body ) - val expectedProposalJson = parse(s"""{ + val expectedProposalJson = s"""{ "from" : "did:prism:test1", "to" : "did:prism:test2", "type": "https://didcomm.org/report-problem/2.0/problem-report", @@ -46,8 +44,8 @@ class ReportProblemSpec extends ZSuite { ], "escalate_to": "mailto:admin@foo.org" } -}""".stripMargin).getOrElse(Json.Null) - val result = reportproblem.asJson.deepDropNullValues +}""".stripMargin.fromJson[Json] + val result = reportproblem.toJsonAST assertEquals(result, expectedProposalJson) } @@ -57,7 +55,7 @@ class ReportProblemSpec extends ZSuite { val fromDid = DidId("did:prism:test1") val toDid = DidId("did:prism:test2") - val reportproblem = ReportProblem.build( + val reportProblem = ReportProblem.build( fromDID = fromDid, toDID = toDid, pthid = "1e513ad4-48c9-444e-9e7e-5b8b45c5e325", @@ -65,21 +63,32 @@ class ReportProblemSpec extends ZSuite { comment = Some("Unable to use the {1} endpoint for {2}.") ) - val result = reportproblem.asJson.deepDropNullValues + val result = reportProblem.toJsonAST - assertEquals(result.hcursor.get[String]("pthid").toOption, Some("1e513ad4-48c9-444e-9e7e-5b8b45c5e325")) - assertEquals(result.hcursor.get[String]("from").toOption, Some("did:prism:test1")) - assertEquals(result.hcursor.get[String]("to").toOption, Some("did:prism:test2")) assertEquals( - result.hcursor.get[String]("type").toOption, - Some("https://didcomm.org/report-problem/2.0/problem-report") + result.flatMap(_.get(JsonCursor.field("pthid").isString)).map(_.value), + Right("1e513ad4-48c9-444e-9e7e-5b8b45c5e325") ) - assertEquals(result.hcursor.downField("body").get[String]("code").toOption, Some("e.p.xfer.cant-use-endpoint")) assertEquals( - result.hcursor.downField("body").get[String]("comment").toOption, - Some("Unable to use the {1} endpoint for {2}.") + result.flatMap(_.get(JsonCursor.field("from").isString)).map(_.value), + Right("did:prism:test1") + ) + assertEquals( + result.flatMap(_.get(JsonCursor.field("to").isString)).map(_.value), + Right("did:prism:test2") + ) + assertEquals( + result.flatMap(_.get(JsonCursor.field("type").isString)).map(_.value), + Right("https://didcomm.org/report-problem/2.0/problem-report") + ) + assertEquals( + result.flatMap(_.get(JsonCursor.field("body").isObject >>> JsonCursor.field("code").isString)).map(_.value), + Right("e.p.xfer.cant-use-endpoint") + ) + assertEquals( + result.flatMap(_.get(JsonCursor.field("body").isObject >>> JsonCursor.field("comment").isString)).map(_.value), + Right("Unable to use the {1} endpoint for {2}.") ) - } } From b8b98793fa7f625a99c80a2f9b4c907b806c40ea Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 15:48:45 +0100 Subject: [PATCH 06/22] feat: migrate protocol-routing Signed-off-by: Benjamin Voiturier --- .../identus/mercury/protocol/routing/ForwardMessage.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mercury/protocol-routing/src/main/scala/org/hyperledger/identus/mercury/protocol/routing/ForwardMessage.scala b/mercury/protocol-routing/src/main/scala/org/hyperledger/identus/mercury/protocol/routing/ForwardMessage.scala index 3744a4c984..8c410f4886 100644 --- a/mercury/protocol-routing/src/main/scala/org/hyperledger/identus/mercury/protocol/routing/ForwardMessage.scala +++ b/mercury/protocol-routing/src/main/scala/org/hyperledger/identus/mercury/protocol/routing/ForwardMessage.scala @@ -1,7 +1,7 @@ package org.hyperledger.identus.mercury.protocol.routing -import io.circe.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, Message, PIURI} +import zio.json.ast.Json type ForwardAttachment = AttachmentDescriptor @@ -38,7 +38,7 @@ final case class ForwardMessage( Message( from = None, to = Seq(to), - body = JsonObject(("next", Json.fromString(body.next.value))), + body = Json.Obj("next" -> Json.Str(body.next.value)), id = id, `type` = `type`, attachments = Some(attachments) From 95cc961b3daf4b8d4f68f2540ce8b9b8919495cc Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 15:51:41 +0100 Subject: [PATCH 07/22] feat: migrate protocol-revocation-notification Signed-off-by: Benjamin Voiturier --- .../RevocationNotification.scala | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/mercury/protocol-revocation-notification/src/main/scala/org/hyperledger/identus/mercury/protocol/revocationnotificaiton/RevocationNotification.scala b/mercury/protocol-revocation-notification/src/main/scala/org/hyperledger/identus/mercury/protocol/revocationnotificaiton/RevocationNotification.scala index be73af85c4..72c134847f 100644 --- a/mercury/protocol-revocation-notification/src/main/scala/org/hyperledger/identus/mercury/protocol/revocationnotificaiton/RevocationNotification.scala +++ b/mercury/protocol-revocation-notification/src/main/scala/org/hyperledger/identus/mercury/protocol/revocationnotificaiton/RevocationNotification.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.mercury.protocol.revocationnotificaiton -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{DidId, Message, PIURI} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} final case class RevocationNotification( id: String = java.util.UUID.randomUUID.toString(), @@ -21,13 +19,13 @@ final case class RevocationNotification( from = Some(this.from), to = Seq(this.to), thid = this.thid, - body = this.body.asJson.asObject.get, + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, ) } object RevocationNotification { - given Encoder[RevocationNotification] = deriveEncoder[RevocationNotification] - given Decoder[RevocationNotification] = deriveDecoder[RevocationNotification] + given JsonEncoder[RevocationNotification] = DeriveJsonEncoder.gen + given JsonDecoder[RevocationNotification] = DeriveJsonDecoder.gen def `type`: PIURI = "https://atalaprism.io/revocation_notification/1.0/revoke" @@ -54,13 +52,13 @@ object RevocationNotification { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def readFromMessage(message: Message): Either[String, RevocationNotification] = - message.body.asJson.as[RevocationNotification.Body] match - case Left(fail) => Left("Fail to parse RevocationNotification's body: " + fail.getMessage) + message.body.as[RevocationNotification.Body] match + case Left(err) => Left("Fail to parse RevocationNotification's body: " + err) case Right(body) => message.from match case None => Left("OfferCredential MUST have the sender explicit") From e22cd9974bf697efff0768784bab452b7f0d4507 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 16:06:26 +0100 Subject: [PATCH 08/22] feat: migrate protocol-trust-ping Signed-off-by: Benjamin Voiturier --- .../mercury/protocol/trustping/TrustPing.scala | 18 ++++++++---------- .../protocol/trustping/TrustPingResponse.scala | 1 - 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/mercury/protocol-trust-ping/src/main/scala/org/hyperledger/identus/mercury/protocol/trustping/TrustPing.scala b/mercury/protocol-trust-ping/src/main/scala/org/hyperledger/identus/mercury/protocol/trustping/TrustPing.scala index 39733f6298..95536a41a9 100644 --- a/mercury/protocol-trust-ping/src/main/scala/org/hyperledger/identus/mercury/protocol/trustping/TrustPing.scala +++ b/mercury/protocol-trust-ping/src/main/scala/org/hyperledger/identus/mercury/protocol/trustping/TrustPing.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.mercury.protocol.trustping -import io.circe.* -import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{DidId, Message, PIURI} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} /** https://identity.foundation/didcomm-messaging/spec/#trust-ping-protocol-20 */ final case class TrustPing( @@ -20,7 +18,7 @@ final case class TrustPing( `type` = this.`type`, from = Some(this.from), to = Seq(this.to), - body = this.body.asJson.asObject.get, + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, ) def makeReply = TrustPingResponse( @@ -36,11 +34,11 @@ object TrustPing { response_requested: Option[Boolean] = Some(true), ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } - given Encoder[TrustPing] = deriveEncoder[TrustPing] - given Decoder[TrustPing] = deriveDecoder[TrustPing] + given JsonEncoder[TrustPing] = DeriveJsonEncoder.gen + given JsonDecoder[TrustPing] = DeriveJsonDecoder.gen /** Parse a generecy DIDComm Message into a TrustPing */ def fromMessage(message: Message): Either[String, TrustPing] = @@ -48,10 +46,10 @@ object TrustPing { piuri <- if (message.`type` == TrustPing.`type`) Right(message.`type`) else Left(s"Message MUST be of the type '${TrustPing.`type`}' instead of '${message.`type`}'") - body <- message.body.asJson + body <- message.body .as[TrustPing.Body] .left - .map(ex => "Fail to parse the body of the TrustPing because: " + ex.message) + .map(err => "Fail to parse the body of the TrustPing because: " + err) ret <- message.to match case Seq(onlyOneRecipient) => message.from match diff --git a/mercury/protocol-trust-ping/src/main/scala/org/hyperledger/identus/mercury/protocol/trustping/TrustPingResponse.scala b/mercury/protocol-trust-ping/src/main/scala/org/hyperledger/identus/mercury/protocol/trustping/TrustPingResponse.scala index bd68d61ba9..a867ef427b 100644 --- a/mercury/protocol-trust-ping/src/main/scala/org/hyperledger/identus/mercury/protocol/trustping/TrustPingResponse.scala +++ b/mercury/protocol-trust-ping/src/main/scala/org/hyperledger/identus/mercury/protocol/trustping/TrustPingResponse.scala @@ -1,6 +1,5 @@ package org.hyperledger.identus.mercury.protocol.trustping -import io.circe.* import org.hyperledger.identus.mercury.model.{DidId, Message, PIURI} final case class TrustPingResponse( From f5cfd97406cb8911b9e955dbe97fa7139af728a0 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 16:41:37 +0100 Subject: [PATCH 09/22] feat: migrate protocol-issue-credential Signed-off-by: Benjamin Voiturier --- .../issuecredential/CredentialPreview.scala | 15 +++++----- .../issuecredential/IssueCredential.scala | 18 ++++++------ .../issuecredential/IssueFormats.scala | 19 ++++++------- .../issuecredential/OfferCredential.scala | 22 ++++++--------- .../issuecredential/ProposeCredential.scala | 18 ++++++------ .../issuecredential/RequestCredential.scala | 18 ++++++------ .../protocol/issuecredential/Utils.scala | 11 ++++---- .../UtilsCredentialSpec.scala | 28 ++++++------------- .../issuecredential/IssueCredentialSpec.scala | 18 ++++-------- .../issuecredential/OfferCredentialSpec.scala | 13 ++++----- .../ProposeCredentialSpec.scala | 14 ++++------ .../RequestCredentialSpec.scala | 13 ++++----- 12 files changed, 86 insertions(+), 121 deletions(-) diff --git a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/CredentialPreview.scala b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/CredentialPreview.scala index 4351ca6367..6115b03d15 100644 --- a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/CredentialPreview.scala +++ b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/CredentialPreview.scala @@ -1,7 +1,6 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.{Decoder, Encoder} -import io.circe.generic.semiauto.* +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} /** @see * https://github.com/decentralized-identity/waci-didcomm/blob/main/issue_credential/README.md#preview-credential @@ -42,15 +41,15 @@ object CredentialPreview { body = CredentialPreviewBody(attributes) ) - given Encoder[CredentialPreview] = deriveEncoder[CredentialPreview] - given Decoder[CredentialPreview] = deriveDecoder[CredentialPreview] + given JsonEncoder[CredentialPreview] = DeriveJsonEncoder.gen + given JsonDecoder[CredentialPreview] = DeriveJsonDecoder.gen } case class CredentialPreviewBody(attributes: Seq[Attribute]) object CredentialPreviewBody { - given Encoder[CredentialPreviewBody] = deriveEncoder[CredentialPreviewBody] - given Decoder[CredentialPreviewBody] = deriveDecoder[CredentialPreviewBody] + given JsonEncoder[CredentialPreviewBody] = DeriveJsonEncoder.gen + given JsonDecoder[CredentialPreviewBody] = DeriveJsonDecoder.gen } /** @param name @@ -71,6 +70,6 @@ final case class Attribute( media_type: Option[String] = None, ) object Attribute { - given Encoder[Attribute] = deriveEncoder[Attribute] - given Decoder[Attribute] = deriveDecoder[Attribute] + given JsonEncoder[Attribute] = DeriveJsonEncoder.gen + given JsonDecoder[Attribute] = DeriveJsonDecoder.gen } diff --git a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueCredential.scala b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueCredential.scala index 25b97a9772..958f0540e8 100644 --- a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueCredential.scala +++ b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueCredential.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, Message, PIURI} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} /** ALL parameterS are DIDCOMMV2 format and naming conventions and follows the protocol * @see @@ -32,7 +30,7 @@ final case class IssueCredential( from = Some(this.from), to = Seq(this.to), thid = this.thid, - body = this.body.asJson.asObject.get, + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, attachments = Some(this.attachments), ) } @@ -40,8 +38,8 @@ final case class IssueCredential( object IssueCredential { import AttachmentDescriptor.attachmentDescriptorEncoderV2 - given Encoder[IssueCredential] = deriveEncoder[IssueCredential] - given Decoder[IssueCredential] = deriveDecoder[IssueCredential] + given JsonEncoder[IssueCredential] = DeriveJsonEncoder.gen + given JsonDecoder[IssueCredential] = DeriveJsonDecoder.gen def `type`: PIURI = "https://didcomm.org/issue-credential/3.0/issue-credential" @@ -69,8 +67,8 @@ object IssueCredential { more_available: Option[String] = None, ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def makeIssueCredentialFromRequestCredential(msg: Message): Either[String, IssueCredential] = @@ -90,8 +88,8 @@ object IssueCredential { } def readFromMessage(message: Message): Either[String, IssueCredential] = { - message.body.asJson.as[IssueCredential.Body] match - case Left(fail) => Left("Fail to parse IssueCredential's body: " + fail.getMessage) + message.body.as[IssueCredential.Body] match + case Left(err) => Left("Fail to parse IssueCredential's body: " + err) case Right(body) => message.from match case None => Left("IssueCredential MUST have the sender explicit") diff --git a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueFormats.scala b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueFormats.scala index 933a440bbe..b25a27c9e4 100644 --- a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueFormats.scala +++ b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueFormats.scala @@ -1,7 +1,6 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.{Decoder, Encoder} -import io.circe.generic.semiauto.* +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} /* Issue Credential Formats: @@ -74,8 +73,8 @@ enum IssueCredentialProposeFormat(val name: String) { } object IssueCredentialProposeFormat { - given Encoder[IssueCredentialProposeFormat] = deriveEncoder[IssueCredentialProposeFormat] - given Decoder[IssueCredentialProposeFormat] = deriveDecoder[IssueCredentialProposeFormat] + given JsonEncoder[IssueCredentialProposeFormat] = DeriveJsonEncoder.gen + given JsonDecoder[IssueCredentialProposeFormat] = DeriveJsonDecoder.gen } /** Issue Offer: @@ -102,8 +101,8 @@ enum IssueCredentialOfferFormat(val name: String) { } object IssueCredentialOfferFormat { - given Encoder[IssueCredentialOfferFormat] = deriveEncoder[IssueCredentialOfferFormat] - given Decoder[IssueCredentialOfferFormat] = deriveDecoder[IssueCredentialOfferFormat] + given JsonEncoder[IssueCredentialOfferFormat] = DeriveJsonEncoder.gen + given JsonDecoder[IssueCredentialOfferFormat] = DeriveJsonDecoder.gen } /** Issue Request: @@ -130,8 +129,8 @@ enum IssueCredentialRequestFormat(val name: String) { } object IssueCredentialRequestFormat { - given Encoder[IssueCredentialRequestFormat] = deriveEncoder[IssueCredentialRequestFormat] - given Decoder[IssueCredentialRequestFormat] = deriveDecoder[IssueCredentialRequestFormat] + given JsonEncoder[IssueCredentialRequestFormat] = DeriveJsonEncoder.gen + given JsonDecoder[IssueCredentialRequestFormat] = DeriveJsonDecoder.gen } /** Issue Credential: @@ -156,6 +155,6 @@ enum IssueCredentialIssuedFormat(val name: String) { } object IssueCredentialIssuedFormat { - given Encoder[IssueCredentialIssuedFormat] = deriveEncoder[IssueCredentialIssuedFormat] - given Decoder[IssueCredentialIssuedFormat] = deriveDecoder[IssueCredentialIssuedFormat] + given JsonEncoder[IssueCredentialIssuedFormat] = DeriveJsonEncoder.gen + given JsonDecoder[IssueCredentialIssuedFormat] = DeriveJsonDecoder.gen } diff --git a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/OfferCredential.scala b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/OfferCredential.scala index 5977283e25..1e2f1d84ef 100644 --- a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/OfferCredential.scala +++ b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/OfferCredential.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, Message, PIURI} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} /** ALL parameterS are DIDCOMMV2 format and naming conventions and follows the protocol * @see @@ -17,7 +15,7 @@ import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, Messa * needs to be used need replying */ final case class OfferCredential( - id: String = java.util.UUID.randomUUID.toString(), + id: String = java.util.UUID.randomUUID.toString, `type`: PIURI = OfferCredential.`type`, body: OfferCredential.Body, attachments: Seq[AttachmentDescriptor], @@ -34,7 +32,7 @@ final case class OfferCredential( from = Some(this.from), to = to.toSeq, thid = this.thid, - body = this.body.asJson.asObject.get, // TODO get + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, // TODO get attachments = Some(this.attachments), ) } @@ -42,10 +40,8 @@ final case class OfferCredential( object OfferCredential { import AttachmentDescriptor.attachmentDescriptorEncoderV2 - - given Encoder[OfferCredential] = deriveEncoder[OfferCredential] - - given Decoder[OfferCredential] = deriveDecoder[OfferCredential] + given JsonEncoder[OfferCredential] = DeriveJsonEncoder.gen + given JsonDecoder[OfferCredential] = DeriveJsonDecoder.gen def `type`: PIURI = "https://didcomm.org/issue-credential/3.0/offer-credential" @@ -77,8 +73,8 @@ object OfferCredential { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def makeOfferToProposeCredential( @@ -106,8 +102,8 @@ object OfferCredential { } def readFromMessage(message: Message): Either[String, OfferCredential] = { - message.body.asJson.as[OfferCredential.Body] match - case Left(fail) => Left("Fail to parse OfferCredential's body: " + fail.getMessage) + message.body.as[OfferCredential.Body] match + case Left(err) => Left("Fail to parse OfferCredential's body: " + err) case Right(body) => message.from match case None => Left("OfferCredential MUST have the sender explicit") diff --git a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/ProposeCredential.scala b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/ProposeCredential.scala index 10bdd4c023..5ae101e0c4 100644 --- a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/ProposeCredential.scala +++ b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/ProposeCredential.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, Message, PIURI} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} /** ALL parameterS are DIDCOMMV2 format and naming conventions and follows the protocol * @see @@ -30,7 +28,7 @@ final case class ProposeCredential( `type` = this.`type`, from = Some(this.from), to = Seq(this.to), - body = this.body.asJson.asObject.get, // TODO get + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, // TODO get attachments = Some(this.attachments) ) } @@ -60,8 +58,8 @@ object ProposeCredential { } import AttachmentDescriptor.attachmentDescriptorEncoderV2 - given Encoder[ProposeCredential] = deriveEncoder[ProposeCredential] - given Decoder[ProposeCredential] = deriveDecoder[ProposeCredential] + given JsonEncoder[ProposeCredential] = DeriveJsonEncoder.gen + given JsonDecoder[ProposeCredential] = DeriveJsonDecoder.gen /** @param goal_code * @param comment @@ -75,13 +73,13 @@ object ProposeCredential { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def readFromMessage(message: Message): Either[String, ProposeCredential] = { - message.body.asJson.as[ProposeCredential.Body] match - case Left(fail) => Left("Fail to parse ProposeCredential's body: " + fail.getMessage) + message.body.as[ProposeCredential.Body] match + case Left(err) => Left("Fail to parse ProposeCredential's body: " + err) case Right(body) => message.from match case None => Left("ProposeCredential MUST have the sender explicit") diff --git a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/RequestCredential.scala b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/RequestCredential.scala index 5d78de761a..c8a8420fd0 100644 --- a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/RequestCredential.scala +++ b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/RequestCredential.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId, Message, PIURI} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} final case class RequestCredential( id: String = java.util.UUID.randomUUID.toString(), @@ -22,15 +20,15 @@ final case class RequestCredential( from = Some(this.from), to = Seq(this.to), thid = this.thid, - body = this.body.asJson.asObject.get, // TODO get + body = this.body.toJsonAST.toOption.flatMap(_.asObject).get, // TODO get attachments = Some(this.attachments), ) } object RequestCredential { import AttachmentDescriptor.attachmentDescriptorEncoderV2 - given Encoder[RequestCredential] = deriveEncoder[RequestCredential] - given Decoder[RequestCredential] = deriveDecoder[RequestCredential] + given JsonEncoder[RequestCredential] = DeriveJsonEncoder.gen + given JsonDecoder[RequestCredential] = DeriveJsonDecoder.gen def `type`: PIURI = "https://didcomm.org/issue-credential/3.0/request-credential" @@ -58,8 +56,8 @@ object RequestCredential { ) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } def makeRequestCredentialFromOffer(oc: OfferCredential): RequestCredential = @@ -72,8 +70,8 @@ object RequestCredential { ) def readFromMessage(message: Message): Either[String, RequestCredential] = { - message.body.asJson.as[RequestCredential.Body] match - case Left(fail) => Left("Fail to parse RequestCredential's body: " + fail.getMessage) + message.body.as[RequestCredential.Body] match + case Left(err) => Left("Fail to parse RequestCredential's body: " + err) case Right(body) => message.from match case None => Left("RequestCredential MUST have the sender explicit") diff --git a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/Utils.scala b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/Utils.scala index 9d3fbb91e1..8377f52138 100644 --- a/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/Utils.scala +++ b/mercury/protocol-issue-credential/src/main/scala/org/hyperledger/identus/mercury/protocol/issuecredential/Utils.scala @@ -1,9 +1,8 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Decoder import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, Base64, JsonData, JwsData, LinkData} +import zio.json.{DecoderOps, JsonDecoder} +import zio.json.EncoderOps private trait ReadAttachmentsUtils { @@ -24,7 +23,7 @@ private trait ReadAttachmentsUtils { formatName, java.util.Base64 .getUrlEncoder() - .encode(obj.json.asJson.noSpaces.getBytes()) + .encode(obj.json.toJson.getBytes()) ) } } @@ -33,12 +32,12 @@ private trait ReadAttachmentsUtils { /** @return * credential data (of a certain format type) in an array of Bytes encoded in base 64 */ - def getCredential[A](credentialFormatName: String)(using decodeA: Decoder[A]): Seq[A] = + def getCredential[A](credentialFormatName: String)(using decoder: JsonDecoder[A]): Seq[A] = getCredentialFormatAndCredential .filter(_._2 == credentialFormatName) .map(e => java.util.Base64.getUrlDecoder().decode(e._3)) .map(String(_)) - .map(e => decode[A](e)) + .map(e => e.fromJson[A]) .flatMap(_.toOption) } diff --git a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/anotherclasspath/UtilsCredentialSpec.scala b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/anotherclasspath/UtilsCredentialSpec.scala index cad5aa83ff..2cae3e032a 100644 --- a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/anotherclasspath/UtilsCredentialSpec.scala +++ b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/anotherclasspath/UtilsCredentialSpec.scala @@ -1,26 +1,14 @@ package org.hyperledger.identus.mercury.protocol.anotherclasspath -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import munit.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId} -import org.hyperledger.identus.mercury.protocol.issuecredential.{ - CredentialPreview, - IssueCredential, - IssueCredentialIssuedFormat, - IssueCredentialOfferFormat, - IssueCredentialProposeFormat, - IssueCredentialRequestFormat, - OfferCredential, - ProposeCredential, - RequestCredential -} +import org.hyperledger.identus.mercury.protocol.issuecredential.{CredentialPreview, IssueCredential, IssueCredentialIssuedFormat, IssueCredentialOfferFormat, IssueCredentialProposeFormat, IssueCredentialRequestFormat, OfferCredential, ProposeCredential, RequestCredential} +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} private case class TestCredentialType(a: String, b: Int, x: Long, name: String, dob: String) private object TestCredentialType { - given Encoder[TestCredentialType] = deriveEncoder[TestCredentialType] - given Decoder[TestCredentialType] = deriveDecoder[TestCredentialType] + given JsonEncoder[TestCredentialType] = DeriveJsonEncoder.gen + given JsonDecoder[TestCredentialType] = DeriveJsonDecoder.gen } /** testOnly org.hyperledger.identus.mercury.protocol.anotherclasspath.UtilsCredentialSpec @@ -50,7 +38,7 @@ class UtilsCredentialSpec extends ZSuite { fromDID = DidId("did:prism:test123from"), toDID = DidId("did:prism:test123to"), credentials = - Seq(IssueCredentialIssuedFormat.Unsupported(nameCredentialType) -> credential.asJson.noSpaces.getBytes()), + Seq(IssueCredentialIssuedFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), ) .makeMessage @@ -74,7 +62,7 @@ class UtilsCredentialSpec extends ZSuite { toDID = DidId("did:prism:test123to"), credential_preview = credentialPreview, credentials = - Seq(IssueCredentialOfferFormat.Unsupported(nameCredentialType) -> credential.asJson.noSpaces.getBytes()), + Seq(IssueCredentialOfferFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), ) .makeMessage @@ -98,7 +86,7 @@ class UtilsCredentialSpec extends ZSuite { toDID = DidId("did:prism:test123to"), credential_preview = Some(credentialPreview), credentials = - Seq(IssueCredentialProposeFormat.Unsupported(nameCredentialType) -> credential.asJson.noSpaces.getBytes()), + Seq(IssueCredentialProposeFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), ) .makeMessage @@ -120,7 +108,7 @@ class UtilsCredentialSpec extends ZSuite { fromDID = DidId("did:prism:test123from"), toDID = DidId("did:prism:test123to"), credentials = - Seq(IssueCredentialRequestFormat.Unsupported(nameCredentialType) -> credential.asJson.noSpaces.getBytes()), + Seq(IssueCredentialRequestFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), ) .makeMessage diff --git a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueCredentialSpec.scala b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueCredentialSpec.scala index 388bcf9894..8230f257ac 100644 --- a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueCredentialSpec.scala +++ b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/IssueCredentialSpec.scala @@ -1,10 +1,9 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Json import munit.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId} +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json class IssueCredentialSpec extends ZSuite { @@ -15,14 +14,10 @@ class IssueCredentialSpec extends ZSuite { val credentialPreview = CredentialPreview(attributes = Seq(attribute1, attribute2)) val body = IssueCredential.Body(goal_code = Some("Issued Credential")) val attachmentDescriptor = AttachmentDescriptor.buildJsonAttachment[CredentialPreview](payload = credentialPreview) - val attachmentDescriptorJson = - attachmentDescriptor - .asJson(AttachmentDescriptor.attachmentDescriptorEncoderV2) - .deepDropNullValues - .noSpaces + val attachmentDescriptorJson = attachmentDescriptor.toJson(AttachmentDescriptor.attachmentDescriptorEncoderV2) // FIXME !!! THIS WILL FAIL! - val expectedProposalJson = parse( + val expectedProposalJson = s"""{ | "id": "061bf917-2cbe-460b-8d12-b1a9609505c2", | "type": "https://didcomm.org/issue-credential/3.0/issue-credential", @@ -32,8 +27,7 @@ class IssueCredentialSpec extends ZSuite { | ], | "to" : "did:prism:test123", | "from" : "did:prism:test123" - |}""".stripMargin - ).getOrElse(Json.Null) + |}""".stripMargin.fromJson[Json] val issueCredential = IssueCredential( id = "061bf917-2cbe-460b-8d12-b1a9609505c2", @@ -43,7 +37,7 @@ class IssueCredentialSpec extends ZSuite { from = DidId("did:prism:test123") ) - val result = issueCredential.asJson.deepDropNullValues + val result = issueCredential.toJsonAST assertEquals(result, expectedProposalJson) } } diff --git a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/OfferCredentialSpec.scala b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/OfferCredentialSpec.scala index d5127b0e17..54848f5f88 100644 --- a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/OfferCredentialSpec.scala +++ b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/OfferCredentialSpec.scala @@ -1,11 +1,10 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Json import munit.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId} import org.hyperledger.identus.mercury.model.AttachmentDescriptor.attachmentDescriptorEncoderV2 +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json class OfferCredentialSpec extends ZSuite { @@ -16,9 +15,9 @@ class OfferCredentialSpec extends ZSuite { val credentialPreview = CredentialPreview(attributes = Seq(attribute1, attribute2)) val body = OfferCredential.Body(goal_code = Some("Offer Credential"), credential_preview = credentialPreview) val attachmentDescriptor = AttachmentDescriptor.buildJsonAttachment[CredentialPreview](payload = credentialPreview) - val attachmentDescriptorJson = attachmentDescriptor.asJson.deepDropNullValues.noSpaces + val attachmentDescriptorJson = attachmentDescriptor.toJson - val expectedOfferCredentialJson = parse(s"""{ + val expectedOfferCredentialJson = s"""{ | "id": "041bf917-2cbe-460b-8d12-b1a9609505c2", | "type": "https://didcomm.org/issue-credential/3.0/offer-credential", | "body": { @@ -38,7 +37,7 @@ class OfferCredentialSpec extends ZSuite { | ], | "to" : "did:prism:test123", | "from" : "did:prism:test123" - |}""".stripMargin).getOrElse(Json.Null) + |}""".stripMargin.fromJson[Json] val offerCredential = OfferCredential( id = "041bf917-2cbe-460b-8d12-b1a9609505c2", @@ -48,7 +47,7 @@ class OfferCredentialSpec extends ZSuite { from = DidId("did:prism:test123") ) - val result = offerCredential.asJson.deepDropNullValues + val result = offerCredential.toJsonAST assertEquals(result, expectedOfferCredentialJson) } diff --git a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/ProposeCredentialSpec.scala b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/ProposeCredentialSpec.scala index f8ca7f006a..490a548d5d 100644 --- a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/ProposeCredentialSpec.scala +++ b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/ProposeCredentialSpec.scala @@ -1,11 +1,10 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Json import munit.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId} import org.hyperledger.identus.mercury.model.AttachmentDescriptor.attachmentDescriptorEncoderV2 +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json class ProposeCredentialSpec extends ZSuite { @@ -17,9 +16,9 @@ class ProposeCredentialSpec extends ZSuite { val body = ProposeCredential.Body(goal_code = Some("Propose Credential"), credential_preview = Some(credentialPreview)) val attachmentDescriptor = AttachmentDescriptor.buildJsonAttachment[CredentialPreview](payload = credentialPreview) - val attachmentDescriptorJson = attachmentDescriptor.asJson.deepDropNullValues.noSpaces + val attachmentDescriptorJson = attachmentDescriptor.toJson - val expectedProposalJson = parse( + val expectedProposalJson = s"""{ | "id": "031bf917-2cbe-460b-8d12-b1a9609505c2", | "type": "https://didcomm.org/issue-credential/3.0/propose-credential", @@ -40,8 +39,7 @@ class ProposeCredentialSpec extends ZSuite { | ], | "to" : "did:prism:test123", | "from" : "did:prism:test123" - |}""".stripMargin - ).getOrElse(Json.Null) + |}""".stripMargin.fromJson[Json] val proposeCredential = ProposeCredential( id = "031bf917-2cbe-460b-8d12-b1a9609505c2", @@ -51,7 +49,7 @@ class ProposeCredentialSpec extends ZSuite { from = DidId("did:prism:test123"), ) - val result = proposeCredential.asJson.deepDropNullValues + val result = proposeCredential.toJsonAST assertEquals(result, expectedProposalJson) } } diff --git a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/RequestCredentialSpec.scala b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/RequestCredentialSpec.scala index e68d20ed0b..430dbf7fcf 100644 --- a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/RequestCredentialSpec.scala +++ b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/issuecredential/RequestCredentialSpec.scala @@ -1,11 +1,10 @@ package org.hyperledger.identus.mercury.protocol.issuecredential -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Json import munit.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId} import org.hyperledger.identus.mercury.model.AttachmentDescriptor.attachmentDescriptorEncoderV2 +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json class RequestCredentialSpec extends ZSuite { test("Holder RequestCredential") { @@ -15,9 +14,9 @@ class RequestCredentialSpec extends ZSuite { val credentialPreview = CredentialPreview(attributes = Seq(attribute1, attribute2)) val body = RequestCredential.Body(goal_code = Some("Request Credential")) val attachmentDescriptor = AttachmentDescriptor.buildJsonAttachment[CredentialPreview](payload = credentialPreview) - val attachmentDescriptorJson = attachmentDescriptor.asJson.deepDropNullValues.noSpaces + val attachmentDescriptorJson = attachmentDescriptor.toJson - val expectedRequestedCredentialJson = parse(s"""{ + val expectedRequestedCredentialJson = s"""{ | "id": "051bf917-2cbe-460b-8d12-b1a9609505c2", | "type": "https://didcomm.org/issue-credential/3.0/request-credential", | "body": @@ -30,7 +29,7 @@ class RequestCredentialSpec extends ZSuite { | ], | "from": "did:prism:test123", | "to" : "did:prism:test123" - |}""".stripMargin).getOrElse(Json.Null) + |}""".stripMargin.fromJson[Json] val requestCredential = RequestCredential( id = "051bf917-2cbe-460b-8d12-b1a9609505c2", @@ -40,7 +39,7 @@ class RequestCredentialSpec extends ZSuite { from = DidId("did:prism:test123") ) - val result = requestCredential.asJson.deepDropNullValues + val result = requestCredential.toJsonAST assertEquals(result, expectedRequestedCredentialJson) } From bce688bebe12bbcb44c2b81aa66ccedf11caa763 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 16:51:18 +0100 Subject: [PATCH 10/22] feat: migrate protocol-coordinate-mediation Signed-off-by: Benjamin Voiturier --- .../CoordinateMediation.scala | 87 +++++++++---------- .../CoordinateMediationSpec.scala | 7 +- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/mercury/protocol-coordinate-mediation/src/main/scala/org/hyperledger/identus/mercury/protocol/coordinatemediation/CoordinateMediation.scala b/mercury/protocol-coordinate-mediation/src/main/scala/org/hyperledger/identus/mercury/protocol/coordinatemediation/CoordinateMediation.scala index 5ccc5713e2..a47812aaf3 100644 --- a/mercury/protocol-coordinate-mediation/src/main/scala/org/hyperledger/identus/mercury/protocol/coordinatemediation/CoordinateMediation.scala +++ b/mercury/protocol-coordinate-mediation/src/main/scala/org/hyperledger/identus/mercury/protocol/coordinatemediation/CoordinateMediation.scala @@ -1,8 +1,7 @@ package org.hyperledger.identus.mercury.protocol.coordinatemediation -import io.circe.* -import io.circe.generic.semiauto.* import org.hyperledger.identus.mercury.model.PIURI +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} final case class MediateRequest( id: String = java.util.UUID.randomUUID.toString(), @@ -10,15 +9,15 @@ final case class MediateRequest( ) { assert(`type` == MediateRequest.`type`) } object MediateRequest { def `type`: PIURI = "https://didcomm.org/coordinate-mediation/2.0/mediate-request" - given Encoder[MediateRequest] = deriveEncoder[MediateRequest] - given Decoder[MediateRequest] = deriveDecoder[MediateRequest] + given JsonEncoder[MediateRequest] = DeriveJsonEncoder.gen + given JsonDecoder[MediateRequest] = DeriveJsonDecoder.gen } final case class MediateDeny(id: String, `type`: PIURI) { assert(`type` == MediateDeny.`type`) } object MediateDeny { def `type`: PIURI = "https://didcomm.org/coordinate-mediation/2.0/mediate-deny" - given Encoder[MediateDeny] = deriveEncoder[MediateDeny] - given Decoder[MediateDeny] = deriveDecoder[MediateDeny] + given JsonEncoder[MediateDeny] = DeriveJsonEncoder.gen + given JsonDecoder[MediateDeny] = DeriveJsonDecoder.gen } final case class MediateGrant(id: String, `type`: PIURI, body: MediateGrant.Body) { @@ -26,8 +25,8 @@ final case class MediateGrant(id: String, `type`: PIURI, body: MediateGrant.Body } object MediateGrant { def `type`: PIURI = "https://didcomm.org/coordinate-mediation/2.0/mediate-grant" - given Encoder[MediateGrant] = deriveEncoder[MediateGrant] - given Decoder[MediateGrant] = deriveDecoder[MediateGrant] + given JsonEncoder[MediateGrant] = DeriveJsonEncoder.gen + given JsonDecoder[MediateGrant] = DeriveJsonDecoder.gen /** @param routing_did * DID of the mediator where forwarded messages should be sent. The recipient may use this DID as an enpoint as @@ -38,8 +37,8 @@ object MediateGrant { final case class Body(routing_did: String) // Seq[String]) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } } @@ -48,16 +47,16 @@ final case class KeylistUpdate(id: String, `type`: PIURI, body: KeylistUpdate.Bo } object KeylistUpdate { def `type`: PIURI = "https://didcomm.org/coordinate-mediation/2.0/keylist-update" - given Encoder[KeylistUpdate] = deriveEncoder[KeylistUpdate] - given Decoder[KeylistUpdate] = deriveDecoder[KeylistUpdate] - given Encoder[Update] = deriveEncoder[Update] - given Decoder[Update] = deriveDecoder[Update] + given JsonEncoder[KeylistUpdate] = DeriveJsonEncoder.gen[KeylistUpdate] + given JsonDecoder[KeylistUpdate] = DeriveJsonDecoder.gen + given JsonEncoder[Update] = DeriveJsonEncoder.gen + given JsonDecoder[Update] = DeriveJsonDecoder.gen final case class Body(updates: Seq[Update]) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } /** @param recipient_did @@ -70,8 +69,8 @@ object KeylistUpdate { case add extends Action case remove extends Action object Action { - given Encoder[Action] = deriveEncoder[Action] - given Decoder[Action] = deriveDecoder[Action] + given JsonEncoder[Action] = DeriveJsonEncoder.gen + given JsonDecoder[Action] = DeriveJsonDecoder.gen } } @@ -80,16 +79,16 @@ final case class KeylistResponse(id: String, `type`: PIURI, body: KeylistRespons } object KeylistResponse { def `type`: PIURI = "https://didcomm.org/coordinate-mediation/2.0/keylist-update-response" - given Encoder[KeylistResponse] = deriveEncoder[KeylistResponse] - given Decoder[KeylistResponse] = deriveDecoder[KeylistResponse] - given Encoder[Update] = deriveEncoder[Update] - given Decoder[Update] = deriveDecoder[Update] + given JsonEncoder[KeylistResponse] = DeriveJsonEncoder.gen + given JsonDecoder[KeylistResponse] = DeriveJsonDecoder.gen + given JsonEncoder[Update] = DeriveJsonEncoder.gen + given JsonDecoder[Update] = DeriveJsonDecoder.gen final case class Body(updated: Seq[Update]) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } /** @param recipient_did @@ -104,8 +103,8 @@ object KeylistResponse { case add extends Action case remove extends Action object Action { - given Encoder[Action] = deriveEncoder[Action] - given Decoder[Action] = deriveDecoder[Action] + given JsonEncoder[Action] = DeriveJsonEncoder.gen + given JsonDecoder[Action] = DeriveJsonDecoder.gen } enum Result: @@ -114,8 +113,8 @@ object KeylistResponse { case no_change extends Result case success extends Result object Result { - given Encoder[Result] = deriveEncoder[Result] - given Decoder[Result] = deriveDecoder[Result] + given JsonEncoder[Result] = DeriveJsonEncoder.gen + given JsonDecoder[Result] = DeriveJsonDecoder.gen } } @@ -124,18 +123,18 @@ final case class KeylistQuery(id: String, `type`: PIURI, body: KeylistQuery.Body } object KeylistQuery { def `type`: PIURI = "https://didcomm.org/coordinate-mediation/2.0/keylist-query" - given Encoder[KeylistQuery] = deriveEncoder[KeylistQuery] - given Decoder[KeylistQuery] = deriveDecoder[KeylistQuery] + given JsonEncoder[KeylistQuery] = DeriveJsonEncoder.gen + given JsonDecoder[KeylistQuery] = DeriveJsonDecoder.gen final case class Body(paginate: Option[Paginate] = None) final case class Paginate(limit: Int, offset: Int) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } object Paginate { - given Encoder[Paginate] = deriveEncoder[Paginate] - given Decoder[Paginate] = deriveDecoder[Paginate] + given JsonEncoder[Paginate] = DeriveJsonEncoder.gen + given JsonDecoder[Paginate] = DeriveJsonDecoder.gen } } @@ -144,25 +143,25 @@ final case class Keylist(id: String, `type`: PIURI, body: Keylist.Body) { } object Keylist { def `type`: PIURI = "https://didcomm.org/coordinate-mediation/2.0/keylist" - given Encoder[Keylist] = deriveEncoder[Keylist] - given Decoder[Keylist] = deriveDecoder[Keylist] - given Encoder[Key] = deriveEncoder[Key] - given Decoder[Key] = deriveDecoder[Key] + given JsonEncoder[Keylist] = DeriveJsonEncoder.gen + given JsonDecoder[Keylist] = DeriveJsonDecoder.gen + given JsonEncoder[Key] = DeriveJsonEncoder.gen + given JsonDecoder[Key] = DeriveJsonDecoder.gen final case class Body(keys: Seq[Key], pagination: Option[Pagination]) final case class Key(recipient_did: String) final case class Pagination(count: Int, offset: Int, remaining: Int) object Body { - given Encoder[Body] = deriveEncoder[Body] - given Decoder[Body] = deriveDecoder[Body] + given JsonEncoder[Body] = DeriveJsonEncoder.gen + given JsonDecoder[Body] = DeriveJsonDecoder.gen } object Key { - given Encoder[Key] = deriveEncoder[Key] - given Decoder[Key] = deriveDecoder[Key] + given JsonEncoder[Key] = DeriveJsonEncoder.gen + given JsonDecoder[Key] = DeriveJsonDecoder.gen } object Pagination { - given Encoder[Pagination] = deriveEncoder[Pagination] - given Decoder[Pagination] = deriveDecoder[Pagination] + given JsonEncoder[Pagination] = DeriveJsonEncoder.gen + given JsonDecoder[Pagination] = DeriveJsonDecoder.gen } } diff --git a/mercury/protocol-coordinate-mediation/src/test/scala/org/hyperledger/identus/mercury/protocol/coordinatemediation/CoordinateMediationSpec.scala b/mercury/protocol-coordinate-mediation/src/test/scala/org/hyperledger/identus/mercury/protocol/coordinatemediation/CoordinateMediationSpec.scala index aea9d232b3..ed3a964e6b 100644 --- a/mercury/protocol-coordinate-mediation/src/test/scala/org/hyperledger/identus/mercury/protocol/coordinatemediation/CoordinateMediationSpec.scala +++ b/mercury/protocol-coordinate-mediation/src/test/scala/org/hyperledger/identus/mercury/protocol/coordinatemediation/CoordinateMediationSpec.scala @@ -1,8 +1,7 @@ package org.hyperledger.identus.mercury.protocol.coordinatemediation -import io.circe.* -import io.circe.parser.* import munit.* +import zio.json.DecoderOps class CoordinateMediationSpec extends ZSuite { val mediateDenyExample = """{ @@ -22,13 +21,13 @@ class CoordinateMediationSpec extends ZSuite { |}""".stripMargin test("parse mediate-grant") { - val aux = parse(mediateGrantExample).flatMap(_.as[MediateGrant]) + val aux = mediateGrantExample.fromJson[MediateGrant] println(aux) assert(aux.isRight) } test("parse mediate-deny") { - val aux = parse(mediateDenyExample).flatMap(_.as[MediateDeny]) + val aux = mediateDenyExample.fromJson[MediateDeny] assert(aux.isRight) } From 23005b2c4bde0a9ed41c6826e0955dbfda6390d7 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Thu, 28 Nov 2024 16:56:10 +0100 Subject: [PATCH 11/22] feat: migrate 'agent' Signed-off-by: Benjamin Voiturier --- .../identus/mercury/CoordinateMediationPrograms.scala | 11 +++++------ .../identus/mercury/InvitationPrograms.scala | 6 +++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/mercury/agent/src/main/scala/org/hyperledger/identus/mercury/CoordinateMediationPrograms.scala b/mercury/agent/src/main/scala/org/hyperledger/identus/mercury/CoordinateMediationPrograms.scala index 800a0a772c..2b92f126b0 100644 --- a/mercury/agent/src/main/scala/org/hyperledger/identus/mercury/CoordinateMediationPrograms.scala +++ b/mercury/agent/src/main/scala/org/hyperledger/identus/mercury/CoordinateMediationPrograms.scala @@ -1,12 +1,11 @@ package org.hyperledger.identus.mercury -import io.circe.* -import io.circe.parser.* -import org.hyperledger.identus.* import org.hyperledger.identus.mercury.model.* import org.hyperledger.identus.mercury.protocol.coordinatemediation.* import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation import zio.* +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json object CoordinateMediationPrograms { @@ -20,8 +19,8 @@ object CoordinateMediationPrograms { ) } - private def toPrettyJson(parseToJson: String): Either[ParsingFailure, String] = { - parse(parseToJson).map(_.spaces2) + private def toPrettyJson(parseToJson: String): Either[String, String] = { + parseToJson.fromJson[Json].map(_.toJsonPretty) } def senderMediationRequestProgram(mediatorURL: String = "http://localhost:8000") = { @@ -57,7 +56,7 @@ object CoordinateMediationPrograms { _ <- Console.printLine(tmp) _ <- Console.printLine("*" * 100) ret <- ZIO - .fromEither(parse(messageReceived.message.toString)) + .fromEither(messageReceived.message.toString.fromJson[Json]) .flatMap { json => json.as[MediateGrant] match { case Right(mediateGrant) => ZIO.succeed(mediateGrant) diff --git a/mercury/agent/src/main/scala/org/hyperledger/identus/mercury/InvitationPrograms.scala b/mercury/agent/src/main/scala/org/hyperledger/identus/mercury/InvitationPrograms.scala index 920df65fb9..0b0f2edca6 100644 --- a/mercury/agent/src/main/scala/org/hyperledger/identus/mercury/InvitationPrograms.scala +++ b/mercury/agent/src/main/scala/org/hyperledger/identus/mercury/InvitationPrograms.scala @@ -1,10 +1,10 @@ package org.hyperledger.identus.mercury -import io.circe.syntax.* import org.hyperledger.identus.mercury.protocol.invitation.* import org.hyperledger.identus.mercury.protocol.invitation.v2.* import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation.Body import zio.* +import zio.json.EncoderOps object InvitationPrograms { @@ -27,8 +27,8 @@ object InvitationPrograms { Body(Some("request-mediate"), Some("RequestMediate"), Seq("didcomm/v2", "didcomm/aip2;env=rfc587")) ) _ <- ZIO.log(s"createInvitationV2 from '${merdiator.id}'") - result = invitation.asJson.deepDropNullValues - } yield (java.util.Base64.getUrlEncoder.encodeToString(result.noSpaces.getBytes)) + result = invitation.toJson + } yield (java.util.Base64.getUrlEncoder.encodeToString(result.toJson.getBytes)) } From eef0b8c86fe132860b283206de33ea0116ff7fdb Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Fri, 29 Nov 2024 14:10:42 +0100 Subject: [PATCH 12/22] feat: migrate agent-didcommx Signed-off-by: Benjamin Voiturier --- .../identus/mercury/MessagingService.scala | 1 - .../hyperledger/identus/mercury/PeerDID.scala | 14 ++--- .../identus/mercury/model/Conversions.scala | 52 ++++++++--------- .../mercury/model/JsonUtilsForDidCommx.scala | 58 ++++++++----------- .../mercury/model/UnpackMessageImpSpec.scala | 9 ++- 5 files changed, 56 insertions(+), 78 deletions(-) diff --git a/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/MessagingService.scala b/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/MessagingService.scala index ef26cf8540..2e4e93517e 100644 --- a/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/MessagingService.scala +++ b/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/MessagingService.scala @@ -1,6 +1,5 @@ package org.hyperledger.identus.mercury -import io.circe.* import org.hyperledger.identus.mercury.model.* import org.hyperledger.identus.mercury.model.error.* import org.hyperledger.identus.mercury.protocol.routing.* diff --git a/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/PeerDID.scala b/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/PeerDID.scala index ef947adebe..6f2eab0711 100644 --- a/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/PeerDID.scala +++ b/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/PeerDID.scala @@ -2,11 +2,9 @@ package org.hyperledger.identus.mercury import com.nimbusds.jose.jwk.* import com.nimbusds.jose.jwk.gen.* -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import org.didcommx.peerdid.* import org.hyperledger.identus.mercury.model.DidId +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} import scala.jdk.CollectionConverters.* @@ -56,8 +54,8 @@ object PeerDID { case class ServiceEndpoint(uri: String, r: Seq[String] = Seq.empty, a: Seq[String] = Seq("didcomm/v2")) object ServiceEndpoint { - implicit val encoder: Encoder[ServiceEndpoint] = deriveEncoder[ServiceEndpoint] - implicit val decoder: Decoder[ServiceEndpoint] = deriveDecoder[ServiceEndpoint] + implicit val encoder: JsonEncoder[ServiceEndpoint] = DeriveJsonEncoder.gen + implicit val decoder: JsonDecoder[ServiceEndpoint] = DeriveJsonDecoder.gen def apply(endpoint: String) = new ServiceEndpoint(uri = endpoint) } @@ -71,8 +69,8 @@ object PeerDID { def accept = s.a } object Service { - implicit val encoder: Encoder[Service] = deriveEncoder[Service] - implicit val decoder: Decoder[Service] = deriveDecoder[Service] + implicit val encoder: JsonEncoder[Service] = DeriveJsonEncoder.gen + implicit val decoder: JsonDecoder[Service] = DeriveJsonDecoder.gen def apply(endpoint: String) = new Service(s = ServiceEndpoint(endpoint)) } @@ -102,7 +100,7 @@ object PeerDID { List(keyAgreemenFromPublicJWK(jwkForKeyAgreement)).asJava, List(keyAuthenticationFromPublicJWK(jwkForKeyAuthentication)).asJava, serviceEndpoint match { - case Some(endpoint) => Service(endpoint).asJson.noSpaces + case Some(endpoint) => Service(endpoint).toJson case None => null } ) diff --git a/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/model/Conversions.scala b/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/model/Conversions.scala index 8ad56dc2d4..754d19711d 100644 --- a/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/model/Conversions.scala +++ b/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/model/Conversions.scala @@ -1,10 +1,8 @@ package org.hyperledger.identus.mercury.model -import io.circe.* import org.didcommx.didcomm.message.{Attachment as XAttachment, MessageBuilder} -import org.didcommx.didcomm.message.Attachment.Data import org.didcommx.didcomm.model.* -import org.hyperledger.identus.mercury.model.* +import zio.json.ast.Json import scala.jdk.CollectionConverters.* import scala.language.implicitConversions @@ -48,39 +46,35 @@ given Conversion[Message, org.didcommx.didcomm.message.Message] with { } def json2Map(json: Json): Any = json match { - case e if e.isArray => e.asArray.get.toList.map(j => json2Map(j)).asJava - case e if e.isBoolean => e.asBoolean.get - case e if e.isNumber => e.asNumber.flatMap(_.toBigDecimal).get - case e if e.isObject => e.asObject.get.toMap.view.mapValues(json2Map).toMap.asJava - case e if e.isString => e.asString.get - case e if e.isNull => null - case _ => null // Impossible case but Json cases are private in circe ... + case e @ Json.Arr(_) => e.asArray.get.toList.map(j => json2Map(j)).asJava + case e @ Json.Bool(_) => e.asBoolean.get + case e @ Json.Num(_) => e.asNumber.map(_.value).get + case e @ Json.Obj(_) => e.asObject.get.toMap.view.mapValues(json2Map).toMap.asJava + case e @ Json.Str(_) => e.asString.get + case e @ Json.Null => null } def mapValueToJson(obj: java.lang.Object): Json = { obj match { case null => Json.Null - case b: java.lang.Boolean => Json.fromBoolean(b) - case i: java.lang.Integer => Json.fromInt(i) - case d: java.lang.Double => - Json.fromDouble(d).getOrElse(Json.fromDouble(0d).get) - case l: java.lang.Long => Json.fromLong(l) - case s: java.lang.String => Json.fromString(String.valueOf(s)) + case b: java.lang.Boolean => Json.Bool(b) + case i: java.lang.Integer => Json.Num(i) + case d: java.lang.Double => Json.Num(d) + case l: java.lang.Long => Json.Num(l) + case s: java.lang.String => Json.Str(String.valueOf(s)) case array: com.nimbusds.jose.shaded.json.JSONArray => { - Json.fromValues(array.iterator().asScala.map(mapValueToJson).toList) + Json.Arr(array.iterator().asScala.map(mapValueToJson).toList: _*) } case joseObject: com.nimbusds.jose.shaded.json.JSONObject => - Json.fromJsonObject { - JsonObject.fromMap( - joseObject - .asInstanceOf[java.util.Map[String, Object]] - .asScala - .toMap - .view - .mapValues(mapValueToJson) - .toMap - ) - } + Json.Obj( + joseObject + .asInstanceOf[java.util.Map[String, Object]] + .asScala + .toMap + .view + .mapValues(mapValueToJson) + .toArray: _* + ) } } @@ -115,7 +109,7 @@ given Conversion[XAttachment, AttachmentDescriptor] with { case e if e contains ("json") => val aux = e("json") val x = aux.asInstanceOf[java.util.Map[String, Object]].asScala.toMap.view.mapValues(mapValueToJson) - JsonData(JsonObject.fromMap(x.toMap)) + JsonData(Json.Obj(x.toArray: _*)) case e if e contains ("base64") => val tmp = e("base64").asInstanceOf[String] // ... Base64(tmp) diff --git a/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/model/JsonUtilsForDidCommx.scala b/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/model/JsonUtilsForDidCommx.scala index bd826a9fd0..233e4f9d27 100644 --- a/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/model/JsonUtilsForDidCommx.scala +++ b/mercury/agent-didcommx/src/main/scala/org/hyperledger/identus/mercury/model/JsonUtilsForDidCommx.scala @@ -1,31 +1,30 @@ package org.hyperledger.identus.mercury.model -import io.circe.* -import io.circe.parser.* +import zio.json.ast.Json +import zio.json.DecoderOps import scala.jdk.CollectionConverters.* object JsonUtilsForDidCommx { - private type JsonValue = Boolean | JsonNumber | String | Json.Null.type + private type JsonValue = Boolean | BigDecimal | String | Json.Null private type SubJsonFields[F] = Seq[F] | Map[String, F] private type JsonRecursiveType[F] = SubJsonFields[F] | JsonValue case class FixJson[F[_]](out: F[FixJson[F]]) type MyJson = FixJson[JsonRecursiveType] type MyJsonTop = Map[String, MyJson] - private def fromJson(body: JsonObject): MyJsonTop = + private def fromJson(body: Json.Obj): MyJsonTop = body.toMap.map { case (k, v) => (k, fromJsonAux(v)) } - private def fromJsonAux(body: Json): MyJson = body.fold[MyJson]( - jsonNull = FixJson(Json.Null), - jsonBoolean = b => FixJson(b), - jsonNumber = n => FixJson(n), // TODO JsonNumber, - jsonString = s => FixJson(s), - jsonArray = v => FixJson(v.toSeq.map(json => fromJsonAux(json))), - jsonObject = m => FixJson(m.toMap.map { case (k, v) => (k, fromJsonAux(v)) }), - ) + private def fromJsonAux(body: Json): MyJson = body match + case Json.Null => FixJson(Json.Null) + case Json.Bool(value) => FixJson(value) + case Json.Num(value) => FixJson(value) + case Json.Str(value) => FixJson(value) + case Json.Arr(elements) => FixJson(elements.toSeq.map(json => fromJsonAux(json))) + case Json.Obj(fields) => FixJson(fields.toMap.map { case (k, v) => (k, fromJsonAux(v)) }) - def fromJsonToJavaMap(body: JsonObject) = toJavaMap(fromJson(body)) + def fromJsonToJavaMap(body: Json.Obj): java.util.Map[String, Any] = toJavaMap(fromJson(body)) private def toJavaMap(json: MyJsonTop): java.util.Map[String, Any] = { def myJsonToMap(f: MyJson): Any = f match { @@ -37,28 +36,17 @@ object JsonUtilsForDidCommx { json.map { case (s, fixJson) => (s, myJsonToMap(fixJson)) }.asJava } - // def toMap(json: MyJsonTop): Map[String, Any] = { - // def myJsonToMap(f: MyJson): Any = f match { - // case FixJson(jsonValue: JsonValue) => jsonValue - // case FixJson(seq: Seq[MyJson] @unchecked) => seq.map(myJsonToMap(_)) - // case FixJson(m: Map[String, MyJson] @unchecked) => toJavaMap(m) - // } - // json.map { case (s, fixJson) => (s, myJsonToMap(fixJson)) } - // } - - def toJson(json: MyJsonTop): JsonObject = { + def toJson(json: MyJsonTop): Json.Obj = { def myJsonToJson(f: MyJson): Json = f match { - case FixJson(jsonValue: Json.Null.type) => Json.Null // TEST - case FixJson(jsonValue: Boolean) => Json.fromBoolean(jsonValue) - case FixJson(jsonValue: JsonNumber) => Json.fromJsonNumber(jsonValue) - case FixJson(jsonValue: String) => Json.fromString(jsonValue) - case FixJson(seq: Seq[MyJson] @unchecked) => Json.fromValues(seq.map(myJsonToJson(_))) - case FixJson(m: Map[String, MyJson] @unchecked) => - Json.fromJsonObject( - JsonObject.fromMap(m.map { case (s, fixJson) => (s, myJsonToJson(fixJson)) }) - ) + case FixJson(value: Json.Null) => value // TEST + case FixJson(value: Boolean) => Json.Bool(value) + case FixJson(value: BigDecimal) => Json.Num(value) + case FixJson(value: String) => Json.Str(value) + case FixJson(elements: Seq[MyJson] @unchecked) => Json.Arr(elements.map(myJsonToJson): _*) + case FixJson(items: Map[String, MyJson] @unchecked) => + Json.Obj(items.map { case (s, fixJson) => (s, myJsonToJson(fixJson)) }.toSeq: _*) } - JsonObject.fromMap(json.map { case (s, fixJson) => (s, myJsonToJson(fixJson)) }) + Json.Obj(json.map { case (s, fixJson) => (s, myJsonToJson(fixJson)) }.toSeq: _*) } def fromJavaMapToJsonAux(m: java.util.Map[String, Any]): MyJsonTop = { @@ -73,7 +61,7 @@ object JsonUtilsForDidCommx { m.asScala.toMap.map { case (s, any) => (s: String, auxMethod(any): MyJson) } } - def fromJavaMapToJson(m: java.util.Map[String, Any]): JsonObject = toJson(fromJavaMapToJsonAux(m)) + def fromJavaMapToJson(m: java.util.Map[String, Any]): Json.Obj = toJson(fromJavaMapToJsonAux(m)) } @main def JsonUtilsForDidCommxMain() = { @@ -86,7 +74,7 @@ object JsonUtilsForDidCommx { | "accept": ["didcomm/v2", "didcomm/aip2;env=rfc587"] |}""".stripMargin - val x1 = parse(json).toOption.flatMap(_.asObject).get + val x1 = json.fromJson[Json].toOption.flatMap(_.asObject).get println(x1) val x2 = JsonUtilsForDidCommx.fromJsonToJavaMap(x1) diff --git a/mercury/agent-didcommx/src/test/scala/org/hyperledger/identus/mercury/model/UnpackMessageImpSpec.scala b/mercury/agent-didcommx/src/test/scala/org/hyperledger/identus/mercury/model/UnpackMessageImpSpec.scala index 4b5c42673e..50aca0a84f 100644 --- a/mercury/agent-didcommx/src/test/scala/org/hyperledger/identus/mercury/model/UnpackMessageImpSpec.scala +++ b/mercury/agent-didcommx/src/test/scala/org/hyperledger/identus/mercury/model/UnpackMessageImpSpec.scala @@ -1,7 +1,7 @@ package org.hyperledger.identus.mercury.model -import io.circe.JsonObject import munit.* +import zio.json.ast.Json import scala.language.implicitConversions @@ -12,7 +12,7 @@ class UnpackMessageImpSpec extends ZSuite { `type` = "type_test", // PIURI, from = None, // Option[DidId], to = Seq(), // Seq[DidId], - body = JsonObject.empty, + body = Json.Obj(), id = "id123", createdTime = None, expiresTimePlus = None, @@ -35,12 +35,11 @@ class UnpackMessageImpSpec extends ZSuite { `type` = "type_test", // PIURI, from = None, // Option[DidId], to = Seq(), // Seq[DidId], - body = JsonObject.empty, + body = Json.Obj(), id = "id123", createdTime = None, expiresTimePlus = None, attachments = None, - thid = None, pthid = None, ack = None, pleaseAck = Some(Seq.empty), @@ -57,7 +56,7 @@ class UnpackMessageImpSpec extends ZSuite { `type` = "type_test", // PIURI, from = None, // Option[DidId], to = Seq(), // Seq[DidId], - body = JsonObject.empty, + body = Json.Obj(), id = "id123", createdTime = None, expiresTimePlus = None, From f756c269b345937d3a960698b7387b1285a78d84 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Fri, 29 Nov 2024 14:55:21 +0100 Subject: [PATCH 13/22] feat: migrate connect-core Signed-off-by: Benjamin Voiturier --- .../identus/connect/core/service/ConnectionServiceImpl.scala | 5 +++-- .../connect/core/service/ConnectionServiceImplSpec.scala | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala index db91377abc..debe152904 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImpl.scala @@ -13,6 +13,7 @@ import org.hyperledger.identus.shared.utils.aspects.CustomMetricsAspect import org.hyperledger.identus.shared.utils.Base64Utils import org.hyperledger.identus.shared.validation.ValidationUtils import zio.* +import zio.json.DecoderOps import zio.prelude.* import java.time.{Duration, Instant} @@ -108,8 +109,8 @@ private class ConnectionServiceImpl( ): ZIO[WalletAccessContext, InvitationParsingError | InvitationAlreadyReceived, ConnectionRecord] = for { invitation <- ZIO - .fromEither(io.circe.parser.decode[Invitation](Base64Utils.decodeUrlToString(invitation))) - .mapError(err => InvitationParsingError(err.getMessage)) + .fromEither(Base64Utils.decodeUrlToString(invitation).fromJson[Invitation]) + .mapError(err => InvitationParsingError(err)) maybeRecord <- connectionRepository.findByThreadId(invitation.id) _ <- ZIO.noneOrFailWith(maybeRecord)(_ => InvitationAlreadyReceived(invitation.id)) wallet <- ZIO.service[WalletAccessContext] diff --git a/connect/core/src/test/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImplSpec.scala b/connect/core/src/test/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImplSpec.scala index e999551dbf..2f8ad0d3b4 100644 --- a/connect/core/src/test/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImplSpec.scala +++ b/connect/core/src/test/scala/org/hyperledger/identus/connect/core/service/ConnectionServiceImplSpec.scala @@ -1,6 +1,5 @@ package org.hyperledger.identus.connect.core.service -import io.circe.syntax.* import org.hyperledger.identus.connect.core.model.error.ConnectionServiceError import org.hyperledger.identus.connect.core.model.error.ConnectionServiceError.InvalidStateForOperation import org.hyperledger.identus.connect.core.model.ConnectionRecord.* @@ -11,6 +10,7 @@ import org.hyperledger.identus.shared.messaging import org.hyperledger.identus.shared.messaging.WalletIdAndRecordId import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} import zio.* +import zio.json.{DecoderOps, EncoderOps} import zio.test.* import zio.test.Assertion.* @@ -291,7 +291,7 @@ object ConnectionServiceImplSpec extends ZIOSpecDefault { ) maybeAcceptedRequestConnectionRecord <- inviterSvc.acceptConnectionRequest(inviterRecord.id) connectionResponseMessage <- ZIO.fromEither( - maybeAcceptedRequestConnectionRecord.connectionResponse.get.makeMessage.asJson.as[Message] + maybeAcceptedRequestConnectionRecord.connectionResponse.get.makeMessage.toJson.fromJson[Message] ) _ <- inviterSvc.markConnectionResponseSent(inviterRecord.id) maybeReceivedResponseConnectionRecord <- inviteeSvc.receiveConnectionResponse( From c9107eb66deecfd9cded4d46b5c5233405de82de Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Fri, 29 Nov 2024 15:00:52 +0100 Subject: [PATCH 14/22] migrate connect-sql-doobie Signed-off-by: Benjamin Voiturier --- .../repository/JdbcConnectionRepository.scala | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala b/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala index 44a3e5912d..ccd3642d35 100644 --- a/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala +++ b/connect/sql-doobie/src/main/scala/org/hyperledger/identus/connect/sql/repository/JdbcConnectionRepository.scala @@ -5,12 +5,10 @@ import doobie.* import doobie.free.connection import doobie.implicits.* import doobie.postgres.implicits.* -import io.circe.* -import io.circe.parser.* -import io.circe.syntax.* import org.hyperledger.identus.connect.core.model.* import org.hyperledger.identus.connect.core.model.ConnectionRecord.{ProtocolState, Role} import org.hyperledger.identus.connect.core.repository.ConnectionRepository +import org.hyperledger.identus.mercury.protocol import org.hyperledger.identus.mercury.protocol.connection.* import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation import org.hyperledger.identus.shared.db.ContextAwareTask @@ -22,7 +20,6 @@ import zio.json.* import java.time.Instant import java.util.UUID -import java.util as ju class JdbcConnectionRepository(xa: Transactor[ContextAwareTask], xb: Transactor[Task]) extends ConnectionRepository { @@ -37,16 +34,16 @@ class JdbcConnectionRepository(xa: Transactor[ContextAwareTask], xb: Transactor[ given roleGet: Get[Role] = Get[String].map(Role.valueOf) given rolePut: Put[Role] = Put[String].contramap(_.toString) - given invitationGet: Get[Invitation] = Get[String].map(decode[Invitation](_).getOrElse(UnexpectedCodeExecutionPath)) - given invitationPut: Put[Invitation] = Put[String].contramap(_.asJson.toString) + given invitationGet: Get[Invitation] = Get[String].map(_.fromJson[Invitation].getOrElse(UnexpectedCodeExecutionPath)) + given invitationPut: Put[Invitation] = Put[String].contramap(_.toJson) given connectionRequestGet: Get[ConnectionRequest] = - Get[String].map(decode[ConnectionRequest](_).getOrElse(UnexpectedCodeExecutionPath)) - given connectionRequestPut: Put[ConnectionRequest] = Put[String].contramap(_.asJson.toString) + Get[String].map(_.fromJson[ConnectionRequest].getOrElse(UnexpectedCodeExecutionPath)) + given connectionRequestPut: Put[ConnectionRequest] = Put[String].contramap(_.toJson) given connectionResponseGet: Get[ConnectionResponse] = - Get[String].map(decode[ConnectionResponse](_).getOrElse(UnexpectedCodeExecutionPath)) - given connectionResponsePut: Put[ConnectionResponse] = Put[String].contramap(_.asJson.toString) + Get[String].map(_.fromJson[protocol.connection.ConnectionResponse].getOrElse(UnexpectedCodeExecutionPath)) + given connectionResponsePut: Put[ConnectionResponse] = Put[String].contramap(_.toJson) given failureGet: Get[Failure] = Get[String].temap(_.fromJson[FailureInfo]) given failurePut: Put[Failure] = Put[String].contramap(_.asFailureInfo.toJson) From 8d4e2f6b802c216ed6bb69a2b4bd082dfaa9ada4 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Fri, 29 Nov 2024 17:05:49 +0100 Subject: [PATCH 15/22] feat: migrate pollux-core Signed-off-by: Benjamin Voiturier --- .../model/CredentialOfferAttachment.scala | 7 +- .../presentation/PresentationAttachment.scala | 11 +- .../core/service/CredentialService.scala | 30 ++-- .../core/service/CredentialServiceImpl.scala | 56 ++++--- .../service/CredentialServiceNotifier.scala | 4 +- .../service/PresentationServiceImpl.scala | 41 +++--- .../PresentationAttachmentSpec.scala | 29 ++-- ...sentationExchangeRepositorySpecSuite.scala | 9 +- .../service/CredentialServiceImplSpec.scala | 50 +++---- .../service/CredentialServiceSpecHelper.scala | 15 +- .../core/service/MockCredentialService.scala | 4 +- .../service/PresentationServiceSpec.scala | 17 +-- .../uriResolvers/DidUrlResolverSpec.scala | 6 +- .../VcVerificationServiceImplSpec.scala | 137 +++++++++++------- .../shared/messaging/MessagingService.scala | 1 - 15 files changed, 204 insertions(+), 213 deletions(-) diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/CredentialOfferAttachment.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/CredentialOfferAttachment.scala index 9897e0f0dc..4d82def463 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/CredentialOfferAttachment.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/CredentialOfferAttachment.scala @@ -1,13 +1,12 @@ package org.hyperledger.identus.pollux.core.model -import io.circe.* -import io.circe.generic.semiauto.* import org.hyperledger.identus.pollux.core.model.presentation.Options import org.hyperledger.identus.pollux.prex.PresentationDefinition +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} final case class CredentialOfferAttachment(options: Options, presentation_definition: PresentationDefinition) object CredentialOfferAttachment { - given Encoder[CredentialOfferAttachment] = deriveEncoder - given Decoder[CredentialOfferAttachment] = deriveDecoder + given JsonEncoder[CredentialOfferAttachment] = DeriveJsonEncoder.gen + given JsonDecoder[CredentialOfferAttachment] = DeriveJsonDecoder.gen } diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/presentation/PresentationAttachment.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/presentation/PresentationAttachment.scala index 41bd261a50..178014e0bd 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/presentation/PresentationAttachment.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/presentation/PresentationAttachment.scala @@ -1,19 +1,18 @@ package org.hyperledger.identus.pollux.core.model.presentation -import io.circe.* -import io.circe.generic.semiauto.* import org.hyperledger.identus.pollux.prex.PresentationDefinition +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} case class Options(challenge: String, domain: String) object Options { - given Encoder[Options] = deriveEncoder[Options] - given Decoder[Options] = deriveDecoder[Options] + given JsonEncoder[Options] = DeriveJsonEncoder.gen + given JsonDecoder[Options] = DeriveJsonDecoder.gen } case class PresentationAttachment(options: Option[Options] = None, presentation_definition: PresentationDefinition) object PresentationAttachment { - given Encoder[PresentationAttachment] = deriveEncoder[PresentationAttachment] - given Decoder[PresentationAttachment] = deriveDecoder[PresentationAttachment] + given JsonEncoder[PresentationAttachment] = DeriveJsonEncoder.gen + given JsonDecoder[PresentationAttachment] = DeriveJsonDecoder.gen def build(options: Option[Options] = None): PresentationAttachment = { val presentationDefinition = diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialService.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialService.scala index 3414f8a351..4342b951cb 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialService.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialService.scala @@ -1,7 +1,5 @@ package org.hyperledger.identus.pollux.core.service -import io.circe.{Json, JsonObject} -import io.circe.syntax.* import org.hyperledger.identus.castor.core.model.did.{CanonicalPrismDID, PrismDID, VerificationRelationship} import org.hyperledger.identus.mercury.model.DidId import org.hyperledger.identus.mercury.protocol.issuecredential.{ @@ -16,6 +14,8 @@ import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError.* import org.hyperledger.identus.pollux.vc.jwt.Issuer import org.hyperledger.identus.shared.models.* import zio.{Duration, IO, UIO, URIO, ZIO} +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json import java.nio.charset.StandardCharsets import java.util.UUID @@ -28,7 +28,7 @@ trait CredentialService { kidIssuer: Option[KeyId], thid: DidCommID, maybeSchemaIds: Option[List[String]], - claims: io.circe.Json, + claims: Json, validityPeriod: Option[Double] = None, automaticIssuance: Option[Boolean], issuingDID: CanonicalPrismDID, @@ -44,7 +44,7 @@ trait CredentialService { kidIssuer: Option[KeyId], thid: DidCommID, maybeSchemaIds: Option[List[String]], - claims: io.circe.Json, + claims: Json, validityPeriod: Option[Double] = None, automaticIssuance: Option[Boolean], issuingDID: CanonicalPrismDID, @@ -60,7 +60,7 @@ trait CredentialService { thid: DidCommID, credentialDefinitionGUID: UUID, credentialDefinitionId: String, - claims: io.circe.Json, + claims: Json, validityPeriod: Option[Double] = None, automaticIssuance: Option[Boolean], goalCode: Option[String], @@ -184,16 +184,15 @@ trait CredentialService { object CredentialService { def convertJsonClaimsToAttributes( - claims: io.circe.Json + claims: Json ): UIO[Seq[Attribute]] = { for { fields <- ZIO.succeed(claims.asObject.map(_.toMap).getOrElse(Map.empty).toList) res <- ZIO.foreach(fields) { - case (k, v) if v.isString => - ZIO.succeed(Attribute(name = k, value = v.asString.get)) + case (k, Json.Str(v)) => ZIO.succeed(Attribute(name = k, value = v)) case (k, v) => ZIO.succeed { - val jsonValue = v.noSpaces + val jsonValue = v.toJson Attribute( name = k, value = java.util.Base64.getUrlEncoder.encodeToString(jsonValue.getBytes(StandardCharsets.UTF_8)), @@ -206,18 +205,17 @@ object CredentialService { def convertAttributesToJsonClaims( attributes: Seq[Attribute] - ): IO[CredentialServiceError, JsonObject] = { + ): IO[CredentialServiceError, Json.Obj] = { for { - claims <- ZIO.foldLeft(attributes)(JsonObject()) { case (jsonObject, attr) => + claims <- ZIO.foldLeft(attributes)(Json.Obj()) { case (jsonObject, attr) => attr.media_type match - case None => - ZIO.succeed(jsonObject.add(attr.name, attr.value.asJson)) + case None => ZIO.succeed(jsonObject.add(attr.name, Json.Str(attr.value))) case Some("application/json") => val jsonBytes = java.util.Base64.getUrlDecoder.decode(attr.value.getBytes(StandardCharsets.UTF_8)) - io.circe.parser.parse(new String(jsonBytes, StandardCharsets.UTF_8)) match - case Right(value) => ZIO.succeed(jsonObject.add(attr.name, value)) - case Left(error) => ZIO.fail(VCClaimsValueParsingError(error.message)) + new String(jsonBytes, StandardCharsets.UTF_8).fromJson[Json] match + case Right(value) => ZIO.succeed(Json.Obj().add(attr.name, value)) + case Left(error) => ZIO.fail(VCClaimsValueParsingError(error)) case Some(media_type) => ZIO.fail(UnsupportedVCClaimsMediaType(media_type)) diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala index 8fdcc7cd57..5a2dab12fc 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImpl.scala @@ -1,9 +1,6 @@ package org.hyperledger.identus.pollux.core.service import cats.implicits.* -import io.circe.* -import io.circe.parser.* -import io.circe.syntax.* import org.hyperledger.identus.agent.walletapi.model.{ManagedDIDState, PublicationState} import org.hyperledger.identus.agent.walletapi.service.ManagedDIDService import org.hyperledger.identus.agent.walletapi.storage.GenericSecretStorage @@ -20,8 +17,6 @@ import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError.* import org.hyperledger.identus.pollux.core.model.presentation.* import org.hyperledger.identus.pollux.core.model.schema.{CredentialDefinition, CredentialSchema} import org.hyperledger.identus.pollux.core.model.secret.CredentialDefinitionSecret -import org.hyperledger.identus.pollux.core.model.CredentialFormat.AnonCreds -import org.hyperledger.identus.pollux.core.model.IssueCredentialRecord.ProtocolState.OfferReceived import org.hyperledger.identus.pollux.core.repository.{CredentialRepository, CredentialStatusListRepository} import org.hyperledger.identus.pollux.prex.{ClaimFormat, Jwt, PresentationDefinition} import org.hyperledger.identus.pollux.sdjwt.* @@ -29,12 +24,14 @@ import org.hyperledger.identus.pollux.vc.jwt.{Issuer as JwtIssuer, *} import org.hyperledger.identus.pollux.vc.jwt.PresentationPayload.Implicits.* import org.hyperledger.identus.shared.crypto.{Ed25519KeyPair, Secp256k1KeyPair} import org.hyperledger.identus.shared.http.UriResolver +import org.hyperledger.identus.shared.json.JsonInterop import org.hyperledger.identus.shared.messaging.{Producer, WalletIdAndRecordId} import org.hyperledger.identus.shared.models.* import org.hyperledger.identus.shared.utils.aspects.CustomMetricsAspect import org.hyperledger.identus.shared.utils.Base64Utils import zio.* import zio.json.* +import zio.json.ast.Json import zio.prelude.ZValidation import java.time.{Instant, ZoneId} @@ -253,7 +250,7 @@ class CredentialServiceImpl( kidIssuer: Option[KeyId], thid: DidCommID, maybeSchemaIds: Option[List[String]], - claims: io.circe.Json, + claims: Json, validityPeriod: Option[Double] = None, automaticIssuance: Option[Boolean], issuingDID: CanonicalPrismDID, @@ -314,7 +311,7 @@ class CredentialServiceImpl( _ <- CredentialSchema .validateAnonCredsClaims( credentialDefinition.schemaId, - claims.noSpaces, + claims.toJson, uriResolver, ) .orDieAsUnmanagedFailure @@ -422,10 +419,8 @@ class CredentialServiceImpl( attachment.data match case JsonData(json) => ZIO - .attempt(json.asJson.hcursor.downField("json").as[CredentialOfferAttachment]) - .mapError(e => - InvalidCredentialOffer(s"An error occurred when parsing the offer attachment: ${e.toString}") - ) + .fromEither(json.as[CredentialOfferAttachment]) + .mapError(err => InvalidCredentialOffer(s"An error occurred when parsing the offer attachment: $err")) case _ => ZIO.fail(InvalidCredentialOffer(s"Only JSON attachments are supported in JWT offers")) case CredentialFormat.AnonCreds => @@ -458,7 +453,7 @@ class CredentialServiceImpl( .collectAll( schemaIds.map(schemaId => CredentialSchema - .validateJWTCredentialSubject(schemaId, claims.noSpaces, uriResolver) + .validateJWTCredentialSubject(schemaId, claims.toJson, uriResolver) ) ) .orDieAsUnmanagedFailure @@ -890,7 +885,7 @@ class CredentialServiceImpl( .updateWithIssuedRawCredential( record.id, issueCredential, - attachment.data.asJson.noSpaces, + attachment.data.toJson, schemaId, credDefId, ProtocolState.CredentialReceived @@ -1212,7 +1207,7 @@ class CredentialServiceImpl( ids.map(id => org.hyperledger.identus.pollux.vc.jwt.CredentialSchema(id, VC_JSON_SCHEMA_TYPE)) ), maybeCredentialStatus = Some(credentialStatus), - credentialSubject = claims.add("id", jwtPresentation.iss.asJson).asJson, + credentialSubject = JsonInterop.toCirceJsonAst(claims.add("id", Json.Str(jwtPresentation.iss))), maybeRefreshService = None, maybeEvidence = None, maybeTermsOfUse = None, @@ -1293,29 +1288,29 @@ class CredentialServiceImpl( } now = Instant.now.getEpochSecond - exp = claims("exp").flatMap(_.asNumber).flatMap(_.toLong) + exp = claims.get("exp").flatMap(_.asNumber).map(_.value.longValue()) expInSeconds <- ZIO.fromEither(exp match { case Some(e) if e > now => Right(e) case Some(e) => Left(ExpirationDateHasPassed(e)) case _ => Right(Instant.now.plus(expirationTime).getEpochSecond) }) claimsUpdated = claims - .add("iss", issuingDID.did.toString.asJson) // This is issuer did - .add("sub", jwtPresentation.iss.asJson) // This is subject did - .add("iat", now.asJson) - .add("exp", expInSeconds.asJson) + .add("iss", Json.Str(issuingDID.did.toString)) // This is issuer did + .add("sub", Json.Str(jwtPresentation.iss)) // This is subject did + .add("iat", Json.Num(now)) + .add("exp", Json.Num(expInSeconds)) credential = { jsonWebKey match { case Some(jwk) => SDJWT.issueCredential( sdJwtPrivateKey, - claimsUpdated.asJson.noSpaces, + claimsUpdated.toJson, sdjwt.HolderPublicKey.fromJWT(jwk.toJson) ) case None => SDJWT.issueCredential( sdJwtPrivateKey, - claimsUpdated.asJson.noSpaces, + claimsUpdated.toJson, ) } } @@ -1448,11 +1443,11 @@ class CredentialServiceImpl( .fromOption(offer.attachments.headOption) .orElse(ZIO.dieMessage(s"Attachments not found in record: ${record.id}")) json <- attachmentDescriptor.data match - case JsonData(json) => ZIO.succeed(json.asJson) + case JsonData(json) => ZIO.succeed(json.toJsonAST.toOption.get) case _ => ZIO.dieMessage(s"Attachment doesn't contain JsonData: ${record.id}") maybeOptions <- ZIO .fromEither(json.as[PresentationAttachment].map(_.options)) - .flatMapError(df => ZIO.dieMessage(df.getMessage)) + .flatMapError(err => ZIO.dieMessage(err)) } yield maybeOptions } @@ -1517,8 +1512,8 @@ class CredentialServiceImpl( ): ZIO[WalletAccessContext, CredentialServiceError, OfferCredential] = { for { invitation <- ZIO - .fromEither(io.circe.parser.decode[Invitation](Base64Utils.decodeUrlToString(invitation))) - .mapError(err => InvitationParsingError(err.getMessage)) + .fromEither(Base64Utils.decodeUrlToString(invitation).fromJson[Invitation]) + .mapError(err => InvitationParsingError(err)) _ <- invitation.expires_time match { case Some(expiryTime) => ZIO @@ -1535,16 +1530,15 @@ class CredentialServiceImpl( invitation.attachments .flatMap( _.headOption.map(attachment => - decode[org.hyperledger.identus.mercury.model.JsonData]( - attachment.data.asJson.noSpaces - ) // TODO Move mercury to use ZIO JSON + attachment.data.toJson + .fromJson[org.hyperledger.identus.mercury.model.JsonData] .flatMap { data => - OfferCredential.given_Decoder_OfferCredential - .decodeJson(data.json.asJson) + OfferCredential.given_JsonDecoder_OfferCredential + .decodeJson(data.json.toJson) .map(r => r.copy(to = Some(pairwiseHolderDID))) .leftMap(err => CredentialOfferDecodingError( - s"Credential Offer As Attachment decoding error: ${err.getMessage}" + s"Credential Offer As Attachment decoding error: $err" ) ) } diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala index 500fdf4c29..b141b83068 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala @@ -1,6 +1,5 @@ package org.hyperledger.identus.pollux.core.service -import io.circe.Json import org.hyperledger.identus.castor.core.model.did.{CanonicalPrismDID, PrismDID, VerificationRelationship} import org.hyperledger.identus.event.notification.* import org.hyperledger.identus.mercury.model.DidId @@ -11,6 +10,7 @@ import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError.* import org.hyperledger.identus.pollux.core.repository.CredentialRepository import org.hyperledger.identus.pollux.vc.jwt.Issuer import org.hyperledger.identus.shared.models.* +import zio.json.ast.Json import zio.{Duration, UIO, URIO, URLayer, ZIO, ZLayer} import java.util.UUID @@ -62,7 +62,7 @@ class CredentialServiceNotifier( kidIssuer: Option[KeyId], thid: DidCommID, maybeSchemaIds: Option[List[String]], - claims: io.circe.Json, + claims: Json, validityPeriod: Option[Double] = None, automaticIssuance: Option[Boolean], issuingDID: CanonicalPrismDID, diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala index 3d18a25bbe..43a9dce134 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala @@ -1,10 +1,6 @@ package org.hyperledger.identus.pollux.core.service -import cats.* import cats.implicits.* -import io.circe.* -import io.circe.parser.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.model.* import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation import org.hyperledger.identus.mercury.protocol.issuecredential.IssueCredentialIssuedFormat @@ -25,11 +21,10 @@ import org.hyperledger.identus.shared.models.* import org.hyperledger.identus.shared.utils.aspects.CustomMetricsAspect import org.hyperledger.identus.shared.utils.Base64Utils import zio.* -import zio.json.* +import zio.json.{EncoderOps, *} import java.time.Instant import java.util.{Base64 as JBase64, UUID} -import java.util as ju import scala.util.chaining.* import scala.util.Try @@ -561,7 +556,8 @@ private class PresentationServiceImpl( PresentationError.PresentationDecodingError, Seq[CredentialCompact] ] = issuedCredentials.map { signedCredential => - decode[org.hyperledger.identus.mercury.model.Base64](signedCredential) + signedCredential + .fromJson[org.hyperledger.identus.mercury.model.Base64] .flatMap(x => Right(CredentialCompact.unsafeFromCompact(new String(java.util.Base64.getUrlDecoder.decode(x.base64)))) ) @@ -569,15 +565,13 @@ private class PresentationServiceImpl( .map(err => PresentationDecodingError(s"JsonData decoding error: $err")) }.sequence - import io.circe.parser.decode - import io.circe.syntax.* - import java.util.Base64 val result: Either[PresentationDecodingError, SDJwtPresentation] = requestPresentation.attachments.headOption .map(attachment => - decode[org.hyperledger.identus.mercury.model.Base64](attachment.data.asJson.noSpaces) + attachment.data.toJson + .fromJson[org.hyperledger.identus.mercury.model.Base64] .leftMap(err => PresentationDecodingError(s"PresentationAttachment decoding error: $err")) .flatMap { base64 => org.hyperledger.identus.pollux.core.service.serdes.SDJwtPresentation.given_JsonDecoder_SDJwtPresentation @@ -631,7 +625,8 @@ private class PresentationServiceImpl( Seq[JwtVerifiableCredentialPayload] ] = issuedCredentials.map { signedCredential => - decode[org.hyperledger.identus.mercury.model.Base64](signedCredential) + signedCredential + .fromJson[org.hyperledger.identus.mercury.model.Base64] .flatMap(x => Right(new String(java.util.Base64.getUrlDecoder.decode(x.base64)))) .flatMap(x => Right(JwtVerifiableCredentialPayload(JWT(x)))) .left @@ -642,10 +637,11 @@ private class PresentationServiceImpl( : Either[PresentationError, Option[org.hyperledger.identus.pollux.core.model.presentation.Options]] = requestPresentation.attachments.headOption .map(attachment => - decode[org.hyperledger.identus.mercury.model.JsonData](attachment.data.asJson.noSpaces) + attachment.data.toJson + .fromJson[org.hyperledger.identus.mercury.model.JsonData] .flatMap(data => - org.hyperledger.identus.pollux.core.model.presentation.PresentationAttachment.given_Decoder_PresentationAttachment - .decodeJson(data.json.asJson) + org.hyperledger.identus.pollux.core.model.presentation.PresentationAttachment.given_JsonDecoder_PresentationAttachment + .decodeJson(data.json.toJson) .map(_.options) .leftMap(err => PresentationDecodingError(s"PresentationAttachment decoding error: $err")) ) @@ -1299,8 +1295,8 @@ private class PresentationServiceImpl( ): ZIO[WalletAccessContext, PresentationError, RequestPresentation] = { for { invitation <- ZIO - .fromEither(io.circe.parser.decode[Invitation](Base64Utils.decodeUrlToString(invitation))) - .mapError(err => InvitationParsingError(err.getMessage)) + .fromEither(Base64Utils.decodeUrlToString(invitation).fromJson[Invitation]) + .mapError(err => InvitationParsingError(err)) _ <- invitation.expires_time match { case Some(expiryTime) => ZIO @@ -1318,16 +1314,15 @@ private class PresentationServiceImpl( invitation.attachments .flatMap( _.headOption.map(attachment => - decode[org.hyperledger.identus.mercury.model.JsonData]( - attachment.data.asJson.noSpaces - ) // TODO Move mercury to use ZIO JSON + attachment.data.toJson + .fromJson[org.hyperledger.identus.mercury.model.JsonData] .flatMap { data => - RequestPresentation.given_Decoder_RequestPresentation - .decodeJson(data.json.asJson) + RequestPresentation.given_JsonDecoder_RequestPresentation + .decodeJson(data.json.toJson) .map(r => r.copy(to = Some(pairwiseProverDID))) .leftMap(err => PresentationDecodingError( - s"RequestPresentation As Attachment decoding error: ${err.getMessage}" + s"RequestPresentation As Attachment decoding error: $err" ) ) } diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/model/presentation/PresentationAttachmentSpec.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/model/presentation/PresentationAttachmentSpec.scala index 725e81271d..1486f652e3 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/model/presentation/PresentationAttachmentSpec.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/model/presentation/PresentationAttachmentSpec.scala @@ -1,17 +1,16 @@ package org.hyperledger.identus.pollux.core.model.presentation -import io.circe.parser.* -import io.circe.syntax.* -import io.circe.Json import munit.* import org.hyperledger.identus.pollux.prex.* +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json import scala.language.implicitConversions class PresentationAttachmentSpec extends ZSuite { test("Verifier Request Presentation Attachment") { - val expectedConstraintJson = parse(s""" + val expectedConstraintJson = s""" { "fields": [ { @@ -24,7 +23,7 @@ class PresentationAttachmentSpec extends ZSuite { } ] } - """.stripMargin).getOrElse(Json.Null) + """.stripMargin.fromJson[Json] val field = Field( None, path = Seq( @@ -35,10 +34,10 @@ class PresentationAttachmentSpec extends ZSuite { ) ) val constraints = Constraints(fields = Some(Seq(field))) - val result = constraints.asJson.deepDropNullValues + val result = constraints.toJsonAST assertEquals(result, expectedConstraintJson) - val expectedInputDescriptorJson = parse(s""" + val expectedInputDescriptorJson = s""" { "id": "wa_driver_license", "name": "Washington State Business License", @@ -56,7 +55,7 @@ class PresentationAttachmentSpec extends ZSuite { ] } } - """.stripMargin).getOrElse(Json.Null) + """.stripMargin.fromJson[Json] val inputDescriptor = InputDescriptor( id = "wa_driver_license", @@ -65,10 +64,10 @@ class PresentationAttachmentSpec extends ZSuite { Some("We can only allow licensed Washington State business representatives into the WA Business Conference"), constraints = constraints ) - val resultInputDescriptor = inputDescriptor.asJson.deepDropNullValues + val resultInputDescriptor = inputDescriptor.toJsonAST assertEquals(resultInputDescriptor, expectedInputDescriptorJson) - val expectedPresentationDefinitionJson = parse(s""" + val expectedPresentationDefinitionJson = s""" { "id": "32f54163-7166-48f1-93d8-ff217bdb0653", "input_descriptors": [ @@ -91,14 +90,14 @@ class PresentationAttachmentSpec extends ZSuite { } ] } - """.stripMargin).getOrElse(Json.Null) + """.stripMargin.fromJson[Json] val presentationDefinition = PresentationDefinition(id = "32f54163-7166-48f1-93d8-ff217bdb0653", input_descriptors = Seq(inputDescriptor)) - val resultPresentationDefinition = presentationDefinition.asJson.deepDropNullValues + val resultPresentationDefinition = presentationDefinition.toJsonAST assertEquals(resultPresentationDefinition, expectedPresentationDefinitionJson) - val expectedPresentationAttachmentJson = parse(s""" + val expectedPresentationAttachmentJson = s""" { "options": { "challenge": "23516943-1d79-4ebd-8981-623f036365ef", @@ -127,11 +126,11 @@ class PresentationAttachmentSpec extends ZSuite { ] } } - """.stripMargin).getOrElse(Json.Null) + """.stripMargin.fromJson[Json] val options = Options(challenge = "23516943-1d79-4ebd-8981-623f036365ef", domain = "us.gov/DriversLicense") val presentationAttachment = PresentationAttachment(presentation_definition = presentationDefinition, options = Some(options)) - val resultPresentationAttachment = presentationAttachment.asJson.deepDropNullValues + val resultPresentationAttachment = presentationAttachment.toJsonAST println(resultPresentationAttachment) assertEquals(resultPresentationAttachment, expectedPresentationAttachmentJson) diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala index 4af60c579b..fa96e3c063 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala @@ -1,11 +1,9 @@ package org.hyperledger.identus.pollux.core.repository -import io.circe.* -import io.circe.generic.auto.* -import io.circe.parser.* import org.hyperledger.identus.pollux.prex.PresentationDefinition import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} -import zio.{durationInt, ZIO, ZLayer} +import zio.json.{DecoderOps, DeriveJsonDecoder, JsonDecoder} +import zio.{ZIO, ZLayer, durationInt} import zio.test.* import zio.test.Assertion.* @@ -15,11 +13,12 @@ import scala.util.Using object PresentationExchangeRepositorySpecSuite { final case class ExampleTransportEnvelope(presentation_definition: PresentationDefinition) + given JsonDecoder[ExampleTransportEnvelope] = DeriveJsonDecoder.gen private val loadPd = ZIO .fromTry(Using(Source.fromResource("pd/minimal_example.json"))(_.mkString)) - .flatMap(json => ZIO.fromEither(decode[ExampleTransportEnvelope](json))) + .flatMap(json => ZIO.fromEither(json.fromJson[ExampleTransportEnvelope])) .map(_.presentation_definition) val testSuite = suite("CRUD operations")( diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImplSpec.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImplSpec.scala index ab9f7b051b..4c154707bd 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImplSpec.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceImplSpec.scala @@ -1,25 +1,22 @@ package org.hyperledger.identus.pollux.core.service -import io.circe.syntax.* -import io.circe.Json import org.bouncycastle.jce.provider.BouncyCastleProvider import org.hyperledger.identus.agent.walletapi.service.MockManagedDIDService import org.hyperledger.identus.castor.core.model.did.* -import org.hyperledger.identus.castor.core.model.did.VerificationRelationship.AssertionMethod import org.hyperledger.identus.castor.core.service.MockDIDService import org.hyperledger.identus.mercury.model.{Base64 as MyBase64, *} import org.hyperledger.identus.mercury.protocol.issuecredential.* import org.hyperledger.identus.pollux.anoncreds.AnoncredCredential import org.hyperledger.identus.pollux.core.model.* -import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError.* import org.hyperledger.identus.pollux.core.model.schema.CredentialDefinition import org.hyperledger.identus.pollux.core.model.IssueCredentialRecord.{ProtocolState, Role} import org.hyperledger.identus.pollux.core.service.uriResolvers.ResourceUrlResolver -import org.hyperledger.identus.pollux.core.service.CredentialServiceImplSpec.test -import org.hyperledger.identus.pollux.vc.jwt.{CredentialIssuer, JWT, JwtCredential, JwtCredentialPayload} +import org.hyperledger.identus.pollux.vc.jwt.{CredentialIssuer, JWT, JwtCredential} import org.hyperledger.identus.shared.models.{KeyId, UnmanagedFailureException, WalletAccessContext, WalletId} import zio.* +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json import zio.mock.MockSpecDefault import zio.test.* import zio.test.Assertion.* @@ -108,10 +105,11 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS Attribute( "address", Base64.getUrlEncoder.encodeToString( - io.circe.parser - .parse("""{"street": "Street Name", "number": "12"}""") + """{"street": "Street Name", "number": "12"}""" + .fromJson[Json] + .toOption .getOrElse(Json.Null) - .noSpaces + .toJson .getBytes(StandardCharsets.UTF_8) ), Some("application/json") @@ -133,8 +131,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS svc <- ZIO.service[CredentialService] pairwiseIssuerDid = DidId("did:peer:INVITER") pairwiseHolderDid = Some(DidId("did:peer:HOLDER")) - claims = io.circe.parser - .parse(""" + claims = """ |{ | "credentialSubject": { | "emailAddress": "alice@wonderland.com", @@ -145,8 +142,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS | "drivingClass": 5 | } |} - |""".stripMargin) - .getOrElse(Json.Null) + |""".stripMargin.fromJson[Json].toOption.getOrElse(Json.Null) thid = DidCommID(UUID.randomUUID().toString()) record <- svc.createJWTIssueCredentialRecord( thid = thid, @@ -195,18 +191,14 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS svc <- ZIO.service[CredentialService] pairwiseIssuerDid = DidId("did:peer:INVITER") pairwiseHolderDid = Some(DidId("did:peer:HOLDER")) - claims = io.circe.parser - .parse( - """ + claims = """ |{ | "emailAddress": "alice@wonderland.com", | "givenName": "Alice", | "familyName": "Wonderland" |} - |""".stripMargin - ) - .getOrElse(Json.Null) - thid = DidCommID(UUID.randomUUID().toString()) + |""".stripMargin.fromJson[Json].toOption.getOrElse(Json.Null) + thid = DidCommID(UUID.randomUUID().toString) record <- svc .createJWTIssueCredentialRecord( thid = thid, @@ -505,7 +497,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS issuerRecordId = offerCreatedRecord.id // Issuer sends offer _ <- issuerSvc.markOfferSent(issuerRecordId) - msg <- ZIO.fromEither(offerCreatedRecord.offerCredentialData.get.makeMessage.asJson.as[Message]) + msg <- ZIO.fromEither(offerCreatedRecord.offerCredentialData.get.makeMessage.toJson.fromJson[Message]) // Holder receives offer offerCredential <- ZIO.fromEither(OfferCredential.readFromMessage(msg)) offerReceivedRecord <- holderSvc.receiveCredentialOffer(offerCredential) @@ -517,7 +509,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS requestGeneratedRecord <- holderSvc.generateJWTCredentialRequest(offerReceivedRecord.id) // Holder sends offer _ <- holderSvc.markRequestSent(holderRecordId) - msg <- ZIO.fromEither(requestGeneratedRecord.requestCredentialData.get.makeMessage.asJson.as[Message]) + msg <- ZIO.fromEither(requestGeneratedRecord.requestCredentialData.get.makeMessage.toJson.fromJson[Message]) // Issuer receives request requestCredential <- ZIO.fromEither(RequestCredential.readFromMessage(msg)) requestReceivedRecord <- issuerSvc.receiveCredentialRequest(requestCredential) @@ -536,7 +528,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS } // Issuer sends credential _ <- issuerSvc.markCredentialSent(issuerRecordId) - msg <- ZIO.fromEither(credentialGenerateRecord.issueCredentialData.get.makeMessage.asJson.as[Message]) + msg <- ZIO.fromEither(credentialGenerateRecord.issueCredentialData.get.makeMessage.toJson.fromJson[Message]) // Holder receives credential issueCredential <- ZIO.fromEither(IssueCredential.readFromMessage(msg)) _ <- holderSvc.receiveCredentialIssue(issueCredential) @@ -560,7 +552,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS issuerRecordId = offerCreatedRecord.id // Issuer sends offer _ <- issuerSvc.markOfferSent(issuerRecordId) - msg <- ZIO.fromEither(offerCreatedRecord.offerCredentialData.get.makeMessage.asJson.as[Message]) + msg <- ZIO.fromEither(offerCreatedRecord.offerCredentialData.get.makeMessage.toJson.fromJson[Message]) // Holder receives offer offerCredential <- ZIO.fromEither(OfferCredential.readFromMessage(msg)) offerReceivedRecord <- holderSvc.receiveCredentialOffer(offerCredential) @@ -572,7 +564,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS requestGeneratedRecord <- holderSvc.generateJWTCredentialRequest(offerReceivedRecord.id) // Holder sends offer _ <- holderSvc.markRequestSent(holderRecordId) - msg <- ZIO.fromEither(requestGeneratedRecord.requestCredentialData.get.makeMessage.asJson.as[Message]) + msg <- ZIO.fromEither(requestGeneratedRecord.requestCredentialData.get.makeMessage.toJson.fromJson[Message]) // Issuer receives request requestCredential <- ZIO.fromEither(RequestCredential.readFromMessage(msg)) requestReceivedRecord <- issuerSvc.receiveCredentialRequest(requestCredential) @@ -591,7 +583,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS } // Issuer sends credential _ <- issuerSvc.markCredentialSent(issuerRecordId) - msg <- ZIO.fromEither(credentialGenerateRecord.issueCredentialData.get.makeMessage.asJson.as[Message]) + msg <- ZIO.fromEither(credentialGenerateRecord.issueCredentialData.get.makeMessage.toJson.fromJson[Message]) // Holder receives credential issueCredential <- ZIO.fromEither(IssueCredential.readFromMessage(msg)) _ <- holderSvc.receiveCredentialIssue(issueCredential) @@ -640,7 +632,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS issuerRecordId = offerCreatedRecord.id // Issuer sends offer _ <- issuerSvc.markOfferSent(issuerRecordId) - msg <- ZIO.fromEither(offerCreatedRecord.offerCredentialData.get.makeMessage.asJson.as[Message]) + msg <- ZIO.fromEither(offerCreatedRecord.offerCredentialData.get.makeMessage.toJson.fromJson[Message]) // Holder receives offer holderCredDefResolverLayer = ZLayer.succeed( Map(s"http://test.com/cred-defs/${credDef.guid.toString}" -> credDef.definition.toString) @@ -661,7 +653,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS requestGeneratedRecord <- holderSvc.generateAnonCredsCredentialRequest(offerReceivedRecord.id) // Holder sends offer _ <- holderSvc.markRequestSent(holderRecordId) - msg <- ZIO.fromEither(requestGeneratedRecord.requestCredentialData.get.makeMessage.asJson.as[Message]) + msg <- ZIO.fromEither(requestGeneratedRecord.requestCredentialData.get.makeMessage.toJson.fromJson[Message]) // Issuer receives request requestCredential <- ZIO.fromEither(RequestCredential.readFromMessage(msg)) _ <- issuerSvc.receiveCredentialRequest(requestCredential) @@ -671,7 +663,7 @@ object CredentialServiceImplSpec extends MockSpecDefault with CredentialServiceS credentialGenerateRecord <- issuerSvc.generateAnonCredsCredential(issuerRecordId) // Issuer sends credential _ <- issuerSvc.markCredentialSent(issuerRecordId) - msg <- ZIO.fromEither(credentialGenerateRecord.issueCredentialData.get.makeMessage.asJson.as[Message]) + msg <- ZIO.fromEither(credentialGenerateRecord.issueCredentialData.get.makeMessage.toJson.fromJson[Message]) // Holder receives credential\ issueCredential <- ZIO.fromEither(IssueCredential.readFromMessage(msg)) record <- holderSvc.receiveCredentialIssue(issueCredential) diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceSpecHelper.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceSpecHelper.scala index 4d872c31b1..78202e7662 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceSpecHelper.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceSpecHelper.scala @@ -1,6 +1,5 @@ package org.hyperledger.identus.pollux.core.service -import io.circe.Json import org.hyperledger.identus.agent.walletapi.memory.GenericSecretStorageInMemory import org.hyperledger.identus.agent.walletapi.service.ManagedDIDService import org.hyperledger.identus.castor.core.model.did.PrismDID @@ -20,6 +19,8 @@ import org.hyperledger.identus.shared.http.UriResolver import org.hyperledger.identus.shared.messaging.{MessagingService, MessagingServiceConfig, WalletIdAndRecordId} import org.hyperledger.identus.shared.models.{KeyId, WalletAccessContext, WalletId} import zio.* +import zio.json.ast.Json +import zio.json.DecoderOps import java.util.UUID @@ -111,8 +112,7 @@ trait CredentialServiceSpecHelper { pairwiseHolderDID: Option[DidId] = Some(DidId("did:prism:holder-pairwise")), thid: DidCommID = DidCommID(), maybeSchemaIds: Option[List[String]] = None, - claims: Json = io.circe.parser - .parse(""" + claims: Json = """ |{ | "name":"Alice", | "address": { @@ -120,8 +120,7 @@ trait CredentialServiceSpecHelper { | "number": "12" | } |} - |""".stripMargin) - .getOrElse(Json.Null), + |""".stripMargin.fromJson[Json].toOption.getOrElse(Json.Null), validityPeriod: Option[Double] = None, automaticIssuance: Option[Boolean] = None, kidIssuer: Option[KeyId] = None @@ -151,8 +150,7 @@ trait CredentialServiceSpecHelper { pairwiseIssuerDID: DidId = DidId("did:prism:issuer"), pairwiseHolderDID: Option[DidId] = Some(DidId("did:prism:holder-pairwise")), thid: DidCommID = DidCommID(), - claims: Json = io.circe.parser - .parse(""" + claims: Json = """ |{ | "emailAddress": "alice@wonderland.com", | "familyName": "Wonderland", @@ -160,8 +158,7 @@ trait CredentialServiceSpecHelper { | "drivingLicenseID": "12345", | "drivingClass": "3" |} - |""".stripMargin) - .getOrElse(Json.Null), + |""".stripMargin.fromJson[Json].toOption.getOrElse(Json.Null), validityPeriod: Option[Double] = None, automaticIssuance: Option[Boolean] = None, credentialDefinitionId: String = "http://test.com/cred-def/1234", diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala index eff67638bc..ab8811d7ed 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala @@ -1,6 +1,5 @@ package org.hyperledger.identus.pollux.core.service -import io.circe.Json import org.hyperledger.identus.castor.core.model.did.{CanonicalPrismDID, PrismDID, VerificationRelationship} import org.hyperledger.identus.mercury.model.DidId import org.hyperledger.identus.mercury.protocol.issuecredential.{IssueCredential, OfferCredential, RequestCredential} @@ -9,7 +8,8 @@ import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError.* import org.hyperledger.identus.pollux.vc.jwt.Issuer import org.hyperledger.identus.shared.models.* -import zio.{mock, Duration, IO, UIO, URIO, URLayer, ZIO, ZLayer} +import zio.json.ast.Json +import zio.{Duration, IO, UIO, URIO, URLayer, ZIO, ZLayer, mock} import zio.mock.{Mock, Proxy} import java.util.UUID diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpec.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpec.scala index 981a187601..62dba5cbbe 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpec.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpec.scala @@ -1,20 +1,15 @@ package org.hyperledger.identus.pollux.core.service -import io.circe.parser.decode -import io.circe.syntax.* import org.hyperledger.identus.agent.walletapi.storage.GenericSecretStorage import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, Base64, DidId} import org.hyperledger.identus.mercury.protocol.issuecredential.{IssueCredential, IssueCredentialIssuedFormat} import org.hyperledger.identus.mercury.protocol.presentproof.* import org.hyperledger.identus.pollux.anoncreds.* import org.hyperledger.identus.pollux.core.model.* -import org.hyperledger.identus.pollux.core.model.error.PresentationError import org.hyperledger.identus.pollux.core.model.error.PresentationError.* import org.hyperledger.identus.pollux.core.model.presentation.Options import org.hyperledger.identus.pollux.core.model.schema.CredentialDefinition.Input import org.hyperledger.identus.pollux.core.model.secret.CredentialDefinitionSecret -import org.hyperledger.identus.pollux.core.model.IssueCredentialRecord.* -import org.hyperledger.identus.pollux.core.model.PresentationRecord.* import org.hyperledger.identus.pollux.core.repository.{CredentialRepository, PresentationRepository} import org.hyperledger.identus.pollux.core.service.serdes.{ AnoncredCredentialProofV1, @@ -22,9 +17,9 @@ import org.hyperledger.identus.pollux.core.service.serdes.{ AnoncredPresentationRequestV1, AnoncredPresentationV1 } -import org.hyperledger.identus.pollux.vc.jwt.* import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} import zio.* +import zio.json.{DecoderOps, EncoderOps} import zio.test.* import zio.test.Assertion.* @@ -96,10 +91,11 @@ object PresentationServiceSpec extends ZIOSpecDefault with PresentationServiceSp val maybePresentationOptions = record.requestPresentationData.get.attachments.headOption .map(attachment => - decode[org.hyperledger.identus.mercury.model.JsonData](attachment.data.asJson.noSpaces) + attachment.data.toJson + .fromJson[org.hyperledger.identus.mercury.model.JsonData] .flatMap(data => - org.hyperledger.identus.pollux.core.model.presentation.PresentationAttachment.given_Decoder_PresentationAttachment - .decodeJson(data.json.asJson) + org.hyperledger.identus.pollux.core.model.presentation.PresentationAttachment.given_JsonDecoder_PresentationAttachment + .decodeJson(data.json.toJson) .map(_.options) ) ) @@ -880,8 +876,7 @@ object PresentationServiceSpec extends ZIOSpecDefault with PresentationServiceSp requestCredentialData = None, anonCredsRequestMetadata = None, issueCredentialData = Some(issueCredential), - issuedCredentialRaw = - Some(issueCredential.attachments.map(_.data.asJson.noSpaces).headOption.getOrElse("???")), + issuedCredentialRaw = Some(issueCredential.attachments.map(_.data.toJson).headOption.getOrElse("???")), issuingDID = None, metaRetries = 5, metaNextRetry = Some(Instant.now()), diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/uriResolvers/DidUrlResolverSpec.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/uriResolvers/DidUrlResolverSpec.scala index 8d24db9ec9..3527948e64 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/uriResolvers/DidUrlResolverSpec.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/uriResolvers/DidUrlResolverSpec.scala @@ -1,14 +1,14 @@ package org.hyperledger.identus.pollux.core.service.uriResolvers -import io.circe.* import io.lemonlabs.uri.Url import org.hyperledger.identus.pollux.vc.jwt.* import org.hyperledger.identus.shared.crypto.Sha256Hash -import org.hyperledger.identus.shared.json.Json as JsonUtils +import org.hyperledger.identus.shared.json.{Json as JsonUtils, JsonInterop} import org.hyperledger.identus.shared.models.PrismEnvelopeData import org.hyperledger.identus.shared.utils.Base64Utils import zio.* import zio.json.* +import zio.json.ast.Json import zio.test.* import zio.test.Assertion.* @@ -155,7 +155,7 @@ object DidUrlResolverSpec extends ZIOSpecDefault { Service( id = "did:prism:462c4811bf61d7de25b3baf86c5d2f0609b4debe53792d297bf612269bf8593a#agent-base-url", `type` = "LinkedResourceV1", - serviceEndpoint = Json.fromString("https://agent-url.com") + serviceEndpoint = JsonInterop.toCirceJsonAst(Json.Str("https://agent-url.com")) ) ) ), diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImplSpec.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImplSpec.scala index 25daf11202..8f42b8aa32 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImplSpec.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImplSpec.scala @@ -1,14 +1,15 @@ package org.hyperledger.identus.pollux.core.service.verification -import io.circe.* -import io.circe.syntax.* +import io.circe.syntax.EncoderOps import org.hyperledger.identus.agent.walletapi.service.MockManagedDIDService import org.hyperledger.identus.castor.core.service.MockDIDService import org.hyperledger.identus.pollux.core.service.uriResolvers.ResourceUrlResolver import org.hyperledger.identus.pollux.vc.jwt.* import org.hyperledger.identus.pollux.vc.jwt.CredentialPayload.Implicits.* +import org.hyperledger.identus.shared.json.JsonInterop import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} import zio.* +import zio.json.ast.Json import zio.test.* import zio.Config.OffsetDateTime @@ -38,10 +39,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -103,10 +106,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -168,10 +173,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -233,10 +240,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -305,10 +314,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -374,10 +385,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Alice"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("alice@wonderland.com") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Alice"), + "age" -> Json.Num(42), + "email" -> Json.Str("alice@wonderland.com") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -449,13 +462,15 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS ) ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Alice"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("alice@wonderland.com"), - "dateOfIssuance" -> Json.fromString("2000-01-01T10:00:00Z"), - "drivingLicenseID" -> Json.fromInt(12345), - "drivingClass" -> Json.fromString("5") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Alice"), + "age" -> Json.Num(42), + "email" -> Json.Str("alice@wonderland.com"), + "dateOfIssuance" -> Json.Str("2000-01-01T10:00:00Z"), + "drivingLicenseID" -> Json.Num(12345), + "drivingClass" -> Json.Str("5") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -527,13 +542,15 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS ) ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Alice"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("alice@wonderland.com"), - "dateOfIssuance" -> Json.fromString("2000-01-01T10:00:00Z"), - "drivingLicenseID" -> Json.fromInt(12345), - "drivingClass" -> Json.fromInt(5) + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Alice"), + "age" -> Json.Num(42), + "email" -> Json.Str("alice@wonderland.com"), + "dateOfIssuance" -> Json.Str("2000-01-01T10:00:00Z"), + "drivingLicenseID" -> Json.Num(12345), + "drivingClass" -> Json.Num(5) + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -600,10 +617,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -666,10 +685,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -732,10 +753,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) ), maybeCredentialStatus = Some( CredentialStatus( @@ -798,10 +821,12 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) ), maybeCredentialStatus = Some( CredentialStatus( diff --git a/shared/core/src/main/scala/org/hyperledger/identus/shared/messaging/MessagingService.scala b/shared/core/src/main/scala/org/hyperledger/identus/shared/messaging/MessagingService.scala index 3ef20e3dd9..838d213345 100644 --- a/shared/core/src/main/scala/org/hyperledger/identus/shared/messaging/MessagingService.scala +++ b/shared/core/src/main/scala/org/hyperledger/identus/shared/messaging/MessagingService.scala @@ -83,7 +83,6 @@ object MessagingService { vSerde: Serde[V] ): RLayer[Scope & MessagingService, Producer[K, V]] = ZLayer.fromZIO(for { messagingService <- ZIO.service[MessagingService] - _ <- ZIO.logInfo("Producer layer invoked!!") producer <- messagingService.makeProducer[K, V]() } yield producer) From 94a515a05f9b5fa43d9e753c72f58a3a32488094 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Fri, 29 Nov 2024 17:39:25 +0100 Subject: [PATCH 16/22] feat: migrate pollux-sql-doobie Signed-off-by: Benjamin Voiturier --- .../core/model/PresentationRecord.scala | 2 +- .../PresentationRepositoryInMemory.scala | 1 - .../repository/JdbcCredentialRepository.scala | 20 ++++----- .../JdbcPresentationRepository.scala | 42 ++++--------------- .../identus/shared/db/ContextAwareTask.scala | 18 ++++++++ 5 files changed, 35 insertions(+), 48 deletions(-) diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/PresentationRecord.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/PresentationRecord.scala index 88c03788de..6a737dcdc0 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/PresentationRecord.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/PresentationRecord.scala @@ -9,7 +9,7 @@ import java.time.temporal.ChronoUnit import java.time.Instant type AnoncredCredentialProofs = zio.json.ast.Json -type SdJwtCredentialToDisclose = zio.json.ast.Json.Obj +type SdJwtCredentialToDisclose = zio.json.ast.Json final case class PresentationRecord( id: DidCommID, diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala index c858330e01..b058da5cae 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationRepositoryInMemory.scala @@ -7,7 +7,6 @@ import org.hyperledger.identus.shared.db.Implicits.* import org.hyperledger.identus.shared.models.* import zio.* import zio.json.* -import zio.json.ast.Json import java.time.Instant diff --git a/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcCredentialRepository.scala b/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcCredentialRepository.scala index 53a3296dc3..6607329ff2 100644 --- a/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcCredentialRepository.scala +++ b/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcCredentialRepository.scala @@ -5,9 +5,6 @@ import doobie.* import doobie.free.connection import doobie.implicits.* import doobie.postgres.implicits.* -import io.circe.* -import io.circe.parser.* -import io.circe.syntax.* import org.hyperledger.identus.castor.core.model.did.* import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation import org.hyperledger.identus.mercury.protocol.issuecredential.{IssueCredential, OfferCredential, RequestCredential} @@ -22,7 +19,6 @@ import zio.interop.catz.* import zio.json.* import java.time.Instant -import java.util.UUID class JdbcCredentialRepository(xa: Transactor[ContextAwareTask], xb: Transactor[Task], maxRetries: Int) extends CredentialRepository { @@ -41,20 +37,20 @@ class JdbcCredentialRepository(xa: Transactor[ContextAwareTask], xb: Transactor[ given rolePut: Put[Role] = Put[String].contramap(_.toString) given offerCredentialGet: Get[OfferCredential] = - Get[String].map(decode[OfferCredential](_).getOrElse(UnexpectedCodeExecutionPath)) - given offerCredentialPut: Put[OfferCredential] = Put[String].contramap(_.asJson.toString) + Get[String].map(_.fromJson[OfferCredential].getOrElse(UnexpectedCodeExecutionPath)) + given offerCredentialPut: Put[OfferCredential] = Put[String].contramap(_.toJson) given requestCredentialGet: Get[RequestCredential] = - Get[String].map(decode[RequestCredential](_).getOrElse(UnexpectedCodeExecutionPath)) - given requestCredentialPut: Put[RequestCredential] = Put[String].contramap(_.asJson.toString) + Get[String].map(_.fromJson[RequestCredential].getOrElse(UnexpectedCodeExecutionPath)) + given requestCredentialPut: Put[RequestCredential] = Put[String].contramap(_.toJson) given acRequestMetadataGet: Get[AnoncredCredentialRequestMetadata] = Get[String].map(_.fromJson[AnoncredCredentialRequestMetadata].getOrElse(UnexpectedCodeExecutionPath)) given acRequestMetadataPut: Put[AnoncredCredentialRequestMetadata] = Put[String].contramap(_.toJson) given issueCredentialGet: Get[IssueCredential] = - Get[String].map(decode[IssueCredential](_).getOrElse(UnexpectedCodeExecutionPath)) - given issueCredentialPut: Put[IssueCredential] = Put[String].contramap(_.asJson.toString) + Get[String].map(_.fromJson[IssueCredential].getOrElse(UnexpectedCodeExecutionPath)) + given issueCredentialPut: Put[IssueCredential] = Put[String].contramap(_.toJson) given keyIdGet: Get[KeyId] = Get[String].map(KeyId(_)) given keyIdPut: Put[KeyId] = Put[String].contramap(_.value) @@ -62,8 +58,8 @@ class JdbcCredentialRepository(xa: Transactor[ContextAwareTask], xb: Transactor[ given failureGet: Get[Failure] = Get[String].temap(_.fromJson[FailureInfo]) given failurePut: Put[Failure] = Put[String].contramap(_.asFailureInfo.toJson) - given invitationGet: Get[Invitation] = Get[String].map(decode[Invitation](_).getOrElse(UnexpectedCodeExecutionPath)) - given invitationPut: Put[Invitation] = Put[String].contramap(_.asJson.toString) + given invitationGet: Get[Invitation] = Get[String].map(_.fromJson[Invitation].getOrElse(UnexpectedCodeExecutionPath)) + given invitationPut: Put[Invitation] = Put[String].contramap(_.toJson) override def create(record: IssueCredentialRecord): URIO[WalletAccessContext, Unit] = { val cxnIO = sql""" diff --git a/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationRepository.scala b/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationRepository.scala index 71b4cad3dc..db5d2c9002 100644 --- a/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationRepository.scala +++ b/pollux/sql-doobie/src/main/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationRepository.scala @@ -4,13 +4,7 @@ import cats.data.NonEmptyList import doobie.* import doobie.free.connection import doobie.implicits.* -import doobie.postgres.* -import doobie.postgres.circe.json.implicits.* import doobie.postgres.implicits.* -import io.circe -import io.circe.* -import io.circe.parser.* -import io.circe.syntax.* import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation import org.hyperledger.identus.mercury.protocol.presentproof.* import org.hyperledger.identus.pollux.core.model.* @@ -21,8 +15,6 @@ import org.hyperledger.identus.shared.models.* import zio.* import zio.interop.catz.* import zio.json.* -import zio.json.ast.Json -import zio.json.ast.Json.* import java.time.Instant import java.util.UUID @@ -116,24 +108,6 @@ class JdbcPresentationRepository( // given logHandler: LogHandler = LogHandler.jdkLogHandler import PresentationRecord.* - def zioJsonToCirceJson(zioJson: Json): circe.Json = { - parse(zioJson.toString).getOrElse(circe.Json.Null) - } - - def circeJsonToZioJson(circeJson: circe.Json): Json = { - circeJson.noSpaces.fromJson[Json].getOrElse(Json.Null) - } - - given jsonGet: Get[AnoncredCredentialProofs] = Get[circe.Json].map { jsonString => circeJsonToZioJson(jsonString) } - given jsonPut: Put[AnoncredCredentialProofs] = Put[circe.Json].contramap(zioJsonToCirceJson(_)) - - def zioJsonToCirceJsonObj(zioJson: Json.Obj): circe.Json = - parse(zioJson.toString).getOrElse(circe.Json.Null) - def circeJsonToZioJsonObj(circeJson: circe.Json): Json.Obj = - circeJson.noSpaces.fromJson[Json.Obj].getOrElse(Json.Obj()) - given Get[SdJwtCredentialToDisclose] = Get[circe.Json].map { jsonString => circeJsonToZioJsonObj(jsonString) } - given Put[SdJwtCredentialToDisclose] = Put[circe.Json].contramap(zioJsonToCirceJsonObj(_)) - given didCommIDGet: Get[DidCommID] = Get[String].map(DidCommID(_)) given didCommIDPut: Put[DidCommID] = Put[String].contramap(_.value) @@ -152,16 +126,16 @@ class JdbcPresentationRepository( given rolePut: Put[Role] = Put[String].contramap(_.toString) given presentationGet: Get[Presentation] = - Get[String].map(decode[Presentation](_).getOrElse(UnexpectedCodeExecutionPath)) - given presentationPut: Put[Presentation] = Put[String].contramap(_.asJson.toString) + Get[String].map(_.fromJson[Presentation].getOrElse(UnexpectedCodeExecutionPath)) + given presentationPut: Put[Presentation] = Put[String].contramap(_.toJson) given requestPresentationGet: Get[RequestPresentation] = - Get[String].map(decode[RequestPresentation](_).getOrElse(UnexpectedCodeExecutionPath)) - given requestPresentationPut: Put[RequestPresentation] = Put[String].contramap(_.asJson.toString) + Get[String].map(_.fromJson[RequestPresentation].getOrElse(UnexpectedCodeExecutionPath)) + given requestPresentationPut: Put[RequestPresentation] = Put[String].contramap(_.toJson) given proposePresentationGet: Get[ProposePresentation] = - Get[String].map(decode[ProposePresentation](_).getOrElse(UnexpectedCodeExecutionPath)) - given proposePresentationPut: Put[ProposePresentation] = Put[String].contramap(_.asJson.toString) + Get[String].map(_.fromJson[ProposePresentation].getOrElse(UnexpectedCodeExecutionPath)) + given proposePresentationPut: Put[ProposePresentation] = Put[String].contramap(_.toJson) given failureGet: Get[Failure] = Get[String].temap(_.fromJson[FailureInfo]) given failurePut: Put[Failure] = Put[String].contramap(_.asFailureInfo.toJson) @@ -169,8 +143,8 @@ class JdbcPresentationRepository( given walletIdGet: Get[WalletId] = Get[UUID].map(id => WalletId.fromUUID(id)) given walletIdPut: Put[WalletId] = Put[UUID].contramap[WalletId](_.toUUID) - given invitationGet: Get[Invitation] = Get[String].map(decode[Invitation](_).getOrElse(UnexpectedCodeExecutionPath)) - given invitationPut: Put[Invitation] = Put[String].contramap(_.asJson.toString) + given invitationGet: Get[Invitation] = Get[String].map(_.fromJson[Invitation].getOrElse(UnexpectedCodeExecutionPath)) + given invitationPut: Put[Invitation] = Put[String].contramap(_.toJson) override def createPresentationRecord(record: PresentationRecord): URIO[WalletAccessContext, Unit] = { diff --git a/shared/core/src/main/scala/org/hyperledger/identus/shared/db/ContextAwareTask.scala b/shared/core/src/main/scala/org/hyperledger/identus/shared/db/ContextAwareTask.scala index 5ffc1e0a90..2fc3e67271 100644 --- a/shared/core/src/main/scala/org/hyperledger/identus/shared/db/ContextAwareTask.scala +++ b/shared/core/src/main/scala/org/hyperledger/identus/shared/db/ContextAwareTask.scala @@ -1,12 +1,17 @@ package org.hyperledger.identus.shared.db +import cats.data.NonEmptyList +import cats.Show import doobie.* import doobie.postgres.implicits.* import doobie.syntax.ConnectionIOOps import doobie.util.transactor.Transactor import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} +import org.postgresql.util.PGobject import zio.* import zio.interop.catz.* +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json import java.util.UUID @@ -19,6 +24,19 @@ object Errors { object Implicits { + private implicit val showPGobject: Show[PGobject] = Show.show(_.getValue.take(250)) + implicit val jsonPut: Put[Json] = Put.Advanced + .other[PGobject](NonEmptyList.of("json")) + .tcontramap[Json] { a => + val o = new PGobject + o.setType("json") + o.setValue(a.toJson) + o + } + implicit val jsonGet: Get[Json] = Get.Advanced + .other[PGobject](NonEmptyList.of("json")) + .temap[Json](a => a.getValue.fromJson[Json]) + given walletIdGet: Get[WalletId] = Get[UUID].map(WalletId.fromUUID) given walletIdPut: Put[WalletId] = Put[UUID].contramap(_.toUUID) From f5402233f7c659a2ba4a8c8eb2f5bce1a9c32741 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Tue, 3 Dec 2024 10:50:49 +0100 Subject: [PATCH 17/22] feat: migrate cloud-agent-server Signed-off-by: Benjamin Voiturier --- .../server/http/ZHttp4sBlazeServer.scala | 11 +++---- .../server/jobs/PresentBackgroundJobs.scala | 19 ++++-------- .../agent/server/jobs/StatusListJobs.scala | 9 +++--- .../controller/IssueControllerImpl.scala | 13 ++++----- .../service/OIDCCredentialIssuerService.scala | 29 +++++++++---------- .../controller/http/PresentationStatus.scala | 3 +- .../VcVerificationControllerImplSpec.scala | 18 ++++++------ 7 files changed, 45 insertions(+), 57 deletions(-) diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/http/ZHttp4sBlazeServer.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/http/ZHttp4sBlazeServer.scala index bb15ac4648..cf37daefe0 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/http/ZHttp4sBlazeServer.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/http/ZHttp4sBlazeServer.scala @@ -1,8 +1,5 @@ package org.hyperledger.identus.agent.server.http -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.syntax.* import io.micrometer.prometheusmetrics.PrometheusMeterRegistry import org.http4s.* import org.http4s.blaze.server.BlazeServerBuilder @@ -18,6 +15,7 @@ import sttp.tapir.server.metrics.MetricLabels import sttp.tapir.ztapir.ZServerEndpoint import zio.* import zio.interop.catz.* +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} class ZHttp4sBlazeServer(micrometerRegistry: PrometheusMeterRegistry, metricsNamespace: String) { @@ -34,9 +32,8 @@ class ZHttp4sBlazeServer(micrometerRegistry: PrometheusMeterRegistry, metricsNam secChUaPlatform: Option[String], ) object FingerPrintData { - given encoder: Encoder[FingerPrintData] = deriveEncoder[FingerPrintData] - - given decoder: Decoder[FingerPrintData] = deriveDecoder[FingerPrintData] + given encoder: JsonEncoder[FingerPrintData] = DeriveJsonEncoder.gen + given decoder: JsonDecoder[FingerPrintData] = DeriveJsonDecoder.gen } val headers = sr.headers @@ -52,7 +49,7 @@ class ZHttp4sBlazeServer(micrometerRegistry: PrometheusMeterRegistry, metricsNam headers.find(_.name.toLowerCase == "sec-ch-ua-platform").map(_.value), ) - val jsonStr = fingerPrintData.asJson.dropNullValues.spaces2 + val jsonStr = fingerPrintData.toJson val canonicalized = Json.canonicalizeToJcs(jsonStr).toOption canonicalized.map(x => Sha256Hash.compute(x.getBytes)) diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala index a6f2bfae67..7a1ba2aff1 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala @@ -1,14 +1,8 @@ package org.hyperledger.identus.agent.server.jobs import cats.syntax.all.* -import io.circe.parser.* -import io.circe.syntax.* import org.hyperledger.identus.agent.server.config.AppConfig -import org.hyperledger.identus.agent.server.jobs.BackgroundJobError.{ - ErrorResponseReceivedFromPeerAgent, - InvalidState, - NotImplemented -} +import org.hyperledger.identus.agent.server.jobs.BackgroundJobError.{ErrorResponseReceivedFromPeerAgent, InvalidState, NotImplemented} import org.hyperledger.identus.agent.walletapi.model.error.{DIDSecretStorageError, GetManagedDIDError} import org.hyperledger.identus.agent.walletapi.service.ManagedDIDService import org.hyperledger.identus.agent.walletapi.storage.DIDNonSecretStorage @@ -27,7 +21,7 @@ import org.hyperledger.identus.pollux.core.model.presentation.Options import org.hyperledger.identus.pollux.core.service.{CredentialService, PresentationService} import org.hyperledger.identus.pollux.core.service.serdes.AnoncredCredentialProofsV1 import org.hyperledger.identus.pollux.sdjwt.{HolderPrivateKey, IssuerPublicKey, PresentationCompact, SDJWT} -import org.hyperledger.identus.pollux.vc.jwt.{DidResolver as JwtDidResolver, Issuer as JwtIssuer, JWT, JwtPresentation} +import org.hyperledger.identus.pollux.vc.jwt.{JWT, JwtPresentation, DidResolver as JwtDidResolver, Issuer as JwtIssuer} import org.hyperledger.identus.pollux.vc.jwt.CredentialSchemaAndTrustedIssuersConstraint import org.hyperledger.identus.resolvers.DIDResolver import org.hyperledger.identus.shared.http.* @@ -37,6 +31,7 @@ import org.hyperledger.identus.shared.models.{Failure, *} import org.hyperledger.identus.shared.utils.aspects.CustomMetricsAspect import org.hyperledger.identus.shared.utils.DurationOps.toMetricsSeconds import zio.* +import zio.json.{DecoderOps, EncoderOps} import zio.metrics.* import zio.prelude.{Validation, ZValidation} import zio.prelude.ZValidation.{Failure as ZFailure, *} @@ -1105,13 +1100,11 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { val maybePresentationOptions: Either[PresentationError, Option[Options]] = requestPresentation.attachments.headOption .map(attachment => - decode[JsonData]( - attachment.data.asJson.noSpaces - ) + attachment.data.toJson.fromJson[JsonData] .leftMap(err => PresentationDecodingError(s"JsonData decoding error: $err")) .flatMap(data => - org.hyperledger.identus.pollux.core.model.presentation.PresentationAttachment.given_Decoder_PresentationAttachment - .decodeJson(data.json.asJson) + org.hyperledger.identus.pollux.core.model.presentation.PresentationAttachment.given_JsonDecoder_PresentationAttachment + .decodeJson(data.json.toJson) .map(_.options) .leftMap(err => PresentationDecodingError(s"PresentationAttachment decoding error: $err")) ) diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/StatusListJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/StatusListJobs.scala index 1fe5d77551..9ef4c91468 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/StatusListJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/StatusListJobs.scala @@ -10,11 +10,14 @@ import org.hyperledger.identus.pollux.core.model.{CredInStatusList, CredentialSt import org.hyperledger.identus.pollux.core.service.{CredentialService, CredentialStatusListService} import org.hyperledger.identus.pollux.vc.jwt.revocation.{BitString, VCStatusList2021, VCStatusList2021Error} import org.hyperledger.identus.resolvers.DIDResolver +import org.hyperledger.identus.shared.json.JsonInterop import org.hyperledger.identus.shared.messaging import org.hyperledger.identus.shared.messaging.{Message, Producer, WalletIdAndRecordId} import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} import org.hyperledger.identus.shared.utils.DurationOps.toMetricsSeconds import zio.* +import zio.json.DecoderOps +import zio.json.ast.Json import zio.metrics.Metric import java.util.UUID @@ -72,12 +75,10 @@ object StatusListJobs extends BackgroundJobsHelper { vcStatusListCredString = statusListWithCreds.statusListCredential walletAccessContext = WalletAccessContext(statusListWithCreds.walletId) effect = for { - vcStatusListCredJson <- ZIO - .fromEither(io.circe.parser.parse(vcStatusListCredString)) - .mapError(_.underlying) + vcStatusListCredJson <- ZIO.fromEither(vcStatusListCredString.fromJson[Json]) issuer <- createJwtVcIssuer(statusListWithCreds.issuer, VerificationRelationship.AssertionMethod, None) vcStatusListCred <- VCStatusList2021 - .decodeFromJson(vcStatusListCredJson, issuer) + .decodeFromJson(JsonInterop.toCirceJsonAst(vcStatusListCredJson), issuer) .mapError(x => new Throwable(x.msg)) bitString <- vcStatusListCred.getBitString.mapError(x => new Throwable(x.msg)) _ <- ZIO.collectAll( diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/issue/controller/IssueControllerImpl.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/issue/controller/IssueControllerImpl.scala index 69cfc710bf..52b3fe1c60 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/issue/controller/IssueControllerImpl.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/issue/controller/IssueControllerImpl.scala @@ -55,10 +55,9 @@ class IssueControllerImpl( ) for { - jsonClaims <- ZIO // TODO: Get read of Circe and use zio-json all the way down - .fromEither(io.circe.parser.parse(request.claims.toString())) - .mapError(e => ErrorResponse.badRequest(detail = Some(e.getMessage))) - credentialFormat = request.credentialFormat.map(CredentialFormat.valueOf).getOrElse(CredentialFormat.JWT) + credentialFormat <- ZIO.succeed( + request.credentialFormat.map(CredentialFormat.valueOf).getOrElse(CredentialFormat.JWT) + ) outcome <- credentialFormat match case JWT => @@ -75,7 +74,7 @@ class IssueControllerImpl( case schemaId: String => List(schemaId) case schemaIds: List[String] => schemaIds }, - claims = jsonClaims, + claims = request.claims, validityPeriod = request.validityPeriod, automaticIssuance = request.automaticIssuance.orElse(Some(true)), issuingDID = issuingDID.asCanonical, @@ -99,7 +98,7 @@ class IssueControllerImpl( case schemaId: String => List(schemaId) case schemaIds: List[String] => schemaIds }, - claims = jsonClaims, + claims = request.claims, validityPeriod = request.validityPeriod, automaticIssuance = request.automaticIssuance.orElse(Some(true)), issuingDID = issuingDID.asCanonical, @@ -160,7 +159,7 @@ class IssueControllerImpl( thid = DidCommID(), credentialDefinitionGUID = credentialDefinitionGUID, credentialDefinitionId = credentialDefinitionId, - claims = jsonClaims, + claims = request.claims, validityPeriod = request.validityPeriod, automaticIssuance = request.automaticIssuance.orElse(Some(true)), goalCode = offerContext.goalCode, diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/service/OIDCCredentialIssuerService.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/service/OIDCCredentialIssuerService.scala index 340dda1622..4e8b4c47a6 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/service/OIDCCredentialIssuerService.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/oid4vci/service/OIDCCredentialIssuerService.scala @@ -1,7 +1,5 @@ package org.hyperledger.identus.oid4vci.service -import io.circe.parser.parse -import io.circe.Json import org.hyperledger.identus.agent.walletapi.storage.DIDNonSecretStorage import org.hyperledger.identus.castor.core.model.did.{DID, DIDUrl, PrismDID, VerificationRelationship} import org.hyperledger.identus.oid4vci.domain.{IssuanceSession, Openid4VCIProofJwtOps} @@ -23,8 +21,11 @@ import org.hyperledger.identus.pollux.vc.jwt.{ * } import org.hyperledger.identus.shared.http.UriResolver +import org.hyperledger.identus.shared.json.JsonInterop import org.hyperledger.identus.shared.models.* import zio.* +import zio.json.ast.Json +import zio.json.EncoderOps import java.net.{URI, URL} import java.time.Instant @@ -48,7 +49,7 @@ trait OIDCCredentialIssuerService { def issueJwtCredential( issuingDID: PrismDID, subjectDID: Option[DID], - claims: zio.json.ast.Json, + claims: Json, credentialIdentifier: Option[String], credentialDefinition: CredentialDefinition, ): IO[Error, JWT] @@ -58,7 +59,7 @@ trait OIDCCredentialIssuerService { issuerId: UUID, credentialConfigurationId: String, issuingDID: PrismDID, - claims: zio.json.ast.Json, + claims: Json, ): ZIO[WalletAccessContext, Error, CredentialOffer] def getIssuanceSessionByIssuerState(issuerState: String): IO[Error, IssuanceSession] @@ -157,7 +158,7 @@ case class OIDCCredentialIssuerServiceImpl( override def issueJwtCredential( issuingDID: PrismDID, subjectDID: Option[DID], - claims: zio.json.ast.Json, + claims: Json, credentialIdentifier: Option[String], credentialDefinition: CredentialDefinition ): IO[Error, JWT] = { @@ -188,7 +189,7 @@ case class OIDCCredentialIssuerServiceImpl( subjectDid: Option[DID], credentialIdentifier: Option[String], credentialDefinition: CredentialDefinition, - claims: zio.json.ast.Json + claims: Json ): IO[Error, W3cCredentialPayload] = { val credential = W3cCredentialPayload( `@context` = Set( @@ -203,7 +204,7 @@ case class OIDCCredentialIssuerServiceImpl( issuanceDate = Instant.now(), maybeExpirationDate = None, // TODO: Add expiration date maybeCredentialSchema = None, // TODO: Add schema from schema registry - credentialSubject = buildCredentialSubject(subjectDid, claims), + credentialSubject = JsonInterop.toCirceJsonAst(buildCredentialSubject(subjectDid, claims)), maybeCredentialStatus = None, // TODO: Add credential status maybeRefreshService = None, // TODO: Add refresh service maybeEvidence = None, // TODO: Add evidence @@ -215,12 +216,8 @@ case class OIDCCredentialIssuerServiceImpl( ZIO.succeed(credential) // TODO: there might be other calls to fill the VC claims from the session, etc } - private def simpleZioToCirce(json: zio.json.ast.Json): Json = - parse(json.toString).toOption.get - - private def buildCredentialSubject(subjectDid: Option[DID], claims: zio.json.ast.Json): Json = { - val subjectClaims = simpleZioToCirce(claims) - subjectDid.fold(subjectClaims)(did => Json.obj("id" -> Json.fromString(did.toString)) deepMerge subjectClaims) + private def buildCredentialSubject(subjectDid: Option[DID], claims: Json): Json = { + subjectDid.fold(claims)(did => claims.asObject.get.add("id", Json.Str(did.toString))) } def issueJwtVC(issuer: Issuer, payload: W3cCredentialPayload): IO[Error, JWT] = { @@ -246,7 +243,7 @@ case class OIDCCredentialIssuerServiceImpl( issuerId: UUID, credentialConfigurationId: String, issuingDID: PrismDID, - claims: zio.json.ast.Json + claims: Json ): ZIO[WalletAccessContext, Error, CredentialOffer] = for { schemaId <- issuerMetadataService @@ -256,7 +253,7 @@ case class OIDCCredentialIssuerServiceImpl( } .map(_.schemaId) _ <- CredentialSchema - .validateJWTCredentialSubject(schemaId.toString(), simpleZioToCirce(claims).noSpaces, uriResolver) + .validateJWTCredentialSubject(schemaId.toString, claims.toJson, uriResolver) .mapError(e => CredentialSchemaError(e)) session <- buildNewIssuanceSession(issuerId, issuingDID, claims, schemaId) _ <- issuanceSessionStorage @@ -289,7 +286,7 @@ case class OIDCCredentialIssuerServiceImpl( private def buildNewIssuanceSession( issuerId: UUID, issuerDid: PrismDID, - claims: zio.json.ast.Json, + claims: Json, schemaId: URI ): UIO[IssuanceSession] = { for { diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatus.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatus.scala index 772c3f31a4..18e7f0ccfc 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatus.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/PresentationStatus.scala @@ -9,6 +9,7 @@ import org.hyperledger.identus.shared.models.{FailureInfo, StatusCode} import sttp.tapir.{Schema, Validator} import sttp.tapir.Schema.annotations.{description, encodedExample, validate} import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} +import zio.json.EncoderOps final case class PresentationStatus( @description(annotations.presentationId.description) @@ -89,7 +90,7 @@ object PresentationStatus { val base64Decoded = new String(java.util.Base64.getUrlDecoder.decode(data)) Seq(base64Decoded) case JsonData(jsonData) => - Seq(jsonData.toJson.toString) + Seq(jsonData.toJson) case any => FeatureNotImplemented } case None => Seq.empty diff --git a/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/verification/controller/VcVerificationControllerImplSpec.scala b/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/verification/controller/VcVerificationControllerImplSpec.scala index 2e75ce25a2..eb753af53e 100644 --- a/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/verification/controller/VcVerificationControllerImplSpec.scala +++ b/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/verification/controller/VcVerificationControllerImplSpec.scala @@ -1,15 +1,14 @@ package org.hyperledger.identus.verification.controller -import io.circe.* -import io.circe.syntax.* import org.hyperledger.identus.agent.walletapi.model.BaseEntity import org.hyperledger.identus.agent.walletapi.service.{ManagedDIDService, MockManagedDIDService} import org.hyperledger.identus.castor.core.service.MockDIDService import org.hyperledger.identus.iam.authentication.AuthenticatorWithAuthZ import org.hyperledger.identus.pollux.vc.jwt.* import org.hyperledger.identus.pollux.vc.jwt.CredentialPayload.Implicits.* +import org.hyperledger.identus.shared.json.JsonInterop import org.hyperledger.identus.verification.controller.http.* -import sttp.client3.{basicRequest, DeserializationException, Response, UriContext} +import sttp.client3.{DeserializationException, Response, UriContext, basicRequest} import sttp.client3.ziojson.* import sttp.model.StatusCode import zio.* @@ -17,6 +16,7 @@ import zio.json.EncoderOps import zio.test.* import zio.test.Assertion.* import zio.Config.OffsetDateTime +import zio.json.ast.Json import java.time.Instant @@ -47,11 +47,11 @@ object VcVerificationControllerImplSpec extends ZIOSpecDefault with VcVerificati `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = Json.obj( - "userName" -> Json.fromString("Bob"), - "age" -> Json.fromInt(42), - "email" -> Json.fromString("email") - ), + credentialSubject = JsonInterop.toCirceJsonAst(Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + )), maybeCredentialStatus = Some( CredentialStatus( id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", @@ -71,7 +71,7 @@ object VcVerificationControllerImplSpec extends ZIOSpecDefault with VcVerificati maybeTermsOfUse = Option.empty, aud = Set(verifier) ).toJwtCredentialPayload - signedJwtCredential = issuer.signer.encode(jwtCredentialPayload.asJson) + signedJwtCredential = issuer.signer.encode(io.circe.syntax.EncoderOps(jwtCredentialPayload).asJson) authenticator <- ZIO.service[AuthenticatorWithAuthZ[BaseEntity]] backend = httpBackend(vcVerificationController, authenticator) request = List( From df11b64610b7dbe2c18194659a78a8c022ee15a6 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Tue, 3 Dec 2024 11:14:32 +0100 Subject: [PATCH 18/22] feat: migrate castor Signed-off-by: Benjamin Voiturier --- .../castor/core/model/ProtoModelHelper.scala | 103 ++++++++---------- .../core/model/did/ServiceEndpoint.scala | 6 +- .../core/model/did/w3c/DIDDocumentRepr.scala | 2 +- .../core/model/did/w3c/W3CModelHelper.scala | 12 +- .../core/model/ProtoModelHelperSpec.scala | 22 ++-- .../identus/castor/core/util/GenUtils.scala | 4 +- 6 files changed, 66 insertions(+), 83 deletions(-) diff --git a/castor/src/main/scala/org/hyperledger/identus/castor/core/model/ProtoModelHelper.scala b/castor/src/main/scala/org/hyperledger/identus/castor/core/model/ProtoModelHelper.scala index 2e66913279..6b92428076 100644 --- a/castor/src/main/scala/org/hyperledger/identus/castor/core/model/ProtoModelHelper.scala +++ b/castor/src/main/scala/org/hyperledger/identus/castor/core/model/ProtoModelHelper.scala @@ -1,33 +1,16 @@ package org.hyperledger.identus.castor.core.model import com.google.protobuf.ByteString -import io.circe.Json -import io.iohk.atala.prism.protos.{common_models, node_api, node_models} +import io.iohk.atala.prism.protos.{node_api, node_models} import io.iohk.atala.prism.protos.common_models.OperationStatus -import io.iohk.atala.prism.protos.node_models.KeyUsage import io.iohk.atala.prism.protos.node_models.PublicKey.KeyData -import org.hyperledger.identus.castor.core.model.did.{ - DIDData, - EllipticCurve, - InternalKeyPurpose, - InternalPublicKey, - PrismDID, - PrismDIDOperation, - PublicKey, - PublicKeyData, - ScheduledDIDOperationDetail, - ScheduledDIDOperationStatus, - Service, - ServiceEndpoint, - ServiceType, - SignedPrismDIDOperation, - UpdateDIDAction, - VerificationRelationship -} +import org.hyperledger.identus.castor.core.model.did.* import org.hyperledger.identus.castor.core.model.did.ServiceEndpoint.{value, UriOrJsonEndpoint} import org.hyperledger.identus.shared.models.{Base64UrlString, KeyId} import org.hyperledger.identus.shared.utils.Traverse.* import zio.* +import zio.json.{DecoderOps, EncoderOps} +import zio.json.ast.Json import java.time.Instant import scala.language.implicitConversions @@ -191,8 +174,8 @@ private[castor] trait ProtoModelHelper { serviceType match { case ServiceType.Single(name) => name.value case ts: ServiceType.Multiple => - val names = ts.values.map(_.value).map(Json.fromString) - Json.arr(names*).noSpaces + val names = ts.values.map(_.value).map(Json.Str(_)) + Json.Arr(names*).toJson } } } @@ -203,14 +186,14 @@ private[castor] trait ProtoModelHelper { case ServiceEndpoint.Single(value) => value match { case UriOrJsonEndpoint.Uri(uri) => uri.value - case UriOrJsonEndpoint.Json(json) => Json.fromJsonObject(json).noSpaces + case UriOrJsonEndpoint.Json(json) => json.toJson } case endpoints: ServiceEndpoint.Multiple => val uris = endpoints.values.map { - case UriOrJsonEndpoint.Uri(uri) => Json.fromString(uri.value) - case UriOrJsonEndpoint.Json(json) => Json.fromJsonObject(json) + case UriOrJsonEndpoint.Uri(uri) => Json.Str(uri.value) + case UriOrJsonEndpoint.Json(json) => json } - Json.arr(uris*).noSpaces + Json.Arr(uris*).toJson } } } @@ -356,24 +339,24 @@ private[castor] trait ProtoModelHelper { def parseServiceType(s: String): Either[String, ServiceType] = { // The type field MUST be a string or a non-empty JSON array of strings. - val parsedJson: Option[Either[String, ServiceType.Multiple]] = io.circe.parser - .parse(s) - .toOption // it's OK to let parsing fail (e.g. LinkedDomains without quote is not a JSON string) - .flatMap(_.asArray) - .map { jsonArr => - jsonArr - .traverse(_.asString.toRight("the service type is not a JSON array of strings")) - .flatMap(_.traverse(ServiceType.Name.fromString)) - .map(_.toList) - .flatMap { - case head :: tail => Right(ServiceType.Multiple(head, tail)) - case Nil => Left("the service type cannot be an empty JSON array") - } - .filterOrElse( - _ => s == io.circe.Json.arr(jsonArr*).noSpaces, - "the service type is a valid JSON array of strings, but not conform to the ABNF" - ) - } + val parsedJson: Option[Either[String, ServiceType.Multiple]] = + s.fromJson[Json] + .toOption // it's OK to let parsing fail (e.g. LinkedDomains without quote is not a JSON string) + .flatMap(_.asArray) + .map { jsonArr => + jsonArr + .traverse(_.asString.toRight("the service type is not a JSON array of strings")) + .flatMap(_.traverse(ServiceType.Name.fromString)) + .map(_.toList) + .flatMap { + case head :: tail => Right(ServiceType.Multiple(head, tail)) + case Nil => Left("the service type cannot be an empty JSON array") + } + .filterOrElse( + _ => s == Json.Arr(jsonArr*).toJson, + "the service type is a valid JSON array of strings, but not conform to the ABNF" + ) + } parsedJson match { // serviceType is a valid JSON array of strings @@ -391,22 +374,22 @@ private[castor] trait ProtoModelHelper { * 2. a JSON object * 3. a non-empty JSON array of URIs and/or JSON objects */ - val parsedJson: Option[Either[String, ServiceEndpoint]] = io.circe.parser - .parse(s) - .toOption // it's OK to let parsing fail (e.g. http://example.com without quote is not a JSON string) - .flatMap { json => - val parsedObject = json.asObject.map(obj => Right(ServiceEndpoint.Single(obj))) - val parsedArray = json.asArray.map(_.traverse[String, UriOrJsonEndpoint] { js => - val obj = js.asObject.map(obj => Right(obj: UriOrJsonEndpoint)) - val str = js.asString.map(str => ServiceEndpoint.UriValue.fromString(str).map[UriOrJsonEndpoint](i => i)) - obj.orElse(str).getOrElse(Left("the service endpoint is not a JSON array of URIs and/or JSON objects")) - }.map(_.toList).flatMap { - case head :: tail => Right(ServiceEndpoint.Multiple(head, tail)) - case Nil => Left("the service endpoint cannot be an empty JSON array") - }) + val parsedJson: Option[Either[String, ServiceEndpoint]] = + s.fromJson[Json] + .toOption // it's OK to let parsing fail (e.g. http://example.com without quote is not a JSON string) + .flatMap { json => + val parsedObject = json.asObject.map(obj => Right(ServiceEndpoint.Single(obj))) + val parsedArray = json.asArray.map(_.traverse[String, UriOrJsonEndpoint] { js => + val obj = js.asObject.map(obj => Right(obj: UriOrJsonEndpoint)) + val str = js.asString.map(str => ServiceEndpoint.UriValue.fromString(str).map[UriOrJsonEndpoint](i => i)) + obj.orElse(str).getOrElse(Left("the service endpoint is not a JSON array of URIs and/or JSON objects")) + }.map(_.toList).flatMap { + case head :: tail => Right(ServiceEndpoint.Multiple(head, tail)) + case Nil => Left("the service endpoint cannot be an empty JSON array") + }) - parsedObject.orElse(parsedArray) - } + parsedObject.orElse(parsedArray) + } parsedJson match { // serviceEndpoint is a valid JSON object or array diff --git a/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/ServiceEndpoint.scala b/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/ServiceEndpoint.scala index 56167dca22..d448450f30 100644 --- a/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/ServiceEndpoint.scala +++ b/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/ServiceEndpoint.scala @@ -1,7 +1,7 @@ package org.hyperledger.identus.castor.core.model.did -import io.circe.JsonObject import org.hyperledger.identus.castor.core.util.UriUtils +import zio.json.ast.Json as ZioJson sealed trait ServiceEndpoint { def normalize(): ServiceEndpoint @@ -35,12 +35,12 @@ object ServiceEndpoint { override def normalize(): UriOrJsonEndpoint = copy(uri = uri.normalize()) } - final case class Json(json: JsonObject) extends UriOrJsonEndpoint { + final case class Json(json: ZioJson.Obj) extends UriOrJsonEndpoint { override def normalize(): UriOrJsonEndpoint = this } given Conversion[UriValue, UriOrJsonEndpoint] = Uri(_) - given Conversion[JsonObject, UriOrJsonEndpoint] = Json(_) + given Conversion[ZioJson.Obj, UriOrJsonEndpoint] = Json(_) } final case class Single(value: UriOrJsonEndpoint) extends ServiceEndpoint { diff --git a/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/w3c/DIDDocumentRepr.scala b/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/w3c/DIDDocumentRepr.scala index 4bdaca0c71..2113e7540a 100644 --- a/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/w3c/DIDDocumentRepr.scala +++ b/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/w3c/DIDDocumentRepr.scala @@ -1,6 +1,6 @@ package org.hyperledger.identus.castor.core.model.did.w3c -import io.circe.Json +import zio.json.ast.Json /** A projection of DIDDocument data model to W3C compliant DID representation */ final case class DIDDocumentRepr( diff --git a/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/w3c/W3CModelHelper.scala b/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/w3c/W3CModelHelper.scala index 47cc7265a2..d3a483d93c 100644 --- a/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/w3c/W3CModelHelper.scala +++ b/castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/w3c/W3CModelHelper.scala @@ -1,10 +1,10 @@ package org.hyperledger.identus.castor.core.model.did.w3c -import io.circe.Json import org.hyperledger.identus.castor.core.model.did.* import org.hyperledger.identus.castor.core.model.did.ServiceEndpoint.UriOrJsonEndpoint import org.hyperledger.identus.shared.crypto.Apollo import org.hyperledger.identus.shared.models.{Base64UrlString, HexString} +import zio.json.ast.Json import java.time.{Instant, ZoneOffset} import java.time.format.DateTimeFormatter @@ -95,15 +95,15 @@ private[castor] trait W3CModelHelper { serviceEndpoint match { case ServiceEndpoint.Single(uri) => uri match { - case UriOrJsonEndpoint.Uri(uri) => Json.fromString(uri.value) - case UriOrJsonEndpoint.Json(json) => Json.fromJsonObject(json) + case UriOrJsonEndpoint.Uri(uri) => Json.Str(uri.value) + case UriOrJsonEndpoint.Json(json) => json } case ep: ServiceEndpoint.Multiple => val uris = ep.values.map { - case UriOrJsonEndpoint.Uri(uri) => Json.fromString(uri.value) - case UriOrJsonEndpoint.Json(json) => Json.fromJsonObject(json) + case UriOrJsonEndpoint.Uri(uri) => Json.Str(uri.value) + case UriOrJsonEndpoint.Json(json) => json } - Json.arr(uris*) + Json.Arr(uris*) } } } diff --git a/castor/src/test/scala/org/hyperledger/identus/castor/core/model/ProtoModelHelperSpec.scala b/castor/src/test/scala/org/hyperledger/identus/castor/core/model/ProtoModelHelperSpec.scala index a72e0f9f82..5b3480a1f5 100644 --- a/castor/src/test/scala/org/hyperledger/identus/castor/core/model/ProtoModelHelperSpec.scala +++ b/castor/src/test/scala/org/hyperledger/identus/castor/core/model/ProtoModelHelperSpec.scala @@ -1,13 +1,13 @@ package org.hyperledger.identus.castor.core.model import com.google.protobuf.timestamp.Timestamp -import io.circe.{Json, JsonObject} import io.iohk.atala.prism.protos.common_models.Ledger import io.iohk.atala.prism.protos.node_models import org.hyperledger.identus.castor.core.model.did.{ServiceEndpoint, ServiceType} import org.hyperledger.identus.castor.core.model.did.ServiceEndpoint.{UriOrJsonEndpoint, UriValue} import org.hyperledger.identus.castor.core.util.GenUtils import zio.* +import zio.json.ast.Json import zio.test.* import zio.test.Assertion.* @@ -20,9 +20,9 @@ object ProtoModelHelperSpec extends ZIOSpecDefault { given Conversion[String, ServiceType.Name] = ServiceType.Name.fromStringUnsafe given Conversion[String, UriOrJsonEndpoint] = s => UriOrJsonEndpoint.Uri(UriValue.fromString(s).toOption.get) - given Conversion[JsonObject, UriOrJsonEndpoint] = UriOrJsonEndpoint.Json(_) + given Conversion[Json.Obj, UriOrJsonEndpoint] = UriOrJsonEndpoint.Json(_) given Conversion[String, ServiceEndpoint] = s => ServiceEndpoint.Single(s) - given Conversion[JsonObject, ServiceEndpoint] = json => ServiceEndpoint.Single(UriOrJsonEndpoint.Json(json)) + given Conversion[Json.Obj, ServiceEndpoint] = json => ServiceEndpoint.Single(UriOrJsonEndpoint.Json(json)) private def makePublicKey(id: String, revokedOn: Option[node_models.LedgerData] = None): node_models.PublicKey = node_models.PublicKey( @@ -351,7 +351,7 @@ object ProtoModelHelperSpec extends ZIOSpecDefault { test("parse valid json object") { val serviceEndpoint = """{"uri": "https://example.com"}""" val result = ProtoModelHelper.parseServiceEndpoint(serviceEndpoint) - val expected: ServiceEndpoint = Json.obj("uri" -> Json.fromString("https://example.com")).asObject.get + val expected: ServiceEndpoint = Json.Obj("uri" -> Json.Str("https://example.com")).asObject.get assert(result)(isRight(equalTo(expected))) }, test("parse invalid endpoint that is not a string or object") { @@ -362,7 +362,7 @@ object ProtoModelHelperSpec extends ZIOSpecDefault { test("parse empty json object") { val serviceEndpoint = "{}" val result = ProtoModelHelper.parseServiceEndpoint(serviceEndpoint) - val expected: ServiceEndpoint = Json.obj().asObject.get + val expected: ServiceEndpoint = Json.Obj().asObject.get assert(result)(isRight(equalTo(expected))) }, test("parse empty json array") { @@ -389,9 +389,9 @@ object ProtoModelHelperSpec extends ZIOSpecDefault { val serviceEndpoint = """[{"uri": "https://example.com"}, {"uri": "https://example2.com"}]""" val result = ProtoModelHelper.parseServiceEndpoint(serviceEndpoint) val expected = ServiceEndpoint.Multiple( - Json.obj("uri" -> Json.fromString("https://example.com")).asObject.get, + Json.Obj("uri" -> Json.Str("https://example.com")).asObject.get, Seq( - Json.obj("uri" -> Json.fromString("https://example2.com")).asObject.get + Json.Obj("uri" -> Json.Str("https://example2.com")).asObject.get ) ) assert(result)(isRight(equalTo(expected))) @@ -400,7 +400,7 @@ object ProtoModelHelperSpec extends ZIOSpecDefault { val serviceEndpoint = """[{"uri": "https://example.com"}, "https://example2.com"]""" val result = ProtoModelHelper.parseServiceEndpoint(serviceEndpoint) val expected = ServiceEndpoint.Multiple( - Json.obj("uri" -> Json.fromString("https://example.com")).asObject.get, + Json.Obj("uri" -> Json.Str("https://example.com")).asObject.get, Seq("https://example2.com") ) assert(result)(isRight(equalTo(expected))) @@ -428,7 +428,7 @@ object ProtoModelHelperSpec extends ZIOSpecDefault { assert(encoded)(equalTo("http://example.com")) }, test("encode single endoint JSON object") { - val uri: UriOrJsonEndpoint = JsonObject("uri" -> Json.fromString("http://example.com")) + val uri: UriOrJsonEndpoint = Json.Obj("uri" -> Json.Str("http://example.com")) val serviceEndpoint = ServiceEndpoint.Single(uri) val encoded = serviceEndpoint.toProto assert(encoded)(equalTo("""{"uri":"http://example.com"}""")) @@ -441,8 +441,8 @@ object ProtoModelHelperSpec extends ZIOSpecDefault { assert(encoded)(equalTo("""["http://example.com","http://example2.com"]""")) }, test("encode multiple endoints JSON object") { - val uri: UriOrJsonEndpoint = JsonObject("uri" -> Json.fromString("http://example.com")) - val uri2: UriOrJsonEndpoint = JsonObject("uri" -> Json.fromString("http://example2.com")) + val uri: UriOrJsonEndpoint = Json.Obj("uri" -> Json.Str("http://example.com")) + val uri2: UriOrJsonEndpoint = Json.Obj("uri" -> Json.Str("http://example2.com")) val serviceEndpoint = ServiceEndpoint.Multiple(uri, Seq(uri2)) val encoded = serviceEndpoint.toProto assert(encoded)(equalTo("""[{"uri":"http://example.com"},{"uri":"http://example2.com"}]""")) diff --git a/castor/src/test/scala/org/hyperledger/identus/castor/core/util/GenUtils.scala b/castor/src/test/scala/org/hyperledger/identus/castor/core/util/GenUtils.scala index e25519ebc2..cbad68e77a 100644 --- a/castor/src/test/scala/org/hyperledger/identus/castor/core/util/GenUtils.scala +++ b/castor/src/test/scala/org/hyperledger/identus/castor/core/util/GenUtils.scala @@ -1,11 +1,11 @@ package org.hyperledger.identus.castor.core.util -import io.circe.Json import org.hyperledger.identus.castor.core.model.did.* import org.hyperledger.identus.castor.core.model.did.ServiceEndpoint.{UriOrJsonEndpoint, UriValue} import org.hyperledger.identus.shared.crypto.Apollo import org.hyperledger.identus.shared.models.{Base64UrlString, KeyId} import zio.* +import zio.json.ast.Json import zio.test.Gen import scala.language.implicitConversions @@ -62,7 +62,7 @@ object GenUtils { ) sampleUri = "https://example.com" uriEndpointGen = Gen.const(UriOrJsonEndpoint.Uri(UriValue.fromString(sampleUri).toOption.get)) - jsonEndpointGen = Gen.const(UriOrJsonEndpoint.Json(Json.obj("uri" -> Json.fromString(sampleUri)).asObject.get)) + jsonEndpointGen = Gen.const(UriOrJsonEndpoint.Json(Json.Obj("uri" -> Json.Str(sampleUri)).asObject.get)) endpoints <- Gen.oneOf[Any, ServiceEndpoint]( uriEndpointGen.map(ServiceEndpoint.Single(_)), jsonEndpointGen.map(ServiceEndpoint.Single(_)), From 9335549413334a08c920b91f508743f3e13c8593 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Tue, 3 Dec 2024 15:10:44 +0100 Subject: [PATCH 19/22] feat: migrate mercury-resolver Signed-off-by: Benjamin Voiturier --- .../castor/controller/http/Service.scala | 7 +- .../identus/resolvers/PeerDidResolver.scala | 160 ++++++++---------- .../resolvers/PeerDidResolverSpec.scala | 9 +- .../identus/pollux/vc/jwt/DidResolver.scala | 13 +- 4 files changed, 84 insertions(+), 105 deletions(-) diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/castor/controller/http/Service.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/castor/controller/http/Service.scala index 52b566f436..3c22f6a220 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/castor/controller/http/Service.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/castor/controller/http/Service.scala @@ -2,14 +2,13 @@ package org.hyperledger.identus.castor.controller.http import org.hyperledger.identus.api.http.Annotation import org.hyperledger.identus.castor.controller.http.Service.annotations -import org.hyperledger.identus.castor.core.model.{did as castorDomain, ProtoModelHelper} import org.hyperledger.identus.castor.core.model.did.w3c -import org.hyperledger.identus.shared.json.JsonInterop +import org.hyperledger.identus.castor.core.model.{ProtoModelHelper, did as castorDomain} import org.hyperledger.identus.shared.utils.Traverse.* import sttp.tapir.Schema import sttp.tapir.Schema.annotations.{description, encodedExample} -import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} import zio.json.ast.Json +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} import scala.language.implicitConversions @@ -62,7 +61,7 @@ object Service { Service( id = service.id, `type` = service.`type`, - serviceEndpoint = ServiceEndpoint.fromJson(JsonInterop.toZioJsonAst(service.serviceEndpoint)) + serviceEndpoint = ServiceEndpoint.fromJson(service.serviceEndpoint) ) extension (service: Service) { diff --git a/mercury/resolver/src/main/scala/org/hyperledger/identus/resolvers/PeerDidResolver.scala b/mercury/resolver/src/main/scala/org/hyperledger/identus/resolvers/PeerDidResolver.scala index e4d09b1892..857eb30169 100644 --- a/mercury/resolver/src/main/scala/org/hyperledger/identus/resolvers/PeerDidResolver.scala +++ b/mercury/resolver/src/main/scala/org/hyperledger/identus/resolvers/PeerDidResolver.scala @@ -1,12 +1,12 @@ package org.hyperledger.identus.resolvers -import io.circe.{Decoder, HCursor, Json} -import io.circe.parser.* import org.didcommx.didcomm.common.* import org.didcommx.didcomm.diddoc.{DIDCommService, DIDDoc, VerificationMethod} import org.didcommx.peerdid.PeerDIDResolver.resolvePeerDID import org.didcommx.peerdid.VerificationMaterialFormatPeerDID import zio.* +import zio.json.{DecoderOps, DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} +import zio.json.ast.Json import scala.jdk.CollectionConverters.* @@ -23,97 +23,85 @@ case class PeerDidResolverImpl() extends PeerDidResolver { def resolveDidAsJson(did: String): UIO[Option[Json]] = { ZIO.succeed { - parse(resolvePeerDID(did, VerificationMaterialFormatPeerDID.MULTIBASE)).toOption + resolvePeerDID(did, VerificationMaterialFormatPeerDID.MULTIBASE).fromJson[Json].toOption } } } +private case class _DIDDocument( + id: String, + service: List[_DIDCommService], + authentication: List[_VerificationMethod], + keyAgreement: List[_VerificationMethod] +) { + def toDIDCommX: DIDDoc = { + val didCommServices = service.map(_.toDIDCommX) + val authVerificationMethods = authentication.map(_.toDIDCommX) + val keyAgreementVerificationMethods = keyAgreement.map(_.toDIDCommX) + new DIDDoc( + id, + keyAgreement.map(_.id).asJava, + authentication.map(_.id).asJava, + (keyAgreementVerificationMethods ++ authVerificationMethods).asJava, + didCommServices.asJava + ) + } +} + +private object _DIDDocument { + given JsonEncoder[_DIDDocument] = DeriveJsonEncoder.gen + + given JsonDecoder[_DIDDocument] = DeriveJsonDecoder.gen +} + +private case class _DIDCommService(id: String, serviceEndpoint: _ServiceEndpoint) { + def toDIDCommX: DIDCommService = + new DIDCommService(id, serviceEndpoint.uri, serviceEndpoint.routingKeys.asJava, serviceEndpoint.accept.asJava) +} + +private object _DIDCommService { + given JsonEncoder[_DIDCommService] = DeriveJsonEncoder.gen + + given JsonDecoder[_DIDCommService] = DeriveJsonDecoder.gen +} + +private case class _ServiceEndpoint( + uri: String, + routingKeys: List[String] = List.empty, + accept: List[String] = List.empty +) + +private object _ServiceEndpoint { + given JsonEncoder[_ServiceEndpoint] = DeriveJsonEncoder.gen + + given JsonDecoder[_ServiceEndpoint] = DeriveJsonDecoder.gen +} + +private case class _VerificationMethod(id: String, controller: String, publicKeyJwk: Json) { + def toDIDCommX: VerificationMethod = { + new VerificationMethod( + id, + VerificationMethodType.JSON_WEB_KEY_2020, + new VerificationMaterial(VerificationMaterialFormat.JWK, publicKeyJwk.toJson), + controller + ) + } +} + +private object _VerificationMethod { + given JsonEncoder[_VerificationMethod] = DeriveJsonEncoder.gen + + given JsonDecoder[_VerificationMethod] = DeriveJsonDecoder.gen +} + object PeerDidResolver { - def resolveUnsafe(didPeer: String) = - parse(resolvePeerDID(didPeer, VerificationMaterialFormatPeerDID.JWK)).toOption.get def getDIDDoc(didPeer: String): DIDDoc = { - val json = resolveUnsafe(didPeer) - val cursor: HCursor = json.hcursor - val did = cursor.downField("id").as[String].getOrElse(UnexpectedCodeExecutionPath) - val service = cursor.downField("service").as[List[Json]] - - val didCommServices: List[DIDCommService] = service - .map { - _.map { item => - val id = item.hcursor.downField("id").as[String].getOrElse(UnexpectedCodeExecutionPath) - // val typ = item.hcursor.downField("type").as[String].getOrElse(UnexpectedCodeExecutionPath) - val serviceEndpointJson = item.hcursor.downField("serviceEndpoint") - // val serviceEndpoint = item.hcursor.downField("serviceEndpoint").as[String].getOrElse(UnexpectedCodeExecutionPath) - val uri = serviceEndpointJson.downField("uri").as[String].getOrElse(UnexpectedCodeExecutionPath) - val routingKeys: Seq[String] = - serviceEndpointJson.downField("routingKeys").as[List[String]].getOrElse(Seq.empty) - val accept: Seq[String] = serviceEndpointJson.downField("accept").as[List[String]].getOrElse(Seq.empty) - new DIDCommService(id, uri, routingKeys.asJava, accept.asJava) - } - } - .getOrElse(List.empty) - - val authentications1 = cursor.downField("authentication").as[List[Json]] - val verificationMethodList1: List[VerificationMethod] = authentications1 - .map { - _.map(item => - val id = item.hcursor.downField("id").as[String].getOrElse(UnexpectedCodeExecutionPath) - - val publicKeyJwk = item.hcursor - .downField("publicKeyJwk") - .as[Json] - .map(_.toString) - .getOrElse(UnexpectedCodeExecutionPath) - - val controller = item.hcursor.downField("controller").as[String].getOrElse(UnexpectedCodeExecutionPath) - val verificationMaterial = new VerificationMaterial(VerificationMaterialFormat.JWK, publicKeyJwk) - new VerificationMethod(id, VerificationMethodType.JSON_WEB_KEY_2020, verificationMaterial, controller) - ) - } - .getOrElse(UnexpectedCodeExecutionPath) - - val keyIdAuthentications: List[String] = authentications1 - .map { - _.map(item => item.hcursor.downField("id").as[String].getOrElse(UnexpectedCodeExecutionPath)) - } - .getOrElse(UnexpectedCodeExecutionPath) - - val keyAgreements1 = cursor.downField("keyAgreement").as[List[Json]] - val verificationMethodList: List[VerificationMethod] = keyAgreements1 - .map { - _.map(item => - val id = item.hcursor.downField("id").as[String].getOrElse(UnexpectedCodeExecutionPath) - - val publicKeyJwk = item.hcursor - .downField("publicKeyJwk") - .as[Json] - .map(_.toString) - .getOrElse(UnexpectedCodeExecutionPath) - - val controller = item.hcursor.downField("controller").as[String].getOrElse(UnexpectedCodeExecutionPath) - val verificationMaterial = new VerificationMaterial(VerificationMaterialFormat.JWK, publicKeyJwk) - new VerificationMethod(id, VerificationMethodType.JSON_WEB_KEY_2020, verificationMaterial, controller) - ) - } - .getOrElse(UnexpectedCodeExecutionPath) - - val keyIds: List[String] = keyAgreements1 - .map { - _.map(item => item.hcursor.downField("id").as[String].getOrElse(UnexpectedCodeExecutionPath)) - } - .getOrElse(UnexpectedCodeExecutionPath) - val mergedList = verificationMethodList ++ verificationMethodList1 - - val didDoc = - new DIDDoc( - did, - keyIds.asJava, - keyIdAuthentications.asJava, - mergedList.asJava, - didCommServices.asJava - ) - didDoc + resolvePeerDID(didPeer, VerificationMaterialFormatPeerDID.JWK) + .fromJson[_DIDDocument] + .toOption + .get + .toDIDCommX } val layer: ULayer[PeerDidResolver] = { diff --git a/mercury/resolver/src/test/scala/org/hyperledger/identus/resolvers/PeerDidResolverSpec.scala b/mercury/resolver/src/test/scala/org/hyperledger/identus/resolvers/PeerDidResolverSpec.scala index a95efd03e0..39df5840ef 100644 --- a/mercury/resolver/src/test/scala/org/hyperledger/identus/resolvers/PeerDidResolverSpec.scala +++ b/mercury/resolver/src/test/scala/org/hyperledger/identus/resolvers/PeerDidResolverSpec.scala @@ -1,9 +1,8 @@ package org.hyperledger.identus.resolvers -import io.circe.parser.* -import io.circe.Json import munit.* import org.didcommx.peerdid.* -import zio.* +import zio.json.DecoderOps +import zio.json.ast.Json import scala.jdk.CollectionConverters.* @@ -12,7 +11,7 @@ class PeerDidResolverSpec extends ZSuite { testZ("peer did") { val peerDid = "did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0" - val expectedDidDocJson = parse("""{ + val expectedDidDocJson = """{ | "id": "did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0", | "authentication": [ | { @@ -51,7 +50,7 @@ class PeerDidResolverSpec extends ZSuite { | } | } | ] - |}""".stripMargin).toOption + |}""".stripMargin.fromJson[Json].toOption val peerDidResolver = PeerDidResolverImpl() val didDocJson = peerDidResolver.resolveDidAsJson(peerDid) diff --git a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/DidResolver.scala b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/DidResolver.scala index 33ebac2154..20c15013a8 100644 --- a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/DidResolver.scala +++ b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/DidResolver.scala @@ -1,16 +1,9 @@ package org.hyperledger.identus.pollux.vc.jwt import io.circe.Json -import org.hyperledger.identus.castor.core.model.did.w3c.{ - makeW3CResolver, - DIDDocumentRepr, - DIDResolutionErrorRepr, - PublicKeyJwk, - PublicKeyRepr, - PublicKeyReprOrRef, - ServiceRepr -} +import org.hyperledger.identus.castor.core.model.did.w3c.{DIDDocumentRepr, DIDResolutionErrorRepr, PublicKeyJwk, PublicKeyRepr, PublicKeyReprOrRef, ServiceRepr, makeW3CResolver} import org.hyperledger.identus.castor.core.service.DIDService +import org.hyperledger.identus.shared.json.JsonInterop import zio.* import java.time.Instant @@ -134,7 +127,7 @@ class PrismDidResolver(didService: DIDService) extends DidResolver { Service( id = service.id, `type` = service.`type`, - serviceEndpoint = service.serviceEndpoint + serviceEndpoint = JsonInterop.toCirceJsonAst(service.serviceEndpoint) ) } From a097cb469056ef65802b03fe3c786aa4c698a62c Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Tue, 3 Dec 2024 16:45:17 +0100 Subject: [PATCH 20/22] feat: migrate pollux-prex Signed-off-by: Benjamin Voiturier --- .../pollux/prex/PresentationDefinition.scala | 35 ++--------------- .../pollux/prex/PresentationSubmission.scala | 11 +++--- .../PresentationSubmissionVerification.scala | 20 ++-------- .../PresentationDefinitionValidatorSpec.scala | 19 ++++++---- .../prex/PresentationSubmissionSpec.scala | 10 +++-- ...esentationSubmissionVerificationSpec.scala | 38 +++++-------------- 6 files changed, 39 insertions(+), 94 deletions(-) diff --git a/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationDefinition.scala b/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationDefinition.scala index ea16960cc9..e6bb34938c 100644 --- a/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationDefinition.scala +++ b/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationDefinition.scala @@ -1,10 +1,7 @@ package org.hyperledger.identus.pollux.prex import com.networknt.schema.{JsonSchema, SpecVersion} -import io.circe.* -import io.circe.generic.semiauto.* -import io.circe.Json as CirceJson -import org.hyperledger.identus.shared.json.{JsonInterop, JsonPath, JsonPathError, JsonSchemaError, JsonSchemaUtils} +import org.hyperledger.identus.shared.json.{JsonPath, JsonPathError, JsonSchemaError, JsonSchemaUtils} import zio.* import zio.json.{JsonDecoder, JsonEncoder} import zio.json.ast.Json as ZioJson @@ -12,8 +9,6 @@ import zio.json.ast.Json as ZioJson opaque type JsonPathValue = String object JsonPathValue { - given Encoder[JsonPathValue] = Encoder.encodeString - given Decoder[JsonPathValue] = Decoder.decodeString given Conversion[String, JsonPathValue] = identity given JsonEncoder[JsonPathValue] = JsonEncoder.string @@ -28,8 +23,6 @@ object JsonPathValue { opaque type FieldFilter = ZioJson object FieldFilter { - given Encoder[FieldFilter] = Encoder.encodeJson.contramap(JsonInterop.toCirceJsonAst) - given Decoder[FieldFilter] = Decoder.decodeJson.map(JsonInterop.toZioJsonAst) given Conversion[ZioJson, FieldFilter] = identity given JsonEncoder[FieldFilter] = ZioJson.encoder @@ -37,7 +30,6 @@ object FieldFilter { extension (f: FieldFilter) def asJsonZio: ZioJson = f - def asJsonCirce: CirceJson = JsonInterop.toCirceJsonAst(f) // Json schema draft 7 must be used // https://identity.foundation/presentation-exchange/spec/v2.1.1/#json-schema @@ -55,9 +47,6 @@ case class Field( ) object Field { - given Encoder[Field] = deriveEncoder[Field] - given Decoder[Field] = deriveDecoder[Field] - given JsonEncoder[Field] = JsonEncoder.derived given JsonDecoder[Field] = JsonDecoder.derived } @@ -65,9 +54,6 @@ object Field { case class Jwt(alg: Seq[String]) object Jwt { - given Encoder[Jwt] = deriveEncoder[Jwt] - given Decoder[Jwt] = deriveDecoder[Jwt] - given JsonEncoder[Jwt] = JsonEncoder.derived given JsonDecoder[Jwt] = JsonDecoder.derived } @@ -75,9 +61,6 @@ object Jwt { case class Ldp(proof_type: Seq[String]) object Ldp { - given Encoder[Ldp] = deriveEncoder[Ldp] - given Decoder[Ldp] = deriveDecoder[Ldp] - given JsonEncoder[Ldp] = JsonEncoder.derived given JsonDecoder[Ldp] = JsonDecoder.derived } @@ -88,8 +71,8 @@ enum ClaimFormatValue(val value: String) { } object ClaimFormatValue { - given Encoder[ClaimFormatValue] = Encoder.encodeString.contramap(_.value) - given Decoder[ClaimFormatValue] = Decoder.decodeString.emap { + given JsonEncoder[ClaimFormatValue] = JsonEncoder[String].contramap(_.value) + given JsonDecoder[ClaimFormatValue] = JsonDecoder[String].mapOrFail { case "jwt_vc" => Right(ClaimFormatValue.jwt_vc) case "jwt_vp" => Right(ClaimFormatValue.jwt_vp) case other => Left(s"Invalid ClaimFormatValue: $other") @@ -104,9 +87,6 @@ case class ClaimFormat( ) object ClaimFormat { - given Encoder[ClaimFormat] = deriveEncoder[ClaimFormat] - given Decoder[ClaimFormat] = deriveDecoder[ClaimFormat] - given JsonEncoder[ClaimFormat] = JsonEncoder.derived given JsonDecoder[ClaimFormat] = JsonDecoder.derived } @@ -114,9 +94,6 @@ object ClaimFormat { case class Constraints(fields: Option[Seq[Field]]) object Constraints { - given Encoder[Constraints] = deriveEncoder[Constraints] - given Decoder[Constraints] = deriveDecoder[Constraints] - given JsonEncoder[Constraints] = JsonEncoder.derived given JsonDecoder[Constraints] = JsonDecoder.derived } @@ -132,9 +109,6 @@ case class InputDescriptor( ) object InputDescriptor { - given Encoder[InputDescriptor] = deriveEncoder[InputDescriptor] - given Decoder[InputDescriptor] = deriveDecoder[InputDescriptor] - given JsonEncoder[InputDescriptor] = JsonEncoder.derived given JsonDecoder[InputDescriptor] = JsonDecoder.derived } @@ -151,9 +125,6 @@ case class PresentationDefinition( ) object PresentationDefinition { - given Encoder[PresentationDefinition] = deriveEncoder[PresentationDefinition] - given Decoder[PresentationDefinition] = deriveDecoder[PresentationDefinition] - given JsonEncoder[PresentationDefinition] = JsonEncoder.derived given JsonDecoder[PresentationDefinition] = JsonDecoder.derived } diff --git a/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationSubmission.scala b/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationSubmission.scala index 10475badc0..1ff6305129 100644 --- a/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationSubmission.scala +++ b/pollux/prex/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationSubmission.scala @@ -1,7 +1,6 @@ package org.hyperledger.identus.pollux.prex -import io.circe.* -import io.circe.generic.semiauto.* +import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} case class InputDescriptorMapping( id: String, @@ -11,8 +10,8 @@ case class InputDescriptorMapping( ) object InputDescriptorMapping { - given Encoder[InputDescriptorMapping] = deriveEncoder[InputDescriptorMapping] - given Decoder[InputDescriptorMapping] = deriveDecoder[InputDescriptorMapping] + given JsonEncoder[InputDescriptorMapping] = DeriveJsonEncoder.gen + given JsonDecoder[InputDescriptorMapping] = DeriveJsonDecoder.gen } /** Refer to ClaimDecodeFailure(format, path, e)) _ <- formatVerification(jwt) .mapError(errors => ClaimFormatVerificationFailure(format, path, errors.mkString)) - } yield JsonInterop.toZioJsonAst(payload.asJson) + } yield JsonInterop.toZioJsonAst(io.circe.syntax.EncoderOps(payload).asJson) } private def verifyJwtVp( @@ -224,6 +212,6 @@ object PresentationSubmissionVerification { .mapError(e => ClaimDecodeFailure(format, path, e.getMessage())) _ <- formatVerification(jwt) .mapError(errors => ClaimFormatVerificationFailure(format, path, errors.mkString)) - } yield JsonInterop.toZioJsonAst(payload.asJson) + } yield JsonInterop.toZioJsonAst(io.circe.syntax.EncoderOps(payload).asJson) } } diff --git a/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationDefinitionValidatorSpec.scala b/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationDefinitionValidatorSpec.scala index 290c72198d..d0eeaeb70b 100644 --- a/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationDefinitionValidatorSpec.scala +++ b/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationDefinitionValidatorSpec.scala @@ -1,8 +1,5 @@ package org.hyperledger.identus.pollux.prex -import io.circe.* -import io.circe.generic.auto.* -import io.circe.parser.* import org.hyperledger.identus.pollux.prex.PresentationDefinitionError.{ DuplicatedDescriptorId, InvalidFilterJsonPath, @@ -10,6 +7,7 @@ import org.hyperledger.identus.pollux.prex.PresentationDefinitionError.{ JsonSchemaOptionNotSupported } import zio.* +import zio.json.{DecoderOps, DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} import zio.test.* import zio.test.Assertion.* @@ -20,6 +18,11 @@ object PresentationDefinitionValidatorSpec extends ZIOSpecDefault { final case class ExampleTransportEnvelope(presentation_definition: PresentationDefinition) + object ExampleTransportEnvelope { + given JsonEncoder[ExampleTransportEnvelope] = DeriveJsonEncoder.gen + given JsonDecoder[ExampleTransportEnvelope] = DeriveJsonDecoder.gen + } + override def spec = suite("PresentationDefinitionValidatorSpec")( test("accept presentation-definition examples from spec") { val resourcePaths = Seq( @@ -34,7 +37,7 @@ object PresentationDefinitionValidatorSpec extends ZIOSpecDefault { validator <- ZIO.service[PresentationDefinitionValidator] _ <- ZIO .fromTry(Using(Source.fromResource(path))(_.mkString)) - .flatMap(json => ZIO.fromEither(decode[ExampleTransportEnvelope](json))) + .flatMap(json => ZIO.fromEither(json.fromJson[ExampleTransportEnvelope])) .map(_.presentation_definition) .flatMap(validator.validate) } yield () @@ -68,7 +71,7 @@ object PresentationDefinitionValidatorSpec extends ZIOSpecDefault { for { validator <- ZIO.service[PresentationDefinitionValidator] pd <- ZIO - .fromEither(decode[ExampleTransportEnvelope](pdJson)) + .fromEither(pdJson.fromJson[ExampleTransportEnvelope]) .map(_.presentation_definition) exit <- validator.validate(pd).exit } yield assert(exit)(failsWithA[InvalidFilterJsonSchema]) @@ -100,7 +103,7 @@ object PresentationDefinitionValidatorSpec extends ZIOSpecDefault { for { validator <- ZIO.service[PresentationDefinitionValidator] pd <- ZIO - .fromEither(decode[ExampleTransportEnvelope](pdJson)) + .fromEither(pdJson.fromJson[ExampleTransportEnvelope]) .map(_.presentation_definition) exit <- validator.validate(pd).exit } yield assert(exit)(failsWithA[JsonSchemaOptionNotSupported]) @@ -131,7 +134,7 @@ object PresentationDefinitionValidatorSpec extends ZIOSpecDefault { for { validator <- ZIO.service[PresentationDefinitionValidator] pd <- ZIO - .fromEither(decode[ExampleTransportEnvelope](pdJson)) + .fromEither(pdJson.fromJson[ExampleTransportEnvelope]) .map(_.presentation_definition) exit <- validator.validate(pd).exit } yield assert(exit)(failsWithA[InvalidFilterJsonPath]) @@ -158,7 +161,7 @@ object PresentationDefinitionValidatorSpec extends ZIOSpecDefault { for { validator <- ZIO.service[PresentationDefinitionValidator] pd <- ZIO - .fromEither(decode[ExampleTransportEnvelope](pdJson)) + .fromEither(pdJson.fromJson[ExampleTransportEnvelope]) .map(_.presentation_definition) exit <- validator.validate(pd).exit } yield assert(exit)(failsWithA[DuplicatedDescriptorId]) diff --git a/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionSpec.scala b/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionSpec.scala index fdc723a246..2bfc034568 100644 --- a/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionSpec.scala +++ b/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionSpec.scala @@ -1,9 +1,7 @@ package org.hyperledger.identus.pollux.prex -import io.circe.* -import io.circe.generic.auto.* -import io.circe.parser.* import zio.* +import zio.json.{DecoderOps, DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} import zio.test.* import scala.io.Source @@ -12,6 +10,10 @@ import scala.util.Using object PresentationSubmissionSpec extends ZIOSpecDefault { final case class ExampleTransportEnvelope(presentation_submission: PresentationSubmission) + object ExampleTransportEnvelope { + given JsonEncoder[ExampleTransportEnvelope] = DeriveJsonEncoder.gen + given JsonDecoder[ExampleTransportEnvelope] = DeriveJsonDecoder.gen + } override def spec = suite("PresentationSubmissionSpec")( test("parse presentation-submission exmaples from spec") { @@ -23,7 +25,7 @@ object PresentationSubmissionSpec extends ZIOSpecDefault { .foreach(resourcePaths) { path => ZIO .fromTry(Using(Source.fromResource(path))(_.mkString)) - .flatMap(json => ZIO.fromEither(decode[ExampleTransportEnvelope](json))) + .flatMap(json => ZIO.fromEither(json.fromJson[ExampleTransportEnvelope])) .map(_.presentation_submission) } .as(assertCompletes) diff --git a/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionVerificationSpec.scala b/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionVerificationSpec.scala index 90f1c40507..75ff38eec9 100644 --- a/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionVerificationSpec.scala +++ b/pollux/prex/src/test/scala/org/hyperledger/identus/pollux/prex/PresentationSubmissionVerificationSpec.scala @@ -1,31 +1,13 @@ package org.hyperledger.identus.pollux.prex -import io.circe.* -import io.circe.parser.* import org.hyperledger.identus.castor.core.model.did.DID -import org.hyperledger.identus.pollux.prex.PresentationSubmissionError.{ - ClaimFormatVerificationFailure, - ClaimNotSatisfyInputConstraint, - InvalidNestedPathDescriptorId, - InvalidSubmissionId, - SubmissionNotSatisfyInputDescriptors -} -import org.hyperledger.identus.pollux.vc.jwt.{ - ES256KSigner, - Issuer, - JWT, - JwtCredential, - JwtCredentialPayload, - JwtPresentation, - JwtPresentationPayload, - JwtVc, - JwtVerifiableCredentialPayload, - JwtVp, - VerifiableCredentialPayload -} +import org.hyperledger.identus.pollux.prex.PresentationSubmissionError.* +import org.hyperledger.identus.pollux.vc.jwt.* import org.hyperledger.identus.shared.crypto.Apollo +import org.hyperledger.identus.shared.json.JsonInterop import zio.* -import zio.json.ast.Json as ZioJson +import zio.json.{DecoderOps, JsonDecoder} +import zio.json.ast.Json import zio.test.* import zio.test.Assertion.* @@ -33,8 +15,8 @@ import java.time.Instant object PresentationSubmissionVerificationSpec extends ZIOSpecDefault { - private def decodeUnsafe[T: Decoder](json: String): T = decode[T](json).toOption.get - private def parseUnsafe(json: String): Json = parse(json).toOption.get + private def decodeUnsafe[T](json: String)(using JsonDecoder[T]): T = json.fromJson[T].toOption.get + private def parseUnsafe(json: String): Json = json.fromJson[Json].toOption.get private val noopFormatVerification = ClaimFormatVerification(jwtVp = _ => ZIO.unit, jwtVc = _ => ZIO.unit) private val basePd: PresentationDefinition = @@ -67,7 +49,7 @@ object PresentationSubmissionVerificationSpec extends ZIOSpecDefault { `@context` = Set("https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"), `type` = Set("VerifiableCredential", "UniversityDegreeCredential"), maybeCredentialSchema = None, - credentialSubject = subject, + credentialSubject = JsonInterop.toCirceJsonAst(subject), maybeCredentialStatus = None, maybeRefreshService = None, maybeEvidence = None, @@ -139,7 +121,7 @@ object PresentationSubmissionVerificationSpec extends ZIOSpecDefault { val ps = basePs.copy(descriptor_map = descriptorMap) for { result <- PresentationSubmissionVerification - .verify(pd, ps, ZioJson.Str(jwt.value))(formatVerification) + .verify(pd, ps, Json.Str(jwt.value))(formatVerification) .exit } yield assert(result)(assertion) } @@ -151,7 +133,7 @@ object PresentationSubmissionVerificationSpec extends ZIOSpecDefault { val jwtVc = generateJwtVc(payload) for { result <- PresentationSubmissionVerification - .verify(basePd, ps, ZioJson.Str(jwtVc.value))(noopFormatVerification) + .verify(basePd, ps, Json.Str(jwtVc.value))(noopFormatVerification) .exit } yield assert(result)(failsWithA[InvalidSubmissionId]) }, From 09767ce860eee4a1d8f85a00dcadce424153e1ca Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Wed, 4 Dec 2024 13:48:42 +0100 Subject: [PATCH 21/22] chore: run scalafmt Signed-off-by: Benjamin Voiturier --- .../server/jobs/PresentBackgroundJobs.scala | 11 ++++++--- .../agent/server/jobs/StatusListJobs.scala | 2 +- .../castor/controller/http/Service.scala | 4 ++-- .../VcVerificationControllerImplSpec.scala | 16 +++++++------ .../UtilsCredentialSpec.scala | 24 ++++++++++++------- .../resolvers/PeerDidResolverSpec.scala | 2 +- .../service/CredentialServiceNotifier.scala | 2 +- ...sentationExchangeRepositorySpecSuite.scala | 2 +- .../core/service/MockCredentialService.scala | 2 +- .../identus/pollux/vc/jwt/DidResolver.scala | 10 +++++++- 10 files changed, 48 insertions(+), 27 deletions(-) diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala index 7a1ba2aff1..c1177b2da2 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala @@ -2,7 +2,11 @@ package org.hyperledger.identus.agent.server.jobs import cats.syntax.all.* import org.hyperledger.identus.agent.server.config.AppConfig -import org.hyperledger.identus.agent.server.jobs.BackgroundJobError.{ErrorResponseReceivedFromPeerAgent, InvalidState, NotImplemented} +import org.hyperledger.identus.agent.server.jobs.BackgroundJobError.{ + ErrorResponseReceivedFromPeerAgent, + InvalidState, + NotImplemented +} import org.hyperledger.identus.agent.walletapi.model.error.{DIDSecretStorageError, GetManagedDIDError} import org.hyperledger.identus.agent.walletapi.service.ManagedDIDService import org.hyperledger.identus.agent.walletapi.storage.DIDNonSecretStorage @@ -21,7 +25,7 @@ import org.hyperledger.identus.pollux.core.model.presentation.Options import org.hyperledger.identus.pollux.core.service.{CredentialService, PresentationService} import org.hyperledger.identus.pollux.core.service.serdes.AnoncredCredentialProofsV1 import org.hyperledger.identus.pollux.sdjwt.{HolderPrivateKey, IssuerPublicKey, PresentationCompact, SDJWT} -import org.hyperledger.identus.pollux.vc.jwt.{JWT, JwtPresentation, DidResolver as JwtDidResolver, Issuer as JwtIssuer} +import org.hyperledger.identus.pollux.vc.jwt.{DidResolver as JwtDidResolver, Issuer as JwtIssuer, JWT, JwtPresentation} import org.hyperledger.identus.pollux.vc.jwt.CredentialSchemaAndTrustedIssuersConstraint import org.hyperledger.identus.resolvers.DIDResolver import org.hyperledger.identus.shared.http.* @@ -1100,7 +1104,8 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { val maybePresentationOptions: Either[PresentationError, Option[Options]] = requestPresentation.attachments.headOption .map(attachment => - attachment.data.toJson.fromJson[JsonData] + attachment.data.toJson + .fromJson[JsonData] .leftMap(err => PresentationDecodingError(s"JsonData decoding error: $err")) .flatMap(data => org.hyperledger.identus.pollux.core.model.presentation.PresentationAttachment.given_JsonDecoder_PresentationAttachment diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/StatusListJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/StatusListJobs.scala index 9ef4c91468..3eb78b2d0b 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/StatusListJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/StatusListJobs.scala @@ -16,8 +16,8 @@ import org.hyperledger.identus.shared.messaging.{Message, Producer, WalletIdAndR import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} import org.hyperledger.identus.shared.utils.DurationOps.toMetricsSeconds import zio.* -import zio.json.DecoderOps import zio.json.ast.Json +import zio.json.DecoderOps import zio.metrics.Metric import java.util.UUID diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/castor/controller/http/Service.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/castor/controller/http/Service.scala index 3c22f6a220..a58ed658ea 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/castor/controller/http/Service.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/castor/controller/http/Service.scala @@ -2,13 +2,13 @@ package org.hyperledger.identus.castor.controller.http import org.hyperledger.identus.api.http.Annotation import org.hyperledger.identus.castor.controller.http.Service.annotations +import org.hyperledger.identus.castor.core.model.{did as castorDomain, ProtoModelHelper} import org.hyperledger.identus.castor.core.model.did.w3c -import org.hyperledger.identus.castor.core.model.{ProtoModelHelper, did as castorDomain} import org.hyperledger.identus.shared.utils.Traverse.* import sttp.tapir.Schema import sttp.tapir.Schema.annotations.{description, encodedExample} -import zio.json.ast.Json import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} +import zio.json.ast.Json import scala.language.implicitConversions diff --git a/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/verification/controller/VcVerificationControllerImplSpec.scala b/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/verification/controller/VcVerificationControllerImplSpec.scala index eb753af53e..5847996fa5 100644 --- a/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/verification/controller/VcVerificationControllerImplSpec.scala +++ b/cloud-agent/service/server/src/test/scala/org/hyperledger/identus/verification/controller/VcVerificationControllerImplSpec.scala @@ -8,15 +8,15 @@ import org.hyperledger.identus.pollux.vc.jwt.* import org.hyperledger.identus.pollux.vc.jwt.CredentialPayload.Implicits.* import org.hyperledger.identus.shared.json.JsonInterop import org.hyperledger.identus.verification.controller.http.* -import sttp.client3.{DeserializationException, Response, UriContext, basicRequest} +import sttp.client3.{basicRequest, DeserializationException, Response, UriContext} import sttp.client3.ziojson.* import sttp.model.StatusCode import zio.* +import zio.json.ast.Json import zio.json.EncoderOps import zio.test.* import zio.test.Assertion.* import zio.Config.OffsetDateTime -import zio.json.ast.Json import java.time.Instant @@ -47,11 +47,13 @@ object VcVerificationControllerImplSpec extends ZIOSpecDefault with VcVerificati `type` = "JsonSchemaValidator2018" ) ), - credentialSubject = JsonInterop.toCirceJsonAst(Json.Obj( - "userName" -> Json.Str("Bob"), - "age" -> Json.Num(42), - "email" -> Json.Str("email") - )), + credentialSubject = JsonInterop.toCirceJsonAst( + Json.Obj( + "userName" -> Json.Str("Bob"), + "age" -> Json.Num(42), + "email" -> Json.Str("email") + ) + ), maybeCredentialStatus = Some( CredentialStatus( id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", diff --git a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/anotherclasspath/UtilsCredentialSpec.scala b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/anotherclasspath/UtilsCredentialSpec.scala index 2cae3e032a..7dfdb4f4e4 100644 --- a/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/anotherclasspath/UtilsCredentialSpec.scala +++ b/mercury/protocol-issue-credential/src/test/scala/org/hyperledger/identus/mercury/protocol/anotherclasspath/UtilsCredentialSpec.scala @@ -2,7 +2,17 @@ package org.hyperledger.identus.mercury.protocol.anotherclasspath import munit.* import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId} -import org.hyperledger.identus.mercury.protocol.issuecredential.{CredentialPreview, IssueCredential, IssueCredentialIssuedFormat, IssueCredentialOfferFormat, IssueCredentialProposeFormat, IssueCredentialRequestFormat, OfferCredential, ProposeCredential, RequestCredential} +import org.hyperledger.identus.mercury.protocol.issuecredential.{ + CredentialPreview, + IssueCredential, + IssueCredentialIssuedFormat, + IssueCredentialOfferFormat, + IssueCredentialProposeFormat, + IssueCredentialRequestFormat, + OfferCredential, + ProposeCredential, + RequestCredential +} import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, EncoderOps, JsonDecoder, JsonEncoder} private case class TestCredentialType(a: String, b: Int, x: Long, name: String, dob: String) @@ -37,8 +47,7 @@ class UtilsCredentialSpec extends ZSuite { .build( fromDID = DidId("did:prism:test123from"), toDID = DidId("did:prism:test123to"), - credentials = - Seq(IssueCredentialIssuedFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), + credentials = Seq(IssueCredentialIssuedFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), ) .makeMessage @@ -61,8 +70,7 @@ class UtilsCredentialSpec extends ZSuite { fromDID = DidId("did:prism:test123from"), toDID = DidId("did:prism:test123to"), credential_preview = credentialPreview, - credentials = - Seq(IssueCredentialOfferFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), + credentials = Seq(IssueCredentialOfferFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), ) .makeMessage @@ -85,8 +93,7 @@ class UtilsCredentialSpec extends ZSuite { fromDID = DidId("did:prism:test123from"), toDID = DidId("did:prism:test123to"), credential_preview = Some(credentialPreview), - credentials = - Seq(IssueCredentialProposeFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), + credentials = Seq(IssueCredentialProposeFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), ) .makeMessage @@ -107,8 +114,7 @@ class UtilsCredentialSpec extends ZSuite { .build( fromDID = DidId("did:prism:test123from"), toDID = DidId("did:prism:test123to"), - credentials = - Seq(IssueCredentialRequestFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), + credentials = Seq(IssueCredentialRequestFormat.Unsupported(nameCredentialType) -> credential.toJson.getBytes()), ) .makeMessage diff --git a/mercury/resolver/src/test/scala/org/hyperledger/identus/resolvers/PeerDidResolverSpec.scala b/mercury/resolver/src/test/scala/org/hyperledger/identus/resolvers/PeerDidResolverSpec.scala index 39df5840ef..ff1385ddab 100644 --- a/mercury/resolver/src/test/scala/org/hyperledger/identus/resolvers/PeerDidResolverSpec.scala +++ b/mercury/resolver/src/test/scala/org/hyperledger/identus/resolvers/PeerDidResolverSpec.scala @@ -1,8 +1,8 @@ package org.hyperledger.identus.resolvers import munit.* import org.didcommx.peerdid.* -import zio.json.DecoderOps import zio.json.ast.Json +import zio.json.DecoderOps import scala.jdk.CollectionConverters.* diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala index 01b7fb4c5c..f086bac1b9 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialServiceNotifier.scala @@ -11,8 +11,8 @@ import org.hyperledger.identus.pollux.core.model.schema.CredentialSchemaRef import org.hyperledger.identus.pollux.core.repository.CredentialRepository import org.hyperledger.identus.pollux.vc.jwt.Issuer import org.hyperledger.identus.shared.models.* -import zio.json.ast.Json import zio.{Duration, UIO, URIO, URLayer, ZIO, ZLayer} +import zio.json.ast.Json import java.util.UUID diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala index fa96e3c063..2ec37a21c0 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala @@ -2,8 +2,8 @@ package org.hyperledger.identus.pollux.core.repository import org.hyperledger.identus.pollux.prex.PresentationDefinition import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} +import zio.{durationInt, ZIO, ZLayer} import zio.json.{DecoderOps, DeriveJsonDecoder, JsonDecoder} -import zio.{ZIO, ZLayer, durationInt} import zio.test.* import zio.test.Assertion.* diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala index fd0de8d5ec..32fbf4b8dc 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockCredentialService.scala @@ -9,8 +9,8 @@ import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError.* import org.hyperledger.identus.pollux.core.model.schema.CredentialSchemaRef import org.hyperledger.identus.pollux.vc.jwt.Issuer import org.hyperledger.identus.shared.models.* +import zio.{mock, Duration, IO, UIO, URIO, URLayer, ZIO, ZLayer} import zio.json.ast.Json -import zio.{Duration, IO, UIO, URIO, URLayer, ZIO, ZLayer, mock} import zio.mock.{Mock, Proxy} import java.util.UUID diff --git a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/DidResolver.scala b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/DidResolver.scala index 20c15013a8..49a3230f3e 100644 --- a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/DidResolver.scala +++ b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/DidResolver.scala @@ -1,7 +1,15 @@ package org.hyperledger.identus.pollux.vc.jwt import io.circe.Json -import org.hyperledger.identus.castor.core.model.did.w3c.{DIDDocumentRepr, DIDResolutionErrorRepr, PublicKeyJwk, PublicKeyRepr, PublicKeyReprOrRef, ServiceRepr, makeW3CResolver} +import org.hyperledger.identus.castor.core.model.did.w3c.{ + makeW3CResolver, + DIDDocumentRepr, + DIDResolutionErrorRepr, + PublicKeyJwk, + PublicKeyRepr, + PublicKeyReprOrRef, + ServiceRepr +} import org.hyperledger.identus.castor.core.service.DIDService import org.hyperledger.identus.shared.json.JsonInterop import zio.* From e2a9919ff77d5e49cff6ae10a90556fcb3f7d7d2 Mon Sep 17 00:00:00 2001 From: Benjamin Voiturier Date: Wed, 4 Dec 2024 15:30:01 +0100 Subject: [PATCH 22/22] fix: fix Json serialisation error when packing forward message for mediator Signed-off-by: Benjamin Voiturier --- .../hyperledger/identus/mercury/model/EncryptedMessage.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/EncryptedMessage.scala b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/EncryptedMessage.scala index 323a377d0f..5e5661016b 100644 --- a/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/EncryptedMessage.scala +++ b/mercury/models/src/main/scala/org/hyperledger/identus/mercury/model/EncryptedMessage.scala @@ -1,7 +1,7 @@ package org.hyperledger.identus.mercury.model import zio.json.ast.Json -import zio.json.EncoderOps +import zio.json.DecoderOps import java.util.Base64 @@ -9,7 +9,8 @@ trait EncryptedMessage { // (private val msg: PackEncryptedResult) { def string: String // = msg.getPackedMessage def base64: String = Base64.getUrlEncoder.encodeToString(string.getBytes) def asJson: Json.Obj = { - string.toJsonAST + string + .fromJson[Json] .flatMap(o => o.asObject match case None => Left(RuntimeException(s"Expecting Json Object got '$o'"))