All about VC & Revocable VCs#
Verifiable credentials is a core of self sovering identity. VC data model spec describe it in details in next video
Lets prepare our test wallets You could follow this notebook in video
const { createWallet } = require('@affinidi/wallet-node-sdk')
// @ts-ignore
const walletFactory = createWallet('AffinityCore')
Lets prepare options
get your API key production or register affinidi account on register
set env to prod
const accessApiKey = '<your api key>'
const options = {
env: 'prod',
accessApiKey,
}
Lets create our issuer and holder wallets. We need to have a holder did to issue a VC for concrete holder.
const password = `P@${(Math.random() + 1).toString(36).substring(2)}!!42`;
walletIssuer = await walletFactory.createWallet(options, password)
walletHolder = await walletFactory.createWallet(options, password)
Lets create a Unsigned Credential#
I just create a custom schema for content Like VCs. Its allow to issue verifiable likes for a content that i like. Schema
// 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'
Every VC should have a unique id.
const id = `claimId:${(Math.random() + 1).toString(36).substring(2)}`
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',
}
unsignedVC
{
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://schema.affinidi.com/ContentLikeV1-0.jsonld'
],
id: 'claimId:i2wgld5x7b',
type: [ 'VerifiableCredential', 'ContentLike' ],
holder: {
id: 'did:elem:EiAs9VqvNcEMkm9OfMdseWR0jMIltWHuUd5tCK_f17M6jA;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek5UUXhZMk01T1RabU56VmxaR1U1WkRnd00yVXlOVE5oTm1FNU5UWXdOekF5TWprMk1EaGhNemM0WVRWbE56RmlaV1V4WldGaE1EQXpObU0zTkdJME1DSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TTJOaU1qZzFPVGRrWkRjM016bG1OREl3WTJaaVpEUXdOekZtTUdNNU5Ua3dPRFZtWVRBNVlqSXlOR1l4Tm1ZeE1UbGlOelV6WVRZeVpXVTJaalJqT1RRaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiOXg1UVpYS0h4OEFCSmd2cmhqVFhhR2NGUC1TSVdoYVJCeW1Vbm9vOGk2dGdMaDhWSnlWWGxnbS0xaTZqSXROTW1NZXEwX2t1SUZRZnVNelVNdVNMbXcifQ'
},
credentialSubject: {
data: {
'@type': [Array],
url: 'https://www.youtube.com/watch?v=owbkzvLhblk',
date: '2022-09-09T13:22:20.668Z',
like: true,
score: 10
}
},
credentialSchema: {
id: 'https://schema.affinidi.com/ContentLikeV1-0.json',
type: 'JsonSchemaValidator2018'
},
issuanceDate: '2022-09-09T13:22:20.668Z',
expirationDate: '2065-09-10T00:00:00.000Z'
}
It is already good VC to sign but what if i ll change my mind in a future ?
VCs are immutable and owned by holder. Once you issue tham you do not have a control on VC any more.
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
It is based on Revocation List 2020 standard
It is quite complex flow but we make it easy for you and implement a method in our SDK. You could upgrade your VC to revocapbe VC. We will prepare and publish revocation list for you
const RevocableVC = await walletIssuer.buildRevocationListStatus(unsignedVC)
Show code cell source
RevocableVC
{
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://schema.affinidi.com/ContentLikeV1-0.jsonld',
'https://w3id.org/vc-revocation-list-2020/v1'
],
id: 'claimId:i2wgld5x7b',
type: [ 'VerifiableCredential', 'ContentLike' ],
holder: {
id: 'did:elem:EiAs9VqvNcEMkm9OfMdseWR0jMIltWHuUd5tCK_f17M6jA;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek5UUXhZMk01T1RabU56VmxaR1U1WkRnd00yVXlOVE5oTm1FNU5UWXdOekF5TWprMk1EaGhNemM0WVRWbE56RmlaV1V4WldGaE1EQXpObU0zTkdJME1DSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TTJOaU1qZzFPVGRrWkRjM016bG1OREl3WTJaaVpEUXdOekZtTUdNNU5Ua3dPRFZtWVRBNVlqSXlOR1l4Tm1ZeE1UbGlOelV6WVRZeVpXVTJaalJqT1RRaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiOXg1UVpYS0h4OEFCSmd2cmhqVFhhR2NGUC1TSVdoYVJCeW1Vbm9vOGk2dGdMaDhWSnlWWGxnbS0xaTZqSXROTW1NZXEwX2t1SUZRZnVNelVNdVNMbXcifQ'
},
credentialSubject: {
data: {
'@type': [Array],
url: 'https://www.youtube.com/watch?v=owbkzvLhblk',
date: '2022-09-09T13:22:20.668Z',
like: true,
score: 10
}
},
credentialSchema: {
id: 'https://schema.affinidi.com/ContentLikeV1-0.json',
type: 'JsonSchemaValidator2018'
},
issuanceDate: '2022-09-09T13:22:20.668Z',
expirationDate: '2065-09-10T00:00:00.000Z',
credentialStatus: {
id: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551#1',
type: 'RevocationList2020Status',
revocationListIndex: '1',
revocationListCredential: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551'
}
}
const revocationListVc = await fetch(RevocableVC.credentialStatus.revocationListCredential)
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.
Show code cell source
revocationListVc.json()
{
id: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551',
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://w3id.org/vc-revocation-list-2020/v1'
],
type: [ 'VerifiableCredential', 'RevocationList2020Credential' ],
issuer: 'did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek1HTXdOMlZtTnpFeU1ETTVaamhtWkdOa1ltVmtPR0V3WldJNFpqaG1ZbU5qTlRaak0ySmpOREEwTVRSak1HRTRaR1F6TVRjeFpHTm1NR1k0TW1KaE1TSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpSaFpEa3hNR1E1WVRSa1lXWTRPV1V5WW1ZNE9USTFPVEEyWlRobU4ySmtaRGhtTVdVM01EWTROMlF6T0RJMVptRmhZems0Tm1ObE5HUmhZVFZqTVdZaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiVC1fc0drTmdMX294cHM1cEFYRDZWLVJCdmtjQzlKOFZJQnN3aGxYazA4TjQwXzBQQWpzbmRTb0FrbFQ5bmZxUWZRYlpLem9jek5QMVd3Z1M3bkVHMGcifQ',
issuanceDate: '2022-09-09T13:22:37.281Z',
credentialSubject: {
id: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551#list',
type: 'RevocationList2020',
encodedList: 'H4sIAAAAAAAAA-3BMQEAAADCoPVPbQsvoAAAAAAAAAAAAAAAAP4GcwM92tQwAAA'
},
proof: {
type: 'EcdsaSecp256k1Signature2019',
created: '2022-09-09T13:22:37Z',
verificationMethod: 'did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw#primary',
proofPurpose: 'assertionMethod',
jws: 'eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..KBSUju310a1tuA-kiq79kUYST0Svn4MdFw_0pCcGoZZR-aiP1wzk1atb0tL7rhxqkJvDjnQIQo0t281-E10IjQ'
}
}
Lets sign it#
To make it verifiable we just need to sign it. So issuence on edge is simple operation
build vc
sign vc
sharewith holder (optional )
const signedRevocableVC = await walletIssuer.signUnsignedCredential(RevocableVC)
Show code cell source
signedRevocableVC
{
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://schema.affinidi.com/ContentLikeV1-0.jsonld',
'https://w3id.org/vc-revocation-list-2020/v1'
],
id: 'claimId:i2wgld5x7b',
type: [ 'VerifiableCredential', 'ContentLike' ],
holder: {
id: 'did:elem:EiAs9VqvNcEMkm9OfMdseWR0jMIltWHuUd5tCK_f17M6jA;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek5UUXhZMk01T1RabU56VmxaR1U1WkRnd00yVXlOVE5oTm1FNU5UWXdOekF5TWprMk1EaGhNemM0WVRWbE56RmlaV1V4WldGaE1EQXpObU0zTkdJME1DSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TTJOaU1qZzFPVGRrWkRjM016bG1OREl3WTJaaVpEUXdOekZtTUdNNU5Ua3dPRFZtWVRBNVlqSXlOR1l4Tm1ZeE1UbGlOelV6WVRZeVpXVTJaalJqT1RRaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiOXg1UVpYS0h4OEFCSmd2cmhqVFhhR2NGUC1TSVdoYVJCeW1Vbm9vOGk2dGdMaDhWSnlWWGxnbS0xaTZqSXROTW1NZXEwX2t1SUZRZnVNelVNdVNMbXcifQ'
},
credentialSubject: {
data: {
'@type': [Array],
url: 'https://www.youtube.com/watch?v=owbkzvLhblk',
date: '2022-09-09T13:22:20.668Z',
like: true,
score: 10
}
},
credentialSchema: {
id: 'https://schema.affinidi.com/ContentLikeV1-0.json',
type: 'JsonSchemaValidator2018'
},
issuanceDate: '2022-09-09T13:22:20.668Z',
expirationDate: '2065-09-10T00:00:00.000Z',
credentialStatus: {
id: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551#1',
type: 'RevocationList2020Status',
revocationListIndex: '1',
revocationListCredential: 'https://revocation-api.prod.affinity-project.org/api/v1/revocation/revocation-list-2020-credentials/did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw/20551'
},
issuer: 'did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw;elem:initial-state=eyJwcm90ZWN0ZWQiOiJleUp2Y0dWeVlYUnBiMjRpT2lKamNtVmhkR1VpTENKcmFXUWlPaUlqY0hKcGJXRnllU0lzSW1Gc1p5STZJa1ZUTWpVMlN5SjkiLCJwYXlsb2FkIjoiZXlKQVkyOXVkR1Y0ZENJNkltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmMyVmpkWEpwZEhrdmRqSWlMQ0p3ZFdKc2FXTkxaWGtpT2x0N0ltbGtJam9pSTNCeWFXMWhjbmtpTENKMWMyRm5aU0k2SW5OcFoyNXBibWNpTENKMGVYQmxJam9pVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T0NJc0luQjFZbXhwWTB0bGVVaGxlQ0k2SWpBek1HTXdOMlZtTnpFeU1ETTVaamhtWkdOa1ltVmtPR0V3WldJNFpqaG1ZbU5qTlRaak0ySmpOREEwTVRSak1HRTRaR1F6TVRjeFpHTm1NR1k0TW1KaE1TSjlMSHNpYVdRaU9pSWpjbVZqYjNabGNua2lMQ0oxYzJGblpTSTZJbkpsWTI5MlpYSjVJaXdpZEhsd1pTSTZJbE5sWTNBeU5UWnJNVlpsY21sbWFXTmhkR2x2Ymt0bGVUSXdNVGdpTENKd2RXSnNhV05MWlhsSVpYZ2lPaUl3TWpSaFpEa3hNR1E1WVRSa1lXWTRPV1V5WW1ZNE9USTFPVEEyWlRobU4ySmtaRGhtTVdVM01EWTROMlF6T0RJMVptRmhZems0Tm1ObE5HUmhZVFZqTVdZaWZWMHNJbUYxZEdobGJuUnBZMkYwYVc5dUlqcGJJaU53Y21sdFlYSjVJbDBzSW1GemMyVnlkR2x2YmsxbGRHaHZaQ0k2V3lJamNISnBiV0Z5ZVNKZGZRIiwic2lnbmF0dXJlIjoiVC1fc0drTmdMX294cHM1cEFYRDZWLVJCdmtjQzlKOFZJQnN3aGxYazA4TjQwXzBQQWpzbmRTb0FrbFQ5bmZxUWZRYlpLem9jek5QMVd3Z1M3bkVHMGcifQ',
proof: {
type: 'EcdsaSecp256k1Signature2019',
created: '2022-09-09T13:23:18Z',
verificationMethod: 'did:elem:EiBIkVawTQOfOCYp2xSITNKKePuELFTj3oc1ITnxk2uehw#primary',
proofPurpose: 'assertionMethod',
jws: 'eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..egv-RIoJfND0Ga-NiqCcPXe7lA2uggrgoAm1yp2dLLVk7mEy_r2RCzVKxzNwPGoma10ZZ7JgL9MY4rrC1z-BpA'
}
}
Verification#
Main idea of VC is verifiable data We could do a verification on edge with our common library
const { Affinity: Verifier } = require('@affinidi/common')
const platformCryptographyTools = require ('@affinidi/wallet-node-sdk/dist/PlatformCryptographyTools')
const verifier = new Verifier({
registryUrl: `https://affinity-registry.${options.env}.affinity-project.org`,
apiKey: accessApiKey
}, platformCryptographyTools)
Lets verify
const verificationResult = await verifier.validateCredential(signedRevocableVC)
{ result: true, error: ‘’ }
Revocation#
Now we could change our mind
await walletIssuer.revokeCredential(id , ' dont like any more ')
Now credential is invalid
const verificationRevokedResult = await verifier4.validateCredential(signedRevocableVC)
(async () => { verificationRevokedResult = await verifier4.validateCredential(signedRevocableVC) })().catch(console.error)
{ result: false, error: ‘claimId:gacultz6iz: Credential revocation status check result is negative.’ }
Revocation API internals#
Affinidi Revocation Service Do all managment of revocation list. Service use did auth to reensure that issuer could have access only to his revocation lists and could revoke only his credentials
Show code cell source
const plantumlEncoder = require('plantuml-encoder')
const tslab = require("tslab");
const flow = plantumlEncoder.encode(`
@startuml
title Affinidi: VC revocation (revocation list 2020) Iusser side
actor "Issuer client , sdk" as client
participant "Revocation Service [[https://gitlab.com/affinidi/foundational/revocation-api repo]], [[http://revocation-api.prod.affinity-project.org/api-docs/ api]]" as rs
== Auth ==
client -> rs: create did auth request
rs -> client : auth token
client -> rs: did auth responce
== Issue revocable VC ==
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]].
client -> rs : buildRevocationListStatus({ credentialId: VC.id, subjectDid: VC.subject })
note across
At revocation service:
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).
2. Save params (credentialId, subjectDid - later could be used as identifiers to revoke VC).
3. Build [[https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020status credentialStatus]] (a status which should be added to a revokable credential).
end note
rs -> client : 200 [credentialStatus, (revocationListCredential <only when new list was created>)]
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).
alt 'yes'
client -> client: sign(revocationList)
client -> rs: publishRevocationListCredential(signedRevocationListCredential)
rs -> client: 200
end
== Revoke VC ==
client -> rs: revokeCredential({ id: revocableCredential.id })
note across: We can update logic to recieve subjectDid, and revoke all issued VCs for some subject. id - its credentialId which was used at buildRevocationListStatus step
note across: Appropriate revocation list will be updated. Updated revocationListCredential (with updated encodedList) will be returned for signing and publishing
rs -> client: 200[revocationListCredential]
note across: NOTE: Sign revocationListCredential at client/SDK side
client -> client: sign(revocationList)
client -> rs: publishRevocationListCredential(signedRevocationListCredential)
rs -> client: 200
@enduml`)
const urlflow = 'http://www.plantuml.com/plantuml/svg/' + flow
tslab.display.html(`<img src="${urlflow}"/>`)