diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/DidCommID.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/DidCommID.scala new file mode 100644 index 0000000000..fdab0c041e --- /dev/null +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/DidCommID.scala @@ -0,0 +1,10 @@ +package io.iohk.atala.pollux.core.model + +import java.util.UUID + +// type DidCommID = String +opaque type DidCommID = String +object DidCommID: + def apply(value: String): DidCommID = value + def apply(): DidCommID = UUID.randomUUID.toString() + extension (id: DidCommID) def value: String = id diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/IssueCredentialRecord.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/IssueCredentialRecord.scala index 16817c9b38..02d461bd63 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/IssueCredentialRecord.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/IssueCredentialRecord.scala @@ -1,7 +1,6 @@ package io.iohk.atala.pollux.core.model import io.iohk.atala.prism.crypto.MerkleInclusionProof -import java.util.UUID import io.iohk.atala.mercury.protocol.issuecredential.OfferCredential import io.iohk.atala.mercury.protocol.issuecredential.RequestCredential import io.iohk.atala.mercury.protocol.issuecredential.IssueCredential @@ -11,10 +10,10 @@ import io.iohk.atala.pollux.vc.jwt.JwtCredential import io.iohk.atala.castor.core.model.did.CanonicalPrismDID final case class IssueCredentialRecord( - id: UUID, + id: DidCommID, createdAt: Instant, updatedAt: Option[Instant], - thid: UUID, + thid: DidCommID, schemaId: Option[String], role: Role, subjectId: String, @@ -30,7 +29,7 @@ final case class IssueCredentialRecord( issuingDID: Option[CanonicalPrismDID] ) final case class ValidIssuedCredentialRecord( - id: UUID, + id: DidCommID, issuedCredentialRaw: Option[String], subjectId: String ) diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/PresentationRecord.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/PresentationRecord.scala index ea74cebde1..c59705def3 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/PresentationRecord.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/PresentationRecord.scala @@ -1,17 +1,16 @@ package io.iohk.atala.pollux.core.model import io.iohk.atala.prism.crypto.MerkleInclusionProof -import java.util.UUID import io.iohk.atala.mercury.protocol.presentproof.ProposePresentation import io.iohk.atala.mercury.protocol.presentproof.RequestPresentation import io.iohk.atala.mercury.protocol.presentproof.Presentation import io.iohk.atala.mercury.model.DidId import java.time.Instant final case class PresentationRecord( - id: UUID, + id: DidCommID, createdAt: Instant, updatedAt: Option[Instant], - thid: UUID, + thid: DidCommID, schemaId: Option[String], connectionId: Option[String], role: PresentationRecord.Role, diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/error/CredentialServiceError.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/error/CredentialServiceError.scala index 93def26510..742e9e6ad0 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/error/CredentialServiceError.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/error/CredentialServiceError.scala @@ -2,14 +2,15 @@ package io.iohk.atala.pollux.core.model.error import java.util.UUID import io.iohk.atala.pollux.vc.jwt.W3cCredentialPayload +import io.iohk.atala.pollux.core.model.DidCommID sealed trait CredentialServiceError object CredentialServiceError { final case class RepositoryError(cause: Throwable) extends CredentialServiceError - final case class RecordIdNotFound(recordId: UUID) extends CredentialServiceError - final case class OperationNotExecuted(recordId: UUID, info: String) extends CredentialServiceError - final case class ThreadIdNotFound(thid: UUID) extends CredentialServiceError + final case class RecordIdNotFound(recordId: DidCommID) extends CredentialServiceError + final case class OperationNotExecuted(recordId: DidCommID, info: String) extends CredentialServiceError + final case class ThreadIdNotFound(thid: DidCommID) extends CredentialServiceError final case class InvalidFlowStateError(msg: String) extends CredentialServiceError final case class UnexpectedError(msg: String) extends CredentialServiceError final case class UnsupportedDidFormat(did: String) extends CredentialServiceError diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/error/PresentationError.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/error/PresentationError.scala index 8b97c5bd4d..1adf1b6717 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/error/PresentationError.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/error/PresentationError.scala @@ -1,13 +1,13 @@ package io.iohk.atala.pollux.core.model.error -import java.util.UUID +import io.iohk.atala.pollux.core.model.DidCommID sealed trait PresentationError object PresentationError { final case class RepositoryError(cause: Throwable) extends PresentationError - final case class RecordIdNotFound(recordId: UUID) extends PresentationError - final case class ThreadIdNotFound(thid: UUID) extends PresentationError + final case class RecordIdNotFound(recordId: DidCommID) extends PresentationError + final case class ThreadIdNotFound(thid: DidCommID) extends PresentationError final case class InvalidFlowStateError(msg: String) extends PresentationError final case class UnexpectedError(msg: String) extends PresentationError final case class IssuedCredentialNotFoundError(cause: Throwable) extends PresentationError diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepository.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepository.scala index 0bd890b609..6c6110b4c3 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepository.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepository.scala @@ -5,7 +5,6 @@ import io.iohk.atala.pollux.core.model._ import io.iohk.atala.prism.crypto.MerkleInclusionProof import zio.* -import java.util.UUID import io.iohk.atala.mercury.protocol.issuecredential.RequestCredential import io.iohk.atala.mercury.protocol.issuecredential.IssueCredential import io.iohk.atala.pollux.core.model.IssueCredentialRecord.ProtocolState @@ -13,42 +12,43 @@ import io.iohk.atala.pollux.core.model.IssueCredentialRecord.ProtocolState trait CredentialRepository[F[_]] { def createIssueCredentialRecord(record: IssueCredentialRecord): F[Int] def getIssueCredentialRecords(): F[Seq[IssueCredentialRecord]] - def getIssueCredentialRecord(recordId: UUID): F[Option[IssueCredentialRecord]] + def getIssueCredentialRecord(recordId: DidCommID): F[Option[IssueCredentialRecord]] def getIssueCredentialRecordsByStates(states: IssueCredentialRecord.ProtocolState*): F[Seq[IssueCredentialRecord]] def updateCredentialRecordStateAndProofByCredentialIdBulk( - idsStatesAndProofs: Seq[(UUID, IssueCredentialRecord.PublicationState, MerkleInclusionProof)] + idsStatesAndProofs: Seq[(DidCommID, IssueCredentialRecord.PublicationState, MerkleInclusionProof)] ): F[Int] - def getIssueCredentialRecordByThreadId(thid: UUID): F[Option[IssueCredentialRecord]] + def getIssueCredentialRecordByThreadId(thid: DidCommID): F[Option[IssueCredentialRecord]] def updateCredentialRecordProtocolState( - recordId: UUID, + recordId: DidCommID, from: IssueCredentialRecord.ProtocolState, to: IssueCredentialRecord.ProtocolState ): F[Int] + def updateCredentialRecordPublicationState( - recordId: UUID, + recordId: DidCommID, from: Option[IssueCredentialRecord.PublicationState], to: Option[IssueCredentialRecord.PublicationState] ): F[Int] - def updateWithRequestCredential(recordId: UUID, request: RequestCredential, protocolState: ProtocolState): F[Int] + def updateWithRequestCredential(recordId: DidCommID, request: RequestCredential, protocolState: ProtocolState): F[Int] def updateWithIssueCredential( - recordId: UUID, + recordId: DidCommID, issue: IssueCredential, protocolState: ProtocolState ): F[Int] def updateWithIssuedRawCredential( - recordId: UUID, + recordId: DidCommID, issue: IssueCredential, issuedRawCredential: String, protocolState: ProtocolState ): F[Int] - def deleteIssueCredentialRecord(recordId: UUID): F[Int] + def deleteIssueCredentialRecord(recordId: DidCommID): F[Int] - def getValidIssuedCredentials(recordId: Seq[UUID]): F[Seq[ValidIssuedCredentialRecord]] + def getValidIssuedCredentials(recordId: Seq[DidCommID]): F[Seq[ValidIssuedCredentialRecord]] } diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepositoryInMemory.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepositoryInMemory.scala index a50cdaeb23..2d49acef8f 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepositoryInMemory.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialRepositoryInMemory.scala @@ -2,10 +2,9 @@ package io.iohk.atala.pollux.core.repository import io.iohk.atala.mercury.protocol.issuecredential.IssueCredential import io.iohk.atala.mercury.protocol.issuecredential.RequestCredential -import io.iohk.atala.pollux.core.model.IssueCredentialRecord +import io.iohk.atala.pollux.core.model._ import io.iohk.atala.pollux.core.model.IssueCredentialRecord.ProtocolState import io.iohk.atala.pollux.core.model.IssueCredentialRecord.PublicationState -import io.iohk.atala.pollux.core.model.ValidIssuedCredentialRecord import io.iohk.atala.pollux.core.model.error.CredentialRepositoryError._ import io.iohk.atala.prism.crypto.MerkleInclusionProof import zio.* @@ -13,16 +12,17 @@ import zio.* import java.time.Instant import java.util.UUID -class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord]]) extends CredentialRepository[Task] { +class CredentialRepositoryInMemory(storeRef: Ref[Map[DidCommID, IssueCredentialRecord]]) + extends CredentialRepository[Task] { override def updateCredentialRecordPublicationState( - recordId: UUID, + recordId: DidCommID, from: Option[PublicationState], to: Option[PublicationState] ): Task[Int] = { for { store <- storeRef.get - maybeRecord = store.find((uuid, record) => uuid == recordId && record.publicationState == from).map(_._2) + maybeRecord = store.find((id, record) => id == recordId && record.publicationState == from).map(_._2) count <- maybeRecord .map(record => for { @@ -46,7 +46,7 @@ class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord } yield 1 } - override def getIssueCredentialRecord(recordId: UUID): Task[Option[IssueCredentialRecord]] = { + override def getIssueCredentialRecord(recordId: DidCommID): Task[Option[IssueCredentialRecord]] = { for { store <- storeRef.get record = store.get(recordId) @@ -60,13 +60,13 @@ class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord } override def updateCredentialRecordProtocolState( - recordId: UUID, + recordId: DidCommID, from: ProtocolState, to: ProtocolState ): Task[Int] = { for { store <- storeRef.get - maybeRecord = store.find((uuid, record) => uuid == recordId && record.protocolState == from).map(_._2) + maybeRecord = store.find((id, record) => id == recordId && record.protocolState == from).map(_._2) count <- maybeRecord .map(record => for { @@ -78,7 +78,7 @@ class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord } override def updateWithIssuedRawCredential( - recordId: UUID, + recordId: DidCommID, issue: IssueCredential, issuedRawCredential: String, protocolState: ProtocolState @@ -105,7 +105,7 @@ class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord } yield count } - override def getValidIssuedCredentials(recordId: Seq[UUID]): Task[Seq[ValidIssuedCredentialRecord]] = { + override def getValidIssuedCredentials(recordId: Seq[DidCommID]): Task[Seq[ValidIssuedCredentialRecord]] = { for { store <- storeRef.get } yield store.values @@ -114,7 +114,7 @@ class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord .toSeq } - override def deleteIssueCredentialRecord(recordId: UUID): Task[Int] = { + override def deleteIssueCredentialRecord(recordId: DidCommID): Task[Int] = { for { maybeRecord <- getIssueCredentialRecord(recordId) count <- maybeRecord @@ -128,7 +128,7 @@ class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord } override def updateWithIssueCredential( - recordId: UUID, + recordId: DidCommID, issue: IssueCredential, protocolState: ProtocolState ): Task[Int] = { @@ -159,14 +159,14 @@ class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord } yield store.values.filter(rec => states.contains(rec.protocolState)).toSeq } - override def getIssueCredentialRecordByThreadId(thid: UUID): Task[Option[IssueCredentialRecord]] = { + override def getIssueCredentialRecordByThreadId(thid: DidCommID): Task[Option[IssueCredentialRecord]] = { for { store <- storeRef.get } yield store.values.find(_.thid == thid) } override def updateWithRequestCredential( - recordId: UUID, + recordId: DidCommID, request: RequestCredential, protocolState: ProtocolState ): Task[Int] = { @@ -192,7 +192,7 @@ class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord } override def updateCredentialRecordStateAndProofByCredentialIdBulk( - idsStatesAndProofs: Seq[(UUID, PublicationState, MerkleInclusionProof)] + idsStatesAndProofs: Seq[(DidCommID, PublicationState, MerkleInclusionProof)] ): Task[Int] = ??? } @@ -200,7 +200,7 @@ class CredentialRepositoryInMemory(storeRef: Ref[Map[UUID, IssueCredentialRecord object CredentialRepositoryInMemory { val layer: ULayer[CredentialRepository[Task]] = ZLayer.fromZIO( Ref - .make(Map.empty[UUID, IssueCredentialRecord]) + .make(Map.empty[DidCommID, IssueCredentialRecord]) .map(CredentialRepositoryInMemory(_)) ) } diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/PresentationRepository.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/PresentationRepository.scala index b807d250c3..d7f39bb710 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/PresentationRepository.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/PresentationRepository.scala @@ -1,7 +1,6 @@ package io.iohk.atala.pollux.core.repository -import io.iohk.atala.pollux.core.model.EncodedJWTCredential -import io.iohk.atala.pollux.core.model.PresentationRecord +import io.iohk.atala.pollux.core.model._ import io.iohk.atala.prism.crypto.MerkleInclusionProof import zio.* @@ -12,21 +11,33 @@ import io.iohk.atala.pollux.core.model.PresentationRecord.ProtocolState trait PresentationRepository[F[_]] { def createPresentationRecord(record: PresentationRecord): F[Int] def getPresentationRecords(): F[Seq[PresentationRecord]] - def getPresentationRecord(recordId: UUID): F[Option[PresentationRecord]] + def getPresentationRecord(recordId: DidCommID): F[Option[PresentationRecord]] def getPresentationRecordsByStates(states: PresentationRecord.ProtocolState*): F[Seq[PresentationRecord]] - def getPresentationRecordByThreadId(thid: UUID): F[Option[PresentationRecord]] + def getPresentationRecordByThreadId(thid: DidCommID): F[Option[PresentationRecord]] def updatePresentationRecordProtocolState( - recordId: UUID, + recordId: DidCommID, from: PresentationRecord.ProtocolState, to: PresentationRecord.ProtocolState ): F[Int] - def updateWithRequestPresentation(recordId: UUID, request: RequestPresentation, protocolState: ProtocolState): F[Int] - def updateWithProposePresentation(recordId: UUID, request: ProposePresentation, protocolState: ProtocolState): F[Int] - def updateWithPresentation(recordId: UUID, presentation: Presentation, protocolState: ProtocolState): F[Int] + def updateWithRequestPresentation( + recordId: DidCommID, + request: RequestPresentation, + protocolState: ProtocolState + ): F[Int] + def updateWithProposePresentation( + recordId: DidCommID, + request: ProposePresentation, + protocolState: ProtocolState + ): F[Int] + def updateWithPresentation( + recordId: DidCommID, + presentation: Presentation, + protocolState: ProtocolState + ): F[Int] def updatePresentationWithCredentialsToUse( - recordId: UUID, + recordId: DidCommID, credentialsToUse: Option[Seq[String]], protocolState: ProtocolState ): F[Int] diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialService.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialService.scala index 3e720e4390..f5f92c775e 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialService.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialService.scala @@ -4,8 +4,7 @@ import io.iohk.atala.mercury.model.DidId import io.iohk.atala.mercury.protocol.issuecredential.IssueCredential import io.iohk.atala.mercury.protocol.issuecredential.OfferCredential import io.iohk.atala.mercury.protocol.issuecredential.RequestCredential -import io.iohk.atala.pollux.core.model.IssueCredentialRecord -import io.iohk.atala.pollux.core.model.PublishedBatchData +import io.iohk.atala.pollux.core.model._ import io.iohk.atala.pollux.core.model.error.CredentialServiceError import io.iohk.atala.pollux.core.model.error.CredentialServiceError._ import io.iohk.atala.pollux.vc.jwt.Issuer @@ -51,12 +50,12 @@ trait CredentialService { ) } - def extractIdFromCredential(credential: W3cCredentialPayload): Option[UUID] + def extractIdFromCredential(credential: W3cCredentialPayload): Option[DidCommID] def createIssueCredentialRecord( pairwiseIssuerDID: DidId, pairwiseHolderDID: DidId, - thid: UUID, + thid: DidCommID, subjectId: String, schemaId: Option[String], claims: Map[String, String], @@ -80,15 +79,15 @@ trait CredentialService { /** Get the CredentialRecord by the record's id. If the record's id is not found the value None will be return * instead. */ - def getIssueCredentialRecord(recordId: UUID): IO[CredentialServiceError, Option[IssueCredentialRecord]] + def getIssueCredentialRecord(recordId: DidCommID): IO[CredentialServiceError, Option[IssueCredentialRecord]] def receiveCredentialOffer(offer: OfferCredential): IO[CredentialServiceError, IssueCredentialRecord] - def acceptCredentialOffer(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] + def acceptCredentialOffer(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] def receiveCredentialRequest(request: RequestCredential): IO[CredentialServiceError, IssueCredentialRecord] - def acceptCredentialRequest(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] + def acceptCredentialRequest(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] def createCredentialPayloadFromRecord( record: IssueCredentialRecord, @@ -107,21 +106,21 @@ trait CredentialService { def receiveCredentialIssue(issue: IssueCredential): IO[CredentialServiceError, IssueCredentialRecord] - def markOfferSent(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] + def markOfferSent(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] - def markRequestSent(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] + def markRequestSent(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] def markCredentialGenerated( - recordId: UUID, + recordId: DidCommID, issueCredential: IssueCredential ): IO[CredentialServiceError, IssueCredentialRecord] - def markCredentialSent(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] + def markCredentialSent(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] - def markCredentialPublicationPending(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] + def markCredentialPublicationPending(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] - def markCredentialPublicationQueued(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] + def markCredentialPublicationQueued(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] - def markCredentialPublished(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] + def markCredentialPublished(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] } diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala index ea19684e08..594731cbb5 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala @@ -13,8 +13,7 @@ import io.iohk.atala.mercury.protocol.issuecredential.CredentialPreview import io.iohk.atala.mercury.protocol.issuecredential.IssueCredential import io.iohk.atala.mercury.protocol.issuecredential.OfferCredential import io.iohk.atala.mercury.protocol.issuecredential.RequestCredential -import io.iohk.atala.pollux.core.model.IssueCredentialRecord -import io.iohk.atala.pollux.core.model.PublishedBatchData +import io.iohk.atala.pollux.core.model._ import io.iohk.atala.pollux.core.model.error.CredentialServiceError import io.iohk.atala.pollux.core.model.error.CredentialServiceError._ import io.iohk.atala.pollux.core.repository.CredentialRepository @@ -36,7 +35,7 @@ import java.time.Instant import java.util.UUID import io.iohk.atala.castor.core.model.did.CanonicalPrismDID import io.iohk.atala.mercury.model.AttachmentDescriptor -import io.iohk.atala.pollux.core.model.CredentialOfferAttachment +import io.iohk.atala.pollux.core.model._ object CredentialServiceImpl { val layer: URLayer[IrisServiceStub & CredentialRepository[Task], CredentialService] = @@ -50,8 +49,8 @@ private class CredentialServiceImpl( import IssueCredentialRecord._ - override def extractIdFromCredential(credential: W3cCredentialPayload): Option[UUID] = - credential.maybeId.map(_.split("/").last).map(UUID.fromString) + override def extractIdFromCredential(credential: W3cCredentialPayload): Option[DidCommID] = + credential.maybeId.map(_.split("/").last).map(DidCommID(_)) override def getIssueCredentialRecords(): IO[CredentialServiceError, Seq[IssueCredentialRecord]] = { for { @@ -61,7 +60,9 @@ private class CredentialServiceImpl( } yield records } - override def getIssueCredentialRecord(recordId: UUID): IO[CredentialServiceError, Option[IssueCredentialRecord]] = { + override def getIssueCredentialRecord( + recordId: DidCommID + ): IO[CredentialServiceError, Option[IssueCredentialRecord]] = { for { record <- credentialRepository .getIssueCredentialRecord(recordId) @@ -72,7 +73,7 @@ private class CredentialServiceImpl( override def createIssueCredentialRecord( pairwiseIssuerDID: DidId, pairwiseHolderDID: DidId, - thid: UUID, + thid: DidCommID, subjectId: String, schemaId: Option[String], claims: Map[String, String], @@ -92,7 +93,7 @@ private class CredentialServiceImpl( ) record <- ZIO.succeed( IssueCredentialRecord( - id = UUID.randomUUID(), + id = DidCommID(), createdAt = Instant.now, updatedAt = None, thid = thid, @@ -148,10 +149,10 @@ private class CredentialServiceImpl( } record <- ZIO.succeed( IssueCredentialRecord( - id = UUID.randomUUID(), + id = DidCommID(), createdAt = Instant.now, updatedAt = None, - thid = UUID.fromString(offer.thid.getOrElse(offer.id)), + thid = DidCommID(offer.thid.getOrElse(offer.id)), schemaId = None, role = Role.Holder, subjectId = offerAttachment.subjectId, @@ -177,11 +178,11 @@ private class CredentialServiceImpl( } yield record } - override def acceptCredentialOffer(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] = { + override def acceptCredentialOffer(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] = { for { - record <- getRecordWithState(recordId, ProtocolState.OfferReceived) + record0 <- getRecordWithState(recordId, ProtocolState.OfferReceived) offer <- ZIO - .fromOption(record.offerCredentialData) + .fromOption(record0.offerCredentialData) .mapError(_ => InvalidFlowStateError(s"No offer found for this record: $recordId")) request = createDidCommRequestCredential(offer) count <- credentialRepository @@ -191,7 +192,7 @@ private class CredentialServiceImpl( case 1 => ZIO.succeed(()) case n => ZIO.fail(RecordIdNotFound(recordId)) record <- credentialRepository - .getIssueCredentialRecord(record.id) + .getIssueCredentialRecord(record0.id) .mapError(RepositoryError.apply) .flatMap { case None => ZIO.fail(RecordIdNotFound(recordId)) @@ -204,7 +205,11 @@ private class CredentialServiceImpl( request: RequestCredential ): IO[CredentialServiceError, IssueCredentialRecord] = { for { - record <- getRecordFromThreadIdWithState(request.thid, ProtocolState.OfferPending, ProtocolState.OfferSent) + record <- getRecordFromThreadIdWithState( + request.thid.map(DidCommID(_)), + ProtocolState.OfferPending, + ProtocolState.OfferSent + ) _ <- credentialRepository .updateWithRequestCredential(record.id, request, ProtocolState.RequestReceived) .flatMap { @@ -219,7 +224,7 @@ private class CredentialServiceImpl( } yield record } - override def acceptCredentialRequest(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] = { + override def acceptCredentialRequest(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] = { for { record <- getRecordWithState(recordId, ProtocolState.RequestReceived) request <- ZIO @@ -244,7 +249,11 @@ private class CredentialServiceImpl( ): IO[CredentialServiceError, IssueCredentialRecord] = { val rawIssuedCredential = issue.attachments.map(_.data.asJson.noSpaces).headOption.getOrElse("???") // TODO for { - record <- getRecordFromThreadIdWithState(issue.thid, ProtocolState.RequestPending, ProtocolState.RequestSent) + record <- getRecordFromThreadIdWithState( + issue.thid.map(DidCommID(_)), + ProtocolState.RequestPending, + ProtocolState.RequestSent + ) _ <- credentialRepository .updateWithIssuedRawCredential(record.id, issue, rawIssuedCredential, ProtocolState.CredentialReceived) .flatMap { @@ -259,14 +268,14 @@ private class CredentialServiceImpl( } yield record } - override def markOfferSent(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] = + override def markOfferSent(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] = updateCredentialRecordProtocolState( recordId, IssueCredentialRecord.ProtocolState.OfferPending, IssueCredentialRecord.ProtocolState.OfferSent ) - override def markRequestSent(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] = + override def markRequestSent(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] = updateCredentialRecordProtocolState( recordId, IssueCredentialRecord.ProtocolState.RequestPending, @@ -274,7 +283,7 @@ private class CredentialServiceImpl( ) override def markCredentialGenerated( - recordId: UUID, + recordId: DidCommID, issueCredential: IssueCredential ): IO[CredentialServiceError, IssueCredentialRecord] = { for { @@ -300,7 +309,7 @@ private class CredentialServiceImpl( } yield record } - override def markCredentialSent(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] = + override def markCredentialSent(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] = updateCredentialRecordProtocolState( recordId, IssueCredentialRecord.ProtocolState.CredentialGenerated, @@ -308,7 +317,7 @@ private class CredentialServiceImpl( ) override def markCredentialPublicationPending( - recordId: UUID + recordId: DidCommID ): IO[CredentialServiceError, IssueCredentialRecord] = updateCredentialRecordPublicationState( recordId, @@ -317,7 +326,7 @@ private class CredentialServiceImpl( ) override def markCredentialPublicationQueued( - recordId: UUID + recordId: DidCommID ): IO[CredentialServiceError, IssueCredentialRecord] = updateCredentialRecordPublicationState( recordId, @@ -325,7 +334,7 @@ private class CredentialServiceImpl( Some(IssueCredentialRecord.PublicationState.PublicationQueued) ) - override def markCredentialPublished(recordId: UUID): IO[CredentialServiceError, IssueCredentialRecord] = + override def markCredentialPublished(recordId: DidCommID): IO[CredentialServiceError, IssueCredentialRecord] = updateCredentialRecordPublicationState( recordId, Some(IssueCredentialRecord.PublicationState.PublicationQueued), @@ -333,7 +342,7 @@ private class CredentialServiceImpl( ) private[this] def getRecordWithState( - recordId: UUID, + recordId: DidCommID, state: ProtocolState ): IO[CredentialServiceError, IssueCredentialRecord] = { for { @@ -351,14 +360,13 @@ private class CredentialServiceImpl( } private[this] def getRecordFromThreadIdWithState( - thid: Option[String], + thid: Option[DidCommID], states: ProtocolState* ): IO[CredentialServiceError, IssueCredentialRecord] = { for { thid <- ZIO .fromOption(thid) .mapError(_ => UnexpectedError("No `thid` found in credential request")) - .map(UUID.fromString) maybeRecord <- credentialRepository .getIssueCredentialRecordByThreadId(thid) .mapError(RepositoryError.apply) @@ -376,7 +384,7 @@ private class CredentialServiceImpl( pairwiseIssuerDID: DidId, pairwiseHolderDID: DidId, claims: Map[String, String], - thid: UUID, + thid: DidCommID, subjectId: String ): OfferCredential = { val attributes = claims.map { case (k, v) => Attribute(k, v) } @@ -436,7 +444,7 @@ private class CredentialServiceImpl( * TODO: this should be improved to behave exactly like atomic operation. */ private[this] def updateCredentialRecordProtocolState( - id: UUID, + id: DidCommID, from: IssueCredentialRecord.ProtocolState, to: IssueCredentialRecord.ProtocolState ): IO[CredentialServiceError, IssueCredentialRecord] = { @@ -489,7 +497,7 @@ private class CredentialServiceImpl( * TODO: this should be improved to behave exactly like atomic operation. */ private[this] def updateCredentialRecordPublicationState( - id: UUID, + id: DidCommID, from: Option[IssueCredentialRecord.PublicationState], to: Option[IssueCredentialRecord.PublicationState] ): IO[CredentialServiceError, IssueCredentialRecord] = { diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationService.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationService.scala index b1423e1eb2..1c61a154bf 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationService.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/PresentationService.scala @@ -28,7 +28,7 @@ import java.time.Instant import io.iohk.atala.mercury.protocol.presentproof.RequestPresentation import java.security.PublicKey import io.iohk.atala.mercury.protocol.issuecredential.IssueCredential -import io.iohk.atala.pollux.core.model.IssueCredentialRecord +import io.iohk.atala.pollux.core.model._ import io.iohk.atala.pollux.core.repository.CredentialRepository import java.{util => ju} import cats.syntax.all._ @@ -39,7 +39,7 @@ trait PresentationService { def extractIdFromCredential(credential: W3cCredentialPayload): Option[UUID] def createPresentationRecord( - thid: UUID, + thid: DidCommID, subjectDid: DidId, connectionId: Option[String], proofTypes: Seq[ProofType], @@ -49,7 +49,7 @@ trait PresentationService { def getPresentationRecords(): IO[PresentationError, Seq[PresentationRecord]] def createPresentationPayloadFromRecord( - record: UUID, + record: DidCommID, issuer: Issuer, issuanceDate: Instant ): IO[PresentationError, PresentationPayload] @@ -58,7 +58,7 @@ trait PresentationService { state: PresentationRecord.ProtocolState* ): IO[PresentationError, Seq[PresentationRecord]] - def getPresentationRecord(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def getPresentationRecord(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] def receiveRequestPresentation( connectionId: Option[String], @@ -66,40 +66,40 @@ trait PresentationService { ): IO[PresentationError, PresentationRecord] def acceptRequestPresentation( - recordId: UUID, + recordId: DidCommID, crecentialsToUse: Seq[String] ): IO[PresentationError, Option[PresentationRecord]] - def rejectRequestPresentation(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def rejectRequestPresentation(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] def receiveProposePresentation(request: ProposePresentation): IO[PresentationError, Option[PresentationRecord]] - def acceptProposePresentation(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def acceptProposePresentation(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] def receivePresentation(presentation: Presentation): IO[PresentationError, Option[PresentationRecord]] - def acceptPresentation(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def acceptPresentation(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] - def rejectPresentation(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def rejectPresentation(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] - def markRequestPresentationSent(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def markRequestPresentationSent(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] - def markRequestPresentationRejected(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def markRequestPresentationRejected(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] - def markProposePresentationSent(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def markProposePresentationSent(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] - def markPresentationSent(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def markPresentationSent(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] def markPresentationGenerated( - recordId: UUID, + recordId: DidCommID, presentation: Presentation ): IO[PresentationError, Option[PresentationRecord]] - def markPresentationVerified(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def markPresentationVerified(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] - def markPresentationRejected(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def markPresentationRejected(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] - def markPresentationAccepted(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] + def markPresentationAccepted(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] } @@ -117,7 +117,7 @@ private class PresentationServiceImpl( import PresentationRecord._ override def markPresentationGenerated( - recordId: UUID, + recordId: DidCommID, presentation: Presentation ): IO[PresentationError, Option[PresentationRecord]] = { for { @@ -136,7 +136,7 @@ private class PresentationServiceImpl( } override def createPresentationPayloadFromRecord( - recordId: UUID, + recordId: DidCommID, prover: Issuer, issuanceDate: Instant ): IO[PresentationError, PresentationPayload] = { @@ -156,7 +156,7 @@ private class PresentationServiceImpl( .fromOption(record.requestPresentationData) .mapError(_ => InvalidFlowStateError(s"RequestPresentation not found: $recordId")) issuedValidCredentials <- credentialRepository - .getValidIssuedCredentials(credentialsToUse.map(UUID.fromString)) + .getValidIssuedCredentials(credentialsToUse.map(DidCommID(_))) .mapError(RepositoryError.apply) _ <- ZIO.cond( @@ -192,7 +192,7 @@ private class PresentationServiceImpl( } yield records } - override def getPresentationRecord(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = { + override def getPresentationRecord(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = { for { record <- presentationRepository .getPresentationRecord(recordId) @@ -200,15 +200,15 @@ private class PresentationServiceImpl( } yield record } - override def rejectRequestPresentation(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = { + override def rejectRequestPresentation(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = { markRequestPresentationRejected(recordId) } - def rejectPresentation(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = { + def rejectPresentation(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = { markPresentationRejected(recordId) } override def createPresentationRecord( - thid: UUID, + thid: DidCommID, subjectId: DidId, connectionId: Option[String], proofTypes: Seq[ProofType], @@ -218,7 +218,7 @@ private class PresentationServiceImpl( request <- ZIO.succeed(createDidCommRequestPresentation(proofTypes, thid, subjectId, options)) record <- ZIO.succeed( PresentationRecord( - id = UUID.randomUUID(), + id = DidCommID(), createdAt = Instant.now, updatedAt = None, thid = thid, @@ -260,10 +260,10 @@ private class PresentationServiceImpl( for { record <- ZIO.succeed( PresentationRecord( - id = UUID.randomUUID(), + id = DidCommID(), createdAt = Instant.now, updatedAt = None, - thid = UUID.fromString(request.thid.getOrElse(request.id)), + thid = DidCommID(request.thid.getOrElse(request.id)), connectionId = connectionId, schemaId = None, role = Role.Prover, @@ -354,14 +354,14 @@ private class PresentationServiceImpl( } def acceptRequestPresentation( - recordId: UUID, + recordId: DidCommID, credentialsToUse: Seq[String] ): IO[PresentationError, Option[PresentationRecord]] = { for { record <- getRecordWithState(recordId, ProtocolState.RequestReceived) issuedValidCredentials <- credentialRepository - .getValidIssuedCredentials(credentialsToUse.map(UUID.fromString)) + .getValidIssuedCredentials(credentialsToUse.map(DidCommID(_))) .mapError(RepositoryError.apply) issuedRawCredentials = issuedValidCredentials.flatMap(_.issuedCredentialRaw.map(IssuedCredentialRaw(_))) issuedCredentials <- ZIO.fromEither( @@ -385,7 +385,7 @@ private class PresentationServiceImpl( } yield record } - override def acceptPresentation(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = { + override def acceptPresentation(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = { for { maybeRecord <- presentationRepository .getPresentationRecord(recordId) @@ -422,7 +422,7 @@ private class PresentationServiceImpl( } yield record } - override def acceptProposePresentation(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = { + override def acceptProposePresentation(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = { for { maybeRecord <- presentationRepository .getPresentationRecord(recordId) @@ -466,7 +466,7 @@ private class PresentationServiceImpl( } private[this] def getRecordWithState( - recordId: UUID, + recordId: DidCommID, state: ProtocolState ): IO[PresentationError, PresentationRecord] = { for { @@ -483,48 +483,48 @@ private class PresentationServiceImpl( } yield record } - override def markRequestPresentationSent(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = + override def markRequestPresentationSent(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = updatePresentationRecordProtocolState( recordId, PresentationRecord.ProtocolState.RequestPending, PresentationRecord.ProtocolState.RequestSent ) - override def markProposePresentationSent(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = + override def markProposePresentationSent(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = updatePresentationRecordProtocolState( recordId, PresentationRecord.ProtocolState.ProposalPending, PresentationRecord.ProtocolState.ProposalSent ) - override def markPresentationVerified(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = + override def markPresentationVerified(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = updatePresentationRecordProtocolState( recordId, PresentationRecord.ProtocolState.PresentationReceived, PresentationRecord.ProtocolState.PresentationVerified ) - override def markPresentationAccepted(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = + override def markPresentationAccepted(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = updatePresentationRecordProtocolState( recordId, PresentationRecord.ProtocolState.PresentationVerified, PresentationRecord.ProtocolState.PresentationAccepted ) - override def markPresentationSent(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = + override def markPresentationSent(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = updatePresentationRecordProtocolState( recordId, PresentationRecord.ProtocolState.PresentationGenerated, PresentationRecord.ProtocolState.PresentationSent ) - override def markPresentationRejected(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = + override def markPresentationRejected(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = updatePresentationRecordProtocolState( recordId, PresentationRecord.ProtocolState.PresentationReceived, PresentationRecord.ProtocolState.PresentationRejected ) - override def markRequestPresentationRejected(recordId: UUID): IO[PresentationError, Option[PresentationRecord]] = + override def markRequestPresentationRejected(recordId: DidCommID): IO[PresentationError, Option[PresentationRecord]] = updatePresentationRecordProtocolState( recordId, PresentationRecord.ProtocolState.RequestReceived, @@ -535,22 +535,22 @@ private class PresentationServiceImpl( thid: Option[String] ): IO[PresentationError, PresentationRecord] = { for { - thid <- ZIO + thidID <- ZIO .fromOption(thid) + .map(DidCommID(_)) .mapError(_ => UnexpectedError("No `thid` found in Presentation request")) - .map(UUID.fromString) maybeRecord <- presentationRepository - .getPresentationRecordByThreadId(thid) + .getPresentationRecordByThreadId(thidID) .mapError(RepositoryError.apply) record <- ZIO .fromOption(maybeRecord) - .mapError(_ => ThreadIdNotFound(thid)) + .mapError(_ => ThreadIdNotFound(thidID)) } yield record } private[this] def createDidCommRequestPresentation( proofTypes: Seq[ProofType], - thid: UUID, + thid: DidCommID, subjectDId: DidId, maybeOptions: Option[io.iohk.atala.pollux.core.model.presentation.Options] ): RequestPresentation = { @@ -625,7 +625,7 @@ private class PresentationServiceImpl( } private[this] def updatePresentationRecordProtocolState( - id: UUID, + id: DidCommID, from: PresentationRecord.ProtocolState, to: PresentationRecord.ProtocolState ): IO[PresentationError, Option[PresentationRecord]] = { diff --git a/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/repository/CredentialRepositorySpecSuite.scala b/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/repository/CredentialRepositorySpecSuite.scala index 10f604bcc9..c358f8a471 100644 --- a/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/repository/CredentialRepositorySpecSuite.scala +++ b/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/repository/CredentialRepositorySpecSuite.scala @@ -4,9 +4,8 @@ import com.squareup.okhttp.Protocol import io.iohk.atala.mercury.model.DidId import io.iohk.atala.mercury.protocol.issuecredential.IssueCredential import io.iohk.atala.mercury.protocol.issuecredential.RequestCredential -import io.iohk.atala.pollux.core.model.IssueCredentialRecord +import io.iohk.atala.pollux.core.model._ import io.iohk.atala.pollux.core.model.IssueCredentialRecord._ -import io.iohk.atala.pollux.core.model.ValidIssuedCredentialRecord import io.iohk.atala.pollux.core.model.error.CredentialRepositoryError._ import io.iohk.atala.prism.identity.Did import zio.Cause @@ -23,10 +22,10 @@ import io.iohk.atala.castor.core.model.did.PrismDID object CredentialRepositorySpecSuite { private def issueCredentialRecord = IssueCredentialRecord( - id = UUID.randomUUID, + id = DidCommID(), createdAt = Instant.ofEpochSecond(Instant.now.getEpochSecond()), updatedAt = None, - thid = UUID.randomUUID, + thid = DidCommID(), schemaId = None, role = IssueCredentialRecord.Role.Issuer, subjectId = "did:prism:HOLDER", @@ -61,7 +60,7 @@ object CredentialRepositorySpecSuite { test("createIssueCredentialRecord prevents creation of 2 records with the same thid") { for { repo <- ZIO.service[CredentialRepository[Task]] - thid = UUID.randomUUID() + thid = DidCommID() aRecord = issueCredentialRecord.copy(thid = thid) bRecord = issueCredentialRecord.copy(thid = thid) aCount <- repo.createIssueCredentialRecord(aRecord) @@ -94,7 +93,7 @@ object CredentialRepositorySpecSuite { bRecord = issueCredentialRecord _ <- repo.createIssueCredentialRecord(aRecord) _ <- repo.createIssueCredentialRecord(bRecord) - record <- repo.getIssueCredentialRecord(UUID.randomUUID()) + record <- repo.getIssueCredentialRecord(DidCommID()) } yield assertTrue(record.isEmpty) }, test("getIssuanceCredentialRecord returns all records") { @@ -133,7 +132,7 @@ object CredentialRepositorySpecSuite { bRecord = issueCredentialRecord _ <- repo.createIssueCredentialRecord(aRecord) _ <- repo.createIssueCredentialRecord(bRecord) - count <- repo.deleteIssueCredentialRecord(UUID.randomUUID) + count <- repo.deleteIssueCredentialRecord(DidCommID()) records <- repo.getIssueCredentialRecords() } yield { assertTrue(count == 0) && @@ -145,7 +144,7 @@ object CredentialRepositorySpecSuite { test("getIssueCredentialRecordByThreadId correctly returns an existing thid") { for { repo <- ZIO.service[CredentialRepository[Task]] - thid = UUID.randomUUID() + thid = DidCommID() aRecord = issueCredentialRecord.copy(thid = thid) bRecord = issueCredentialRecord _ <- repo.createIssueCredentialRecord(aRecord) @@ -160,7 +159,7 @@ object CredentialRepositorySpecSuite { bRecord = issueCredentialRecord _ <- repo.createIssueCredentialRecord(aRecord) _ <- repo.createIssueCredentialRecord(bRecord) - record <- repo.getIssueCredentialRecordByThreadId(UUID.randomUUID()) + record <- repo.getIssueCredentialRecordByThreadId(DidCommID()) } yield assertTrue(record.isEmpty) }, test("getIssueCredentialRecordsByStates returns valid records") { diff --git a/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/service/CredentialServiceImplSpec.scala b/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/service/CredentialServiceImplSpec.scala index 386d6851fa..285f3243b8 100644 --- a/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/service/CredentialServiceImplSpec.scala +++ b/pollux/lib/core/src/test/scala/io/iohk/atala/pollux/core/service/CredentialServiceImplSpec.scala @@ -12,6 +12,7 @@ import io.iohk.atala.mercury.protocol.issuecredential.CredentialPreview import io.iohk.atala.mercury.protocol.issuecredential.IssueCredential import io.iohk.atala.mercury.protocol.issuecredential.OfferCredential import io.iohk.atala.mercury.protocol.issuecredential.RequestCredential +import io.iohk.atala.pollux.core.model._ import io.iohk.atala.pollux.core.model.IssueCredentialRecord._ import io.iohk.atala.pollux.core.model.error.CredentialServiceError import io.iohk.atala.pollux.core.model.error.CredentialServiceError._ @@ -22,7 +23,6 @@ import zio.test.* import java.util.UUID import io.iohk.atala.castor.core.model.did.CanonicalPrismDID import io.iohk.atala.mercury.model.AttachmentDescriptor -import io.iohk.atala.pollux.core.model.CredentialOfferAttachment object CredentialServiceImplSpec extends ZIOSpecDefault { @@ -35,7 +35,7 @@ object CredentialServiceImplSpec extends ZIOSpecDefault { suite("CredentialServiceImpl")( test("createIssuerCredentialRecord creates a valid issuer credential record") { check( - Gen.uuid, + Gen.uuid.map(e => DidCommID(e.toString())), Gen.option(Gen.string), Gen.option(Gen.double), Gen.option(Gen.boolean), @@ -105,7 +105,7 @@ object CredentialServiceImplSpec extends ZIOSpecDefault { test("createIssuerCredentialRecord should reject creation with a duplicate 'thid'") { for { svc <- ZIO.service[CredentialService] - thid = UUID.randomUUID() + thid = DidCommID() aRecord <- svc.createRecord(thid = thid) bRecord <- svc.createRecord(thid = thid).exit } yield { @@ -150,7 +150,7 @@ object CredentialServiceImplSpec extends ZIOSpecDefault { svc <- ZIO.service[CredentialService] aRecord <- svc.createRecord() bRecord <- svc.createRecord() - record <- svc.getIssueCredentialRecord(UUID.randomUUID()) + record <- svc.getIssueCredentialRecord(DidCommID()) } yield assertTrue(record.isEmpty) }, test("receiveCredentialOffer successfully creates a record") { @@ -260,7 +260,7 @@ object CredentialServiceImplSpec extends ZIOSpecDefault { issuerSvc <- ZIO.service[CredentialService].provideLayer(credentialServiceLayer) issuerRecord <- issuerSvc.createRecord() _ <- issuerSvc.markOfferSent(issuerRecord.id) - request = requestCredential(Some(UUID.randomUUID())) + request = requestCredential(Some(DidCommID())) exit <- issuerSvc.receiveCredentialRequest(request).exit } yield { assertTrue(exit match @@ -351,7 +351,7 @@ object CredentialServiceImplSpec extends ZIOSpecDefault { offerReceivedRecord <- holderSvc.receiveCredentialOffer(offer) _ <- holderSvc.acceptCredentialOffer(offerReceivedRecord.id) _ <- holderSvc.markRequestSent(offerReceivedRecord.id) - issue = issueCredential(thid = Some(UUID.randomUUID())) + issue = issueCredential(thid = Some(DidCommID())) exit <- holderSvc.receiveCredentialIssue(issue).exit } yield { assertTrue(exit match @@ -413,7 +413,7 @@ object CredentialServiceImplSpec extends ZIOSpecDefault { ) ) - private[this] def requestCredential(thid: Option[UUID] = Some(UUID.randomUUID())) = RequestCredential( + private[this] def requestCredential(thid: Option[DidCommID] = Some(DidCommID())) = RequestCredential( from = DidId("did:prism:holder"), to = DidId("did:prism:issuer"), thid = thid.map(_.toString), @@ -421,7 +421,7 @@ object CredentialServiceImplSpec extends ZIOSpecDefault { body = RequestCredential.Body() ) - private[this] def issueCredential(thid: Option[UUID] = Some(UUID.randomUUID())) = IssueCredential( + private[this] def issueCredential(thid: Option[DidCommID] = Some(DidCommID())) = IssueCredential( from = DidId("did:prism:issuer"), to = DidId("did:prism:holder"), thid = thid.map(_.toString), @@ -433,7 +433,7 @@ object CredentialServiceImplSpec extends ZIOSpecDefault { def createRecord( pairwiseIssuerDID: DidId = DidId("did:prism:issuer"), pairwiseHolderDID: DidId = DidId("did:prism:holder-pairwise"), - thid: UUID = UUID.randomUUID(), + thid: DidCommID = DidCommID(), subjectId: String = "did:prism:holder", schemaId: Option[String] = None, claims: Map[String, String] = Map("name" -> "Alice"), diff --git a/pollux/lib/sql-doobie/src/main/resources/sql/pollux/V1__init_tables.sql b/pollux/lib/sql-doobie/src/main/resources/sql/pollux/V1__init_tables.sql index ff5693961a..91b80738a2 100644 --- a/pollux/lib/sql-doobie/src/main/resources/sql/pollux/V1__init_tables.sql +++ b/pollux/lib/sql-doobie/src/main/resources/sql/pollux/V1__init_tables.sql @@ -14,10 +14,10 @@ -- ); CREATE TABLE public.issue_credential_records( - "id" VARCHAR(36) NOT NULL PRIMARY KEY, + "id" VARCHAR(64) NOT NULL PRIMARY KEY,-- must be <=32 bytes string consisting entirely of unreserved URI characters "created_at" BIGINT NOT NULL, "updated_at" BIGINT, - "thid" VARCHAR(36) NOT NULL, + "thid" VARCHAR(64) NOT NULL, "schema_id" VARCHAR(36), "role" VARCHAR(50) NOT NULL, "subject_id" TEXT NOT NULL, @@ -29,14 +29,14 @@ CREATE TABLE public.issue_credential_records( "offer_credential_data" TEXT, "request_credential_data" TEXT, "issue_credential_data" TEXT, - "issued_credential_raw" TEXT + "issued_credential_raw" TEXT ); CREATE TABLE public.presentation_records( - "id" VARCHAR(36) NOT NULL PRIMARY KEY, + "id" VARCHAR(64) NOT NULL PRIMARY KEY, "created_at" BIGINT NOT NULL, "updated_at" BIGINT, - "thid" VARCHAR(36) NOT NULL, + "thid" VARCHAR(64) NOT NULL, "schema_id" VARCHAR(36), "connection_id" VARCHAR(36), "role" VARCHAR(50) NOT NULL, @@ -45,4 +45,4 @@ CREATE TABLE public.presentation_records( "request_presentation_data" TEXT, "propose_presentation_data" TEXT, "presentation_data" TEXT -); \ No newline at end of file +); diff --git a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialRepository.scala b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialRepository.scala index 59a47e25ae..f868338353 100644 --- a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialRepository.scala +++ b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialRepository.scala @@ -44,8 +44,11 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor // given logHandler: LogHandler = LogHandler.jdkLogHandler import IssueCredentialRecord._ - given uuidGet: Get[UUID] = Get[String].map(UUID.fromString) - given uuidPut: Put[UUID] = Put[String].contramap(_.toString()) + // given uuidGet: Get[UUID] = Get[String].map(UUID.fromString) + // given uuidPut: Put[UUID] = Put[String].contramap(_.toString()) + + given didCommIDGet: Get[DidCommID] = Get[String].map(DidCommID(_)) + given didCommIDPut: Put[DidCommID] = Put[String].contramap(_.value) given instantGet: Get[Instant] = Get[Long].map(Instant.ofEpochSecond) given instantPut: Put[Instant] = Put[Long].contramap(_.getEpochSecond()) @@ -190,7 +193,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor .transact(xa) } - override def getIssueCredentialRecord(recordId: UUID): Task[Option[IssueCredentialRecord]] = { + override def getIssueCredentialRecord(recordId: DidCommID): Task[Option[IssueCredentialRecord]] = { val cxnIO = sql""" | SELECT | id, @@ -220,7 +223,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor .transact(xa) } - override def getIssueCredentialRecordByThreadId(thid: UUID): Task[Option[IssueCredentialRecord]] = { + override def getIssueCredentialRecordByThreadId(thid: DidCommID): Task[Option[IssueCredentialRecord]] = { val cxnIO = sql""" | SELECT | id, @@ -251,7 +254,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor } override def updateCredentialRecordProtocolState( - recordId: UUID, + recordId: DidCommID, from: IssueCredentialRecord.ProtocolState, to: IssueCredentialRecord.ProtocolState ): Task[Int] = { @@ -271,7 +274,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor // TODO: refactor to work with issueCredential form mercury override def updateCredentialRecordStateAndProofByCredentialIdBulk( - idsStatesAndProofs: Seq[(UUID, IssueCredentialRecord.PublicationState, MerkleInclusionProof)] + idsStatesAndProofs: Seq[(DidCommID, IssueCredentialRecord.PublicationState, MerkleInclusionProof)] ): Task[Int] = { if (idsStatesAndProofs.isEmpty) ZIO.succeed(0) @@ -295,7 +298,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor } override def updateCredentialRecordPublicationState( - recordId: UUID, + recordId: DidCommID, from: Option[IssueCredentialRecord.PublicationState], to: Option[IssueCredentialRecord.PublicationState] ): Task[Int] = { @@ -318,7 +321,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor } override def updateWithRequestCredential( - recordId: UUID, + recordId: DidCommID, request: RequestCredential, protocolState: ProtocolState ): Task[Int] = { @@ -337,7 +340,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor } override def updateWithIssueCredential( - recordId: UUID, + recordId: DidCommID, issue: IssueCredential, protocolState: ProtocolState ): Task[Int] = { @@ -355,7 +358,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor .transact(xa) } - override def getValidIssuedCredentials(recordIds: Seq[UUID]): Task[Seq[ValidIssuedCredentialRecord]] = { + override def getValidIssuedCredentials(recordIds: Seq[DidCommID]): Task[Seq[ValidIssuedCredentialRecord]] = { val idAsStrings = recordIds.map(_.toString) val nel = NonEmptyList.of(idAsStrings.head, idAsStrings.tail: _*) val inClauseFragment = Fragments.in(fr"id", nel) @@ -378,7 +381,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor } - override def deleteIssueCredentialRecord(recordId: UUID): Task[Int] = { + override def deleteIssueCredentialRecord(recordId: DidCommID): Task[Int] = { val cxnIO = sql""" | DELETE | FROM public.issue_credential_records @@ -390,7 +393,7 @@ class JdbcCredentialRepository(xa: Transactor[Task]) extends CredentialRepositor } override def updateWithIssuedRawCredential( - recordId: UUID, + recordId: DidCommID, issue: IssueCredential, issuedRawCredential: String, protocolState: ProtocolState diff --git a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcPresentationRepository.scala b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcPresentationRepository.scala index 1582ab7eb4..af8cb9faaa 100644 --- a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcPresentationRepository.scala +++ b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcPresentationRepository.scala @@ -28,7 +28,7 @@ class JdbcPresentationRepository(xa: Transactor[Task]) extends PresentationRepos // serializes into hex string override def updatePresentationWithCredentialsToUse( - recordId: ju.UUID, + recordId: DidCommID, credentialsToUse: Option[Seq[String]], protocolState: ProtocolState ): Task[Int] = { @@ -60,8 +60,11 @@ class JdbcPresentationRepository(xa: Transactor[Task]) extends PresentationRepos // given logHandler: LogHandler = LogHandler.jdkLogHandler import PresentationRecord._ - given uuidGet: Get[UUID] = Get[String].map(UUID.fromString) - given uuidPut: Put[UUID] = Put[String].contramap(_.toString()) + // given uuidGet: Get[UUID] = Get[String].map(UUID.fromString) + // given uuidPut: Put[UUID] = Put[String].contramap(_.toString()) + + given didCommIDGet: Get[DidCommID] = Get[String].map(DidCommID(_)) + given didCommIDPut: Put[DidCommID] = Put[String].contramap(_.value) given instantGet: Get[Instant] = Get[Long].map(Instant.ofEpochSecond) given instantPut: Put[Instant] = Put[Long].contramap(_.getEpochSecond()) @@ -177,7 +180,7 @@ class JdbcPresentationRepository(xa: Transactor[Task]) extends PresentationRepos .transact(xa) } - override def getPresentationRecord(recordId: UUID): Task[Option[PresentationRecord]] = { + override def getPresentationRecord(recordId: DidCommID): Task[Option[PresentationRecord]] = { val cxnIO = sql""" | SELECT | id, @@ -203,7 +206,7 @@ class JdbcPresentationRepository(xa: Transactor[Task]) extends PresentationRepos .transact(xa) } - override def getPresentationRecordByThreadId(thid: UUID): Task[Option[PresentationRecord]] = { + override def getPresentationRecordByThreadId(thid: DidCommID): Task[Option[PresentationRecord]] = { val cxnIO = sql""" | SELECT | id, @@ -230,7 +233,7 @@ class JdbcPresentationRepository(xa: Transactor[Task]) extends PresentationRepos } override def updatePresentationRecordProtocolState( - recordId: UUID, + recordId: DidCommID, from: PresentationRecord.ProtocolState, to: PresentationRecord.ProtocolState ): Task[Int] = { @@ -249,7 +252,7 @@ class JdbcPresentationRepository(xa: Transactor[Task]) extends PresentationRepos } override def updateWithRequestPresentation( - recordId: UUID, + recordId: DidCommID, request: RequestPresentation, protocolState: ProtocolState ): Task[Int] = { @@ -268,7 +271,7 @@ class JdbcPresentationRepository(xa: Transactor[Task]) extends PresentationRepos } override def updateWithProposePresentation( - recordId: UUID, + recordId: DidCommID, propose: ProposePresentation, protocolState: ProtocolState ): Task[Int] = { @@ -287,7 +290,7 @@ class JdbcPresentationRepository(xa: Transactor[Task]) extends PresentationRepos } override def updateWithPresentation( - recordId: UUID, + recordId: DidCommID, presentation: Presentation, protocolState: ProtocolState ): Task[Int] = {