From 1b83c3ea9394d043dc708f98c870ffbbd46bb79d Mon Sep 17 00:00:00 2001 From: olegnn Date: Thu, 10 Oct 2024 16:13:02 +0200 Subject: [PATCH] Improve docs + force `DIDDocument` to check for duplicates --- examples/CHANGELOG.md | 9 ++ examples/package.json | 8 +- packages/cheqd-blockchain-api/CHANGELOG.md | 6 + packages/cheqd-blockchain-api/package.json | 11 +- .../cheqd-blockchain-modules/CHANGELOG.md | 11 ++ packages/cheqd-blockchain-modules/README.md | 9 +- .../cheqd-blockchain-modules/package.json | 6 +- packages/credential-sdk/CHANGELOG.md | 6 + packages/credential-sdk/package.json | 2 +- .../credential-sdk/src/types/did/document.js | 28 +++-- packages/dock-blockchain-api/CHANGELOG.md | 7 ++ packages/dock-blockchain-api/package.json | 4 +- packages/dock-blockchain-modules/CHANGELOG.md | 11 ++ packages/dock-blockchain-modules/package.json | 6 +- .../dock-blockchain-modules/src/did/module.js | 23 +++- tutorials/src/revocation.md | 109 ++++++++++++++++++ tutorials/src/tutorial_blobs_schemas.md | 10 +- tutorials/src/tutorials.md | 6 +- 18 files changed, 223 insertions(+), 49 deletions(-) create mode 100644 tutorials/src/revocation.md diff --git a/examples/CHANGELOG.md b/examples/CHANGELOG.md index 566a5e030..9a813319b 100644 --- a/examples/CHANGELOG.md +++ b/examples/CHANGELOG.md @@ -1,5 +1,14 @@ # @docknetwork/sdk-examples +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @docknetwork/dock-blockchain-modules@0.2.0 + - @docknetwork/credential-sdk@0.2.0 + - @docknetwork/dock-blockchain-api@0.1.2 + ## 0.1.1 ### Patch Changes diff --git a/examples/package.json b/examples/package.json index 341a42f5e..ae3ad5875 100644 --- a/examples/package.json +++ b/examples/package.json @@ -2,7 +2,7 @@ "name": "@docknetwork/sdk-examples", "private": true, "type": "module", - "version": "0.1.1", + "version": "0.1.2", "scripts": { "bbs-dock-example": "babel-node --loader=./loader.mjs ./bbs-dock.js", "claim-deduction-example": "babel-node --loader=./loader.mjs ./claim-deduction.js", @@ -19,9 +19,9 @@ "lint": "eslint \"*.js\"" }, "dependencies": { - "@docknetwork/credential-sdk": "0.1.1", - "@docknetwork/dock-blockchain-api": "0.1.1", - "@docknetwork/dock-blockchain-modules": "0.1.1" + "@docknetwork/credential-sdk": "0.2.0", + "@docknetwork/dock-blockchain-api": "0.1.2", + "@docknetwork/dock-blockchain-modules": "0.2.0" }, "devDependencies": { "babel-eslint": "^10.1.0", diff --git a/packages/cheqd-blockchain-api/CHANGELOG.md b/packages/cheqd-blockchain-api/CHANGELOG.md index 828c4fa47..c9c7cf4ef 100644 --- a/packages/cheqd-blockchain-api/CHANGELOG.md +++ b/packages/cheqd-blockchain-api/CHANGELOG.md @@ -1,5 +1,11 @@ # @docknetwork/cheqd-blockchain-api +## 0.1.2 + +### Patch Changes + +- Change `DIDDocument` modification behaviour to throw error on attempt to add key/service/controller with duplicate id. + ## 0.1.1 ### Minor Changes diff --git a/packages/cheqd-blockchain-api/package.json b/packages/cheqd-blockchain-api/package.json index d1173be5f..a5daf9d7e 100644 --- a/packages/cheqd-blockchain-api/package.json +++ b/packages/cheqd-blockchain-api/package.json @@ -1,6 +1,6 @@ { "name": "@docknetwork/cheqd-blockchain-api", - "version": "0.1.1", + "version": "0.1.2", "license": "MIT", "main": "./dist/esm/index.js", "type": "module", @@ -27,6 +27,9 @@ "engines": { "node": ">=20.0.0" }, + "dependencies": { + "@cheqd/sdk": "^4.0.4" + }, "devDependencies": { "@babel/cli": "^7.24.1", "@babel/core": "^7.24.3", @@ -78,11 +81,5 @@ "watch": "rollup -c -w", "docs": "rm -rf out && mkdir out && touch out/.nojekyll && jsdoc src -r -c ../../.jsdoc -d out/reference", "type-check": "tsc --allowJs --checkJs --noEmit --moduleResolution node --resolveJsonModule --target ES6 --skipLibCheck true --allowSyntheticDefaultImports true" - }, - "resolutions": { - "@polkadot/api": "10.12.4" - }, - "dependencies": { - "@cheqd/sdk": "^4.0.4" } } diff --git a/packages/cheqd-blockchain-modules/CHANGELOG.md b/packages/cheqd-blockchain-modules/CHANGELOG.md index ef845b0cb..354e05df7 100644 --- a/packages/cheqd-blockchain-modules/CHANGELOG.md +++ b/packages/cheqd-blockchain-modules/CHANGELOG.md @@ -1,5 +1,16 @@ # @docknetwork/cheqd-blockchain-modules +## 0.2.0 + +### Minor Changes + +- Change `DIDDocument` modification behaviour to throw error on attempt to add key/service/controller with duplicate id. + +### Patch Changes + +- Updated dependencies + - @docknetwork/credential-sdk@0.2.0 + ## 0.1.1 ### Minor Changes diff --git a/packages/cheqd-blockchain-modules/README.md b/packages/cheqd-blockchain-modules/README.md index 9a0582961..5b5ee5771 100644 --- a/packages/cheqd-blockchain-modules/README.md +++ b/packages/cheqd-blockchain-modules/README.md @@ -1,6 +1,4 @@ -# @docknetwork/cheqd-blockchain-modules - -A JavaScript library created for managing credential SDK components such as DIDs and accumulators etc on the Cheqd blockchain. +# Cheqd Blockchain Modules ## Setup @@ -76,9 +74,6 @@ expect((await attestModule.getDocument(did)).attests.toJSON()).toEqual(iri); - Accumulator - Anchor - Blob -- OffchainSignatures -- BBS -- BBSPlus -- PS +- OffchainSignatures params (BBS/BBSPlus/PS) - StatusListCredential - TrustRegistry diff --git a/packages/cheqd-blockchain-modules/package.json b/packages/cheqd-blockchain-modules/package.json index db132cc7c..5e3ceb6ea 100644 --- a/packages/cheqd-blockchain-modules/package.json +++ b/packages/cheqd-blockchain-modules/package.json @@ -1,6 +1,6 @@ { "name": "@docknetwork/cheqd-blockchain-modules", - "version": "0.1.1", + "version": "0.2.0", "type": "module", "license": "MIT", "main": "./dist/esm/index.js", @@ -28,7 +28,7 @@ "node": ">=18.0.0" }, "dependencies": { - "@docknetwork/credential-sdk": "0.1.1" + "@docknetwork/credential-sdk": "0.2.0" }, "devDependencies": { "@babel/cli": "^7.24.1", @@ -37,7 +37,7 @@ "@babel/plugin-syntax-import-attributes": "^7.25.6", "@babel/plugin-transform-modules-commonjs": "^7.24.1", "@babel/preset-env": "^7.24.3", - "@docknetwork/cheqd-blockchain-api": "0.1.1", + "@docknetwork/cheqd-blockchain-api": "0.1.2", "@rollup/plugin-alias": "^4.0.2", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^24.0.0", diff --git a/packages/credential-sdk/CHANGELOG.md b/packages/credential-sdk/CHANGELOG.md index 41cf41f80..c53562088 100644 --- a/packages/credential-sdk/CHANGELOG.md +++ b/packages/credential-sdk/CHANGELOG.md @@ -1,5 +1,11 @@ # @docknetwork/credential-sdk +## 0.2.0 + +### Minor Changes + +- Change `DIDDocument` modification behaviour to throw error on attempt to add key/service/controller with duplicate id. + ## 0.1.1 ### Minor Changes diff --git a/packages/credential-sdk/package.json b/packages/credential-sdk/package.json index 614747a41..b4f0aaa53 100644 --- a/packages/credential-sdk/package.json +++ b/packages/credential-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@docknetwork/credential-sdk", - "version": "0.1.1", + "version": "0.2.0", "license": "MIT", "type": "module", "files": [ diff --git a/packages/credential-sdk/src/types/did/document.js b/packages/credential-sdk/src/types/did/document.js index 5ee61f92b..d7cb83cdf 100644 --- a/packages/credential-sdk/src/types/did/document.js +++ b/packages/credential-sdk/src/types/did/document.js @@ -7,6 +7,7 @@ import { TypedBytes, TypedEnum, TypedNumber, + TypedSet, TypedString, TypedStruct, TypedTuple, @@ -574,12 +575,18 @@ export class DIDDocument extends TypedStruct { } addController(controller) { + if (this.controller.some((ctrl) => ctrl.eq(controller))) { + throw new Error(`Controller \`${controller}\` already exists`); + } this.controller.push(controller); return this; } addServiceEndpoint(id, serviceEndpoint) { + if (this.service.some((service) => service.id.eq(id))) { + throw new Error(`Service endpoint with id \`${id}\` already exists`); + } this.service.push(Service.fromServiceEndpoint(id, serviceEndpoint)); return this; @@ -632,31 +639,30 @@ export class DIDDocument extends TypedStruct { assertionMethod, keyAgreement, capabilityInvocation, - capabilityDelegation, } = this; - if (capabilityDelegation && capabilityDelegation.length > 0) { - throw new Error('Capability delegation is not supported'); + class VerificationMethodRefSet extends TypedSet { + static Class = VerificationMethodRef; } - const auth = new Set([...authentication].map(String)); - const assertion = new Set([...assertionMethod].map(String)); - const keyAgr = new Set([...keyAgreement].map(String)); - const capInv = new Set([...capabilityInvocation].map(String)); + const auth = new VerificationMethodRefSet(authentication); + const assertion = new VerificationMethodRefSet(assertionMethod); + const keyAgr = new VerificationMethodRefSet(keyAgreement); + const capInv = new VerificationMethodRefSet(capabilityInvocation); const keys = [...verificationMethod] .map((method) => { const verRels = new VerificationRelationship(); - if (auth.has(String(method.id))) { + if (auth.has(method.id)) { verRels.setAuthentication(); } - if (assertion.has(String(method.id))) { + if (assertion.has(method.id)) { verRels.setAssertion(); } - if (keyAgr.has(String(method.id))) { + if (keyAgr.has(method.id)) { verRels.setKeyAgreement(); } - if (capInv.has(String(method.id))) { + if (capInv.has(method.id)) { verRels.setCapabilityInvocation(); } diff --git a/packages/dock-blockchain-api/CHANGELOG.md b/packages/dock-blockchain-api/CHANGELOG.md index 9602a8403..9874d03dc 100644 --- a/packages/dock-blockchain-api/CHANGELOG.md +++ b/packages/dock-blockchain-api/CHANGELOG.md @@ -1,5 +1,12 @@ # @docknetwork/dock-blockchain-api +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @docknetwork/credential-sdk@0.2.0 + ## 0.1.1 ### Minor Changes diff --git a/packages/dock-blockchain-api/package.json b/packages/dock-blockchain-api/package.json index aef7c6d37..70516eb23 100644 --- a/packages/dock-blockchain-api/package.json +++ b/packages/dock-blockchain-api/package.json @@ -1,6 +1,6 @@ { "name": "@docknetwork/dock-blockchain-api", - "version": "0.1.1", + "version": "0.1.2", "license": "MIT", "main": "./dist/esm/index.js", "type": "module", @@ -84,7 +84,7 @@ "@polkadot/api": "10.12.4" }, "dependencies": { - "@docknetwork/credential-sdk": "0.1.1", + "@docknetwork/credential-sdk": "0.2.0", "@docknetwork/node-types": "^0.17.0", "@juanelas/base64": "^1.0.5", "@polkadot/api": "10.12.4", diff --git a/packages/dock-blockchain-modules/CHANGELOG.md b/packages/dock-blockchain-modules/CHANGELOG.md index f78ccd0f5..e23ee1e96 100644 --- a/packages/dock-blockchain-modules/CHANGELOG.md +++ b/packages/dock-blockchain-modules/CHANGELOG.md @@ -1,5 +1,16 @@ # @docknetwork/dock-blockchain-modules +## 0.2.0 + +### Minor Changes + +- Change `DIDDocument` modification behaviour to throw error on attempt to add key/service/controller with duplicate id. + +### Patch Changes + +- Updated dependencies + - @docknetwork/credential-sdk@0.2.0 + ## 0.1.1 ### Minor Changes diff --git a/packages/dock-blockchain-modules/package.json b/packages/dock-blockchain-modules/package.json index 896ba884c..2023bdf3c 100644 --- a/packages/dock-blockchain-modules/package.json +++ b/packages/dock-blockchain-modules/package.json @@ -1,6 +1,6 @@ { "name": "@docknetwork/dock-blockchain-modules", - "version": "0.1.1", + "version": "0.2.0", "license": "MIT", "type": "module", "main": "./dist/esm/index.js", @@ -28,7 +28,7 @@ "node": ">=18.0.0" }, "dependencies": { - "@docknetwork/credential-sdk": "0.1.1" + "@docknetwork/credential-sdk": "0.2.0" }, "devDependencies": { "@babel/cli": "^7.24.1", @@ -37,7 +37,7 @@ "@babel/plugin-syntax-import-attributes": "^7.25.6", "@babel/plugin-transform-modules-commonjs": "^7.24.1", "@babel/preset-env": "^7.24.3", - "@docknetwork/dock-blockchain-api": "0.1.1", + "@docknetwork/dock-blockchain-api": "0.1.2", "@rollup/plugin-alias": "^4.0.2", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^24.0.0", diff --git a/packages/dock-blockchain-modules/src/did/module.js b/packages/dock-blockchain-modules/src/did/module.js index 91b538079..1c6465cdf 100644 --- a/packages/dock-blockchain-modules/src/did/module.js +++ b/packages/dock-blockchain-modules/src/did/module.js @@ -29,14 +29,24 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { const keys = didDocument.didKeys(); const { - controller, service, id, '@context': context, + controller, + service, + id, + '@context': context, + capabilityDelegation, + attests, } = document; if (service?.length) { throw new Error( '`service` is not supported in the `createDocument` transaction. Use `updateDocument` to add `service` to the existing document.', ); - } - if (context.length !== 1 || context[0].value !== CONTEXT_URI) { + } else if (capabilityDelegation?.length) { + throw new Error('Capability delegation is not supported'); + } else if (attests != null) { + throw new Error( + '`attests` are not supported in the `createDocument` transaction. Use `attest` module to attach `attests` to the existing document.', + ); + } else if (context.length !== 1 || context[0].value !== CONTEXT_URI) { throw new Error( `Context must be equal to \`${[ CONTEXT_URI, @@ -63,6 +73,13 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { if (modified.size) { throw new Error("Can't have modified verificationMethods"); + } else if ( + nextDocument.attests + && !nextDocument.attests.eq(currentDocument.attests) + ) { + throw new Error( + '`attests` modifications are not supported in the `updateDocument` transaction. Use `attest` module to attach `attests` to the existing document.', + ); } if ( diff --git a/tutorials/src/revocation.md b/tutorials/src/revocation.md new file mode 100644 index 000000000..6bd722778 --- /dev/null +++ b/tutorials/src/revocation.md @@ -0,0 +1,109 @@ +# Revocation + + +This guide provides instructions for managing credential revocation using `StatusList2021Credential`. + +## Prerequisites + +- Ensure you have access to Dock's Credential SDK and Blockchain API. +- The Dock API is initialized and connected to the blockchain. +- You have a valid issuer DID registered on the Dock network. + +## Steps to Manage Revocation + +### Create a Status List Credential + +1. **Generate a Random Status List ID:** + Create a unique identifier for tracking revocation status. + + ```javascript + import { DockStatusListCredentialId } from '@docknetwork/credential-sdk/types'; + + const statusListCredentialId = DockStatusListCredentialId.random(); + ``` + +2. **Create Status List Credential:** + Use the issuer's key to create a new status list credential with a specified purpose (e.g., "suspension"). + + ```javascript + import { StatusList2021Credential } from '@docknetwork/credential-sdk/types'; + + const issuerKey = /* Obtain issuer key document */; + const statusListCred = await StatusList2021Credential.create( + issuerKey, + statusListCredentialId, + { statusPurpose: "suspension" }, + ); + + await modules.statusListCredential.createStatusListCredential( + statusListCredentialId, + statusListCred, + issuerDID, + issuerKeyPair, + ); + ``` + +### Issue a Credential with Revocation Data + +1. **Add Revocation Entry:** + Include a status list entry in the credential for potential revocation. + + ```javascript + import { addStatusList21EntryToCredential } from '@docknetwork/credential-sdk/vc'; + + let unsignedCred = /* Obtain unsigned credential */; + unsignedCred = addStatusList21EntryToCredential( + unsignedCred, + statusListCredentialId, + statusListCredentialIndex, // Unique index for the credential + "suspension", // Purpose matching the status list credential + ); + ``` + +2. **Issue Credential:** + Sign and issue the credential with the added status list entry. + + ```javascript + import { addStatusList21EntryToCredential } from '@docknetwork/credential-sdk/vc'; + + const credential = await issueCredential( + issuerKey, + unsignedCred, + void 0, + defaultDocumentLoader(resolver), + ); + ``` + +### Revoke the Credential + +1. **Fetch and Update Status List:** + Retrieve the existing status list credential and update it to revoke the issued credential by its index. + + ```javascript + const fetchedCred = await modules.statusListCredential.getStatusListCredential(statusListCredentialId); + await fetchedCred.update(issuerKey, { + revokeIndices: [statusListCredentialIndex], // Index of the credential to revoke + }); + + await modules.statusListCredential.updateStatusListCredential( + statusListCredentialId, + fetchedCred, + issuerDID, + issuerKeyPair, + ); + ``` + +### Verify the Revoked Credential + +1. **Verify Credential Status:** + Check the validity of the credential post-revocation. Verification should indicate the credential is no longer valid. + + ```javascript + const result = await verifyCredential(credential, { + resolver, + compactProof: true, + }); + if (!result.verified) { + console.error("Credential is revoked or suspended."); + } + ``` diff --git a/tutorials/src/tutorial_blobs_schemas.md b/tutorials/src/tutorial_blobs_schemas.md index f6e7b2905..486a8b414 100644 --- a/tutorials/src/tutorial_blobs_schemas.md +++ b/tutorials/src/tutorial_blobs_schemas.md @@ -32,14 +32,12 @@ It accepts a `blob` object with the struct to store on chain (it can either be a keyPair to sign the payload with). You'll get a signed extrinsic that you can send to the Dock chain: ```javascript -const blobId = randomAsHex(DockBlobIdByteSize); // 32-bytes long hex string to use as the blob's id +const blobId = DockBlobId.random(); // 32-bytes long hex string to use as the blob's id const blobStruct = { id: blobId, blob: blobHexOrArray, // Contents of your blob as a hex string or byte array }; -const result = await dock.blob.new(blobStruct, signerDid, keypair, { - didModule: dock.didModule, -}); +const result = await dock.blob.new(blobStruct, ownerDid, didKeypair); ``` If everything worked properly `result` will indicate a successful transaction. @@ -139,7 +137,7 @@ Writing a Schema to the Dock chain is similar to writing any other Blob. `1` is ```javascript > const formattedBlob = myNewSchema.toBlob(dockDID); -> await myNewSchema.writeToChain(dock, dockDID, keypair); +> await myNewSchema.writeToChain(modules.blob, dockDID, keypair); ``` ### Reading a Schema from the Dock chain @@ -149,7 +147,7 @@ It accepts a string `id` param (a fully-qualified blob id like "blob:dock:0x..." `dockAPI` instance: ```javascript -> const result = await Schema.get(blob.id, dock); +> const result = await Schema.get(blob.id, modules.blob); ``` `result[0]` will be the author of the Schema, and `result[1]` will be the contents of the schema itself. diff --git a/tutorials/src/tutorials.md b/tutorials/src/tutorials.md index 5e1c5b980..5510636e9 100644 --- a/tutorials/src/tutorials.md +++ b/tutorials/src/tutorials.md @@ -1,5 +1,7 @@ # Tutorials 1. [DID](./tutorial_did.md) -2. [Verifiable credentials](./tutorial_ipv.md) -3. [Blobs and Schemas](./tutorial_blobs_schemas.md) +2. [Revocation](./tutorial_revocation.md) +3. [Verifiable credentials](./tutorial_ipv.md) +4. [Blobs and Schemas](./tutorial_blobs_schemas.md) +5. [EVM integration](./tutorial_evm.md)