-
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.
Aries RFC 0434: Out-of-Band Protocol 1.1 (#22)
* [WIP] Aries RFC 0434: Out-of-Band Protocol 1.1 * Aries RFC 0434: Out-of-Band Protocol 1.1 * added serviceType * Add OutOfBand Message Invitation parser method * Minimizing git diffs * Minimizing git diffs * Clean up * Minor update to Documentation Co-authored-by: FabioPinheiro <[email protected]>
- Loading branch information
1 parent
45a18c9
commit 57ed209
Showing
14 changed files
with
348 additions
and
94 deletions.
There are no files selected for viewing
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
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
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
50 changes: 21 additions & 29 deletions
50
mercury/prism-mediator/protocol-invitation/Invitation-Protocol.md
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,57 +1,49 @@ | ||
# Invitation Protocol | ||
|
||
This Protocol is parte of the DIDComm Messaging Specification. | ||
This Protocol is parte of the **DIDComm Messaging Specification** but also **Aries RFC 0434: Out-of-Band Protocol 1.1** | ||
|
||
Its a out-of-band style protocol. | ||
|
||
The out-of-band protocol is used when you wish to engage with another agent and you don't have a DIDComm connection to use for the interaction. | ||
|
||
See [https://identity.foundation/didcomm-messaging/spec/#invitation] | ||
See [https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md] | ||
|
||
## PIURI | ||
|
||
`https://didcomm.org/out-of-band/2.0/invitation` | ||
Version 1.0: `https://didcomm.org/out-of-band/1.0/invitation` | ||
|
||
Version 2.0: `https://didcomm.org/out-of-band/2.0/invitation` | ||
|
||
### Roles | ||
|
||
- Invitee | ||
- Sender | ||
- Will create the message `https://didcomm.org/out-of-band/2.0/invitation` | ||
- Inviter | ||
- Receiver | ||
- Will accept the invitation | ||
|
||
### Notes | ||
|
||
- Invitation has expiry date | ||
|
||
### Invitee create invitation message | ||
|
||
```mermaid | ||
stateDiagram-v2 | ||
[*] --> [*] | ||
``` | ||
|
||
### Inviter accepting invitation (Flow Diagram) | ||
### Sender create invitation message (Flow Diagram) | ||
|
||
```mermaid | ||
stateDiagram-v2 | ||
[*] --> Invited:Send Invitation | ||
Invited --> Requested:Recieve connection request | ||
Requested --> Responded:Send Connection Response | ||
Responded --> Invited: Send Connection Error Retry if possible stay in same state | ||
Responded --> Completed:Recieve Acknowledgement | ||
Completed --> Responded:Recieve Acknowledgement Error Retry if possible stay in same state | ||
Completed --> [*] | ||
[*] --> Initial | ||
Initial --> await_response:Send out-of-band invitation message | ||
await_response --> done:receive DIDCOMM response message(single use) | ||
await_response --> await_response:recieve DIDCOMM response message(multi use message) | ||
await_response --> error:recieve problem report response | ||
done --> [*] | ||
``` | ||
|
||
--- | ||
|
||
### Invitee Confirming (Flow Diagram) | ||
### Receiver accepting invitation (Flow Diagram) | ||
|
||
```mermaid | ||
stateDiagram-v2 | ||
[*] --> Invited:Recieve Invitation | ||
Invited --> Requested: Send Connection Request | ||
Requested --> Responded: Recieve Connection Response | ||
Responded --> Invited: Send Connection Error Response Retry if possible stay in same state | ||
Responded --> Completed: Send Acknowledgement | ||
Completed --> Responded: Recieve Acknowledgement Error Retry if possible stay in same sate | ||
Completed --> [*] | ||
[*] --> Initial | ||
Initial --> prepare_response:recieve out-of-band invitation message | ||
prepare_response --> done:send DIDCOMM response message | ||
done --> [*] | ||
``` |
41 changes: 41 additions & 0 deletions
41
...ation/src/main/scala/io/iohk/atala/mercury/protocol/invitation/AttachmentDescriptor.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,41 @@ | ||
package io.iohk.atala.mercury.protocol.invitation | ||
import java.util.{Base64 => JBase64} | ||
import io.circe.Encoder | ||
import io.circe.generic.semiauto._ | ||
import io.circe.syntax._ | ||
|
||
sealed trait AttachmentData | ||
|
||
final case class Base64(base64: String) extends AttachmentData | ||
|
||
/** @see | ||
* https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0017-attachments | ||
* @param `@id` | ||
* @param `mime-type` | ||
* @param data | ||
* @param filename | ||
* @param lastmod_time | ||
* @param byte_count | ||
* @param description | ||
*/ | ||
final case class AttachmentDescriptor( | ||
`@id`: Option[String] = None, | ||
`mime-type`: Option[String] = None, | ||
data: Base64 = Base64(""), | ||
filename: Option[String] = None, | ||
lastmod_time: Option[String] = None, | ||
byte_count: Option[Int] = None, | ||
description: Option[String] = None | ||
) | ||
|
||
object AttachmentDescriptor { | ||
def buildAttachment[A: Encoder]( | ||
id: Option[String] = None, | ||
payload: A, | ||
mimeType: Option[String] = Some("application/json") | ||
): AttachmentDescriptor = { | ||
val encoded = JBase64.getUrlEncoder.encodeToString(payload.asJson.noSpaces.getBytes) | ||
AttachmentDescriptor(id, mimeType, Base64(encoded)) | ||
} | ||
|
||
} |
17 changes: 0 additions & 17 deletions
17
...ocol-invitation/src/main/scala/io/iohk/atala/mercury/protocol/invitation/Invitation.scala
This file was deleted.
Oops, something went wrong.
51 changes: 51 additions & 0 deletions
51
...invitation/src/main/scala/io/iohk/atala/mercury/protocol/invitation/InvitationCodec.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,51 @@ | ||
package io.iohk.atala.mercury.protocol.invitation | ||
import cats.implicits._ | ||
import io.circe.syntax._ | ||
import io.circe.generic.semiauto._ | ||
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} | ||
import io.circe.{Decoder, Encoder, HCursor, Json} | ||
import io.iohk.atala.mercury.protocol.invitation.v1.{Invitation => InvitationV1} | ||
import io.iohk.atala.mercury.protocol.invitation.v2.{Invitation => InvitationV2} | ||
|
||
object InvitationCodec { | ||
|
||
implicit val serviceEncoder: Encoder[Service] = deriveEncoder[Service] | ||
implicit val serviceDecoder: Decoder[Service] = deriveDecoder[Service] | ||
|
||
implicit val didEncoder: Encoder[Did] = (a: Did) => Json.fromString(a.did) | ||
implicit val didDecoder: Decoder[Did] = (c: HCursor) => c.value.as[String].map(did => Did(did)) | ||
|
||
implicit val serviceTypeEncoder: Encoder[ServiceType] = Encoder.instance { | ||
case service @ Service(_, _, _, _, _) => service.asJson | ||
case did @ Did(_) => did.asJson | ||
} | ||
|
||
implicit val serviceTypeDecoder: Decoder[ServiceType] = | ||
List[Decoder[ServiceType]]( | ||
Decoder[Service].widen, | ||
Decoder[Did].widen | ||
).reduceLeft(_ or _) | ||
|
||
implicit val base64Encoder: Encoder[Base64] = deriveEncoder[Base64] | ||
implicit val base64eDecoder: Decoder[Base64] = deriveDecoder[Base64] | ||
|
||
implicit val attachmentDescriptorEncoder: Encoder[AttachmentDescriptor] = deriveEncoder[AttachmentDescriptor] | ||
implicit val attachmentDescriptorDecoder: Decoder[AttachmentDescriptor] = deriveDecoder[AttachmentDescriptor] | ||
|
||
implicit val invitationEncoderV1: Encoder[InvitationV1] = (entity: InvitationV1) => | ||
Json.obj( | ||
"@id" -> Json.fromString(entity.`@id`), | ||
"@type" -> Json.fromString(entity.`@type`), | ||
"label" -> Json.fromString(entity.label), | ||
"goal" -> Json.fromString(entity.goal), | ||
"goal_code" -> Json.fromString(entity.goal_code), | ||
"accept" -> entity.accept.asJson, | ||
"handshake_protocols" -> entity.handshake_protocols.asJson, | ||
"requests~attach" -> entity.`requests~attach`.asJson, | ||
"services" -> entity.services.asJson | ||
) | ||
implicit val invitationDecoderV1: Decoder[InvitationV1] = deriveDecoder[InvitationV1] | ||
|
||
implicit val invitationEncoderV2: Encoder[InvitationV2] = deriveEncoder[InvitationV2] | ||
implicit val invitationDecoderV2: Decoder[InvitationV2] = deriveDecoder[InvitationV2] | ||
} |
67 changes: 20 additions & 47 deletions
67
...tocol-invitation/src/main/scala/io/iohk/atala/mercury/protocol/invitation/OutOfBand.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,52 +1,25 @@ | ||
package io.iohk.atala.mercury.protocol.invitation | ||
|
||
import io.circe.syntax.EncoderOps | ||
import io.circe.generic.auto._ | ||
import java.util.Base64 | ||
|
||
// TODO split into files | ||
|
||
case class CreateInvitation(goal: String, goal_code: String) | ||
|
||
case class CreateInvitationResponse(alias: String, invitation: Invitation, invitationUrl: String) | ||
|
||
case class Body(goal: String, goal_code: String, accept: Seq[String]) | ||
|
||
sealed trait ServiceType | ||
|
||
case class Service( | ||
id: String, | ||
serviceEndpoint: String, | ||
`type`: String, | ||
recipientKeys: Seq[String], | ||
routingKeys: Seq[String] | ||
) extends ServiceType | ||
|
||
case class Did(did: String) extends ServiceType | ||
|
||
object CreateInvitationResponse { | ||
val accepts = Seq("didcomm/v2") | ||
|
||
def apply(goal: String, goal_code: String): CreateInvitationResponse = { | ||
val body = Body(goal, goal_code, accepts) | ||
val service = Service( | ||
id = "did:prism:PR6vs6GEZ8rHaVgjg2WodM#did-communication", | ||
serviceEndpoint = "http://localhost:8080/create-connection", | ||
`type` = "did-communication", | ||
recipientKeys = Seq("did:prism:PR6vs6GEZ8rHaVgjg2WodM"), | ||
routingKeys = Seq("did:prism:PR6vs6GEZ8rHaVgjg2WodM") | ||
) | ||
val invitation = Invitation( | ||
id = "f3375429-b116-4224-b55f-563d7ef461f1", | ||
`@type` = "https://didcomm.org/out-of-band/2.0/invitation", | ||
label = "Mediator Invitation", | ||
body = body, | ||
handshake_protocols = Seq("https://didcomm.org/didexchange/1.0"), | ||
service = Seq(service) | ||
) | ||
import java.net.URL | ||
import java.{util => ju} | ||
import io.iohk.atala.mercury.protocol.invitation.v2._ | ||
import io.iohk.atala.mercury.protocol.invitation.InvitationCodec._ | ||
import io.circe._ | ||
import io.circe.parser._ | ||
|
||
object OutOfBand { | ||
|
||
def parseLink(url: String): Option[String] = parseLink(new URL(url)) | ||
def parseLink(url: URL): Option[String] = (url.getQuery() match { | ||
case str if str.startsWith("_oob=") => Some(str.drop(5)) | ||
case _ => None | ||
}).map { e => | ||
val decoder = ju.Base64.getUrlDecoder() | ||
String(decoder.decode(e)) | ||
} | ||
|
||
val encodedString = Base64.getUrlEncoder.encodeToString(invitation.asJson.noSpaces.getBytes) | ||
val invitationUrl = s"http://localhost:8080/invitation?_oob=$encodedString" | ||
CreateInvitationResponse(alias = "Mediator", invitation, invitationUrl) | ||
def parseInvitation(url: String): Option[Invitation] = { | ||
parseLink(url).map(e => parse(e).getOrElse(???).as[Invitation].getOrElse(???)) | ||
} | ||
|
||
} |
27 changes: 27 additions & 0 deletions
27
...col-invitation/src/main/scala/io/iohk/atala/mercury/protocol/invitation/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 |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package io.iohk.atala.mercury.protocol.invitation | ||
import cats.implicits._ | ||
import io.circe.syntax._ | ||
import io.circe.generic.semiauto._ | ||
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} | ||
import io.circe.{Decoder, Encoder, HCursor, Json} | ||
|
||
sealed trait ServiceType | ||
|
||
/** Service block | ||
* @see | ||
* https://github.com/hyperledger/aries-rfcs/tree/main/features/0434-outofband | ||
* @param id | ||
* @param `type` | ||
* @param recipientKeys | ||
* @param routingKeys | ||
* @param serviceEndpoint | ||
*/ | ||
case class Service( | ||
id: String, | ||
`type`: String, | ||
recipientKeys: Seq[String], | ||
routingKeys: Option[Seq[String]], | ||
serviceEndpoint: String, | ||
) extends ServiceType | ||
|
||
case class Did(did: String) extends ServiceType |
11 changes: 11 additions & 0 deletions
11
...rotocol-invitation/src/main/scala/io/iohk/atala/mercury/protocol/invitation/package.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,11 @@ | ||
package io.iohk.atala.mercury.protocol | ||
|
||
import java.util.UUID | ||
|
||
package object invitation { | ||
|
||
/** provides new msg id | ||
* @return | ||
*/ | ||
def getNewMsgId: String = UUID.randomUUID().toString | ||
} |
35 changes: 35 additions & 0 deletions
35
...l-invitation/src/main/scala/io/iohk/atala/mercury/protocol/invitation/v1/Invitation.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,35 @@ | ||
package io.iohk.atala.mercury.protocol.invitation.v1 | ||
import cats.implicits._ | ||
import io.circe.syntax._ | ||
import io.circe.generic.semiauto._ | ||
import io.circe.{Encoder, Json} | ||
import io.iohk.atala.mercury.model.PIURI | ||
|
||
import scala.annotation.targetName | ||
import io.iohk.atala.mercury.protocol.invitation.AttachmentDescriptor | ||
import io.iohk.atala.mercury.protocol.invitation.ServiceType | ||
|
||
/** Out-Of-Band invitation Example | ||
* @see | ||
* https://github.com/hyperledger/aries-rfcs/tree/main/features/0434-outofband | ||
* | ||
* @param `id` | ||
* @param label | ||
* @param goal | ||
* @param goal_code | ||
* @param handshake_protocols | ||
* @param `request~attach` | ||
* @param services | ||
*/ | ||
final case class Invitation( | ||
`@id`: String = io.iohk.atala.mercury.protocol.invitation.getNewMsgId, | ||
label: String, | ||
goal: String, | ||
goal_code: String, | ||
accept: Seq[String], | ||
handshake_protocols: Seq[String], | ||
`requests~attach`: Seq[AttachmentDescriptor], | ||
services: Seq[ServiceType] | ||
) { | ||
val `@type`: PIURI = "https://didcomm.org/out-of-band/2.0/invitation" | ||
} |
Oops, something went wrong.