npm init -y
npm install @affinidi/wallet-node-sdk fetch@2 ts-node
ts-node revocable-vc.ts
Last active
September 9, 2022 14:36
-
-
Save Volland/b411c787be180c13592a96cfcabc0627 to your computer and use it in GitHub Desktop.
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
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"# Preinstall \n", | |
"We use sos notebooks. You could use a docker instalation [guide](https://vatlab.github.io/sos-docs/running.html)\n", | |
"This notebook is self contained \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"# Preinstall \n", | |
"We use sos notebooks. You could use a docker instalation [guide](https://vatlab.github.io/sos-docs/running.html)\n", | |
"This notebook is self contained " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"kernel": "Python3" | |
}, | |
"outputs": [], | |
"source": [ | |
"!pip install iplantuml" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"kernel": "Python3" | |
}, | |
"outputs": [], | |
"source": [ | |
"!npm init -y\n", | |
"!npm install @affinidi/wallet-node-sdk fetch@2" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"# Revocable VCs \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"# Revocable VCs " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 64, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"Lets prepare our test wallets \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"Lets prepare our test wallets " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"const { createWallet } = require('@affinidi/wallet-node-sdk')\n", | |
"// @ts-ignore\n", | |
"const walletFactory = createWallet('AffinityCore')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"Lets prepare options \n", | |
"- get your API key [production](https://apikey.affinidi.com/) or register affinidi account on [register](https://build.affinidi.com/register)\n", | |
"- set env to prod \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"Lets prepare options \n", | |
"- get your API key [production](https://apikey.affinidi.com/) or register affinidi account on [register](https://build.affinidi.com/register)\n", | |
"- set env to prod " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"kernel": "Python3" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/vnd.jupyter.widget-view+json": { | |
"model_id": "69ed51aff5674589920dbc4d0a1f5941", | |
"version_major": 2, | |
"version_minor": 0 | |
}, | |
"text/plain": [ | |
"Password(description='API KEY:', placeholder='EnterAPI key')" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"import ipywidgets\n", | |
"apikey_widget = ipywidgets.Password(description='API KEY:', placeholder='EnterAPI key')\n", | |
"apikey_widget" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": { | |
"kernel": "Python3" | |
}, | |
"outputs": [], | |
"source": [ | |
"accessApiKey = apikey_widget.value " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"1" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"%get accessApiKey --from Python3\n", | |
"options = {\n", | |
" env: 'prod',\n", | |
" accessApiKey: accessApiKey\n", | |
"}\n", | |
"1" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": { | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"Lets create our issuer and holder wallets.\n", | |
"We need to have a holder did to issue a VC for concrete holder.\n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"Lets create our issuer and holder wallets.\n", | |
"We need to have a holder did to issue a VC for concrete holder." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
" password = `P@${(Math.random() + 1).toString(36).substring(2)}!!42`;\n", | |
"\n", | |
"(async () => {\n", | |
" walletIssuer = await walletFactory.createWallet(options, password)\n", | |
" walletHolder = await walletFactory.createWallet(options, password)\n", | |
" })().catch(console.error)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"## Lets create a Unsigned Credential \n", | |
"I just create a custom schema for content Like VCs. Its allow to issue verifiable likes for a content that i like.\n", | |
"[Schema](https://ui.schema.affinidi.com/schemas/ContentLikeV1-0)\n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"## Lets create a Unsigned Credential \n", | |
"I just create a custom schema for content Like VCs. Its allow to issue verifiable likes for a content that i like.\n", | |
"[Schema](https://ui.schema.affinidi.com/schemas/ContentLikeV1-0)\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"\n", | |
"// https://ui.schema.affinidi.com/schemas/ContentLikeV1-0\n", | |
"const jsonSchema = 'https://schema.affinidi.com/ContentLikeV1-0.json'\n", | |
"const jsonContext = 'https://schema.affinidi.com/ContentLikeV1-0.jsonld'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 65, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"Every VC should have a unique id. \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"Every VC should have a unique id. " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"const id = `claimId:${(Math.random() + 1).toString(36).substring(2)}`" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{\n", | |
" '@context': [\n", | |
" 'https://www.w3.org/2018/credentials/v1',\n", | |
" 'https://schema.affinidi.com/ContentLikeV1-0.jsonld'\n", | |
" ],\n", | |
" id: 'claimId:i2wgld5x7b',\n", | |
" type: [ 'VerifiableCredential', 'ContentLike' ],\n", | |
" holder: {\n", | |
" id: 'did:elem:EiAs9VqvNcEMkm9OfMdseWR0jMIltWHuUd5tCK_f17M6jA;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek5UUXhZMk01T1RabU56VmxaR1U1WkRnd00yVXlOVE5oTm1FNU5UWXdOekF5TWprMk1EaGhNemM0WVRWbE56RmlaV1V4WldGaE1EQXpObU0zTkdJME1DSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TTJOaU1qZzFPVGRrWkRjM016bG1OREl3WTJaaVpEUXdOekZtTUdNNU5Ua3dPRFZtWVRBNVlqSXlOR1l4Tm1ZeE1UbGlOelV6WVRZeVpXVTJaalJqT1RRaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiOXg1UVpYS0h4OEFCSmd2cmhqVFhhR2NGUC1TSVdoYVJCeW1Vbm9vOGk2dGdMaDhWSnlWWGxnbS0xaTZqSXROTW1NZXEwX2t1SUZRZnVNelVNdVNMbXcifQ'\n", | |
" },\n", | |
" credentialSubject: {\n", | |
" data: {\n", | |
" '@type': [Array],\n", | |
" url: 'https://www.youtube.com/watch?v=owbkzvLhblk',\n", | |
" date: '2022-09-09T13:22:20.668Z',\n", | |
" like: true,\n", | |
" score: 10\n", | |
" }\n", | |
" },\n", | |
" credentialSchema: {\n", | |
" id: 'https://schema.affinidi.com/ContentLikeV1-0.json',\n", | |
" type: 'JsonSchemaValidator2018'\n", | |
" },\n", | |
" issuanceDate: '2022-09-09T13:22:20.668Z',\n", | |
" expirationDate: '2065-09-10T00:00:00.000Z'\n", | |
"}" | |
] | |
}, | |
"execution_count": 18, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
" unsignedVC = {\n", | |
" '@context': ['https://www.w3.org/2018/credentials/v1', jsonContext],\n", | |
" id,\n", | |
" type: ['VerifiableCredential', 'ContentLike'],\n", | |
" holder: {\n", | |
" id: walletHolder.did\n", | |
" },\n", | |
" credentialSubject: {\n", | |
" data: {\n", | |
" '@type': ['VerifiableCredential', 'ContentLike'],\n", | |
" url: 'https://www.youtube.com/watch?v=owbkzvLhblk',\n", | |
" date: new Date().toISOString(),\n", | |
" like: true,\n", | |
" score: 10\n", | |
" },\n", | |
" },\n", | |
" credentialSchema: {\n", | |
" id: jsonSchema,\n", | |
" type: 'JsonSchemaValidator2018',\n", | |
" },\n", | |
" issuanceDate: new Date().toISOString(),\n", | |
" expirationDate: '2065-09-10T00:00:00.000Z',\n", | |
" }\n", | |
" unsignedVC " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 19, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"It is already good VC to sign but what if i ll change my mind in a future ?\n", | |
"\n", | |
"VCs are immutable and owned by holder. Once you issue tham you do not have a control on VC any more.\n", | |
"\n", | |
"We have a special type of VCs that allow you to Revoke a VC in a future even if you dont have a control on VC itself\n", | |
"\n", | |
"It is based on [Revocation List 2020](https://w3c-ccg.github.io/vc-status-rl-2020/#core-concept) standard \n", | |
"\n", | |
"It is quite complex flow but we make it easy for you and implement a method in our SDK.\n", | |
"You could upgrade your VC to revocapbe VC. We will prepare and publish revocation list for you \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"It is already good VC to sign but what if i ll change my mind in a future ?\n", | |
"\n", | |
"VCs are immutable and owned by holder. Once you issue tham you do not have a control on VC any more.\n", | |
"\n", | |
"We have a special type of VCs that allow you to Revoke a VC in a future even if you dont have a control on VC itself\n", | |
"\n", | |
"It is based on [Revocation List 2020](https://w3c-ccg.github.io/vc-status-rl-2020/#core-concept) standard \n", | |
"\n", | |
"It is quite complex flow but we make it easy for you and implement a method in our SDK.\n", | |
"You could upgrade your VC to revocapbe VC. We will prepare and publish revocation list for you \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 20, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"(async () => { \n", | |
" RevocableVC = await walletIssuer.buildRevocationListStatus(unsignedVC)\n", | |
"\n", | |
"})().catch(console.error)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 21, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{\n", | |
" '@context': [\n", | |
" 'https://www.w3.org/2018/credentials/v1',\n", | |
" 'https://schema.affinidi.com/ContentLikeV1-0.jsonld',\n", | |
" 'https://w3id.org/vc-revocation-list-2020/v1'\n", | |
" ],\n", | |
" id: 'claimId:i2wgld5x7b',\n", | |
" type: [ 'VerifiableCredential', 'ContentLike' ],\n", | |
" holder: {\n", | |
" id: 'did:elem:EiAs9VqvNcEMkm9OfMdseWR0jMIltWHuUd5tCK_f17M6jA;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek5UUXhZMk01T1RabU56VmxaR1U1WkRnd00yVXlOVE5oTm1FNU5UWXdOekF5TWprMk1EaGhNemM0WVRWbE56RmlaV1V4WldGaE1EQXpObU0zTkdJME1DSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TTJOaU1qZzFPVGRrWkRjM016bG1OREl3WTJaaVpEUXdOekZtTUdNNU5Ua3dPRFZtWVRBNVlqSXlOR1l4Tm1ZeE1UbGlOelV6WVRZeVpXVTJaalJqT1RRaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiOXg1UVpYS0h4OEFCSmd2cmhqVFhhR2NGUC1TSVdoYVJCeW1Vbm9vOGk2dGdMaDhWSnlWWGxnbS0xaTZqSXROTW1NZXEwX2t1SUZRZnVNelVNdVNMbXcifQ'\n", | |
" },\n", | |
" credentialSubject: {\n", | |
" data: {\n", | |
" '@type': [Array],\n", | |
" url: 'https://www.youtube.com/watch?v=owbkzvLhblk',\n", | |
" date: '2022-09-09T13:22:20.668Z',\n", | |
" like: true,\n", | |
" score: 10\n", | |
" }\n", | |
" },\n", | |
" credentialSchema: {\n", | |
" id: 'https://schema.affinidi.com/ContentLikeV1-0.json',\n", | |
" type: 'JsonSchemaValidator2018'\n", | |
" },\n", | |
" issuanceDate: '2022-09-09T13:22:20.668Z',\n", | |
" expirationDate: '2065-09-10T00:00:00.000Z',\n", | |
" credentialStatus: {\n", | |
" id: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551#1',\n", | |
" type: 'RevocationList2020Status',\n", | |
" revocationListIndex: '1',\n", | |
" revocationListCredential: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551'\n", | |
" }\n", | |
"}" | |
] | |
}, | |
"execution_count": 21, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"\n", | |
"RevocableVC" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 22, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"(async () => {\n", | |
"revocationListVc = await fetch(RevocableVC.credentialStatus.revocationListCredential)\n", | |
"})().catch(console.error)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 23, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"Together with a VC we issue a Revocation List VC connected to our Credential. This credential is Issuer specific List and Signed and controled by issuer. Every time when Issuer bublish new Revocable VC or revoke a VC. Revocation List gets updated and published.\n", | |
"\n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"Together with a VC we issue a Revocation List VC connected to our Credential. This credential is Issuer specific List and Signed and controled by issuer. Every time when Issuer bublish new Revocable VC or revoke a VC. Revocation List gets updated and published.\n", | |
"\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 24, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{\n", | |
" id: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551',\n", | |
" '@context': [\n", | |
" 'https://www.w3.org/2018/credentials/v1',\n", | |
" 'https://w3id.org/vc-revocation-list-2020/v1'\n", | |
" ],\n", | |
" type: [ 'VerifiableCredential', 'RevocationList2020Credential' ],\n", | |
" issuer: 'did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek1HTXdOMlZtTnpFeU1ETTVaamhtWkdOa1ltVmtPR0V3WldJNFpqaG1ZbU5qTlRaak0ySmpOREEwTVRSak1HRTRaR1F6TVRjeFpHTm1NR1k0TW1KaE1TSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpSaFpEa3hNR1E1WVRSa1lXWTRPV1V5WW1ZNE9USTFPVEEyWlRobU4ySmtaRGhtTVdVM01EWTROMlF6T0RJMVptRmhZems0Tm1ObE5HUmhZVFZqTVdZaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiVC1fc0drTmdMX294cHM1cEFYRDZWLVJCdmtjQzlKOFZJQnN3aGxYazA4TjQwXzBQQWpzbmRTb0FrbFQ5bmZxUWZRYlpLem9jek5QMVd3Z1M3bkVHMGcifQ',\n", | |
" issuanceDate: '2022-09-09T13:22:37.281Z',\n", | |
" credentialSubject: {\n", | |
" id: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551#list',\n", | |
" type: 'RevocationList2020',\n", | |
" encodedList: 'H4sIAAAAAAAAA-3BMQEAAADCoPVPbQsvoAAAAAAAAAAAAAAAAP4GcwM92tQwAAA'\n", | |
" },\n", | |
" proof: {\n", | |
" type: 'EcdsaSecp256k1Signature2019',\n", | |
" created: '2022-09-09T13:22:37Z',\n", | |
" verificationMethod: 'did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw#primary',\n", | |
" proofPurpose: 'assertionMethod',\n", | |
" jws: 'eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..KBSUju310a1tuA-kiq79kUYST0Svn4MdFw_0pCcGoZZR-aiP1wzk1atb0tL7rhxqkJvDjnQIQo0t281-E10IjQ'\n", | |
" }\n", | |
"}" | |
] | |
}, | |
"execution_count": 24, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"revocationListVc.json()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 25, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"## Lets sign it \n", | |
"To make it verifiable we just need to sign it.\n", | |
"So issuence on edge is simple operation \n", | |
"- build vc \n", | |
"- sign vc\n", | |
"- sharewith holder (optional )\n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"## Lets sign it \n", | |
"To make it verifiable we just need to sign it.\n", | |
"So issuence on edge is simple operation \n", | |
"- build vc \n", | |
"- sign vc\n", | |
"- sharewith holder (optional )" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 26, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"(async () => {\n", | |
" signedRevocableVC = await walletIssuer.signUnsignedCredential(RevocableVC)\n", | |
"})().catch(console.error)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{\n", | |
" '@context': [\n", | |
" 'https://www.w3.org/2018/credentials/v1',\n", | |
" 'https://schema.affinidi.com/ContentLikeV1-0.jsonld',\n", | |
" 'https://w3id.org/vc-revocation-list-2020/v1'\n", | |
" ],\n", | |
" id: 'claimId:i2wgld5x7b',\n", | |
" type: [ 'VerifiableCredential', 'ContentLike' ],\n", | |
" holder: {\n", | |
" id: 'did:elem:EiAs9VqvNcEMkm9OfMdseWR0jMIltWHuUd5tCK_f17M6jA;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek5UUXhZMk01T1RabU56VmxaR1U1WkRnd00yVXlOVE5oTm1FNU5UWXdOekF5TWprMk1EaGhNemM0WVRWbE56RmlaV1V4WldGaE1EQXpObU0zTkdJME1DSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TTJOaU1qZzFPVGRrWkRjM016bG1OREl3WTJaaVpEUXdOekZtTUdNNU5Ua3dPRFZtWVRBNVlqSXlOR1l4Tm1ZeE1UbGlOelV6WVRZeVpXVTJaalJqT1RRaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiOXg1UVpYS0h4OEFCSmd2cmhqVFhhR2NGUC1TSVdoYVJCeW1Vbm9vOGk2dGdMaDhWSnlWWGxnbS0xaTZqSXROTW1NZXEwX2t1SUZRZnVNelVNdVNMbXcifQ'\n", | |
" },\n", | |
" credentialSubject: {\n", | |
" data: {\n", | |
" '@type': [Array],\n", | |
" url: 'https://www.youtube.com/watch?v=owbkzvLhblk',\n", | |
" date: '2022-09-09T13:22:20.668Z',\n", | |
" like: true,\n", | |
" score: 10\n", | |
" }\n", | |
" },\n", | |
" credentialSchema: {\n", | |
" id: 'https://schema.affinidi.com/ContentLikeV1-0.json',\n", | |
" type: 'JsonSchemaValidator2018'\n", | |
" },\n", | |
" issuanceDate: '2022-09-09T13:22:20.668Z',\n", | |
" expirationDate: '2065-09-10T00:00:00.000Z',\n", | |
" credentialStatus: {\n", | |
" id: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551#1',\n", | |
" type: 'RevocationList2020Status',\n", | |
" revocationListIndex: '1',\n", | |
" revocationListCredential: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551'\n", | |
" },\n", | |
" issuer: 'did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek1HTXdOMlZtTnpFeU1ETTVaamhtWkdOa1ltVmtPR0V3WldJNFpqaG1ZbU5qTlRaak0ySmpOREEwTVRSak1HRTRaR1F6TVRjeFpHTm1NR1k0TW1KaE1TSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpSaFpEa3hNR1E1WVRSa1lXWTRPV1V5WW1ZNE9USTFPVEEyWlRobU4ySmtaRGhtTVdVM01EWTROMlF6T0RJMVptRmhZems0Tm1ObE5HUmhZVFZqTVdZaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiVC1fc0drTmdMX294cHM1cEFYRDZWLVJCdmtjQzlKOFZJQnN3aGxYazA4TjQwXzBQQWpzbmRTb0FrbFQ5bmZxUWZRYlpLem9jek5QMVd3Z1M3bkVHMGcifQ',\n", | |
" proof: {\n", | |
" type: 'EcdsaSecp256k1Signature2019',\n", | |
" created: '2022-09-09T13:23:18Z',\n", | |
" verificationMethod: 'did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw#primary',\n", | |
" proofPurpose: 'assertionMethod',\n", | |
" jws: 'eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..egv-RIoJfND0Ga-NiqCcPXe7lA2uggrgoAm1yp2dLLVk7mEy_r2RCzVKxzNwPGoma10ZZ7JgL9MY4rrC1z-BpA'\n", | |
" }\n", | |
"}" | |
] | |
}, | |
"execution_count": 27, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"signedRevocableVC" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 28, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"## Verification\n", | |
"Main idea of VC is verifiable data\n", | |
"We could do a verification on edge with our common library\n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"## Verification\n", | |
"Main idea of VC is verifiable data\n", | |
"We could do a verification on edge with our common library\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 37, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"const { Affinity: Verifier } = require('@affinidi/common')\n", | |
"const platformCryptographyTools = require ('@affinidi/wallet-node-sdk/dist/PlatformCryptographyTools')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 39, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"const verifier4 = new Verifier({\n", | |
" registryUrl: `https://affinity-registry.${options.env}.affinity-project.org`,\n", | |
" apiKey: accessApiKey\n", | |
"}, platformCryptographyTools)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 40, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"Lets verify \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"Lets verify " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 48, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"(async () => {\n", | |
" verificationResult = await verifier4.validateCredential(signedRevocableVC)\n", | |
"})().catch(console.error)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 59, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"{ result: true, error: '' }\n", | |
"## Revocation \n", | |
"Now we could change our mind \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"{ result: true, error: '' }\n", | |
"## Revocation \n", | |
"Now we could change our mind " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 57, | |
"metadata": { | |
"kernel": "JavaScript" | |
}, | |
"outputs": [], | |
"source": [ | |
"(async () => {\n", | |
" await walletIssuer.revokeCredential(id , ' dont like any more ')\n", | |
"})().catch(console.error)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 58, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"Now credential is invalid \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"Now credential is invalid " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 60, | |
"metadata": { | |
"collapsed": true, | |
"jupyter": { | |
"outputs_hidden": true | |
}, | |
"kernel": "JavaScript" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"(async () => {\n", | |
" verificationRevokedResult = await verifier4.validateCredential(signedRevocableVC)\n", | |
"})().catch(console.error)\n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"(async () => {\n", | |
" verificationRevokedResult = await verifier4.validateCredential(signedRevocableVC)\n", | |
"})().catch(console.error)\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 61, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"{\n", | |
" result: false,\n", | |
" error: 'claimId:gacultz6iz: Credential revocation status check result is negative.'\n", | |
"}\n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"{\n", | |
" result: false,\n", | |
" error: 'claimId:gacultz6iz: Credential revocation status check result is negative.'\n", | |
"}" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 69, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Markdown" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/markdown": [ | |
"## Revocation API internals\n", | |
"[Affinidi Revocation Service](http://revocation-api.prod.affinity-project.org/api-docs) Do all managment of revocation list.\n", | |
"Service use did auth to reensure that issuer could have access only to his revocation lists and could revoke only his credentials \n" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"## Revocation API internals\n", | |
"[Affinidi Revocation Service](http://revocation-api.prod.affinity-project.org/api-docs) Do all managment of revocation list.\n", | |
"Service use did auth to reensure that issuer could have access only to his revocation lists and could revoke only his credentials \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 66, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Python3" | |
}, | |
"outputs": [], | |
"source": [ | |
"import iplantuml" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 68, | |
"metadata": { | |
"jupyter": { | |
"source_hidden": true | |
}, | |
"kernel": "Python3" | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": [ | |
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" contentStyleType=\"text/css\" height=\"1055px\" preserveAspectRatio=\"none\" style=\"width:1838px;height:1055px;background:#FFFFFF;\" version=\"1.1\" viewBox=\"0 0 1838 1055\" width=\"1838px\" zoomAndPan=\"magnify\"><defs/><g><rect fill=\"none\" height=\"26.2969\" id=\"_title\" style=\"stroke:none;stroke-width:1.0;\" width=\"468\" x=\"681\" y=\"10\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"14\" font-weight=\"bold\" lengthAdjust=\"spacing\" textLength=\"458\" x=\"686\" y=\"27.9951\">Affinidi: VC revocation (revocation list 2020) Iusser side</text><rect fill=\"none\" height=\"117.5313\" style=\"stroke:#000000;stroke-width:1.5;\" width=\"759.5\" x=\"558\" y=\"518.3203\"/><line style=\"stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;\" x1=\"632\" x2=\"632\" y1=\"118.5938\" y2=\"975.1797\"/><line style=\"stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;\" x1=\"1197.5\" x2=\"1197.5\" y1=\"118.5938\" y2=\"975.1797\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" textLength=\"123\" x=\"568\" y=\"115.292\">Issuer client , sdk</text><ellipse cx=\"632.5\" cy=\"50.7969\" fill=\"#E2E2F0\" rx=\"8\" ry=\"8\" style=\"stroke:#181818;stroke-width:0.5;\"/><path d=\"M632.5,58.7969 L632.5,85.7969 M619.5,66.7969 L645.5,66.7969 M632.5,85.7969 L619.5,100.7969 M632.5,85.7969 L645.5,100.7969 \" fill=\"none\" style=\"stroke:#181818;stroke-width:0.5;\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" textLength=\"123\" x=\"568\" y=\"987.1748\">Issuer client , sdk</text><ellipse cx=\"632.5\" cy=\"998.9766\" fill=\"#E2E2F0\" rx=\"8\" ry=\"8\" style=\"stroke:#181818;stroke-width:0.5;\"/><path d=\"M632.5,1006.9766 L632.5,1033.9766 M619.5,1014.9766 L645.5,1014.9766 M632.5,1033.9766 L619.5,1048.9766 M632.5,1033.9766 L645.5,1048.9766 \" fill=\"none\" style=\"stroke:#181818;stroke-width:0.5;\"/><rect fill=\"#E2E2F0\" height=\"30.2969\" rx=\"2.5\" ry=\"2.5\" style=\"stroke:#181818;stroke-width:0.5;\" width=\"220\" x=\"1087.5\" y=\"87.2969\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" textLength=\"138\" x=\"1094.5\" y=\"107.292\">Revocation Service</text><a href=\"https://gitlab.com/affinidi/foundational/revocation-api\" target=\"_top\" title=\"https://gitlab.com/affinidi/foundational/revocation-api\" xlink:actuate=\"onRequest\" xlink:href=\"https://gitlab.com/affinidi/foundational/revocation-api\" xlink:show=\"new\" xlink:title=\"https://gitlab.com/affinidi/foundational/revocation-api\" xlink:type=\"simple\"><text fill=\"#0000FF\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" text-decoration=\"underline\" textLength=\"34\" x=\"1236.5\" y=\"107.292\">repo</text></a><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" textLength=\"4\" x=\"1270.5\" y=\"107.292\">,</text><a href=\"http://revocation-api.dev.affinity-project.org/api-docs/\" target=\"_top\" title=\"http://revocation-api.dev.affinity-project.org/api-docs/\" xlink:actuate=\"onRequest\" xlink:href=\"http://revocation-api.dev.affinity-project.org/api-docs/\" xlink:show=\"new\" xlink:title=\"http://revocation-api.dev.affinity-project.org/api-docs/\" xlink:type=\"simple\"><text fill=\"#0000FF\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" text-decoration=\"underline\" textLength=\"22\" x=\"1278.5\" y=\"107.292\">api</text></a><rect fill=\"#E2E2F0\" height=\"30.2969\" rx=\"2.5\" ry=\"2.5\" style=\"stroke:#181818;stroke-width:0.5;\" width=\"220\" x=\"1087.5\" y=\"974.1797\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" textLength=\"138\" x=\"1094.5\" y=\"994.1748\">Revocation Service</text><a href=\"https://gitlab.com/affinidi/foundational/revocation-api\" target=\"_top\" title=\"https://gitlab.com/affinidi/foundational/revocation-api\" xlink:actuate=\"onRequest\" xlink:href=\"https://gitlab.com/affinidi/foundational/revocation-api\" xlink:show=\"new\" xlink:title=\"https://gitlab.com/affinidi/foundational/revocation-api\" xlink:type=\"simple\"><text fill=\"#0000FF\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" text-decoration=\"underline\" textLength=\"34\" x=\"1236.5\" y=\"994.1748\">repo</text></a><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" textLength=\"4\" x=\"1270.5\" y=\"994.1748\">,</text><a href=\"http://revocation-api.dev.affinity-project.org/api-docs/\" target=\"_top\" title=\"http://revocation-api.dev.affinity-project.org/api-docs/\" xlink:actuate=\"onRequest\" xlink:href=\"http://revocation-api.dev.affinity-project.org/api-docs/\" xlink:show=\"new\" xlink:title=\"http://revocation-api.dev.affinity-project.org/api-docs/\" xlink:type=\"simple\"><text fill=\"#0000FF\" font-family=\"sans-serif\" font-size=\"14\" lengthAdjust=\"spacing\" text-decoration=\"underline\" textLength=\"22\" x=\"1278.5\" y=\"994.1748\">api</text></a><rect fill=\"#EEEEEE\" height=\"3\" style=\"stroke:#EEEEEE;stroke-width:1.0;\" width=\"1831\" x=\"0\" y=\"149.1602\"/><line style=\"stroke:#000000;stroke-width:1.0;\" x1=\"0\" x2=\"1831\" y1=\"149.1602\" y2=\"149.1602\"/><line style=\"stroke:#000000;stroke-width:1.0;\" x1=\"0\" x2=\"1831\" y1=\"152.1602\" y2=\"152.1602\"/><rect fill=\"#EEEEEE\" height=\"23.1328\" style=\"stroke:#000000;stroke-width:2.0;\" width=\"55\" x=\"888\" y=\"138.5938\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" font-weight=\"bold\" lengthAdjust=\"spacing\" textLength=\"36\" x=\"894\" y=\"154.6606\">Auth</text><polygon fill=\"#181818\" points=\"1185.5,188.8594,1195.5,192.8594,1185.5,196.8594,1189.5,192.8594\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"632.5\" x2=\"1191.5\" y1=\"192.8594\" y2=\"192.8594\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"150\" x=\"639.5\" y=\"187.7935\">create did auth request</text><polygon fill=\"#181818\" points=\"643.5,217.9922,633.5,221.9922,643.5,225.9922,639.5,221.9922\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"637.5\" x2=\"1196.5\" y1=\"221.9922\" y2=\"221.9922\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"69\" x=\"649.5\" y=\"216.9263\">auth token</text><polygon fill=\"#181818\" points=\"1185.5,247.125,1195.5,251.125,1185.5,255.125,1189.5,251.125\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"632.5\" x2=\"1191.5\" y1=\"251.125\" y2=\"251.125\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"115\" x=\"639.5\" y=\"246.0591\">did auth responce</text><rect fill=\"#EEEEEE\" height=\"3\" style=\"stroke:#EEEEEE;stroke-width:1.0;\" width=\"1831\" x=\"0\" y=\"279.6914\"/><line style=\"stroke:#000000;stroke-width:1.0;\" x1=\"0\" x2=\"1831\" y1=\"279.6914\" y2=\"279.6914\"/><line style=\"stroke:#000000;stroke-width:1.0;\" x1=\"0\" x2=\"1831\" y1=\"282.6914\" y2=\"282.6914\"/><rect fill=\"#EEEEEE\" height=\"23.1328\" style=\"stroke:#000000;stroke-width:2.0;\" width=\"161\" x=\"835\" y=\"269.125\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" font-weight=\"bold\" lengthAdjust=\"spacing\" textLength=\"142\" x=\"841\" y=\"285.1919\">Issue revocable VC</text><path d=\"M547,307.2578 L547,332.2578 L1281,332.2578 L1281,317.2578 L1271,307.2578 L547,307.2578 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><path d=\"M1271,307.2578 L1271,317.2578 L1281,317.2578 L1271,307.2578 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"325\" x=\"637.75\" y=\"324.3247\">From the high level perspective current flow fit the</text><a href=\"https://w3c-ccg.github.io/vc-status-rl-2020/#generate-algorithm\" target=\"_top\" title=\"https://w3c-ccg.github.io/vc-status-rl-2020/#generate-algorithm\" xlink:actuate=\"onRequest\" xlink:href=\"https://w3c-ccg.github.io/vc-status-rl-2020/#generate-algorithm\" xlink:show=\"new\" xlink:title=\"https://w3c-ccg.github.io/vc-status-rl-2020/#generate-algorithm\" xlink:type=\"simple\"><text fill=\"#0000FF\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" text-decoration=\"underline\" textLength=\"211\" x=\"966.75\" y=\"324.3247\">revocation list creating algorithm</text></a><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"4\" x=\"1177.75\" y=\"324.3247\">.</text><polygon fill=\"#181818\" points=\"1185.5,354.5234,1195.5,358.5234,1185.5,362.5234,1189.5,358.5234\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"632.5\" x2=\"1191.5\" y1=\"358.5234\" y2=\"358.5234\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"469\" x=\"639.5\" y=\"353.4575\">buildRevocationListStatus({ credentialId: VC.id, subjectDid: VC.subject })</text><path d=\"M5,371.5234 L5,441.5234 L1826,441.5234 L1826,381.5234 L1816,371.5234 L5,371.5234 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><path d=\"M1816,371.5234 L1816,381.5234 L1826,381.5234 L1816,371.5234 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"141\" x=\"11\" y=\"388.5903\">At revocation service:</text><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"24\" x=\"11\" y=\"403.7231\">1. If</text><a href=\"https://w3c-ccg.github.io/vc-status-rl-2020/#core-concept\" target=\"_top\" title=\"https://w3c-ccg.github.io/vc-status-rl-2020/#core-concept\" xlink:actuate=\"onRequest\" xlink:href=\"https://w3c-ccg.github.io/vc-status-rl-2020/#core-concept\" xlink:show=\"new\" xlink:title=\"https://w3c-ccg.github.io/vc-status-rl-2020/#core-concept\" xlink:type=\"simple\"><text fill=\"#0000FF\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" text-decoration=\"underline\" textLength=\"126\" x=\"39\" y=\"403.7231\">revocation list 2020</text></a><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"473\" x=\"169\" y=\"403.7231\">does not exist yet, or it's full filled - creating revocation list 2020 and build</text><a href=\"https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020credential\" target=\"_top\" title=\"https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020credential\" xlink:actuate=\"onRequest\" xlink:href=\"https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020credential\" xlink:show=\"new\" xlink:title=\"https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020credential\" xlink:type=\"simple\"><text fill=\"#0000FF\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" text-decoration=\"underline\" textLength=\"155\" x=\"646\" y=\"403.7231\">revocationListCredential</text></a><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"1006\" x=\"805\" y=\"403.7231\">(Its credential which encapsulates revocation list and should be used to check revocable VC status after. P.S. this credential should be signed and published).</text><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"576\" x=\"11\" y=\"418.856\">2. Save params (credentialId, subjectDid - later could be used as identifiers to revoke VC).</text><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"46\" x=\"11\" y=\"433.9888\">3. Build</text><a href=\"https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020status\" target=\"_top\" title=\"https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020status\" xlink:actuate=\"onRequest\" xlink:href=\"https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020status\" xlink:show=\"new\" xlink:title=\"https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020status\" xlink:type=\"simple\"><text fill=\"#0000FF\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" text-decoration=\"underline\" textLength=\"104\" x=\"61\" y=\"433.9888\">credentialStatus</text></a><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"380\" x=\"169\" y=\"433.9888\">(a status which should be added to a revokable credential).</text><polygon fill=\"#181818\" points=\"643.5,464.1875,633.5,468.1875,643.5,472.1875,639.5,468.1875\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"637.5\" x2=\"1196.5\" y1=\"468.1875\" y2=\"468.1875\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"541\" x=\"649.5\" y=\"463.1216\">200 [credentialStatus, (revocationListCredential <only when new list was created>)]</text><path d=\"M313,481.1875 L313,506.1875 L1517,506.1875 L1517,491.1875 L1507,481.1875 L313,481.1875 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><path d=\"M1507,481.1875 L1507,491.1875 L1517,491.1875 L1507,481.1875 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"40\" x=\"319\" y=\"498.2544\">NOTE:</text><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" font-weight=\"bold\" lengthAdjust=\"spacing\" textLength=\"14\" x=\"363\" y=\"498.2544\">IF</text><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"1121\" x=\"381\" y=\"498.2544\">new revocation List was created and new revocationListCredential should be published (default size of revocation list is `100000`, so this case not suppose to happens often).</text><path d=\"M558,518.3203 L624,518.3203 L624,525.4531 L614,535.4531 L558,535.4531 L558,518.3203 \" fill=\"#EEEEEE\" style=\"stroke:#000000;stroke-width:1.5;\"/><rect fill=\"none\" height=\"117.5313\" style=\"stroke:#000000;stroke-width:1.5;\" width=\"759.5\" x=\"558\" y=\"518.3203\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" font-weight=\"bold\" lengthAdjust=\"spacing\" textLength=\"21\" x=\"573\" y=\"531.3872\">alt</text><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"11\" font-weight=\"bold\" lengthAdjust=\"spacing\" textLength=\"38\" x=\"639\" y=\"530.5308\">['yes']</text><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"632.5\" x2=\"674.5\" y1=\"556.5859\" y2=\"556.5859\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"674.5\" x2=\"674.5\" y1=\"556.5859\" y2=\"569.5859\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"633.5\" x2=\"674.5\" y1=\"569.5859\" y2=\"569.5859\"/><polygon fill=\"#181818\" points=\"643.5,565.5859,633.5,569.5859,643.5,573.5859,639.5,569.5859\" style=\"stroke:#181818;stroke-width:1.0;\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"126\" x=\"639.5\" y=\"551.52\">sign(revocationList)</text><polygon fill=\"#181818\" points=\"1185.5,594.7188,1195.5,598.7188,1185.5,602.7188,1189.5,598.7188\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"632.5\" x2=\"1191.5\" y1=\"598.7188\" y2=\"598.7188\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"415\" x=\"639.5\" y=\"593.6528\">publishRevocationListCredential(signedRevocationListCredential)</text><polygon fill=\"#181818\" points=\"643.5,623.8516,633.5,627.8516,643.5,631.8516,639.5,627.8516\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"637.5\" x2=\"1196.5\" y1=\"627.8516\" y2=\"627.8516\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"24\" x=\"649.5\" y=\"622.7856\">200</text><rect fill=\"#EEEEEE\" height=\"3\" style=\"stroke:#EEEEEE;stroke-width:1.0;\" width=\"1831\" x=\"0\" y=\"663.418\"/><line style=\"stroke:#000000;stroke-width:1.0;\" x1=\"0\" x2=\"1831\" y1=\"663.418\" y2=\"663.418\"/><line style=\"stroke:#000000;stroke-width:1.0;\" x1=\"0\" x2=\"1831\" y1=\"666.418\" y2=\"666.418\"/><rect fill=\"#EEEEEE\" height=\"23.1328\" style=\"stroke:#000000;stroke-width:2.0;\" width=\"99\" x=\"866\" y=\"652.8516\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" font-weight=\"bold\" lengthAdjust=\"spacing\" textLength=\"80\" x=\"872\" y=\"668.9185\">Revoke VC</text><polygon fill=\"#181818\" points=\"1185.5,703.1172,1195.5,707.1172,1185.5,711.1172,1189.5,707.1172\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"632.5\" x2=\"1191.5\" y1=\"707.1172\" y2=\"707.1172\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"308\" x=\"639.5\" y=\"702.0513\">revokeCredential({ id: revocableCredential.id })</text><path d=\"M547,720.1172 L547,760.1172 L1281,760.1172 L1281,730.1172 L1271,720.1172 L547,720.1172 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><path d=\"M1271,720.1172 L1271,730.1172 L1281,730.1172 L1271,720.1172 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"557\" x=\"631.25\" y=\"737.1841\">We can update logic to recieve subjectDid, and revoke all issued VCs for some subject.</text><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"441\" x=\"635.25\" y=\"752.3169\">id - its credentialId which was used at buildRevocationListStatus step</text><path d=\"M434,770.3828 L434,795.3828 L1395,795.3828 L1395,780.3828 L1385,770.3828 L434,770.3828 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><path d=\"M1385,770.3828 L1385,780.3828 L1395,780.3828 L1385,770.3828 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"940\" x=\"440\" y=\"787.4497\">Appropriate revocation list will be updated. Updated revocationListCredential (with updated encodedList) will be returned for signing and publishing</text><polygon fill=\"#181818\" points=\"643.5,817.6484,633.5,821.6484,643.5,825.6484,639.5,821.6484\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"637.5\" x2=\"1196.5\" y1=\"821.6484\" y2=\"821.6484\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"189\" x=\"649.5\" y=\"816.5825\">200[revocationListCredential]</text><path d=\"M547,834.6484 L547,859.6484 L1281,859.6484 L1281,844.6484 L1271,834.6484 L547,834.6484 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><path d=\"M1271,834.6484 L1271,844.6484 L1281,844.6484 L1271,834.6484 \" fill=\"#FEFFDD\" style=\"stroke:#181818;stroke-width:0.5;\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"345\" x=\"737.25\" y=\"851.7153\">NOTE: Sign revocationListCredential at client/SDK side</text><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"632.5\" x2=\"674.5\" y1=\"885.9141\" y2=\"885.9141\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"674.5\" x2=\"674.5\" y1=\"885.9141\" y2=\"898.9141\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"633.5\" x2=\"674.5\" y1=\"898.9141\" y2=\"898.9141\"/><polygon fill=\"#181818\" points=\"643.5,894.9141,633.5,898.9141,643.5,902.9141,639.5,898.9141\" style=\"stroke:#181818;stroke-width:1.0;\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"126\" x=\"639.5\" y=\"880.8481\">sign(revocationList)</text><polygon fill=\"#181818\" points=\"1185.5,924.0469,1195.5,928.0469,1185.5,932.0469,1189.5,928.0469\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"632.5\" x2=\"1191.5\" y1=\"928.0469\" y2=\"928.0469\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"415\" x=\"639.5\" y=\"922.981\">publishRevocationListCredential(signedRevocationListCredential)</text><polygon fill=\"#181818\" points=\"643.5,953.1797,633.5,957.1797,643.5,961.1797,639.5,957.1797\" style=\"stroke:#181818;stroke-width:1.0;\"/><line style=\"stroke:#181818;stroke-width:1.0;\" x1=\"637.5\" x2=\"1196.5\" y1=\"957.1797\" y2=\"957.1797\"/><text fill=\"#000000\" font-family=\"sans-serif\" font-size=\"13\" lengthAdjust=\"spacing\" textLength=\"24\" x=\"649.5\" y=\"952.1138\">200</text><!--MD5=[46da195cde591b6015bd85a2e2f1f921]\n", | |
"@startuml\n", | |
"title Affinidi: VC revocation (revocation list 2020) Iusser side\n", | |
"actor \"Issuer client , sdk\" as client\n", | |
"participant \"Revocation Service [[https://gitlab.com/affinidi/foundational/revocation-api repo]], [[http://revocation-api.dev.affinity-project.org/api-docs/ api]]\" as rs \n", | |
"== Auth ==\n", | |
"client -> rs: create did auth request\n", | |
"rs -> client : auth token\n", | |
"client -> rs: did auth responce \n", | |
"== Issue revocable VC ==\n", | |
"note across: From the high level perspective current flow fit the [[https://w3c-ccg.github.io/vc-status-rl-2020/#generate-algorithm revocation list creating algorithm]].\n", | |
" client -> rs : buildRevocationListStatus({ credentialId: VC.id, subjectDid: VC.subject })\n", | |
"note across\n", | |
"At revocation service:\n", | |
"1. If [[https://w3c-ccg.github.io/vc-status-rl-2020/#core-concept revocation list 2020]] does not exist yet, or it's full filled - creating revocation list 2020 and build [[https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020credential revocationListCredential]] (Its credential which encapsulates revocation list and should be used to check revocable VC status after. P.S. this credential should be signed and published).\n", | |
"2. Save params (credentialId, subjectDid - later could be used as identifiers to revoke VC).\n", | |
"3. Build [[https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020status credentialStatus]] (a status which should be added to a revokable credential).\n", | |
"end note\n", | |
"rs -> client : 200 [credentialStatus, (revocationListCredential <only when new list was created>)]\n", | |
"note across: NOTE: **IF** new revocation List was created and new revocationListCredential should be published (default size of revocation list is `100000`, so this case not suppose to happens often).\n", | |
"alt 'yes'\n", | |
"client -> client: sign(revocationList)\n", | |
"client -> rs: publishRevocationListCredential(signedRevocationListCredential)\n", | |
"rs -> client: 200\n", | |
"end\n", | |
"== Revoke VC ==\n", | |
"client -> rs: revokeCredential({ id: revocableCredential.id })\n", | |
"\n", | |
"note across: We can update logic to recieve subjectDid, and revoke all issued VCs for some subject.\\n id - its credentialId which was used at buildRevocationListStatus step\n", | |
"note across: Appropriate revocation list will be updated. Updated revocationListCredential (with updated encodedList) will be returned for signing and publishing\n", | |
"\n", | |
"rs -> client: 200[revocationListCredential]\n", | |
"note across: NOTE: Sign revocationListCredential at client/SDK side\n", | |
"client -> client: sign(revocationList) \n", | |
"client -> rs: publishRevocationListCredential(signedRevocationListCredential)\n", | |
"rs -> client: 200\n", | |
"@enduml\n", | |
"\n", | |
"PlantUML version 1.2022.8beta2(Unknown compile time)\n", | |
"(GPL source distribution)\n", | |
"Java Runtime: Java(TM) SE Runtime Environment\n", | |
"JVM: Java HotSpot(TM) 64-Bit Server VM\n", | |
"Default Encoding: UTF-8\n", | |
"Language: en\n", | |
"Country: US\n", | |
"--></g></svg>" | |
], | |
"text/plain": [ | |
"<IPython.core.display.SVG object>" | |
] | |
}, | |
"execution_count": 68, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"%%plantuml\n", | |
"@startuml\n", | |
"title Affinidi: VC revocation (revocation list 2020) Iusser side\n", | |
"actor \"Issuer client , sdk\" as client\n", | |
"participant \"Revocation Service [[https://gitlab.com/affinidi/foundational/revocation-api repo]], [[http://revocation-api.prod.affinity-project.org/api-docs/ api]]\" as rs \n", | |
"== Auth ==\n", | |
"client -> rs: create did auth request\n", | |
"rs -> client : auth token\n", | |
"client -> rs: did auth responce \n", | |
"== Issue revocable VC ==\n", | |
"note across: From the high level perspective current flow fit the [[https://w3c-ccg.github.io/vc-status-rl-2020/#generate-algorithm revocation list creating algorithm]].\n", | |
" client -> rs : buildRevocationListStatus({ credentialId: VC.id, subjectDid: VC.subject })\n", | |
"note across\n", | |
"At revocation service:\n", | |
"1. If [[https://w3c-ccg.github.io/vc-status-rl-2020/#core-concept revocation list 2020]] does not exist yet, or it's full filled - creating revocation list 2020 and build [[https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020credential revocationListCredential]] (Its credential which encapsulates revocation list and should be used to check revocable VC status after. P.S. this credential should be signed and published).\n", | |
"2. Save params (credentialId, subjectDid - later could be used as identifiers to revoke VC).\n", | |
"3. Build [[https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020status credentialStatus]] (a status which should be added to a revokable credential).\n", | |
"end note\n", | |
"rs -> client : 200 [credentialStatus, (revocationListCredential <only when new list was created>)]\n", | |
"note across: NOTE: **IF** new revocation List was created and new revocationListCredential should be published (default size of revocation list is `100000`, so this case not suppose to happens often).\n", | |
"alt 'yes'\n", | |
"client -> client: sign(revocationList)\n", | |
"client -> rs: publishRevocationListCredential(signedRevocationListCredential)\n", | |
"rs -> client: 200\n", | |
"end\n", | |
"== Revoke VC ==\n", | |
"client -> rs: revokeCredential({ id: revocableCredential.id })\n", | |
"\n", | |
"note across: We can update logic to recieve subjectDid, and revoke all issued VCs for some subject.\\n id - its credentialId which was used at buildRevocationListStatus step\n", | |
"note across: Appropriate revocation list will be updated. Updated revocationListCredential (with updated encodedList) will be returned for signing and publishing\n", | |
"\n", | |
"rs -> client: 200[revocationListCredential]\n", | |
"note across: NOTE: Sign revocationListCredential at client/SDK side\n", | |
"client -> client: sign(revocationList) \n", | |
"client -> rs: publishRevocationListCredential(signedRevocationListCredential)\n", | |
"rs -> client: 200\n", | |
"@enduml\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"kernel": "Python3" | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "SoS", | |
"language": "sos", | |
"name": "sos" | |
}, | |
"language_info": { | |
"codemirror_mode": "sos", | |
"file_extension": ".sos", | |
"mimetype": "text/x-sos", | |
"name": "sos", | |
"nbconvert_exporter": "sos_notebook.converter.SoS_Exporter", | |
"pygments_lexer": "sos" | |
}, | |
"sos": { | |
"kernels": [ | |
[ | |
"JavaScript", | |
"javascript", | |
"JavaScript", | |
"#c8e1ae", | |
"" | |
], | |
[ | |
"Markdown", | |
"markdown", | |
"markdown", | |
"", | |
"markdown" | |
], | |
[ | |
"Python3", | |
"python3", | |
"Python3", | |
"#FFD91A", | |
{ | |
"name": "ipython", | |
"version": 3 | |
} | |
] | |
], | |
"version": "0.21.21" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
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
import { createWallet } from '@affinidi/wallet-node-sdk' | |
import { Affinity } from '@affinidi/common' | |
// @ts-ignore | |
import platformCryptographyTools from '@affinidi/wallet-node-sdk/dist/PlatformCryptographyTools' | |
// @ts-ignore | |
const walletFactory = createWallet('AffinityCore') | |
const main = async () => { | |
const accessApiKey = '<your api key hash>' | |
const options = { | |
env: 'prod' as 'dev' | 'staging' | 'prod', | |
accessApiKey | |
} | |
const password = 'DemoP@ssw0rd!!' | |
const walletIssuer = await walletFactory.createWallet(options, password) | |
const walletHolder = await walletFactory.createWallet(options, password) | |
const id = `claimId:${(Math.random() + 1).toString(36).substring(2)}` | |
// https://ui.schema.affinidi.com/schemas/ContentLikeV1-0 | |
const jsonSchema = 'https://schema.affinidi.com/ContentLikeV1-0.json' | |
const jsonContext = 'https://schema.affinidi.com/ContentLikeV1-0.jsonld' | |
const unsignedVC = { | |
'@context': ['https://www.w3.org/2018/credentials/v1', jsonContext], | |
id, | |
type: ['VerifiableCredential', 'ContentLike'], | |
holder: { | |
id: walletHolder.did | |
}, | |
credentialSubject: { | |
data: { | |
'@type': ['VerifiableCredential', 'ContentLike'], | |
url: 'https://www.youtube.com/watch?v=owbkzvLhblk', | |
date: new Date().toISOString(), | |
like: true, | |
score: 10 | |
}, | |
}, | |
credentialSchema: { | |
id: jsonSchema, | |
type: 'JsonSchemaValidator2018', | |
}, | |
issuanceDate: new Date().toISOString(), | |
expirationDate: '2065-09-10T00:00:00.000Z', | |
} | |
const rvc = await walletIssuer.buildRevocationListStatus(unsignedVC) | |
const signedRevocableVC = await walletIssuer.signUnsignedCredential(rvc) | |
const verifier = new Affinity({ | |
registryUrl: `https://affinity-registry.${options.env}.affinity-project.org`, | |
apiKey: accessApiKey | |
}, platformCryptographyTools) | |
console.log(signedRevocableVC) | |
const vr = await verifier.validateCredential(signedRevocableVC) | |
console.log(vr) | |
await walletIssuer.revokeCredential(id , ' dont like any more ') | |
const vrRevoked = await verifier.validateCredential(signedRevocableVC) | |
console.log(vrRevoked) | |
} | |
main().catch(console.error) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment