From 9072c046e80aa2e367697aa6c9dbc33cb75e72b7 Mon Sep 17 00:00:00 2001 From: chereseeriepa Date: Tue, 29 Oct 2024 15:25:29 +1300 Subject: [PATCH] docs: update the connectionless documentation Signed-off-by: chereseeriepa --- docs/examples/ConnectionlessOffer.md | 2 +- docs/examples/ConnectionlessPresentation.md | 207 +++++++++++++++----- 2 files changed, 164 insertions(+), 45 deletions(-) diff --git a/docs/examples/ConnectionlessOffer.md b/docs/examples/ConnectionlessOffer.md index 1c0c4d73b..76e78883e 100644 --- a/docs/examples/ConnectionlessOffer.md +++ b/docs/examples/ConnectionlessOffer.md @@ -128,7 +128,7 @@ sequenceDiagram 9. The `Peer`listens for the credential and stores it in pluto - ```javascript + ```typescript agent.addListener(SDK.ListenerKey.MESSAGE, async (newMessages: SDK.Domain.Message[]) => { // newMessages can contain any didcomm message that is received, including // Credential Offers, Issued credentials and Request Presentation Messages diff --git a/docs/examples/ConnectionlessPresentation.md b/docs/examples/ConnectionlessPresentation.md index 819abdda9..02197c111 100644 --- a/docs/examples/ConnectionlessPresentation.md +++ b/docs/examples/ConnectionlessPresentation.md @@ -1,56 +1,175 @@ # Edge SDK Connectionless Presentation -## Requirements -1. A working Identus Mediator and an Identus Cloud Agent. -2. A holder who already has a JWT Credential issued by a known issuer (prism:did) [Holder A] +## User Flow -> NOTE: -> -> Please follow the [Quick started guide](../../docs/quick-start) to complete steps 1, 2 +```mermaid +sequenceDiagram + autonumber + actor Peer + actor Admin + participant Verifier -## Flow -1. The verifier will need to generate an invitation url as follows: + Admin->> Verifier: Request a Connectionless Presentation Invitation + Verifier->> Admin: Connectionless Presentation Invitation -``` -curl --location 'http:///cloud-agent/present-proof/presentations/invitation' \ ---header 'Content-Type: application/json' \ ---data '{ - "goalCode" : "present-vp", - "goal" : "Request proof of vaccination information", - "proofs": [], - "options": { - "challenge": "11c91493-01b3-4c4d-ac36-b336bab5bddf", - "domain": "https://prism-verifier.com" - } -} -``` + Admin->>Peer: Connectionless Presentation Invitation (OOB) -The response will look as follows: + Peer ->> Peer: Parse the OOB + + Peer ->> Verifier: Accept the Connectionless Presentation Invitation (OOB) + Verifier ->> Peer: Connectionless Presentation Request + Peer ->> Verifier: Presentation + Admin ->> Verifier: Get Presentation + Verifier ->> Admin: Verified ``` -{ - "presentationId": "715bc063-cd61-4049-834c-465b3eb19042", - "thid": "71a16da3-97ff-460a-b5f9-25a61fe864f4", - "role": "Verifier", - "status": "InvitationGenerated", - "proofs": [], - "data": [], - "goalCode": "present-vp", - "goal": "Request proof of vaccination information", - "myDid": "did:peer:2.Ez6LSt2C1xviB7nFEUHJAyWqvDF2xyJtQHWafQMxmy1SySoH6.Vz6MkgMChqZVQ47G88EBY6QZoPbBsCqByhtyfA3TQpyBKn7Ej.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly8xOTIuMTY4LjEuNDQ6ODAwMC9kaWRjb21tIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfX0", - "invitation": { - "id": "71a16da3-97ff-460a-b5f9-25a61fe864f4", - "type": "https://didcomm.org/out-of-band/2.0/invitation", - "from": "did:peer:2.Ez6LSt2C1xviB7nFEUHJAyWqvDF2xyJtQHWafQMxmy1SySoH6.Vz6MkgMChqZVQ47G88EBY6QZoPbBsCqByhtyfA3TQpyBKn7Ej.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly8xOTIuMTY4LjEuNDQ6ODAwMC9kaWRjb21tIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfX0", - "invitationUrl": "https://my.domain.com/path?_oob=eyJpZCI6IjcxYTE2ZGEzLTk3ZmYtNDYwYS1iNWY5LTI1YTYxZmU4NjRmNCIsInR5cGUiOiJodHRwczovL2RpZGNvbW0ub3JnL291dC1vZi1iYW5kLzIuMC9pbnZpdGF0aW9uIiwiZnJvbSI6ImRpZDpwZWVyOjIuRXo2TFN0MkMxeHZpQjduRkVVSEpBeVdxdkRGMnh5SnRRSFdhZlFNeG15MVN5U29INi5WejZNa2dNQ2hxWlZRNDdHODhFQlk2UVpvUGJCc0NxQnlodHlmQTNUUXB5QktuN0VqLlNleUowSWpvaVpHMGlMQ0p6SWpwN0luVnlhU0k2SW1oMGRIQTZMeTh4T1RJdU1UWTRMakV1TkRRNk9EQXdNQzlrYVdSamIyMXRJaXdpY2lJNlcxMHNJbUVpT2xzaVpHbGtZMjl0YlM5Mk1pSmRmWDAiLCJib2R5Ijp7ImdvYWxfY29kZSI6InByZXNlbnQtdnAiLCJnb2FsIjoiUmVxdWVzdCBwcm9vZiBvZiB2YWNjaW5hdGlvbiBpbmZvcm1hdGlvbiIsImFjY2VwdCI6W119LCJhdHRhY2htZW50cyI6W3siaWQiOiJjOGMxY2E3Zi05YjJjLTQwOGQtODZkMi0zNWJiYmU2ZTMwNjgiLCJtZWRpYV90eXBlIjoiYXBwbGljYXRpb24vanNvbiIsImRhdGEiOnsianNvbiI6eyJpZCI6Ijc4ZTc5NTFhLWZhOTYtNDg2Mi1hYmVkLWFmYTBhZWQyMzgzNCIsInR5cGUiOiJodHRwczovL2RpZGNvbW0uYXRhbGFwcmlzbS5pby9wcmVzZW50LXByb29mLzMuMC9yZXF1ZXN0LXByZXNlbnRhdGlvbiIsImJvZHkiOnsiZ29hbF9jb2RlIjoiUmVxdWVzdCBQcm9vZiBQcmVzZW50YXRpb24iLCJ3aWxsX2NvbmZpcm0iOmZhbHNlLCJwcm9vZl90eXBlcyI6W119LCJhdHRhY2htZW50cyI6W3siaWQiOiJiNWIzZjBjMC05NWQ2LTRkOTItOWQ0Ni1hNDVmYTdlMzVjYWEiLCJtZWRpYV90eXBlIjoiYXBwbGljYXRpb24vanNvbiIsImRhdGEiOnsianNvbiI6eyJvcHRpb25zIjp7ImNoYWxsZW5nZSI6IjExYzkxNDkzLTAxYjMtNGM0ZC1hYzM2LWIzMzZiYWI1YmRkZiIsImRvbWFpbiI6Imh0dHBzOi8vcHJpc20tdmVyaWZpZXIuY29tIn0sInByZXNlbnRhdGlvbl9kZWZpbml0aW9uIjp7ImlkIjoiZjNmNmQwYTAtYzdhNS00NjAzLWJkZjUtMjU1ZWJkZGU5ODdiIiwiaW5wdXRfZGVzY3JpcHRvcnMiOltdfX19LCJmb3JtYXQiOiJwcmlzbS9qd3QifV0sInRoaWQiOiI3MWExNmRhMy05N2ZmLTQ2MGEtYjVmOS0yNWE2MWZlODY0ZjQiLCJmcm9tIjoiZGlkOnBlZXI6Mi5FejZMU3QyQzF4dmlCN25GRVVISkF5V3F2REYyeHlKdFFIV2FmUU14bXkxU3lTb0g2LlZ6Nk1rZ01DaHFaVlE0N0c4OEVCWTZRWm9QYkJzQ3FCeWh0eWZBM1RRcHlCS243RWouU2V5SjBJam9pWkcwaUxDSnpJanA3SW5WeWFTSTZJbWgwZEhBNkx5OHhPVEl1TVRZNExqRXVORFE2T0RBd01DOWthV1JqYjIxdElpd2ljaUk2VzEwc0ltRWlPbHNpWkdsa1kyOXRiUzkyTWlKZGZYMCJ9fX1dLCJjcmVhdGVkX3RpbWUiOjE3MjQ0MjY1NjgsImV4cGlyZXNfdGltZSI6MTcyNDQyNjg2OH0=" - }, - "metaRetries": 5 -} -``` -The Verifier will make this available to the holder in shape of QA code, link, etc. +## Steps + +1. **Admin** requests a connectionless presentation request invitation from the **Verifier** + + ```bash + curl --location 'http://localhost:9000/cloud-agent/present-proof/presentations/invitation' \ + --header 'Content-Type: application/json' \ + --data '{ + "goalCode" : "present-vp", + "goal" : "Request presentation", + "proofs": [], + "options": { + "challenge": "a6af4ea1-2f11-43de-bd17-e0182e55f919", + "domain": "http://localhost:9000/cloud-agent" + } + }' + ``` + +2. The **Verifier** sends back the `Connectionless Presentation Request Invitation` + - Response example: + + ```json + { + "presentationId": "76b2b571-8456-4413-8dd3-d8f5186fd472", + "thid": "9d99f0b4-25b7-47e6-8816-1687c86dc3f1", + "role": "Verifier", + "status": "InvitationGenerated", + "proofs": [], + "data": [], + "requestData": [ + { + "options": { + "challenge": "a6af4ea1-2f11-43de-bd17-e0182e55f919", + "domain" : "http://localhost:9000/cloud-agent" + }, + "presentation_definition" : { + "id": "070cd2f8-e8cc-4ae4-94bd-3ac886fed6df", + "input_descriptors": [], + "name": null, + "purpose": null, + "format" : null + } + } + ], + "goalCode": "present-vp", + "goal": "Request presentation", + "myDid": "did:peer:2.Ez6LS...", + "invitation": { + "id": "9d99f0b4-25b7-47e6-8816-1687c86dc3f1", + "type": "https://didcomm.org/out-of-band/2.0/invitation", + "from": "did:peer:2.Ez6LS...9", + "invitationUrl": "https://my.domain.com/path?_oob=eyJpZCI6IjlkOTlmMGI0LTI1YjctNDdlNi04ODE2LTE2ODdjODZkYzNmMSIsInR5cGUiOiJodHRwczovL2RpZGNvbW0ub3JnL291dC1vZi1iYW5kLzIuMC9pbnZpdGF0aW9uIiwiZnJvbSI6ImRpZDpwZWVyOjIuRXo2TFNpb2Foa3lncmZ0cnpLUWM2aXNyVngyTEhoSlFpQTF1U0ZCeHBXMW02aE56SC5WejZNa2VvdlE5bUVoVm9TcXJucUhkYVltRjhHRTdvOXlXWTJvVmlrdThFelhLNGloLlNleUowSWpvaVpHMGlMQ0p6SWpwN0luVnlhU0k2SW1oMGRIQTZMeTh4T1RJdU1UWTRMalk0TGpZeU9qa3dNREF2Wkdsa1kyOXRiU0lzSW5JaU9sdGRMQ0poSWpwYkltUnBaR052YlcwdmRqSWlYWDE5IiwiYm9keSI6eyJnb2FsX2NvZGUiOiJwcmVzZW50LXZwIiwiZ29hbCI6IlJlcXVlc3QgcHJlc2VudGF0aW9uIiwiYWNjZXB0IjpbImRpZGNvbW0vdjIiXX0sImF0dGFjaG1lbnRzIjpbeyJpZCI6ImZjMGQ1MWY0LTlhMmItNDVmOS1hM2E0LWJkNmQwZTE2MzZjZCIsIm1lZGlhX3R5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwiZGF0YSI6eyJqc29uIjp7ImlkIjoiYjgwMDkyZGUtZTU2MS00YzI2LTkzNzYtMTgxMWEwMWNiNWNjIiwidHlwZSI6Imh0dHBzOi8vZGlkY29tbS5hdGFsYXByaXNtLmlvL3ByZXNlbnQtcHJvb2YvMy4wL3JlcXVlc3QtcHJlc2VudGF0aW9uIiwiYm9keSI6eyJnb2FsX2NvZGUiOiJSZXF1ZXN0IFByb29mIFByZXNlbnRhdGlvbiIsIndpbGxfY29uZmlybSI6ZmFsc2UsInByb29mX3R5cGVzIjpbXX0sImF0dGFjaG1lbnRzIjpbeyJpZCI6IjIyOTM0Y2U5LTJmMzMtNDkxYS1hODEyLTAyOGNkMDAzYjQ3NiIsIm1lZGlhX3R5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwiZGF0YSI6eyJqc29uIjp7Im9wdGlvbnMiOnsiY2hhbGxlbmdlIjoiYTZhZjRlYTEtMmYxMS00M2RlLWJkMTctZTAxODJlNTVmOTE5IiwiZG9tYWluIjoiaHR0cDovL2xvY2FsaG9zdDo5MDAwL2Nsb3VkLWFnZW50In0sInByZXNlbnRhdGlvbl9kZWZpbml0aW9uIjp7ImlkIjoiMDcwY2QyZjgtZThjYy00YWU0LTk0YmQtM2FjODg2ZmVkNmRmIiwiaW5wdXRfZGVzY3JpcHRvcnMiOltdfX19LCJmb3JtYXQiOiJwcmlzbS9qd3QifV0sInRoaWQiOiI5ZDk5ZjBiNC0yNWI3LTQ3ZTYtODgxNi0xNjg3Yzg2ZGMzZjEiLCJmcm9tIjoiZGlkOnBlZXI6Mi5FejZMU2lvYWhreWdyZnRyektRYzZpc3JWeDJMSGhKUWlBMXVTRkJ4cFcxbTZoTnpILlZ6Nk1rZW92UTltRWhWb1Nxcm5xSGRhWW1GOEdFN285eVdZMm9WaWt1OEV6WEs0aWguU2V5SjBJam9pWkcwaUxDSnpJanA3SW5WeWFTSTZJbWgwZEhBNkx5OHhPVEl1TVRZNExqWTRMall5T2prd01EQXZaR2xrWTI5dGJTSXNJbklpT2x0ZExDSmhJanBiSW1ScFpHTnZiVzB2ZGpJaVhYMTkifX19XSwiY3JlYXRlZF90aW1lIjoxNzMwMTY3MTIxLCJleHBpcmVzX3RpbWUiOjE3MzAxNjc0MjF9" + }, + "metaRetries": 5 + } + ``` + +3. The **Admin** forwards the `invitationUrl` to the **Peer**. + +4. The **Peer** validates the `invitationUrl` with `agent.parseInvitation`: + + ```typescript + const oob = await agent.parseInvitation(invitationUrl) + ``` -2. The holder then opens its the Edge Agent Wallet SDK, "Connections tab" and will pase the invitation link in the field. +5. The **Peer** accepts the invitation using `agent.acceptInvitation`: -Once the invitation is parsed, the user will then be able to see a new Verification request, choose one of the available credentials and send the proof as the verifier requested. + ```typescript + await agent.acceptInvitation(oob) + ``` + +6. The **Verifier** sends the presentation request to the **Peer**. + +7. The **Peer** listens for the presentation request and prepares the presentation of the verifiable credential. + + ```typescript + agent.addListener(SDK.ListenerKey.MESSAGE, async (newMessages: SDK.Domain.Message[]) => { + const presentationRequests = newMessages.filter( + (message) => message.piuri === 'https://didcomm.org/present-proof/3.0/request-presentation' + ) + + const credentials = await agent.pluto.getAllCredentials() + const lastCredential = lastCredentials.at(-1) + + if (presentationRequests.length) { + for (const requestMessage of presentationRequests) { + try { + const presentationRequest = await SDK.RequestPresentation.fromMessage(requestMessage) + const presentation = await agent.createPresentationForRequestProof(presentationRequest, lastCredential) + await agent.sendMessage(presentation.makeMessage()) + } catch (err) { + console.error('Error presenting the credential:', err) + } + } + } + }) + ``` + +8. The **Admin** requests the presentation from the **Verifier** + + ```bash + curl -X GET "http://localhost:9000/present-proof/presentations/76b2b571-8456-4413-8dd3-d8f5186fd472" \ + -H "accept: application/json" \ + -H "Content-Type: application/json" \ + -H "apikey: [[VERIFIER_API_KEY]]" + ``` + +9. The **Verifier** responds that the Credential is verified + + - Response example: + + ```json + { + "presentationId": "76b2b571-8456-4413-8dd3-d8f5186fd472", + "thid": "9d99f0b4-25b7-47e6-8816-1687c86dc3f1", + "role": "Verifier", + "status": "PresentationVerified", + "proofs": [], + "data": [ + "eyJhbGciOiJFUzI...." + ], + "requestData": [ + { + "options": { + "challenge": "a6af4ea1-2f11-43de-bd17-e0182e55f919", + "domain" : "http://localhost:9000/cloud-agent" + }, + "presentation_definition" : { + "id": "070cd2f8-e8cc-4ae4-94bd-3ac886fed6df", + "input_descriptors": [], + "name": null, + "purpose": null, + "format" : null + } + } + ], + "goalCode": "present-vp", + "goal": "Request presentation", + "myDid": "did:peer:2.Ez6LS...", + "invitation": { + "id": "9d99f0b4-25b7-47e6-8816-1687c86dc3f1", + "type": "https://didcomm.org/out-of-band/2.0/invitation", + "from": "did:peer:2.Ez6LS...9", + "invitationUrl": "https://my.domain.com/path?_oob=eyJpZCI6IjlkOTlmMGI0LTI1YjctNDdlNi04ODE2LTE2ODdjODZkYzNmMSIsInR5cGUiOiJodHRwczovL2RpZGNvbW0ub3JnL291dC1vZi1iYW5kLzIuMC9pbnZpdGF0aW9uIiwiZnJvbSI6ImRpZDpwZWVyOjIuRXo2TFNpb2Foa3lncmZ0cnpLUWM2aXNyVngyTEhoSlFpQTF1U0ZCeHBXMW02aE56SC5WejZNa2VvdlE5bUVoVm9TcXJucUhkYVltRjhHRTdvOXlXWTJvVmlrdThFelhLNGloLlNleUowSWpvaVpHMGlMQ0p6SWpwN0luVnlhU0k2SW1oMGRIQTZMeTh4T1RJdU1UWTRMalk0TGpZeU9qa3dNREF2Wkdsa1kyOXRiU0lzSW5JaU9sdGRMQ0poSWpwYkltUnBaR052YlcwdmRqSWlYWDE5IiwiYm9keSI6eyJnb2FsX2NvZGUiOiJwcmVzZW50LXZwIiwiZ29hbCI6IlJlcXVlc3QgcHJlc2VudGF0aW9uIiwiYWNjZXB0IjpbImRpZGNvbW0vdjIiXX0sImF0dGFjaG1lbnRzIjpbeyJpZCI6ImZjMGQ1MWY0LTlhMmItNDVmOS1hM2E0LWJkNmQwZTE2MzZjZCIsIm1lZGlhX3R5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwiZGF0YSI6eyJqc29uIjp7ImlkIjoiYjgwMDkyZGUtZTU2MS00YzI2LTkzNzYtMTgxMWEwMWNiNWNjIiwidHlwZSI6Imh0dHBzOi8vZGlkY29tbS5hdGFsYXByaXNtLmlvL3ByZXNlbnQtcHJvb2YvMy4wL3JlcXVlc3QtcHJlc2VudGF0aW9uIiwiYm9keSI6eyJnb2FsX2NvZGUiOiJSZXF1ZXN0IFByb29mIFByZXNlbnRhdGlvbiIsIndpbGxfY29uZmlybSI6ZmFsc2UsInByb29mX3R5cGVzIjpbXX0sImF0dGFjaG1lbnRzIjpbeyJpZCI6IjIyOTM0Y2U5LTJmMzMtNDkxYS1hODEyLTAyOGNkMDAzYjQ3NiIsIm1lZGlhX3R5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwiZGF0YSI6eyJqc29uIjp7Im9wdGlvbnMiOnsiY2hhbGxlbmdlIjoiYTZhZjRlYTEtMmYxMS00M2RlLWJkMTctZTAxODJlNTVmOTE5IiwiZG9tYWluIjoiaHR0cDovL2xvY2FsaG9zdDo5MDAwL2Nsb3VkLWFnZW50In0sInByZXNlbnRhdGlvbl9kZWZpbml0aW9uIjp7ImlkIjoiMDcwY2QyZjgtZThjYy00YWU0LTk0YmQtM2FjODg2ZmVkNmRmIiwiaW5wdXRfZGVzY3JpcHRvcnMiOltdfX19LCJmb3JtYXQiOiJwcmlzbS9qd3QifV0sInRoaWQiOiI5ZDk5ZjBiNC0yNWI3LTQ3ZTYtODgxNi0xNjg3Yzg2ZGMzZjEiLCJmcm9tIjoiZGlkOnBlZXI6Mi5FejZMU2lvYWhreWdyZnRyektRYzZpc3JWeDJMSGhKUWlBMXVTRkJ4cFcxbTZoTnpILlZ6Nk1rZW92UTltRWhWb1Nxcm5xSGRhWW1GOEdFN285eVdZMm9WaWt1OEV6WEs0aWguU2V5SjBJam9pWkcwaUxDSnpJanA3SW5WeWFTSTZJbWgwZEhBNkx5OHhPVEl1TVRZNExqWTRMall5T2prd01EQXZaR2xrWTI5dGJTSXNJbklpT2x0ZExDSmhJanBiSW1ScFpHTnZiVzB2ZGpJaVhYMTkifX19XSwiY3JlYXRlZF90aW1lIjoxNzMwMTY3MTIxLCJleHBpcmVzX3RpbWUiOjE3MzAxNjc0MjF9" + }, + "metaRetries": 5 + } + ```