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 7646a8b5b5..2624e36d11 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 @@ -1,6 +1,5 @@ package org.hyperledger.identus.issue.controller -import cats.Applicative import org.hyperledger.identus.agent.server.config.AppConfig import org.hyperledger.identus.agent.server.ControllerHelper import org.hyperledger.identus.agent.walletapi.model.PublicationState @@ -65,7 +64,10 @@ class IssueControllerImpl( pairwiseHolderDID = offerContext.pairwiseHolderDID, kidIssuer = request.issuingKid, thid = DidCommID(), - maybeSchemaIds = Applicative[Option].map2(request.schemaIds, request.schemaId.map(List(_)))(_ ++ _), + maybeSchemaIds = request.schemaId.map { + case schemaId: String => List(schemaId) + case schemaIds: List[String] => schemaIds + }, claims = jsonClaims, validityPeriod = request.validityPeriod, automaticIssuance = request.automaticIssuance.orElse(Some(true)), @@ -90,7 +92,10 @@ class IssueControllerImpl( pairwiseHolderDID = offerContext.pairwiseHolderDID, kidIssuer = request.issuingKid, thid = DidCommID(), - maybeSchemaIds = request.schemaId.map(List(_)), + maybeSchemaIds = request.schemaId.map { + case schemaId: String => List(schemaId) + case schemaIds: List[String] => schemaIds + }, claims = jsonClaims, validityPeriod = request.validityPeriod, automaticIssuance = request.automaticIssuance.orElse(Some(true)), diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/issue/controller/http/CreateIssueCredentialRecordRequest.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/issue/controller/http/CreateIssueCredentialRecordRequest.scala index eddce4d98e..a19ce368b0 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/issue/controller/http/CreateIssueCredentialRecordRequest.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/issue/controller/http/CreateIssueCredentialRecordRequest.scala @@ -9,6 +9,7 @@ import sttp.tapir.Schema.annotations.{description, encodedExample} import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} import java.util.UUID +import scala.language.implicitConversions /** A class to represent an incoming request to create a new credential offer. * @@ -33,10 +34,7 @@ final case class CreateIssueCredentialRecordRequest( validityPeriod: Option[Double] = None, @description(annotations.schemaId.description) @encodedExample(annotations.schemaId.example) - schemaId: Option[String] = None, - @description(annotations.schemaId.description) - @encodedExample(annotations.schemaId.example) - schemaIds: Option[List[String]] = None, + schemaId: Option[String | List[String]] = None, @description(annotations.credentialDefinitionId.description) @encodedExample(annotations.credentialDefinitionId.example) credentialDefinitionId: Option[UUID], @@ -88,21 +86,6 @@ object CreateIssueCredentialRecordRequest { ) ) - object schemaIds - extends Annotation[Option[List[String]]]( - description = """ - |The URL pointing to the JSON schema that will be used for this offer (should be 'http' or 'https'). - |When dereferenced, the returned content should be a JSON schema compliant with the '[Draft 2020-12](https://json-schema.org/draft/2020-12/release-notes)' version of the specification. - |Note that this parameter only applies when the offer is of type 'JWT'. - |""".stripMargin, - example = Some( - List( - "https://agent-host.com/cloud-agent/schema-registry/schemas/d9569cec-c81e-4779-aa86-0d5994d82676/schema", - "https://agent-host.com/cloud-agent/schema-registry/schemas/d9569cec-c81e-4779-aa86-0d5994d82676/schema2" - ) - ) - ) - object credentialDefinitionId extends Annotation[Option[UUID]]( description = """ @@ -196,6 +179,19 @@ object CreateIssueCredentialRecordRequest { ) } + given schemaIdEncoder: JsonEncoder[String | List[String]] = + JsonEncoder[String] + .orElseEither(JsonEncoder[List[String]]) + .contramap[String | List[String]] { + case schemaId: String => Left(schemaId) + case schemaIds: List[String] => Right(schemaIds) + } + + given schemaIdDecoder: JsonDecoder[String | List[String]] = + JsonDecoder[List[String]] + .map(schemaId => schemaId: String | List[String]) + .orElse(JsonDecoder[String].map(schemaId => schemaId: String | List[String])) + given encoder: JsonEncoder[CreateIssueCredentialRecordRequest] = DeriveJsonEncoder.gen[CreateIssueCredentialRecordRequest] @@ -203,6 +199,17 @@ object CreateIssueCredentialRecordRequest { DeriveJsonDecoder.gen[CreateIssueCredentialRecordRequest] given schemaJson: Schema[KeyId] = Schema.schemaForString.map[KeyId](v => Some(KeyId(v)))(KeyId.value) + + given schemaId: Schema[String | List[String]] = Schema + .schemaForEither(Schema.schemaForString, Schema.schemaForArray[String]) + .map[String | List[String]] { + case Left(value) => Some(value) + case Right(values) => Some(values.toList) + } { + case value: String => Left(value) + case values: List[String] => Right(values.toArray) + } + given schema: Schema[CreateIssueCredentialRecordRequest] = Schema.derived } 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 b2e0fcf012..c1e77224cb 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 @@ -42,11 +42,9 @@ object VcVerificationControllerImplSpec extends ZIOSpecDefault with VcVerificati maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( 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 6b48dbe6b7..34af9e443c 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 @@ -1151,7 +1151,7 @@ class CredentialServiceImpl( issuanceDate = issuanceDate, maybeExpirationDate = record.validityPeriod.map(sec => issuanceDate.plusSeconds(sec.toLong)), maybeCredentialSchema = record.schemaUris.map(ids => - Right(ids.map(id => org.hyperledger.identus.pollux.vc.jwt.CredentialSchema(id, VC_JSON_SCHEMA_TYPE))) + 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, diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImpl.scala index 7ad3c9588d..5cb0fbc27a 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImpl.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/verification/VcVerificationServiceImpl.scala @@ -2,7 +2,14 @@ package org.hyperledger.identus.pollux.core.service.verification import org.hyperledger.identus.pollux.core.model.schema.CredentialSchema import org.hyperledger.identus.pollux.core.service.URIDereferencer -import org.hyperledger.identus.pollux.vc.jwt.{CredentialPayload, DidResolver, JWT, JWTVerification, JwtCredential} +import org.hyperledger.identus.pollux.vc.jwt.{ + CredentialPayload, + CredentialSchema as JwtCredentialSchema, + DidResolver, + JWT, + JWTVerification, + JwtCredential +} import org.hyperledger.identus.pollux.vc.jwt.CredentialPayload.Implicits import zio.* @@ -54,7 +61,10 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe ZIO .fromOption(decodedJwt.maybeCredentialSchema) .mapError(error => VcVerificationServiceError.UnexpectedError(s"Missing Credential Schema: $error")) - credentialSchemas = credentialSchema.fold(List(_), identity) + credentialSchemas = credentialSchema match { + case schema: JwtCredentialSchema => List(schema) + case schemaList: List[JwtCredentialSchema] => schemaList + } result <- ZIO.collectAll( credentialSchemas.map(credentialSchema => @@ -98,7 +108,10 @@ class VcVerificationServiceImpl(didResolver: DidResolver, uriDereferencer: URIDe ZIO .fromOption(decodedJwt.maybeCredentialSchema) .mapError(error => VcVerificationServiceError.UnexpectedError(s"Missing Credential Schema: $error")) - credentialSchemas = credentialSchema.fold(List(_), identity) + credentialSchemas = credentialSchema match { + case schema: JwtCredentialSchema => List(schema) + case schemaList: List[JwtCredentialSchema] => schemaList + } result <- ZIO.collectAll( credentialSchemas.map(credentialSchema => 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 62be6e2e87..0ec283e663 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 @@ -33,11 +33,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( @@ -100,11 +98,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( @@ -167,11 +163,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( @@ -234,11 +228,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( @@ -308,11 +300,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( @@ -379,11 +369,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "resource:///vc-schema-personal.json", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "resource:///vc-schema-personal.json", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( @@ -450,16 +438,14 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Right( - List( - CredentialSchema( - id = "resource:///vc-schema-personal.json", - `type` = "JsonSchemaValidator2018" - ), - CredentialSchema( - id = "resource:///vc-schema-driver-license.json", - `type` = "JsonSchemaValidator2018" - ) + List( + CredentialSchema( + id = "resource:///vc-schema-personal.json", + `type` = "JsonSchemaValidator2018" + ), + CredentialSchema( + id = "resource:///vc-schema-driver-license.json", + `type` = "JsonSchemaValidator2018" ) ) ), @@ -530,16 +516,14 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Right( - List( - CredentialSchema( - id = "resource:///vc-schema-personal.json", - `type` = "JsonSchemaValidator2018" - ), - CredentialSchema( - id = "resource:///vc-schema-driver-license.json", - `type` = "JsonSchemaValidator2018" - ) + List( + CredentialSchema( + id = "resource:///vc-schema-personal.json", + `type` = "JsonSchemaValidator2018" + ), + CredentialSchema( + id = "resource:///vc-schema-driver-license.json", + `type` = "JsonSchemaValidator2018" ) ) ), @@ -611,11 +595,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( @@ -679,11 +661,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( @@ -747,11 +727,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( @@ -815,11 +793,9 @@ object VcVerificationServiceImplSpec extends ZIOSpecDefault with VcVerificationS maybeValidFrom = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeValidUntil = Some(Instant.parse("2010-01-12T00:00:00Z")), maybeCredentialSchema = Some( - Left( - CredentialSchema( - id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", - `type` = "JsonSchemaValidator2018" - ) + CredentialSchema( + id = "did:work:MDP8AsFhHzhwUvGNuYkX7T;id=06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", + `type` = "JsonSchemaValidator2018" ) ), credentialSubject = Json.obj( diff --git a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiableCredentialPayload.scala b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiableCredentialPayload.scala index cb7d84dd0b..1e71ec3eef 100644 --- a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiableCredentialPayload.scala +++ b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiableCredentialPayload.scala @@ -87,7 +87,7 @@ sealed trait CredentialPayload { def maybeTermsOfUse: Option[Json] - def maybeCredentialSchema: Option[Either[CredentialSchema, List[CredentialSchema]]] + def maybeCredentialSchema: Option[CredentialSchema | List[CredentialSchema]] def credentialSubject: Json @@ -137,7 +137,7 @@ sealed trait CredentialPayload { case class JwtVc( `@context`: Set[String], `type`: Set[String], - maybeCredentialSchema: Option[Either[CredentialSchema, List[CredentialSchema]]], + maybeCredentialSchema: Option[CredentialSchema | List[CredentialSchema]], credentialSubject: Json, maybeValidFrom: Option[Instant], maybeValidUntil: Option[Instant], @@ -177,7 +177,7 @@ case class W3cCredentialPayload( issuer: Either[String, CredentialIssuer], issuanceDate: Instant, maybeExpirationDate: Option[Instant], - override val maybeCredentialSchema: Option[Either[CredentialSchema, List[CredentialSchema]]], + override val maybeCredentialSchema: Option[CredentialSchema | List[CredentialSchema]], override val credentialSubject: Json, override val maybeCredentialStatus: Option[CredentialStatus], override val maybeRefreshService: Option[RefreshService], @@ -241,9 +241,9 @@ object CredentialPayload { case Right(issuer) => issuer.asJson } - implicit val eitherCredentialSchemaOrListEncoder: Encoder[Either[CredentialSchema, List[CredentialSchema]]] = { - case Left(credentialSchema) => credentialSchema.asJson - case Right(credentialSchemas) => credentialSchemas.asJson + implicit val credentialSchemaOrListEncoder: Encoder[CredentialSchema | List[CredentialSchema]] = Encoder.instance { + case schema: CredentialSchema => Encoder[CredentialSchema].apply(schema) + case schemaList: List[CredentialSchema] => Encoder[List[CredentialSchema]].apply(schemaList) } implicit val w3cCredentialPayloadEncoder: Encoder[W3cCredentialPayload] = @@ -373,10 +373,10 @@ object CredentialPayload { implicit val eitherStringOrCredentialIssuerDecoder: Decoder[Either[String, CredentialIssuer]] = Decoder[String].map(Left(_)).or(Decoder[CredentialIssuer].map(Right(_))) - implicit val eitherCredentialSchemaOrListDecoder: Decoder[Either[CredentialSchema, List[CredentialSchema]]] = + implicit val credentialSchemaOrListDecoder: Decoder[CredentialSchema | List[CredentialSchema]] = Decoder[CredentialSchema] - .map(Left(_)) - .or(Decoder[List[CredentialSchema]].map(Right(_))) + .map(schema => schema: CredentialSchema | List[CredentialSchema]) + .or(Decoder[List[CredentialSchema]].map(schema => schema: CredentialSchema | List[CredentialSchema])) implicit val w3cCredentialPayloadDecoder: Decoder[W3cCredentialPayload] = (c: HCursor) => @@ -397,7 +397,7 @@ object CredentialPayload { maybeValidUntil <- c.downField("validUntil").as[Option[Instant]] maybeCredentialSchema <- c .downField("credentialSchema") - .as[Option[Either[CredentialSchema, List[CredentialSchema]]]] + .as[Option[CredentialSchema | List[CredentialSchema]]] credentialSubject <- c.downField("credentialSubject").as[Json] maybeCredentialStatus <- c.downField("credentialStatus").as[Option[CredentialStatus]] maybeRefreshService <- c.downField("refreshService").as[Option[RefreshService]] @@ -436,7 +436,7 @@ object CredentialPayload { .orElse(c.downField("type").as[String].map(Set(_))) maybeCredentialSchema <- c .downField("credentialSchema") - .as[Option[Either[CredentialSchema, List[CredentialSchema]]]] + .as[Option[CredentialSchema | List[CredentialSchema]]] credentialSubject <- c.downField("credentialSubject").as[Json] maybeCredentialStatus <- c.downField("credentialStatus").as[Option[CredentialStatus]] maybeRefreshService <- c.downField("refreshService").as[Option[RefreshService]]