From 0676b2b461e31416be58496dad4e2e106df5aaaa Mon Sep 17 00:00:00 2001 From: olegnn Date: Thu, 17 Oct 2024 17:24:49 +0200 Subject: [PATCH 01/11] `CheqdBlobModule` + tweaks --- examples/schema.js | 3 +- packages/cheqd-blockchain-api/src/index.js | 4 +- .../src/attest/internal.js | 59 ++-- .../src/blob/internal.js | 41 +++ .../src/blob/module.js | 25 ++ .../src/blob/types.js | 6 + .../src/common/builders.js | 71 ++++- .../src/did/module.js | 17 +- .../cheqd-blockchain-modules/src/index.js | 13 +- .../tests/attest-module.test.js | 29 ++ .../tests/attest.test.js | 63 ---- .../tests/blob-module.test.js | 35 +++ .../tests/did-module.test.js | 152 +-------- packages/credential-sdk/package.json | 1 - .../src/generate-tests/attest-module.js | 49 +++ .../src/generate-tests/blob-module.js | 51 +++ .../src/generate-tests/common.js | 6 + .../src/generate-tests/did-module.js | 206 ++++++++++++ .../src/modules/schema/module.js | 8 +- .../src/resolver/did/dock-did-resolver.js | 12 +- .../src/types/accumulator/index.js | 20 +- .../credential-sdk/src/types/blob/blob-id.js | 62 +--- .../credential-sdk/src/types/blob/blob.js | 4 + .../credential-sdk/src/types/blob/const.js | 2 + .../credential-sdk/src/types/blob/index.js | 9 +- .../credential-sdk/src/types/did/document.js | 297 ++++++++++++------ .../src/types/did/onchain/did-key.js | 18 +- .../src/types/did/onchain/index.js | 17 +- .../types/did/onchain/typed-did/cheqd-did.js | 17 +- .../did-method-key-public-key.js | 44 ++- .../did-method-key-signature.js | 16 +- .../did/onchain/typed-did/dock-did-value.js | 41 ++- .../src/types/did/onchain/typed-did/index.js | 93 ++++-- .../types/did/onchain/typed-did/signature.js | 3 + .../src/types/did/onchain/utils.js | 83 ----- .../src/types/generic/typed-enum.js | 70 +++-- .../src/types/generic/typed-number.js | 12 + .../src/types/generic/typed-uuid.js | 25 +- .../src/types/generic/with-qualifier.js | 22 +- .../types/offchain-signatures/params/index.js | 5 + .../types/offchain-signatures/params/value.js | 3 + .../offchain-signatures/public-keys/index.js | 15 +- .../offchain-signatures/public-keys/value.js | 7 +- packages/credential-sdk/src/utils/bytes.js | 4 +- packages/credential-sdk/src/utils/misc.js | 4 - .../tests/__snapshots__/document.test.js.snap | 40 ++- .../credential-sdk/tests/document.test.js | 19 +- packages/credential-sdk/tests/schema.test.js | 15 +- .../credential-sdk/tests/serialize.test.js | 3 +- packages/dock-blockchain-api/src/api/index.js | 21 +- .../src/attest/module.js | 6 +- .../src/blob/actions.js | 4 +- .../dock-blockchain-modules/src/blob/types.js | 14 +- .../src/common/builders.js | 4 +- .../src/common/dock-api-provider.js | 26 +- .../src/common/with-params-and-public-keys.js | 8 +- .../dock-blockchain-modules/src/did/module.js | 179 +++++++---- .../src/trust-registry/internal.js | 172 +++++----- .../src/trust-registry/module.js | 27 +- .../integration/modules/attest-module.test.js | 32 ++ .../integration/modules/blob-module.test.js | 33 ++ .../integration/modules/did-module.test.js | 34 ++ .../tests/integration/schema.test.js | 2 +- scripts/with_cheqd_docker_test_node | 2 +- scripts/with_dock_docker_test_node | 2 +- tutorials/src/tutorial_blobs_schemas.md | 2 +- tutorials/src/tutorial_resolver.md | 16 +- tutorials/src/tutorial_revocation.md | 14 +- 68 files changed, 1522 insertions(+), 897 deletions(-) create mode 100644 packages/cheqd-blockchain-modules/src/blob/internal.js create mode 100644 packages/cheqd-blockchain-modules/src/blob/module.js create mode 100644 packages/cheqd-blockchain-modules/src/blob/types.js create mode 100644 packages/cheqd-blockchain-modules/tests/attest-module.test.js delete mode 100644 packages/cheqd-blockchain-modules/tests/attest.test.js create mode 100644 packages/cheqd-blockchain-modules/tests/blob-module.test.js create mode 100644 packages/credential-sdk/src/generate-tests/attest-module.js create mode 100644 packages/credential-sdk/src/generate-tests/blob-module.js create mode 100644 packages/credential-sdk/src/generate-tests/common.js create mode 100644 packages/credential-sdk/src/generate-tests/did-module.js create mode 100644 packages/credential-sdk/src/types/did/onchain/typed-did/signature.js delete mode 100644 packages/credential-sdk/src/types/did/onchain/utils.js create mode 100644 packages/dock-blockchain-modules/tests/integration/modules/attest-module.test.js create mode 100644 packages/dock-blockchain-modules/tests/integration/modules/blob-module.test.js create mode 100644 packages/dock-blockchain-modules/tests/integration/modules/did-module.test.js diff --git a/examples/schema.js b/examples/schema.js index d46f2f990..cc540ab39 100644 --- a/examples/schema.js +++ b/examples/schema.js @@ -6,6 +6,7 @@ import { DIDDocument, DidKey, VerificationRelationship, + DockBlobId, } from '@docknetwork/credential-sdk/types'; import { Schema } from '@docknetwork/credential-sdk/modules'; import { DockCoreModules } from '@docknetwork/dock-blockchain-modules'; @@ -70,7 +71,7 @@ async function main() { await createDID(subjectDID, subjectPair); console.log('Creating a new schema...'); - const schema = new Schema(); + const schema = new Schema(DockBlobId.random()); await schema.setJSONSchema({ $schema: 'http://json-schema.org/draft-07/schema#', description: 'Dock Schema Example', diff --git a/packages/cheqd-blockchain-api/src/index.js b/packages/cheqd-blockchain-api/src/index.js index 0ff3bebc5..7bc6a744c 100644 --- a/packages/cheqd-blockchain-api/src/index.js +++ b/packages/cheqd-blockchain-api/src/index.js @@ -145,7 +145,9 @@ export class CheqdAPI extends ApiProvider { if (res.code) { console.error(res); - throw new Error(`Error: ${JSON.stringify(res)}`); + throw new Error( + JSON.stringify(res, (_, value) => (typeof value === 'bigint' ? `${value.toString()}n` : value)), + ); } return res; diff --git a/packages/cheqd-blockchain-modules/src/attest/internal.js b/packages/cheqd-blockchain-modules/src/attest/internal.js index 59a63fa2e..b830babc9 100644 --- a/packages/cheqd-blockchain-modules/src/attest/internal.js +++ b/packages/cheqd-blockchain-modules/src/attest/internal.js @@ -1,52 +1,39 @@ -import { CheqdDid, Iri } from '@docknetwork/credential-sdk/types'; -import { TypedUUID, option } from '@docknetwork/credential-sdk/types/generic'; -import { CheqdCreateResource, createInternalCheqdModule } from '../common'; +import { CheqdDid, Iri } from "@docknetwork/credential-sdk/types"; +import { TypedUUID, option } from "@docknetwork/credential-sdk/types/generic"; +import { CheqdCreateResource, createInternalCheqdModule } from "../common"; const methods = { - setClaim: (iri, targetDid) => new CheqdCreateResource( - targetDid.value, - TypedUUID.random(), - '1.0', - [], - 'Attestation', - 'attest', - Iri.from(iri), - ), + setClaim: (iri, targetDid) => + new CheqdCreateResource( + CheqdDid.from(targetDid).value, + TypedUUID.random(), + "1.0", + [], + "Attestation", + "attest", + Iri.from(iri) + ), }; export default class CheqdInternalAttestModule extends createInternalCheqdModule( - methods, + methods ) { - static Prop = 'resource'; + static Prop = "resource"; static MsgNames = { - setClaim: 'MsgCreateResource', + setClaim: "MsgCreateResource", }; async attest(did, attestId) { - const stringDid = CheqdDid.from(did).toEncodedString(); - const stringAttestId = String(TypedUUID.from(attestId)); - const item = await this.query.resource(stringDid, stringAttestId); - - return option(Iri).from(item?.resource?.data); + return option(Iri).from( + (await this.resource(did, attestId))?.resource?.data + ); } async attestId(did) { - let resources = []; - let paginationKey; - - do { - // eslint-disable-next-line no-await-in-loop - const res = await this.query.collectionResources( - CheqdDid.from(did).toEncodedString(), - paginationKey, - ); - resources = resources.concat( - res.resources.filter((resource) => resource.resourceType === 'attest'), - ); - ({ paginationKey } = res); - } while (!resources.length && paginationKey != null); - - return resources.find((resource) => !resource.nextVersionId)?.id; + return await this.latestResourceIdBy( + did, + (resource) => resource.resourceType === "attest" + ); } } diff --git a/packages/cheqd-blockchain-modules/src/blob/internal.js b/packages/cheqd-blockchain-modules/src/blob/internal.js new file mode 100644 index 000000000..fe0852896 --- /dev/null +++ b/packages/cheqd-blockchain-modules/src/blob/internal.js @@ -0,0 +1,41 @@ +import { + Blob, + CheqdBlobId, + CheqdBlobWithId, + CheqdDid, +} from "@docknetwork/credential-sdk/types"; +import { option } from "@docknetwork/credential-sdk/types/generic"; +import { CheqdCreateResource, createInternalCheqdModule } from "../common"; + +const methods = { + new: (blobWithId) => { + const { blob, id } = CheqdBlobWithId.from(blobWithId); + const [did, uuid] = id; + + return new CheqdCreateResource( + CheqdDid.from(did).value, + uuid, + "1.0", + [], + "Blob", + "blob", + blob + ); + }, +}; + +export default class CheqdInternalBlobModule extends createInternalCheqdModule( + methods +) { + static Prop = "resource"; + + static MsgNames = { + new: "MsgCreateResource", + }; + + async blob(blobId) { + return option(Blob).from( + (await this.resource(...CheqdBlobId.from(blobId)))?.resource?.data + ); + } +} diff --git a/packages/cheqd-blockchain-modules/src/blob/module.js b/packages/cheqd-blockchain-modules/src/blob/module.js new file mode 100644 index 000000000..83d51c90e --- /dev/null +++ b/packages/cheqd-blockchain-modules/src/blob/module.js @@ -0,0 +1,25 @@ +import AbstractBlobModule from '@docknetwork/credential-sdk/modules/blob/module'; +import { NoBlobError } from '@docknetwork/credential-sdk/modules/blob/errors'; +import { CheqdBlobId } from '@docknetwork/credential-sdk/types'; +import { injectCheqd } from '../common'; +import CheqdInternalBlobModule from './internal'; +import { OwnerWithBlob } from './types'; + +export default class CheqdBlobModule extends injectCheqd(AbstractBlobModule) { + static CheqdOnly = CheqdInternalBlobModule; + + async newTx(blobWithId, targetDid, didKeypair) { + return await this.cheqdOnly.tx.new(blobWithId, targetDid, didKeypair); + } + + async get(blobId) { + const id = CheqdBlobId.from(blobId); + const blob = await this.cheqdOnly.blob(id); + + if (blob == null) { + throw new NoBlobError(id); + } + + return new OwnerWithBlob(id[0], blob); + } +} diff --git a/packages/cheqd-blockchain-modules/src/blob/types.js b/packages/cheqd-blockchain-modules/src/blob/types.js new file mode 100644 index 000000000..0f88d2492 --- /dev/null +++ b/packages/cheqd-blockchain-modules/src/blob/types.js @@ -0,0 +1,6 @@ +import { CheqdDid, Blob } from '@docknetwork/credential-sdk/types'; +import { TypedTuple } from '@docknetwork/credential-sdk/types/generic'; + +export class OwnerWithBlob extends TypedTuple { + static Classes = [CheqdDid, Blob]; +} diff --git a/packages/cheqd-blockchain-modules/src/common/builders.js b/packages/cheqd-blockchain-modules/src/common/builders.js index d5e3c187f..546bed48d 100644 --- a/packages/cheqd-blockchain-modules/src/common/builders.js +++ b/packages/cheqd-blockchain-modules/src/common/builders.js @@ -1,5 +1,9 @@ -import { VerificationMethodSignature } from '@docknetwork/credential-sdk/types'; -import { CheqdPayloadWithTypeUrl } from './payload'; +import { + VerificationMethodSignature, + CheqdDid, +} from "@docknetwork/credential-sdk/types"; +import { TypedUUID } from "@docknetwork/credential-sdk/types/generic"; +import { CheqdPayloadWithTypeUrl } from "./payload"; /** * Creates DID method transaction builder. @@ -14,12 +18,14 @@ export const createDIDMethodTx = (fnName) => { const payload = root.payload[fnName].apply(this.root, args); const bytes = await root.apiProvider.stateChangeBytes( root.constructor.MsgNames[fnName], - payload, + payload ); const signatures = [] .concat(didKeypairs) - .map((didKeypair) => VerificationMethodSignature.fromDidKeypair(didKeypair, bytes)); + .map((didKeypair) => + VerificationMethodSignature.fromDidKeypair(didKeypair, bytes) + ); const value = { payload, @@ -28,7 +34,7 @@ export const createDIDMethodTx = (fnName) => { return new CheqdPayloadWithTypeUrl( root.constructor.MsgNames[fnName], - value, + value ); }, }; @@ -44,7 +50,7 @@ export const createCall = (fnName) => { async [fnName](...args) { const { root } = this; const tx = await root.tx[fnName]( - ...args.slice(0, root.payload[fnName].length), + ...args.slice(0, root.payload[fnName].length) ); return await root.signAndSend(tx, args[root.payload[fnName].length]); @@ -61,7 +67,7 @@ export const createAccountTx = (fnName) => { const obj = { async [fnName](...args) { return await this.root.rawTx[fnName]( - ...this.root.payload[fnName].apply(this.root, args), + ...this.root.payload[fnName].apply(this.root, args) ); }, }; @@ -77,7 +83,7 @@ class Root { export function createInternalCheqdModule( methods = Object.create(null), - baseClass = class CheqdModuleBaseClass {}, + baseClass = class CheqdModuleBaseClass {} ) { const name = `internalCheqdModule(${baseClass.name})`; class RootPayload extends (baseClass.RootPayload ?? Root) {} @@ -100,6 +106,55 @@ export function createInternalCheqdModule( this.apiProvider = apiProvider; } + async resource(did, id) { + const strDid = CheqdDid.from(did).toEncodedString(); + const strID = String(TypedUUID.from(id)); + + try { + return await this.apiProvider.sdk.querier.resource.resource( + strDid, + strID + ); + } catch (err) { + if (!String(err).includes("DID Doc not found")) { + throw err; + } + } + + return null; + } + + async latestResourceIdBy(did, cond) { + let resources; + let paginationKey; + const encodedDid = CheqdDid.from(did).toEncodedString(); + + do { + try { + ({ resources, paginationKey } = + // eslint-disable-next-line no-await-in-loop + await this.apiProvider.sdk.querier.resource.collectionResources( + encodedDid, + paginationKey + )); + } catch (err) { + if (!String(err).includes("DID Doc not found")) { + throw err; + } else { + break; + } + } + + for (const resource of resources) { + if (cond(resource) && !resource.nextVersionId) { + return resource.id; + } + } + } while (paginationKey != null); + + return null; + } + get query() { return this.apiProvider.sdk.querier[this.constructor.Prop]; } diff --git a/packages/cheqd-blockchain-modules/src/did/module.js b/packages/cheqd-blockchain-modules/src/did/module.js index ffd8f34d2..7f2dd8f1b 100644 --- a/packages/cheqd-blockchain-modules/src/did/module.js +++ b/packages/cheqd-blockchain-modules/src/did/module.js @@ -34,9 +34,13 @@ export default class CheqdDIDModule extends injectCheqd(AbstractDIDModule) { async updateDocumentTx(document, didSigners) { const didDocument = DIDDocument.from(document); if (didDocument.attests != null) { - throw new Error( - `Non-null \`attest\` was provided for DID document \`${didDocument.id}\`. Use \`attest\` module to set attestations.`, - ); + const currentDocument = await this.getDocument(didDocument.id); + + if (!didDocument.attests.eq(currentDocument.attests)) { + throw new Error( + '`attests` modifications are not supported in the `updateDocument` transaction.', + ); + } } return await this.cheqdOnly.tx.updateDidDocument(didDocument, didSigners); @@ -71,9 +75,8 @@ export default class CheqdDIDModule extends injectCheqd(AbstractDIDModule) { throw new NoDIDError(cheqdDid); } - const document = CheqdDIDDocument.from(doc).toDIDDocument(); - const attests = await this.attest.getAttests(did); - - return document.setAttests(attests); + return CheqdDIDDocument.from(doc) + .toDIDDocument() + .setAttests(await this.attest.getAttests(cheqdDid)); } } diff --git a/packages/cheqd-blockchain-modules/src/index.js b/packages/cheqd-blockchain-modules/src/index.js index 1032f97b1..6e011f25b 100644 --- a/packages/cheqd-blockchain-modules/src/index.js +++ b/packages/cheqd-blockchain-modules/src/index.js @@ -1,9 +1,9 @@ -import { AbstractCoreModules } from '@docknetwork/credential-sdk/modules'; -import CheqdAttestModule from './attest/module'; -import CheqdDIDModule from './did/module'; +import { AbstractCoreModules } from "@docknetwork/credential-sdk/modules"; +import CheqdAttestModule from "./attest/module"; +import CheqdBlobModule from "./blob/module"; +import CheqdDIDModule from "./did/module"; // import CheqdAccumulatorModule from './accumulator/module'; // import CheqdAnchorModule from './anchor/module'; -// import CheqdBlobModule from './blob/module'; // import CheqdOffchainSignaturesModule from './offchain-signatures/module'; // import CheqdBBSModule from './offchain-signatures/bbs'; // import CheqdBBSPlusModule from './offchain-signatures/bbs-plus'; @@ -18,7 +18,7 @@ export class CheqdCoreModules extends AbstractCoreModules { static AttestModule = CheqdAttestModule; - // static BlobModule = CheqdBlobModule; + static BlobModule = CheqdBlobModule; static DIDModule = CheqdDIDModule; @@ -38,9 +38,10 @@ export class CheqdCoreModules extends AbstractCoreModules { export { CheqdAttestModule, CheqdDIDModule, + CheqdBlobModule, // CheqdAccumulatorModule, // CheqdAnchorModule, - // CheqdBlobModule, + // , // CheqdOffchainSignaturesModule, // CheqdBBSModule, // CheqdBBSPlusModule, diff --git a/packages/cheqd-blockchain-modules/tests/attest-module.test.js b/packages/cheqd-blockchain-modules/tests/attest-module.test.js new file mode 100644 index 000000000..0bb7096da --- /dev/null +++ b/packages/cheqd-blockchain-modules/tests/attest-module.test.js @@ -0,0 +1,29 @@ +import { CheqdAPI } from "@docknetwork/cheqd-blockchain-api"; +import { CheqdTestnetDid } from "@docknetwork/credential-sdk/types"; +import generateAttestModuleTests from "@docknetwork/credential-sdk/generate-tests/attest-module"; +import CheqdDIDModule from "../src/did/module"; +import { faucet } from "./constants"; +import CheqdAttestModule from "../src/attest/module"; + +describe("AttestModule", () => { + const cheqd = new CheqdAPI(); + + beforeAll(async () => { + await cheqd.init({ + url: process.env.ENDPOINT_URL || "http://localhost:26657", + mnemonic: faucet.mnemonic, + }); + }); + + afterAll(async () => { + await cheqd.disconnect(); + }); + + generateAttestModuleTests( + { + did: new CheqdDIDModule(cheqd), + attest: new CheqdAttestModule(cheqd), + }, + { DID: CheqdTestnetDid } + ); +}); diff --git a/packages/cheqd-blockchain-modules/tests/attest.test.js b/packages/cheqd-blockchain-modules/tests/attest.test.js deleted file mode 100644 index a2537edff..000000000 --- a/packages/cheqd-blockchain-modules/tests/attest.test.js +++ /dev/null @@ -1,63 +0,0 @@ -import { - DidKeypair, - Ed25519Keypair, -} from "@docknetwork/credential-sdk/keypairs"; -import { CheqdAPI } from "@docknetwork/cheqd-blockchain-api"; -import { timeout } from "@docknetwork/credential-sdk/utils"; -import { - DIDDocument, - CheqdTestnetDid, -} from "@docknetwork/credential-sdk/types"; -import CheqdDIDModule from "../src/did/module"; -import { faucet } from "./constants"; -import CheqdAttestModule from "../src/attest/module"; - -describe("DIDModule", () => { - const cheqd = new CheqdAPI(); - const didModule = new CheqdDIDModule(cheqd); - const attestModule = new CheqdAttestModule(cheqd); - - beforeAll(async () => { - await cheqd.init({ - url: process.env.ENDPOINT_URL || "http://localhost:26657", - mnemonic: faucet.mnemonic, - }); - }); - - afterAll(async () => { - await cheqd.disconnect(); - }); - - it("Generates a `DIDDocument` and appends an attestation to it", async () => { - const did = CheqdTestnetDid.random(); - - const keyPair = Ed25519Keypair.random(); - const didKeypair = new DidKeypair([did, 1], keyPair); - - const document = DIDDocument.create(did, [didKeypair.didKey()]); - - await didModule.createDocument(document, didKeypair); - - expect((await didModule.getDocument(did)).toJSON()).toEqual( - document.toJSON() - ); - - const iri = "some iri"; - await attestModule.setClaim(iri, did, didKeypair); - - expect((await attestModule.getAttests(did)).toString()).toBe(iri); - document.setAttests(iri); - expect((await didModule.getDocument(did)).toJSON()).toEqual( - document.toJSON() - ); - - const iri2 = "other iri"; - await attestModule.setClaim(iri2, did, didKeypair); - await timeout(500); - expect((await attestModule.getAttests(did)).toString()).toBe(iri2); - document.setAttests(iri2); - expect((await didModule.getDocument(did)).toJSON()).toEqual( - document.toJSON() - ); - }); -}); diff --git a/packages/cheqd-blockchain-modules/tests/blob-module.test.js b/packages/cheqd-blockchain-modules/tests/blob-module.test.js new file mode 100644 index 000000000..9f9580199 --- /dev/null +++ b/packages/cheqd-blockchain-modules/tests/blob-module.test.js @@ -0,0 +1,35 @@ +import { CheqdAPI } from "@docknetwork/cheqd-blockchain-api"; +import { + CheqdTestnetDid, + CheqdBlobId, +} from "@docknetwork/credential-sdk/types"; +import generateBlobModuleTests from "@docknetwork/credential-sdk/generate-tests/blob-module"; +import CheqdDIDModule from "../src/did/module"; +import { faucet } from "./constants"; +import CheqdBlobModule from "../src/blob/module"; + +describe("BlobModule", () => { + const cheqd = new CheqdAPI(); + + beforeAll(async () => { + await cheqd.init({ + url: process.env.ENDPOINT_URL || "http://localhost:26657", + mnemonic: faucet.mnemonic, + }); + }); + + afterAll(async () => { + await cheqd.disconnect(); + }); + + generateBlobModuleTests( + { + did: new CheqdDIDModule(cheqd), + blob: new CheqdBlobModule(cheqd), + }, + { + DID: CheqdTestnetDid, + BlobId: CheqdBlobId, + } + ); +}); diff --git a/packages/cheqd-blockchain-modules/tests/did-module.test.js b/packages/cheqd-blockchain-modules/tests/did-module.test.js index 14ba87f01..4d21854c2 100644 --- a/packages/cheqd-blockchain-modules/tests/did-module.test.js +++ b/packages/cheqd-blockchain-modules/tests/did-module.test.js @@ -1,26 +1,11 @@ -import { - DidKeypair, - Ed25519Keypair, -} from "@docknetwork/credential-sdk/keypairs"; import { CheqdAPI } from "@docknetwork/cheqd-blockchain-api"; +import { CheqdTestnetDid } from "@docknetwork/credential-sdk/types"; +import didModuleTests from "@docknetwork/credential-sdk/generate-tests/did-module"; import CheqdDIDModule from "../src/did/module"; import { faucet } from "./constants"; -import { - DIDDocument, - BBSPublicKeyValue, - DidKey, - BBSPlusPublicKeyValue, - PSPublicKeyValue, - VerificationMethodRef, - CheqdTestnetDid, -} from "@docknetwork/credential-sdk/types"; -import { TypedBytes } from "@docknetwork/credential-sdk/types/generic"; -import { ServiceEndpoint } from "@docknetwork/credential-sdk/types/did/offchain"; -import { NoDIDError } from "@docknetwork/credential-sdk/modules/did"; describe("DIDModule", () => { const cheqd = new CheqdAPI(); - const module = new CheqdDIDModule(cheqd); beforeAll(async () => { await cheqd.init({ @@ -33,136 +18,5 @@ describe("DIDModule", () => { await cheqd.disconnect(); }); - it("Creates basic `DIDDocument` with keys", async () => { - const did = CheqdTestnetDid.random(); - - const keyPair = Ed25519Keypair.random(); - const didKeypair = new DidKeypair([did, 1], keyPair); - - const document = DIDDocument.create(did, [didKeypair.didKey()]); - - await module.createDocument(document, didKeypair); - - expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - }); - - it("Operates with `DIDDocument` containing BBS/BBSPlus/PS keys", async () => { - const did = CheqdTestnetDid.random(); - - const keyPair = Ed25519Keypair.random(); - const didKeypair = new DidKeypair([did, 1], keyPair); - - const bbsKey = new BBSPublicKeyValue(TypedBytes.random(100)); - const bbsPlusKey = new BBSPlusPublicKeyValue(TypedBytes.random(100)); - const psKey = new PSPublicKeyValue(TypedBytes.random(1000)); - - const document = DIDDocument.create(did, [ - didKeypair.didKey(), - new DidKey(bbsKey), - new DidKey(bbsPlusKey), - new DidKey(psKey), - ]); - - await module.createDocument(document, didKeypair); - - expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - - document.removeKey([did, 3]); - - await module.updateDocument(document, didKeypair); - - expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - - expect(document.didKeys().toJSON()).toEqual([ - [didKeypair.verificationMethodId.toJSON(), didKeypair.didKey().toJSON()], - [new VerificationMethodRef(did, 2).toJSON(), new DidKey(bbsKey).toJSON()], - [new VerificationMethodRef(did, 4).toJSON(), new DidKey(psKey).toJSON()], - ]); - }); - - it("Operates with `DIDDocument` containing services", async () => { - const did = CheqdTestnetDid.random(); - - const keyPair = Ed25519Keypair.random(); - const didKeypair = new DidKeypair([did, 1], keyPair); - - const service1 = new ServiceEndpoint("LinkedDomains", [ - "ServiceEndpoint#1", - ]); - const service2 = new ServiceEndpoint("LinkedDomains", [ - "ServiceEndpoint#2", - ]); - - const document = DIDDocument.create(did, [didKeypair.didKey()], [did], { - service1, - service2, - }); - - await module.createDocument(document, didKeypair); - - expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - - document.removeServiceEndpoint([did, "service2"]); - - await module.updateDocument(document, didKeypair); - - expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - - expect(document.service.length).toEqual(1); - }); - - it("Updates `DIDDocument`'s keys", async () => { - const did = CheqdTestnetDid.random(); - - const keyPair1 = Ed25519Keypair.random(); - const keyPair2 = Ed25519Keypair.random(); - const keyPair3 = Ed25519Keypair.random(); - - const didKeypair1 = new DidKeypair([did, 1], keyPair1); - const didKeypair2 = new DidKeypair([did, 2], keyPair2); - const didKeypair3 = new DidKeypair([did, 3], keyPair3); - - const document = DIDDocument.create(did, [ - didKeypair1.didKey(), - didKeypair2.didKey(), - ]); - - await module.createDocument(document, didKeypair2); - expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - - document.removeKey([did, 2]); - await module.updateDocument(document, didKeypair1); - expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - - await expect(() => - module.updateDocument(document, didKeypair2) - ).rejects.toThrow(); - - document.addKey([did, 3], didKeypair3.didKey()); - await module.updateDocument(document, didKeypair1); - expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - }); - - it("Deactivates `DIDDocument`", async () => { - const did = CheqdTestnetDid.random(); - - const keyPair = Ed25519Keypair.random(); - const didKeypair = new DidKeypair([did, 1], keyPair); - - const document = DIDDocument.create(did, [didKeypair.didKey()]); - - await module.createDocument(document, didKeypair); - expect( - (await module.cheqdOnly.getDidDocumentWithMetadata(did)).metadata - .deactivated - ).toBe(false); - expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - - await module.removeDocument(did, didKeypair); - expect( - (await module.cheqdOnly.getDidDocumentWithMetadata(did)).metadata - .deactivated - ).toBe(true); - expect(() => module.getDocument(did)).rejects.toThrow(new NoDIDError(did)); - }); + didModuleTests({ did: new CheqdDIDModule(cheqd) }, { DID: CheqdTestnetDid }); }); diff --git a/packages/credential-sdk/package.json b/packages/credential-sdk/package.json index b4f0aaa53..9878e001b 100644 --- a/packages/credential-sdk/package.json +++ b/packages/credential-sdk/package.json @@ -93,7 +93,6 @@ "test-ipfs": "NODE_OPTIONS=--experimental-vm-modules NODE_ENV=production jest --verbose --runInBand --forceExit ./tests/ipfs", "test-ipfs-with-node": "../scripts/with_dock_docker_test_node yarn test-ipfs", "test": "yarn jest --verbose ./tests", - "test-with-node": "../../scripts/with_dock_docker_test_node yarn test", "test-with-all-nodes": "../../scripts/with_all_dock_docker_test_nodes yarn test-integration", "lint": "eslint \"src/**/*.js\"", "lint-scripts": "eslint \"scripts/**/*.js\"", diff --git a/packages/credential-sdk/src/generate-tests/attest-module.js b/packages/credential-sdk/src/generate-tests/attest-module.js new file mode 100644 index 000000000..d9e9f2b01 --- /dev/null +++ b/packages/credential-sdk/src/generate-tests/attest-module.js @@ -0,0 +1,49 @@ +import { DidKeypair, Ed25519Keypair } from '../keypairs'; +import { DIDDocument } from '../types'; +import { itIf } from './common'; + +// eslint-disable-next-line jest/no-export +export default function generateAttestModuleTests( + { did: didModule, attest: attestModule }, + { DID }, + filter = () => true, +) { + const test = itIf(filter); + + test('Generates a `DIDDocument` and appends an attestation to it', async () => { + const did = DID.random(); + + const keyPair = Ed25519Keypair.random(); + const didKeypair = new DidKeypair([did, 1], keyPair); + + const document = DIDDocument.create(did, [didKeypair.didKey()]); + + await didModule.createDocument(document, didKeypair); + + expect((await didModule.getDocument(did)).toJSON()).toEqual( + document.toJSON(), + ); + + const iri = 'some iri'; + await attestModule.setClaim(iri, did, didKeypair); + + expect((await attestModule.getAttests(did)).toString()).toBe(iri); + document.setAttests(iri); + expect((await didModule.getDocument(did)).toJSON()).toEqual( + document.toJSON(), + ); + + const iri2 = 'other iri'; + await attestModule.setClaim(iri2, did, didKeypair); + + expect((await attestModule.getAttests(did)).toString()).toBe(iri2); + document.setAttests(iri2); + expect((await didModule.getDocument(did)).toJSON()).toEqual( + document.toJSON(), + ); + }); + + test('Returns `null` on missing attest', async () => { + expect(await attestModule.getAttests(DID.random())).toBe(null); + }); +} diff --git a/packages/credential-sdk/src/generate-tests/blob-module.js b/packages/credential-sdk/src/generate-tests/blob-module.js new file mode 100644 index 000000000..b40f58d4e --- /dev/null +++ b/packages/credential-sdk/src/generate-tests/blob-module.js @@ -0,0 +1,51 @@ +import { DidKeypair, Ed25519Keypair } from '../keypairs'; +import { NoBlobError } from '../modules/blob/errors'; +import { DIDDocument } from '../types'; + +// eslint-disable-next-line jest/no-export +export default function generateBlobModuleTests( + { did: didModule, blob: blobModule }, + { DID, BlobId }, +) { + it('Generates a `DIDDocument` and creates a blob owned by this DID', async () => { + const did = DID.random(); + + const keyPair = Ed25519Keypair.random(); + const didKeypair = new DidKeypair([did, 1], keyPair); + + const document = DIDDocument.create(did, [didKeypair.didKey()]); + + await didModule.createDocument(document, didKeypair); + + const blob1 = { + id: BlobId.random(did), + blob: 'abcdef', + }; + await blobModule.new(blob1, did, didKeypair); + + const written1 = await blobModule.get(blob1.id); + + expect(written1[0].eq(did)).toBe(true); + expect(written1[1].toUTF8String()).toEqual(blob1.blob); + + const blob2 = { + id: BlobId.random(did), + blob: { + example: 'content', + }, + }; + await blobModule.new(blob2, did, didKeypair); + + const written2 = await blobModule.get(blob2.id); + expect(written2[0].eq(did)).toBe(true); + expect(written2[1].toObject()).toEqual(blob2.blob); + + await expect(() => blobModule.new(blob2, did, didKeypair)).rejects.toThrow(); + }); + + it('Throws an error on missing blob', async () => { + const id = BlobId.random(DID.random()); + + await expect(() => blobModule.get(id)).rejects.toThrow(new NoBlobError(id)); + }); +} diff --git a/packages/credential-sdk/src/generate-tests/common.js b/packages/credential-sdk/src/generate-tests/common.js new file mode 100644 index 000000000..26cddd3d9 --- /dev/null +++ b/packages/credential-sdk/src/generate-tests/common.js @@ -0,0 +1,6 @@ +/* eslint-disable */ +export const itIf = + (filter) => + (...args) => + filter(...args) ? it(...args) : it.skip(...args); +/* eslint-enable */ diff --git a/packages/credential-sdk/src/generate-tests/did-module.js b/packages/credential-sdk/src/generate-tests/did-module.js new file mode 100644 index 000000000..f1107df57 --- /dev/null +++ b/packages/credential-sdk/src/generate-tests/did-module.js @@ -0,0 +1,206 @@ +import { DidKeypair, Ed25519Keypair } from "../keypairs"; +import { + DIDDocument, + BBSPublicKeyValue, + DidKey, + BBSPlusPublicKeyValue, + PSPublicKeyValue, + VerificationMethodRef, +} from "../types"; +import { TypedBytes } from "../types/generic"; +import { ServiceEndpoint } from "../types/did/offchain"; +import { NoDIDError } from "../modules/did"; +import { itIf } from "./common"; + +export default function generateDIDModuleTests( + { did: module }, + { DID }, + filter = () => true +) { + const test = itIf(filter); + + test("Creates basic `DIDDocument` with keys", async () => { + const did = DID.random(); + + const keyPair = Ed25519Keypair.random(); + const didKeypair = new DidKeypair([did, 1], keyPair); + + const document = DIDDocument.create(did, [didKeypair.didKey()]); + + await module.createDocument(document, didKeypair); + + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + }); + + test("Creates `DIDDocument` containing BBS/BBSPlus/PS keys", async () => { + const did = DID.random(); + + const keyPair = Ed25519Keypair.random(); + const didKeypair = new DidKeypair([did, 1], keyPair); + + const bbsKey = new BBSPublicKeyValue(TypedBytes.random(100)); + const bbsPlusKey = new BBSPlusPublicKeyValue(TypedBytes.random(100)); + const psKey = new PSPublicKeyValue(TypedBytes.random(1000)); + + const document = DIDDocument.create(did, [ + didKeypair.didKey(), + new DidKey(bbsKey), + new DidKey(bbsPlusKey), + new DidKey(psKey), + ]); + + await module.createDocument(document, didKeypair); + + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + }); + + test("Updates with `DIDDocument` containing BBS/BBSPlus/PS keys", async () => { + const did = DID.random(); + + const keyPair = Ed25519Keypair.random(); + const didKeypair = new DidKeypair([did, 1], keyPair); + + const bbsKey = new DidKey(new BBSPublicKeyValue(TypedBytes.random(100))); + const bbsPlusKey = new DidKey( + new BBSPlusPublicKeyValue(TypedBytes.random(100)) + ); + const psKey = new DidKey(new PSPublicKeyValue(TypedBytes.random(1000))); + + const document = DIDDocument.create(did, [didKeypair.didKey()]); + + await module.createDocument(document, didKeypair); + + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + + document.addKey([did, document.nextKeyIndex()], bbsKey); + document.addKey([did, document.nextKeyIndex()], bbsPlusKey); + document.addKey([did, document.nextKeyIndex()], psKey); + + await module.updateDocument(document, didKeypair); + + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + + expect(document.didKeys().toJSON()).toEqual([ + [didKeypair.verificationMethodId.toJSON(), didKeypair.didKey().toJSON()], + [new VerificationMethodRef(did, 2).toJSON(), bbsKey.toJSON()], + [new VerificationMethodRef(did, 3).toJSON(), bbsPlusKey.toJSON()], + [new VerificationMethodRef(did, 4).toJSON(), psKey.toJSON()], + ]); + }); + + test("Creates `DIDDocument` containing services", async () => { + const did = DID.random(); + + const keyPair = Ed25519Keypair.random(); + const didKeypair = new DidKeypair([did, 1], keyPair); + + const service1 = new ServiceEndpoint("LinkedDomains", [ + "ServiceEndpoint#1", + ]); + const service2 = new ServiceEndpoint("LinkedDomains", [ + "ServiceEndpoint#2", + ]); + + const document = DIDDocument.create(did, [didKeypair.didKey()], [], { + service1, + service2, + }); + console.log(document.toJSON()); + + await module.createDocument(document, didKeypair); + + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + }); + + test("Updates `DIDDocument` containing services", async () => { + const did = DID.random(); + + const keyPair = Ed25519Keypair.random(); + const didKeypair = new DidKeypair([did, 1], keyPair); + + const service1 = new ServiceEndpoint("LinkedDomains", [ + "ServiceEndpoint#1", + ]); + const service2 = new ServiceEndpoint("LinkedDomains", [ + "ServiceEndpoint#2", + ]); + + const document = DIDDocument.create(did, [didKeypair.didKey()]); + + await module.createDocument(document, didKeypair); + + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + + document.addServiceEndpoint([did, "service1"], service1); + document.addServiceEndpoint([did, "service2"], service2); + + await module.updateDocument(document, didKeypair); + + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + + document.removeServiceEndpoint([did, "service2"]); + + await module.updateDocument(document, didKeypair); + + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + + expect(document.service.length).toEqual(1); + }); + + test("Updates `DIDDocument`'s keys", async () => { + const did = DID.random(); + + const keyPair1 = Ed25519Keypair.random(); + const keyPair2 = Ed25519Keypair.random(); + const keyPair3 = Ed25519Keypair.random(); + + const didKeypair1 = new DidKeypair([did, 1], keyPair1); + const didKeypair2 = new DidKeypair([did, 2], keyPair2); + const didKeypair3 = new DidKeypair([did, 3], keyPair3); + + const document = DIDDocument.create(did, [ + didKeypair1.didKey(), + didKeypair2.didKey(), + ]); + + await module.createDocument(document, didKeypair2); + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + + document.removeKey([did, 2]); + await module.updateDocument(document, didKeypair1); + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + + document.addKey([did, 3], didKeypair3.didKey()); + await expect(() => + module.updateDocument(document, didKeypair2) + ).rejects.toThrow(); + + await module.updateDocument(document, didKeypair1); + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + }); + + test("Removes (deactivates) `DIDDocument`", async () => { + const did = DID.random(); + + const keyPair = Ed25519Keypair.random(); + const didKeypair = new DidKeypair([did, 1], keyPair); + + const document = DIDDocument.create(did, [didKeypair.didKey()]); + + await module.createDocument(document, didKeypair); + expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); + + await module.removeDocument(did, didKeypair); + await expect(() => module.getDocument(did)).rejects.toThrow( + new NoDIDError(did) + ); + }); + + test("Throws an error if `DIDDocument` doesn't exist", async () => { + const did = DID.random(); + + await expect(() => module.getDocument(did)).rejects.toThrow( + new NoDIDError(did) + ); + }); +} diff --git a/packages/credential-sdk/src/modules/schema/module.js b/packages/credential-sdk/src/modules/schema/module.js index 5f30b1046..940c74ca8 100644 --- a/packages/credential-sdk/src/modules/schema/module.js +++ b/packages/credential-sdk/src/modules/schema/module.js @@ -4,16 +4,16 @@ import { validate } from 'jsonschema'; // Supported schemas import JSONSchema07 from '../../vc/schemas/schema-draft-07'; import jsonFetch from '../../utils/json-fetch'; -import { BlobId, Blob, BlobWithId } from '../../types'; +import { Blob, BlobWithId } from '../../types'; export default class Schema { /** * Creates a new `Schema` object * @constructor - * @param {string} [id] - optional schema ID, if not given, generate a random id + * @param {string} [id] - schema ID */ - constructor(id = BlobId.random(32)) { - this.id = BlobId.from(id); + constructor(id) { + this.id = id; } static fromJSON(json) { diff --git a/packages/credential-sdk/src/resolver/did/dock-did-resolver.js b/packages/credential-sdk/src/resolver/did/dock-did-resolver.js index 56ba9fd83..1926bb727 100644 --- a/packages/credential-sdk/src/resolver/did/dock-did-resolver.js +++ b/packages/credential-sdk/src/resolver/did/dock-did-resolver.js @@ -1,10 +1,9 @@ -import { AbstractDIDModule } from '../../modules/did'; -import { validateDockDIDSS58Identifier } from '../../types/did'; -import DIDResolver from './did-resolver'; -import { ensureInstanceOf } from '../../utils'; +import { AbstractDIDModule } from "../../modules/did"; +import DIDResolver from "./did-resolver"; +import { ensureInstanceOf } from "../../utils"; class DockDIDResolver extends DIDResolver { - static METHOD = 'dock'; + static METHOD = "dock"; /** * @param {DockAPI} dock - An initialized connection to a dock full-node. @@ -20,8 +19,7 @@ class DockDIDResolver extends DIDResolver { } async resolve(qualifiedDid) { - const { id, did } = this.parseDid(qualifiedDid); - validateDockDIDSS58Identifier(id); + const { did } = this.parseDid(qualifiedDid); const document = await this.didModule.getDocument(did); diff --git a/packages/credential-sdk/src/types/accumulator/index.js b/packages/credential-sdk/src/types/accumulator/index.js index ae00852c2..d7f6ebd6a 100644 --- a/packages/credential-sdk/src/types/accumulator/index.js +++ b/packages/credential-sdk/src/types/accumulator/index.js @@ -1,9 +1,7 @@ -import { IdentRef } from '../did'; -import { - TypedBytes, TypedUUID, sized, withFrom, -} from '../generic'; +import { DIDRef } from "../did"; +import { TypedBytes, TypedUUID, sized, withFrom } from "../generic"; -export class AccumulatorId extends IdentRef {} +export class AccumulatorId extends DIDRef {} export class CheqdAccumulatorIdIdent extends TypedUUID {} @@ -14,7 +12,7 @@ export class CheqdAccumulatorId extends AccumulatorId { export class DockAccumulatorIdIdent extends withFrom( sized(TypedBytes), // eslint-disable-next-line no-use-before-define - (value, from) => (value instanceof DockAccumulatorId ? value[1] : from(value)), + (value, from) => (value instanceof DockAccumulatorId ? value[1] : from(value)) ) { static Size = 32; } @@ -23,8 +21,8 @@ export class DockAccumulatorId extends AccumulatorId { static Ident = DockAccumulatorIdIdent; } -export * from './keys'; -export * from './params'; -export * from './public-key'; -export * from './accumulator'; -export * from './counters'; +export * from "./keys"; +export * from "./params"; +export * from "./public-key"; +export * from "./accumulator"; +export * from "./counters"; diff --git a/packages/credential-sdk/src/types/blob/blob-id.js b/packages/credential-sdk/src/types/blob/blob-id.js index 60e51714b..70952e14f 100644 --- a/packages/credential-sdk/src/types/blob/blob-id.js +++ b/packages/credential-sdk/src/types/blob/blob-id.js @@ -1,26 +1,29 @@ -import { encodeAsSS58, decodeFromSS58 } from '../../utils/ss58'; -import { isHex } from '../../utils/bytes'; -import { TypedBytes, sized, withQualifier } from '../generic'; -import { DockBlobQualifier } from './const'; +import { encodeAsSS58, decodeFromSS58 } from "../../utils/ss58"; +import { isHex } from "../../utils/bytes"; +import { TypedBytes, TypedUUID, sized, withQualifier } from "../generic"; +import { CheqdBlobQualifier, DockBlobQualifier } from "./const"; +import { CheqdMainnetDid, CheqdTestnetDid, DIDRef } from "../did"; -export class BlobId extends withQualifier(TypedBytes) { - static Qualifier = DockBlobQualifier; +export class CheqdBlobId extends DIDRef { + static Qualifier = CheqdBlobQualifier; - static fromUnqualifiedString(bytes) { - return new this(isHex(bytes) ? bytes : decodeFromSS58(bytes)); - } + static Ident = TypedUUID; toEncodedString() { - return encodeAsSS58(this.value); + let prefix = ""; + if (this[0].value instanceof CheqdTestnetDid) { + prefix = "testnet"; + } else if (this[0].value instanceof CheqdMainnetDid) { + prefix = "mainnet"; + } + + return `${prefix}:${this.value}`; } } -export class DockBlobId extends sized(BlobId) { +export class DockBlobId extends sized(withQualifier(TypedBytes)) { static Size = 32; -} -/* -export class BlobIdIdent extends withQualifier(TypedBytes) { static Qualifier = DockBlobQualifier; static fromUnqualifiedString(bytes) { @@ -31,34 +34,3 @@ export class BlobIdIdent extends withQualifier(TypedBytes) { return encodeAsSS58(this.value); } } - -export class BlobId extends IdentRef {} - -export class CheqdBlobIdIdent extends withFrom(sized(BlobIdIdent), (value, from) => value instanceof CheqdBlobId ? value[1]: from(value)) { - static Qualifier = DockBlobQualifier; - - static fromUnqualifiedString(bytes) { - return new this(bytes); - } - - toEncodedString() { - return this.value; - } -} - -export class CheqdBlobId extends BlobId { - static Ident = CheqdBlobIdIdent; -} - -export class DockBlobIdIdent extends withFrom(sized(BlobIdIdent), (value, from) => value instanceof DockBlobId ? value[1]: from(value)) { - static Size = 32; -} - -export class DockBlobId extends BlobId { - static Ident = DockBlobIdIdent; -} - -export class DockBlobId extends sized(BlobId) { - static Size = 32; -} -*/ diff --git a/packages/credential-sdk/src/types/blob/blob.js b/packages/credential-sdk/src/types/blob/blob.js index d62e0cd3e..a777a8dc3 100644 --- a/packages/credential-sdk/src/types/blob/blob.js +++ b/packages/credential-sdk/src/types/blob/blob.js @@ -37,6 +37,10 @@ export default class Blob extends TypedBytes { return new this(value); } + toUTF8String() { + return u8aToString(this); + } + toObject() { try { return JSON.parse(u8aToString(this.bytes)); diff --git a/packages/credential-sdk/src/types/blob/const.js b/packages/credential-sdk/src/types/blob/const.js index 1a559584e..b2595e0b9 100644 --- a/packages/credential-sdk/src/types/blob/const.js +++ b/packages/credential-sdk/src/types/blob/const.js @@ -1,2 +1,4 @@ export const DockBlobQualifier = 'blob:dock:'; +export const CheqdBlobQualifier = 'blob:cheqd:'; export const DockBlobIdByteSize = 32; +export const CheqdBlobIdByteSize = 16; diff --git a/packages/credential-sdk/src/types/blob/index.js b/packages/credential-sdk/src/types/blob/index.js index 1db3c6ceb..0b697ea7e 100644 --- a/packages/credential-sdk/src/types/blob/index.js +++ b/packages/credential-sdk/src/types/blob/index.js @@ -1,5 +1,5 @@ -import { TypedStruct } from '../generic'; -import { BlobId } from './blob-id'; +import { Any, TypedStruct, withProp } from '../generic'; +import { CheqdBlobId, DockBlobId } from './blob-id'; import Blob from './blob'; export * from './blob-id'; @@ -7,7 +7,10 @@ export { default as Blob } from './blob'; export class BlobWithId extends TypedStruct { static Classes = { - id: BlobId, + id: Any, blob: Blob, }; } + +export class CheqdBlobWithId extends withProp(BlobWithId, 'id', CheqdBlobId) {} +export class DockBlobWithId extends withProp(BlobWithId, 'id', DockBlobId) {} diff --git a/packages/credential-sdk/src/types/did/document.js b/packages/credential-sdk/src/types/did/document.js index bf2a24406..13dbe9bc8 100644 --- a/packages/credential-sdk/src/types/did/document.js +++ b/packages/credential-sdk/src/types/did/document.js @@ -1,6 +1,6 @@ -import { base58btc } from 'multiformats/bases/base58'; -import varint from 'varint'; -import bs58 from 'bs58'; +import { base58btc } from "multiformats/bases/base58"; +import varint from "varint"; +import bs58 from "bs58"; import { Null, TypedArray, @@ -15,33 +15,45 @@ import { option, withFrom, withQualifier, -} from '../generic'; -import { LinkedDomains } from './offchain'; -import { NamespaceDid } from './onchain/typed-did'; -import { DidKey, DidKeyValue, DidKeys } from './onchain/did-key'; -import { VerificationRelationship } from './onchain/verification-relationship'; +} from "../generic"; +import { LinkedDomains } from "./offchain"; +import { NamespaceDid } from "./onchain/typed-did"; +import { DidKey, DidKeyValue, DidKeys } from "./onchain/did-key"; +import { VerificationRelationship } from "./onchain/verification-relationship"; import { EcdsaSecp256k1VerKeyName, Ed255192020VerKeyName, Ed25519VerKeyName, Sr25519VerKeyName, -} from '../../vc/custom_crypto'; +} from "../../vc/custom_crypto"; import { PublicKeyEd25519, PublicKeySecp256k1, PublicKeySr25519, -} from '../public-keys'; +} from "../public-keys"; import { fmtIter, isBytes, stringToU8a, u8aToString, + valueBytes, withExtendedStaticProperties, -} from '../../utils'; +} from "../../utils"; +import { + BBDT16PublicKey, + BBDT16PublicKeyValue, + BBSPlusPublicKey, + BBSPlusPublicKeyValue, + BBSPublicKey, + BBSPublicKeyValue, + PSPublicKey, + PSPublicKeyValue, +} from "../offchain-signatures"; -export const ATTESTS_IRI = 'https://rdf.dock.io/alpha/2021#attestsDocumentContents'; +export const ATTESTS_IRI = + "https://rdf.dock.io/alpha/2021#attestsDocumentContents"; -export const CONTEXT_URI = 'https://www.w3.org/ns/did/v1'; +export const CONTEXT_URI = "https://www.w3.org/ns/did/v1"; class Context extends TypedArray { static Class = TypedString; @@ -61,47 +73,47 @@ class VerificationMethodType extends TypedEnum {} class Ed25519Verification2018Method extends VerificationMethodType { static Class = Null; - static Type = 'Ed25519VerificationKey2018'; + static Type = "Ed25519VerificationKey2018"; } class Ed25519Verification2020Method extends VerificationMethodType { static Class = Null; - static Type = 'Ed25519VerificationKey2020'; + static Type = "Ed25519VerificationKey2020"; } class Sr25519Verification2020Method extends VerificationMethodType { static Class = Null; - static Type = 'Sr25519VerificationKey2020'; + static Type = "Sr25519VerificationKey2020"; } class EcdsaSecp256k1VerificationKey2019 extends VerificationMethodType { static Class = Null; - static Type = 'EcdsaSecp256k1VerificationKey2019'; + static Type = "EcdsaSecp256k1VerificationKey2019"; } class X25519KeyAgreementKey2019 extends VerificationMethodType { static Class = Null; - static Type = 'X25519KeyAgreementKey2019'; + static Type = "X25519KeyAgreementKey2019"; } class Bls12381G2VerificationKeyDock2022 extends VerificationMethodType { static Class = Null; - static Type = 'Bls12381G2VerificationKeyDock2022'; + static Type = "Bls12381G2VerificationKeyDock2022"; } class Bls12381BBSVerificationKeyDock2023 extends VerificationMethodType { static Class = Null; - static Type = 'Bls12381BBSVerificationKeyDock2023'; + static Type = "Bls12381BBSVerificationKeyDock2023"; } class Bls12381BBDT16VerificationKeyDock2024 extends VerificationMethodType { static Class = Null; - static Type = 'Bls12381BBDT16VerificationKeyDock2024'; + static Type = "Bls12381BBDT16VerificationKeyDock2024"; } class Bls12381PSVerificationKeyDock2023 extends VerificationMethodType { static Class = Null; - static Type = 'Bls12381PSVerificationKeyDock2023'; + static Type = "Bls12381PSVerificationKeyDock2023"; } VerificationMethodType.bindVariants( Ed25519Verification2018Method, @@ -112,18 +124,19 @@ VerificationMethodType.bindVariants( Bls12381G2VerificationKeyDock2022, Bls12381BBSVerificationKeyDock2023, Bls12381BBDT16VerificationKeyDock2024, - Bls12381PSVerificationKeyDock2023, + Bls12381PSVerificationKeyDock2023 ); export class TypedNumberOrTypedString extends withFrom( TypedNumber, - (value, from) => (!Number.isNaN(Number(value)) || value instanceof TypedNumber - ? from(value) - : TypedString.from(value)), + (value, from) => + !Number.isNaN(Number(value)) || value instanceof TypedNumber + ? from(value) + : TypedString.from(value) ) {} export class VerificationMethodRef extends withQualifier(TypedTuple) { - static Qualifier = ''; + static Qualifier = ""; static Classes = [NamespaceDid, TypedNumber]; @@ -159,7 +172,7 @@ export class VerificationMethodRef extends withQualifier(TypedTuple) { } export class IdentRef extends withQualifier(TypedTuple) { - static Qualifier = ''; + static Qualifier = ""; static Ident = TypedString; @@ -210,14 +223,14 @@ export class VerificationMethodRefOrIdentRef extends withFrom( } catch { return IdentRef.from(value); } - }, + } ) {} export class DidKeyValueWithRef extends withFrom( TypedStruct, function (value, from) { - if (typeof value === 'string') { - const [ref, key] = value.split('='); + if (typeof value === "string") { + const [ref, key] = value.split("="); // eslint-disable-next-line no-use-before-define const parsed = JSON.parse(u8aToString(new PublicKeyBase58(key).bytes)); @@ -225,13 +238,23 @@ export class DidKeyValueWithRef extends withFrom( } else { return from(value); } - }, + } ) { static Classes = { ref: VerificationMethodRef, key: DidKeyValue, }; + toVerificationMethod() { + // eslint-disable-next-line no-use-before-define + return new VerificationMethod( + this.ref, + this.key.constructor.VerKeyType, + this.ref.did, + this.key.value.bytes + ); + } + toJSON() { const { ref, key } = this; @@ -250,12 +273,12 @@ export class VerificationMethodRefOrKey extends withFrom( } catch (err) { return from(value); } - }, + } ) {} export class PublicKeyBase58 extends TypedString { constructor(value) { - if (typeof value === 'string') { + if (typeof value === "string") { // Decoding base58 if the input is a string super(bs58.decode(value)); } else { @@ -272,15 +295,15 @@ export class PublicKeyBase58 extends TypedString { } export class PublicKeyMultibase extends withExtendedStaticProperties( - ['Prefix'], - TypedString, + ["Prefix"], + TypedString ) { // Define the static prefix as a class variable static Prefix; constructor(value) { - if (typeof value === 'string') { - if (value.startsWith('z')) { + if (typeof value === "string") { + if (value.startsWith("z")) { // Decode base58btc multibase string const decoded = base58btc.decode(value); varint.decode(decoded); // Decode to get byte length @@ -320,7 +343,7 @@ export class CheqdEd25519Key extends PublicKeyMultibase { export class PublicKeyBase64 extends TypedString { constructor(value) { - if (typeof value === 'string') { + if (typeof value === "string") { super(atob(value)); } else { super(value); @@ -333,9 +356,11 @@ export class PublicKeyBase64 extends TypedString { } // eslint-disable-next-line no-use-before-define -export class VerificationMethod extends withFrom(TypedStruct, (value, from) => (value instanceof CheqdVerificationMethod - ? value.toVerificationMethod() - : from(value))) { +export class VerificationMethod extends withFrom(TypedStruct, (value, from) => + value instanceof CheqdVerificationMethod + ? value.toVerificationMethod() + : from(value) +) { static Classes = { id: VerificationMethodRef, type: VerificationMethodType, @@ -346,43 +371,52 @@ export class VerificationMethod extends withFrom(TypedStruct, (value, from) => ( publicKeyHex: option(TypedBytes), }; + isOffchain() { + return !( + this.type instanceof Ed25519Verification2018Method || + this.type instanceof Ed25519Verification2020Method + ); + } + publicKey() { const bytes = ( - this.publicKeyBase58 - || this.publicKeyBase64 - || this.publicKeyJwk - || this.publicKeyHex + this.publicKeyBase58 || + this.publicKeyBase64 || + this.publicKeyJwk || + this.publicKeyHex )?.bytes; + if (bytes == null) { throw new Error( `Expected either of ${fmtIter([ - 'publicKeyBase58', - 'publicKeyBase64', - 'publicKeyJwk', - 'publicKeyHex', - ])} to be specified`, + "publicKeyBase58", + "publicKeyBase64", + "publicKeyJwk", + "publicKeyHex", + ])} to be specified` ); } - let PublicKey; switch (this.type.type) { case Ed25519VerKeyName: - PublicKey = PublicKeyEd25519; - break; + return new PublicKeyEd25519(bytes); case Sr25519VerKeyName: - PublicKey = PublicKeySr25519; - break; + return new PublicKeySr25519(bytes); case Ed255192020VerKeyName: - PublicKey = PublicKeyEd25519; - break; + return new PublicKeyEd25519(bytes); case EcdsaSecp256k1VerKeyName: - PublicKey = PublicKeySecp256k1; - break; + return new PublicKeySecp256k1(bytes); + case Bls12381G2VerificationKeyDock2022.Type: + return new BBSPlusPublicKey(new BBSPlusPublicKeyValue(bytes)); + case Bls12381BBSVerificationKeyDock2023.Type: + return new BBSPublicKey(new BBSPublicKeyValue(bytes)); + case Bls12381PSVerificationKeyDock2023.Type: + return new PSPublicKey(new PSPublicKeyValue(bytes)); + case Bls12381BBDT16VerificationKeyDock2024.Type: + return new BBDT16PublicKey(new BBDT16PublicKeyValue(bytes)); default: throw new Error(`Unknown key type ${this.type.type}`); } - - return new PublicKey(bytes); } static fromDidKey(keyRef, didKey) { @@ -392,7 +426,7 @@ export class VerificationMethod extends withFrom(TypedStruct, (value, from) => ( ref, didKey.publicKey.constructor.VerKeyType, ref[0], - didKey.publicKey.value, + valueBytes(didKey.publicKey) ); } @@ -402,16 +436,21 @@ export class VerificationMethod extends withFrom(TypedStruct, (value, from) => ( this.id, this.controller, this.type, - this.publicKey().value.bytes, + valueBytes(this.publicKey()) ); } + + toDidKeyValueWithRef() { + return new DidKeyValueWithRef(this.id, this.publicKey()); + } } export class CheqdVerificationMethod extends withFrom( TypedStruct, - (value, from) => (value instanceof VerificationMethod - ? value.toCheqdVerificationMethod() - : from(value)), + (value, from) => + value instanceof VerificationMethod + ? value.toCheqdVerificationMethod() + : from(value) ) { static Classes = { id: VerificationMethodRef, @@ -420,12 +459,19 @@ export class CheqdVerificationMethod extends withFrom( verificationMaterial: PublicKeyBase58, }; + isOffchain() { + return !( + this.verificationMethodType instanceof Ed25519Verification2018Method || + this.verificationMethodType instanceof Ed25519Verification2020Method + ); + } + toVerificationMethod() { return new VerificationMethod( this.id, this.verificationMethodType, this.controller, - this.verificationMaterial, + this.verificationMaterial ); } } @@ -438,7 +484,8 @@ export class ServiceEndpointId extends IdentRef {} export class SuffixServiceEndpointId extends withFrom( TypedString, - (value, from) => from(isBytes(value) ? value : ServiceEndpointId.from(value)[1]), + (value, from) => + from(isBytes(value) ? value : ServiceEndpointId.from(value)[1]) ) {} export class Service extends TypedStruct { @@ -460,7 +507,9 @@ export class Service extends TypedStruct { } } -export class CheqdService extends withFrom(TypedStruct, (value, from) => (value instanceof Service ? value.toCheqdService() : from(value))) { +export class CheqdService extends withFrom(TypedStruct, (value, from) => + value instanceof Service ? value.toCheqdService() : from(value) +) { static Classes = { id: ServiceEndpointId, serviceType: LinkedDomains, @@ -490,14 +539,14 @@ class AssertionMethod extends TypedArray { export class DIDDocument extends TypedStruct { static Classes = { - '@context': Context, + "@context": Context, id: ID, alsoKnownAs: option(AlsoKnownAs), controller: Controllers, verificationMethod: VerificationMethods, service: option(Services), authentication: option(VerificationMethodReferences), - assertionMethod: option(AssertionMethod), + assertionMethod: option(VerificationMethodReferences), keyAgreement: option(VerificationMethodReferences), capabilityInvocation: option(VerificationMethodReferences), capabilityDelegation: option(VerificationMethodReferences), @@ -506,7 +555,7 @@ export class DIDDocument extends TypedStruct { static create( did, - keys, + keys = [], controllers = [], serviceEndpoints = {}, { @@ -514,9 +563,9 @@ export class DIDDocument extends TypedStruct { alsoKnownAs = [], capabilityDelegation = [], [ATTESTS_IRI]: attests = null, - } = {}, + } = {} ) { - const obj = new this( + const doc = new this( context, did, alsoKnownAs, @@ -528,48 +577,53 @@ export class DIDDocument extends TypedStruct { [], [], capabilityDelegation, - attests, + attests ); let idx = 0; + let selfControlled = false; for (const key of keys) { - obj.addKey([did, ++idx], key); + const didKey = DidKey.from(key); + doc.addKey([did, ++idx], didKey); + + selfControlled ||= didKey.verRels.isAuthentication(); } for (const [id, serviceEndpoint] of Object.entries(serviceEndpoints)) { - obj.addServiceEndpoint([did, id], serviceEndpoint); + doc.addServiceEndpoint([did, id], serviceEndpoint); + } + if (selfControlled && !doc.controller.find((ctrl) => ctrl.eq(did))) { + doc.addController(did); } - return obj; + return doc; } addKey(keyRef, didKey) { const ref = VerificationMethodRef.from(keyRef); const key = DidKey.from(didKey); - const isVerificationMethod = key.publicKey.constructor.VerificationMethod; - const refOrKey = isVerificationMethod - ? ref - : new DidKeyValueWithRef(keyRef, key.publicKey); + + if (this.verificationMethod.find((existing) => existing.eq(ref))) { + throw new Error(`Verification method \`${ref}\` already exists`); + } if (key.verRels.isAuthentication()) { this.authentication ||= []; - this.authentication.push(refOrKey); + this.authentication.push(ref); } if (key.verRels.isAssertion()) { this.assertionMethod ||= []; - this.assertionMethod.push(refOrKey); + this.assertionMethod.push(ref); } if (key.verRels.isKeyAgreement()) { this.keyAgreement ||= []; - this.keyAgreement.push(refOrKey); + this.keyAgreement.push(ref); } if (key.verRels.isCapabilityInvocation()) { this.capabilityInvocation ||= []; - this.capabilityInvocation.push(refOrKey); + this.capabilityInvocation.push(ref); } - if (isVerificationMethod) { - this.verificationMethod.push(VerificationMethod.fromDidKey(keyRef, key)); - } + this.verificationMethod.push(VerificationMethod.fromDidKey(ref, key)); return this; } @@ -600,11 +654,15 @@ export class DIDDocument extends TypedStruct { removeKey(keyRef) { const ref = VerificationMethodRef.from(keyRef); - const keyIndex = this.verificationMethod.findIndex((method) => method.id.eq(ref)); + const keyIndex = this.verificationMethod.findIndex((method) => + method.id.eq(ref) + ); // eslint-disable-next-line no-bitwise if (~keyIndex) { this.verificationMethod.splice(keyIndex, 1); + } else { + throw new Error(`Verification method with id \`${ref}\` doesn't exist`); } const isNotRef = (value) => !(value.ref ?? value).eq(ref); @@ -618,6 +676,15 @@ export class DIDDocument extends TypedStruct { return this; } + nextKeyIndex() { + return ( + [...this.verificationMethod].reduce( + (max, { id: { index } }) => Math.max(max, index ?? 0), + 0 + ) + 1 + ); + } + get attests() { return this[ATTESTS_IRI]; } @@ -626,8 +693,12 @@ export class DIDDocument extends TypedStruct { return this.verificationMethod; } - setAttests(iri) { + set attests(iri) { this[ATTESTS_IRI] = iri; + } + + setAttests(iri) { + this.attests = iri; return this; } @@ -668,11 +739,6 @@ export class DIDDocument extends TypedStruct { return [method.id, new DidKey(method.publicKey(), verRels)]; }) - .concat( - [...assertionMethod] - .filter((v) => v instanceof DidKeyValueWithRef) - .map((v) => [v.ref, new DidKey(v.key)]), - ) .filter(Boolean); return new DidKeys(keys); @@ -680,7 +746,7 @@ export class DIDDocument extends TypedStruct { toCheqd(versionId = TypedUUID.random()) { const { - '@context': context, + "@context": context, id, alsoKnownAs, controller, @@ -706,7 +772,7 @@ export class DIDDocument extends TypedStruct { keyAgreement, capabilityInvocation, capabilityDelegation, - versionId, + versionId ); } } @@ -731,6 +797,24 @@ export class CheqdDIDDocument extends TypedStruct { versionId: option(VersionId), }; + constructor(...args) { + super(...args); + + const offchainVerMethod = [ + ...this.verificationMethod.filter((verMethod) => verMethod.isOffchain()), + ].map((verMethod) => verMethod.toVerificationMethod()); + this.verificationMethod = this.verificationMethod.filter( + (verMethod) => !verMethod.isOffchain() + ); + + this.assertionMethod = [ + ...this.assertionMethod, + ...[...offchainVerMethod].map((verMethod) => + verMethod.toDidKeyValueWithRef() + ), + ]; + } + toDIDDocument() { const { context, @@ -746,19 +830,28 @@ export class CheqdDIDDocument extends TypedStruct { service, } = this; + const offchainVerMethod = [ + ...assertionMethod.filter( + (keyRefOrKey) => keyRefOrKey instanceof DidKeyValueWithRef + ), + ].map((verMethod) => verMethod.toVerificationMethod()); + const assertionMethodWithoutOffchainKeys = assertionMethod.filter( + (keyRefOrKey) => !(keyRefOrKey instanceof DidKeyValueWithRef) + ); + return new DIDDocument( context, id, alsoKnownAs, controller, - verificationMethod, + [...verificationMethod, ...offchainVerMethod], service, authentication, - assertionMethod, + assertionMethodWithoutOffchainKeys, keyAgreement, capabilityInvocation, capabilityDelegation, - null, + null ); } } diff --git a/packages/credential-sdk/src/types/did/onchain/did-key.js b/packages/credential-sdk/src/types/did/onchain/did-key.js index 6d99abbee..348c01853 100644 --- a/packages/credential-sdk/src/types/did/onchain/did-key.js +++ b/packages/credential-sdk/src/types/did/onchain/did-key.js @@ -43,8 +43,6 @@ export class DidKeyEd25519PublicKey extends DidKeyValue { static Type = 'ed25519'; static Class = PublicKeyEd25519Value; - - static VerificationMethod = true; } /** * Class representing Secp256k1 PublicKey @@ -55,8 +53,6 @@ export class DidKeySecp256k1PublicKey extends DidKeyValue { static Type = 'secp256k1'; static Class = PublicKeySecp256k1Value; - - static VerificationMethod = true; } /** * Class representing Sr25519 PublicKey @@ -67,8 +63,6 @@ export class DidKeySr25519PublicKey extends DidKeyValue { static Type = 'sr25519'; static Class = PublicKeySr25519Value; - - static VerificationMethod = true; } /** * Class representing X25519 PublicKey @@ -79,8 +73,6 @@ export class DidKeyX25519PublicKey extends DidKeyValue { static Type = 'x25519'; static Class = PublicKeyX25519Value; - - static VerificationMethod = true; } export class DidKeyBBSPublicKey extends DidKeyValue { static Class = BBSPublicKeyValue; @@ -88,8 +80,6 @@ export class DidKeyBBSPublicKey extends DidKeyValue { static Type = 'bbs'; static VerKeyType = Bls12381BBS23DockVerKeyName; - - static VerificationMethod = false; } export class DidKeyBBSPlusPublicKey extends DidKeyValue { static Class = BBSPlusPublicKeyValue; @@ -97,8 +87,6 @@ export class DidKeyBBSPlusPublicKey extends DidKeyValue { static Type = 'bbsPlus'; static VerKeyType = Bls12381BBSDockVerKeyName; - - static VerificationMethod = false; } export class DidKeyPSPublicKey extends DidKeyValue { static Class = PSPublicKeyValue; @@ -106,8 +94,6 @@ export class DidKeyPSPublicKey extends DidKeyValue { static Type = 'ps'; static VerKeyType = Bls12381PSDockVerKeyName; - - static VerificationMethod = false; } DidKeyValue.bindVariants( @@ -170,6 +156,10 @@ export class DidKey extends TypedStruct { static fromKeypair(keyPair, verRels) { return new this(keyPair.publicKey(), verRels); } + + isOffchain() { + return Assertion.some((klass) => this.publicKey instanceof klass); + } } export class DidKeysList extends TypedArray { diff --git a/packages/credential-sdk/src/types/did/onchain/index.js b/packages/credential-sdk/src/types/did/onchain/index.js index 411dbcafa..f540c6a2b 100644 --- a/packages/credential-sdk/src/types/did/onchain/index.js +++ b/packages/credential-sdk/src/types/did/onchain/index.js @@ -1,12 +1,11 @@ -import { Null, TypedNumber, TypedStruct } from '../../generic'; - -export * from './utils'; -export * from './constants'; -export * from './typed-did'; -export * from './controllers'; -export * from './verification-relationship'; -export * from './did-key'; -export * from './verification-method-signature'; +import { Null, TypedNumber, TypedStruct } from "../../generic"; + +export * from "./constants"; +export * from "./typed-did"; +export * from "./controllers"; +export * from "./verification-relationship"; +export * from "./did-key"; +export * from "./verification-method-signature"; export class DidMethodKeyDetails extends TypedStruct { static Classes = { diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/cheqd-did.js b/packages/credential-sdk/src/types/did/onchain/typed-did/cheqd-did.js index 4fcc76a78..590db16ea 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/cheqd-did.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/cheqd-did.js @@ -2,9 +2,9 @@ import { CheqdDIDQualifier, CheqdDIDTestnetQualifier, CheqdDIDMainnetQualifier, -} from '../constants'; -import { TypedEnum, withQualifier } from '../../../generic'; -import TypedUUID from '../../../generic/typed-uuid'; +} from "../constants"; +import { TypedEnum, withQualifier } from "../../../generic"; +import TypedUUID from "../../../generic/typed-uuid"; /** * `did:cheqd:*` @@ -42,17 +42,12 @@ export class CheqdDid extends withQualifier(TypedEnum, true) { export class CheqdTestnetDid extends CheqdDid { static Class = CheqdTestnetDidValue; - static Type = 'testnet'; + static Type = "testnet"; } export class CheqdMainnetDid extends CheqdDid { static Class = CheqdMainnetDidValue; - static Type = 'mainnet'; + static Type = "mainnet"; } -export class CheqdGenericDid extends CheqdDid { - static Class = CheqdDidValue; - static Type = 'generic'; -} - -CheqdDid.bindVariants(CheqdTestnetDid, CheqdMainnetDid, CheqdGenericDid); +CheqdDid.bindVariants(CheqdTestnetDid, CheqdMainnetDid); diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-public-key.js b/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-public-key.js index d48356ee0..164b79208 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-public-key.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-public-key.js @@ -1,23 +1,25 @@ -import bs58 from 'bs58'; -import { base58btc } from 'multiformats/bases/base58'; -import varint from 'varint'; -import { TypedEnum, withQualifier } from '../../../../generic'; +import bs58 from "bs58"; +import { base58btc } from "multiformats/bases/base58"; +import varint from "varint"; +import { TypedEnum, TypedStruct, withQualifier } from "../../../../generic"; import { PublicKeyEd25519Value, PublicKeySecp256k1Value, -} from '../../../../public-keys'; +} from "../../../../public-keys"; import { DidMethodKeyBytePrefixEd25519, DidMethodKeyBytePrefixSecp256k1, DidMethodKeyQualifier, Ed25519PublicKeyPrefix, Secp256k1PublicKeyPrefix, -} from '../../constants'; +} from "../../constants"; +import DidOrDidMethodKeySignature from "../signature"; +import { DidMethodKeySignatureValue } from "./did-method-key-signature"; export class DidMethodKeyPublicKey extends withQualifier(TypedEnum) { static Qualifier = DidMethodKeyQualifier; - static Type = 'didMethodKey'; + static Type = "didMethodKey"; /** * Instantiates `DidMethodKey` from a fully qualified did string. @@ -71,18 +73,30 @@ export class DidMethodKeyPublicKey extends withQualifier(TypedEnum) { signWith(keyPair, bytes) { if (!this.eq(this.constructor.fromKeypair(keyPair))) { - throw new Error('Expected keypair that has the same key as in `this`'); + throw new Error("Expected keypair that has the same key as in `this`"); } - return { - didMethodKeySignature: { - didMethodKey: this, - sig: keyPair.sign(bytes), - }, - }; + // eslint-disable-next-line no-use-before-define + return new DidMethodKeySignature( + // eslint-disable-next-line no-use-before-define + new DidMethodKeySignatureValueObject(this, keyPair.sign(bytes)) + ); } } +export class DidMethodKeySignatureValueObject extends TypedStruct { + static Classes = { + didMethodKey: DidMethodKeyPublicKey, + sig: DidMethodKeySignatureValue, + }; +} + +export class DidMethodKeySignature extends DidOrDidMethodKeySignature { + static Type = "didMethodKeySignature"; + + static Class = DidMethodKeySignatureValueObject; +} + export class DidMethodKeyPublicKeyEd25519 extends DidMethodKeyPublicKey { static Class = PublicKeyEd25519Value; @@ -100,5 +114,5 @@ export class DidMethodKeyPublicKeySecp256k1 extends DidMethodKeyPublicKey { DidMethodKeyPublicKey.bindVariants( DidMethodKeyPublicKeyEd25519, - DidMethodKeyPublicKeySecp256k1, + DidMethodKeyPublicKeySecp256k1 ); diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-signature.js b/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-signature.js index 22684ffc3..6cde4521b 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-signature.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-signature.js @@ -1,18 +1,18 @@ -import { TypedEnum } from '../../../../generic'; +import { TypedEnum } from "../../../../generic"; import { SignatureEd25519Value, SignatureSecp256k1Value, -} from '../../../../signatures'; +} from "../../../../signatures"; -export class DidMethodKeySignature extends TypedEnum {} -export class DidMethodKeySignatureEd25519 extends DidMethodKeySignature { +export class DidMethodKeySignatureValue extends TypedEnum {} +export class DidMethodKeySignatureValueEd25519 extends DidMethodKeySignatureValue { static Class = SignatureEd25519Value; } -export class DidMethodKeySignatureSecp256k1 extends DidMethodKeySignature { +export class DidMethodKeySignatureValueSecp256k1 extends DidMethodKeySignatureValue { static Class = SignatureSecp256k1Value; } -DidMethodKeySignature.bindVariants( - DidMethodKeySignatureEd25519, - DidMethodKeySignatureSecp256k1, +DidMethodKeySignatureValue.bindVariants( + DidMethodKeySignatureValueEd25519, + DidMethodKeySignatureValueSecp256k1 ); diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/dock-did-value.js b/packages/credential-sdk/src/types/did/onchain/typed-did/dock-did-value.js index 5362dee57..1225d2e14 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/dock-did-value.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/dock-did-value.js @@ -1,6 +1,14 @@ -import { DockDIDQualifier } from '../constants'; -import { decodeFromSS58, encodeAsSS58, isHex } from '../../../../utils'; -import { withQualifier, TypedBytes, sized } from '../../../generic'; +import { DockDIDQualifier } from "../constants"; +import { decodeFromSS58, encodeAsSS58, isHex } from "../../../../utils"; +import { + withQualifier, + TypedBytes, + sized, + TypedNumber, + TypedStruct, +} from "../../../generic"; +import DidOrDidMethodKeySignature from "./signature"; +import { Signature } from "../../../signatures"; /** * `did:dock:*` @@ -8,7 +16,7 @@ import { withQualifier, TypedBytes, sized } from '../../../generic'; export default class DockDidValue extends sized(withQualifier(TypedBytes)) { static Qualifier = DockDIDQualifier; - static Type = 'did'; + static Type = "did"; static Size = 32; @@ -24,12 +32,23 @@ export default class DockDidValue extends sized(withQualifier(TypedBytes)) { } signWith(keyPair, bytes) { - return { - didSignature: { - did: this, - keyId: keyPair.keyId, - sig: keyPair.sign(bytes), - }, - }; + // eslint-disable-next-line no-use-before-define + return new DockDidSignature( + new DockDidSignatureValue(this, keyPair.keyId, keyPair.sign(bytes)) + ); } } + +export class DockDidSignatureValue extends TypedStruct { + static Classes = { + did: DockDidValue, + keyId: class KeyId extends TypedNumber {}, + sig: Signature, + }; +} + +export class DockDidSignature extends DidOrDidMethodKeySignature { + static Type = "didSignature"; + + static Class = DockDidSignatureValue; +} diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/index.js b/packages/credential-sdk/src/types/did/onchain/typed-did/index.js index a76be7329..0cbc11b17 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/index.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/index.js @@ -1,7 +1,9 @@ -import { DidMethodKeyPublicKey } from './did-method-key'; -import DockDidValue from './dock-did-value'; -import { TypedEnum, withQualifier } from '../../../generic'; -import { CheqdDid } from './cheqd-did'; +import { DidMethodKeyPublicKey, DidMethodKeySignature } from "./did-method-key"; +import DockDidValue, { DockDidSignature } from "./dock-did-value"; +import { TypedEnum, TypedTuple, withQualifier } from "../../../generic"; +import { CheqdDid } from "./cheqd-did"; +import { withExtendedStaticProperties } from "../../../../utils"; +import DidOrDidMethodKeySignature from "./signature"; export const DockDidOrDidMethodKey = withQualifier( class DockDidOrDidMethodKey extends TypedEnum { @@ -19,20 +21,17 @@ export const DockDidOrDidMethodKey = withQualifier( /** * Creates signature for the state change with supplied arguments. * - * @param api + * @param apiProvider * @param name * @param payload * @param keyRef * @returns {object} */ async signStateChange(apiProvider, name, payload, keyRef) { - // eslint-disable-next-line no-param-reassign - payload.nonce ??= 1 + (await apiProvider.nonce(this)); - if ( - Number(process.env.LOG_STATE_CHANGE) - || Boolean(process.env.LOG_STATE_CHANGE) - ) { - console.log('State change:', name, '=>', payload); + const { LOG_STATE_CHANGE } = process.env; + + if (Number(LOG_STATE_CHANGE) || Boolean(LOG_STATE_CHANGE)) { + console.dir(payload, { depth: null }); } const bytes = await apiProvider.stateChangeBytes(name, payload); @@ -49,8 +48,10 @@ export const DockDidOrDidMethodKey = withQualifier( * @param keyRef */ async changeState(api, method, name, payload, keyRef) { - const signature = await this.signStateChange(api, name, payload, keyRef); - return await method(payload, signature); + return await method( + payload, + await this.signStateChange(api, name, payload, keyRef) + ); } toString() { @@ -82,7 +83,7 @@ export const DockDidOrDidMethodKey = withQualifier( } } }, - true, + true ); export class DockDid extends DockDidOrDidMethodKey { @@ -145,30 +146,80 @@ export const NamespaceDid = withQualifier( return super.from( value instanceof DockDidOrDidMethodKey && value.isDid ? { dock: value.asDid } - : value, + : value ); } }, - true, + true ); class DockNamespaceDid extends NamespaceDid { - static Type = 'dock'; + static Type = "dock"; static Class = DockDidValueToString; } class DidNamespaceKey extends NamespaceDid { - static Type = 'didMethodKey'; + static Type = "didMethodKey"; static Class = DidMethodKeyPublicKeyToString; } class CheqdNamespaceDid extends NamespaceDid { - static Type = 'cheqd'; + static Type = "cheqd"; static Class = CheqdDid; } NamespaceDid.bindVariants(DockNamespaceDid, DidNamespaceKey, CheqdNamespaceDid); +export class DIDRef extends withExtendedStaticProperties( + ["Ident"], + withQualifier(TypedTuple) +) { + static Qualifier = ""; + + static get Classes() { + return [NamespaceDid, this.Ident]; + } + + static random(did) { + return new this(did, this.Ident.random()); + } + + get did() { + return this[0]; + } + + get value() { + return this[1]; + } + + static fromUnqualifiedString(str) { + const regex = new RegExp(`^${this.Qualifier}([^#]+):(.+)$`); + const match = str.match(regex); + + if (!match) { + throw new Error(`Invalid format for DID reference: \`${str}\``); + } + + const [, did, value] = match; + return new this(did, value); + } + + toEncodedString() { + const { did, value } = this; + + return `${did}:${value}`; + } + + toJSON() { + return this.toString(); + } +} + +DidOrDidMethodKeySignature.bindVariants( + DockDidSignature, + DidMethodKeySignature +); + export { DockDidValue, DidMethodKeyPublicKey }; -export * from './cheqd-did'; +export * from "./cheqd-did"; diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/signature.js b/packages/credential-sdk/src/types/did/onchain/typed-did/signature.js new file mode 100644 index 000000000..3eea5507d --- /dev/null +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/signature.js @@ -0,0 +1,3 @@ +import { TypedEnum } from "../../../generic"; + +export default class DidOrDidMethodKeySignature extends TypedEnum {} diff --git a/packages/credential-sdk/src/types/did/onchain/utils.js b/packages/credential-sdk/src/types/did/onchain/utils.js deleted file mode 100644 index 36448e5a8..000000000 --- a/packages/credential-sdk/src/types/did/onchain/utils.js +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint-disable max-classes-per-file */ - -import { isHexWithGivenByteSize } from '../../../utils/bytes'; -import { - PublicKey, // eslint-disable-line -} from '../../public-keys'; - -import { Signature } from "../../signatures"; // eslint-disable-line - -import { DockDIDByteSize } from './constants'; - -/** - * Check if the given identifier is the hex representation of a Dock DID. - * @param {string} identifier - The identifier to check. - * @return {void} Throws exception if invalid identifier - */ -export function validateDockDIDHexIdentifier(identifier) { - // Byte size of the Dock DID identifier, i.e. the `DockDIDQualifier` is not counted. - if (!isHexWithGivenByteSize(identifier, DockDIDByteSize)) { - throw new Error(`DID identifier must be ${DockDIDByteSize} bytes`); - } -} - -/** - * Check if the given identifier is 32 byte valid SS58 string - * @param {string} identifier - The identifier to check. - * @return {void} Throws exception if invalid identifier - */ -export function validateDockDIDSS58Identifier(identifier) { - // base58-check regex - const regex = new RegExp(/^[5KL][1-9A-HJ-NP-Za-km-z]{47}$/); - const matches = regex.exec(identifier); - if (!matches) { - throw new Error('The identifier must be 32 bytes and valid SS58 string'); - } -} - -/** - * Returns a `DidKey` as expected by the Substrate node - * @param {PublicKey} publicKey - The public key for the DID. The Keyring is intentionally avoided here as it may not be - * accessible always, like in case of hardware wallet - * @param {VerificationRelationship} verRel - * @returns {object} - The object has structure and keys with same names as expected by the Substrate node - */ -export function createDidKey(publicKey, verRel) { - return { - publicKey: publicKey.toJSON(), - verRels: verRel.value, - }; -} - -/** - * - * @param {string|DockDidOrDidMethodKey} did - DID as string or an object - * @param {number} keyId - - * @param rawSig - * @param {Signature} sig - * @returns {object} - */ -export function createDidSig(did, { keyId }, rawSig) { - const sig = rawSig.toJSON(); - - if (did.isDid) { - return { - DidSignature: { - did: did.asDid, - keyId, - sig, - }, - }; - } else if (did.isDidMethodKey) { - return { - DidMethodKeySignature: { - didMethodKey: did.asDidMethodKey, - sig, - }, - }; - } else { - throw new Error( - `Incorrect DID passed: \`${did}\`, expected instance of either \`DockDid\` or \`DidMethodKey\``, - ); - } -} diff --git a/packages/credential-sdk/src/types/generic/typed-enum.js b/packages/credential-sdk/src/types/generic/typed-enum.js index 05bd0c508..fbd42a136 100644 --- a/packages/credential-sdk/src/types/generic/typed-enum.js +++ b/packages/credential-sdk/src/types/generic/typed-enum.js @@ -1,19 +1,19 @@ /* eslint-disable max-classes-per-file */ -import { fmtIter } from '../../utils/generic'; +import { fmtIter } from "../../utils/generic"; import { isEqualToOrPrototypeOf, withExtendedStaticProperties, -} from '../../utils/inheritance'; +} from "../../utils/inheritance"; import { maybeEq, maybeFrom, maybeNew, maybeToJSON, -} from '../../utils/interfaces'; -import withBase from './with-base'; -import Null from './typed-null'; -import withCatchNull from './with-catch-null'; -import withEq from './with-eq'; +} from "../../utils/interfaces"; +import withBase from "./with-base"; +import Null from "./typed-null"; +import withCatchNull from "./with-catch-null"; +import withEq from "./with-eq"; /** * @template V @@ -87,6 +87,22 @@ class TypedEnum extends withBase(class EnumBase {}) { }); const that = this; + + // TODO: revisit this + if (Class.Variants) { + const klassFrom = Class.from; + + for (const Variant of Class.Variants) { + Variant.from = function from(value) { + if (value instanceof that) { + return klassFrom.call(this, value[asIdentifier]); + } else { + return klassFrom.call(this, value); + } + }; + } + } + const klassFrom = Class.from; Class.from = function from(value) { if (value instanceof that) { @@ -181,17 +197,17 @@ class TypedEnum extends withBase(class EnumBase {}) { static fromJSON(json) { if (json == null) { throw new Error( - `Received \`null\` while object was expected by \`${this.name}\``, + `Received \`null\` while object was expected by \`${this.name}\`` ); } - if (typeof json === 'string' && this.isNullish) { + if (typeof json === "string" && this.isNullish) { if (this.Class != null) { if (this.JsonType === json || this.Type === json) { return maybeNew(this, []); } throw new Error( - `Unexpected json in \`${this}\`: \`${json}\`, expected \`${this.JsonType}\``, + `Unexpected json in \`${this}\`: \`${json}\`, expected \`${this.JsonType}\`` ); } else { for (const Variant of this.Variants) { @@ -202,8 +218,8 @@ class TypedEnum extends withBase(class EnumBase {}) { throw new Error( `Unexpected json in \`${this}\`: \`${json}\`, expected one of ${fmtIter( - new Set([...this.Variants].flatMap((v) => [v.JsonType, v.Type])), - )}`, + new Set([...this.Variants].flatMap((v) => [v.JsonType, v.Type])) + )}` ); } } @@ -212,8 +228,8 @@ class TypedEnum extends withBase(class EnumBase {}) { if (keys.length !== 1) { throw new Error( `Expected object with 1 key, received \`${json}\` with keys: ${fmtIter( - keys, - )} by ${this.name}`, + keys + )} by ${this.name}` ); } const [key] = keys; @@ -224,7 +240,7 @@ class TypedEnum extends withBase(class EnumBase {}) { } throw new Error( - `Unexpected key \`${key}\`, expected \`${this.JsonType}\` by \`${this.name}\``, + `Unexpected key \`${key}\`, expected \`${this.JsonType}\` by \`${this.name}\`` ); } else { for (const Variant of this.Variants) { @@ -235,8 +251,8 @@ class TypedEnum extends withBase(class EnumBase {}) { throw new Error( `Invalid key \`${key}\`, expected one of ${fmtIter( - new Set([...this.Variants].flatMap((v) => [v.JsonType, v.Type])), - )} by \`${this.name}\``, + new Set([...this.Variants].flatMap((v) => [v.JsonType, v.Type])) + )} by \`${this.name}\`` ); } } @@ -247,7 +263,7 @@ class TypedEnum extends withBase(class EnumBase {}) { return maybeNew(this, [obj[this.asIdentifier]]); } else { throw new Error( - `Incompatible value provided: \`${obj}\` to \`${this}\``, + `Incompatible value provided: \`${obj}\` to \`${this}\`` ); } } else { @@ -260,19 +276,23 @@ class TypedEnum extends withBase(class EnumBase {}) { throw new Error( `Invalid object received: \`${maybeToJSON( - obj, + obj )}\`, expected to build an instance of ${fmtIter( - this.Variants.map((v) => v.Type), - )} by \`${this.name}\``, + this.Variants.map((v) => v.Type) + )} by \`${this.name}\`` ); } static variant(obj) { - return this.Variants.find((variant) => isEqualToOrPrototypeOf(variant.Class, obj?.constructor ?? Null)); + return this.Variants.find((variant) => + isEqualToOrPrototypeOf(variant.Class, obj?.constructor ?? Null) + ); } static directVariant(obj) { - return this.Variants.find((variant) => isEqualToOrPrototypeOf(variant, obj?.constructor ?? Null)); + return this.Variants.find((variant) => + isEqualToOrPrototypeOf(variant, obj?.constructor ?? Null) + ); } static get isNullish() { @@ -284,7 +304,7 @@ class TypedEnum extends withBase(class EnumBase {}) { static from(obj) { if (obj instanceof this) { return obj; - } else if (typeof obj === 'string' && this.isNullish) { + } else if (typeof obj === "string" && this.isNullish) { return this.fromJSON(obj); } else if (Object.getPrototypeOf(obj) === Object.getPrototypeOf({})) { return this.fromJSON(obj); @@ -317,5 +337,5 @@ class TypedEnum extends withBase(class EnumBase {}) { } export default withEq( - withCatchNull(withExtendedStaticProperties(['Variants'], TypedEnum)), + withCatchNull(withExtendedStaticProperties(["Variants"], TypedEnum)) ); diff --git a/packages/credential-sdk/src/types/generic/typed-number.js b/packages/credential-sdk/src/types/generic/typed-number.js index dd58358e2..64798c95d 100644 --- a/packages/credential-sdk/src/types/generic/typed-number.js +++ b/packages/credential-sdk/src/types/generic/typed-number.js @@ -31,6 +31,18 @@ class TypedNumber extends withBase(class NumberBase {}) { return this.value; } + inc() { + this.value++; + + return this; + } + + dec() { + this.value--; + + return this; + } + static fromJSON(value) { return new this(value); } diff --git a/packages/credential-sdk/src/types/generic/typed-uuid.js b/packages/credential-sdk/src/types/generic/typed-uuid.js index 18530d786..19531e03f 100644 --- a/packages/credential-sdk/src/types/generic/typed-uuid.js +++ b/packages/credential-sdk/src/types/generic/typed-uuid.js @@ -1,9 +1,10 @@ import { parse, validate, stringify, v4, } from 'uuid'; -import TypedString from './typed-string'; +import TypedBytes from './typed-bytes'; +import { normalizeOrConvertStringToU8a } from '../../utils'; -export default class TypedUUID extends TypedString { +export default class TypedUUID extends TypedBytes { constructor(id) { super(validate(id) ? parse(id) : id); @@ -20,6 +21,26 @@ export default class TypedUUID extends TypedString { return this.value; } + static fromBytesAdapt(bytesOrString) { + let bytes = normalizeOrConvertStringToU8a(bytesOrString); + if (bytes.length < 16) { + const newBytes = new Uint8Array(16); + newBytes.set(bytes); + newBytes.fill(0, bytes.length); + + bytes = newBytes; + } else if (bytes.length > 16) { + bytes = bytes.slice(0, 16); + } + + // eslint-disable-next-line no-bitwise + bytes[6] = (bytes[6] & 0x0f) | 0x40; + // eslint-disable-next-line no-bitwise + bytes[8] = (bytes[8] & 0x3f) | 0x80; + + return new this(bytes); + } + static random() { return new this(v4()); } diff --git a/packages/credential-sdk/src/types/generic/with-qualifier.js b/packages/credential-sdk/src/types/generic/with-qualifier.js index 4c81b37fd..f158a0fd9 100644 --- a/packages/credential-sdk/src/types/generic/with-qualifier.js +++ b/packages/credential-sdk/src/types/generic/with-qualifier.js @@ -1,13 +1,13 @@ -import { ID_STR } from '@docknetwork/crypto-wasm-ts'; -import TypedBytes from './typed-bytes'; +import { ID_STR } from "@docknetwork/crypto-wasm-ts"; +import TypedBytes from "./typed-bytes"; import { withExtendedStaticProperties, withExtendedPrototypeProperties, -} from '../../utils/inheritance'; -import { maybeFrom } from '../../utils/interfaces'; -import withFrom from './with-from'; -import { fmtIter } from '../../utils'; -import TypedString from './typed-string'; +} from "../../utils/inheritance"; +import { maybeFrom } from "../../utils/interfaces"; +import withFrom from "./with-from"; +import { fmtIter } from "../../utils"; +import TypedString from "./typed-string"; /** * Extends supplied class. @@ -95,6 +95,10 @@ export default function withQualifier(klass, wrapper = false) { toString() { return this.value.toString(); } + + eq(other) { + return String(this) === String(other); + } }, }; @@ -165,6 +169,10 @@ export default function withQualifier(klass, wrapper = false) { toString() { return this.toQualifiedEncodedString(); } + + eq(other) { + return String(this) === String(other); + } }, }; diff --git a/packages/credential-sdk/src/types/offchain-signatures/params/index.js b/packages/credential-sdk/src/types/offchain-signatures/params/index.js index 858657de8..72547aa07 100644 --- a/packages/credential-sdk/src/types/offchain-signatures/params/index.js +++ b/packages/credential-sdk/src/types/offchain-signatures/params/index.js @@ -29,6 +29,11 @@ export class PSParams extends OffchainSignatureParams { static Class = PSParamsValue; } +export class BBDT16Params extends OffchainSignatureParams { + static Type = 'bbdt16'; + + static Class = BBDT16Params; +} OffchainSignatureParams.bindVariants(BBSParams, BBSPlusParams, PSParams); diff --git a/packages/credential-sdk/src/types/offchain-signatures/params/value.js b/packages/credential-sdk/src/types/offchain-signatures/params/value.js index 6e2d24f53..c6fa6e073 100644 --- a/packages/credential-sdk/src/types/offchain-signatures/params/value.js +++ b/packages/credential-sdk/src/types/offchain-signatures/params/value.js @@ -21,3 +21,6 @@ export class BBSPlusParamsValue extends OffchainSignatureParamsValue { export class PSParamsValue extends OffchainSignatureParamsValue { static Type = 'ps'; } +export class BBDT16ParamsValue extends OffchainSignatureParamsValue { + static Type = 'bbdt16'; +} diff --git a/packages/credential-sdk/src/types/offchain-signatures/public-keys/index.js b/packages/credential-sdk/src/types/offchain-signatures/public-keys/index.js index 668ea7079..1028a7cc5 100644 --- a/packages/credential-sdk/src/types/offchain-signatures/public-keys/index.js +++ b/packages/credential-sdk/src/types/offchain-signatures/public-keys/index.js @@ -1,4 +1,4 @@ -import { TypedEnum, withProp } from '../../generic'; +import { TypedEnum, option, withProp } from '../../generic'; import { Bls12381BBS23DockVerKeyName, Bls12381BBSDockVerKeyName, @@ -8,11 +8,13 @@ import { BBSPublicKeyValue, BBSPlusPublicKeyValue, PSPublicKeyValue, + BBDT16PublicKeyValue, } from './value'; import { CheqdOffchainSignatureParamsRef, DockOffchainSignatureParamsRef, } from './ref'; +import { Bls12381BBDT16DockVerKeyName } from '../../../vc/crypto/constants'; export class OffchainSignaturePublicKey extends TypedEnum { get bytes() { @@ -52,6 +54,13 @@ export class PSPublicKey extends OffchainSignaturePublicKey { static VerKeyType = Bls12381PSDockVerKeyName; } +export class BBDT16PublicKey extends OffchainSignaturePublicKey { + static Class = BBDT16PublicKeyValue; + + static type = 'bbdt16'; + + static VerKeyType = Bls12381BBDT16DockVerKeyName; +} OffchainSignaturePublicKey.bindVariants( BBSPublicKey, @@ -62,13 +71,13 @@ OffchainSignaturePublicKey.bindVariants( export class DockOffchainSignaturePublicKey extends withProp( OffchainSignaturePublicKey, 'paramsRef', - DockOffchainSignatureParamsRef, + option(DockOffchainSignatureParamsRef), ) {} export class CheqdOffchainSignaturePublicKey extends withProp( OffchainSignaturePublicKey, 'paramsRef', - CheqdOffchainSignatureParamsRef, + option(CheqdOffchainSignatureParamsRef), ) {} export * from './value'; diff --git a/packages/credential-sdk/src/types/offchain-signatures/public-keys/value.js b/packages/credential-sdk/src/types/offchain-signatures/public-keys/value.js index 4e0010d33..d6743769f 100644 --- a/packages/credential-sdk/src/types/offchain-signatures/public-keys/value.js +++ b/packages/credential-sdk/src/types/offchain-signatures/public-keys/value.js @@ -6,7 +6,9 @@ import { Any, } from '../../generic'; import { CurveType, CurveTypeBls12381 } from '../curve-type'; -import { BBSParams, BBSPlusParams, PSParams } from '../params'; +import { + BBDT16Params, BBSParams, BBSPlusParams, PSParams, +} from '../params'; export class OffchainSignaturePublicKeyValue extends TypedStruct { static Classes = { @@ -36,3 +38,6 @@ export class BBSPlusPublicKeyValue extends OffchainSignaturePublicKeyValue { export class PSPublicKeyValue extends OffchainSignaturePublicKeyValue { static Params = PSParams; } +export class BBDT16PublicKeyValue extends OffchainSignaturePublicKeyValue { + static Params = BBDT16Params; +} diff --git a/packages/credential-sdk/src/utils/bytes.js b/packages/credential-sdk/src/utils/bytes.js index 2198fc5dc..b5d0dd261 100644 --- a/packages/credential-sdk/src/utils/bytes.js +++ b/packages/credential-sdk/src/utils/bytes.js @@ -1,5 +1,5 @@ import { applyToValue } from './interfaces'; -import { ensureBytes, ensureString, ensureUint8Array } from './type-helpers'; +import { ensureBytes, ensureString } from './type-helpers'; /** * Check if the given input is hexadecimal or not. Optionally checks for the byte size of the hex. Case-insensitive on hex chars @@ -153,7 +153,7 @@ export const normalizeOrConvertStringToU8a = (bytesOrString) => (typeof bytesOrS */ export const valueBytes = (value) => applyToValue( (inner) => Array.isArray(inner) || inner instanceof Uint8Array || 'bytes' in inner, - (inner) => ensureUint8Array(inner.bytes ?? u8aToU8a(inner)), + (inner) => normalizeToU8a(inner.bytes ?? inner), value, ); diff --git a/packages/credential-sdk/src/utils/misc.js b/packages/credential-sdk/src/utils/misc.js index 6f719b7e1..2a372b2aa 100644 --- a/packages/credential-sdk/src/utils/misc.js +++ b/packages/credential-sdk/src/utils/misc.js @@ -18,10 +18,6 @@ export function getBytesForStateChange(api, stateChange) { return api.createType('StateChange', stateChange).toU8a(); } -export async function getDidNonce() { - throw new Error('Unimplemented'); -} - export function getStateChange(api, name, value) { const stateChange = {}; stateChange[name] = value; diff --git a/packages/credential-sdk/tests/__snapshots__/document.test.js.snap b/packages/credential-sdk/tests/__snapshots__/document.test.js.snap index 935618de3..d0c4bd6d2 100644 --- a/packages/credential-sdk/tests/__snapshots__/document.test.js.snap +++ b/packages/credential-sdk/tests/__snapshots__/document.test.js.snap @@ -20,6 +20,43 @@ exports[`\`DIDDocument\` \`DIDDocument.create\` works 1`] = ` `; exports[`\`DIDDocument\` \`DIDDocument.create\` works 2`] = ` +{ + "@context": [ + "https://www.w3.org/ns/did/v1", + ], + "alsoKnownAs": [], + "assertionMethod": [ + "did:cheqd:testnet:f1749383-d9dd-479f-82aa-e52fe8f59c54#keys-1", + ], + "authentication": [ + "did:cheqd:testnet:f1749383-d9dd-479f-82aa-e52fe8f59c54#keys-1", + ], + "capabilityDelegation": [], + "capabilityInvocation": [ + "did:cheqd:testnet:f1749383-d9dd-479f-82aa-e52fe8f59c54#keys-1", + ], + "controller": [ + "did:cheqd:testnet:f1749383-d9dd-479f-82aa-e52fe8f59c54", + ], + "https://rdf.dock.io/alpha/2021#attestsDocumentContents": null, + "id": "did:cheqd:testnet:f1749383-d9dd-479f-82aa-e52fe8f59c54", + "keyAgreement": [], + "service": [], + "verificationMethod": [ + { + "controller": "did:cheqd:testnet:f1749383-d9dd-479f-82aa-e52fe8f59c54", + "id": "did:cheqd:testnet:f1749383-d9dd-479f-82aa-e52fe8f59c54#keys-1", + "publicKeyBase58": "Bt5Mafvpcqou1pBF8SnW1BJMvpkSzZnPEgWunTUFwHZm", + "publicKeyBase64": null, + "publicKeyHex": null, + "publicKeyJwk": null, + "type": "Ed25519VerificationKey2018", + }, + ], +} +`; + +exports[`\`DIDDocument\` \`DIDDocument.create\` works 3`] = ` { "@context": [ "https://www.w3.org/ns/did/v1", @@ -46,6 +83,7 @@ exports[`\`DIDDocument\` \`DIDDocument.create\` works 2`] = ` ], "controller": [ "did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8", + "did:dock:5DEHasvC9G3eVF3qCsN2VQvEbHYdQtsv74ozZ1ngQQj39Luk", ], "https://rdf.dock.io/alpha/2021#attestsDocumentContents": null, "id": "did:dock:5DEHasvC9G3eVF3qCsN2VQvEbHYdQtsv74ozZ1ngQQj39Luk", @@ -130,7 +168,7 @@ exports[`\`DIDDocument\` \`DIDDocument.create\` works 2`] = ` } `; -exports[`\`DIDDocument\` \`DIDDocument.create\` works 3`] = ` +exports[`\`DIDDocument\` \`DIDDocument.create\` works 4`] = ` { "@context": [ "overriden", diff --git a/packages/credential-sdk/tests/document.test.js b/packages/credential-sdk/tests/document.test.js index 5989fe094..29e5268be 100644 --- a/packages/credential-sdk/tests/document.test.js +++ b/packages/credential-sdk/tests/document.test.js @@ -1,4 +1,8 @@ -import { VerificationRelationship, DidKey } from "../src/types/did"; +import { + VerificationRelationship, + DidKey, + CheqdTestnetDid, +} from "../src/types/did"; import { DIDDocument } from "../src/types/did/document"; import { PublicKeyEd25519 } from "../src/types"; @@ -51,6 +55,14 @@ describe("`DIDDocument`", () => { ) ).toMatchSnapshot(); + const cheqdDid = CheqdTestnetDid.from( + "did:cheqd:testnet:f1749383-d9dd-479f-82aa-e52fe8f59c54" + ); + + expect( + DIDDocument.create(cheqdDid, [new DidKey(RANDOM_PKS[0])], [cheqdDid], []) + ).toMatchSnapshot(); + expect( DIDDocument.create( "did:dock:5DEHasvC9G3eVF3qCsN2VQvEbHYdQtsv74ozZ1ngQQj39Luk", @@ -64,7 +76,10 @@ describe("`DIDDocument`", () => { new DidKey(RANDOM_PKS[6], AUTH | ASSERT | CAP_INV), new DidKey(RANDOM_PKS[7], KEY_AGR), ], - ["did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8"], + [ + "did:key:z6MktvqCyLxTsXUH1tUZncNdVeEZ7hNh7npPRbUU27GTrYb8", + "did:dock:5DEHasvC9G3eVF3qCsN2VQvEbHYdQtsv74ozZ1ngQQj39Luk", + ], [] ) ).toMatchSnapshot(); diff --git a/packages/credential-sdk/tests/schema.test.js b/packages/credential-sdk/tests/schema.test.js index d33f04b90..e0b83314d 100644 --- a/packages/credential-sdk/tests/schema.test.js +++ b/packages/credential-sdk/tests/schema.test.js @@ -2,7 +2,7 @@ import VerifiableCredential from "../src/vc/verifiable-credential"; import { Schema } from "../src/modules/schema"; -import { BlobId } from "../src/types/blob"; +import { DockBlobId } from "../src/types/blob"; import { expandJSONLD } from "../src/vc/helpers"; @@ -39,18 +39,11 @@ describe("VerifiableCredential Tests", () => { describe("Basic Schema Tests", () => { let schema; + beforeAll(async () => { - schema = new Schema(); + schema = new Schema(DockBlobId.random()); }, 10000); - test("accepts the id optionally and generates id of correct size when id is not given", () => { - const schemaNoID = new Schema(); - const encodedIDByteSize = 48; - expect(String(schemaNoID.id).length).toBe( - encodedIDByteSize + BlobId.Qualifier.length - ); - }); - test("setJSONSchema will only accept valid JSON schema and set the schema key of the object.", async () => { await expect( schema.setJSONSchema({ @@ -88,7 +81,7 @@ describe("Basic Schema Tests", () => { }); describe("Validate Credential Schema utility", () => { - const schema = new Schema(); + const schema = new Schema(DockBlobId.random()); schema.setJSONSchema(exampleSchema); let expandedCredential; diff --git a/packages/credential-sdk/tests/serialize.test.js b/packages/credential-sdk/tests/serialize.test.js index 119ebe45c..8896db987 100644 --- a/packages/credential-sdk/tests/serialize.test.js +++ b/packages/credential-sdk/tests/serialize.test.js @@ -3,6 +3,7 @@ import VerifiablePresentation from "../src/vc/verifiable-presentation"; import { Schema } from "../src/modules/schema"; import exampleCredential from "./utils/example-credential"; +import { DockBlobId } from "../src/types"; describe("Serialization", () => { test("VerifiableCredential fromJSON should fail if no type is provided", () => { @@ -62,7 +63,7 @@ describe("Serialization", () => { }); test("Schema from/to JSON serialization", async () => { - const schema = new Schema(); + const schema = new Schema(DockBlobId.random()); await schema.setJSONSchema({ $schema: "http://json-schema.org/draft-07/schema#", description: "Dock Schema Example", diff --git a/packages/dock-blockchain-api/src/api/index.js b/packages/dock-blockchain-api/src/api/index.js index c73ae083f..81745bc01 100644 --- a/packages/dock-blockchain-api/src/api/index.js +++ b/packages/dock-blockchain-api/src/api/index.js @@ -156,7 +156,7 @@ export default class DockAPI extends ApiProvider { } isInitialized() { - return !!this.api; + return this.api != null; } /** TODO: Should probably use set/get and rename account to _account @@ -183,9 +183,9 @@ export default class DockAPI extends ApiProvider { */ async signExtrinsic(extrinsic, params = {}) { if (this.customSignTx) { - return this.customSignTx(extrinsic, params, this); + return await this.customSignTx(extrinsic, params, this); } - return extrinsic.signAsync(this.getAccount(), params); + return await extrinsic.signAsync(this.getAccount(), params); } /** @@ -233,10 +233,25 @@ export default class DockAPI extends ApiProvider { ); } + /** + * Converts supplied payload to bytes representing state change with the provided name. + * @param {string} name + * @param {object} payload + * @returns {Uint8Array} + */ async stateChangeBytes(name, payload) { return this.api.createType('StateChange', { [name]: payload }).toU8a(); } + /** + * Batches supplied transactions into a single call. + * @param {Array} + * @returns {SubmittableExtrinsics} + */ + async batchAll(transactions) { + return this.api.tx.utility.batchAll(transactions); + } + /** * Helper function to send without retrying a transaction that has already been signed. * @param {DockAPI} dock diff --git a/packages/dock-blockchain-modules/src/attest/module.js b/packages/dock-blockchain-modules/src/attest/module.js index 6c5f257cb..ec9101158 100644 --- a/packages/dock-blockchain-modules/src/attest/module.js +++ b/packages/dock-blockchain-modules/src/attest/module.js @@ -7,8 +7,8 @@ export default class DockAttestModule extends injectDock(AbstractAttestModule) { /** * Fetches the DIDs attestations IRI from the chain - * @param {string} hexId - DID in hex format - * @return {Promise} The DID's attestation, if any + * @param {*} did + * @return {Promise} The DID's attestation, if any */ async getAttests(did) { return (await this.dockOnly.attest(did)).iri?.value; @@ -16,11 +16,9 @@ export default class DockAttestModule extends injectDock(AbstractAttestModule) { /** * Creates an attestation claim on chain for a specific DID - * @param priority * @param iri * @param did * @param signingKeyRef - * @param params */ async setClaimTx(iri, targetDid, didKeypair) { ensureTargetKeypair(targetDid, didKeypair); diff --git a/packages/dock-blockchain-modules/src/blob/actions.js b/packages/dock-blockchain-modules/src/blob/actions.js index 117170b52..b467445eb 100644 --- a/packages/dock-blockchain-modules/src/blob/actions.js +++ b/packages/dock-blockchain-modules/src/blob/actions.js @@ -2,11 +2,11 @@ import { TypedStruct, TypedNumber, } from '@docknetwork/credential-sdk/types/generic'; -import { BlobWithDockId } from './types'; +import { DockBlobWithId } from '@docknetwork/credential-sdk/types'; export class AddBlob extends TypedStruct { static Classes = { - blob: BlobWithDockId, + blob: DockBlobWithId, nonce: class Nonce extends TypedNumber {}, }; } diff --git a/packages/dock-blockchain-modules/src/blob/types.js b/packages/dock-blockchain-modules/src/blob/types.js index 35aca36e4..3602312f2 100644 --- a/packages/dock-blockchain-modules/src/blob/types.js +++ b/packages/dock-blockchain-modules/src/blob/types.js @@ -1,16 +1,6 @@ -import { - DockDidOrDidMethodKey, - Blob, - BlobWithId, -} from '@docknetwork/credential-sdk/types'; -import { DockBlobId } from '@docknetwork/credential-sdk/types/blob/blob-id'; -import { - TypedTuple, - withProp, -} from '@docknetwork/credential-sdk/types/generic'; +import { DockDidOrDidMethodKey, Blob } from '@docknetwork/credential-sdk/types'; +import { TypedTuple } from '@docknetwork/credential-sdk/types/generic'; export class OwnerWithBlob extends TypedTuple { static Classes = [DockDidOrDidMethodKey, Blob]; } - -export class BlobWithDockId extends withProp(BlobWithId, 'id', DockBlobId) {} diff --git a/packages/dock-blockchain-modules/src/common/builders.js b/packages/dock-blockchain-modules/src/common/builders.js index 639c515f0..8be1d880d 100644 --- a/packages/dock-blockchain-modules/src/common/builders.js +++ b/packages/dock-blockchain-modules/src/common/builders.js @@ -31,7 +31,7 @@ export const createDIDMethodWithPolicyTx = (fnName) => { const { did: signer } = ensureInstanceOf(didKeypair, DidKeypair); // eslint-disable-next-line no-param-reassign args[root.payload[fnName].length - 1] - ??= 1 + (await root.apiProvider.didNonce(didKeypair.did)); + ??= await root.apiProvider.nextDidNonce(didKeypair.did); const { data, nonce } = root.payload[fnName].apply(this.root, args); const sig = await DockDidOrDidMethodKey.from(signer).signStateChange( @@ -61,7 +61,7 @@ export const createDIDMethodTx = (fnName) => { ensureInstanceOf(didKeypair, DidKeypair); // eslint-disable-next-line no-param-reassign args[root.payload[fnName].length - 1] - ??= 1 + (await root.apiProvider.didNonce(didKeypair.did)); + ??= await root.apiProvider.nextDidNonce(didKeypair.did); return await DockDidOrDidMethodKey.from(didKeypair.did).changeState( root.apiProvider, diff --git a/packages/dock-blockchain-modules/src/common/dock-api-provider.js b/packages/dock-blockchain-modules/src/common/dock-api-provider.js index f72090d23..759f8f1f7 100644 --- a/packages/dock-blockchain-modules/src/common/dock-api-provider.js +++ b/packages/dock-blockchain-modules/src/common/dock-api-provider.js @@ -1,21 +1,21 @@ -import { ApiProvider } from '@docknetwork/credential-sdk/modules/common'; -import { ensureInstanceOf } from '@docknetwork/credential-sdk/utils/type-helpers'; -import { DockDIDModuleInternal } from '../did/internal'; +import { ApiProvider } from "@docknetwork/credential-sdk/modules/common"; +import { ensureInstanceOf } from "@docknetwork/credential-sdk/utils/type-helpers"; +import { DockDIDModuleInternal } from "../did/internal"; class DockApiProvider extends ApiProvider { constructor(dock) { super(); this.dock = ensureInstanceOf(dock, ApiProvider); - if (typeof dock.getAllExtrinsicsFromBlock !== 'function') { - throw new Error('`getAllExtrinsicsFromBlock` must be a function'); + if (typeof dock.getAllExtrinsicsFromBlock !== "function") { + throw new Error("`getAllExtrinsicsFromBlock` must be a function"); } } get api() { const { api } = this.dock; if (!api.isConnected) { - throw new Error('API is not connected'); + throw new Error("API is not connected"); } return api; @@ -32,12 +32,22 @@ class DockApiProvider extends ApiProvider { async getAllExtrinsicsFromBlock(numberOrHash, includeFailedExtrinsics) { return await this.dock.getAllExtrinsicsFromBlock( numberOrHash, - includeFailedExtrinsics, + includeFailedExtrinsics ); } async didNonce(did) { - return await new DockDIDModuleInternal(this).nonce(did); + return typeof this.dock.didNonce === "function" + ? await this.dock.didNonce(did) + : await new DockDIDModuleInternal(this).nonce(did); + } + + async nextDidNonce(did) { + return (await this.didNonce(did)).inc(); + } + + async batchAll(transactions) { + return await this.dock.batchAll(transactions); } } diff --git a/packages/dock-blockchain-modules/src/common/with-params-and-public-keys.js b/packages/dock-blockchain-modules/src/common/with-params-and-public-keys.js index 839237ce6..0a7fbd4f0 100644 --- a/packages/dock-blockchain-modules/src/common/with-params-and-public-keys.js +++ b/packages/dock-blockchain-modules/src/common/with-params-and-public-keys.js @@ -104,11 +104,10 @@ export default function withParamsAndPublicKeys(klass) { * Add a public key * @param publicKey - public key to add. * @param targetDid - The DID to which key is being added - * @param signerDid - The DID that is adding the key by signing the payload because it controls `targetDid` - * @param signingKeyRef - Signer's signingKeyRef + * @param didKeypair - Signer's didKeypair * @returns {Promise<*>} */ - async addPublicKeyTx(id, publicKey, targetDid, didKeypair) { + async addPublicKeyTx(_id, publicKey, targetDid, didKeypair) { return await this.dockOnly.tx.addPublicKey( publicKey, targetDid, @@ -120,8 +119,7 @@ export default function withParamsAndPublicKeys(klass) { * Remove public key * @param removeKeyId - Identifier of the public key to be removed. * @param targetDid - The DID from which key is being removed - * @param signerDid - The DID that is removing the key by signing the payload because it controls `targetDid` - * @param signingKeyRef - Signer's signing key reference + * @param didKeypair - Signer's signing key reference * @returns {Promise<*>} */ async removePublicKeyTx(id, targetDid, didKeypair) { diff --git a/packages/dock-blockchain-modules/src/did/module.js b/packages/dock-blockchain-modules/src/did/module.js index 1c6465cdf..8ededeb71 100644 --- a/packages/dock-blockchain-modules/src/did/module.js +++ b/packages/dock-blockchain-modules/src/did/module.js @@ -1,18 +1,18 @@ -import bs58 from 'bs58'; -import { AbstractDIDModule } from '@docknetwork/credential-sdk/modules/did'; +import bs58 from "bs58"; +import { AbstractDIDModule } from "@docknetwork/credential-sdk/modules/did"; import { DockDid, DockDidOrDidMethodKey, -} from '@docknetwork/credential-sdk/types'; +} from "@docknetwork/credential-sdk/types"; import { DIDDocument, Service, CONTEXT_URI, -} from '@docknetwork/credential-sdk/types/did/document'; -import { DockDIDModuleInternal } from './internal'; -import injectDock from '../common/inject-dock'; -import DockAttestModule from '../attest/module'; -import DockOffchainSignaturesModule from '../offchain-signatures/module'; +} from "@docknetwork/credential-sdk/types/did/document"; +import { DockDIDModuleInternal } from "./internal"; +import injectDock from "../common/inject-dock"; +import DockAttestModule from "../attest/module"; +import DockOffchainSignaturesModule from "../offchain-signatures/module"; export default class DockDIDModule extends injectDock(AbstractDIDModule) { static DockOnly = DockDIDModuleInternal; @@ -32,25 +32,25 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { controller, service, id, - '@context': context, + "@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.', + "`service` is not supported in the `createDocument` transaction. Use `updateDocument` to add `service` to the existing document." ); } else if (capabilityDelegation?.length) { - throw new Error('Capability delegation is not supported'); + 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.', + "`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, - ]}\`, received: \`${context}\``, + ]}\`, received: \`${context}\`` ); } @@ -68,84 +68,122 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { removed: removedMethods, modified, } = nextDocument.didKeys().diff(currentDocument.didKeys()); - const { added: newControllers, removed: removedControllers } = nextDocument.controller.diff(currentDocument.controller); - const { added: newServices, removed: removedServices } = nextDocument.service.diff(currentDocument.service); + const { added: newControllers, removed: removedControllers } = + nextDocument.controller.diff(currentDocument.controller); + const { added: newServices, removed: removedServices } = + nextDocument.service.diff(currentDocument.service); + const newOnChainKeys = [...newMethods].filter( + ([_, key]) => !key.isOffchain() + ); + const newOffchainKeys = [...newMethods].filter(([_, key]) => + key.isOffchain() + ); + const removedOnChainKeys = [...removedMethods].filter( + ([_, key]) => !key.isOffchain() + ); + const removedOffchainKeys = [...removedMethods].filter(([_, key]) => + key.isOffchain() + ); if (modified.size) { throw new Error("Can't have modified verificationMethods"); } else if ( - nextDocument.attests - && !nextDocument.attests.eq(currentDocument.attests) + 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.', + "`attests` modifications are not supported in the `updateDocument` transaction. Use `attest` module to attach `attests` to the existing document." ); } if ( - [...newMethods.keys()].find((method) => !method.did.eq(didDocument.id)) - || [...removedMethods.keys()].find( - (method) => !method.did.eq(didDocument.id), + [...newMethods.keys()].find((method) => !method.did.eq(didDocument.id)) || + [...removedMethods.keys()].find( + (method) => !method.did.eq(didDocument.id) ) ) { - throw new Error('Can change controller keys'); + throw new Error("Can't change controller keys"); } - let nonce = +(await this.dockOnly.nonce(signerDid)); - - const { id: did, '@context': context } = nextDocument; + const { id: docId, "@context": context } = nextDocument; + const did = DockDidOrDidMethodKey.from(docId); if (context.length !== 1 || context[0].value !== CONTEXT_URI) { throw new Error( `Context must be equal to \`${[ CONTEXT_URI, - ]}\`, received: \`${context}\``, + ]}\`, received: \`${context}\`` ); } - const txs = await Promise.all( - [ - newMethods.size - && this.dockOnly.tx.addKeys( - [...newMethods.values()], - did, - didKeypair, - ++nonce, - ), - newControllers.length - && this.dockOnly.tx.addControllers( - newControllers, - did, - didKeypair, - ++nonce, - ), - ...[...newServices].map(({ id, type, serviceEndpoint }) => this.dockOnly.tx.addServiceEndpoint( + const nonce = await this.dockOnly.apiProvider.didNonce(signerDid); + + const txs = [ + newOnChainKeys.length && + this.dockOnly.tx.addKeys( + [...newOnChainKeys].map(([_, key]) => key), + did, + didKeypair, + nonce.inc() + ), + newControllers.length && + this.dockOnly.tx.addControllers( + newControllers, + did, + didKeypair, + nonce.inc() + ), + ...newOffchainKeys.map(([_, key]) => + this.offchainSignatures.dockOnly.tx.addPublicKey( + key.publicKey, + did, + didKeypair, + nonce.inc() + ) + ), + ...[...newServices].map(({ id, type, serviceEndpoint }) => + this.dockOnly.tx.addServiceEndpoint( id, type, serviceEndpoint, did, didKeypair, - ++nonce, - )), - ...[...removedServices].map(({ id }) => this.dockOnly.tx.removeServiceEndpoint(id, did, didKeypair, ++nonce)), - removedControllers.length - && this.dockOnly.tx.removeControllers( - removedControllers, - did, - didKeypair, - ++nonce, - ), - removedMethods.size - && this.dockOnly.tx.removeKeys( - [...removedMethods.keys()].map((method) => method.index), - did, - didKeypair, - ++nonce, - ), - ].filter(Boolean), - ); + nonce.inc() + ) + ), + ...[...removedServices].map(({ id }) => + this.dockOnly.tx.removeServiceEndpoint(id, didKeypair, nonce.inc()) + ), + ...removedOffchainKeys.map(([{ index }]) => + this.offchainSignatures.dockOnly.tx.removePublicKey( + index, + did, + didKeypair, + nonce.inc() + ) + ), + removedControllers.length && + this.dockOnly.tx.removeControllers( + removedControllers, + did, + didKeypair, + nonce.inc() + ), + removedOnChainKeys.length && + this.dockOnly.tx.removeKeys( + [...removedOnChainKeys].map(([{ index }]) => index), + did, + didKeypair, + nonce.inc() + ), + ]; + + const filteredTxs = (await Promise.all(txs)).filter(Boolean); + if (!filteredTxs.length) { + throw new Error(`No changes for ${did}`); + } - return await this.dockOnly.apiProvider.api.tx.utility.batchAll(txs); + return await this.dockOnly.apiProvider.batchAll(filteredTxs); } async removeDocumentTx(did, didKeypair) { @@ -166,7 +204,7 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { const hexDid = typedDid.asDid; const { data: didDetails } = await this.dockOnly.getOnchainDidDetail( - hexDid, + hexDid ); // Get DIDs attestations @@ -176,9 +214,10 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { const id = String(typedDid); // Get controllers - const controllers = didDetails.activeControllers > 0 - ? await this.dockOnly.controllers(typedDid) - : []; + const controllers = + didDetails.activeControllers > 0 + ? await this.dockOnly.controllers(typedDid) + : []; // Get service endpoints const serviceEndpoints = await this.dockOnly.serviceEndpoints(hexDid); @@ -242,7 +281,9 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { const capabilityInvocation = capInv.map((i) => `${id}#keys-${i}`); const keyAgreement = keyAgr.map((i) => `${id}#keys-${i}`); - const service = [...serviceEndpoints].map(([spId, sp]) => Service.fromServiceEndpoint(spId, sp)); + const service = [...serviceEndpoints].map(([spId, sp]) => + Service.fromServiceEndpoint(spId, sp) + ); // Construct document return new DIDDocument( @@ -257,7 +298,7 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { keyAgreement, capabilityInvocation, [], - attests, + attests ); } } diff --git a/packages/dock-blockchain-modules/src/trust-registry/internal.js b/packages/dock-blockchain-modules/src/trust-registry/internal.js index 368def392..f24aba8b5 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/internal.js +++ b/packages/dock-blockchain-modules/src/trust-registry/internal.js @@ -2,28 +2,29 @@ import { DidMethodKey, DockDid, DockDidOrDidMethodKey, -} from '@docknetwork/credential-sdk/types/did'; +} from "@docknetwork/credential-sdk/types/did"; import { isHexWithGivenByteSize, u8aToHex, -} from '@docknetwork/credential-sdk/utils/bytes'; -import { ensureMatchesPattern } from '@docknetwork/credential-sdk/utils/misc'; -import { IssuersSet } from '@docknetwork/credential-sdk/types/trust-registry'; -import { maybeToJSON } from '@docknetwork/credential-sdk/utils'; -import { createInternalDockModule } from '../common'; +} from "@docknetwork/credential-sdk/utils/bytes"; +import { ensureMatchesPattern } from "@docknetwork/credential-sdk/utils/misc"; +import { IssuersSet } from "@docknetwork/credential-sdk/types/trust-registry"; +import { maybeToJSON } from "@docknetwork/credential-sdk/utils"; +import { createInternalDockModule } from "../common"; -const callValueMethodOrObjectMethod = (method) => (value) => (typeof value[method] === 'function' - ? [...value[method]()] - : Object[method](value)); +const callValueMethodOrObjectMethod = (method) => (value) => + typeof value[method] === "function" + ? [...value[method]()] + : Object[method](value); -const entries = callValueMethodOrObjectMethod('entries'); -const values = callValueMethodOrObjectMethod('values'); +const entries = callValueMethodOrObjectMethod("entries"); +const values = callValueMethodOrObjectMethod("values"); /** * `Trust Registry` module. */ export default class DockInternalTrustRegistryModule extends createInternalDockModule() { - static Prop = 'trustRegistry'; + static Prop = "trustRegistry"; /** * Returns Trust Registries information according to the supplied `by` argument. @@ -35,7 +36,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseRegistryInfo, - await this.rpc.registriesInfoBy(by), + await this.rpc.registriesInfoBy(by) ); } @@ -51,7 +52,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseSchemaMetadata, - await this.rpc.registrySchemaMetadataBy(by, regId), + await this.rpc.registrySchemaMetadataBy(by, regId) ); } @@ -65,7 +66,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM async schemaMetadataInRegistry(schemaId, regId) { return this.parseSingleEntry( this.parseSchemaMetadata, - await this.rpc.schemaMetadataInRegistry(schemaId, regId), + await this.rpc.schemaMetadataInRegistry(schemaId, regId) ); } @@ -79,7 +80,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseSchemaMetadata, - await this.rpc.schemaMetadata(schemaId), + await this.rpc.schemaMetadata(schemaId) ); } @@ -93,7 +94,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM async schemaIssuersInRegistry(schemaId, regId) { return this.parseSingleEntry( this.parseSchemaIssuers, - await this.rpc.schemaIssuersInRegistry(schemaId, regId), + await this.rpc.schemaIssuersInRegistry(schemaId, regId) ); } @@ -107,7 +108,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseSchemaIssuers, - await this.rpc.schemaIssuers(schemaId), + await this.rpc.schemaIssuers(schemaId) ); } @@ -121,7 +122,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM async schemaVerifiersInRegistry(schemaId, regId) { return this.parseSingleEntry( this.parseSchemaVerifiers, - await this.rpc.schemaVerifiersInRegistry(schemaId, regId), + await this.rpc.schemaVerifiersInRegistry(schemaId, regId) ); } @@ -135,7 +136,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseSchemaVerifiers, - await this.rpc.schemaVerifiers(schemaId), + await this.rpc.schemaVerifiers(schemaId) ); } @@ -167,14 +168,14 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM const participantWithInfo = async (did) => { const info = await this.query.trustRegistryParticipantsInformation( registryId, - did, + did ); return [did, info.isSome ? info.unwrap().toJSON() : null]; }; return Object.fromEntries( - await Promise.all(participants.map(participantWithInfo)), + await Promise.all(participants.map(participantWithInfo)) ); } @@ -194,14 +195,14 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM name, govFramework, signingKeyRef, - params = {}, + params = {} ) { const tx = await this.initOrUpdateTx( convenerDid, registryId, name, govFramework, - signingKeyRef, + signingKeyRef ); return await this.signAndSend(tx, params); } @@ -222,24 +223,24 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM name, govFramework, signingKeyRef, - nonce, + nonce ) { const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce( convenerDid, - nonce, + nonce ); return await convenerHexDid.changeState( this.apiProvider, this.rawTx.initOrUpdateTrustRegistry, - 'InitOrUpdateTrustRegistry', + "InitOrUpdateTrustRegistry", { registryId, name, govFramework, nonce: lastNonce, }, - signingKeyRef, + signingKeyRef ); } @@ -259,16 +260,17 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, participants, signingKeyRef, - nonce, + nonce ) { - const [convenerOrIssuerOrVerifierHexDid, lastNonce] = await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); + const [convenerOrIssuerOrVerifierHexDid, lastNonce] = + await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); return { sig: await convenerOrIssuerOrVerifierHexDid.signStateChange( this.apiProvider, - 'ChangeParticipants', + "ChangeParticipants", { data: { registryId, participants }, nonce: lastNonce }, - signingKeyRef, + signingKeyRef ), nonce: lastNonce, }; @@ -292,12 +294,12 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM participants, sigs, waitForFinalization = true, - params = {}, + params = {} ) { return await this.signAndSend( await this.changeParticipantsTx(registryId, participants, sigs), waitForFinalization, - params, + params ); } @@ -312,7 +314,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM async changeParticipantsTx(registryId, participants, sigs) { ensureMatchesPattern( this.constructor.ChangeParticipantsPattern, - participants, + participants ); return this.rawTx.changeParticipants( @@ -320,7 +322,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, participants, }, - sigs, + sigs ); } @@ -340,19 +342,20 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM participant, participantInformation, signingKeyRef, - nonce, + nonce ) { - const [convenerOrIssuerOrVerifierHexDid, lastNonce] = await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); + const [convenerOrIssuerOrVerifierHexDid, lastNonce] = + await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); return { sig: await convenerOrIssuerOrVerifierHexDid.signStateChange( this.apiProvider, - 'SetParticipantInformation', + "SetParticipantInformation", { data: { registryId, participant, participantInformation }, nonce: lastNonce, }, - signingKeyRef, + signingKeyRef ), nonce: lastNonce, }; @@ -374,17 +377,17 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM participantInformation, sigs, waitForFinalization = true, - params = {}, + params = {} ) { return await this.signAndSend( await this.setParticipantInformationTx( registryId, participant, participantInformation, - sigs, + sigs ), waitForFinalization, - params, + params ); } @@ -401,11 +404,11 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, participant, participantInformation, - sigs, + sigs ) { ensureMatchesPattern( this.constructor.SetParticipantInformationPattern, - participantInformation, + participantInformation ); return this.rawTx.setParticipantInformation( @@ -414,7 +417,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM participant, participantInformation, }, - sigs, + sigs ); } @@ -432,13 +435,13 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, schemas, signingKeyRef, - params = {}, + params = {} ) { const tx = await this.setSchemasMetadataTx( convenerOrIssuerOrVerifierDid, registryId, schemas, - signingKeyRef, + signingKeyRef ); return await this.signAndSend(tx, params); } @@ -459,17 +462,18 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, schemas, signingKeyRef, - nonce, + nonce ) { - const [convenerOrIssuerOrVerifierHexDid, lastNonce] = await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); + const [convenerOrIssuerOrVerifierHexDid, lastNonce] = + await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); ensureMatchesPattern(this.constructor.SchemasUpdatePattern, schemas); return await convenerOrIssuerOrVerifierHexDid.changeState( this.apiProvider, this.rawTx.setSchemasMetadata, - 'SetSchemasMetadata', + "SetSchemasMetadata", { registryId, schemas, nonce: lastNonce }, - signingKeyRef, + signingKeyRef ); } @@ -487,13 +491,13 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, issuers, signingKeyRef, - params = {}, + params = {} ) { const tx = await this.suspendIssuersTx( convenerDid, registryId, issuers, - signingKeyRef, + signingKeyRef ); return await this.signAndSend(tx, params); } @@ -512,11 +516,11 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, rawIssuers, signingKeyRef, - nonce, + nonce ) { const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce( convenerDid, - nonce, + nonce ); const hexIssuers = IssuersSet.from(rawIssuers); @@ -524,9 +528,9 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return await convenerHexDid.changeState( this.apiProvider, this.rawTx.suspendIssuers, - 'SuspendIssuers', + "SuspendIssuers", { registryId, issuers: hexIssuers, nonce: lastNonce }, - signingKeyRef, + signingKeyRef ); } @@ -544,13 +548,13 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, issuers, signingKeyRef, - params = {}, + params = {} ) { const tx = await this.unsuspendIssuersTx( convenerDid, registryId, issuers, - signingKeyRef, + signingKeyRef ); return await this.signAndSend(tx, params); } @@ -569,11 +573,11 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, rawIssuers, signingKeyRef, - nonce, + nonce ) { const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce( convenerDid, - nonce, + nonce ); const issuers = IssuersSet.from(rawIssuers); @@ -581,9 +585,9 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return await convenerHexDid.changeState( this.apiProvider, this.rawTx.unsuspendIssuers, - 'UnsuspendIssuers', + "UnsuspendIssuers", { registryId, issuers, nonce: lastNonce }, - signingKeyRef, + signingKeyRef ); } @@ -605,23 +609,23 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM signingKeyRef, nonce, waitForFinalization = true, - params = {}, + params = {} ) { const [issuerHexDid, lastNonce] = await this.getActorDidAndNonce( issuerDid, - nonce, + nonce ); return await this.signAndSend( await issuerHexDid.changeState( this.apiProvider, this.rawTx.updateDelegatedIssuers, - 'UpdateDelegatedIssuers', + "UpdateDelegatedIssuers", { registryId, delegated, nonce: lastNonce }, - signingKeyRef, + signingKeyRef ), waitForFinalization, - params, + params ); } @@ -635,7 +639,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM */ async getActorDidAndNonce(actorDid, nonce) { const hexDID = DockDidOrDidMethodKey.from(actorDid); - const lastNonce = nonce ?? 1 + (await this.apiProvider.didNonce(hexDID)); + const lastNonce = nonce ?? (await this.apiProvider.nextDidNonce(hexDID)); return [hexDID, lastNonce]; } @@ -672,7 +676,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM keyParser.call(this, key), valueParser.call(this, value), ]) - .sort(([key1], [key2]) => key1.localeCompare(key2)), + .sort(([key1], [key2]) => key1.localeCompare(key2)) ); } @@ -725,7 +729,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM String(DockDidOrDidMethodKey.from(issuer)), maybeToJSON(info), ]) - .sort(([iss1], [iss2]) => iss1.localeCompare(iss2)), + .sort(([iss1], [iss2]) => iss1.localeCompare(iss2)) ); } @@ -747,7 +751,7 @@ const DockDidOrDidMethodKeyPattern = { }; const VerificationPricePattern = { - $anyOf: [{ $matchType: 'number' }, { $matchType: 'object' }], + $anyOf: [{ $matchType: "number" }, { $matchType: "object" }], }; const Hex32Pattern = { @@ -769,9 +773,9 @@ const VerifiersUpdatePattern = { DockDidOrDidMethodKeyPattern, { $anyOf: [ - { $matchValue: 'Remove' }, + { $matchValue: "Remove" }, { - $matchValue: 'Add', + $matchValue: "Add", }, ], }, @@ -780,16 +784,16 @@ const VerifiersUpdatePattern = { const IssuerPricesPattern = { // $instanceOf: BTreeMap, - $mapOf: [{ $matchType: 'string' }, VerificationPricePattern], + $mapOf: [{ $matchType: "string" }, VerificationPricePattern], }; const IssuerPricesUpdatePattern = { // $instanceOf: BTreeMap, $mapOf: [ - { $matchType: 'string' }, + { $matchType: "string" }, { $anyOf: [ - { $matchValue: 'Remove' }, + { $matchValue: "Remove" }, { $objOf: { Add: VerificationPricePattern, @@ -868,7 +872,7 @@ const ModifySchemasPattern = { }, }, { - $matchValue: 'Remove', + $matchValue: "Remove", }, ], }, @@ -888,13 +892,13 @@ const AnyOfOrAllDockDidOrDidMethodKeyPattern = { DockInternalTrustRegistryModule.SetParticipantInformationPattern = { $matchObject: { orgName: { - $matchType: 'string', + $matchType: "string", }, logo: { - $matchType: 'string', + $matchType: "string", }, description: { - $matchType: 'string', + $matchType: "string", }, }, }; @@ -910,10 +914,10 @@ DockInternalTrustRegistryModule.ChangeParticipantsPattern = { { $anyOf: [ { - $matchValue: 'Add', + $matchValue: "Add", }, { - $matchValue: 'Remove', + $matchValue: "Remove", }, ], }, diff --git a/packages/dock-blockchain-modules/src/trust-registry/module.js b/packages/dock-blockchain-modules/src/trust-registry/module.js index 27aba269a..443856789 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/module.js +++ b/packages/dock-blockchain-modules/src/trust-registry/module.js @@ -1,17 +1,17 @@ -import { AbstractTrustRegistryModule } from '@docknetwork/credential-sdk/modules/trust-registry'; +import { AbstractTrustRegistryModule } from "@docknetwork/credential-sdk/modules/trust-registry"; import { TrustRegistryInfo, DockTrustRegistryId, TrustRegistries, TrustRegistry, DockDidOrDidMethodKey, -} from '@docknetwork/credential-sdk/types'; -import { option } from '@docknetwork/credential-sdk/types/generic'; -import { injectDock } from '../common'; -import DockInternalTrustRegistryModule from './internal'; +} from "@docknetwork/credential-sdk/types"; +import { option } from "@docknetwork/credential-sdk/types/generic"; +import { injectDock } from "../common"; +import DockInternalTrustRegistryModule from "./internal"; export default class DockTrustRegistryModule extends injectDock( - AbstractTrustRegistryModule, + AbstractTrustRegistryModule ) { static DockOnly = DockInternalTrustRegistryModule; @@ -37,20 +37,20 @@ export default class DockTrustRegistryModule extends injectDock( return new TrustRegistries( await Promise.all( - [...ids].map(async (id) => [id, await this.getRegistry(id)]), - ), + [...ids].map(async (id) => [id, await this.getRegistry(id)]) + ) ); } async createRegistryTx(id, info, schemas, didKeypair) { - const nonce = await this.dockOnly.apiProvider.didNonce(didKeypair.did); + const nonce = await this.dockOnly.apiProvider.nextDidNonce(didKeypair.did); const init = await this.dockOnly.initOrUpdateTx( info.convener, id, info.name, info.govFramework, didKeypair, - 1 + nonce, + nonce ); const setSchemas = await this.dockOnly.setSchemasMetadataTx( @@ -58,13 +58,10 @@ export default class DockTrustRegistryModule extends injectDock( id, { Set: schemas }, didKeypair, - 2 + nonce, + nonce.inc() ); - return await this.dockOnly.apiProvider.api.tx.utility.batchAll([ - init, - setSchemas, - ]); + return await this.dockOnly.apiProvider.batchAll([init, setSchemas]); } async updateRegistryTx(id, info, schemas, didKeypair) { diff --git a/packages/dock-blockchain-modules/tests/integration/modules/attest-module.test.js b/packages/dock-blockchain-modules/tests/integration/modules/attest-module.test.js new file mode 100644 index 000000000..28a185182 --- /dev/null +++ b/packages/dock-blockchain-modules/tests/integration/modules/attest-module.test.js @@ -0,0 +1,32 @@ +import { DockAPI } from "@docknetwork/dock-blockchain-api"; +import { DockDid } from "@docknetwork/credential-sdk/types"; +import generateAttestModuleTests from "@docknetwork/credential-sdk/generate-tests/attest-module"; +import DockAttestModule from "../../../src/attest/module"; +import { DockDIDModule } from "../../../src"; +import { + FullNodeEndpoint, + TestAccountURI, + TestKeyringOpts, +} from "../../test-constants"; + +describe("AttestModule", () => { + const dock = new DockAPI(); + + beforeAll(async () => { + await dock.init({ + keyring: TestKeyringOpts, + address: FullNodeEndpoint, + }); + const account = dock.keyring.addFromUri(TestAccountURI); + dock.setAccount(account); + }); + + afterAll(async () => { + await dock.disconnect(); + }); + + generateAttestModuleTests( + { did: new DockDIDModule(dock), attest: new DockAttestModule(dock) }, + DockDid + ); +}); diff --git a/packages/dock-blockchain-modules/tests/integration/modules/blob-module.test.js b/packages/dock-blockchain-modules/tests/integration/modules/blob-module.test.js new file mode 100644 index 000000000..db83c93fe --- /dev/null +++ b/packages/dock-blockchain-modules/tests/integration/modules/blob-module.test.js @@ -0,0 +1,33 @@ +import { DockAPI } from "@docknetwork/dock-blockchain-api"; +import { DockDid } from "@docknetwork/credential-sdk/types"; +import generateBlobModuleTests from "@docknetwork/credential-sdk/generate-tests/blob-module"; +import DockBlobModule from "../../../src/blob/module"; +import { DockDIDModule } from "../../../src"; +import { + FullNodeEndpoint, + TestAccountURI, + TestKeyringOpts, +} from "../../test-constants"; +import { DockBlobId } from "../../../../credential-sdk/src/types"; + +describe("BlobModule", () => { + const dock = new DockAPI(); + + beforeAll(async () => { + await dock.init({ + keyring: TestKeyringOpts, + address: FullNodeEndpoint, + }); + const account = dock.keyring.addFromUri(TestAccountURI); + dock.setAccount(account); + }); + + afterAll(async () => { + await dock.disconnect(); + }); + + generateBlobModuleTests( + { did: new DockDIDModule(dock), blob: new DockBlobModule(dock) }, + { DID: DockDid, BlobId: DockBlobId } + ); +}); diff --git a/packages/dock-blockchain-modules/tests/integration/modules/did-module.test.js b/packages/dock-blockchain-modules/tests/integration/modules/did-module.test.js new file mode 100644 index 000000000..95383099c --- /dev/null +++ b/packages/dock-blockchain-modules/tests/integration/modules/did-module.test.js @@ -0,0 +1,34 @@ +import didModuleTests from "@docknetwork/credential-sdk/generate-tests/did-module"; +import { DockAPI } from "@docknetwork/dock-blockchain-api"; +import DockDIDModule from "../../../src/did/module"; +import { + FullNodeEndpoint, + TestAccountURI, + TestKeyringOpts, +} from "../../test-constants"; +import { DockDid } from "@docknetwork/credential-sdk/types"; + +describe("DIDModule", () => { + const dock = new DockAPI(); + + beforeAll(async () => { + await dock.init({ + keyring: TestKeyringOpts, + address: FullNodeEndpoint, + }); + const account = dock.keyring.addFromUri(TestAccountURI); + dock.setAccount(account); + }); + + afterAll(async () => { + await dock.disconnect(); + }); + + didModuleTests( + { did: new DockDIDModule(dock) }, + DockDid, + (name) => + name !== "Creates `DIDDocument` containing BBS/BBSPlus/PS keys" && + name !== "Creates `DIDDocument` containing services" + ); +}); diff --git a/packages/dock-blockchain-modules/tests/integration/schema.test.js b/packages/dock-blockchain-modules/tests/integration/schema.test.js index fbac5ebf3..ff7e18568 100644 --- a/packages/dock-blockchain-modules/tests/integration/schema.test.js +++ b/packages/dock-blockchain-modules/tests/integration/schema.test.js @@ -136,7 +136,7 @@ describe("Schema Blob Module Integration", () => { }, 30000); test("Set and get schema", async () => { - const schema = new Schema(); + const schema = new Schema(DockBlobId.random()); await schema.setJSONSchema(exampleSchema); await modules.blob.new(schema.toBlob(), dockDID, pair); const schemaObj = await Schema.get(blobId, modules.blob); diff --git a/scripts/with_cheqd_docker_test_node b/scripts/with_cheqd_docker_test_node index bad8fa9bb..08dba63ac 100755 --- a/scripts/with_cheqd_docker_test_node +++ b/scripts/with_cheqd_docker_test_node @@ -10,7 +10,7 @@ config="$(realpath $(dirname $0)/cheqd_config.toml)" docker pull --platform linux/amd64 ghcr.io/cheqd/cheqd-node # start a pos alice node -alice_container_id=$(docker run --platform linux/amd64 -d --rm -p 26656:26656 -p 26657:26657 -p 1317:1317 -p 9090:9090 -e CHEQD_MNEMONIC="$CHEQD_MNEMONIC" -v $entrypoint:/usr/local/bin/entrypoint.sh -v $config:/tmp/cheqd_config.toml --entrypoint /usr/local/bin/entrypoint.sh ghcr.io/cheqd/cheqd-node start) +alice_container_id=$(docker run --platform linux/amd64 -d --rm --name cheqd-dev -p 26656:26656 -p 26657:26657 -p 1317:1317 -p 9090:9090 -e CHEQD_MNEMONIC="$CHEQD_MNEMONIC" -v $entrypoint:/usr/local/bin/entrypoint.sh -v $config:/tmp/cheqd_config.toml --entrypoint /usr/local/bin/entrypoint.sh ghcr.io/cheqd/cheqd-node start) try_with_node() { sleep 10; diff --git a/scripts/with_dock_docker_test_node b/scripts/with_dock_docker_test_node index de14ffba9..7056e46da 100755 --- a/scripts/with_dock_docker_test_node +++ b/scripts/with_dock_docker_test_node @@ -11,7 +11,7 @@ docker pull $CONFIG_DOCK_NODE_IMAGE # start a pos alice node alice_container_id=$( - docker run --rm -d --name alice \ + docker run --rm -d --name dock-dev \ -p 9944:9944 -p 9933:9933 -p 30333:30333 \ $CONFIG_DOCK_NODE_IMAGE \ --alice --rpc-external --ws-external diff --git a/tutorials/src/tutorial_blobs_schemas.md b/tutorials/src/tutorial_blobs_schemas.md index 486a8b414..20c53d381 100644 --- a/tutorials/src/tutorial_blobs_schemas.md +++ b/tutorials/src/tutorial_blobs_schemas.md @@ -68,7 +68,7 @@ The first step to creating a Schema is to initialize it, we can do that using th accepts an (optional) `id` string as sole argument: ```javascript -const myNewSchema = new Schema(); +const myNewSchema = new Schema(DockBlobId.random()); ``` When an `id` isn't passed, a random `blobId` will be assigned as the schema's id. diff --git a/tutorials/src/tutorial_resolver.md b/tutorials/src/tutorial_resolver.md index d99fc0557..28fe2c7a4 100644 --- a/tutorials/src/tutorial_resolver.md +++ b/tutorials/src/tutorial_resolver.md @@ -26,10 +26,10 @@ This is how you resolve a Dock DID: ```js import { DockResolver } from "@docknetwork/credential-sdk/resolver"; -// Assuming the presence of Dock API object `dock` -const dockResolver = new DockResolver(dock); +// Assuming the presence of modules created using `CheqdCoreModules` or `DockCoreModules` from the API object. +const dockResolver = new DockResolver(modules); // Say you had a DID `did:dock:5D.....` -const didDocument = dockResolver.resolve("did:dock:5D....."); +const didDocument = await dockResolver.resolve("did:dock:5D....."); ``` ## Creating a resolver class for a different method @@ -78,7 +78,7 @@ class EtherResolver extends DIDResolver { const ethResolver = new EtherResolver(ethereumProviderConfig); // Say you had a DID `did:ethr:0x6f....` -const didDocument = ethResolver.resolve("did:ethr:0x6f...."); +const didDocument = await ethResolver.resolve("did:ethr:0x6f...."); ``` ## Universal resolver @@ -119,9 +119,9 @@ import { class MultiDIDResolver extends DIDResolver { static METHOD = WILDCARD; - constructor(dock) { + constructor(modules) { super([ - new DockDIDResolver(dock), + new DockDIDResolver(modules.did), new EtherResolver(ethereumProviderConfig), new UniversalResolver(universalResolverUrl), ]); @@ -131,8 +131,8 @@ class MultiDIDResolver extends DIDResolver { const multiResolver = new MultiDIDResolver(resolvers); // Say you had a DID `did:dock:5D....`, then the `DockResolver` will be used as there a resolver for Dock DID. -const didDocumentDock = multiResolver.resolve("did:dock:5D...."); +const didDocumentDock = await multiResolver.resolve("did:dock:5D...."); // Say you had a DID `did:btcr:xk....`, then the `UniversalResolver` will be used as there is no resolver for BTC DID. -const didDocumentBtc = multiResolver.resolve("did:btcr:xk...."); +const didDocumentBtc = await multiResolver.resolve("did:btcr:xk...."); ``` diff --git a/tutorials/src/tutorial_revocation.md b/tutorials/src/tutorial_revocation.md index 6bd722778..5732b9367 100644 --- a/tutorials/src/tutorial_revocation.md +++ b/tutorials/src/tutorial_revocation.md @@ -1,6 +1,5 @@ # Revocation - This guide provides instructions for managing credential revocation using `StatusList2021Credential`. ## Prerequisites @@ -17,7 +16,7 @@ This guide provides instructions for managing credential revocation using `Statu Create a unique identifier for tracking revocation status. ```javascript - import { DockStatusListCredentialId } from '@docknetwork/credential-sdk/types'; + import { DockStatusListCredentialId } from "@docknetwork/credential-sdk/types"; const statusListCredentialId = DockStatusListCredentialId.random(); ``` @@ -64,13 +63,13 @@ This guide provides instructions for managing credential revocation using `Statu Sign and issue the credential with the added status list entry. ```javascript - import { addStatusList21EntryToCredential } from '@docknetwork/credential-sdk/vc'; + import { addStatusList21EntryToCredential } from "@docknetwork/credential-sdk/vc"; const credential = await issueCredential( issuerKey, unsignedCred, void 0, - defaultDocumentLoader(resolver), + defaultDocumentLoader(resolver) ); ``` @@ -80,7 +79,10 @@ This guide provides instructions for managing credential revocation using `Statu 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); + const fetchedCred = + await modules.statusListCredential.getStatusListCredential( + statusListCredentialId + ); await fetchedCred.update(issuerKey, { revokeIndices: [statusListCredentialIndex], // Index of the credential to revoke }); @@ -89,7 +91,7 @@ This guide provides instructions for managing credential revocation using `Statu statusListCredentialId, fetchedCred, issuerDID, - issuerKeyPair, + issuerKeyPair ); ``` From deaf9afa5130048419a959e2da11e8425762fdea Mon Sep 17 00:00:00 2001 From: olegnn Date: Thu, 17 Oct 2024 17:26:35 +0200 Subject: [PATCH 02/11] Lints --- .../src/attest/internal.js | 35 ++-- .../src/blob/internal.js | 22 +-- .../src/common/builders.js | 30 ++-- .../cheqd-blockchain-modules/src/index.js | 8 +- .../src/generate-tests/did-module.js | 58 +++--- .../src/resolver/did/dock-did-resolver.js | 8 +- .../src/types/accumulator/index.js | 18 +- .../credential-sdk/src/types/blob/blob-id.js | 18 +- .../credential-sdk/src/types/did/document.js | 166 ++++++++--------- .../src/types/did/onchain/index.js | 16 +- .../types/did/onchain/typed-did/cheqd-did.js | 10 +- .../did-method-key-public-key.js | 26 +-- .../did-method-key-signature.js | 6 +- .../did/onchain/typed-did/dock-did-value.js | 17 +- .../src/types/did/onchain/typed-did/index.js | 36 ++-- .../types/did/onchain/typed-did/signature.js | 2 +- .../src/types/generic/typed-enum.js | 54 +++--- .../src/types/generic/with-qualifier.js | 14 +- .../src/common/dock-api-provider.js | 16 +- .../dock-blockchain-modules/src/did/module.js | 149 +++++++-------- .../src/trust-registry/internal.js | 170 +++++++++--------- .../src/trust-registry/module.js | 20 +-- 22 files changed, 432 insertions(+), 467 deletions(-) diff --git a/packages/cheqd-blockchain-modules/src/attest/internal.js b/packages/cheqd-blockchain-modules/src/attest/internal.js index b830babc9..eb7e93603 100644 --- a/packages/cheqd-blockchain-modules/src/attest/internal.js +++ b/packages/cheqd-blockchain-modules/src/attest/internal.js @@ -1,39 +1,38 @@ -import { CheqdDid, Iri } from "@docknetwork/credential-sdk/types"; -import { TypedUUID, option } from "@docknetwork/credential-sdk/types/generic"; -import { CheqdCreateResource, createInternalCheqdModule } from "../common"; +import { CheqdDid, Iri } from '@docknetwork/credential-sdk/types'; +import { TypedUUID, option } from '@docknetwork/credential-sdk/types/generic'; +import { CheqdCreateResource, createInternalCheqdModule } from '../common'; const methods = { - setClaim: (iri, targetDid) => - new CheqdCreateResource( - CheqdDid.from(targetDid).value, - TypedUUID.random(), - "1.0", - [], - "Attestation", - "attest", - Iri.from(iri) - ), + setClaim: (iri, targetDid) => new CheqdCreateResource( + CheqdDid.from(targetDid).value, + TypedUUID.random(), + '1.0', + [], + 'Attestation', + 'attest', + Iri.from(iri), + ), }; export default class CheqdInternalAttestModule extends createInternalCheqdModule( - methods + methods, ) { - static Prop = "resource"; + static Prop = 'resource'; static MsgNames = { - setClaim: "MsgCreateResource", + setClaim: 'MsgCreateResource', }; async attest(did, attestId) { return option(Iri).from( - (await this.resource(did, attestId))?.resource?.data + (await this.resource(did, attestId))?.resource?.data, ); } async attestId(did) { return await this.latestResourceIdBy( did, - (resource) => resource.resourceType === "attest" + (resource) => resource.resourceType === 'attest', ); } } diff --git a/packages/cheqd-blockchain-modules/src/blob/internal.js b/packages/cheqd-blockchain-modules/src/blob/internal.js index fe0852896..9c5ce9a68 100644 --- a/packages/cheqd-blockchain-modules/src/blob/internal.js +++ b/packages/cheqd-blockchain-modules/src/blob/internal.js @@ -3,9 +3,9 @@ import { CheqdBlobId, CheqdBlobWithId, CheqdDid, -} from "@docknetwork/credential-sdk/types"; -import { option } from "@docknetwork/credential-sdk/types/generic"; -import { CheqdCreateResource, createInternalCheqdModule } from "../common"; +} from '@docknetwork/credential-sdk/types'; +import { option } from '@docknetwork/credential-sdk/types/generic'; +import { CheqdCreateResource, createInternalCheqdModule } from '../common'; const methods = { new: (blobWithId) => { @@ -15,27 +15,27 @@ const methods = { return new CheqdCreateResource( CheqdDid.from(did).value, uuid, - "1.0", + '1.0', [], - "Blob", - "blob", - blob + 'Blob', + 'blob', + blob, ); }, }; export default class CheqdInternalBlobModule extends createInternalCheqdModule( - methods + methods, ) { - static Prop = "resource"; + static Prop = 'resource'; static MsgNames = { - new: "MsgCreateResource", + new: 'MsgCreateResource', }; async blob(blobId) { return option(Blob).from( - (await this.resource(...CheqdBlobId.from(blobId)))?.resource?.data + (await this.resource(...CheqdBlobId.from(blobId)))?.resource?.data, ); } } diff --git a/packages/cheqd-blockchain-modules/src/common/builders.js b/packages/cheqd-blockchain-modules/src/common/builders.js index 546bed48d..614d2bd65 100644 --- a/packages/cheqd-blockchain-modules/src/common/builders.js +++ b/packages/cheqd-blockchain-modules/src/common/builders.js @@ -1,9 +1,9 @@ import { VerificationMethodSignature, CheqdDid, -} from "@docknetwork/credential-sdk/types"; -import { TypedUUID } from "@docknetwork/credential-sdk/types/generic"; -import { CheqdPayloadWithTypeUrl } from "./payload"; +} from '@docknetwork/credential-sdk/types'; +import { TypedUUID } from '@docknetwork/credential-sdk/types/generic'; +import { CheqdPayloadWithTypeUrl } from './payload'; /** * Creates DID method transaction builder. @@ -18,14 +18,12 @@ export const createDIDMethodTx = (fnName) => { const payload = root.payload[fnName].apply(this.root, args); const bytes = await root.apiProvider.stateChangeBytes( root.constructor.MsgNames[fnName], - payload + payload, ); const signatures = [] .concat(didKeypairs) - .map((didKeypair) => - VerificationMethodSignature.fromDidKeypair(didKeypair, bytes) - ); + .map((didKeypair) => VerificationMethodSignature.fromDidKeypair(didKeypair, bytes)); const value = { payload, @@ -34,7 +32,7 @@ export const createDIDMethodTx = (fnName) => { return new CheqdPayloadWithTypeUrl( root.constructor.MsgNames[fnName], - value + value, ); }, }; @@ -50,7 +48,7 @@ export const createCall = (fnName) => { async [fnName](...args) { const { root } = this; const tx = await root.tx[fnName]( - ...args.slice(0, root.payload[fnName].length) + ...args.slice(0, root.payload[fnName].length), ); return await root.signAndSend(tx, args[root.payload[fnName].length]); @@ -67,7 +65,7 @@ export const createAccountTx = (fnName) => { const obj = { async [fnName](...args) { return await this.root.rawTx[fnName]( - ...this.root.payload[fnName].apply(this.root, args) + ...this.root.payload[fnName].apply(this.root, args), ); }, }; @@ -81,9 +79,10 @@ class Root { } } +/* eslint-disable sonarjs/cognitive-complexity */ export function createInternalCheqdModule( methods = Object.create(null), - baseClass = class CheqdModuleBaseClass {} + baseClass = class CheqdModuleBaseClass {}, ) { const name = `internalCheqdModule(${baseClass.name})`; class RootPayload extends (baseClass.RootPayload ?? Root) {} @@ -113,10 +112,10 @@ export function createInternalCheqdModule( try { return await this.apiProvider.sdk.querier.resource.resource( strDid, - strID + strID, ); } catch (err) { - if (!String(err).includes("DID Doc not found")) { + if (!String(err).includes('DID Doc not found')) { throw err; } } @@ -131,14 +130,15 @@ export function createInternalCheqdModule( do { try { + // eslint-disable-next-line operator-linebreak ({ resources, paginationKey } = // eslint-disable-next-line no-await-in-loop await this.apiProvider.sdk.querier.resource.collectionResources( encodedDid, - paginationKey + paginationKey, )); } catch (err) { - if (!String(err).includes("DID Doc not found")) { + if (!String(err).includes('DID Doc not found')) { throw err; } else { break; diff --git a/packages/cheqd-blockchain-modules/src/index.js b/packages/cheqd-blockchain-modules/src/index.js index 6e011f25b..7287f463a 100644 --- a/packages/cheqd-blockchain-modules/src/index.js +++ b/packages/cheqd-blockchain-modules/src/index.js @@ -1,7 +1,7 @@ -import { AbstractCoreModules } from "@docknetwork/credential-sdk/modules"; -import CheqdAttestModule from "./attest/module"; -import CheqdBlobModule from "./blob/module"; -import CheqdDIDModule from "./did/module"; +import { AbstractCoreModules } from '@docknetwork/credential-sdk/modules'; +import CheqdAttestModule from './attest/module'; +import CheqdBlobModule from './blob/module'; +import CheqdDIDModule from './did/module'; // import CheqdAccumulatorModule from './accumulator/module'; // import CheqdAnchorModule from './anchor/module'; // import CheqdOffchainSignaturesModule from './offchain-signatures/module'; diff --git a/packages/credential-sdk/src/generate-tests/did-module.js b/packages/credential-sdk/src/generate-tests/did-module.js index f1107df57..d1c0c67b5 100644 --- a/packages/credential-sdk/src/generate-tests/did-module.js +++ b/packages/credential-sdk/src/generate-tests/did-module.js @@ -1,4 +1,4 @@ -import { DidKeypair, Ed25519Keypair } from "../keypairs"; +import { DidKeypair, Ed25519Keypair } from '../keypairs'; import { DIDDocument, BBSPublicKeyValue, @@ -6,20 +6,20 @@ import { BBSPlusPublicKeyValue, PSPublicKeyValue, VerificationMethodRef, -} from "../types"; -import { TypedBytes } from "../types/generic"; -import { ServiceEndpoint } from "../types/did/offchain"; -import { NoDIDError } from "../modules/did"; -import { itIf } from "./common"; +} from '../types'; +import { TypedBytes } from '../types/generic'; +import { ServiceEndpoint } from '../types/did/offchain'; +import { NoDIDError } from '../modules/did'; +import { itIf } from './common'; export default function generateDIDModuleTests( { did: module }, { DID }, - filter = () => true + filter = () => true, ) { const test = itIf(filter); - test("Creates basic `DIDDocument` with keys", async () => { + test('Creates basic `DIDDocument` with keys', async () => { const did = DID.random(); const keyPair = Ed25519Keypair.random(); @@ -32,7 +32,7 @@ export default function generateDIDModuleTests( expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); }); - test("Creates `DIDDocument` containing BBS/BBSPlus/PS keys", async () => { + test('Creates `DIDDocument` containing BBS/BBSPlus/PS keys', async () => { const did = DID.random(); const keyPair = Ed25519Keypair.random(); @@ -54,7 +54,7 @@ export default function generateDIDModuleTests( expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); }); - test("Updates with `DIDDocument` containing BBS/BBSPlus/PS keys", async () => { + test('Updates with `DIDDocument` containing BBS/BBSPlus/PS keys', async () => { const did = DID.random(); const keyPair = Ed25519Keypair.random(); @@ -62,7 +62,7 @@ export default function generateDIDModuleTests( const bbsKey = new DidKey(new BBSPublicKeyValue(TypedBytes.random(100))); const bbsPlusKey = new DidKey( - new BBSPlusPublicKeyValue(TypedBytes.random(100)) + new BBSPlusPublicKeyValue(TypedBytes.random(100)), ); const psKey = new DidKey(new PSPublicKeyValue(TypedBytes.random(1000))); @@ -88,17 +88,17 @@ export default function generateDIDModuleTests( ]); }); - test("Creates `DIDDocument` containing services", async () => { + test('Creates `DIDDocument` containing services', async () => { const did = DID.random(); const keyPair = Ed25519Keypair.random(); const didKeypair = new DidKeypair([did, 1], keyPair); - const service1 = new ServiceEndpoint("LinkedDomains", [ - "ServiceEndpoint#1", + const service1 = new ServiceEndpoint('LinkedDomains', [ + 'ServiceEndpoint#1', ]); - const service2 = new ServiceEndpoint("LinkedDomains", [ - "ServiceEndpoint#2", + const service2 = new ServiceEndpoint('LinkedDomains', [ + 'ServiceEndpoint#2', ]); const document = DIDDocument.create(did, [didKeypair.didKey()], [], { @@ -112,17 +112,17 @@ export default function generateDIDModuleTests( expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); }); - test("Updates `DIDDocument` containing services", async () => { + test('Updates `DIDDocument` containing services', async () => { const did = DID.random(); const keyPair = Ed25519Keypair.random(); const didKeypair = new DidKeypair([did, 1], keyPair); - const service1 = new ServiceEndpoint("LinkedDomains", [ - "ServiceEndpoint#1", + const service1 = new ServiceEndpoint('LinkedDomains', [ + 'ServiceEndpoint#1', ]); - const service2 = new ServiceEndpoint("LinkedDomains", [ - "ServiceEndpoint#2", + const service2 = new ServiceEndpoint('LinkedDomains', [ + 'ServiceEndpoint#2', ]); const document = DIDDocument.create(did, [didKeypair.didKey()]); @@ -131,14 +131,14 @@ export default function generateDIDModuleTests( expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - document.addServiceEndpoint([did, "service1"], service1); - document.addServiceEndpoint([did, "service2"], service2); + document.addServiceEndpoint([did, 'service1'], service1); + document.addServiceEndpoint([did, 'service2'], service2); await module.updateDocument(document, didKeypair); expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); - document.removeServiceEndpoint([did, "service2"]); + document.removeServiceEndpoint([did, 'service2']); await module.updateDocument(document, didKeypair); @@ -171,15 +171,13 @@ export default function generateDIDModuleTests( expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); document.addKey([did, 3], didKeypair3.didKey()); - await expect(() => - module.updateDocument(document, didKeypair2) - ).rejects.toThrow(); + await expect(() => module.updateDocument(document, didKeypair2)).rejects.toThrow(); await module.updateDocument(document, didKeypair1); expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); }); - test("Removes (deactivates) `DIDDocument`", async () => { + test('Removes (deactivates) `DIDDocument`', async () => { const did = DID.random(); const keyPair = Ed25519Keypair.random(); @@ -192,7 +190,7 @@ export default function generateDIDModuleTests( await module.removeDocument(did, didKeypair); await expect(() => module.getDocument(did)).rejects.toThrow( - new NoDIDError(did) + new NoDIDError(did), ); }); @@ -200,7 +198,7 @@ export default function generateDIDModuleTests( const did = DID.random(); await expect(() => module.getDocument(did)).rejects.toThrow( - new NoDIDError(did) + new NoDIDError(did), ); }); } diff --git a/packages/credential-sdk/src/resolver/did/dock-did-resolver.js b/packages/credential-sdk/src/resolver/did/dock-did-resolver.js index 1926bb727..34fc62ea5 100644 --- a/packages/credential-sdk/src/resolver/did/dock-did-resolver.js +++ b/packages/credential-sdk/src/resolver/did/dock-did-resolver.js @@ -1,9 +1,9 @@ -import { AbstractDIDModule } from "../../modules/did"; -import DIDResolver from "./did-resolver"; -import { ensureInstanceOf } from "../../utils"; +import { AbstractDIDModule } from '../../modules/did'; +import DIDResolver from './did-resolver'; +import { ensureInstanceOf } from '../../utils'; class DockDIDResolver extends DIDResolver { - static METHOD = "dock"; + static METHOD = 'dock'; /** * @param {DockAPI} dock - An initialized connection to a dock full-node. diff --git a/packages/credential-sdk/src/types/accumulator/index.js b/packages/credential-sdk/src/types/accumulator/index.js index d7f6ebd6a..ee0f2393c 100644 --- a/packages/credential-sdk/src/types/accumulator/index.js +++ b/packages/credential-sdk/src/types/accumulator/index.js @@ -1,5 +1,7 @@ -import { DIDRef } from "../did"; -import { TypedBytes, TypedUUID, sized, withFrom } from "../generic"; +import { DIDRef } from '../did'; +import { + TypedBytes, TypedUUID, sized, withFrom, +} from '../generic'; export class AccumulatorId extends DIDRef {} @@ -12,7 +14,7 @@ export class CheqdAccumulatorId extends AccumulatorId { export class DockAccumulatorIdIdent extends withFrom( sized(TypedBytes), // eslint-disable-next-line no-use-before-define - (value, from) => (value instanceof DockAccumulatorId ? value[1] : from(value)) + (value, from) => (value instanceof DockAccumulatorId ? value[1] : from(value)), ) { static Size = 32; } @@ -21,8 +23,8 @@ export class DockAccumulatorId extends AccumulatorId { static Ident = DockAccumulatorIdIdent; } -export * from "./keys"; -export * from "./params"; -export * from "./public-key"; -export * from "./accumulator"; -export * from "./counters"; +export * from './keys'; +export * from './params'; +export * from './public-key'; +export * from './accumulator'; +export * from './counters'; diff --git a/packages/credential-sdk/src/types/blob/blob-id.js b/packages/credential-sdk/src/types/blob/blob-id.js index 70952e14f..721cfd5d1 100644 --- a/packages/credential-sdk/src/types/blob/blob-id.js +++ b/packages/credential-sdk/src/types/blob/blob-id.js @@ -1,8 +1,10 @@ -import { encodeAsSS58, decodeFromSS58 } from "../../utils/ss58"; -import { isHex } from "../../utils/bytes"; -import { TypedBytes, TypedUUID, sized, withQualifier } from "../generic"; -import { CheqdBlobQualifier, DockBlobQualifier } from "./const"; -import { CheqdMainnetDid, CheqdTestnetDid, DIDRef } from "../did"; +import { encodeAsSS58, decodeFromSS58 } from '../../utils/ss58'; +import { isHex } from '../../utils/bytes'; +import { + TypedBytes, TypedUUID, sized, withQualifier, +} from '../generic'; +import { CheqdBlobQualifier, DockBlobQualifier } from './const'; +import { CheqdMainnetDid, CheqdTestnetDid, DIDRef } from '../did'; export class CheqdBlobId extends DIDRef { static Qualifier = CheqdBlobQualifier; @@ -10,11 +12,11 @@ export class CheqdBlobId extends DIDRef { static Ident = TypedUUID; toEncodedString() { - let prefix = ""; + let prefix = ''; if (this[0].value instanceof CheqdTestnetDid) { - prefix = "testnet"; + prefix = 'testnet'; } else if (this[0].value instanceof CheqdMainnetDid) { - prefix = "mainnet"; + prefix = 'mainnet'; } return `${prefix}:${this.value}`; diff --git a/packages/credential-sdk/src/types/did/document.js b/packages/credential-sdk/src/types/did/document.js index 13dbe9bc8..046946c57 100644 --- a/packages/credential-sdk/src/types/did/document.js +++ b/packages/credential-sdk/src/types/did/document.js @@ -1,6 +1,6 @@ -import { base58btc } from "multiformats/bases/base58"; -import varint from "varint"; -import bs58 from "bs58"; +import { base58btc } from 'multiformats/bases/base58'; +import varint from 'varint'; +import bs58 from 'bs58'; import { Null, TypedArray, @@ -15,22 +15,22 @@ import { option, withFrom, withQualifier, -} from "../generic"; -import { LinkedDomains } from "./offchain"; -import { NamespaceDid } from "./onchain/typed-did"; -import { DidKey, DidKeyValue, DidKeys } from "./onchain/did-key"; -import { VerificationRelationship } from "./onchain/verification-relationship"; +} from '../generic'; +import { LinkedDomains } from './offchain'; +import { NamespaceDid } from './onchain/typed-did'; +import { DidKey, DidKeyValue, DidKeys } from './onchain/did-key'; +import { VerificationRelationship } from './onchain/verification-relationship'; import { EcdsaSecp256k1VerKeyName, Ed255192020VerKeyName, Ed25519VerKeyName, Sr25519VerKeyName, -} from "../../vc/custom_crypto"; +} from '../../vc/custom_crypto'; import { PublicKeyEd25519, PublicKeySecp256k1, PublicKeySr25519, -} from "../public-keys"; +} from '../public-keys'; import { fmtIter, isBytes, @@ -38,7 +38,7 @@ import { u8aToString, valueBytes, withExtendedStaticProperties, -} from "../../utils"; +} from '../../utils'; import { BBDT16PublicKey, BBDT16PublicKeyValue, @@ -48,12 +48,11 @@ import { BBSPublicKeyValue, PSPublicKey, PSPublicKeyValue, -} from "../offchain-signatures"; +} from '../offchain-signatures'; -export const ATTESTS_IRI = - "https://rdf.dock.io/alpha/2021#attestsDocumentContents"; +export const ATTESTS_IRI = 'https://rdf.dock.io/alpha/2021#attestsDocumentContents'; -export const CONTEXT_URI = "https://www.w3.org/ns/did/v1"; +export const CONTEXT_URI = 'https://www.w3.org/ns/did/v1'; class Context extends TypedArray { static Class = TypedString; @@ -73,47 +72,47 @@ class VerificationMethodType extends TypedEnum {} class Ed25519Verification2018Method extends VerificationMethodType { static Class = Null; - static Type = "Ed25519VerificationKey2018"; + static Type = 'Ed25519VerificationKey2018'; } class Ed25519Verification2020Method extends VerificationMethodType { static Class = Null; - static Type = "Ed25519VerificationKey2020"; + static Type = 'Ed25519VerificationKey2020'; } class Sr25519Verification2020Method extends VerificationMethodType { static Class = Null; - static Type = "Sr25519VerificationKey2020"; + static Type = 'Sr25519VerificationKey2020'; } class EcdsaSecp256k1VerificationKey2019 extends VerificationMethodType { static Class = Null; - static Type = "EcdsaSecp256k1VerificationKey2019"; + static Type = 'EcdsaSecp256k1VerificationKey2019'; } class X25519KeyAgreementKey2019 extends VerificationMethodType { static Class = Null; - static Type = "X25519KeyAgreementKey2019"; + static Type = 'X25519KeyAgreementKey2019'; } class Bls12381G2VerificationKeyDock2022 extends VerificationMethodType { static Class = Null; - static Type = "Bls12381G2VerificationKeyDock2022"; + static Type = 'Bls12381G2VerificationKeyDock2022'; } class Bls12381BBSVerificationKeyDock2023 extends VerificationMethodType { static Class = Null; - static Type = "Bls12381BBSVerificationKeyDock2023"; + static Type = 'Bls12381BBSVerificationKeyDock2023'; } class Bls12381BBDT16VerificationKeyDock2024 extends VerificationMethodType { static Class = Null; - static Type = "Bls12381BBDT16VerificationKeyDock2024"; + static Type = 'Bls12381BBDT16VerificationKeyDock2024'; } class Bls12381PSVerificationKeyDock2023 extends VerificationMethodType { static Class = Null; - static Type = "Bls12381PSVerificationKeyDock2023"; + static Type = 'Bls12381PSVerificationKeyDock2023'; } VerificationMethodType.bindVariants( Ed25519Verification2018Method, @@ -124,19 +123,18 @@ VerificationMethodType.bindVariants( Bls12381G2VerificationKeyDock2022, Bls12381BBSVerificationKeyDock2023, Bls12381BBDT16VerificationKeyDock2024, - Bls12381PSVerificationKeyDock2023 + Bls12381PSVerificationKeyDock2023, ); export class TypedNumberOrTypedString extends withFrom( TypedNumber, - (value, from) => - !Number.isNaN(Number(value)) || value instanceof TypedNumber - ? from(value) - : TypedString.from(value) + (value, from) => (!Number.isNaN(Number(value)) || value instanceof TypedNumber + ? from(value) + : TypedString.from(value)), ) {} export class VerificationMethodRef extends withQualifier(TypedTuple) { - static Qualifier = ""; + static Qualifier = ''; static Classes = [NamespaceDid, TypedNumber]; @@ -172,7 +170,7 @@ export class VerificationMethodRef extends withQualifier(TypedTuple) { } export class IdentRef extends withQualifier(TypedTuple) { - static Qualifier = ""; + static Qualifier = ''; static Ident = TypedString; @@ -223,14 +221,14 @@ export class VerificationMethodRefOrIdentRef extends withFrom( } catch { return IdentRef.from(value); } - } + }, ) {} export class DidKeyValueWithRef extends withFrom( TypedStruct, function (value, from) { - if (typeof value === "string") { - const [ref, key] = value.split("="); + if (typeof value === 'string') { + const [ref, key] = value.split('='); // eslint-disable-next-line no-use-before-define const parsed = JSON.parse(u8aToString(new PublicKeyBase58(key).bytes)); @@ -238,7 +236,7 @@ export class DidKeyValueWithRef extends withFrom( } else { return from(value); } - } + }, ) { static Classes = { ref: VerificationMethodRef, @@ -251,7 +249,7 @@ export class DidKeyValueWithRef extends withFrom( this.ref, this.key.constructor.VerKeyType, this.ref.did, - this.key.value.bytes + this.key.value.bytes, ); } @@ -273,12 +271,12 @@ export class VerificationMethodRefOrKey extends withFrom( } catch (err) { return from(value); } - } + }, ) {} export class PublicKeyBase58 extends TypedString { constructor(value) { - if (typeof value === "string") { + if (typeof value === 'string') { // Decoding base58 if the input is a string super(bs58.decode(value)); } else { @@ -295,15 +293,15 @@ export class PublicKeyBase58 extends TypedString { } export class PublicKeyMultibase extends withExtendedStaticProperties( - ["Prefix"], - TypedString + ['Prefix'], + TypedString, ) { // Define the static prefix as a class variable static Prefix; constructor(value) { - if (typeof value === "string") { - if (value.startsWith("z")) { + if (typeof value === 'string') { + if (value.startsWith('z')) { // Decode base58btc multibase string const decoded = base58btc.decode(value); varint.decode(decoded); // Decode to get byte length @@ -343,7 +341,7 @@ export class CheqdEd25519Key extends PublicKeyMultibase { export class PublicKeyBase64 extends TypedString { constructor(value) { - if (typeof value === "string") { + if (typeof value === 'string') { super(atob(value)); } else { super(value); @@ -356,11 +354,9 @@ export class PublicKeyBase64 extends TypedString { } // eslint-disable-next-line no-use-before-define -export class VerificationMethod extends withFrom(TypedStruct, (value, from) => - value instanceof CheqdVerificationMethod - ? value.toVerificationMethod() - : from(value) -) { +export class VerificationMethod extends withFrom(TypedStruct, (value, from) => (value instanceof CheqdVerificationMethod + ? value.toVerificationMethod() + : from(value))) { static Classes = { id: VerificationMethodRef, type: VerificationMethodType, @@ -373,27 +369,27 @@ export class VerificationMethod extends withFrom(TypedStruct, (value, from) => isOffchain() { return !( - this.type instanceof Ed25519Verification2018Method || - this.type instanceof Ed25519Verification2020Method + this.type instanceof Ed25519Verification2018Method + || this.type instanceof Ed25519Verification2020Method ); } publicKey() { const bytes = ( - this.publicKeyBase58 || - this.publicKeyBase64 || - this.publicKeyJwk || - this.publicKeyHex + this.publicKeyBase58 + || this.publicKeyBase64 + || this.publicKeyJwk + || this.publicKeyHex )?.bytes; if (bytes == null) { throw new Error( `Expected either of ${fmtIter([ - "publicKeyBase58", - "publicKeyBase64", - "publicKeyJwk", - "publicKeyHex", - ])} to be specified` + 'publicKeyBase58', + 'publicKeyBase64', + 'publicKeyJwk', + 'publicKeyHex', + ])} to be specified`, ); } @@ -426,7 +422,7 @@ export class VerificationMethod extends withFrom(TypedStruct, (value, from) => ref, didKey.publicKey.constructor.VerKeyType, ref[0], - valueBytes(didKey.publicKey) + valueBytes(didKey.publicKey), ); } @@ -436,7 +432,7 @@ export class VerificationMethod extends withFrom(TypedStruct, (value, from) => this.id, this.controller, this.type, - valueBytes(this.publicKey()) + valueBytes(this.publicKey()), ); } @@ -447,10 +443,9 @@ export class VerificationMethod extends withFrom(TypedStruct, (value, from) => export class CheqdVerificationMethod extends withFrom( TypedStruct, - (value, from) => - value instanceof VerificationMethod - ? value.toCheqdVerificationMethod() - : from(value) + (value, from) => (value instanceof VerificationMethod + ? value.toCheqdVerificationMethod() + : from(value)), ) { static Classes = { id: VerificationMethodRef, @@ -461,8 +456,8 @@ export class CheqdVerificationMethod extends withFrom( isOffchain() { return !( - this.verificationMethodType instanceof Ed25519Verification2018Method || - this.verificationMethodType instanceof Ed25519Verification2020Method + this.verificationMethodType instanceof Ed25519Verification2018Method + || this.verificationMethodType instanceof Ed25519Verification2020Method ); } @@ -471,7 +466,7 @@ export class CheqdVerificationMethod extends withFrom( this.id, this.verificationMethodType, this.controller, - this.verificationMaterial + this.verificationMaterial, ); } } @@ -484,8 +479,7 @@ export class ServiceEndpointId extends IdentRef {} export class SuffixServiceEndpointId extends withFrom( TypedString, - (value, from) => - from(isBytes(value) ? value : ServiceEndpointId.from(value)[1]) + (value, from) => from(isBytes(value) ? value : ServiceEndpointId.from(value)[1]), ) {} export class Service extends TypedStruct { @@ -507,9 +501,7 @@ export class Service extends TypedStruct { } } -export class CheqdService extends withFrom(TypedStruct, (value, from) => - value instanceof Service ? value.toCheqdService() : from(value) -) { +export class CheqdService extends withFrom(TypedStruct, (value, from) => (value instanceof Service ? value.toCheqdService() : from(value))) { static Classes = { id: ServiceEndpointId, serviceType: LinkedDomains, @@ -539,7 +531,7 @@ class AssertionMethod extends TypedArray { export class DIDDocument extends TypedStruct { static Classes = { - "@context": Context, + '@context': Context, id: ID, alsoKnownAs: option(AlsoKnownAs), controller: Controllers, @@ -563,7 +555,7 @@ export class DIDDocument extends TypedStruct { alsoKnownAs = [], capabilityDelegation = [], [ATTESTS_IRI]: attests = null, - } = {} + } = {}, ) { const doc = new this( context, @@ -577,7 +569,7 @@ export class DIDDocument extends TypedStruct { [], [], capabilityDelegation, - attests + attests, ); let idx = 0; @@ -654,9 +646,7 @@ export class DIDDocument extends TypedStruct { removeKey(keyRef) { const ref = VerificationMethodRef.from(keyRef); - const keyIndex = this.verificationMethod.findIndex((method) => - method.id.eq(ref) - ); + const keyIndex = this.verificationMethod.findIndex((method) => method.id.eq(ref)); // eslint-disable-next-line no-bitwise if (~keyIndex) { @@ -680,7 +670,7 @@ export class DIDDocument extends TypedStruct { return ( [...this.verificationMethod].reduce( (max, { id: { index } }) => Math.max(max, index ?? 0), - 0 + 0, ) + 1 ); } @@ -746,7 +736,7 @@ export class DIDDocument extends TypedStruct { toCheqd(versionId = TypedUUID.random()) { const { - "@context": context, + '@context': context, id, alsoKnownAs, controller, @@ -772,7 +762,7 @@ export class DIDDocument extends TypedStruct { keyAgreement, capabilityInvocation, capabilityDelegation, - versionId + versionId, ); } } @@ -804,14 +794,12 @@ export class CheqdDIDDocument extends TypedStruct { ...this.verificationMethod.filter((verMethod) => verMethod.isOffchain()), ].map((verMethod) => verMethod.toVerificationMethod()); this.verificationMethod = this.verificationMethod.filter( - (verMethod) => !verMethod.isOffchain() + (verMethod) => !verMethod.isOffchain(), ); this.assertionMethod = [ ...this.assertionMethod, - ...[...offchainVerMethod].map((verMethod) => - verMethod.toDidKeyValueWithRef() - ), + ...[...offchainVerMethod].map((verMethod) => verMethod.toDidKeyValueWithRef()), ]; } @@ -832,11 +820,11 @@ export class CheqdDIDDocument extends TypedStruct { const offchainVerMethod = [ ...assertionMethod.filter( - (keyRefOrKey) => keyRefOrKey instanceof DidKeyValueWithRef + (keyRefOrKey) => keyRefOrKey instanceof DidKeyValueWithRef, ), ].map((verMethod) => verMethod.toVerificationMethod()); const assertionMethodWithoutOffchainKeys = assertionMethod.filter( - (keyRefOrKey) => !(keyRefOrKey instanceof DidKeyValueWithRef) + (keyRefOrKey) => !(keyRefOrKey instanceof DidKeyValueWithRef), ); return new DIDDocument( @@ -851,7 +839,7 @@ export class CheqdDIDDocument extends TypedStruct { keyAgreement, capabilityInvocation, capabilityDelegation, - null + null, ); } } diff --git a/packages/credential-sdk/src/types/did/onchain/index.js b/packages/credential-sdk/src/types/did/onchain/index.js index f540c6a2b..17480ce25 100644 --- a/packages/credential-sdk/src/types/did/onchain/index.js +++ b/packages/credential-sdk/src/types/did/onchain/index.js @@ -1,11 +1,11 @@ -import { Null, TypedNumber, TypedStruct } from "../../generic"; - -export * from "./constants"; -export * from "./typed-did"; -export * from "./controllers"; -export * from "./verification-relationship"; -export * from "./did-key"; -export * from "./verification-method-signature"; +import { Null, TypedNumber, TypedStruct } from '../../generic'; + +export * from './constants'; +export * from './typed-did'; +export * from './controllers'; +export * from './verification-relationship'; +export * from './did-key'; +export * from './verification-method-signature'; export class DidMethodKeyDetails extends TypedStruct { static Classes = { diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/cheqd-did.js b/packages/credential-sdk/src/types/did/onchain/typed-did/cheqd-did.js index 590db16ea..8df748078 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/cheqd-did.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/cheqd-did.js @@ -2,9 +2,9 @@ import { CheqdDIDQualifier, CheqdDIDTestnetQualifier, CheqdDIDMainnetQualifier, -} from "../constants"; -import { TypedEnum, withQualifier } from "../../../generic"; -import TypedUUID from "../../../generic/typed-uuid"; +} from '../constants'; +import { TypedEnum, withQualifier } from '../../../generic'; +import TypedUUID from '../../../generic/typed-uuid'; /** * `did:cheqd:*` @@ -42,12 +42,12 @@ export class CheqdDid extends withQualifier(TypedEnum, true) { export class CheqdTestnetDid extends CheqdDid { static Class = CheqdTestnetDidValue; - static Type = "testnet"; + static Type = 'testnet'; } export class CheqdMainnetDid extends CheqdDid { static Class = CheqdMainnetDidValue; - static Type = "mainnet"; + static Type = 'mainnet'; } CheqdDid.bindVariants(CheqdTestnetDid, CheqdMainnetDid); diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-public-key.js b/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-public-key.js index 164b79208..e7a4557f3 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-public-key.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-public-key.js @@ -1,25 +1,25 @@ -import bs58 from "bs58"; -import { base58btc } from "multiformats/bases/base58"; -import varint from "varint"; -import { TypedEnum, TypedStruct, withQualifier } from "../../../../generic"; +import bs58 from 'bs58'; +import { base58btc } from 'multiformats/bases/base58'; +import varint from 'varint'; +import { TypedEnum, TypedStruct, withQualifier } from '../../../../generic'; import { PublicKeyEd25519Value, PublicKeySecp256k1Value, -} from "../../../../public-keys"; +} from '../../../../public-keys'; import { DidMethodKeyBytePrefixEd25519, DidMethodKeyBytePrefixSecp256k1, DidMethodKeyQualifier, Ed25519PublicKeyPrefix, Secp256k1PublicKeyPrefix, -} from "../../constants"; -import DidOrDidMethodKeySignature from "../signature"; -import { DidMethodKeySignatureValue } from "./did-method-key-signature"; +} from '../../constants'; +import DidOrDidMethodKeySignature from '../signature'; +import { DidMethodKeySignatureValue } from './did-method-key-signature'; export class DidMethodKeyPublicKey extends withQualifier(TypedEnum) { static Qualifier = DidMethodKeyQualifier; - static Type = "didMethodKey"; + static Type = 'didMethodKey'; /** * Instantiates `DidMethodKey` from a fully qualified did string. @@ -73,13 +73,13 @@ export class DidMethodKeyPublicKey extends withQualifier(TypedEnum) { signWith(keyPair, bytes) { if (!this.eq(this.constructor.fromKeypair(keyPair))) { - throw new Error("Expected keypair that has the same key as in `this`"); + throw new Error('Expected keypair that has the same key as in `this`'); } // eslint-disable-next-line no-use-before-define return new DidMethodKeySignature( // eslint-disable-next-line no-use-before-define - new DidMethodKeySignatureValueObject(this, keyPair.sign(bytes)) + new DidMethodKeySignatureValueObject(this, keyPair.sign(bytes)), ); } } @@ -92,7 +92,7 @@ export class DidMethodKeySignatureValueObject extends TypedStruct { } export class DidMethodKeySignature extends DidOrDidMethodKeySignature { - static Type = "didMethodKeySignature"; + static Type = 'didMethodKeySignature'; static Class = DidMethodKeySignatureValueObject; } @@ -114,5 +114,5 @@ export class DidMethodKeyPublicKeySecp256k1 extends DidMethodKeyPublicKey { DidMethodKeyPublicKey.bindVariants( DidMethodKeyPublicKeyEd25519, - DidMethodKeyPublicKeySecp256k1 + DidMethodKeyPublicKeySecp256k1, ); diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-signature.js b/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-signature.js index 6cde4521b..8d8d85fbb 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-signature.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/did-method-key/did-method-key-signature.js @@ -1,8 +1,8 @@ -import { TypedEnum } from "../../../../generic"; +import { TypedEnum } from '../../../../generic'; import { SignatureEd25519Value, SignatureSecp256k1Value, -} from "../../../../signatures"; +} from '../../../../signatures'; export class DidMethodKeySignatureValue extends TypedEnum {} export class DidMethodKeySignatureValueEd25519 extends DidMethodKeySignatureValue { @@ -14,5 +14,5 @@ export class DidMethodKeySignatureValueSecp256k1 extends DidMethodKeySignatureVa DidMethodKeySignatureValue.bindVariants( DidMethodKeySignatureValueEd25519, - DidMethodKeySignatureValueSecp256k1 + DidMethodKeySignatureValueSecp256k1, ); diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/dock-did-value.js b/packages/credential-sdk/src/types/did/onchain/typed-did/dock-did-value.js index 1225d2e14..e04d4fbc7 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/dock-did-value.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/dock-did-value.js @@ -1,14 +1,14 @@ -import { DockDIDQualifier } from "../constants"; -import { decodeFromSS58, encodeAsSS58, isHex } from "../../../../utils"; +import { DockDIDQualifier } from '../constants'; +import { decodeFromSS58, encodeAsSS58, isHex } from '../../../../utils'; import { withQualifier, TypedBytes, sized, TypedNumber, TypedStruct, -} from "../../../generic"; -import DidOrDidMethodKeySignature from "./signature"; -import { Signature } from "../../../signatures"; +} from '../../../generic'; +import DidOrDidMethodKeySignature from './signature'; +import { Signature } from '../../../signatures'; /** * `did:dock:*` @@ -16,7 +16,7 @@ import { Signature } from "../../../signatures"; export default class DockDidValue extends sized(withQualifier(TypedBytes)) { static Qualifier = DockDIDQualifier; - static Type = "did"; + static Type = 'did'; static Size = 32; @@ -34,7 +34,8 @@ export default class DockDidValue extends sized(withQualifier(TypedBytes)) { signWith(keyPair, bytes) { // eslint-disable-next-line no-use-before-define return new DockDidSignature( - new DockDidSignatureValue(this, keyPair.keyId, keyPair.sign(bytes)) + // eslint-disable-next-line no-use-before-define + new DockDidSignatureValue(this, keyPair.keyId, keyPair.sign(bytes)), ); } } @@ -48,7 +49,7 @@ export class DockDidSignatureValue extends TypedStruct { } export class DockDidSignature extends DidOrDidMethodKeySignature { - static Type = "didSignature"; + static Type = 'didSignature'; static Class = DockDidSignatureValue; } diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/index.js b/packages/credential-sdk/src/types/did/onchain/typed-did/index.js index 0cbc11b17..0468fd14d 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/index.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/index.js @@ -1,9 +1,9 @@ -import { DidMethodKeyPublicKey, DidMethodKeySignature } from "./did-method-key"; -import DockDidValue, { DockDidSignature } from "./dock-did-value"; -import { TypedEnum, TypedTuple, withQualifier } from "../../../generic"; -import { CheqdDid } from "./cheqd-did"; -import { withExtendedStaticProperties } from "../../../../utils"; -import DidOrDidMethodKeySignature from "./signature"; +import { DidMethodKeyPublicKey, DidMethodKeySignature } from './did-method-key'; +import DockDidValue, { DockDidSignature } from './dock-did-value'; +import { TypedEnum, TypedTuple, withQualifier } from '../../../generic'; +import { CheqdDid } from './cheqd-did'; +import { withExtendedStaticProperties } from '../../../../utils'; +import DidOrDidMethodKeySignature from './signature'; export const DockDidOrDidMethodKey = withQualifier( class DockDidOrDidMethodKey extends TypedEnum { @@ -50,7 +50,7 @@ export const DockDidOrDidMethodKey = withQualifier( async changeState(api, method, name, payload, keyRef) { return await method( payload, - await this.signStateChange(api, name, payload, keyRef) + await this.signStateChange(api, name, payload, keyRef), ); } @@ -83,7 +83,7 @@ export const DockDidOrDidMethodKey = withQualifier( } } }, - true + true, ); export class DockDid extends DockDidOrDidMethodKey { @@ -146,25 +146,25 @@ export const NamespaceDid = withQualifier( return super.from( value instanceof DockDidOrDidMethodKey && value.isDid ? { dock: value.asDid } - : value + : value, ); } }, - true + true, ); class DockNamespaceDid extends NamespaceDid { - static Type = "dock"; + static Type = 'dock'; static Class = DockDidValueToString; } class DidNamespaceKey extends NamespaceDid { - static Type = "didMethodKey"; + static Type = 'didMethodKey'; static Class = DidMethodKeyPublicKeyToString; } class CheqdNamespaceDid extends NamespaceDid { - static Type = "cheqd"; + static Type = 'cheqd'; static Class = CheqdDid; } @@ -172,10 +172,10 @@ class CheqdNamespaceDid extends NamespaceDid { NamespaceDid.bindVariants(DockNamespaceDid, DidNamespaceKey, CheqdNamespaceDid); export class DIDRef extends withExtendedStaticProperties( - ["Ident"], - withQualifier(TypedTuple) + ['Ident'], + withQualifier(TypedTuple), ) { - static Qualifier = ""; + static Qualifier = ''; static get Classes() { return [NamespaceDid, this.Ident]; @@ -218,8 +218,8 @@ export class DIDRef extends withExtendedStaticProperties( DidOrDidMethodKeySignature.bindVariants( DockDidSignature, - DidMethodKeySignature + DidMethodKeySignature, ); export { DockDidValue, DidMethodKeyPublicKey }; -export * from "./cheqd-did"; +export * from './cheqd-did'; diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/signature.js b/packages/credential-sdk/src/types/did/onchain/typed-did/signature.js index 3eea5507d..bb6818d40 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/signature.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/signature.js @@ -1,3 +1,3 @@ -import { TypedEnum } from "../../../generic"; +import { TypedEnum } from '../../../generic'; export default class DidOrDidMethodKeySignature extends TypedEnum {} diff --git a/packages/credential-sdk/src/types/generic/typed-enum.js b/packages/credential-sdk/src/types/generic/typed-enum.js index fbd42a136..742993e1c 100644 --- a/packages/credential-sdk/src/types/generic/typed-enum.js +++ b/packages/credential-sdk/src/types/generic/typed-enum.js @@ -1,19 +1,19 @@ /* eslint-disable max-classes-per-file */ -import { fmtIter } from "../../utils/generic"; +import { fmtIter } from '../../utils/generic'; import { isEqualToOrPrototypeOf, withExtendedStaticProperties, -} from "../../utils/inheritance"; +} from '../../utils/inheritance'; import { maybeEq, maybeFrom, maybeNew, maybeToJSON, -} from "../../utils/interfaces"; -import withBase from "./with-base"; -import Null from "./typed-null"; -import withCatchNull from "./with-catch-null"; -import withEq from "./with-eq"; +} from '../../utils/interfaces'; +import withBase from './with-base'; +import Null from './typed-null'; +import withCatchNull from './with-catch-null'; +import withEq from './with-eq'; /** * @template V @@ -197,17 +197,17 @@ class TypedEnum extends withBase(class EnumBase {}) { static fromJSON(json) { if (json == null) { throw new Error( - `Received \`null\` while object was expected by \`${this.name}\`` + `Received \`null\` while object was expected by \`${this.name}\``, ); } - if (typeof json === "string" && this.isNullish) { + if (typeof json === 'string' && this.isNullish) { if (this.Class != null) { if (this.JsonType === json || this.Type === json) { return maybeNew(this, []); } throw new Error( - `Unexpected json in \`${this}\`: \`${json}\`, expected \`${this.JsonType}\`` + `Unexpected json in \`${this}\`: \`${json}\`, expected \`${this.JsonType}\``, ); } else { for (const Variant of this.Variants) { @@ -218,8 +218,8 @@ class TypedEnum extends withBase(class EnumBase {}) { throw new Error( `Unexpected json in \`${this}\`: \`${json}\`, expected one of ${fmtIter( - new Set([...this.Variants].flatMap((v) => [v.JsonType, v.Type])) - )}` + new Set([...this.Variants].flatMap((v) => [v.JsonType, v.Type])), + )}`, ); } } @@ -228,8 +228,8 @@ class TypedEnum extends withBase(class EnumBase {}) { if (keys.length !== 1) { throw new Error( `Expected object with 1 key, received \`${json}\` with keys: ${fmtIter( - keys - )} by ${this.name}` + keys, + )} by ${this.name}`, ); } const [key] = keys; @@ -240,7 +240,7 @@ class TypedEnum extends withBase(class EnumBase {}) { } throw new Error( - `Unexpected key \`${key}\`, expected \`${this.JsonType}\` by \`${this.name}\`` + `Unexpected key \`${key}\`, expected \`${this.JsonType}\` by \`${this.name}\``, ); } else { for (const Variant of this.Variants) { @@ -251,8 +251,8 @@ class TypedEnum extends withBase(class EnumBase {}) { throw new Error( `Invalid key \`${key}\`, expected one of ${fmtIter( - new Set([...this.Variants].flatMap((v) => [v.JsonType, v.Type])) - )} by \`${this.name}\`` + new Set([...this.Variants].flatMap((v) => [v.JsonType, v.Type])), + )} by \`${this.name}\``, ); } } @@ -263,7 +263,7 @@ class TypedEnum extends withBase(class EnumBase {}) { return maybeNew(this, [obj[this.asIdentifier]]); } else { throw new Error( - `Incompatible value provided: \`${obj}\` to \`${this}\`` + `Incompatible value provided: \`${obj}\` to \`${this}\``, ); } } else { @@ -276,23 +276,19 @@ class TypedEnum extends withBase(class EnumBase {}) { throw new Error( `Invalid object received: \`${maybeToJSON( - obj + obj, )}\`, expected to build an instance of ${fmtIter( - this.Variants.map((v) => v.Type) - )} by \`${this.name}\`` + this.Variants.map((v) => v.Type), + )} by \`${this.name}\``, ); } static variant(obj) { - return this.Variants.find((variant) => - isEqualToOrPrototypeOf(variant.Class, obj?.constructor ?? Null) - ); + return this.Variants.find((variant) => isEqualToOrPrototypeOf(variant.Class, obj?.constructor ?? Null)); } static directVariant(obj) { - return this.Variants.find((variant) => - isEqualToOrPrototypeOf(variant, obj?.constructor ?? Null) - ); + return this.Variants.find((variant) => isEqualToOrPrototypeOf(variant, obj?.constructor ?? Null)); } static get isNullish() { @@ -304,7 +300,7 @@ class TypedEnum extends withBase(class EnumBase {}) { static from(obj) { if (obj instanceof this) { return obj; - } else if (typeof obj === "string" && this.isNullish) { + } else if (typeof obj === 'string' && this.isNullish) { return this.fromJSON(obj); } else if (Object.getPrototypeOf(obj) === Object.getPrototypeOf({})) { return this.fromJSON(obj); @@ -337,5 +333,5 @@ class TypedEnum extends withBase(class EnumBase {}) { } export default withEq( - withCatchNull(withExtendedStaticProperties(["Variants"], TypedEnum)) + withCatchNull(withExtendedStaticProperties(['Variants'], TypedEnum)), ); diff --git a/packages/credential-sdk/src/types/generic/with-qualifier.js b/packages/credential-sdk/src/types/generic/with-qualifier.js index f158a0fd9..ad81b883d 100644 --- a/packages/credential-sdk/src/types/generic/with-qualifier.js +++ b/packages/credential-sdk/src/types/generic/with-qualifier.js @@ -1,13 +1,13 @@ -import { ID_STR } from "@docknetwork/crypto-wasm-ts"; -import TypedBytes from "./typed-bytes"; +import { ID_STR } from '@docknetwork/crypto-wasm-ts'; +import TypedBytes from './typed-bytes'; import { withExtendedStaticProperties, withExtendedPrototypeProperties, -} from "../../utils/inheritance"; -import { maybeFrom } from "../../utils/interfaces"; -import withFrom from "./with-from"; -import { fmtIter } from "../../utils"; -import TypedString from "./typed-string"; +} from '../../utils/inheritance'; +import { maybeFrom } from '../../utils/interfaces'; +import withFrom from './with-from'; +import { fmtIter } from '../../utils'; +import TypedString from './typed-string'; /** * Extends supplied class. diff --git a/packages/dock-blockchain-modules/src/common/dock-api-provider.js b/packages/dock-blockchain-modules/src/common/dock-api-provider.js index 759f8f1f7..97dd0e3ae 100644 --- a/packages/dock-blockchain-modules/src/common/dock-api-provider.js +++ b/packages/dock-blockchain-modules/src/common/dock-api-provider.js @@ -1,21 +1,21 @@ -import { ApiProvider } from "@docknetwork/credential-sdk/modules/common"; -import { ensureInstanceOf } from "@docknetwork/credential-sdk/utils/type-helpers"; -import { DockDIDModuleInternal } from "../did/internal"; +import { ApiProvider } from '@docknetwork/credential-sdk/modules/common'; +import { ensureInstanceOf } from '@docknetwork/credential-sdk/utils/type-helpers'; +import { DockDIDModuleInternal } from '../did/internal'; class DockApiProvider extends ApiProvider { constructor(dock) { super(); this.dock = ensureInstanceOf(dock, ApiProvider); - if (typeof dock.getAllExtrinsicsFromBlock !== "function") { - throw new Error("`getAllExtrinsicsFromBlock` must be a function"); + if (typeof dock.getAllExtrinsicsFromBlock !== 'function') { + throw new Error('`getAllExtrinsicsFromBlock` must be a function'); } } get api() { const { api } = this.dock; if (!api.isConnected) { - throw new Error("API is not connected"); + throw new Error('API is not connected'); } return api; @@ -32,12 +32,12 @@ class DockApiProvider extends ApiProvider { async getAllExtrinsicsFromBlock(numberOrHash, includeFailedExtrinsics) { return await this.dock.getAllExtrinsicsFromBlock( numberOrHash, - includeFailedExtrinsics + includeFailedExtrinsics, ); } async didNonce(did) { - return typeof this.dock.didNonce === "function" + return typeof this.dock.didNonce === 'function' ? await this.dock.didNonce(did) : await new DockDIDModuleInternal(this).nonce(did); } diff --git a/packages/dock-blockchain-modules/src/did/module.js b/packages/dock-blockchain-modules/src/did/module.js index 8ededeb71..9c867b063 100644 --- a/packages/dock-blockchain-modules/src/did/module.js +++ b/packages/dock-blockchain-modules/src/did/module.js @@ -1,18 +1,18 @@ -import bs58 from "bs58"; -import { AbstractDIDModule } from "@docknetwork/credential-sdk/modules/did"; +import bs58 from 'bs58'; +import { AbstractDIDModule } from '@docknetwork/credential-sdk/modules/did'; import { DockDid, DockDidOrDidMethodKey, -} from "@docknetwork/credential-sdk/types"; +} from '@docknetwork/credential-sdk/types'; import { DIDDocument, Service, CONTEXT_URI, -} from "@docknetwork/credential-sdk/types/did/document"; -import { DockDIDModuleInternal } from "./internal"; -import injectDock from "../common/inject-dock"; -import DockAttestModule from "../attest/module"; -import DockOffchainSignaturesModule from "../offchain-signatures/module"; +} from '@docknetwork/credential-sdk/types/did/document'; +import { DockDIDModuleInternal } from './internal'; +import injectDock from '../common/inject-dock'; +import DockAttestModule from '../attest/module'; +import DockOffchainSignaturesModule from '../offchain-signatures/module'; export default class DockDIDModule extends injectDock(AbstractDIDModule) { static DockOnly = DockDIDModuleInternal; @@ -32,25 +32,25 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { controller, service, id, - "@context": context, + '@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." + '`service` is not supported in the `createDocument` transaction. Use `updateDocument` to add `service` to the existing document.', ); } else if (capabilityDelegation?.length) { - throw new Error("Capability delegation is not supported"); + 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." + '`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, - ]}\`, received: \`${context}\`` + ]}\`, received: \`${context}\``, ); } @@ -68,113 +68,99 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { removed: removedMethods, modified, } = nextDocument.didKeys().diff(currentDocument.didKeys()); - const { added: newControllers, removed: removedControllers } = - nextDocument.controller.diff(currentDocument.controller); - const { added: newServices, removed: removedServices } = - nextDocument.service.diff(currentDocument.service); + const { added: newControllers, removed: removedControllers } = nextDocument.controller.diff(currentDocument.controller); + const { added: newServices, removed: removedServices } = nextDocument.service.diff(currentDocument.service); const newOnChainKeys = [...newMethods].filter( - ([_, key]) => !key.isOffchain() - ); - const newOffchainKeys = [...newMethods].filter(([_, key]) => - key.isOffchain() + ([_, key]) => !key.isOffchain(), ); + const newOffchainKeys = [...newMethods].filter(([_, key]) => key.isOffchain()); const removedOnChainKeys = [...removedMethods].filter( - ([_, key]) => !key.isOffchain() - ); - const removedOffchainKeys = [...removedMethods].filter(([_, key]) => - key.isOffchain() + ([_, key]) => !key.isOffchain(), ); + const removedOffchainKeys = [...removedMethods].filter(([_, key]) => key.isOffchain()); if (modified.size) { throw new Error("Can't have modified verificationMethods"); } else if ( - nextDocument.attests && - !nextDocument.attests.eq(currentDocument.attests) + 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." + '`attests` modifications are not supported in the `updateDocument` transaction. Use `attest` module to attach `attests` to the existing document.', ); } if ( - [...newMethods.keys()].find((method) => !method.did.eq(didDocument.id)) || - [...removedMethods.keys()].find( - (method) => !method.did.eq(didDocument.id) + [...newMethods.keys()].find((method) => !method.did.eq(didDocument.id)) + || [...removedMethods.keys()].find( + (method) => !method.did.eq(didDocument.id), ) ) { throw new Error("Can't change controller keys"); } - const { id: docId, "@context": context } = nextDocument; + const { id: docId, '@context': context } = nextDocument; const did = DockDidOrDidMethodKey.from(docId); if (context.length !== 1 || context[0].value !== CONTEXT_URI) { throw new Error( `Context must be equal to \`${[ CONTEXT_URI, - ]}\`, received: \`${context}\`` + ]}\`, received: \`${context}\``, ); } const nonce = await this.dockOnly.apiProvider.didNonce(signerDid); const txs = [ - newOnChainKeys.length && - this.dockOnly.tx.addKeys( + newOnChainKeys.length + && this.dockOnly.tx.addKeys( [...newOnChainKeys].map(([_, key]) => key), did, didKeypair, - nonce.inc() + nonce.inc(), ), - newControllers.length && - this.dockOnly.tx.addControllers( + newControllers.length + && this.dockOnly.tx.addControllers( newControllers, did, didKeypair, - nonce.inc() + nonce.inc(), ), - ...newOffchainKeys.map(([_, key]) => - this.offchainSignatures.dockOnly.tx.addPublicKey( - key.publicKey, - did, - didKeypair, - nonce.inc() - ) - ), - ...[...newServices].map(({ id, type, serviceEndpoint }) => - this.dockOnly.tx.addServiceEndpoint( - id, - type, - serviceEndpoint, - did, - didKeypair, - nonce.inc() - ) - ), - ...[...removedServices].map(({ id }) => - this.dockOnly.tx.removeServiceEndpoint(id, didKeypair, nonce.inc()) - ), - ...removedOffchainKeys.map(([{ index }]) => - this.offchainSignatures.dockOnly.tx.removePublicKey( - index, - did, - didKeypair, - nonce.inc() - ) - ), - removedControllers.length && - this.dockOnly.tx.removeControllers( + ...newOffchainKeys.map(([_, key]) => this.offchainSignatures.dockOnly.tx.addPublicKey( + key.publicKey, + did, + didKeypair, + nonce.inc(), + )), + ...[...newServices].map(({ id, type, serviceEndpoint }) => this.dockOnly.tx.addServiceEndpoint( + id, + type, + serviceEndpoint, + did, + didKeypair, + nonce.inc(), + )), + ...[...removedServices].map(({ id }) => this.dockOnly.tx.removeServiceEndpoint(id, didKeypair, nonce.inc())), + ...removedOffchainKeys.map(([{ index }]) => this.offchainSignatures.dockOnly.tx.removePublicKey( + index, + did, + didKeypair, + nonce.inc(), + )), + removedControllers.length + && this.dockOnly.tx.removeControllers( removedControllers, did, didKeypair, - nonce.inc() + nonce.inc(), ), - removedOnChainKeys.length && - this.dockOnly.tx.removeKeys( + removedOnChainKeys.length + && this.dockOnly.tx.removeKeys( [...removedOnChainKeys].map(([{ index }]) => index), did, didKeypair, - nonce.inc() + nonce.inc(), ), ]; @@ -204,7 +190,7 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { const hexDid = typedDid.asDid; const { data: didDetails } = await this.dockOnly.getOnchainDidDetail( - hexDid + hexDid, ); // Get DIDs attestations @@ -214,10 +200,9 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { const id = String(typedDid); // Get controllers - const controllers = - didDetails.activeControllers > 0 - ? await this.dockOnly.controllers(typedDid) - : []; + const controllers = didDetails.activeControllers > 0 + ? await this.dockOnly.controllers(typedDid) + : []; // Get service endpoints const serviceEndpoints = await this.dockOnly.serviceEndpoints(hexDid); @@ -281,9 +266,7 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { const capabilityInvocation = capInv.map((i) => `${id}#keys-${i}`); const keyAgreement = keyAgr.map((i) => `${id}#keys-${i}`); - const service = [...serviceEndpoints].map(([spId, sp]) => - Service.fromServiceEndpoint(spId, sp) - ); + const service = [...serviceEndpoints].map(([spId, sp]) => Service.fromServiceEndpoint(spId, sp)); // Construct document return new DIDDocument( @@ -298,7 +281,7 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { keyAgreement, capabilityInvocation, [], - attests + attests, ); } } diff --git a/packages/dock-blockchain-modules/src/trust-registry/internal.js b/packages/dock-blockchain-modules/src/trust-registry/internal.js index f24aba8b5..fd630287a 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/internal.js +++ b/packages/dock-blockchain-modules/src/trust-registry/internal.js @@ -2,29 +2,28 @@ import { DidMethodKey, DockDid, DockDidOrDidMethodKey, -} from "@docknetwork/credential-sdk/types/did"; +} from '@docknetwork/credential-sdk/types/did'; import { isHexWithGivenByteSize, u8aToHex, -} from "@docknetwork/credential-sdk/utils/bytes"; -import { ensureMatchesPattern } from "@docknetwork/credential-sdk/utils/misc"; -import { IssuersSet } from "@docknetwork/credential-sdk/types/trust-registry"; -import { maybeToJSON } from "@docknetwork/credential-sdk/utils"; -import { createInternalDockModule } from "../common"; +} from '@docknetwork/credential-sdk/utils/bytes'; +import { ensureMatchesPattern } from '@docknetwork/credential-sdk/utils/misc'; +import { IssuersSet } from '@docknetwork/credential-sdk/types/trust-registry'; +import { maybeToJSON } from '@docknetwork/credential-sdk/utils'; +import { createInternalDockModule } from '../common'; -const callValueMethodOrObjectMethod = (method) => (value) => - typeof value[method] === "function" - ? [...value[method]()] - : Object[method](value); +const callValueMethodOrObjectMethod = (method) => (value) => (typeof value[method] === 'function' + ? [...value[method]()] + : Object[method](value)); -const entries = callValueMethodOrObjectMethod("entries"); -const values = callValueMethodOrObjectMethod("values"); +const entries = callValueMethodOrObjectMethod('entries'); +const values = callValueMethodOrObjectMethod('values'); /** * `Trust Registry` module. */ export default class DockInternalTrustRegistryModule extends createInternalDockModule() { - static Prop = "trustRegistry"; + static Prop = 'trustRegistry'; /** * Returns Trust Registries information according to the supplied `by` argument. @@ -36,7 +35,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseRegistryInfo, - await this.rpc.registriesInfoBy(by) + await this.rpc.registriesInfoBy(by), ); } @@ -52,7 +51,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseSchemaMetadata, - await this.rpc.registrySchemaMetadataBy(by, regId) + await this.rpc.registrySchemaMetadataBy(by, regId), ); } @@ -66,7 +65,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM async schemaMetadataInRegistry(schemaId, regId) { return this.parseSingleEntry( this.parseSchemaMetadata, - await this.rpc.schemaMetadataInRegistry(schemaId, regId) + await this.rpc.schemaMetadataInRegistry(schemaId, regId), ); } @@ -80,7 +79,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseSchemaMetadata, - await this.rpc.schemaMetadata(schemaId) + await this.rpc.schemaMetadata(schemaId), ); } @@ -94,7 +93,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM async schemaIssuersInRegistry(schemaId, regId) { return this.parseSingleEntry( this.parseSchemaIssuers, - await this.rpc.schemaIssuersInRegistry(schemaId, regId) + await this.rpc.schemaIssuersInRegistry(schemaId, regId), ); } @@ -108,7 +107,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseSchemaIssuers, - await this.rpc.schemaIssuers(schemaId) + await this.rpc.schemaIssuers(schemaId), ); } @@ -122,7 +121,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM async schemaVerifiersInRegistry(schemaId, regId) { return this.parseSingleEntry( this.parseSchemaVerifiers, - await this.rpc.schemaVerifiersInRegistry(schemaId, regId) + await this.rpc.schemaVerifiersInRegistry(schemaId, regId), ); } @@ -136,7 +135,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return this.parseMapEntries( String, this.parseSchemaVerifiers, - await this.rpc.schemaVerifiers(schemaId) + await this.rpc.schemaVerifiers(schemaId), ); } @@ -168,14 +167,14 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM const participantWithInfo = async (did) => { const info = await this.query.trustRegistryParticipantsInformation( registryId, - did + did, ); return [did, info.isSome ? info.unwrap().toJSON() : null]; }; return Object.fromEntries( - await Promise.all(participants.map(participantWithInfo)) + await Promise.all(participants.map(participantWithInfo)), ); } @@ -195,14 +194,14 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM name, govFramework, signingKeyRef, - params = {} + params = {}, ) { const tx = await this.initOrUpdateTx( convenerDid, registryId, name, govFramework, - signingKeyRef + signingKeyRef, ); return await this.signAndSend(tx, params); } @@ -223,24 +222,24 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM name, govFramework, signingKeyRef, - nonce + nonce, ) { const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce( convenerDid, - nonce + nonce, ); return await convenerHexDid.changeState( this.apiProvider, this.rawTx.initOrUpdateTrustRegistry, - "InitOrUpdateTrustRegistry", + 'InitOrUpdateTrustRegistry', { registryId, name, govFramework, nonce: lastNonce, }, - signingKeyRef + signingKeyRef, ); } @@ -260,17 +259,16 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, participants, signingKeyRef, - nonce + nonce, ) { - const [convenerOrIssuerOrVerifierHexDid, lastNonce] = - await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); + const [convenerOrIssuerOrVerifierHexDid, lastNonce] = await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); return { sig: await convenerOrIssuerOrVerifierHexDid.signStateChange( this.apiProvider, - "ChangeParticipants", + 'ChangeParticipants', { data: { registryId, participants }, nonce: lastNonce }, - signingKeyRef + signingKeyRef, ), nonce: lastNonce, }; @@ -294,12 +292,12 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM participants, sigs, waitForFinalization = true, - params = {} + params = {}, ) { return await this.signAndSend( await this.changeParticipantsTx(registryId, participants, sigs), waitForFinalization, - params + params, ); } @@ -314,7 +312,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM async changeParticipantsTx(registryId, participants, sigs) { ensureMatchesPattern( this.constructor.ChangeParticipantsPattern, - participants + participants, ); return this.rawTx.changeParticipants( @@ -322,7 +320,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, participants, }, - sigs + sigs, ); } @@ -342,20 +340,19 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM participant, participantInformation, signingKeyRef, - nonce + nonce, ) { - const [convenerOrIssuerOrVerifierHexDid, lastNonce] = - await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); + const [convenerOrIssuerOrVerifierHexDid, lastNonce] = await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); return { sig: await convenerOrIssuerOrVerifierHexDid.signStateChange( this.apiProvider, - "SetParticipantInformation", + 'SetParticipantInformation', { data: { registryId, participant, participantInformation }, nonce: lastNonce, }, - signingKeyRef + signingKeyRef, ), nonce: lastNonce, }; @@ -377,17 +374,17 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM participantInformation, sigs, waitForFinalization = true, - params = {} + params = {}, ) { return await this.signAndSend( await this.setParticipantInformationTx( registryId, participant, participantInformation, - sigs + sigs, ), waitForFinalization, - params + params, ); } @@ -404,11 +401,11 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, participant, participantInformation, - sigs + sigs, ) { ensureMatchesPattern( this.constructor.SetParticipantInformationPattern, - participantInformation + participantInformation, ); return this.rawTx.setParticipantInformation( @@ -417,7 +414,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM participant, participantInformation, }, - sigs + sigs, ); } @@ -435,13 +432,13 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, schemas, signingKeyRef, - params = {} + params = {}, ) { const tx = await this.setSchemasMetadataTx( convenerOrIssuerOrVerifierDid, registryId, schemas, - signingKeyRef + signingKeyRef, ); return await this.signAndSend(tx, params); } @@ -462,18 +459,17 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, schemas, signingKeyRef, - nonce + nonce, ) { - const [convenerOrIssuerOrVerifierHexDid, lastNonce] = - await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); + const [convenerOrIssuerOrVerifierHexDid, lastNonce] = await this.getActorDidAndNonce(convenerOrIssuerOrVerifierDid, nonce); ensureMatchesPattern(this.constructor.SchemasUpdatePattern, schemas); return await convenerOrIssuerOrVerifierHexDid.changeState( this.apiProvider, this.rawTx.setSchemasMetadata, - "SetSchemasMetadata", + 'SetSchemasMetadata', { registryId, schemas, nonce: lastNonce }, - signingKeyRef + signingKeyRef, ); } @@ -491,13 +487,13 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, issuers, signingKeyRef, - params = {} + params = {}, ) { const tx = await this.suspendIssuersTx( convenerDid, registryId, issuers, - signingKeyRef + signingKeyRef, ); return await this.signAndSend(tx, params); } @@ -516,11 +512,11 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, rawIssuers, signingKeyRef, - nonce + nonce, ) { const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce( convenerDid, - nonce + nonce, ); const hexIssuers = IssuersSet.from(rawIssuers); @@ -528,9 +524,9 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return await convenerHexDid.changeState( this.apiProvider, this.rawTx.suspendIssuers, - "SuspendIssuers", + 'SuspendIssuers', { registryId, issuers: hexIssuers, nonce: lastNonce }, - signingKeyRef + signingKeyRef, ); } @@ -548,13 +544,13 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, issuers, signingKeyRef, - params = {} + params = {}, ) { const tx = await this.unsuspendIssuersTx( convenerDid, registryId, issuers, - signingKeyRef + signingKeyRef, ); return await this.signAndSend(tx, params); } @@ -573,11 +569,11 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM registryId, rawIssuers, signingKeyRef, - nonce + nonce, ) { const [convenerHexDid, lastNonce] = await this.getActorDidAndNonce( convenerDid, - nonce + nonce, ); const issuers = IssuersSet.from(rawIssuers); @@ -585,9 +581,9 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM return await convenerHexDid.changeState( this.apiProvider, this.rawTx.unsuspendIssuers, - "UnsuspendIssuers", + 'UnsuspendIssuers', { registryId, issuers, nonce: lastNonce }, - signingKeyRef + signingKeyRef, ); } @@ -609,23 +605,23 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM signingKeyRef, nonce, waitForFinalization = true, - params = {} + params = {}, ) { const [issuerHexDid, lastNonce] = await this.getActorDidAndNonce( issuerDid, - nonce + nonce, ); return await this.signAndSend( await issuerHexDid.changeState( this.apiProvider, this.rawTx.updateDelegatedIssuers, - "UpdateDelegatedIssuers", + 'UpdateDelegatedIssuers', { registryId, delegated, nonce: lastNonce }, - signingKeyRef + signingKeyRef, ), waitForFinalization, - params + params, ); } @@ -676,7 +672,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM keyParser.call(this, key), valueParser.call(this, value), ]) - .sort(([key1], [key2]) => key1.localeCompare(key2)) + .sort(([key1], [key2]) => key1.localeCompare(key2)), ); } @@ -729,7 +725,7 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM String(DockDidOrDidMethodKey.from(issuer)), maybeToJSON(info), ]) - .sort(([iss1], [iss2]) => iss1.localeCompare(iss2)) + .sort(([iss1], [iss2]) => iss1.localeCompare(iss2)), ); } @@ -751,7 +747,7 @@ const DockDidOrDidMethodKeyPattern = { }; const VerificationPricePattern = { - $anyOf: [{ $matchType: "number" }, { $matchType: "object" }], + $anyOf: [{ $matchType: 'number' }, { $matchType: 'object' }], }; const Hex32Pattern = { @@ -773,9 +769,9 @@ const VerifiersUpdatePattern = { DockDidOrDidMethodKeyPattern, { $anyOf: [ - { $matchValue: "Remove" }, + { $matchValue: 'Remove' }, { - $matchValue: "Add", + $matchValue: 'Add', }, ], }, @@ -784,16 +780,16 @@ const VerifiersUpdatePattern = { const IssuerPricesPattern = { // $instanceOf: BTreeMap, - $mapOf: [{ $matchType: "string" }, VerificationPricePattern], + $mapOf: [{ $matchType: 'string' }, VerificationPricePattern], }; const IssuerPricesUpdatePattern = { // $instanceOf: BTreeMap, $mapOf: [ - { $matchType: "string" }, + { $matchType: 'string' }, { $anyOf: [ - { $matchValue: "Remove" }, + { $matchValue: 'Remove' }, { $objOf: { Add: VerificationPricePattern, @@ -872,7 +868,7 @@ const ModifySchemasPattern = { }, }, { - $matchValue: "Remove", + $matchValue: 'Remove', }, ], }, @@ -892,13 +888,13 @@ const AnyOfOrAllDockDidOrDidMethodKeyPattern = { DockInternalTrustRegistryModule.SetParticipantInformationPattern = { $matchObject: { orgName: { - $matchType: "string", + $matchType: 'string', }, logo: { - $matchType: "string", + $matchType: 'string', }, description: { - $matchType: "string", + $matchType: 'string', }, }, }; @@ -914,10 +910,10 @@ DockInternalTrustRegistryModule.ChangeParticipantsPattern = { { $anyOf: [ { - $matchValue: "Add", + $matchValue: 'Add', }, { - $matchValue: "Remove", + $matchValue: 'Remove', }, ], }, diff --git a/packages/dock-blockchain-modules/src/trust-registry/module.js b/packages/dock-blockchain-modules/src/trust-registry/module.js index 443856789..b57c5dfc1 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/module.js +++ b/packages/dock-blockchain-modules/src/trust-registry/module.js @@ -1,17 +1,17 @@ -import { AbstractTrustRegistryModule } from "@docknetwork/credential-sdk/modules/trust-registry"; +import { AbstractTrustRegistryModule } from '@docknetwork/credential-sdk/modules/trust-registry'; import { TrustRegistryInfo, DockTrustRegistryId, TrustRegistries, TrustRegistry, DockDidOrDidMethodKey, -} from "@docknetwork/credential-sdk/types"; -import { option } from "@docknetwork/credential-sdk/types/generic"; -import { injectDock } from "../common"; -import DockInternalTrustRegistryModule from "./internal"; +} from '@docknetwork/credential-sdk/types'; +import { option } from '@docknetwork/credential-sdk/types/generic'; +import { injectDock } from '../common'; +import DockInternalTrustRegistryModule from './internal'; export default class DockTrustRegistryModule extends injectDock( - AbstractTrustRegistryModule + AbstractTrustRegistryModule, ) { static DockOnly = DockInternalTrustRegistryModule; @@ -37,8 +37,8 @@ export default class DockTrustRegistryModule extends injectDock( return new TrustRegistries( await Promise.all( - [...ids].map(async (id) => [id, await this.getRegistry(id)]) - ) + [...ids].map(async (id) => [id, await this.getRegistry(id)]), + ), ); } @@ -50,7 +50,7 @@ export default class DockTrustRegistryModule extends injectDock( info.name, info.govFramework, didKeypair, - nonce + nonce, ); const setSchemas = await this.dockOnly.setSchemasMetadataTx( @@ -58,7 +58,7 @@ export default class DockTrustRegistryModule extends injectDock( id, { Set: schemas }, didKeypair, - nonce.inc() + nonce.inc(), ); return await this.dockOnly.apiProvider.batchAll([init, setSchemas]); From e9a131feed799f1df30140b73bcab9b269a9a24b Mon Sep 17 00:00:00 2001 From: olegnn Date: Thu, 17 Oct 2024 17:30:59 +0200 Subject: [PATCH 03/11] Bump up versions --- examples/CHANGELOG.md | 16 ++++++++++++++++ examples/package.json | 8 ++++---- packages/cheqd-blockchain-api/CHANGELOG.md | 9 +++++++++ packages/cheqd-blockchain-api/package.json | 2 +- packages/cheqd-blockchain-modules/CHANGELOG.md | 14 ++++++++++++++ packages/cheqd-blockchain-modules/package.json | 6 +++--- packages/credential-sdk/CHANGELOG.md | 9 +++++++++ packages/credential-sdk/package.json | 2 +- packages/dock-blockchain-api/CHANGELOG.md | 14 ++++++++++++++ packages/dock-blockchain-api/package.json | 4 ++-- packages/dock-blockchain-modules/CHANGELOG.md | 14 ++++++++++++++ packages/dock-blockchain-modules/package.json | 6 +++--- 12 files changed, 90 insertions(+), 14 deletions(-) diff --git a/examples/CHANGELOG.md b/examples/CHANGELOG.md index 9a813319b..ba66dc420 100644 --- a/examples/CHANGELOG.md +++ b/examples/CHANGELOG.md @@ -1,5 +1,21 @@ # @docknetwork/sdk-examples +## 0.2.0 + +### Minor Changes + +- - Updated `DIDDocument`: modified the rules for storing keys in the verificationMethod and added the required validations. + - Developed generic tests for modules to ensure they cover the same use cases, regardless of the specific implementation. + - Implemented the `CheqdBlobModule`. + - Misc tweaks. + +### Patch Changes + +- Updated dependencies + - @docknetwork/dock-blockchain-modules@0.3.0 + - @docknetwork/dock-blockchain-api@0.2.0 + - @docknetwork/credential-sdk@0.3.0 + ## 0.1.2 ### Patch Changes diff --git a/examples/package.json b/examples/package.json index ae3ad5875..3e2bf0532 100644 --- a/examples/package.json +++ b/examples/package.json @@ -2,7 +2,7 @@ "name": "@docknetwork/sdk-examples", "private": true, "type": "module", - "version": "0.1.2", + "version": "0.2.0", "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.2.0", - "@docknetwork/dock-blockchain-api": "0.1.2", - "@docknetwork/dock-blockchain-modules": "0.2.0" + "@docknetwork/credential-sdk": "0.3.0", + "@docknetwork/dock-blockchain-api": "0.2.0", + "@docknetwork/dock-blockchain-modules": "0.3.0" }, "devDependencies": { "babel-eslint": "^10.1.0", diff --git a/packages/cheqd-blockchain-api/CHANGELOG.md b/packages/cheqd-blockchain-api/CHANGELOG.md index c9c7cf4ef..f6b2d0f81 100644 --- a/packages/cheqd-blockchain-api/CHANGELOG.md +++ b/packages/cheqd-blockchain-api/CHANGELOG.md @@ -1,5 +1,14 @@ # @docknetwork/cheqd-blockchain-api +## 0.2.0 + +### Minor Changes + +- - Updated `DIDDocument`: modified the rules for storing keys in the verificationMethod and added the required validations. + - Developed generic tests for modules to ensure they cover the same use cases, regardless of the specific implementation. + - Implemented the `CheqdBlobModule`. + - Misc tweaks. + ## 0.1.2 ### Patch Changes diff --git a/packages/cheqd-blockchain-api/package.json b/packages/cheqd-blockchain-api/package.json index a5daf9d7e..ba6a10d20 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.2", + "version": "0.2.0", "license": "MIT", "main": "./dist/esm/index.js", "type": "module", diff --git a/packages/cheqd-blockchain-modules/CHANGELOG.md b/packages/cheqd-blockchain-modules/CHANGELOG.md index 354e05df7..1b5a60d2d 100644 --- a/packages/cheqd-blockchain-modules/CHANGELOG.md +++ b/packages/cheqd-blockchain-modules/CHANGELOG.md @@ -1,5 +1,19 @@ # @docknetwork/cheqd-blockchain-modules +## 0.3.0 + +### Minor Changes + +- - Updated `DIDDocument`: modified the rules for storing keys in the verificationMethod and added the required validations. + - Developed generic tests for modules to ensure they cover the same use cases, regardless of the specific implementation. + - Implemented the `CheqdBlobModule`. + - Misc tweaks. + +### Patch Changes + +- Updated dependencies + - @docknetwork/credential-sdk@0.3.0 + ## 0.2.0 ### Minor Changes diff --git a/packages/cheqd-blockchain-modules/package.json b/packages/cheqd-blockchain-modules/package.json index 5e3ceb6ea..7e9d65c1e 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.2.0", + "version": "0.3.0", "type": "module", "license": "MIT", "main": "./dist/esm/index.js", @@ -28,7 +28,7 @@ "node": ">=18.0.0" }, "dependencies": { - "@docknetwork/credential-sdk": "0.2.0" + "@docknetwork/credential-sdk": "0.3.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.2", + "@docknetwork/cheqd-blockchain-api": "0.2.0", "@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 c90e717d0..abeb424a5 100644 --- a/packages/credential-sdk/CHANGELOG.md +++ b/packages/credential-sdk/CHANGELOG.md @@ -1,5 +1,14 @@ # @docknetwork/credential-sdk +## 0.3.0 + +### Minor Changes + +- - Updated `DIDDocument`: modified the rules for storing keys in the verificationMethod and added the required validations. + - Developed generic tests for modules to ensure they cover the same use cases, regardless of the specific implementation. + - Implemented the `CheqdBlobModule`. + - Misc tweaks. + ## 0.2.0 ### Minor Changes diff --git a/packages/credential-sdk/package.json b/packages/credential-sdk/package.json index 9878e001b..c67c61b45 100644 --- a/packages/credential-sdk/package.json +++ b/packages/credential-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@docknetwork/credential-sdk", - "version": "0.2.0", + "version": "0.3.0", "license": "MIT", "type": "module", "files": [ diff --git a/packages/dock-blockchain-api/CHANGELOG.md b/packages/dock-blockchain-api/CHANGELOG.md index 9874d03dc..b91d5747f 100644 --- a/packages/dock-blockchain-api/CHANGELOG.md +++ b/packages/dock-blockchain-api/CHANGELOG.md @@ -1,5 +1,19 @@ # @docknetwork/dock-blockchain-api +## 0.2.0 + +### Minor Changes + +- - Updated `DIDDocument`: modified the rules for storing keys in the verificationMethod and added the required validations. + - Developed generic tests for modules to ensure they cover the same use cases, regardless of the specific implementation. + - Implemented the `CheqdBlobModule`. + - Misc tweaks. + +### Patch Changes + +- Updated dependencies + - @docknetwork/credential-sdk@0.3.0 + ## 0.1.2 ### Patch Changes diff --git a/packages/dock-blockchain-api/package.json b/packages/dock-blockchain-api/package.json index 3f32cccf6..f71ebcb7f 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.2", + "version": "0.2.0", "license": "MIT", "main": "./dist/esm/index.js", "type": "module", @@ -84,7 +84,7 @@ "@polkadot/api": "10.12.4" }, "dependencies": { - "@docknetwork/credential-sdk": "0.2.0", + "@docknetwork/credential-sdk": "0.3.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 e23ee1e96..7c8995f3b 100644 --- a/packages/dock-blockchain-modules/CHANGELOG.md +++ b/packages/dock-blockchain-modules/CHANGELOG.md @@ -1,5 +1,19 @@ # @docknetwork/dock-blockchain-modules +## 0.3.0 + +### Minor Changes + +- - Updated `DIDDocument`: modified the rules for storing keys in the verificationMethod and added the required validations. + - Developed generic tests for modules to ensure they cover the same use cases, regardless of the specific implementation. + - Implemented the `CheqdBlobModule`. + - Misc tweaks. + +### Patch Changes + +- Updated dependencies + - @docknetwork/credential-sdk@0.3.0 + ## 0.2.0 ### Minor Changes diff --git a/packages/dock-blockchain-modules/package.json b/packages/dock-blockchain-modules/package.json index fbb4f9dd2..33bdf12ff 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.2.0", + "version": "0.3.0", "license": "MIT", "type": "module", "main": "./dist/esm/index.js", @@ -28,7 +28,7 @@ "node": ">=18.0.0" }, "dependencies": { - "@docknetwork/credential-sdk": "0.2.0" + "@docknetwork/credential-sdk": "0.3.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.2", + "@docknetwork/dock-blockchain-api": "0.2.0", "@rollup/plugin-alias": "^4.0.2", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^24.0.0", From c32280aafcdde212d10285e13ebc01a2a2acadb9 Mon Sep 17 00:00:00 2001 From: olegnn Date: Thu, 17 Oct 2024 23:16:46 +0200 Subject: [PATCH 04/11] Tweaks --- .../src/generate-tests/attest-module.js | 2 +- .../src/generate-tests/blob-module.js | 2 +- .../src/generate-tests/did-module.js | 3 +- .../src/types/did/onchain/typed-did/index.js | 6 ++++ .../src/types/generic/with-eq.js | 4 ++- .../src/types/generic/with-qualifier.js | 28 +++++++++++++------ .../tests/__snapshots__/document.test.js.snap | 2 +- .../credential-sdk/tests/document.test.js | 2 +- 8 files changed, 34 insertions(+), 15 deletions(-) diff --git a/packages/credential-sdk/src/generate-tests/attest-module.js b/packages/credential-sdk/src/generate-tests/attest-module.js index d9e9f2b01..b9080469b 100644 --- a/packages/credential-sdk/src/generate-tests/attest-module.js +++ b/packages/credential-sdk/src/generate-tests/attest-module.js @@ -10,7 +10,7 @@ export default function generateAttestModuleTests( ) { const test = itIf(filter); - test('Generates a `DIDDocument` and appends an attestation to it', async () => { + test('Generates a `DIDDocument` and appends an `Attest` to it', async () => { const did = DID.random(); const keyPair = Ed25519Keypair.random(); diff --git a/packages/credential-sdk/src/generate-tests/blob-module.js b/packages/credential-sdk/src/generate-tests/blob-module.js index b40f58d4e..5b2e72fb4 100644 --- a/packages/credential-sdk/src/generate-tests/blob-module.js +++ b/packages/credential-sdk/src/generate-tests/blob-module.js @@ -7,7 +7,7 @@ export default function generateBlobModuleTests( { did: didModule, blob: blobModule }, { DID, BlobId }, ) { - it('Generates a `DIDDocument` and creates a blob owned by this DID', async () => { + it('Generates a `DIDDocument` and creates a `Blob` owned by this DID', async () => { const did = DID.random(); const keyPair = Ed25519Keypair.random(); diff --git a/packages/credential-sdk/src/generate-tests/did-module.js b/packages/credential-sdk/src/generate-tests/did-module.js index d1c0c67b5..754737c14 100644 --- a/packages/credential-sdk/src/generate-tests/did-module.js +++ b/packages/credential-sdk/src/generate-tests/did-module.js @@ -54,7 +54,7 @@ export default function generateDIDModuleTests( expect((await module.getDocument(did)).toJSON()).toEqual(document.toJSON()); }); - test('Updates with `DIDDocument` containing BBS/BBSPlus/PS keys', async () => { + test('Updates `DIDDocument` containing BBS/BBSPlus/PS keys', async () => { const did = DID.random(); const keyPair = Ed25519Keypair.random(); @@ -105,7 +105,6 @@ export default function generateDIDModuleTests( service1, service2, }); - console.log(document.toJSON()); await module.createDocument(document, didKeypair); diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/index.js b/packages/credential-sdk/src/types/did/onchain/typed-did/index.js index 0468fd14d..127de52e7 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/index.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/index.js @@ -154,16 +154,22 @@ export const NamespaceDid = withQualifier( ); class DockNamespaceDid extends NamespaceDid { + static Qualifier = 'did:dock:'; + static Type = 'dock'; static Class = DockDidValueToString; } class DidNamespaceKey extends NamespaceDid { + static Qualifier = 'did:key:'; + static Type = 'didMethodKey'; static Class = DidMethodKeyPublicKeyToString; } class CheqdNamespaceDid extends NamespaceDid { + static Qualifier = 'did:cheqd:'; + static Type = 'cheqd'; static Class = CheqdDid; diff --git a/packages/credential-sdk/src/types/generic/with-eq.js b/packages/credential-sdk/src/types/generic/with-eq.js index a9e1414e6..ca9db2137 100644 --- a/packages/credential-sdk/src/types/generic/with-eq.js +++ b/packages/credential-sdk/src/types/generic/with-eq.js @@ -17,7 +17,9 @@ export default function withEq(klass) { return false; } else if (Object.is(this, other)) { return true; - } else if (!isEqualToOrPrototypeOf(klass, other.constructor)) { + } else if ( + !isEqualToOrPrototypeOf(this.constructor, other.constructor) + ) { let compareWith; try { compareWith = this.constructor.from(other); diff --git a/packages/credential-sdk/src/types/generic/with-qualifier.js b/packages/credential-sdk/src/types/generic/with-qualifier.js index ad81b883d..b928a7db2 100644 --- a/packages/credential-sdk/src/types/generic/with-qualifier.js +++ b/packages/credential-sdk/src/types/generic/with-qualifier.js @@ -95,10 +95,6 @@ export default function withQualifier(klass, wrapper = false) { toString() { return this.value.toString(); } - - eq(other) { - return String(this) === String(other); - } }, }; @@ -109,6 +105,19 @@ export default function withQualifier(klass, wrapper = false) { } else { return this.fromQualifiedString(String(value)); } + } else if ( + value?.constructor?.Qualifier != null && + !this.Qualifiers.find((qualifier) => + value.constructor.Qualifier.startsWith(qualifier) + ) + ) { + throw new Error( + `Value has a different qualifier: \`${ + value.constructor.Qualifier + }\` while expected one of \`${fmtIter(this.Qualifiers)}\` by \`${ + this.name + }\`` + ); } else { return from(value); } @@ -169,10 +178,6 @@ export default function withQualifier(klass, wrapper = false) { toString() { return this.toQualifiedEncodedString(); } - - eq(other) { - return String(this) === String(other); - } }, }; @@ -191,6 +196,13 @@ export default function withQualifier(klass, wrapper = false) { } else { return this.fromUnqualifiedString(String(value)); } + } else if ( + value?.constructor?.Qualifier != null && + !value.constructor.Qualifier.startsWith(this.Qualifier) + ) { + throw new Error( + `Value has a different qualifier: \`${value.constructor.Qualifier}\` while expected \`${this.Qualifier}\` by \`${this.name}\`` + ); } else { return from(value); } diff --git a/packages/credential-sdk/tests/__snapshots__/document.test.js.snap b/packages/credential-sdk/tests/__snapshots__/document.test.js.snap index d0c4bd6d2..e3e8252fc 100644 --- a/packages/credential-sdk/tests/__snapshots__/document.test.js.snap +++ b/packages/credential-sdk/tests/__snapshots__/document.test.js.snap @@ -187,7 +187,7 @@ exports[`\`DIDDocument\` \`DIDDocument.create\` works 4`] = ` } `; -exports[`\`DIDDocument\` DIDDocument.from works 1`] = ` +exports[`\`DIDDocument\` \`DIDDocument.from\` works 1`] = ` { "@context": [ "test", diff --git a/packages/credential-sdk/tests/document.test.js b/packages/credential-sdk/tests/document.test.js index 29e5268be..0b25b05af 100644 --- a/packages/credential-sdk/tests/document.test.js +++ b/packages/credential-sdk/tests/document.test.js @@ -26,7 +26,7 @@ describe("`DIDDocument`", () => { const CAP_INV = new VerificationRelationship().setCapabilityInvocation(); const KEY_AGR = new VerificationRelationship().setKeyAgreement(); - test(`DIDDocument.from works`, () => { + test(`\`DIDDocument.from\` works`, () => { const doc = { "@context": ["test"], id: "did:dock:5DEHasvC9G3eVF3qCsN2VQvEbHYdQtsv74ozZ1ngQQj39Luk", From 7964bdd7f7e89726862183b0f72ff4e22b6b0ce9 Mon Sep 17 00:00:00 2001 From: olegnn Date: Fri, 18 Oct 2024 13:50:42 +0200 Subject: [PATCH 05/11] Corrections --- .../src/types/did/onchain/typed-did/index.js | 1 - .../src/types/generic/typed-number.js | 28 ++++++++----------- .../tests/integration/did/did-basic.test.js | 17 +++++------ scripts/with_cheqd_docker_test_node | 8 +++++- scripts/with_dock_docker_test_node | 8 +++++- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/packages/credential-sdk/src/types/did/onchain/typed-did/index.js b/packages/credential-sdk/src/types/did/onchain/typed-did/index.js index 127de52e7..0d6204fd2 100644 --- a/packages/credential-sdk/src/types/did/onchain/typed-did/index.js +++ b/packages/credential-sdk/src/types/did/onchain/typed-did/index.js @@ -29,7 +29,6 @@ export const DockDidOrDidMethodKey = withQualifier( */ async signStateChange(apiProvider, name, payload, keyRef) { const { LOG_STATE_CHANGE } = process.env; - if (Number(LOG_STATE_CHANGE) || Boolean(LOG_STATE_CHANGE)) { console.dir(payload, { depth: null }); } diff --git a/packages/credential-sdk/src/types/generic/typed-number.js b/packages/credential-sdk/src/types/generic/typed-number.js index 64798c95d..aac792b1c 100644 --- a/packages/credential-sdk/src/types/generic/typed-number.js +++ b/packages/credential-sdk/src/types/generic/typed-number.js @@ -17,6 +17,18 @@ class TypedNumber extends withBase(class NumberBase {}) { this.value = num; } + inc() { + return new this.constructor(++this.value); + } + + dec() { + return new this.constructor(--this.value); + } + + toJSON() { + return this.value; + } + static from(value) { if (value instanceof this) { return value; @@ -27,22 +39,6 @@ class TypedNumber extends withBase(class NumberBase {}) { } } - toJSON() { - return this.value; - } - - inc() { - this.value++; - - return this; - } - - dec() { - this.value--; - - return this; - } - static fromJSON(value) { return new this(value); } diff --git a/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js b/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js index b77872cd6..15a6a05dd 100644 --- a/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js +++ b/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js @@ -55,22 +55,19 @@ describe("Basic DID tests", () => { expect(!!dock.account).toBe(true); }); - test("Can create and update document", async () => { + test.only("Can create and update document", async () => { const did = DockDid.random(); const pair = new Ed25519Keypair(seed); - const publicKey = pair.publicKey(); - - const verRels = new VerificationRelationship(); - const didKey = new DidKey(publicKey, verRels); + const didPair = new DidKeypair([did, 1], pair); - const doc = DIDDocument.create(did, [didKey], [did]); + const doc = DIDDocument.create(did, [didPair.didKey()], [did]); await modules.did.createDocument(doc); expect((await modules.did.getDocument(did)).toJSON()).toEqual(doc.toJSON()); const pair2 = Ed25519Keypair.random(); - const didKey2 = new DidKey(pair2.publicKey(), verRels); + const didPair2 = new DidKeypair([did, 2], pair2); const service1 = new ServiceEndpoint("LinkedDomains", [ "ServiceEndpoint#1", @@ -78,10 +75,10 @@ describe("Basic DID tests", () => { doc .addServiceEndpoint([did, "service1"], service1) - .addKey([did, 2], didKey2) + .addKey([did, 2], didPair2.didKey()) .removeKey([did, 1]); - await modules.did.updateDocument(doc, new DidKeypair([did, 1], pair)); + await modules.did.updateDocument(doc, didPair); expect((await modules.did.getDocument(did)).toJSON()).toEqual(doc.toJSON()); @@ -92,7 +89,7 @@ describe("Basic DID tests", () => { doc .removeServiceEndpoint("service1") .addServiceEndpoint([did, "service2"], service2); - await modules.did.updateDocument(doc, new DidKeypair([did, 2], pair2)); + await modules.did.updateDocument(doc, didPair2); expect((await modules.did.getDocument(did)).toJSON()).toEqual(doc.toJSON()); }); diff --git a/scripts/with_cheqd_docker_test_node b/scripts/with_cheqd_docker_test_node index 08dba63ac..d94ed89f5 100755 --- a/scripts/with_cheqd_docker_test_node +++ b/scripts/with_cheqd_docker_test_node @@ -12,12 +12,18 @@ docker pull --platform linux/amd64 ghcr.io/cheqd/cheqd-node # start a pos alice node alice_container_id=$(docker run --platform linux/amd64 -d --rm --name cheqd-dev -p 26656:26656 -p 26657:26657 -p 1317:1317 -p 9090:9090 -e CHEQD_MNEMONIC="$CHEQD_MNEMONIC" -v $entrypoint:/usr/local/bin/entrypoint.sh -v $config:/tmp/cheqd_config.toml --entrypoint /usr/local/bin/entrypoint.sh ghcr.io/cheqd/cheqd-node start) +cleanup() { + docker kill $alice_container_id +} + try_with_node() { sleep 10; # Execute the commands, potentially against the nodes $@ } +trap cleanup SIGINT + if try_with_node $@; then exit_code=$? else @@ -25,6 +31,6 @@ else fi # Kill nodes -docker kill $alice_container_id +cleanup exit $exit_code diff --git a/scripts/with_dock_docker_test_node b/scripts/with_dock_docker_test_node index 7056e46da..a8a938ddf 100755 --- a/scripts/with_dock_docker_test_node +++ b/scripts/with_dock_docker_test_node @@ -17,6 +17,10 @@ alice_container_id=$( --alice --rpc-external --ws-external ) +cleanup() { + docker kill $alice_container_id +} + try_with_node() { # Wait for nodes to start listening for RPC "$root_dir"/scripts/wait_for_node_rpc_http @@ -24,6 +28,8 @@ try_with_node() { $@ } +trap cleanup SIGINT + if try_with_node $@; then exit_code=$? else @@ -31,6 +37,6 @@ else fi # Kill nodes -docker kill $alice_container_id +cleanup exit $exit_code From 866121c8dc6a601efe50329d065448aad5e7343f Mon Sep 17 00:00:00 2001 From: olegnn Date: Fri, 18 Oct 2024 13:53:14 +0200 Subject: [PATCH 06/11] Reenable other tests --- .../tests/integration/did/did-basic.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js b/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js index 15a6a05dd..17f226f74 100644 --- a/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js +++ b/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js @@ -55,7 +55,7 @@ describe("Basic DID tests", () => { expect(!!dock.account).toBe(true); }); - test.only("Can create and update document", async () => { + test("Can create and update document", async () => { const did = DockDid.random(); const pair = new Ed25519Keypair(seed); From d3ae2f39aa7767de995d7421fa59ab0d15d00939 Mon Sep 17 00:00:00 2001 From: olegnn Date: Fri, 18 Oct 2024 14:49:28 +0200 Subject: [PATCH 07/11] Fix arguments --- .../tests/integration/modules/attest-module.test.js | 2 +- .../tests/integration/modules/did-module.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dock-blockchain-modules/tests/integration/modules/attest-module.test.js b/packages/dock-blockchain-modules/tests/integration/modules/attest-module.test.js index 28a185182..85b908695 100644 --- a/packages/dock-blockchain-modules/tests/integration/modules/attest-module.test.js +++ b/packages/dock-blockchain-modules/tests/integration/modules/attest-module.test.js @@ -27,6 +27,6 @@ describe("AttestModule", () => { generateAttestModuleTests( { did: new DockDIDModule(dock), attest: new DockAttestModule(dock) }, - DockDid + { DID: DockDid } ); }); diff --git a/packages/dock-blockchain-modules/tests/integration/modules/did-module.test.js b/packages/dock-blockchain-modules/tests/integration/modules/did-module.test.js index 95383099c..4eb35f615 100644 --- a/packages/dock-blockchain-modules/tests/integration/modules/did-module.test.js +++ b/packages/dock-blockchain-modules/tests/integration/modules/did-module.test.js @@ -26,7 +26,7 @@ describe("DIDModule", () => { didModuleTests( { did: new DockDIDModule(dock) }, - DockDid, + { DID: DockDid }, (name) => name !== "Creates `DIDDocument` containing BBS/BBSPlus/PS keys" && name !== "Creates `DIDDocument` containing services" From a49db126638f727dbfa26093b43b9a9922a21eb8 Mon Sep 17 00:00:00 2001 From: olegnn Date: Fri, 18 Oct 2024 16:50:36 +0200 Subject: [PATCH 08/11] `withDidNonce` --- .../src/attest/module.js | 2 +- .../src/common/builders.js | 70 +++++++++----- .../src/common/dock-api-provider.js | 14 ++- .../dock-blockchain-modules/src/did/module.js | 95 +++++++++---------- .../src/trust-registry/internal.js | 3 +- .../src/trust-registry/module.js | 38 ++++---- .../tests/integration/did/did-basic.test.js | 2 +- .../tests/integration/did/did-key.test.js | 4 +- 8 files changed, 125 insertions(+), 103 deletions(-) diff --git a/packages/dock-blockchain-modules/src/attest/module.js b/packages/dock-blockchain-modules/src/attest/module.js index ec9101158..3578d8b77 100644 --- a/packages/dock-blockchain-modules/src/attest/module.js +++ b/packages/dock-blockchain-modules/src/attest/module.js @@ -11,7 +11,7 @@ export default class DockAttestModule extends injectDock(AbstractAttestModule) { * @return {Promise} The DID's attestation, if any */ async getAttests(did) { - return (await this.dockOnly.attest(did)).iri?.value; + return (await this.dockOnly.attest(did)).iri; } /** diff --git a/packages/dock-blockchain-modules/src/common/builders.js b/packages/dock-blockchain-modules/src/common/builders.js index 8be1d880d..5256a65a7 100644 --- a/packages/dock-blockchain-modules/src/common/builders.js +++ b/packages/dock-blockchain-modules/src/common/builders.js @@ -29,20 +29,32 @@ export const createDIDMethodWithPolicyTx = (fnName) => { const [didKeypair] = args.slice(root.payload[fnName].length - 2); const { did: signer } = ensureInstanceOf(didKeypair, DidKeypair); - // eslint-disable-next-line no-param-reassign - args[root.payload[fnName].length - 1] - ??= await root.apiProvider.nextDidNonce(didKeypair.did); - const { data, nonce } = root.payload[fnName].apply(this.root, args); - - const sig = await DockDidOrDidMethodKey.from(signer).signStateChange( - root.apiProvider, - root.constructor.MethodNameOverrides?.[fnName] - ?? fnNameToMethodName(fnName), - { data, nonce }, - didKeypair, - ); - return await root.rawTx[fnName](data, [{ sig, nonce }]); + const signStateChange = async (maybeDidNonce) => { + // eslint-disable-next-line no-param-reassign + args[root.payload[fnName].length - 1] ??= maybeDidNonce.inc(); + + const { data, nonce } = root.payload[fnName].apply(this.root, args); + + const sig = await DockDidOrDidMethodKey.from(signer).signStateChange( + root.apiProvider, + root.constructor.MethodNameOverrides?.[fnName] + ?? fnNameToMethodName(fnName), + { data, nonce }, + didKeypair, + ); + + return await root.rawTx[fnName](data, [{ sig, nonce }]); + }; + + if (args[root.payload[fnName].length - 1] == null) { + return await root.apiProvider.withDidNonce( + didKeypair.did, + signStateChange, + ); + } else { + return await signStateChange(); + } }, }; @@ -59,18 +71,26 @@ export const createDIDMethodTx = (fnName) => { const [didKeypair] = args.slice(root.payload[fnName].length - 2); ensureInstanceOf(didKeypair, DidKeypair); - // eslint-disable-next-line no-param-reassign - args[root.payload[fnName].length - 1] - ??= await root.apiProvider.nextDidNonce(didKeypair.did); - - return await DockDidOrDidMethodKey.from(didKeypair.did).changeState( - root.apiProvider, - root.rawTx[fnName], - root.constructor.MethodNameOverrides?.[fnName] - ?? fnNameToMethodName(fnName), - root.payload[fnName].apply(this.root, args), - didKeypair, - ); + + const changeState = async (maybeDidNonce) => { + // eslint-disable-next-line no-param-reassign + args[root.payload[fnName].length - 1] ??= maybeDidNonce.inc(); + + return await DockDidOrDidMethodKey.from(didKeypair.did).changeState( + root.apiProvider, + root.rawTx[fnName], + root.constructor.MethodNameOverrides?.[fnName] + ?? fnNameToMethodName(fnName), + root.payload[fnName].apply(this.root, args), + didKeypair, + ); + }; + + if (args[root.payload[fnName].length - 1] == null) { + return await root.apiProvider.withDidNonce(didKeypair.did, changeState); + } else { + return await changeState(); + } }, }; diff --git a/packages/dock-blockchain-modules/src/common/dock-api-provider.js b/packages/dock-blockchain-modules/src/common/dock-api-provider.js index 97dd0e3ae..bae49add5 100644 --- a/packages/dock-blockchain-modules/src/common/dock-api-provider.js +++ b/packages/dock-blockchain-modules/src/common/dock-api-provider.js @@ -36,14 +36,12 @@ class DockApiProvider extends ApiProvider { ); } - async didNonce(did) { - return typeof this.dock.didNonce === 'function' - ? await this.dock.didNonce(did) - : await new DockDIDModuleInternal(this).nonce(did); - } - - async nextDidNonce(did) { - return (await this.didNonce(did)).inc(); + async withDidNonce(did, fn) { + if (typeof this.dock.withDidNonce === 'function') { + return await this.dock.withDidNonce(did, fn); + } else { + return await fn(await new DockDIDModuleInternal(this).nonce(did)); + } } async batchAll(transactions) { diff --git a/packages/dock-blockchain-modules/src/did/module.js b/packages/dock-blockchain-modules/src/did/module.js index 9c867b063..2f5711383 100644 --- a/packages/dock-blockchain-modules/src/did/module.js +++ b/packages/dock-blockchain-modules/src/did/module.js @@ -110,66 +110,65 @@ export default class DockDIDModule extends injectDock(AbstractDIDModule) { ); } - const nonce = await this.dockOnly.apiProvider.didNonce(signerDid); - - const txs = [ - newOnChainKeys.length - && this.dockOnly.tx.addKeys( - [...newOnChainKeys].map(([_, key]) => key), - did, - didKeypair, - nonce.inc(), - ), - newControllers.length - && this.dockOnly.tx.addControllers( - newControllers, + const txs = ( + await this.dockOnly.apiProvider.withDidNonce(signerDid, (nonce) => Promise.all([ + newOnChainKeys.length + && this.dockOnly.tx.addKeys( + [...newOnChainKeys].map(([_, key]) => key), + did, + didKeypair, + nonce.inc(), + ), + newControllers.length + && this.dockOnly.tx.addControllers( + newControllers, + did, + didKeypair, + nonce.inc(), + ), + ...newOffchainKeys.map(([_, key]) => this.offchainSignatures.dockOnly.tx.addPublicKey( + key.publicKey, did, didKeypair, nonce.inc(), - ), - ...newOffchainKeys.map(([_, key]) => this.offchainSignatures.dockOnly.tx.addPublicKey( - key.publicKey, - did, - didKeypair, - nonce.inc(), - )), - ...[...newServices].map(({ id, type, serviceEndpoint }) => this.dockOnly.tx.addServiceEndpoint( - id, - type, - serviceEndpoint, - did, - didKeypair, - nonce.inc(), - )), - ...[...removedServices].map(({ id }) => this.dockOnly.tx.removeServiceEndpoint(id, didKeypair, nonce.inc())), - ...removedOffchainKeys.map(([{ index }]) => this.offchainSignatures.dockOnly.tx.removePublicKey( - index, - did, - didKeypair, - nonce.inc(), - )), - removedControllers.length - && this.dockOnly.tx.removeControllers( - removedControllers, + )), + ...[...newServices].map(({ id, type, serviceEndpoint }) => this.dockOnly.tx.addServiceEndpoint( + id, + type, + serviceEndpoint, did, didKeypair, nonce.inc(), - ), - removedOnChainKeys.length - && this.dockOnly.tx.removeKeys( - [...removedOnChainKeys].map(([{ index }]) => index), + )), + ...[...removedServices].map(({ id }) => this.dockOnly.tx.removeServiceEndpoint(id, didKeypair, nonce.inc())), + ...removedOffchainKeys.map(([{ index }]) => this.offchainSignatures.dockOnly.tx.removePublicKey( + index, did, didKeypair, nonce.inc(), - ), - ]; - - const filteredTxs = (await Promise.all(txs)).filter(Boolean); - if (!filteredTxs.length) { + )), + removedControllers.length + && this.dockOnly.tx.removeControllers( + removedControllers, + did, + didKeypair, + nonce.inc(), + ), + removedOnChainKeys.length + && this.dockOnly.tx.removeKeys( + [...removedOnChainKeys].map(([{ index }]) => index), + did, + didKeypair, + nonce.inc(), + ), + ])) + ).filter(Boolean); + + if (!txs.length) { throw new Error(`No changes for ${did}`); } - return await this.dockOnly.apiProvider.batchAll(filteredTxs); + return await this.dockOnly.apiProvider.batchAll(txs); } async removeDocumentTx(did, didKeypair) { diff --git a/packages/dock-blockchain-modules/src/trust-registry/internal.js b/packages/dock-blockchain-modules/src/trust-registry/internal.js index fd630287a..c9490c8a5 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/internal.js +++ b/packages/dock-blockchain-modules/src/trust-registry/internal.js @@ -635,7 +635,8 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM */ async getActorDidAndNonce(actorDid, nonce) { const hexDID = DockDidOrDidMethodKey.from(actorDid); - const lastNonce = nonce ?? (await this.apiProvider.nextDidNonce(hexDID)); + const lastNonce = nonce + ?? (await this.apiProvider.withDidNonce((didNonce) => didNonce.inc())); return [hexDID, lastNonce]; } diff --git a/packages/dock-blockchain-modules/src/trust-registry/module.js b/packages/dock-blockchain-modules/src/trust-registry/module.js index b57c5dfc1..d942609ed 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/module.js +++ b/packages/dock-blockchain-modules/src/trust-registry/module.js @@ -43,25 +43,29 @@ export default class DockTrustRegistryModule extends injectDock( } async createRegistryTx(id, info, schemas, didKeypair) { - const nonce = await this.dockOnly.apiProvider.nextDidNonce(didKeypair.did); - const init = await this.dockOnly.initOrUpdateTx( - info.convener, - id, - info.name, - info.govFramework, - didKeypair, - nonce, - ); - - const setSchemas = await this.dockOnly.setSchemasMetadataTx( + return await this.dockOnly.apiProvider.withDidNonce( didKeypair.did, - id, - { Set: schemas }, - didKeypair, - nonce.inc(), - ); + async (nonce) => { + const init = await this.dockOnly.initOrUpdateTx( + info.convener, + id, + info.name, + info.govFramework, + didKeypair, + nonce, + ); - return await this.dockOnly.apiProvider.batchAll([init, setSchemas]); + const setSchemas = await this.dockOnly.setSchemasMetadataTx( + didKeypair.did, + id, + { Set: schemas }, + didKeypair, + nonce.inc(), + ); + + return await this.dockOnly.apiProvider.batchAll([init, setSchemas]); + }, + ); } async updateRegistryTx(id, info, schemas, didKeypair) { diff --git a/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js b/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js index 17f226f74..4c8621d6b 100644 --- a/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js +++ b/packages/dock-blockchain-modules/tests/integration/did/did-basic.test.js @@ -167,7 +167,7 @@ describe("Basic DID tests", () => { await modules.attest.setClaim(iri, dockDid, pair); const att = await modules.attest.getAttests(dockDid); - expect(att).toEqual(iri); + expect(att.value).toEqual(iri); // Get document to verify the claim is there const didDocument = await modules.did.getDocument(dockDid); diff --git a/packages/dock-blockchain-modules/tests/integration/did/did-key.test.js b/packages/dock-blockchain-modules/tests/integration/did/did-key.test.js index 0929f8d88..bf258c34e 100644 --- a/packages/dock-blockchain-modules/tests/integration/did/did-key.test.js +++ b/packages/dock-blockchain-modules/tests/integration/did/did-key.test.js @@ -72,7 +72,7 @@ describe("Basic DID tests", () => { ); const att1 = await modules.attest.getAttests(testDidMethodKey1); - expect(att1).toEqual(iri); + expect(att1.value).toEqual(iri); await modules.attest.setClaim( iri, @@ -81,7 +81,7 @@ describe("Basic DID tests", () => { ); const att2 = await modules.attest.getAttests(testDidMethodKey2); - expect(att2).toEqual(iri); + expect(att2.value).toEqual(iri); }, 30000); test("Conversion works properly (including SS58 format)", () => { From c6be275e218cae3aef9b928364c5e1582e07ffa8 Mon Sep 17 00:00:00 2001 From: olegnn Date: Fri, 18 Oct 2024 16:55:45 +0200 Subject: [PATCH 09/11] Tweak --- .../dock-blockchain-modules/src/trust-registry/internal.js | 7 ++++--- .../dock-blockchain-modules/src/trust-registry/module.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/dock-blockchain-modules/src/trust-registry/internal.js b/packages/dock-blockchain-modules/src/trust-registry/internal.js index c9490c8a5..20116c0d6 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/internal.js +++ b/packages/dock-blockchain-modules/src/trust-registry/internal.js @@ -634,10 +634,11 @@ export default class DockInternalTrustRegistryModule extends createInternalDockM * @returns {Promise} */ async getActorDidAndNonce(actorDid, nonce) { - const hexDID = DockDidOrDidMethodKey.from(actorDid); + const actor = DockDidOrDidMethodKey.from(actorDid); const lastNonce = nonce - ?? (await this.apiProvider.withDidNonce((didNonce) => didNonce.inc())); - return [hexDID, lastNonce]; + ?? (await this.apiProvider.withDidNonce(actor, (didNonce) => didNonce.inc())); + + return [actor, lastNonce]; } /** diff --git a/packages/dock-blockchain-modules/src/trust-registry/module.js b/packages/dock-blockchain-modules/src/trust-registry/module.js index d942609ed..900c9c18e 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/module.js +++ b/packages/dock-blockchain-modules/src/trust-registry/module.js @@ -52,7 +52,7 @@ export default class DockTrustRegistryModule extends injectDock( info.name, info.govFramework, didKeypair, - nonce, + nonce.inc(), ); const setSchemas = await this.dockOnly.setSchemasMetadataTx( From 37ad9d7f6166e35e40d38c0a78735ff2bbe00fe2 Mon Sep 17 00:00:00 2001 From: olegnn Date: Fri, 18 Oct 2024 18:40:19 +0200 Subject: [PATCH 10/11] Make `withDidNonce` non-async function --- .../src/common/builders.js | 62 +++++++++---------- .../src/common/dock-api-provider.js | 2 +- .../src/trust-registry/module.js | 42 ++++++------- 3 files changed, 50 insertions(+), 56 deletions(-) diff --git a/packages/dock-blockchain-modules/src/common/builders.js b/packages/dock-blockchain-modules/src/common/builders.js index 5256a65a7..2f62e8ba6 100644 --- a/packages/dock-blockchain-modules/src/common/builders.js +++ b/packages/dock-blockchain-modules/src/common/builders.js @@ -30,31 +30,26 @@ export const createDIDMethodWithPolicyTx = (fnName) => { const [didKeypair] = args.slice(root.payload[fnName].length - 2); const { did: signer } = ensureInstanceOf(didKeypair, DidKeypair); - const signStateChange = async (maybeDidNonce) => { + const handlePayload = (maybeDidNonce) => { // eslint-disable-next-line no-param-reassign args[root.payload[fnName].length - 1] ??= maybeDidNonce.inc(); - const { data, nonce } = root.payload[fnName].apply(this.root, args); + return root.payload[fnName].apply(this.root, args); + }; - const sig = await DockDidOrDidMethodKey.from(signer).signStateChange( - root.apiProvider, - root.constructor.MethodNameOverrides?.[fnName] - ?? fnNameToMethodName(fnName), - { data, nonce }, - didKeypair, - ); + const { data, nonce } = args[root.payload[fnName].length - 1] == null + ? await root.apiProvider.withDidNonce(didKeypair.did, handlePayload) + : handlePayload(); - return await root.rawTx[fnName](data, [{ sig, nonce }]); - }; + const sig = await DockDidOrDidMethodKey.from(signer).signStateChange( + root.apiProvider, + root.constructor.MethodNameOverrides?.[fnName] + ?? fnNameToMethodName(fnName), + { data, nonce }, + didKeypair, + ); - if (args[root.payload[fnName].length - 1] == null) { - return await root.apiProvider.withDidNonce( - didKeypair.did, - signStateChange, - ); - } else { - return await signStateChange(); - } + return await root.rawTx[fnName](data, [{ sig, nonce }]); }, }; @@ -72,25 +67,26 @@ export const createDIDMethodTx = (fnName) => { const [didKeypair] = args.slice(root.payload[fnName].length - 2); ensureInstanceOf(didKeypair, DidKeypair); - const changeState = async (maybeDidNonce) => { + // eslint-disable-next-line + const handlePayload = (maybeDidNonce) => { // eslint-disable-next-line no-param-reassign args[root.payload[fnName].length - 1] ??= maybeDidNonce.inc(); - return await DockDidOrDidMethodKey.from(didKeypair.did).changeState( - root.apiProvider, - root.rawTx[fnName], - root.constructor.MethodNameOverrides?.[fnName] - ?? fnNameToMethodName(fnName), - root.payload[fnName].apply(this.root, args), - didKeypair, - ); + return root.payload[fnName].apply(this.root, args); }; - if (args[root.payload[fnName].length - 1] == null) { - return await root.apiProvider.withDidNonce(didKeypair.did, changeState); - } else { - return await changeState(); - } + const payload = args[root.payload[fnName].length - 1] == null + ? await root.apiProvider.withDidNonce(didKeypair.did, handlePayload) + : handlePayload(); + + return await DockDidOrDidMethodKey.from(didKeypair.did).changeState( + root.apiProvider, + root.rawTx[fnName], + root.constructor.MethodNameOverrides?.[fnName] + ?? fnNameToMethodName(fnName), + payload, + didKeypair, + ); }, }; diff --git a/packages/dock-blockchain-modules/src/common/dock-api-provider.js b/packages/dock-blockchain-modules/src/common/dock-api-provider.js index bae49add5..af769b1c9 100644 --- a/packages/dock-blockchain-modules/src/common/dock-api-provider.js +++ b/packages/dock-blockchain-modules/src/common/dock-api-provider.js @@ -40,7 +40,7 @@ class DockApiProvider extends ApiProvider { if (typeof this.dock.withDidNonce === 'function') { return await this.dock.withDidNonce(did, fn); } else { - return await fn(await new DockDIDModuleInternal(this).nonce(did)); + return fn(await new DockDIDModuleInternal(this).nonce(did)); } } diff --git a/packages/dock-blockchain-modules/src/trust-registry/module.js b/packages/dock-blockchain-modules/src/trust-registry/module.js index 900c9c18e..3a44f04ba 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/module.js +++ b/packages/dock-blockchain-modules/src/trust-registry/module.js @@ -43,28 +43,26 @@ export default class DockTrustRegistryModule extends injectDock( } async createRegistryTx(id, info, schemas, didKeypair) { - return await this.dockOnly.apiProvider.withDidNonce( - didKeypair.did, - async (nonce) => { - const init = await this.dockOnly.initOrUpdateTx( - info.convener, - id, - info.name, - info.govFramework, - didKeypair, - nonce.inc(), - ); - - const setSchemas = await this.dockOnly.setSchemasMetadataTx( - didKeypair.did, - id, - { Set: schemas }, - didKeypair, - nonce.inc(), - ); - - return await this.dockOnly.apiProvider.batchAll([init, setSchemas]); - }, + return await this.dockOnly.apiProvider.batchAll( + await Promise.all( + this.dockOnly.apiProvider.withDidNonce(didKeypair.did, (nonce) => [ + this.dockOnly.initOrUpdateTx( + info.convener, + id, + info.name, + info.govFramework, + didKeypair, + nonce.inc(), + ), + this.dockOnly.setSchemasMetadataTx( + didKeypair.did, + id, + { Set: schemas }, + didKeypair, + nonce.inc(), + ), + ]), + ), ); } From f7c4ddd6d9d73e9c10815d64a681854fe3dfc52e Mon Sep 17 00:00:00 2001 From: olegnn Date: Fri, 18 Oct 2024 19:39:24 +0200 Subject: [PATCH 11/11] `await` --- .../src/trust-registry/module.js | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/dock-blockchain-modules/src/trust-registry/module.js b/packages/dock-blockchain-modules/src/trust-registry/module.js index 3a44f04ba..70aba58df 100644 --- a/packages/dock-blockchain-modules/src/trust-registry/module.js +++ b/packages/dock-blockchain-modules/src/trust-registry/module.js @@ -45,23 +45,26 @@ export default class DockTrustRegistryModule extends injectDock( async createRegistryTx(id, info, schemas, didKeypair) { return await this.dockOnly.apiProvider.batchAll( await Promise.all( - this.dockOnly.apiProvider.withDidNonce(didKeypair.did, (nonce) => [ - this.dockOnly.initOrUpdateTx( - info.convener, - id, - info.name, - info.govFramework, - didKeypair, - nonce.inc(), - ), - this.dockOnly.setSchemasMetadataTx( - didKeypair.did, - id, - { Set: schemas }, - didKeypair, - nonce.inc(), - ), - ]), + await this.dockOnly.apiProvider.withDidNonce( + didKeypair.did, + (nonce) => [ + this.dockOnly.initOrUpdateTx( + info.convener, + id, + info.name, + info.govFramework, + didKeypair, + nonce.inc(), + ), + this.dockOnly.setSchemasMetadataTx( + didKeypair.did, + id, + { Set: schemas }, + didKeypair, + nonce.inc(), + ), + ], + ), ), ); }