Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
Added Kotlin Shnips for PEX (#1199)
Browse files Browse the repository at this point in the history
* kotlin shnips

* adding new line

* kotlin shnip wasnt generating

* removing extra code snippet

* enabling switch content

* adding clarity for presentation submission with Kotlin

* showing language switcher at the top

* adding back title

* adding back title

* hardcode imports

* make verifiable presentation more obvious

* put language switcher at the top

* remove unnnecessary import

* possible note for missing method

* PR #1199 - Fix jackson.core to a more compatible version

* handle all imports with model.*

* add in as snippet

---------

Co-authored-by: Andrew Lee Rubinger <[email protected]>
  • Loading branch information
2 people authored and acekyd committed Feb 12, 2024
1 parent b681bf4 commit c201f8d
Show file tree
Hide file tree
Showing 5 changed files with 504 additions and 75 deletions.
145 changes: 132 additions & 13 deletions site/docs/web5/build/verifiable-credentials/presentation-exchange.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
---
title: Presentation Exchange
hide_title: true
sidebar_position: 3
---

import CodeSnippet from '@site/src/components/CodeSnippet';

import getLoanAppPresentationDefinition from '!!raw-loader!@site/snippets/testsuite-javascript/__tests__/web5/build/verifiable-credentials/getLoanAppPresentationDefinition.snippet.js'
import satisfiesPresentationDefinitionForPex from '!!raw-loader!@site/snippets/testsuite-javascript/__tests__/web5/build/verifiable-credentials/satisfiesPresentationDefinitionForPex.snippet.js'
import selectCredentialsForPex from '!!raw-loader!@site/snippets/testsuite-javascript/__tests__/web5/build/verifiable-credentials/selectCredentialsForPex.snippet.js'
import createPresentationFromCredentialsForPex from '!!raw-loader!@site/snippets/testsuite-javascript/__tests__/web5/build/verifiable-credentials/createPresentationFromCredentialsForPex.snippet.js'
import validVerifiablePresentationForPex from '!!raw-loader!@site/snippets/testsuite-javascript/__tests__/web5/build/verifiable-credentials/validVerifiablePresentationForPex.snippet.js'
import validPresentationSubmissionForPex from '!!raw-loader!@site/snippets/testsuite-javascript/__tests__/web5/build/verifiable-credentials/validPresentationSubmissionForPex.snippet.js'


import getLoanAppPresentationDefinitionKt from '!!raw-loader!@site/snippets/testsuite-kotlin/src/test/kotlin/docs/web5/build/verifiablecredentials/getLoanAppPresentationDefinitionKt.snippet.kt'
import satisfiesPresentationDefinitionForPexKt from '!!raw-loader!@site/snippets/testsuite-kotlin/src/test/kotlin/docs/web5/build/verifiablecredentials/satisfiesPresentationDefinitionForPexKt.snippet.kt'
import selectCredentialsForPexKt from '!!raw-loader!@site/snippets/testsuite-kotlin/src/test/kotlin/docs/web5/build/verifiablecredentials/selectCredentialsForPexKt.snippet.kt'
import createPresentationFromCredentialsForPexKt from '!!raw-loader!@site/snippets/testsuite-kotlin/src/test/kotlin/docs/web5/build/verifiablecredentials/createPresentationFromCredentialsForPexKt.snippet.kt'
import validVerifiablePresentationForPexKt from '!!raw-loader!@site/snippets/testsuite-kotlin/src/test/kotlin/docs/web5/build/verifiablecredentials/validVerifiablePresentationForPexKt.snippet.kt'

<LanguageSwitcher languages="JavaScript, Kotlin" />

# Presentation Exchange

Expand All @@ -26,7 +43,12 @@ Assume a lender has an existing Presentation Definition specifying that applican
<details>
<summary>Presentation Definition</summary>

<CodeSnippet functionName="pex_getLoanAppPresentationDefinition" />
<Shnip
snippets={[
{ snippetContent: getLoanAppPresentationDefinition, language: 'JavaScript'},
{ snippetContent: getLoanAppPresentationDefinitionKt, language: 'Kotlin'}
]}
/>

</details>

Expand All @@ -37,35 +59,69 @@ We'll use the Presentation Definition above to present credentials that meet its
All methods needed to perform a PEX are in the `PresentationExchange` class.
You can import this class from the `@web5/credentials` package:

```js
<Shnip
inlineSnippets={[
{
code: `
import { PresentationExchange } from '@web5/credentials';
```
`,
language: 'JavaScript',
},
{
code: `
import web5.sdk.credentials.PresentationExchange
import web5.sdk.credentials.VerifiablePresentation
import web5.sdk.credentials.model.*
`,
language: 'Kotlin',
}
]}
/>

## Select Credentials

A user may possess multiple credentials.
To preserve the user's privacy, when creating a Presentation, you'll want to present only the VCs that match the Presentation Definition requirements.
This is done with the `selectCredentials()` method:

<CodeSnippet functionName="pex_selectCredentials" />
<Shnip
snippets={[
{ snippetContent: selectCredentialsForPex, language: 'JavaScript'},
{ snippetContent: selectCredentialsForPexKt, language: 'Kotlin'}
]}
/>

## Satisfy Presentation Definition

To ensure that the selected credentials collectively satisfy all of the Presentation Definition's requirements, call the `satisfiesPresentationDefinition()` method:

<CodeSnippet functionName="pex_checkPresentationDefinitionSatisfaction" />
<Shnip
snippets={[
{ snippetContent: satisfiesPresentationDefinitionForPex, language: 'JavaScript'},
{ snippetContent: satisfiesPresentationDefinitionForPexKt, language: 'Kotlin'}
]}
/>

This method will throw an error if all requirements of the Presentation Definition are not satisfied.

## Create Presentation

Once you've confirmed that the VCs successfully satisfy the Presentation Definition, you can create a presentation using the `createPresentationFromCredentials()` method:

<CodeSnippet functionName="pex_createPresentationFromCredentials" />
<Shnip
snippets={[
{ snippetContent: createPresentationFromCredentialsForPex, language: 'JavaScript'},
{ snippetContent: createPresentationFromCredentialsForPexKt, language: 'Kotlin'},
]}
/>

This method returns a `PresentationResult` which contains the presentation:

```js

<Shnip
inlineSnippets={[
{
content: 'This method returns a `PresentationResult` which contains the presentation:',
code: `
{
"presentation": {
"@context": [
Expand Down Expand Up @@ -103,13 +159,70 @@ This method returns a `PresentationResult` which contains the presentation:
]
}
}
```
`,
language: 'JavaScript',
},
{
content: 'This method returns a `VerifiablePresentation` which contains the presentation:',
code: `
{
"@context": [
"https://www.w3.org/2018/credentials/v1"
],
"type": [
"VerifiablePresentation"
],
"id": "urn:uuid:258bd593-0057-4944-9119-baf53ffd654a",
"presentation_submission": {
"id": "epzZXstAcVNt5MRrcyG91",
"definitionId": "presDefIdloanAppVerification123",
"descriptorMap": [
{
"id": "employmentVerification",
"format": "jwt_vc",
"path": "$.verifiableCredential[0]"
},
{
"id": "dobVerification",
"format": "jwt_vc",
"path": "$.verifiableCredential[1]"
},
{
"id": "nameVerification",
"format": "jwt_vc",
"path": "$.verifiableCredential[2]"
}
]
},
"verifiableCredential": [
"eyJraWQiOiJkaWQ6a2V5OnpRM3NoVWFqYWNvUFQxc3dGOW91bkZqRGRTV2YzeTRBMTJ2bWtneG9WVDVzcmZuaUIjelEzc2hVYWphY29QVDFzd0Y5b3VuRmpEZFNXZjN5NEExMnZta2d4b1ZUNXNyZm5pQiIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2SyJ9.eyJpc3MiOiJkaWQ6a2V5OnpRM3NoVWFqYWNvUFQxc3dGOW91bkZqRGRTV2YzeTRBMTJ2bWtneG9WVDVzcmZuaUIiLCJzdWIiOiJkaWQ6a2V5OnpRM3NoWHJBbmJnZnl0UVlRamlmVW0yRWNCQmJSQWVBZUdmZ0M0VFpyanc0WDcxaVoiLCJpYXQiOjE3MDcxMzAwMDksInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJFbXBsb3ltZW50Q3JlZGVudGlhbCJdLCJpZCI6InVybjp1dWlkOjc3MWJhNzE3LTc2NGEtNGU5NC1iNzAwLTM4ODY2YTE3OTc5YiIsImlzc3VlciI6ImRpZDprZXk6elEzc2hVYWphY29QVDFzd0Y5b3VuRmpEZFNXZjN5NEExMnZta2d4b1ZUNXNyZm5pQiIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDItMDVUMTA6NDY6NDlaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6a2V5OnpRM3NoWHJBbmJnZnl0UVlRamlmVW0yRWNCQmJSQWVBZUdmZ0M0VFpyanc0WDcxaVoiLCJlbXBsb3ltZW50U3RhdHVzIjoiZW1wbG95ZWQifX19.94QKD7UU6lAi1x_AMCJ7_-nfyV41mHXDBVwYdyWHB6ZYlCoDOroovhxgjtweqiQ7sRjTbZfoEu01-RmF_J9yQg",
"eyJraWQiOiJkaWQ6a2V5OnpRM3NoVWFqYWNvUFQxc3dGOW91bkZqRGRTV2YzeTRBMTJ2bWtneG9WVDVzcmZuaUIjelEzc2hVYWphY29QVDFzd0Y5b3VuRmpEZFNXZjN5NEExMnZta2d4b1ZUNXNyZm5pQiIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2SyJ9.eyJpc3MiOiJkaWQ6a2V5OnpRM3NoVWFqYWNvUFQxc3dGOW91bkZqRGRTV2YzeTRBMTJ2bWtneG9WVDVzcmZuaUIiLCJzdWIiOiJkaWQ6a2V5OnpRM3NoWHJBbmJnZnl0UVlRamlmVW0yRWNCQmJSQWVBZUdmZ0M0VFpyanc0WDcxaVoiLCJpYXQiOjE3MDcxMzAwMDksInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJEYXRlT2ZCaXJ0aENyZWRlbnRpYWwiXSwiaWQiOiJ1cm46dXVpZDoxNTBkMmE4OC1iMzViLTQ1NTUtODNiOC0yNmY1NmJkZjVmZDAiLCJpc3N1ZXIiOiJkaWQ6a2V5OnpRM3NoVWFqYWNvUFQxc3dGOW91bkZqRGRTV2YzeTRBMTJ2bWtneG9WVDVzcmZuaUIiLCJpc3N1YW5jZURhdGUiOiIyMDI0LTAyLTA1VDEwOjQ2OjQ5WiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmtleTp6UTNzaFhyQW5iZ2Z5dFFZUWppZlVtMkVjQkJiUkFlQWVHZmdDNFRacmp3NFg3MWlaIiwiZGF0ZU9mQmlydGgiOiIxOTkwLTAxLTAxIn19fQ.GZwkqdUdXL8SEpP6Cjm3BdVrGVNLVvqehBBVpgixrfAQ4IiY3eZFmNMRqfkK_Qbk4XKksAyMrr-58WwISh3zcA",
],
"holder": "did:key:zQ3shXrAnbgfytQYQjifUm2EcBBbRAeAeGfgC4TZrjw4X71iZ"
}
`,
language: 'Kotlin',
codeLanguage: 'json'
}
]}
/>


## Validate Presentation Submission

Before submitting the presentation to a lender, you can validate the Presentation via the `validateSubmission()` method:

<CodeSnippet functionName="pex_submissionCheck" />
<Shnip
snippets={[
{ snippetContent: validPresentationSubmissionForPex, language: 'JavaScript'},
]}
inlineSnippets={[
{
content: 'This functionality is soon to be implemented in the Kotlin SDK.' ,
language: 'Kotlin',
}
]}
/>

This method checks the presentation submission for any errors, returns an array of `Checked` objects representing the validation checks performed on the presentation submission:

Expand All @@ -125,6 +238,12 @@ Each `Checked` object contains:

## Verifiable Presentation

Once the [Presentation](/docs/glossary#verifiable-presentation) is error-free and has passed the validation checks, you can submit the Verifiable Presentation by providing the lender with the `presentation` JSON object:

<CodeSnippet functionName="pex_getPresentationFromResult" />

<Shnip
snippets={[
{ content: 'Once the [Presentation](/docs/glossary#verifiable-presentation) is error-free and has passed the validation checks, you can submit the Verifiable Presentation by providing the lender with the `presentation` JSON object:', snippetContent: validVerifiablePresentationForPex, language: 'JavaScript'},
{ content: 'After successfully creating the [Presentation](/docs/glossary#verifiable-presentation) using `VerifiablePresentation.create()`, and ensuring it is error-free and has passed all validation checks, you can submit the Verifiable Presentation by providing the lender with the `mappedPresentationSubmission` object:', snippetContent: validVerifiablePresentationForPexKt, language: 'Kotlin'},
]}
/>

35 changes: 18 additions & 17 deletions site/src/components/language/Shnip.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import LanguageSwitchBlock from '@site/src/components/language/LanguageSwitchBlo
import LanguageTabBar from '@site/src/components/language/LanguageTabBar';
import CodeSnippet from '@site/src/components/CodeSnippet';
import CodeBlock from '@theme/CodeBlock';
import ReactMarkdown from 'react-markdown';

const Shnip = ({ snippets, inlineSnippets }) => {
// support line breaks for inline code snippets
Expand All @@ -26,27 +27,27 @@ const Shnip = ({ snippets, inlineSnippets }) => {
<LanguageTabBar />
<LanguageSwitchBlock>
{snippets &&
snippets.map(({ snippetContent, language, title }) => (
<div key={`ref-${language}`} language={language}>
<CodeSnippet
snippet={snippetContent}
language={language.toLowerCase()}
title={title}
/>
</div>
))}
snippets.map(
({ snippetContent, language, title, content }, index) => (
<div key={`snippet-${language}-${index}`} language={language}>
{content && <ReactMarkdown>{content}</ReactMarkdown>}
<CodeSnippet
snippet={snippetContent}
language={language.toLowerCase()}
title={title}
/>
</div>
),
)}

{inlineSnippets &&
inlineSnippets.map(
({ code, language, codeLanguage, title, breakLineAt }) => (
<div key={`inline-${language}`} language={language}>
<CodeBlock
// parse as specified language such as bash OR parse as language from tab
language={(codeLanguage || language).toLowerCase()}
title={title}
>
({ content, code, language, codeLanguage, breakLineAt }, index) => (
<div key={`inline-${language}-${index}`} language={language}>
{content && <ReactMarkdown>{content}</ReactMarkdown>}
{code && <CodeBlock language={(codeLanguage || language).toLowerCase()}>
{addLineBreaks(code, breakLineAt)}
</CodeBlock>
</CodeBlock>}
</div>
),
)}
Expand Down
Loading

0 comments on commit c201f8d

Please sign in to comment.