Show code cell source
import { createWallet } from '@affinidi/wallet-node-sdk'
import { VCV1Type, VPV1 } from '@affinidi/vc-common'
import { uuid } from 'uuidv4';
import { PEX } from '@sphereon/pex'
// @ts-ignore
import platformCryptographyTools from '@affinidi/wallet-node-sdk/dist/PlatformCryptographyTools'
import {W3CVerifiablePresentation} from "@sphereon/ssi-types/src/types/vc";
// @ts-ignore
Presentation Exchange#
We already talk a lot about a Verifiable Presentations and how to share VC with a verifier. Today we descover yet another exchange protocol that actively suported by community nowadays Current Pex v2 introduce a few addinional concepts.
Presentation Definition#
Presentation Definitions are objects that articulate what proofs a Verifier requires. These help the Verifier to decide how or whether to interact with a Holder. Presentation Definitions are composed of inputs, which describe the forms and details of the proofs they require, and optional sets of selection rules, to allow Holders flexibility in cases where many different types of proofs may satisfy an input requirement. If we keep it simple definition is a requirement and query to a user wallet that allow to select VCs needed for verification
Presentation Submission#
Presentation Submissions are objects embedded within VP claim negotiation formats that unify the presentation of proofs to a Verifier in accordance with the requirements a Verifier specified in a Presentation Definition.
We will see in examples and details how presentation definition is corelated with submission part of VP. Submission part contains a id of definition and a descriptors map that help Verifier to navigate to a VC that satisfy concrete input descriptor of presentation definition
Follow a Video#
Show code cell source
const plantumlEncoder = require('plantuml-encoder')
const tslab = require("tslab");
const encodedTriangle = plantumlEncoder.encode(`
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Boundary(b1,"Presentation exchange") {
Person(holder, "Holder", $sprite="person2")
Person(verifier, "Verifier")
}
Rel(verifier, holder, "1 ask for VCs", "Presentation Definition")
Rel(holder, holder, "2 filter and select VC to share acconding to definition", "VCs", $sprite = "&envelope-closed")
Rel(holder, verifier, "3 issue signed VP", "VP with a submission", $sprite = "&envelope-closed")
Rel(verifier, verifier, "4 verify vp over definition", "VP with submission & definition")
@enduml
`)
const urlTriangle = 'http://www.plantuml.com/plantuml/svg/' + encodedTriangle
tslab.display.html(`<img src="${urlTriangle}"/>`)
Flow implementation#
1 Create a Definition#
Definition consist of
mandatory unique Id
name and purpouse - could be used on UI of wallet to explain expectations and needs
list of input descriptors - query and requirements
Input descriptors is most critical part that contains
id unique in definition
name and purpouse
constraints - requirements for a VC fields and values
We could describe a Constraint as a combination of 2 big parts
Array of Json pathes that give a flexibility and allow to select fields from a VCs that have different shape. Try to keep json pathes simple and avoid complex queries. JsonPath is a 1:1 mapping of xpath for xml
filter - optional but quite poverful way to validate a value of field that was selected by path. is JSONSchema compatible definition pls refer to reference
Lets imagin that we want to get from User VC with his working email. So definition will look like:
const definition = {
id: uuid(),
input_descriptors: [
{
id: 'email',
name: 'email for login',
purpose: 'we want to use you email to login',
constraints: {
fields: [
{
path: [
'$.credentialSubject.email',
'$.credentialSubject.data.email',
'$.credentialSubject.workemail',
],
purpose: 'auth requirement',
filter: {
"type": "string",
"pattern": "^[\\w.%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$"
}
}
]
}
},
{
id: 'type',
name: 'we want to use work email only',
purpose: 'authorization of user with work email only',
constraints: {
fields: [
{
path: [
'$.credentialSubject.emailType',
],
filter: {
type: 'string',
const: 'work'
},
}
]
}
}
]
}
2 Filtering a VCs in wallet#
Preparation of VCs#
We need a bit of preparation and create our VCs that we could filter. So lets do a simple steps that we do all time in our videos
obtain api key via affinidi CLI
create a Affinidi Project in VScode extension and define VC schema (optional)
create a wallet. I use already predefined seed to speed up a process. it is a test data
generate a VCs for user
const API_KEY = '<get your key from affinidi vs code extension or cli>'
const options = {
env: 'prod' as 'dev' | 'staging' | 'prod',
accessApiKey : API_KEY
}
// @ts-ignore
const walletFactory = createWallet('AffinityCore')
const password = 'Test8b60806087f5e7b8eee6607ae8!!'
const seed = 'a6a6c462b15619273fbf942c99e2b7c1be03ef184f5d1d27a17f29b45c4676dcc5e07ecc835acf1ff1d6f437e95f5cc77ce597d254a7b7db932bbb2698d0804e47cd02c7f02580da2132d008c0e313820964646c7630e01d65925d4b5f8db741'
const walletHolder = await walletFactory.openWalletByEncryptedSeed(options, seed, password)
const createEmailVC = async ({holderId, email, type }: {holderId?: string, email: string, type?: string}) => {
const jsonSchema = 'https://schema.affinidi.com/VPTestEmailV1-1.json'
const jsonContext = 'https://schema.affinidi.com/VPTestEmailV1-1.jsonld'
const unsignedVC = {
'@context': ['https://www.w3.org/2018/credentials/v1', jsonContext],
id : `urn:uuid:${uuid()}`,
type: ['VerifiableCredential', 'VPTestEmail'] as VCV1Type,
holder: {
id: holderId || walletHolder.did
},
credentialSubject: {
email,
emailType: type || 'personal'
},
credentialSchema: {
id: jsonSchema,
type: 'JsonSchemaValidator2018',
},
issuanceDate: new Date().toISOString(),
}
return await walletHolder.signUnsignedCredential(unsignedVC)
}
const generateVCs = async () => {
const emails = [{ email: 'volodymyr.p+dev1@gmail.com', type:'personal'},
{email: 'randomId', type: 'personal'},
{email: 'vp@work.com', type: 'work'},
{email: 'vp2+test@office.com', type: 'work'},
]
return await Promise.all([...emails.map( l => createEmailVC(l))])
}
const vcs = await generateVCs();
vcs[0]
{
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://schema.affinidi.com/VPTestEmailV1-1.jsonld'
],
id: 'urn:uuid:47bf3837-4e55-4a31-8295-92621273a345',
type: [ 'VerifiableCredential', 'VPTestEmail' ],
holder: {
id: 'did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ'
},
credentialSubject: { email: 'volodymyr.p+dev1@gmail.com', emailType: 'personal' },
credentialSchema: {
id: 'https://schema.affinidi.com/VPTestEmailV1-1.json',
type: 'JsonSchemaValidator2018'
},
issuanceDate: '2023-03-17T10:25:08.237Z',
issuer: 'did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ',
proof: {
type: 'EcdsaSecp256k1Signature2019',
created: '2023-03-17T10:25:08Z',
verificationMethod: 'did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ#primary',
proofPurpose: 'assertionMethod',
jws: 'eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..STVXtzS39fOVF4XnSssDiOn5maeyJp1OM4Qv_dEtkkMhudbNmsTjj7VdUU_ZwvJhkXgkYntO7H41VVjnhdWMlQ'
}
}
Now on wallet side we a ready to implement filtering and VC selection#
Filtering part
const pex: PEX = new PEX();
// Extension VC filter logic
const srMatches = pex.selectFrom(definition, vcs)
JSON.stringify(srMatches, null,1)
{
"errors": [],
"matches": [
{
"name": "email for login",
"rule": "all",
"vc_path": [
"$.verifiableCredential[0]"
]
},
{
"name": "we want to use work email only",
"rule": "all",
"vc_path": [
"$.verifiableCredential[0]"
]
},
{
"name": "email for login",
"rule": "all",
"vc_path": [
"$.verifiableCredential[1]"
]
},
{
"name": "we want to use work email only",
"rule": "all",
"vc_path": [
"$.verifiableCredential[1]"
]
}
],
"areRequiredCredentialsPresent": "info",
"verifiableCredential": [
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schema.affinidi.com/VPTestEmailV1-1.jsonld"
],
"id": "urn:uuid:2fcfde66-6a85-4ac8-ba0f-bf0660d10ace",
"type": [
"VerifiableCredential",
"VPTestEmail"
],
"holder": {
"id": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ"
},
"credentialSubject": {
"email": "vp@work.com",
"emailType": "work"
},
"credentialSchema": {
"id": "https://schema.affinidi.com/VPTestEmailV1-1.json",
"type": "JsonSchemaValidator2018"
},
"issuanceDate": "2023-03-17T10:25:08.294Z",
"issuer": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ",
"proof": {
"type": "EcdsaSecp256k1Signature2019",
"created": "2023-03-17T10:25:08Z",
"verificationMethod": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ#primary",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..ziFqSWNK0oUDrNKAg8eHpSXvQCm7akDBvQ5SYZdB_WltfkiKwsCA7A3yZMEQOtF4XKIDptlhu_Ccp-wu49WBsg"
}
},
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schema.affinidi.com/VPTestEmailV1-1.jsonld"
],
"id": "urn:uuid:39a44fe4-2769-480e-9c85-dff79c78770e",
"type": [
"VerifiableCredential",
"VPTestEmail"
],
"holder": {
"id": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ"
},
"credentialSubject": {
"email": "vp2+test@office.com",
"emailType": "work"
},
"credentialSchema": {
"id": "https://schema.affinidi.com/VPTestEmailV1-1.json",
"type": "JsonSchemaValidator2018"
},
"issuanceDate": "2023-03-17T10:25:08.322Z",
"issuer": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ",
"proof": {
"type": "EcdsaSecp256k1Signature2019",
"created": "2023-03-17T10:25:08Z",
"verificationMethod": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ#primary",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..-H69QkVAVRTeTEBCdBbwabay7I7C2oGtXnkgVCgUDHpcByzC8QZffZa7xWH5ZaDszHSDHmCz5mx0rm-OUaTtgQ"
}
}
],
"warnings": []
}
Now Wallet could decide and optionaly show a UI interface that ask user to share all or only selected VCs. Lets share first VC
3 Issue a VP#
Issuence consists of 2 simple steps
preparing a presentation
VPsign
const presentation = pex.presentationFrom(definition, [srMatches.verifiableCredential[0]], walletHolder.did);
presentation.id = `urn:uuid:${uuid()}`
// Create affinidi signed VP
const domain = 'affinidi.io'
const challenge = definition.id
const affinidiPresentation = JSON.parse(JSON.stringify(presentation))
affinidiPresentation.holder = {id: affinidiPresentation.holder }
const affinidiSignedVP = await walletHolder.signUnsignedPresentation(affinidiPresentation, challenge, domain)
JSON.stringify(affinidiSignedVP, null, 1)
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://identity.foundation/presentation-exchange/submission/v1"
],
"type": [
"VerifiablePresentation",
"PresentationSubmission"
],
"holder": {
"id": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ"
},
"presentation_submission": {
"id": "pQ4NfGdXr_s_0w-MzZrJJ",
"definition_id": "93d94bd3-aa6f-49c1-baf0-3870c1571059",
"descriptor_map": [
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[0]"
},
{
"id": "type",
"format": "ldp_vc",
"path": "$.verifiableCredential[0]"
}
]
},
"verifiableCredential": [
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schema.affinidi.com/VPTestEmailV1-1.jsonld"
],
"id": "urn:uuid:2fcfde66-6a85-4ac8-ba0f-bf0660d10ace",
"type": [
"VerifiableCredential",
"VPTestEmail"
],
"holder": {
"id": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ"
},
"credentialSubject": {
"email": "vp@work.com",
"emailType": "work"
},
"credentialSchema": {
"id": "https://schema.affinidi.com/VPTestEmailV1-1.json",
"type": "JsonSchemaValidator2018"
},
"issuanceDate": "2023-03-17T10:25:08.294Z",
"issuer": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ",
"proof": {
"type": "EcdsaSecp256k1Signature2019",
"created": "2023-03-17T10:25:08Z",
"verificationMethod": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ#primary",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..ziFqSWNK0oUDrNKAg8eHpSXvQCm7akDBvQ5SYZdB_WltfkiKwsCA7A3yZMEQOtF4XKIDptlhu_Ccp-wu49WBsg"
}
}
],
"id": "urn:uuid:6d6b6345-8293-408f-a939-399930114f88",
"proof": {
"type": "EcdsaSecp256k1Signature2019",
"created": "2023-03-17T10:25:18Z",
"verificationMethod": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ#primary",
"proofPurpose": "authentication",
"challenge": "93d94bd3-aa6f-49c1-baf0-3870c1571059",
"domain": "affinidi.io",
"jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..6WZAkVAa2J8vPq3bcK-g3i09yrUTdAU9HczvJC4MeCIf6nZPzqszNM1QALpPvRif728QBXgZqe4b2-gb0pdiUQ"
}
}
4 Verify a VP#
Now we gets back to a verifier and Validate a VP. VP validation is a complex tasks that include few steps
check a VP integrity and signature
check the challenge part
evaluate a VP over presentation definition
check the validity and integrity of every VC
For simplisity we will focus on 2 key point that matter for PEX
Evaluate a VP#
const sphereonVP = JSON.parse(JSON.stringify(affinidiSignedVP))
sphereonVP.holder = sphereonVP.holder.id
const result = pex.evaluatePresentation(definition, sphereonVP)
JSON.stringify(result, null,1)
{
"areRequiredCredentialsPresent": "info",
"verifiableCredential": [
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schema.affinidi.com/VPTestEmailV1-1.jsonld"
],
"id": "urn:uuid:2fcfde66-6a85-4ac8-ba0f-bf0660d10ace",
"type": [
"VerifiableCredential",
"VPTestEmail"
],
"holder": {
"id": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ"
},
"credentialSubject": {
"email": "vp@work.com",
"emailType": "work"
},
"credentialSchema": {
"id": "https://schema.affinidi.com/VPTestEmailV1-1.json",
"type": "JsonSchemaValidator2018"
},
"issuanceDate": "2023-03-17T10:25:08.294Z",
"issuer": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ",
"proof": {
"type": "EcdsaSecp256k1Signature2019",
"created": "2023-03-17T10:25:08Z",
"verificationMethod": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ#primary",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..ziFqSWNK0oUDrNKAg8eHpSXvQCm7akDBvQ5SYZdB_WltfkiKwsCA7A3yZMEQOtF4XKIDptlhu_Ccp-wu49WBsg"
}
}
],
"warnings": [],
"errors": [],
"value": {
"id": "w2rpt--45agft3AUbaPRn",
"definition_id": "93d94bd3-aa6f-49c1-baf0-3870c1571059",
"descriptor_map": [
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[0]"
},
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[2]"
},
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[3]"
},
{
"id": "type",
"format": "ldp_vc",
"path": "$.verifiableCredential[2]"
},
{
"id": "type",
"format": "ldp_vc",
"path": "$.verifiableCredential[3]"
},
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[0]"
},
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[2]"
},
{
"id": "type",
"format": "ldp_vc",
"path": "$.verifiableCredential[2]"
},
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[3]"
},
{
"id": "type",
"format": "ldp_vc",
"path": "$.verifiableCredential[3]"
},
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[0]"
},
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[2]"
},
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[3]"
},
{
"id": "type",
"format": "ldp_vc",
"path": "$.verifiableCredential[2]"
},
{
"id": "type",
"format": "ldp_vc",
"path": "$.verifiableCredential[3]"
},
{
"id": "email",
"path": "$.verifiableCredential[0]"
},
{
"id": "email",
"path": "$.verifiableCredential[0]"
},
{
"id": "email",
"path": "$.verifiableCredential[3]"
},
{
"id": "type",
"path": "$.verifiableCredential[3]"
},
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[0]"
}
]
}
}
const {errors , warnings } = result
const isEvaluated = errors.length === 0 && warnings.length === 0
isEvaluated
true
Integrity Check#
const validationResult = await walletHolder.verifyPresentation(affinidiSignedVP as VPV1)
JSON.stringify(validationResult, null,1)
{
"isValid": true,
"did": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ",
"challenge": "93d94bd3-aa6f-49c1-baf0-3870c1571059",
"suppliedPresentation": {
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://identity.foundation/presentation-exchange/submission/v1"
],
"type": [
"VerifiablePresentation",
"PresentationSubmission"
],
"holder": {
"id": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ"
},
"presentation_submission": {
"id": "pQ4NfGdXr_s_0w-MzZrJJ",
"definition_id": "93d94bd3-aa6f-49c1-baf0-3870c1571059",
"descriptor_map": [
{
"id": "email",
"format": "ldp_vc",
"path": "$.verifiableCredential[0]"
},
{
"id": "type",
"format": "ldp_vc",
"path": "$.verifiableCredential[0]"
}
]
},
"verifiableCredential": [
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schema.affinidi.com/VPTestEmailV1-1.jsonld"
],
"id": "urn:uuid:2fcfde66-6a85-4ac8-ba0f-bf0660d10ace",
"type": [
"VerifiableCredential",
"VPTestEmail"
],
"holder": {
"id": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ"
},
"credentialSubject": {
"email": "vp@work.com",
"emailType": "work"
},
"credentialSchema": {
"id": "https://schema.affinidi.com/VPTestEmailV1-1.json",
"type": "JsonSchemaValidator2018"
},
"issuanceDate": "2023-03-17T10:25:08.294Z",
"issuer": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek4yTTFaVFV3WTJKaE9HRTNNamRoWkRSbE5XWXdNamc0Tm1VMll6bGxabVk0TWpGaFl6QTJOV1ZtWXpFd1pEZGhPVEkyT1RJME1XTTNZV1kxTUdVek1pSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpNeVpUazVZekl3T1dVd01HSmxOVGM1TldRMFpqUXlNR0psTlRoak1qQm1OREV5Tm1Vd05qZ3hNbVUxTVROalpXWmtOVEprWW1KaU5qazRNekkxTURNaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiRWhKdDlCVEtyV0YyRjdRSGhPNTJuODhtZTdxU3VMOHdJOVdCSGh3UC1BQkVvZzF6R2t3SkJUSkdaNE0wTjZLb1c0U2RGYXRlSnJZTUNhamhNeWtSZlEifQ",
"proof": {
"type": "EcdsaSecp256k1Signature2019",
"created": "2023-03-17T10:25:08Z",
"verificationMethod": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ#primary",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..ziFqSWNK0oUDrNKAg8eHpSXvQCm7akDBvQ5SYZdB_WltfkiKwsCA7A3yZMEQOtF4XKIDptlhu_Ccp-wu49WBsg"
}
}
],
"id": "urn:uuid:6d6b6345-8293-408f-a939-399930114f88",
"proof": {
"type": "EcdsaSecp256k1Signature2019",
"created": "2023-03-17T10:25:18Z",
"verificationMethod": "did:elem:EiBi2nJp4p8x6dVz8zW635_ccJFn3Y_tIQDIvdxUUmtMgQ#primary",
"proofPurpose": "authentication",
"challenge": "93d94bd3-aa6f-49c1-baf0-3870c1571059",
"domain": "affinidi.io",
"jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..6WZAkVAa2J8vPq3bcK-g3i09yrUTdAU9HczvJC4MeCIf6nZPzqszNM1QALpPvRif728QBXgZqe4b2-gb0pdiUQ"
}
}
}
isEvaluated && validationResult.isValid
true