Skip to content

Commit

Permalink
feat(prism-agent): add listManagedDID endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Pat Losoponkul committed Dec 6, 2022
1 parent 811c034 commit 376d008
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 11 deletions.
24 changes: 23 additions & 1 deletion prism-agent/service/api/http/castor/schemas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ components:
properties:
did:
type: string
example: did:prism:unpublished:7a3a5cd1beab57a65c18c584848029c513ca27c8edfb69ceb2c7aef3d659bf44?instance=https://offchain-storage.com"
example: did:prism:7a3a5cd1beab57a65c18c584848029c513ca27c8edfb69ceb2c7aef3d659bf44?instance=https://offchain-storage.com"
updatePublicKey:
type: string
example: "EiBkRSeixqX-PhOij6PIpuGfPld5Nif5MxcrgtGCw-t6LA"
Expand Down Expand Up @@ -232,6 +232,28 @@ components:
description: A long-form DID for the created DID
example: did:prism:1:abc123:abc123

ListManagedDIDResponse:
type: array
items:
type: object
required:
- did
- status
properties:
did:
type: string
example: did:prism:abc
longFormDid:
type: string
description: A long-form DID. Mandatory when status is not PUBLISHED and optional when status is PUBLISHED
example: did:prism:abc:123
status:
type: string
enum:
- CREATED
- PUBLICATION_PENDING
- PUBLISHED

Delta:
type: object
required:
Expand Down
31 changes: 25 additions & 6 deletions prism-agent/service/api/http/prism-agent-openapi-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,25 @@ paths:
$ref: "./castor/schemas.yaml#/components/schemas/ErrorResponse"

/did-registrar/dids:
get:
tags: [ "DID Registrar" ]
operationId: listManagedDid
summary: List all DIDs managed by PrismAgent.
description: List all DIDs managed by PrismAgent.
responses:
"200":
description: List managed DIDs
content:
application/json:
schema:
$ref: "./castor/schemas.yaml#/components/schemas/ListManagedDIDResponse"
"422":
description: The DID creation failed.
content:
application/json:
schema:
$ref: "./castor/schemas.yaml#/components/schemas/ErrorResponse"

post:
tags: [ "DID Registrar" ]
operationId: createManagedDid
Expand Down Expand Up @@ -745,7 +764,7 @@ paths:
application/json:
schema:
$ref: "./castor/schemas.yaml#/components/schemas/ErrorResponse"

/issue-credentials/records:
get:
tags: [ "Issue Credentials Protocol" ]
Expand Down Expand Up @@ -785,7 +804,7 @@ paths:
application/json:
schema:
$ref: "./pollux/schemas.yaml#/components/schemas/ErrorResponse"

/issue-credentials/records/{recordId}/accept-offer:
post:
tags: [ "Issue Credentials Protocol" ]
Expand Down Expand Up @@ -978,9 +997,9 @@ paths:
operationId: createConnection
summary: Creates new connection and returns an invitation.
description: |-
Returns new invitation object and creates new connection state record in `pending` state.
Content of invitation depends on DIDComm protocol used, here is an example of how it would look like for `AIP 1.0 connection/v1` protocol.
Once connection invitation is accepted, Agent should filter all additional attempts to accept it.
Returns new invitation object and creates new connection state record in `pending` state.
Content of invitation depends on DIDComm protocol used, here is an example of how it would look like for `AIP 1.0 connection/v1` protocol.
Once connection invitation is accepted, Agent should filter all additional attempts to accept it.
We consider mult-party connections as out of scope for now.
requestBody:
required: true
Expand Down Expand Up @@ -1079,4 +1098,4 @@ paths:
content:
application/json:
schema:
$ref: "./connect/schemas.yaml#/components/schemas/ErrorResponse"
$ref: "./connect/schemas.yaml#/components/schemas/ErrorResponse"
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ import io.iohk.atala.agent.openapi.model.{
CreateManagedDIDResponse,
CreateManagedDidRequest,
DIDOperationResponse,
ErrorResponse
ErrorResponse,
ListManagedDIDResponseInner
}
import spray.json.RootJsonFormat
import zio.*

object DIDRegistrarApiMarshallerImpl extends JsonSupport {

val layer: ULayer[DIDRegistrarApiMarshaller] = ZLayer.succeed {
new DIDRegistrarApiMarshaller:
new DIDRegistrarApiMarshaller {
override implicit def fromEntityUnmarshallerCreateManagedDidRequest
: FromEntityUnmarshaller[CreateManagedDidRequest] = summon[RootJsonFormat[CreateManagedDidRequest]]

Expand All @@ -25,8 +26,13 @@ object DIDRegistrarApiMarshallerImpl extends JsonSupport {
override implicit def toEntityMarshallerCreateManagedDIDResponse: ToEntityMarshaller[CreateManagedDIDResponse] =
summon[RootJsonFormat[CreateManagedDIDResponse]]

override implicit def toEntityMarshallerListManagedDIDResponseInnerarray
: ToEntityMarshaller[Seq[ListManagedDIDResponseInner]] =
summon[RootJsonFormat[Seq[ListManagedDIDResponseInner]]]

override implicit def toEntityMarshallerErrorResponse: ToEntityMarshaller[ErrorResponse] =
summon[RootJsonFormat[ErrorResponse]]
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
given RootJsonFormat[DidOperationType] = jsonFormat0(DidOperationType.apply)
given RootJsonFormat[DIDResponse] = jsonFormat2(DIDResponse.apply)
given RootJsonFormat[ErrorResponse] = jsonFormat5(ErrorResponse.apply)
given RootJsonFormat[ListManagedDIDResponseInner] = jsonFormat3(ListManagedDIDResponseInner.apply)
given RootJsonFormat[PublicKey] = jsonFormat5(PublicKey.apply)
given RootJsonFormat[PublicKeyJwk] = jsonFormat5(PublicKeyJwk.apply)
given RootJsonFormat[RecoverDIDRequest] = jsonFormat5(RecoverDIDRequest.apply)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import io.iohk.atala.agent.openapi.model.{
DidOperationSubmission,
IssueCredentialRecord,
IssueCredentialRecordCollection,
ListManagedDIDResponseInner,
PublicKey,
PublicKeyJwk,
Service,
Expand All @@ -35,6 +36,8 @@ import io.iohk.atala.mercury.model.AttachmentDescriptor
import io.iohk.atala.mercury.model.Base64
import zio.ZIO
import io.iohk.atala.agent.server.http.model.HttpServiceError.InvalidPayload
import io.iohk.atala.agent.walletapi.model.ManagedDIDState
import io.iohk.atala.castor.core.model.did.{LongFormPrismDID, PrismDID}

import java.util.UUID
import io.iohk.atala.connect.core.model.ConnectionRecord.Role
Expand Down Expand Up @@ -202,4 +205,20 @@ trait OASDomainModelHelper {
)
}

extension (didDetail: walletDomain.ManagedDIDDetail) {
def toOAS: ListManagedDIDResponseInner = {
val (longFormDID, status) = didDetail.state match {
case ManagedDIDState.Created(operation) => Some(PrismDID.buildLongFormFromOperation(operation)) -> "CREATED"
case ManagedDIDState.PublicationPending(operation, _) =>
Some(PrismDID.buildLongFormFromOperation(operation)) -> "PUBLICATION_PENDING"
case ManagedDIDState.Published(_, _) => None -> "PUBLISHED"
}
ListManagedDIDResponseInner(
did = didDetail.did.toString,
longFormDid = longFormDID.map(_.toString),
status = status
)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ class DIDRegistrarApiServiceImpl(service: ManagedDIDService)(using runtime: Runt
}
}

override def listManagedDid()(implicit
toEntityMarshallerListManagedDIDResponseInnerarray: ToEntityMarshaller[Seq[ListManagedDIDResponseInner]],
toEntityMarshallerErrorResponse: ToEntityMarshaller[ErrorResponse]
): Route = {
val result = service.listManagedDID.map(_.map(_.toOAS))

onZioSuccess(result.either) {
case Left(error) => ??? // TODO: implement error handling
case Right(result) => listManagedDid200(result)
}
}

override def publishManagedDid(didRef: String)(implicit
toEntityMarshallerDIDOperationResponse: ToEntityMarshaller[DIDOperationResponse],
toEntityMarshallerErrorResponse: ToEntityMarshaller[ErrorResponse]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.iohk.atala.agent.walletapi.model

import io.iohk.atala.castor.core.model.did.PrismDIDOperation
import io.iohk.atala.castor.core.model.did.{CanonicalPrismDID, PrismDIDOperation}

import scala.collection.immutable.ArraySeq

final case class ManagedDIDDetail(did: CanonicalPrismDID, state: ManagedDIDState)

sealed trait ManagedDIDState

object ManagedDIDState {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package io.iohk.atala.agent.walletapi.service

import io.iohk.atala.agent.walletapi.crypto.{ECWrapper, KeyGeneratorWrapper}
import io.iohk.atala.agent.walletapi.model.{DIDPublicKeyTemplate, ECKeyPair, ManagedDIDState, ManagedDIDTemplate}
import io.iohk.atala.agent.walletapi.model.{
DIDPublicKeyTemplate,
ECKeyPair,
ManagedDIDDetail,
ManagedDIDState,
ManagedDIDTemplate
}
import io.iohk.atala.agent.walletapi.model.ECCoordinates.*
import io.iohk.atala.agent.walletapi.model.error.{CreateManagedDIDError, PublishManagedDIDError}
import io.iohk.atala.agent.walletapi.service.ManagedDIDService.{CreateDIDSecret, DEFAULT_MASTER_KEY_ID}
Expand Down Expand Up @@ -50,6 +56,11 @@ final class ManagedDIDService private[walletapi] (

private val CURVE = EllipticCurve.SECP256K1

def listManagedDID: Task[Seq[ManagedDIDDetail]] = nonSecretStorage.listManagedDID
.map(_.toSeq.map { case (did, state) =>
ManagedDIDDetail(did = did.asCanonical, state = state)
})

def publishStoredDID(did: CanonicalPrismDID): IO[PublishManagedDIDError, ScheduleDIDOperationOutcome] = {
def syncDLTStateAndPersist =
nonSecretStorage
Expand Down

0 comments on commit 376d008

Please sign in to comment.