Skip to content

Instantly share code, notes, and snippets.

@Volland
Last active September 9, 2022 14:36
Show Gist options
  • Save Volland/b411c787be180c13592a96cfcabc0627 to your computer and use it in GitHub Desktop.
Save Volland/b411c787be180c13592a96cfcabc0627 to your computer and use it in GitHub Desktop.
npm init -y
npm install @affinidi/wallet-node-sdk fetch@2 ts-node

ts-node revocable-vc.ts
Display the source blob
Display the rendered blob
Raw
{
"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 &lt;only when new list was created&gt;)]</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
}
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