-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ATL-1926] feat(castor): implement createPublishedDID (2) (#53)
* feat(castor): partially implement createPublishedDID * feat(castor): add missing layer in prism-agent * feat(castor): fix typo * feat(castor): move common primitives to shared * feat(castor): move common primitives to shared * feat(agent): integrate castor createPublishedDID with HTTP endpoint * feat(castor): add validation for unique id * chore(iris): format source * feat(castor): add operation validator unique key tests * feat(castor): add exisitng did check when create new did * feat(castor): implement data access for castor * chore(agent): use provided helper functions for model conversion * chore: remove wrongly added directory * feat(castor): use OperationOutcome as operation result * feat(castor): simplify OAS to only account for PublishedDID * feat(castor): remove unnecessary fields in OAS * feat(castor): add PrismDID model * feat(agent): convert castor operation outcome to http response * chore(agent): remove inaccurate comment * chore: pr diff cleanup * feat(infra): make agent uses DB in local deployment * chore: pr diff cleanup
- Loading branch information
Showing
37 changed files
with
798 additions
and
267 deletions.
There are no files selected for viewing
4 changes: 0 additions & 4 deletions
4
castor/lib/core/src/main/scala/io/iohk/atala/castor/core/model/Models.scala
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
...e/src/main/scala/io/iohk/atala/castor/core/model/did/ConfirmedPublishedDIDOperation.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package io.iohk.atala.castor.core.model.did | ||
|
||
import java.time.Instant | ||
|
||
final case class ConfirmedPublishedDIDOperation( | ||
operation: PublishedDIDOperation, | ||
anchoredAt: Instant, | ||
blockNumber: Int, | ||
blockIndex: Int | ||
) |
13 changes: 11 additions & 2 deletions
13
castor/lib/core/src/main/scala/io/iohk/atala/castor/core/model/did/EllipticCurve.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,16 @@ | ||
package io.iohk.atala.castor.core.model.did | ||
|
||
sealed trait EllipticCurve | ||
// EC Name is used in JWK https://w3c-ccg.github.io/security-vocab/#publicKeyJwk | ||
// It MUST match the curve name in https://www.iana.org/assignments/jose/jose.xhtml | ||
// in the "JSON Web Key Elliptic Curve" section | ||
enum EllipticCurve(val name: String) { | ||
case SECP256K1 extends EllipticCurve("secp256k1") | ||
} | ||
|
||
object EllipticCurve { | ||
case object SECP256K1 extends EllipticCurve | ||
|
||
private val lookup = EllipticCurve.values.map(i => i.name -> i).toMap | ||
|
||
def parseString(s: String): Option[EllipticCurve] = lookup.get(s) | ||
|
||
} |
47 changes: 47 additions & 0 deletions
47
castor/lib/core/src/main/scala/io/iohk/atala/castor/core/model/did/PrismDID.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package io.iohk.atala.castor.core.model.did | ||
|
||
import io.iohk.atala.castor.core.model.ProtoModelHelper | ||
import io.iohk.atala.prism.crypto.Sha256 | ||
import io.iohk.atala.shared.models.HexStrings.HexString | ||
|
||
enum PrismDIDVersion(val id: Int) { | ||
case V0 extends PrismDIDVersion(0) | ||
case V1 extends PrismDIDVersion(1) | ||
} | ||
|
||
/** Represents a [Did] used in PRISM with prism-specific method and keys as [PrismDid] | ||
*/ | ||
sealed trait PrismDID { | ||
|
||
val version: PrismDIDVersion | ||
|
||
val versionSpecificId: String | ||
|
||
override def toString: String = did.toString | ||
|
||
def did: DID = DID( | ||
method = "prism", | ||
methodSpecificId = version match { | ||
case PrismDIDVersion.V0 => versionSpecificId | ||
case _ => s"${version.id}:$versionSpecificId" | ||
} | ||
) | ||
|
||
} | ||
|
||
final case class PrismDIDV1 private (suffix: HexString) extends PrismDID { | ||
|
||
override val version: PrismDIDVersion = PrismDIDVersion.V1 | ||
|
||
override val versionSpecificId: String = suffix.toString | ||
|
||
} | ||
|
||
object PrismDIDV1 extends ProtoModelHelper { | ||
def fromCreateOperation(op: PublishedDIDOperation.Create): PrismDIDV1 = { | ||
val createDIDProto = op.toProto | ||
val initialState = createDIDProto.toByteArray | ||
val suffix = HexString.fromByteArray(Sha256.compute(initialState).getValue) | ||
PrismDIDV1(suffix) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 8 additions & 2 deletions
10
castor/lib/core/src/main/scala/io/iohk/atala/castor/core/model/did/ServiceType.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,13 @@ | ||
package io.iohk.atala.castor.core.model.did | ||
|
||
sealed trait ServiceType | ||
enum ServiceType(val name: String) { | ||
case MediatorService extends ServiceType("MediatorService") | ||
} | ||
|
||
object ServiceType { | ||
case object MediatorService extends ServiceType | ||
|
||
private val lookup = ServiceType.values.map(i => i.name -> i).toMap | ||
|
||
def parseString(s: String): Option[ServiceType] = lookup.get(s) | ||
|
||
} |
13 changes: 8 additions & 5 deletions
13
...ib/core/src/main/scala/io/iohk/atala/castor/core/model/did/VerificationRelationship.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
package io.iohk.atala.castor.core.model.did | ||
|
||
sealed trait VerificationRelationship | ||
enum VerificationRelationship(val name: String) { | ||
case Authentication extends VerificationRelationship("authentication") | ||
case AssertionMethod extends VerificationRelationship("assertionMethod") | ||
case KeyAgreement extends VerificationRelationship("keyAgreement") | ||
case CapabilityInvocation extends VerificationRelationship("capabilityInvocation") | ||
} | ||
|
||
object VerificationRelationship { | ||
case object Authentication extends VerificationRelationship | ||
|
||
case object AssertionMethod extends VerificationRelationship | ||
private val lookup = VerificationRelationship.values.map(i => i.name -> i).toMap | ||
|
||
case object KeyAgreement extends VerificationRelationship | ||
def parseString(s: String): Option[VerificationRelationship] = lookup.get(s) | ||
|
||
case object CapabilityInvocation extends VerificationRelationship | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 2 additions & 3 deletions
5
...lib/core/src/main/scala/io/iohk/atala/castor/core/repository/DIDOperationRepository.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,8 @@ | ||
package io.iohk.atala.castor.core.repository | ||
|
||
import io.iohk.atala.castor.core.model.IrisNotification | ||
import io.iohk.atala.castor.core.model.did.{ConfirmedPublishedDIDOperation, PrismDIDV1} | ||
import zio.* | ||
|
||
// TODO: replace with actual implementation | ||
trait DIDOperationRepository[F[_]] { | ||
def getIrisNotification: F[Seq[IrisNotification]] | ||
def getConfirmedPublishedDIDOperations(did: PrismDIDV1): F[Seq[ConfirmedPublishedDIDOperation]] | ||
} |
61 changes: 47 additions & 14 deletions
61
castor/lib/core/src/main/scala/io/iohk/atala/castor/core/service/DIDService.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,77 @@ | ||
package io.iohk.atala.castor.core.service | ||
|
||
import io.iohk.atala.castor.core.model.did.{DIDDocument, PublishedDIDOperation} | ||
import io.iohk.atala.castor.core.model.did.{ | ||
DIDDocument, | ||
PrismDIDV1, | ||
PublishedDIDOperation, | ||
PublishedDIDOperationOutcome | ||
} | ||
import zio.* | ||
import io.iohk.atala.castor.core.model.ProtoModelHelper | ||
import io.iohk.atala.castor.core.model.error.DIDOperationError | ||
import io.iohk.atala.castor.core.repository.DIDOperationRepository | ||
import io.iohk.atala.castor.core.util.DIDOperationValidator | ||
import io.iohk.atala.iris.proto.service.IrisServiceGrpc.IrisServiceStub | ||
import io.iohk.atala.prism.crypto.Sha256 | ||
import io.iohk.atala.shared.models.HexStrings.HexString | ||
import io.iohk.atala.iris.proto as iris_proto | ||
|
||
trait DIDService { | ||
def createPublishedDID(operation: PublishedDIDOperation.Create): IO[DIDOperationError, DIDDocument] | ||
def createPublishedDID(operation: PublishedDIDOperation.Create): IO[DIDOperationError, PublishedDIDOperationOutcome] | ||
} | ||
|
||
object MockDIDService { | ||
val layer: ULayer[DIDService] = ZLayer.succeed { | ||
new DIDService { | ||
def createPublishedDID(operation: PublishedDIDOperation.Create): IO[DIDOperationError, DIDDocument] = | ||
def createPublishedDID( | ||
operation: PublishedDIDOperation.Create | ||
): IO[DIDOperationError, PublishedDIDOperationOutcome] = | ||
ZIO.fail(DIDOperationError.InvalidArgument("mocked error")) | ||
} | ||
} | ||
} | ||
|
||
object DIDServiceImpl { | ||
val layer: URLayer[IrisServiceStub & DIDOperationValidator, DIDService] = ZLayer.fromFunction(DIDServiceImpl(_, _)) | ||
val layer: URLayer[IrisServiceStub & DIDOperationValidator & DIDOperationRepository[Task], DIDService] = | ||
ZLayer.fromFunction(DIDServiceImpl(_, _, _)) | ||
} | ||
|
||
private class DIDServiceImpl(irisClient: IrisServiceStub, operationValidator: DIDOperationValidator) | ||
extends DIDService, | ||
private class DIDServiceImpl( | ||
irisClient: IrisServiceStub, | ||
operationValidator: DIDOperationValidator, | ||
didOpRepo: DIDOperationRepository[Task] | ||
) extends DIDService, | ||
ProtoModelHelper { | ||
|
||
// TODO: | ||
// 1. generate DID identifier from operation | ||
// 2. check if DID already exists | ||
// 3. persist state | ||
override def createPublishedDID(operation: PublishedDIDOperation.Create): IO[DIDOperationError, DIDDocument] = { | ||
override def createPublishedDID( | ||
operation: PublishedDIDOperation.Create | ||
): IO[DIDOperationError, PublishedDIDOperationOutcome] = { | ||
val prismDID = PrismDIDV1.fromCreateOperation(operation) | ||
val irisOpProto = iris_proto.dlt.IrisOperation( | ||
operation = iris_proto.dlt.IrisOperation.Operation.CreateDid(operation.toProto) | ||
) | ||
for { | ||
_ <- ZIO.fromEither(operationValidator.validate(operation)) | ||
_ <- ZIO | ||
.fromFuture(_ => irisClient.scheduleOperation(operation.toProto)) | ||
confirmedOps <- didOpRepo | ||
.getConfirmedPublishedDIDOperations(prismDID) | ||
.mapError(DIDOperationError.InternalErrorDB.apply) | ||
_ <- confirmedOps | ||
.map(_.operation) | ||
.collectFirst { case op: PublishedDIDOperation.Create => op } | ||
.fold(ZIO.unit)(_ => | ||
ZIO.fail( | ||
DIDOperationError | ||
.InvalidPrecondition(s"PublishedDID with suffix ${prismDID.did} has already been created and confirmed") | ||
) | ||
) | ||
irisOutcome <- ZIO | ||
.fromFuture(_ => irisClient.scheduleOperation(irisOpProto)) | ||
.mapError(DIDOperationError.DLTProxyError.apply) | ||
} yield operation.document | ||
} yield PublishedDIDOperationOutcome( | ||
did = prismDID, | ||
operation = operation, | ||
operationId = HexString.fromByteArray(irisOutcome.operationId.toByteArray) | ||
) | ||
} | ||
|
||
} |
Oops, something went wrong.