From c2c4c53531fdb20fa07dca2f5851fa9c0ede21d2 Mon Sep 17 00:00:00 2001 From: Satish Mohan <54302767+smohan-dw@users.noreply.github.com> Date: Wed, 22 Jun 2022 20:33:13 +0530 Subject: [PATCH 1/8] remove exchange module --- packages/api/package.json | 1 - packages/api/src/index.ts | 2 - packages/exchange/LICENSE | 201 -------------------------- packages/exchange/package.json | 35 ----- packages/exchange/src/Request.ts | 136 ----------------- packages/exchange/src/Share.ts | 74 ---------- packages/exchange/src/Verify.ts | 98 ------------- packages/exchange/src/index.ts | 9 -- packages/exchange/src/types.ts | 6 - packages/exchange/tsconfig.build.json | 16 -- tsconfig.json | 1 - yarn.lock | 17 --- 12 files changed, 596 deletions(-) delete mode 100644 packages/exchange/LICENSE delete mode 100644 packages/exchange/package.json delete mode 100644 packages/exchange/src/Request.ts delete mode 100644 packages/exchange/src/Share.ts delete mode 100644 packages/exchange/src/Verify.ts delete mode 100644 packages/exchange/src/index.ts delete mode 100644 packages/exchange/src/types.ts delete mode 100644 packages/exchange/tsconfig.build.json diff --git a/packages/api/package.json b/packages/api/package.json index e6ece579..a54c6504 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -44,7 +44,6 @@ "webpack-cli": "^4.5.0" }, "dependencies": { - "@cord.network/exchange": "workspace:*", "@cord.network/messaging": "workspace:*", "@cord.network/modules": "workspace:*", "@cord.network/network": "workspace:*", diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index ec42079c..fa6a27bd 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1,8 +1,6 @@ export * from '@cord.network/modules' export { Message } from '@cord.network/messaging' export * as Messaging from '@cord.network/messaging' -export * as Exchange from '@cord.network/exchange' -export { Request, Share, Verify } from '@cord.network/exchange' export { ChainUtils } from '@cord.network/network' export * as ChainHelpers from '@cord.network/network' export * as Utils from '@cord.network/utils' diff --git a/packages/exchange/LICENSE b/packages/exchange/LICENSE deleted file mode 100644 index 0d381b2e..00000000 --- a/packages/exchange/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/packages/exchange/package.json b/packages/exchange/package.json deleted file mode 100644 index 9d422949..00000000 --- a/packages/exchange/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "@cord.network/exchange", - "version": "0.7.3-0", - "description": "Exchange API", - "main": "./lib/index.js", - "typings": "./lib/index.d.ts", - "files": [ - "lib/**/*" - ], - "scripts": { - "clean": "rimraf ./lib", - "build": "yarn clean && yarn build:ts", - "build:ts": "tsc --declaration -p tsconfig.build.json" - }, - "repository": "github:dhiway/cord.js", - "engines": { - "node": ">=14.0" - }, - "author": "Dhiway", - "bugs": "https://github.com/dhiway/cord.js/issues", - "homepage": "https://github.com/dhiway/cord.js#readme", - "devDependencies": { - "rimraf": "^3.0.2", - "typescript": "^4.5.4" - }, - "dependencies": { - "@cord.network/config": "workspace:*", - "@cord.network/messaging": "workspace:*", - "@cord.network/modules": "workspace:*", - "@cord.network/network": "workspace:*", - "@cord.network/types": "workspace:*", - "@cord.network/utils": "workspace:*", - "@polkadot/api-augment": "^8.0.0" - } -} diff --git a/packages/exchange/src/Request.ts b/packages/exchange/src/Request.ts deleted file mode 100644 index fdadc35b..00000000 --- a/packages/exchange/src/Request.ts +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @packageDocumentation - * @module Request - */ - -import { - // Credential, - Schema, - SDKErrors, - Identity, -} from '@cord.network/modules' -// import { ConfigService } from '@cord.network/config' -import type { - IPublicIdentity, - IMessage, - // ICredential, - // IMarkContent, - // IMessage, - IRequestStreamForCredential, -} from '@cord.network/types' -import { Message } from '@cord.network/messaging' -import { UUID, Crypto } from '@cord.network/utils' - -export interface IPresentationReq { - properties: string[] - id?: Schema['identifier'] - proofs?: boolean - requestUpdatedAfter?: Date -} - -export interface IPartialRequest { - id: Schema['identifier'] - properties: string[] -} - -export interface IRequestSession { - requestedProperties: IPartialRequest[] -} - -/** - * A helper class to initiate a verification by creating a presentation request which is built - * on a specific [[MType]] and attributes of the [[Stream]] the verifier requires to see. - */ -export class PresentationRequestBuilder { - private partialReq: IPartialRequest[] - constructor() { - this.partialReq = [] - } - - /** - * Initiates a verification by creating a presentation request for a specific [[Schema]]. - * Note that you are required to call [[finalize]] on the request to conclude it. - * - * @param p The parameter object. - * @param p.id The ID of the [[Schema]]. - * @param p.properties A list of properties of the [[Credential]]s requested. - * @param p.proofs An optional boolean representing whether the verifier requests to see the proofs of the issuers which signed the [[Credentials]]s. - * The default value for this is the current date. - * @returns A [[PresentationRequestBuilder]] on which you need to call [[finalize]] to complete the presentation request. - */ - public requestPresentation({ - id, - properties, - proofs, - }: IPresentationReq): PresentationRequestBuilder { - const rawProperties = properties.map((attr) => `${attr}`) - - if (typeof id !== 'undefined') { - rawProperties.push('content.id') - } - if (proofs === true) { - rawProperties.push('proof') - } - if (!id) throw new SDKErrors.ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED() - this.partialReq.push({ - id: id, - properties: rawProperties, - }) - return this - } - - /** - * Concludes the presentation request. - * - * @param requester The [[Identity]] of the verifier used to sign. - * @param holder The [[IPublicIdentity]] for which the message should be encrypted (note: the message will be return unencrypted. Use Message.getEncryptedMessage to encrypt the message). - * @returns A session and a message object. - * The **session** object will be used in [[verifyPresentation]] and should be kept private by the verifier. - * The **message** object should be sent to the Holder and used in [[createPresentation]]. - */ - public finalize( - purpose: string, - requester: Identity, - holder: IPublicIdentity, - validUntil: number, - relatedData: boolean - ): { - session: IRequestSession - message: IMessage - } { - const session = { - requestedProperties: this.partialReq, - } - const message = new Message( - { - request: UUID.generate(), - type: Message.BodyType.REQUEST_CREDENTIAL, - content: this.partialReq.map((pr): IRequestStreamForCredential => { - return { - id: pr.id, - requiredProperties: pr.properties, - } - }), - purpose, - validUntil, - relatedData, - }, - requester, - holder - ) - const hash = Crypto.hashStr(JSON.stringify(message)) - message.body.requestorSignature = requester.signStr(hash) - return { - session: session, - message: message, - } - } -} -/** - * Initiates a verification by creating a request on the Verifier's side. - * - * @returns A [[PresentationRequestBuilder]] based on a [[MType]] and a list of required disclosed attributes of the [[MarkedStream]]s. - */ -export function newRequestBuilder(): PresentationRequestBuilder { - return new PresentationRequestBuilder() -} diff --git a/packages/exchange/src/Share.ts b/packages/exchange/src/Share.ts deleted file mode 100644 index c5578b15..00000000 --- a/packages/exchange/src/Share.ts +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @packageDocumentation - * @module Share - */ - -import { Credential, Identity, SDKErrors } from '@cord.network/modules' -import type { - IMessage, - IPublicIdentity, - IPresentationOptions, - IPresentationSigningOptions, -} from '@cord.network/types' -import { Message } from '@cord.network/messaging' - -/** - * Creates a presentation for an arbitrary amount of [[MarkedStream]]s which can be verified in [[verifyPresentation]]. - * - * @param identity The Holder [[Identity]] which owns the [[MarkedStream]]s. - * @param message The message which represents multiple [[MType]]s, [[IRequestStreamsForMTypes]]s and whether privacy - * enhancement is supported. - * @param verifier The [[IPublicIdentity]] of the verifier that requested the presentation. - * @param credentials The [[MarkedStream]]s which should be verified. - * @throws [[ERROR_PE_MISMATCH]], [[ERROR_MESSAGE_TYPE]], [[ERROR_PE_CREDENTIAL_MISSING]]. - * @returns A message which represents either an array of [[MarkedStream]]s if privacy enhancement is not supported - * or a combined presentation. Both of these options can be verified. - */ -export function createPresentation( - identity: Identity, - message: IMessage, - verifier: IPublicIdentity, - credentials: Credential[], - { - showAttributes, - hideAttributes = [], - signer, - request = message.request, - }: IPresentationOptions & Partial = {} -): Message { - // did we get the right message type? - if (message.body.type !== Message.BodyType.REQUEST_CREDENTIAL) { - throw new SDKErrors.ERROR_MESSAGE_TYPE( - message.body.type, - Message.BodyType.REQUEST_CREDENTIAL - ) - } - - // create presentation for each credential - const credentialStreams = credentials.map((cred, i) => { - const presentation = cred.createPresentation({ - showAttributes, - hideAttributes, - signer, - request, - }) - - return presentation - }) - - const resMessage = new Message( - { - request: message.body.request, - type: Message.BodyType.SUBMIT_CREDENTIAL, - content: credentialStreams, - purpose: message.body.purpose, - validUntil: message.body.validUntil, - relatedData: message.body.relatedData, - requestorSignature: message.body.requestorSignature, - }, - identity, - verifier - ) - - return resMessage -} diff --git a/packages/exchange/src/Verify.ts b/packages/exchange/src/Verify.ts deleted file mode 100644 index bf6d8d5c..00000000 --- a/packages/exchange/src/Verify.ts +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @packageDocumentation - * @module Request - */ - -import { Credential, SDKErrors } from '@cord.network/modules' -import { ConfigService } from '@cord.network/config' -import type { ICredential, IContentStream, IMessage } from '@cord.network/types' -import { Message } from '@cord.network/messaging' -import { IRequestSession } from './Request' - -const log = ConfigService.LoggingFactory.getLogger('Request') - -/** -// * Initiates a verification by creating a request on the Verifier's side. -// * -// * @returns A [[PresentationRequestBuilder]] based on a [[MType]] and a list of required disclosed attributes of the [[MarkedStream]]s. -// */ -// export function newRequestBuilder(): PresentationRequestBuilder { -// return new PresentationRequestBuilder() -// } - -/** - * [ASYNC] Checks that the submitted marks fulfil the ones requested upon presentation creation. - * - * @param markedStreams The attested streams submitted by the holder. - * @param session The stored session object. - * @returns An object describing whether the verification was successful. - */ -async function verifySharedPresentation( - credStreams: Credential[], - session: IRequestSession -): Promise<{ - verified: boolean - streams: Array> -}> { - if (credStreams.length !== session.requestedProperties.length) { - log.info( - `Rejected presentation because the number of shared streams (${credStreams.length}) did not match the number of requested streams (${session.requestedProperties.length}).` - ) - return { - verified: false, - streams: [], - } - } - - const allVerified = await Promise.all( - session.requestedProperties.map(async (requested, i) => { - const ac = credStreams[i] - const providedProperties = ac.getAttributes() - const rawProperties = Array.from(providedProperties.keys()).map( - (prop) => `${prop}` - ) - rawProperties.push('content.id') - rawProperties.push('content.issuer') - return ( - requested.properties.every((p) => { - return rawProperties.includes(p) - }) && ac.verify() - ) - }) - ) - const verified = !allVerified.includes(false) - return { verified, streams: verified ? credStreams : [] } -} - -/** - * [ASYNC] Verifies the Holder's presentation of [[MarkedStream]]s. - * - * @param message The Holder's presentation of the [[MarkedStream]]s that should be verified, the result of [[createPresentation]]. - * @param session The Verifier's private verification session created in [[finalize]]. - * @throws [[ERROR_MESSAGE_TYPE]]. - * @returns An object containing the keys - * **verified** (which describes whether the [[MarkedStream]]s could be verified) - * and **streams** (an array of [[Stream]]s restricted on the disclosed attributes selected in [[requestPresentationForMtype]]). - */ -export async function verifyPresentation( - message: IMessage, - session: IRequestSession -): Promise<{ - verified: boolean - streams: Array> -}> { - if (message.body.type !== Message.BodyType.SUBMIT_CREDENTIAL) - throw new SDKErrors.ERROR_MESSAGE_TYPE( - message.body.type, - Message.BodyType.SUBMIT_CREDENTIAL - ) - const credentialStreams: ICredential[] = message.body.content.map( - (credentials: any, i: any) => { - return credentials.credentials[i] - } - ) - const credStreams = credentialStreams.map(Credential.fromCredential) - - // currently only supporting id-ed credentials - return verifySharedPresentation(credStreams, session) -} diff --git a/packages/exchange/src/index.ts b/packages/exchange/src/index.ts deleted file mode 100644 index 34b2c53a..00000000 --- a/packages/exchange/src/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -// import * as Requestor from './actors/Requestor' -// import * as Issuer from './actors/Issuer' -import * as Share from './Share' -import * as Request from './Request' -import * as Verify from './Verify' - -import type * as types from './types' - -export { Share, Request, Verify, types } diff --git a/packages/exchange/src/types.ts b/packages/exchange/src/types.ts deleted file mode 100644 index 7b58857e..00000000 --- a/packages/exchange/src/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * @packageDocumentation - * @module ActorsTypes - */ - -export { IPresentationReq, IPartialRequest, IRequestSession } from './Request' diff --git a/packages/exchange/tsconfig.build.json b/packages/exchange/tsconfig.build.json deleted file mode 100644 index ab6a2e29..00000000 --- a/packages/exchange/tsconfig.build.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "../../tsconfig.build.json", - - "compilerOptions": { - "outDir": "./lib" - }, - - "include": [ - "src/**/*.ts", "src/**/*.js" - ], - - "exclude": [ - "coverage", - "**/*.spec.ts", - ] -} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index abb5bfcb..9fae67b5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,6 @@ "@cord.network/api": ["api/src"], "@cord.network/types": ["types/src"], "@cord.network/utils": ["utils/src"], - "@cord.network/exchange": ["exchange/src"], "@cord.network/credential": ["credential/src"], } }, diff --git a/yarn.lock b/yarn.lock index 8282e268..79b34634 100644 --- a/yarn.lock +++ b/yarn.lock @@ -592,7 +592,6 @@ __metadata: version: 0.0.0-use.local resolution: "@cord.network/api@workspace:packages/api" dependencies: - "@cord.network/exchange": "workspace:*" "@cord.network/messaging": "workspace:*" "@cord.network/modules": "workspace:*" "@cord.network/network": "workspace:*" @@ -625,22 +624,6 @@ __metadata: languageName: unknown linkType: soft -"@cord.network/exchange@workspace:*, @cord.network/exchange@workspace:packages/exchange": - version: 0.0.0-use.local - resolution: "@cord.network/exchange@workspace:packages/exchange" - dependencies: - "@cord.network/config": "workspace:*" - "@cord.network/messaging": "workspace:*" - "@cord.network/modules": "workspace:*" - "@cord.network/network": "workspace:*" - "@cord.network/types": "workspace:*" - "@cord.network/utils": "workspace:*" - "@polkadot/api-augment": ^8.0.0 - rimraf: ^3.0.2 - typescript: ^4.5.4 - languageName: unknown - linkType: soft - "@cord.network/messaging@workspace:*, @cord.network/messaging@workspace:packages/messaging": version: 0.0.0-use.local resolution: "@cord.network/messaging@workspace:packages/messaging" From 1b6a3266a63d5143b53e9bcaf71631f9330ed472 Mon Sep 17 00:00:00 2001 From: Satish Mohan <54302767+smohan-dw@users.noreply.github.com> Date: Wed, 22 Jun 2022 22:39:25 +0530 Subject: [PATCH 2/8] set default stream expiry date --- demo/src/demo-vc.ts | 28 ++++++----- .../src/contentstream/ContentStream.ts | 49 +++++++++++++------ packages/types/src/ContentStream.ts | 2 + packages/vc-export/src/types.ts | 2 +- .../vc-export/src/vc-js/context/context.json | 8 +-- .../src/vc-js/suites/CordAnchoredSuite.ts | 12 ++--- 6 files changed, 63 insertions(+), 38 deletions(-) diff --git a/demo/src/demo-vc.ts b/demo/src/demo-vc.ts index 08ccd378..3ae50ea7 100644 --- a/demo/src/demo-vc.ts +++ b/demo/src/demo-vc.ts @@ -1,5 +1,6 @@ import * as Cord from '@cord.network/api' import { UUID } from '@cord.network/utils' +import type { VerifiableCredential } from 'vc-export/src/types' import * as VCUtils from 'vc-export/src' async function main() { @@ -160,18 +161,21 @@ async function main() { console.log(`\n❄️ Verifiy Presentation`) + const VCfromPresentation = + vcPresentation.verifiableCredential as VerifiableCredential + const signatureResult = await VCUtils.verification.verifySelfSignedProof( - vcPresentation.verifiableCredential, - vcPresentation.verifiableCredential.proof[0] + VCfromPresentation, + VCfromPresentation.proof[0] ) const streamResult = await VCUtils.verification.verifyStreamProof( - vcPresentation.verifiableCredential, - vcPresentation.verifiableCredential.proof[1] + VCfromPresentation, + VCfromPresentation.proof[1] ) const digestResult = await VCUtils.verification.verifyCredentialDigestProof( - vcPresentation.verifiableCredential, - vcPresentation.verifiableCredential.proof[2] + VCfromPresentation, + VCfromPresentation.proof[2] ) if ( (!streamResult && !streamResult['verified']) || @@ -180,21 +184,21 @@ async function main() { ) { console.log( `❌ Verification failed `, - 'Signature Proof', + 'Signature-Proof', signatureResult['verified'], - 'Stream Proof', + ', Stream-Proof', streamResult['verified'], - 'Digest Proof', + ', Digest-Proof', digestResult['verified'] ) } else { console.log( '✅ All valid? ', - 'Signature Proof', + 'Signature-Proof', signatureResult['verified'], - 'Stream Proof', + ', Stream-Proof', streamResult['verified'], - 'Digest Proof', + ', Digest-Proof', digestResult['verified'] ) } diff --git a/packages/modules/src/contentstream/ContentStream.ts b/packages/modules/src/contentstream/ContentStream.ts index 9abdd027..2ca35d9b 100644 --- a/packages/modules/src/contentstream/ContentStream.ts +++ b/packages/modules/src/contentstream/ContentStream.ts @@ -10,7 +10,11 @@ import * as ContentUtils from '../content/Content.utils.js' import { Credential } from '../credential/Credential.js' import { Identity } from '../identity/Identity.js' import * as ContentStreamUtils from './ContentStream.utils.js' -import { STREAM_IDENTIFIER, STREAM_PREFIX } from '@cord.network/types' +import { + STREAM_IDENTIFIER, + STREAM_PREFIX, + DEFAULT_STREAM_VALIDITY, +} from '@cord.network/types' import { Identifier } from '@cord.network/utils' import { HexString } from '@polkadot/util/types.js' @@ -31,7 +35,7 @@ export type Options = { legitimations?: Credential[] link?: IContentStream['link'] space?: IContentStream['space'] - expiry?: IContentStream['expirationDate'] + expiry?: Date } export class ContentStream implements IContentStream { @@ -70,10 +74,18 @@ export class ContentStream implements IContentStream { const { hashes: contentHashes, nonceMap: contentNonceMap } = ContentUtils.hashContents(content) - const issuanceDate = new Date().toISOString() - const issuanceDateHash = Crypto.hashObjectAsHexStr(issuanceDate) - const expirationDate = expiry || 'Not Set' - const expirationDateHash = Crypto.hashObjectAsHexStr(expirationDate) + const issuanceDate = new Date() + const issuanceDateString = issuanceDate.toISOString() + const issuanceDateHash = Crypto.hashObjectAsHexStr(issuanceDateString) + const expirationDate = + expiry || + new Date( + issuanceDate.setFullYear( + issuanceDate.getFullYear() + DEFAULT_STREAM_VALIDITY + ) + ) + const expirationDateString = expirationDate.toISOString() + const expirationDateHash = Crypto.hashObjectAsHexStr(expirationDateString) const rootHash = ContentStream.calculateRootHash( { @@ -93,8 +105,8 @@ export class ContentStream implements IContentStream { space: space || null, issuerSignature: ContentStream.sign(issuer, rootHash), rootHash, - issuanceDate, - expirationDate, + issuanceDate: issuanceDateString, + expirationDate: expirationDateString, identifier: Identifier.getIdentifier( rootHash, STREAM_IDENTIFIER, @@ -125,11 +137,18 @@ export class ContentStream implements IContentStream { const { hashes: contentHashes, nonceMap: contentNonceMap } = ContentUtils.hashContents(content.content) - - const issuanceDate = new Date().toISOString() - const issuanceDateHash = Crypto.hashObjectAsHexStr(issuanceDate) - const expirationDate = expiry || 'Not Set' - const expirationDateHash = Crypto.hashObjectAsHexStr(expirationDate) + const issuanceDate = new Date() + const issuanceDateString = issuanceDate.toISOString() + const issuanceDateHash = Crypto.hashObjectAsHexStr(issuanceDateString) + const expirationDate = + expiry || + new Date( + issuanceDate.setFullYear( + issuanceDate.getFullYear() + DEFAULT_STREAM_VALIDITY + ) + ) + const expirationDateString = expirationDate.toISOString() + const expirationDateHash = Crypto.hashObjectAsHexStr(expirationDateString) const rootHash = ContentStream.calculateRootHash( { @@ -149,8 +168,8 @@ export class ContentStream implements IContentStream { space: content.space, issuerSignature: ContentStream.sign(issuer, rootHash), rootHash, - issuanceDate, - expirationDate, + issuanceDate: issuanceDateString, + expirationDate: expirationDateString, identifier: content.identifier, }) } diff --git a/packages/types/src/ContentStream.ts b/packages/types/src/ContentStream.ts index 4b3ab633..94af4d8f 100644 --- a/packages/types/src/ContentStream.ts +++ b/packages/types/src/ContentStream.ts @@ -7,6 +7,8 @@ import type { HexString } from '@polkadot/util/types' import type { ICredential, CompressedCredential } from './Credential.js' import type { IContent, CompressedContent } from './Content.js' +export const DEFAULT_STREAM_VALIDITY: number = 99 + export type Hash = HexString export type NonceHash = { diff --git a/packages/vc-export/src/types.ts b/packages/vc-export/src/types.ts index cd7269ae..a847064e 100644 --- a/packages/vc-export/src/types.ts +++ b/packages/vc-export/src/types.ts @@ -80,7 +80,7 @@ export interface VerifiableCredential { export interface VerifiablePresentation { '@context': [typeof DEFAULT_VERIFIABLE_CREDENTIAL_CONTEXT, ...string[]] type: [typeof DEFAULT_VERIFIABLEPRESENTATION_TYPE, ...string[]] - verifiableCredential: VerifiableCredential + verifiableCredential: VerifiableCredential | VerifiableCredential[] holder?: string proof: Proof | Proof[] } diff --git a/packages/vc-export/src/vc-js/context/context.json b/packages/vc-export/src/vc-js/context/context.json index 63479d09..f9cf30d6 100644 --- a/packages/vc-export/src/vc-js/context/context.json +++ b/packages/vc-export/src/vc-js/context/context.json @@ -3,7 +3,7 @@ "@version": 1.1, "@protected": true, "cred": "https://www.w3.org/2018/credentials#", - "dwayCred": "https://cord.network/contexts/credentials#", + "cordCred": "https://cord.network/contexts/credentials#", "sec": "https://w3id.org/security#", "xsd": "http://www.w3.org/2001/XMLSchema#", "verificationMethod": { @@ -21,12 +21,12 @@ } }, "CordCredential2020": { - "@id": "dwayCred:CordCredential", + "@id": "cordCred:CordCredential", "@context": { "@version": 1.1, "@protected": true, "legitimationIds": { - "@id": "dwayCred:legitimationIds", + "@id": "cordCred:legitimationIds", "@type": "@id", "@container": "@set" }, @@ -37,7 +37,7 @@ } }, "CordSelfSigned2020": { - "@id": "dwayCred:CordSelfSigned2020", + "@id": "cordCred:CordSelfSigned2020", "@context": { "@version": 1.1, "@protected": true, diff --git a/packages/vc-export/src/vc-js/suites/CordAnchoredSuite.ts b/packages/vc-export/src/vc-js/suites/CordAnchoredSuite.ts index b93e3199..047dd767 100644 --- a/packages/vc-export/src/vc-js/suites/CordAnchoredSuite.ts +++ b/packages/vc-export/src/vc-js/suites/CordAnchoredSuite.ts @@ -13,13 +13,13 @@ import { verifyStreamProof, StreamStatus } from '../../verificationUtils.js' import { CORD_ANCHORED_PROOF_TYPE } from '../../constants.js' import CordAbstractSuite from './CordAbstractSuite.js' -class MarkError extends Error { - public readonly journalStatus: StreamStatus +class StreamError extends Error { + public readonly streamStatus: StreamStatus - constructor(message: string, journalStatus: StreamStatus) { + constructor(message: string, streamStatus: StreamStatus) { super(message) - this.name = 'JournalError' - this.journalStatus = journalStatus + this.name = 'StreamError' + this.streamStatus = streamStatus } } @@ -64,7 +64,7 @@ export default class CordAnchoredSuite extends CordAbstractSuite { if (errors.length > 0) return { verified, - error: new MarkError(errors[0].message, status), + error: new StreamError(errors[0].message, status), } return { verified } } catch (e: any) { From 4061d9e96d1361ba0c0854f8d3d81b8aa9703a81 Mon Sep 17 00:00:00 2001 From: Satish Mohan <54302767+smohan-dw@users.noreply.github.com> Date: Wed, 22 Jun 2022 23:19:03 +0530 Subject: [PATCH 3/8] vc vocab alignment: legitimation -> evidence --- .../src/contentstream/ContentStream.ts | 44 +++++++++---------- .../src/contentstream/ContentStream.utils.ts | 8 ++-- packages/modules/src/credential/Credential.ts | 12 ++--- packages/types/src/ContentStream.ts | 2 +- packages/utils/src/SDKErrors.ts | 8 ++-- packages/vc-export/README.md | 2 +- .../src/exportToVerifiableCredential.ts | 6 +-- packages/vc-export/src/types.ts | 2 +- .../vc-export/src/vc-js/context/context.json | 4 +- .../src/vc-js/examples/example-vc.json | 2 +- packages/vc-export/src/verificationUtils.ts | 10 ++--- 11 files changed, 50 insertions(+), 50 deletions(-) diff --git a/packages/modules/src/contentstream/ContentStream.ts b/packages/modules/src/contentstream/ContentStream.ts index 2ca35d9b..8d7433d6 100644 --- a/packages/modules/src/contentstream/ContentStream.ts +++ b/packages/modules/src/contentstream/ContentStream.ts @@ -32,7 +32,7 @@ function getHashRoot(leaves: Uint8Array[]): Uint8Array { } export type Options = { - legitimations?: Credential[] + evidenceIds?: Credential[] link?: IContentStream['link'] space?: IContentStream['space'] expiry?: Date @@ -56,7 +56,7 @@ export class ContentStream implements IContentStream { * @param content An `IContentStream` object the request for credential is built for. * @param issuer The Issuer's [[Identity]]. * @param option Container for different options that can be passed to this method. - * @param option.legitimations Array of [[Credential]] objects the Issuer include as legitimations. + * @param option.evidenceIds Array of [[Credential]] objects the Issuer include as evidenceIds. * @param option.link Identifier of the stream this credential is linked to. * @param option.space Identifier of the space this credential is linked to. * @throws [[ERROR_IDENTITY_MISMATCH]] when streamInput's issuer address does not match the supplied identity's address. @@ -65,7 +65,7 @@ export class ContentStream implements IContentStream { public static fromContent( content: IContent, issuer: Identity, - { legitimations, link, space, expiry }: Options = {} + { evidenceIds, link, space, expiry }: Options = {} ): ContentStream { if (content.issuer !== issuer.address) { throw new SDKErrors.ERROR_IDENTITY_MISMATCH() @@ -89,7 +89,7 @@ export class ContentStream implements IContentStream { const rootHash = ContentStream.calculateRootHash( { - legitimations, + evidenceIds, contentHashes, }, issuanceDateHash, @@ -100,7 +100,7 @@ export class ContentStream implements IContentStream { content, contentHashes, contentNonceMap, - legitimations: legitimations || [], + evidenceIds: evidenceIds || [], link: link || null, space: space || null, issuerSignature: ContentStream.sign(issuer, rootHash), @@ -121,19 +121,19 @@ export class ContentStream implements IContentStream { * @param content An `IContentStream` object the request for credential is built for. * @param issuer The Issuer's [[Identity]]. * @param option Container for different options that can be passed to this method. - * @param option.legitimations Array of [[Credential]] objects the Issuer include as legitimations. + * @param option.evidenceIds Array of [[Credential]] objects the Issuer include as evidenceIds. * @throws [[ERROR_IDENTITY_MISMATCH]] when streamInput's issuer address does not match the supplied identity's address. * @returns An updated [[ContentStream]] object. */ public static updateContentProperties( content: IContentStream, issuer: Identity, - { legitimations, expiry }: Options = {} + { evidenceIds, expiry }: Options = {} ): ContentStream { if (content.content.issuer !== issuer.address) { throw new SDKErrors.ERROR_IDENTITY_MISMATCH() } - let updateLegitimations = legitimations || content.legitimations + let updateEvidenceIds = evidenceIds || content.evidenceIds const { hashes: contentHashes, nonceMap: contentNonceMap } = ContentUtils.hashContents(content.content) @@ -152,7 +152,7 @@ export class ContentStream implements IContentStream { const rootHash = ContentStream.calculateRootHash( { - legitimations: updateLegitimations, + evidenceIds: updateEvidenceIds, contentHashes, }, issuanceDateHash, @@ -163,7 +163,7 @@ export class ContentStream implements IContentStream { content: content.content, contentHashes, contentNonceMap, - legitimations: updateLegitimations || content.legitimations, + evidenceIds: updateEvidenceIds || content.evidenceIds, link: content.link, space: content.space, issuerSignature: ContentStream.sign(issuer, rootHash), @@ -193,7 +193,7 @@ export class ContentStream implements IContentStream { public content: IContentStream['content'] public contentHashes: IContentStream['contentHashes'] public contentNonceMap: IContentStream['contentNonceMap'] - public legitimations: IContentStream['legitimations'] + public evidenceIds: IContentStream['evidenceIds'] public link: IContentStream['link'] | null public space: IContentStream['space'] | null public issuerSignature: string @@ -215,15 +215,15 @@ export class ContentStream implements IContentStream { this.contentHashes = contentStreamRequest.contentHashes this.contentNonceMap = contentStreamRequest.contentNonceMap if ( - contentStreamRequest.legitimations && - Array.isArray(contentStreamRequest.legitimations) && - contentStreamRequest.legitimations.length + contentStreamRequest.evidenceIds && + Array.isArray(contentStreamRequest.evidenceIds) && + contentStreamRequest.evidenceIds.length ) { - this.legitimations = contentStreamRequest.legitimations.map((proof) => + this.evidenceIds = contentStreamRequest.evidenceIds.map((proof) => Credential.fromCredential(proof) ) } else { - this.legitimations = [] + this.evidenceIds = [] } this.link = contentStreamRequest.link this.space = contentStreamRequest.space @@ -293,7 +293,7 @@ export class ContentStream implements IContentStream { ) // check proofs - Credential.validateLegitimations(input.legitimations) + Credential.validateEvidenceIds(input.evidenceIds) return true } @@ -344,7 +344,7 @@ export class ContentStream implements IContentStream { private static getHashLeaves( contentHashes: Hash[], - legitimations: ICredential[], + evidenceIds: ICredential[], issueDate: HexString, expiryDate: HexString ): Uint8Array[] { @@ -352,9 +352,9 @@ export class ContentStream implements IContentStream { contentHashes.forEach((item) => { result.push(Crypto.coToUInt8(item)) }) - if (legitimations) { - legitimations.forEach((legitimation) => { - result.push(Crypto.coToUInt8(legitimation.request.identifier)) + if (evidenceIds) { + evidenceIds.forEach((evidence) => { + result.push(Crypto.coToUInt8(evidence.request.identifier)) }) } result.push(Crypto.coToUInt8(issueDate)) @@ -392,7 +392,7 @@ export class ContentStream implements IContentStream { ): Hash { const hashes: Uint8Array[] = ContentStream.getHashLeaves( credential.contentHashes || [], - credential.legitimations || [], + credential.evidenceIds || [], issuanceDate, expirationDate ) diff --git a/packages/modules/src/contentstream/ContentStream.utils.ts b/packages/modules/src/contentstream/ContentStream.utils.ts index 931182f4..571f520f 100644 --- a/packages/modules/src/contentstream/ContentStream.utils.ts +++ b/packages/modules/src/contentstream/ContentStream.utils.ts @@ -24,8 +24,8 @@ export function errorCheck(input: IContentStream): void { } else { ContentUtils.errorCheck(input.content) } - if (!input.legitimations && !Array.isArray(input.legitimations)) { - throw new SDKErrors.ERROR_LEGITIMATIONS_NOT_PROVIDED() + if (!input.evidenceIds && !Array.isArray(input.evidenceIds)) { + throw new SDKErrors.ERROR_EVIDENCE_ID_NOT_PROVIDED() } if (!input.contentNonceMap) { throw new SDKErrors.ERROR_CONTENT_NONCE_MAP_NOT_PROVIDED() @@ -92,7 +92,7 @@ export function compress( contentStream.issuerSignature, contentStream.link, contentStream.space, - compressProof(contentStream.legitimations), + compressProof(contentStream.evidenceIds), contentStream.rootHash, contentStream.identifier, contentStream.issuanceDate, @@ -122,7 +122,7 @@ export function decompress( issuerSignature: contentStream[3], link: contentStream[4], space: contentStream[5], - legitimations: decompressProof(contentStream[6]), + evidenceIds: decompressProof(contentStream[6]), rootHash: contentStream[7], identifier: contentStream[8], issuanceDate: contentStream[9], diff --git a/packages/modules/src/credential/Credential.ts b/packages/modules/src/credential/Credential.ts index dc5cefc3..b388de27 100644 --- a/packages/modules/src/credential/Credential.ts +++ b/packages/modules/src/credential/Credential.ts @@ -143,15 +143,15 @@ export class Credential implements ICredential { /** * [STATIC] Verifies the data of each element of the given Array of IMarkedStreams. * - * @param legitimations Array of IMarkedStreams to validate. - * @throws [[ERROR_LEGITIMATIONS_UNVERIFIABLE]] when one of the IMarkedStreams data is unable to be verified. + * @param evidenceIds Array of IMarkedStreams to validate. + * @throws [[ERROR_EVIDENCE_ID_UNVERIFIABLE]] when one of the IMarkedStreams data is unable to be verified. * * @returns Boolean whether each element of the given Array of IMarkedStreams is verifiable. */ - public static validateLegitimations(legitimations: ICredential[]): boolean { - legitimations.forEach((legitimation: ICredential) => { - if (!Credential.verifyData(legitimation)) { - throw new SDKErrors.ERROR_LEGITIMATIONS_UNVERIFIABLE() + public static validateEvidenceIds(evidenceIds: ICredential[]): boolean { + evidenceIds.forEach((evidence: ICredential) => { + if (!Credential.verifyData(evidence)) { + throw new SDKErrors.ERROR_EVIDENCE_ID_UNVERIFIABLE() } }) return true diff --git a/packages/types/src/ContentStream.ts b/packages/types/src/ContentStream.ts index 94af4d8f..dd01c5d8 100644 --- a/packages/types/src/ContentStream.ts +++ b/packages/types/src/ContentStream.ts @@ -20,7 +20,7 @@ export interface IContentStream { content: IContent contentHashes: Hash[] contentNonceMap: Record - legitimations: ICredential[] + evidenceIds: ICredential[] link: string | null space: string | null issuerSignature: string diff --git a/packages/utils/src/SDKErrors.ts b/packages/utils/src/SDKErrors.ts index 0f668ab5..199621df 100644 --- a/packages/utils/src/SDKErrors.ts +++ b/packages/utils/src/SDKErrors.ts @@ -117,9 +117,9 @@ export class ERROR_MC_NOT_PROVIDED extends SDKError { } } -export class ERROR_LEGITIMATIONS_NOT_PROVIDED extends SDKError { +export class ERROR_EVIDENCE_ID_NOT_PROVIDED extends SDKError { constructor() { - super('Legitimations missing') + super('Evidence ID missing') } } @@ -217,9 +217,9 @@ export class ERROR_ADDRESS_INVALID extends SDKError { } } -export class ERROR_LEGITIMATIONS_UNVERIFIABLE extends SDKError { +export class ERROR_EVIDENCE_ID_UNVERIFIABLE extends SDKError { constructor() { - super('Legitimations could not be verified') + super('Evidence ID could not be verified') } } export class ERROR_SIGNATURE_UNVERIFIABLE extends SDKError { diff --git a/packages/vc-export/README.md b/packages/vc-export/README.md index db84042f..d571646b 100644 --- a/packages/vc-export/README.md +++ b/packages/vc-export/README.md @@ -15,7 +15,7 @@ It provides you with tools to export your existing CORD credentials to the widel - verification utils - functions that verify three proof types: - holder's self-signed proof over the credential digest - - credential digest proof that assures the integrity of disclosed attributes, holder identity, legitimations and delegations + - credential digest proof that assures the integrity of disclosed attributes, holder identity, evidenceIds and delegations - credential proof that assures the credential is attested by the identity disclosed as the `issuer` and not revoked - a function to validate the disclosed stream properties against the schema of a CORD MType, which is a prescriptive schema detailing fields and their data types. - vc-js suites: tooling to integrate CORD VCs with `vc-js` and `jsonld-signatures^5.0.0` diff --git a/packages/vc-export/src/exportToVerifiableCredential.ts b/packages/vc-export/src/exportToVerifiableCredential.ts index 1c53694d..f9144ac4 100644 --- a/packages/vc-export/src/exportToVerifiableCredential.ts +++ b/packages/vc-export/src/exportToVerifiableCredential.ts @@ -53,7 +53,7 @@ export function fromCredential( ): VerifiableCredential { const { contentHashes, - legitimations, + evidenceIds, rootHash, issuerSignature, content, @@ -90,7 +90,7 @@ export function fromCredential( } } - const legitimationIds = legitimations.map((leg) => leg.request.rootHash) + const evidence = evidenceIds.map((leg) => leg.request.rootHash) const proof: Proof[] = [] @@ -106,7 +106,7 @@ export function fromCredential( expirationDate, credentialSubject, credentialHash: rootHash, - legitimationIds, + evidence, nonTransferable: true, proof, credentialSchema, diff --git a/packages/vc-export/src/types.ts b/packages/vc-export/src/types.ts index a847064e..2833851d 100644 --- a/packages/vc-export/src/types.ts +++ b/packages/vc-export/src/types.ts @@ -70,7 +70,7 @@ export interface VerifiableCredential { // rootHash of the credential credentialHash: string // Ids / digests of streams that empower the issuer to provide judegment - legitimationIds: string[] + evidence: string[] // digital proof that makes the credential tamper-evident proof: Proof | Proof[] nonTransferable?: boolean diff --git a/packages/vc-export/src/vc-js/context/context.json b/packages/vc-export/src/vc-js/context/context.json index f9cf30d6..4b4ce855 100644 --- a/packages/vc-export/src/vc-js/context/context.json +++ b/packages/vc-export/src/vc-js/context/context.json @@ -25,8 +25,8 @@ "@context": { "@version": 1.1, "@protected": true, - "legitimationIds": { - "@id": "cordCred:legitimationIds", + "evidence": { + "@id": "cordCred:evidence", "@type": "@id", "@container": "@set" }, diff --git a/packages/vc-export/src/vc-js/examples/example-vc.json b/packages/vc-export/src/vc-js/examples/example-vc.json index a3cd5303..0cc29c82 100644 --- a/packages/vc-export/src/vc-js/examples/example-vc.json +++ b/packages/vc-export/src/vc-js/examples/example-vc.json @@ -17,7 +17,7 @@ "name": "Kurt", "premium": true }, - "legitimationIds": [], + "evidence": [], "issuer": "did:cord:4sejigvu6STHdYmmYf2SuN92aNp8TbrsnBBDUj7tMrJ9Z3cG", "issuanceDate": "2021-03-25T10:20:44.242Z", "nonTransferable": true, diff --git a/packages/vc-export/src/verificationUtils.ts b/packages/vc-export/src/verificationUtils.ts index e895e581..d18d4832 100644 --- a/packages/vc-export/src/verificationUtils.ts +++ b/packages/vc-export/src/verificationUtils.ts @@ -314,7 +314,7 @@ function calculateRootHash( ): Hash { const hashes: Uint8Array[] = getHashLeaves( proof.contentHashes || [], - credential.legitimationIds || [], + credential.evidence || [], issuanceDate, expirationDate ) @@ -324,7 +324,7 @@ function calculateRootHash( function getHashLeaves( contentHashes: string[], - legitimations: string[], + evidenceIds: string[], issueDate: HexString, expiryDate: HexString ): Uint8Array[] { @@ -332,9 +332,9 @@ function getHashLeaves( contentHashes.forEach((item) => { result.push(Crypto.coToUInt8(item)) }) - if (legitimations) { - legitimations.forEach((legitimation) => { - result.push(Crypto.coToUInt8(legitimation)) + if (evidenceIds) { + evidenceIds.forEach((evidence) => { + result.push(Crypto.coToUInt8(evidence)) }) } result.push(Crypto.coToUInt8(issueDate)) From cf54d78506ad67a79833091c321ef8bfebd112ac Mon Sep 17 00:00:00 2001 From: Satish Mohan <54302767+smohan-dw@users.noreply.github.com> Date: Wed, 22 Jun 2022 23:43:54 +0530 Subject: [PATCH 4/8] add cord signature proof --- demo/src/demo-vc.ts | 3 +- packages/vc-export/src/constants.ts | 2 +- .../src/exportToVerifiableCredential.ts | 8 +-- packages/vc-export/src/types.ts | 6 +- .../vc-export/src/vc-js/context/context.json | 4 +- .../src/vc-js/examples/example-vc.json | 56 ------------------- .../src/vc-js/suites/CordSignatureSuite.ts | 12 ++-- packages/vc-export/src/verificationUtils.ts | 10 ++-- 8 files changed, 23 insertions(+), 78 deletions(-) delete mode 100644 packages/vc-export/src/vc-js/examples/example-vc.json diff --git a/demo/src/demo-vc.ts b/demo/src/demo-vc.ts index 3ae50ea7..a91ab5d5 100644 --- a/demo/src/demo-vc.ts +++ b/demo/src/demo-vc.ts @@ -152,6 +152,7 @@ async function main() { console.log(`\n❄️ Verifiable Presentation - Selective Disclosure `) const sharedCredential = JSON.parse(JSON.stringify(VC)) + console.log(JSON.stringify(VC)) const vcPresentation = await VCUtils.presentation.makePresentation( sharedCredential, ['name', 'country'] @@ -164,7 +165,7 @@ async function main() { const VCfromPresentation = vcPresentation.verifiableCredential as VerifiableCredential - const signatureResult = await VCUtils.verification.verifySelfSignedProof( + const signatureResult = await VCUtils.verification.verifyCordSignatureProof( VCfromPresentation, VCfromPresentation.proof[0] ) diff --git a/packages/vc-export/src/constants.ts b/packages/vc-export/src/constants.ts index 34db8edc..d998af4c 100644 --- a/packages/vc-export/src/constants.ts +++ b/packages/vc-export/src/constants.ts @@ -17,7 +17,7 @@ export const DEFAULT_VERIFIABLEPRESENTATION_TYPE = 'VerifiablePresentation' export const CORD_VERIFIABLE_CREDENTIAL_TYPE = 'CordCredential2020' -export const CORD_SELF_SIGNED_PROOF_TYPE = 'CordSelfSigned2020' +export const CORD_SIGNATURE_PROOF_TYPE = 'CordSignature2020' export const CORD_ANCHORED_PROOF_TYPE = 'CordCredential2020' export const CORD_CREDENTIAL_DIGEST_PROOF_TYPE = 'CordCredentialDigest2020' diff --git a/packages/vc-export/src/exportToVerifiableCredential.ts b/packages/vc-export/src/exportToVerifiableCredential.ts index f9144ac4..7aa20bfc 100644 --- a/packages/vc-export/src/exportToVerifiableCredential.ts +++ b/packages/vc-export/src/exportToVerifiableCredential.ts @@ -16,7 +16,7 @@ import { KeyTypesMap, CORD_ANCHORED_PROOF_TYPE, CORD_CREDENTIAL_DIGEST_PROOF_TYPE, - CORD_SELF_SIGNED_PROOF_TYPE, + CORD_SIGNATURE_PROOF_TYPE, CORD_CREDENTIAL_CONTEXT_URL, CORD_VERIFIABLE_CREDENTIAL_TYPE, CORD_CREDENTIAL_IRI_PREFIX, @@ -26,7 +26,7 @@ import type { CredentialDigestProof, CredentialSchema, Proof, - SelfSignedProof, + CordSignatureProof, VerifiableCredential, } from './types.js' import { SDKErrors, Identifier } from '@cord.network/utils' @@ -127,8 +127,8 @@ export function fromCredential( throw new SDKErrors.ERROR_IDENTITY_MISMATCH() } - const sSProof: SelfSignedProof = { - type: CORD_SELF_SIGNED_PROOF_TYPE, + const sSProof: CordSignatureProof = { + type: CORD_SIGNATURE_PROOF_TYPE, proofPurpose: 'assertionMethod', verificationMethod: { type: keyType, diff --git a/packages/vc-export/src/types.ts b/packages/vc-export/src/types.ts index 2833851d..45bdc2ca 100644 --- a/packages/vc-export/src/types.ts +++ b/packages/vc-export/src/types.ts @@ -12,7 +12,7 @@ import type { JSON_SCHEMA_TYPE, CORD_ANCHORED_PROOF_TYPE, CORD_CREDENTIAL_DIGEST_PROOF_TYPE, - CORD_SELF_SIGNED_PROOF_TYPE, + CORD_SIGNATURE_PROOF_TYPE, } from './constants.js' export interface Proof { @@ -25,8 +25,8 @@ export interface Proof { export type IPublicKeyRecord = Partial & Pick -export interface SelfSignedProof extends Proof { - type: typeof CORD_SELF_SIGNED_PROOF_TYPE +export interface CordSignatureProof extends Proof { + type: typeof CORD_SIGNATURE_PROOF_TYPE verificationMethod: string | IPublicKeyRecord signature: string } diff --git a/packages/vc-export/src/vc-js/context/context.json b/packages/vc-export/src/vc-js/context/context.json index 4b4ce855..691b7fe0 100644 --- a/packages/vc-export/src/vc-js/context/context.json +++ b/packages/vc-export/src/vc-js/context/context.json @@ -36,8 +36,8 @@ } } }, - "CordSelfSigned2020": { - "@id": "cordCred:CordSelfSigned2020", + "CordSignature2020": { + "@id": "cordCred:CordSignature2020", "@context": { "@version": 1.1, "@protected": true, diff --git a/packages/vc-export/src/vc-js/examples/example-vc.json b/packages/vc-export/src/vc-js/examples/example-vc.json deleted file mode 100644 index 0cc29c82..00000000 --- a/packages/vc-export/src/vc-js/examples/example-vc.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://cord.network/contexts/credentials" - ], - "type": [ - "VerifiableCredential", - "CordCredential" - ], - "id": "cord:cred:0x24195dd6313c0bb560f3043f839533b54bcd32d602dd848471634b0345ec88ad", - "credentialSubject": { - "@id": "did:cord:4r1WkS3t8rbCb11H8t3tJvGVCynwDXSUBiuGB6sLRHzCLCjs", - "@context": { - "@vocab": "cord:schema:0xf0fd09f9ed6233b2627d37eb5d6c528345e8945e0b610e70997ed470728b2ebf#" - }, - "birthday": "1991-01-01", - "name": "Kurt", - "premium": true - }, - "evidence": [], - "issuer": "did:cord:4sejigvu6STHdYmmYf2SuN92aNp8TbrsnBBDUj7tMrJ9Z3cG", - "issuanceDate": "2021-03-25T10:20:44.242Z", - "nonTransferable": true, - "proof": [ - { - "type": "SelfSigned", - "proofPurpose": "assertionMethod", - "verificationMethod": { - "type": "Ed25519VerificationKey2018", - "publicKeyHex": "0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee" - }, - "signature": "0x00c374b5314d7192224bd620047f740c029af118eb5645a4662f76a2e3d70a877290f9a96cb9ee9ccc6c6bce24a0cf132a07edb603d0d0632f84210d528d2a7701" - }, - { - "type": "Credential", - "proofPurpose": "assertionMethod", - "issuerAddress": "4sejigvu6STHdYmmYf2SuN92aNp8TbrsnBBDUj7tMrJ9Z3cG" - }, - { - "type": "CredentialDigest", - "proofPurpose": "assertionMethod", - "nonces": { - "0xe5a099ea4f8be89227af8a5d74b0371e1c13232978c8b8edce1ecec698eb2665": "eab8a98c-0ef3-4a33-a5c7-c9821b3bec45", - "0x14a06c5955ebc9247c9f54b30e0f1714e6ebd54ae05ad7b16fa9a4643dff1dc2": "fda7a7d4-770c-4cae-9cd9-6deebdb3ed80", - "0xb102f462e4cde1b48e7936085cef1e2ab6ae4f7ca46cd3fab06074c00546a33d": "ed28443a-ec36-4a54-9caa-6bf014df257d", - "0xf42b46c4a7a3bad68650069bd81fdf2085c9ea02df1c27a82282e97e3f71ef8e": "adc7dc71-ab0a-45f9-a091-9f3ec1bb96c7" - }, - "streamHashes": [ - "0x0586412d7b8adf811c288211c9c704b3331bb3adb61fba6448c89453568180f6", - "0x3856178f49d3c379e00793125678eeb8db61cfa4ed32cd7a4b67ac8e27714fc1", - "0x683428497edeba0198f02a45a7015fc2c010fa75994bc1d1372349c25e793a10", - "0x8804cc546c4597b2ab0541dd3a6532e338b0b5b4d2458eb28b4d909a5d4caf4e" - ] - } - ] -} \ No newline at end of file diff --git a/packages/vc-export/src/vc-js/suites/CordSignatureSuite.ts b/packages/vc-export/src/vc-js/suites/CordSignatureSuite.ts index 592b999a..04cca9d7 100644 --- a/packages/vc-export/src/vc-js/suites/CordSignatureSuite.ts +++ b/packages/vc-export/src/vc-js/suites/CordSignatureSuite.ts @@ -5,14 +5,14 @@ import type { VerificationResult, } from 'jsonld-signatures' import type { JsonLdObj } from 'jsonld/jsonld-spec' -import type { IPublicKeyRecord, SelfSignedProof } from '../../types.js' -import { verifySelfSignedProof } from '../../verificationUtils.js' +import type { IPublicKeyRecord, CordSignatureProof } from '../../types.js' +import { verifyCordSignatureProof } from '../../verificationUtils.js' import CordAbstractSuite from './CordAbstractSuite.js' -import { CORD_SELF_SIGNED_PROOF_TYPE } from '../../constants.js' +import { CORD_SIGNATURE_PROOF_TYPE } from '../../constants.js' export default class CordSignatureSuite extends CordAbstractSuite { constructor() { - super({ type: CORD_SELF_SIGNED_PROOF_TYPE, verificationMethod: '' }) + super({ type: CORD_SIGNATURE_PROOF_TYPE, verificationMethod: '' }) } public async verifyProof(options: { @@ -29,7 +29,7 @@ export default class CordSignatureSuite extends CordAbstractSuite { if (!proof || typeof proof !== 'object') throw new TypeError('proof must be a JsonLd object') const compactedDoc = await this.compactDoc(document, options) - const compactedProof = await this.compactProof( + const compactedProof = await this.compactProof( proof, options ) @@ -46,7 +46,7 @@ export default class CordSignatureSuite extends CordAbstractSuite { dereferenced.document as IPublicKeyRecord } // note that we currently don't check whether the public key in the proof is linked to the credential subject - const { verified, errors } = verifySelfSignedProof( + const { verified, errors } = verifyCordSignatureProof( compactedDoc, compactedProof ) diff --git a/packages/vc-export/src/verificationUtils.ts b/packages/vc-export/src/verificationUtils.ts index d18d4832..e46d6279 100644 --- a/packages/vc-export/src/verificationUtils.ts +++ b/packages/vc-export/src/verificationUtils.ts @@ -9,14 +9,14 @@ import jsonld from 'jsonld' import { Stream, TypeSchema, DidUtils } from '@cord.network/modules' import { Crypto, JsonSchema } from '@cord.network/utils' import { - CORD_SELF_SIGNED_PROOF_TYPE, + CORD_SIGNATURE_PROOF_TYPE, CORD_ANCHORED_PROOF_TYPE, CORD_CREDENTIAL_DIGEST_PROOF_TYPE, KeyTypesMap, } from './constants.js' import type { VerifiableCredential, - SelfSignedProof, + CordSignatureProof, CordStreamProof, CredentialDigestProof, } from './types.js' @@ -56,15 +56,15 @@ const PROOF_MALFORMED_ERROR = (reason: string): Error => * @param proof CORD self signed proof object. * @returns Object indicating whether proof could be verified. */ -export function verifySelfSignedProof( +export function verifyCordSignatureProof( credential: VerifiableCredential, - proof: SelfSignedProof + proof: CordSignatureProof ): VerificationResult { const result: VerificationResult = { verified: true, errors: [] } try { // check proof const type = proof['@type'] || proof.type - if (type !== CORD_SELF_SIGNED_PROOF_TYPE) + if (type !== CORD_SIGNATURE_PROOF_TYPE) throw new Error('Proof type mismatch') if (!proof.signature) throw PROOF_MALFORMED_ERROR('signature missing') const { verificationMethod } = proof From fa0df7da5e318ef6bb0d0dab073300b7fec7c74a Mon Sep 17 00:00:00 2001 From: Satish Mohan <54302767+smohan-dw@users.noreply.github.com> Date: Thu, 23 Jun 2022 01:57:51 +0530 Subject: [PATCH 5/8] add cord identifiers to vc --- demo/src/demo-vc.ts | 1 - packages/modules/src/content/Content.utils.ts | 10 +++- packages/modules/src/did/Did.utils.ts | 19 +------ packages/types/src/Content.ts | 1 + packages/types/src/Identity.ts | 2 + packages/utils/src/Identifier.ts | 43 +++++++++++++- packages/utils/src/SDKErrors.ts | 6 ++ .../src/exportToVerifiableCredential.ts | 11 ++-- packages/vc-export/src/types.ts | 1 - .../src/vc-js/examples/example-vc-old.json | 56 +++++++++++++++++++ packages/vc-export/src/verificationUtils.ts | 34 ++++++----- 11 files changed, 139 insertions(+), 45 deletions(-) create mode 100644 packages/vc-export/src/vc-js/examples/example-vc-old.json diff --git a/demo/src/demo-vc.ts b/demo/src/demo-vc.ts index a91ab5d5..f14dcd0b 100644 --- a/demo/src/demo-vc.ts +++ b/demo/src/demo-vc.ts @@ -152,7 +152,6 @@ async function main() { console.log(`\n❄️ Verifiable Presentation - Selective Disclosure `) const sharedCredential = JSON.parse(JSON.stringify(VC)) - console.log(JSON.stringify(VC)) const vcPresentation = await VCUtils.presentation.makePresentation( sharedCredential, ['name', 'country'] diff --git a/packages/modules/src/content/Content.utils.ts b/packages/modules/src/content/Content.utils.ts index 07d98de2..646540d4 100644 --- a/packages/modules/src/content/Content.utils.ts +++ b/packages/modules/src/content/Content.utils.ts @@ -6,7 +6,13 @@ import type { PartialContent, CompressedPartialContent, } from '@cord.network/types' -import { jsonabc, DataUtils, Crypto, SDKErrors } from '@cord.network/utils' +import { + jsonabc, + DataUtils, + Crypto, + SDKErrors, + Identifier, +} from '@cord.network/utils' const VC_VOCAB = 'https://www.w3.org/2018/credentials#' @@ -27,7 +33,7 @@ function jsonLDcontents( if (!schema) new SDKErrors.ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED() const vocabulary = `${schema}#` const result: Record = {} - if (holder) result['@id'] = holder + if (holder) result['@id'] = Identifier.getAccountIdentifierFromAddress(holder) if (!expanded) { return { diff --git a/packages/modules/src/did/Did.utils.ts b/packages/modules/src/did/Did.utils.ts index b33f74d4..72e597b5 100644 --- a/packages/modules/src/did/Did.utils.ts +++ b/packages/modules/src/did/Did.utils.ts @@ -12,7 +12,7 @@ import { Identity } from '../identity/Identity.js' import { CONTEXT, IDENTIFIER_PREFIX, - ACCOUNT_IDENTIFIER_PREFIX, + // ACCOUNT_IDENTIFIER_PREFIX, IDid, IDidDocument, IDidDocumentSigned, @@ -57,14 +57,6 @@ export function getIdentifierFromAddress( : IDENTIFIER_PREFIX + address } -export function getAccountIdentifierFromAddress( - address: IPublicIdentity['address'] -): IDid['identifier'] { - return address.startsWith(ACCOUNT_IDENTIFIER_PREFIX) - ? address - : ACCOUNT_IDENTIFIER_PREFIX + address -} - /** * Fetches the root of this delegation node. * @@ -83,15 +75,6 @@ export function getAddressFromIdentifier( return identifier.substr(IDENTIFIER_PREFIX.length) } -export function getAccountAddressFromIdentifier( - address: IDid['identifier'] -): IPublicIdentity['address'] { - if (!address.startsWith(ACCOUNT_IDENTIFIER_PREFIX)) { - throw new SDKErrors.ERROR_INVALID_DID_PREFIX(address) - } - return address.substr(ACCOUNT_IDENTIFIER_PREFIX.length) -} - export function createDefaultDidDocument( identifier: string, publicBoxKey: string, diff --git a/packages/types/src/Content.ts b/packages/types/src/Content.ts index 4407d97d..85622718 100644 --- a/packages/types/src/Content.ts +++ b/packages/types/src/Content.ts @@ -9,6 +9,7 @@ import type { IPublicIdentity } from './PublicIdentity' * The minimal partial stream from which a JSON-LD representation can be built. */ export type PartialContent = Partial & Pick +export const HASH_PREFIX: string = 'hash:cord:' export type IContents = Record< string, diff --git a/packages/types/src/Identity.ts b/packages/types/src/Identity.ts index 9427c7be..9e46dada 100644 --- a/packages/types/src/Identity.ts +++ b/packages/types/src/Identity.ts @@ -8,6 +8,8 @@ import type { BoxKeyPair } from 'tweetnacl' import type { Index } from '@polkadot/types/interfaces' import { AnyNumber } from '@polkadot/types/types' +export const ACCOUNT_IDENTIFIER_PREFIX: string = 'id:cord:' + export interface IIdentity { readonly signKeyringPair: KeyringPair readonly seed: Uint8Array diff --git a/packages/utils/src/Identifier.ts b/packages/utils/src/Identifier.ts index acc721d2..eb1b6abf 100644 --- a/packages/utils/src/Identifier.ts +++ b/packages/utils/src/Identifier.ts @@ -9,6 +9,8 @@ import { isHex, u8aToHex, } from '@polkadot/util' +import type { IPublicIdentity } from '@cord.network/types' +import { ACCOUNT_IDENTIFIER_PREFIX, HASH_PREFIX } from '@cord.network/types' const defaults = { allowedDecodedLengths: [1, 2, 4, 8, 32, 33], @@ -147,8 +149,15 @@ export function getIdentifierKey( return identifier.split(prefix).join('') } -export function getIdentifierHash(identifier: string, prefix: string): string { - const id = identifier.split(prefix).join('') +export function getHashIdentifier( + identifier: HexString | Uint8Array | string +): string { + assert(identifier, 'Invalid key string passed') + return `${HASH_PREFIX}${identifier}` +} + +export function getIdentifierHash(identifier: string): string { + const id = identifier.split(HASH_PREFIX).join('') return decodeIdentifierHash(id) } @@ -179,3 +188,33 @@ export function checkIdentifier( return [isValid, isValid ? null : 'Invalid decoded identifier checksum'] } + +/** + * Creates Account Identifier from Fetches Account Address. + * + * @param address Account address to derive it's identifier. + * + * @returns The Address identifier from the Account Address. + */ +export function getAccountIdentifierFromAddress( + address: IPublicIdentity['address'] +): string { + return address.startsWith(ACCOUNT_IDENTIFIER_PREFIX) + ? address + : ACCOUNT_IDENTIFIER_PREFIX + address +} + +/** + * Fetches Account Address from Identifier. + * + * @param address Account identifier to derive it's address from. + * @throws When the identifier is not prefixed with the defined ACCOUNT_IDENTIFIER_PREFIX. + * @throws [[ERROR_INVALID_ID_PREFIX]]. + * + * @returns The Address derived from the Account Identifier. + */ +export function getAccountAddressFromIdentifier( + address: string +): IPublicIdentity['address'] { + return address.split(ACCOUNT_IDENTIFIER_PREFIX).join('') +} diff --git a/packages/utils/src/SDKErrors.ts b/packages/utils/src/SDKErrors.ts index 199621df..d2590ee0 100644 --- a/packages/utils/src/SDKErrors.ts +++ b/packages/utils/src/SDKErrors.ts @@ -364,6 +364,12 @@ export class ERROR_DID_IDENTIFIER_MISMATCH extends SDKError { } } +export class ERROR_INVALID_ID_PREFIX extends SDKError { + constructor(identifier: string) { + super(`Not a Cord ID\n${identifier}`) + } +} + export class ERROR_MESSAGE_TYPE extends SDKError { constructor(message: string, expected: string) { super(`Unexpected message type. Received ${message}, expected ${expected}`) diff --git a/packages/vc-export/src/exportToVerifiableCredential.ts b/packages/vc-export/src/exportToVerifiableCredential.ts index 7aa20bfc..07150f12 100644 --- a/packages/vc-export/src/exportToVerifiableCredential.ts +++ b/packages/vc-export/src/exportToVerifiableCredential.ts @@ -6,7 +6,7 @@ import { decodeAddress } from '@polkadot/keyring' import { u8aToHex } from '@polkadot/util' import type { AnyJson } from '@polkadot/types/types' -import { DidUtils, ContentUtils, Identity } from '@cord.network/modules' +import { ContentUtils, Identity } from '@cord.network/modules' import type { ICredential, ISchema } from '@cord.network/types' import { signatureVerify } from '@polkadot/util-crypto' import { @@ -71,7 +71,7 @@ export function fromCredential( Record > - const issuer = DidUtils.getAccountIdentifierFromAddress(input.stream.issuer) + const issuer = Identifier.getAccountIdentifierFromAddress(input.stream.issuer) const issuanceDate = input.request.issuanceDate const expirationDate = input.request.expirationDate @@ -85,7 +85,7 @@ export function fromCredential( name: schema.title, schema, author: controller - ? DidUtils.getAccountIdentifierFromAddress(controller) + ? Identifier.getAccountIdentifierFromAddress(controller) : undefined, } } @@ -105,7 +105,7 @@ export function fromCredential( issuanceDate, expirationDate, credentialSubject, - credentialHash: rootHash, + credentialHash: Identifier.getHashIdentifier(rootHash), evidence, nonTransferable: true, proof, @@ -121,7 +121,7 @@ export function fromCredential( )}\nReceived: ${keyType}` ) - // add self-signed proof + // add cord signature proof (issuer) // infer key type if (input.stream.holder !== holder.address) { throw new SDKErrors.ERROR_IDENTITY_MISMATCH() @@ -143,7 +143,6 @@ export function fromCredential( type: CORD_ANCHORED_PROOF_TYPE, proofPurpose: 'assertionMethod', issuerAddress: input.stream.issuer, - holderAddress: holder ? input.stream.holder : undefined, } VC.proof.push(streamProof) diff --git a/packages/vc-export/src/types.ts b/packages/vc-export/src/types.ts index 45bdc2ca..aa019d3d 100644 --- a/packages/vc-export/src/types.ts +++ b/packages/vc-export/src/types.ts @@ -33,7 +33,6 @@ export interface CordSignatureProof extends Proof { export interface CordStreamProof extends Proof { type: typeof CORD_ANCHORED_PROOF_TYPE issuerAddress: string - holderAddress?: string } export interface CredentialDigestProof extends Proof { type: typeof CORD_CREDENTIAL_DIGEST_PROOF_TYPE diff --git a/packages/vc-export/src/vc-js/examples/example-vc-old.json b/packages/vc-export/src/vc-js/examples/example-vc-old.json new file mode 100644 index 00000000..0cc29c82 --- /dev/null +++ b/packages/vc-export/src/vc-js/examples/example-vc-old.json @@ -0,0 +1,56 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://cord.network/contexts/credentials" + ], + "type": [ + "VerifiableCredential", + "CordCredential" + ], + "id": "cord:cred:0x24195dd6313c0bb560f3043f839533b54bcd32d602dd848471634b0345ec88ad", + "credentialSubject": { + "@id": "did:cord:4r1WkS3t8rbCb11H8t3tJvGVCynwDXSUBiuGB6sLRHzCLCjs", + "@context": { + "@vocab": "cord:schema:0xf0fd09f9ed6233b2627d37eb5d6c528345e8945e0b610e70997ed470728b2ebf#" + }, + "birthday": "1991-01-01", + "name": "Kurt", + "premium": true + }, + "evidence": [], + "issuer": "did:cord:4sejigvu6STHdYmmYf2SuN92aNp8TbrsnBBDUj7tMrJ9Z3cG", + "issuanceDate": "2021-03-25T10:20:44.242Z", + "nonTransferable": true, + "proof": [ + { + "type": "SelfSigned", + "proofPurpose": "assertionMethod", + "verificationMethod": { + "type": "Ed25519VerificationKey2018", + "publicKeyHex": "0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee" + }, + "signature": "0x00c374b5314d7192224bd620047f740c029af118eb5645a4662f76a2e3d70a877290f9a96cb9ee9ccc6c6bce24a0cf132a07edb603d0d0632f84210d528d2a7701" + }, + { + "type": "Credential", + "proofPurpose": "assertionMethod", + "issuerAddress": "4sejigvu6STHdYmmYf2SuN92aNp8TbrsnBBDUj7tMrJ9Z3cG" + }, + { + "type": "CredentialDigest", + "proofPurpose": "assertionMethod", + "nonces": { + "0xe5a099ea4f8be89227af8a5d74b0371e1c13232978c8b8edce1ecec698eb2665": "eab8a98c-0ef3-4a33-a5c7-c9821b3bec45", + "0x14a06c5955ebc9247c9f54b30e0f1714e6ebd54ae05ad7b16fa9a4643dff1dc2": "fda7a7d4-770c-4cae-9cd9-6deebdb3ed80", + "0xb102f462e4cde1b48e7936085cef1e2ab6ae4f7ca46cd3fab06074c00546a33d": "ed28443a-ec36-4a54-9caa-6bf014df257d", + "0xf42b46c4a7a3bad68650069bd81fdf2085c9ea02df1c27a82282e97e3f71ef8e": "adc7dc71-ab0a-45f9-a091-9f3ec1bb96c7" + }, + "streamHashes": [ + "0x0586412d7b8adf811c288211c9c704b3331bb3adb61fba6448c89453568180f6", + "0x3856178f49d3c379e00793125678eeb8db61cfa4ed32cd7a4b67ac8e27714fc1", + "0x683428497edeba0198f02a45a7015fc2c010fa75994bc1d1372349c25e793a10", + "0x8804cc546c4597b2ab0541dd3a6532e338b0b5b4d2458eb28b4d909a5d4caf4e" + ] + } + ] +} \ No newline at end of file diff --git a/packages/vc-export/src/verificationUtils.ts b/packages/vc-export/src/verificationUtils.ts index e46d6279..0b71497d 100644 --- a/packages/vc-export/src/verificationUtils.ts +++ b/packages/vc-export/src/verificationUtils.ts @@ -6,8 +6,8 @@ // import { u8aConcat, hexToU8a, u8aToHex } from '@polkadot/util' import { signatureVerify, blake2AsHex } from '@polkadot/util-crypto' import jsonld from 'jsonld' -import { Stream, TypeSchema, DidUtils } from '@cord.network/modules' -import { Crypto, JsonSchema } from '@cord.network/utils' +import { Stream, TypeSchema } from '@cord.network/modules' +import { Crypto, JsonSchema, Identifier } from '@cord.network/utils' import { CORD_SIGNATURE_PROOF_TYPE, CORD_ANCHORED_PROOF_TYPE, @@ -87,7 +87,9 @@ export function verifyCordSignatureProof( ) const signerPubKey = verificationMethod.publicKeyHex - const rootHash = fromCredentialIRI(credential.credentialHash) + const rootHash = Identifier.getIdentifierHash( + fromCredentialIRI(credential.credentialHash) + ) // validate signature over root hash // signatureVerify can handle all required signature types out of the box const verification = signatureVerify( @@ -127,22 +129,15 @@ export async function verifyStreamProof( const type = proof['@type'] || proof.type if (type !== CORD_ANCHORED_PROOF_TYPE) throw new Error('Proof type mismatch') - const { issuerAddress, holderAddress } = proof + const { issuerAddress } = proof if (typeof issuerAddress !== 'string' || !issuerAddress) throw PROOF_MALFORMED_ERROR('issuer address not understood') if ( issuerAddress !== - DidUtils.getAccountAddressFromIdentifier(credential.issuer) + Identifier.getAccountAddressFromIdentifier(credential.issuer) ) throw PROOF_MALFORMED_ERROR('credential issuer address is not matching') - if (holderAddress) { - if (typeof holderAddress !== 'string') - throw PROOF_MALFORMED_ERROR('holder address not understood') - if (credential.credentialSubject['@id'] !== holderAddress) - throw PROOF_MALFORMED_ERROR('credential holder address is not matching') - } - if (typeof credential.id !== 'string' || !credential.id) throw CREDENTIAL_MALFORMED_ERROR( 'stream id (=stream hash) missing / invalid' @@ -166,10 +161,14 @@ export async function verifyStreamProof( ) } // if holder data on proof does not correspond to data on chain, proof is incorrect + const holderAddress = credential.credentialSubject['@id'] if (holderAddress) { if (typeof holderAddress !== 'string') throw PROOF_MALFORMED_ERROR('holder address not understood') - if (onChain.holder !== holderAddress) + if ( + onChain.holder !== + Identifier.getAccountAddressFromIdentifier(holderAddress) + ) throw new Error( `proof not matching on-chain data: proof ${{ holder: holderAddress, @@ -178,7 +177,10 @@ export async function verifyStreamProof( } // if rootHash on credential does not correspond to data on chain, proof is incorrect - if (onChain.streamHash !== credential.credentialHash) + if ( + onChain.streamHash !== + Identifier.getIdentifierHash(credential.credentialHash) + ) throw new Error( `credential hash is not matching on-chain data: proof ${{ hash: credential.credentialHash, @@ -231,7 +233,9 @@ export async function verifyCredentialDigestProof( throw CREDENTIAL_MALFORMED_ERROR('credential subject missing') const rootHash = verifyRootHash(credential, proof) // throw if root hash does not match expected (=id) - const expectedRootHash = credential.credentialHash + const expectedRootHash = Identifier.getIdentifierHash( + credential.credentialHash + ) if (expectedRootHash !== rootHash) throw new Error('computed root hash does not match expected') From 898787c246facce4b6a77ca7456a59e09e02915f Mon Sep 17 00:00:00 2001 From: Satish Mohan <54302767+smohan-dw@users.noreply.github.com> Date: Fri, 1 Jul 2022 11:36:02 +0530 Subject: [PATCH 6/8] no classes for core modules (#16) * add evidence and rootHash to vc * no clasess for stream and chain * no clasess for schema * no clasess for content stream and credentials * no clasess for space * no clasess for Credentials * demo updates --- demo/res/schema.json | 2 +- demo/src/demo-messaging.ts | 232 ++---- demo/src/demo-vc.ts | 14 +- demo/src/demo.ts | 57 +- demo/src/identifier.ts | 34 +- demo/src/stream-bench.ts | 94 +-- packages/config/src/ConfigService.ts | 2 +- packages/messaging/src/Message.ts | 8 +- packages/messaging/src/Message.utils.ts | 42 +- packages/modules/src/content/Content.ts | 495 ++++++++---- packages/modules/src/content/Content.utils.ts | 271 ------- packages/modules/src/content/index.ts | 3 +- .../src/contentstream/ContentStream.ts | 751 ++++++++++-------- .../src/contentstream/ContentStream.utils.ts | 155 ---- packages/modules/src/contentstream/index.ts | 3 +- packages/modules/src/credential/Credential.ts | 405 +++++----- .../src/credential/Credential.utils.ts | 93 --- .../modules/src/credential/Presentation.ts | 102 --- packages/modules/src/credential/index.ts | 4 +- packages/modules/src/identity/Identity.ts | 24 +- packages/modules/src/index.ts | 18 +- packages/modules/src/schema/Schema.chain.ts | 94 +-- packages/modules/src/schema/Schema.ts | 513 +++++++----- .../schema/{TypeSchema.ts => Schema.types.ts} | 0 packages/modules/src/schema/Schema.utils.ts | 255 ------ packages/modules/src/schema/SchemaMetadata.ts | 31 - packages/modules/src/schema/index.ts | 7 +- packages/modules/src/space/Space.chain.ts | 91 +-- packages/modules/src/space/Space.ts | 269 ++----- packages/modules/src/space/Space.utils.ts | 28 - packages/modules/src/space/index.ts | 4 +- packages/modules/src/stream/Stream.chain.ts | 60 +- packages/modules/src/stream/Stream.ts | 418 ++++------ packages/modules/src/stream/Stream.utils.ts | 92 --- .../modules/src/stream/StreamDetails.utils.ts | 82 -- packages/modules/src/stream/index.ts | 5 +- packages/network/src/chain/Chain.ts | 8 +- packages/network/src/chain/Chain.utils.ts | 4 +- packages/types/src/ContentStream.ts | 2 +- packages/types/src/Identity.ts | 6 + packages/types/src/Schema.ts | 6 +- packages/types/src/Space.ts | 3 +- packages/utils/src/DataUtils.ts | 5 +- packages/utils/src/SDKErrors.ts | 15 +- .../src/exportToVerifiableCredential.ts | 4 +- packages/vc-export/src/index.ts | 4 +- .../vc-export/src/vc-js/context/context.json | 6 +- .../src/vc-js/suites/CordAbstractSuite.ts | 1 + packages/vc-export/src/verificationUtils.ts | 4 +- tsconfig.json | 1 + 50 files changed, 1865 insertions(+), 2962 deletions(-) delete mode 100644 packages/modules/src/content/Content.utils.ts delete mode 100644 packages/modules/src/contentstream/ContentStream.utils.ts delete mode 100644 packages/modules/src/credential/Credential.utils.ts delete mode 100644 packages/modules/src/credential/Presentation.ts rename packages/modules/src/schema/{TypeSchema.ts => Schema.types.ts} (100%) delete mode 100644 packages/modules/src/schema/Schema.utils.ts delete mode 100644 packages/modules/src/schema/SchemaMetadata.ts delete mode 100644 packages/modules/src/space/Space.utils.ts delete mode 100644 packages/modules/src/stream/Stream.utils.ts delete mode 100644 packages/modules/src/stream/StreamDetails.utils.ts diff --git a/demo/res/schema.json b/demo/res/schema.json index da2bbe82..66cabce3 100644 --- a/demo/res/schema.json +++ b/demo/res/schema.json @@ -17,7 +17,7 @@ "type": "string" }, "credit": { - "type": "integer" + "type": "integer" } }, "type": "object" diff --git a/demo/src/demo-messaging.ts b/demo/src/demo-messaging.ts index 7a852096..1ff6b7d2 100644 --- a/demo/src/demo-messaging.ts +++ b/demo/src/demo-messaging.ts @@ -45,7 +45,7 @@ async function main() { let newSpace = Cord.Space.fromSpaceProperties(spaceContent, employeeIdentity) - let spaceCreationExtrinsic = await newSpace.create() + let spaceCreationExtrinsic = await Cord.Space.create(newSpace) console.dir(newSpace, { depth: null, colors: true }) @@ -76,7 +76,7 @@ async function main() { newSpace.identifier ) - let schemaCreationExtrinsic = await newSchema.create() + let schemaCreationExtrinsic = await Cord.Schema.create(newSchema) console.dir(newSchema, { depth: null, colors: true }) @@ -106,7 +106,7 @@ async function main() { country: 'India', credit: 1000, } - let schemaStream = Cord.Content.fromProperties( + let schemaStream = Cord.Content.fromSchemaAndContent( newSchema, content, employeeIdentity.address, @@ -123,7 +123,7 @@ async function main() { let newStream = Cord.Stream.fromContentStream(newStreamContent) - let streamCreationExtrinsic = await newStream.create() + let streamCreationExtrinsic = await Cord.Stream.create(newStream) console.dir(newStream, { depth: null, colors: true }) try { @@ -140,162 +140,92 @@ async function main() { console.log(e.errorCode, '-', e.message) } - // Step 4: Update a Stream - console.log(`\n❄️ Update - ${newStreamContent.identifier}`) - const updateContent = JSON.parse(JSON.stringify(newStreamContent)) - // { ...newStreamContent } - updateContent.content.contents.name = 'Alice Jackson' - - let updateStreamContent = Cord.ContentStream.updateContentProperties( - updateContent, - employeeIdentity - ) - console.dir(updateStreamContent, { depth: null, colors: true }) - - let updateStream = Cord.Stream.fromContentStream(updateStreamContent) - let updateStreamCreationExtrinsic = await updateStream.update() - console.dir(updateStream, { depth: null, colors: true }) + // await utils.waitForEnter('\n⏎ Press Enter to continue..') - try { - await Cord.ChainUtils.signAndSubmitTx( - updateStreamCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) - console.log('✅ Stream updated!') - } catch (e: any) { - console.log(e.errorCode, '-', e.message) - } + // Step 7: Credential exchange via messaging + console.log(`\n\n📩 Credential Exchange - Selective Disclosure (Verifier)`) + console.log(`🔑 Verifier Address: ${verifierIdentity.address}`) + const purpose = 'Account Opening Request' + const validUntil = Date.now() + 864000000 + const relatedData = true - // Step 3: Validate a Credential - console.log(`\n❄️ Verify - ${updateStreamContent.identifier} `) - const stream = await Cord.Stream.query(updateStream.identifier) - if (!stream) { - console.log(`Stream not anchored on CORD`) - } else { - const credential = Cord.Credential.fromRequestAndStream( - updateStreamContent, - stream - ) - const isCredentialValid = await credential.verify() - console.log(`Is Alices's credential valid? ${isCredentialValid}`) + const messageBodyForClaimer: Cord.MessageBody = { + type: Cord.Message.BodyType.REQUEST_CREDENTIAL, + content: { schemas: [{ schemaIdentifier: schemaStream.schema }] }, } - - // Step 3: Validate a modified Credential - // TODO: fix error handling - // console.log(`\n❄️ Validate Credential - ${updateStream.identifier} `) - // const chainStream = await Cord.Stream.query(updateStream.identifier) - // if (!chainStream) { - // console.log(`Stream not anchored on CORD`) - // } else { - // console.dir(newStreamContent, { depth: null, colors: true }) - // const credential = Cord.Credential.fromRequestAndStream( - // newStreamContent, - // chainStream - // ) - - // const isCredentialValid = await credential.verify() - // console.log(`Is Alices's modified credential valid? ${isCredentialValid}`) - // } - - // Step 3: Revoke a Stream - console.log(`\n❄️ Revoke - ${updateStreamContent.identifier} `) - let revokeStream = updateStream - - let revokeStreamCreationExtrinsic = await revokeStream.revoke( - employeeIdentity + const messageForClaimer = new Kilt.Message( + messageBodyForClaimer, + verifierLightDID.did, + claimerLightDid.did ) - try { - await Cord.ChainUtils.signAndSubmitTx( - revokeStreamCreationExtrinsic, - entityIdentity, + const { session, message: message } = + cord.Exchange.Request.newRequestBuilder() + .requestPresentation({ + id: schemaStream.schemaId, + properties: ['name', 'age'], + }) + .finalize( + purpose, + verifierIdentity, + holderIdentity.getPublicIdentity(), + validUntil, + relatedData + ) + + console.log(`\n📧 Selective Disclosure Request`) + console.dir(message, { depth: null, colors: true }) + + const chainStream = await cord.Stream.query(newStream.streamId) + if (chainStream) { + let credential: cord.Credential + credential = cord.Credential.fromMarkContentStream( + newStreamContent, + chainStream + ) + const presentation = cord.Exchange.Share.createPresentation( + holderIdentity, + message, + verifierIdentity.getPublicIdentity(), + [credential], { - resolveOn: Cord.ChainUtils.IS_READY, - rejectOn: Cord.ChainUtils.IS_ERROR, + showAttributes: message.body.content[0].requiredProperties, + signer: holderIdentity, + request: message.body.request, } ) - console.log('✅ Stream revoked!') - } catch (e: any) { - console.log(e.errorCode, '-', e.message) - } - - // await utils.waitForEnter('\n⏎ Press Enter to continue..') - - // // Step 7: Credential exchange via messaging - // console.log(`\n\n📩 Credential Exchange - Selective Disclosure (Verifier)`) - // console.log(`🔑 Verifier Address: ${verifierIdentity.address}`) - // const purpose = 'Account Opening Request' - // const validUntil = Date.now() + 864000000 - // const relatedData = true - - // const { session, message: message } = - // cord.Exchange.Request.newRequestBuilder() - // .requestPresentation({ - // id: schemaStream.schemaId, - // properties: ['name', 'age'], - // }) - // .finalize( - // purpose, - // verifierIdentity, - // holderIdentity.getPublicIdentity(), - // validUntil, - // relatedData - // ) - - // console.log(`\n📧 Selective Disclosure Request`) - // console.dir(message, { depth: null, colors: true }) - - // const chainStream = await cord.Stream.query(newStream.streamId) - // if (chainStream) { - // let credential: cord.Credential - // credential = cord.Credential.fromMarkContentStream(newStreamContent, chainStream) - // const presentation = cord.Exchange.Share.createPresentation( - // holderIdentity, - // message, - // verifierIdentity.getPublicIdentity(), - // [credential], - // { - // showAttributes: message.body.content[0].requiredProperties, - // signer: holderIdentity, - // request: message.body.request, - // } - // ) - // const { verified } = await cord.Exchange.Verify.verifyPresentation( - // presentation, - // session - // ) - // console.log(`\n📧 Received Credential `) - // console.dir(presentation, { depth: null, colors: true }) - - // let result = vcPresentation.verifiableCredential.proof.forEach(function ( - // proof: any - // ) { - // console.log(proof) - // if (proof.type === VCUtils.constants.CORD_ANCHORED_PROOF_TYPE) - // VCUtils.verification.verifyStreamProof( - // vcPresentation.verifiableCredential, - // proof - // ) - // }) - // console.log(result) - // if (result && result.verified) { - // console.log( - // `Name of the crook: ${vcPresentation.verifiableCredential.credentialSubject.name}` - // ) // prints 'Billy The Kid' - // // console.log( - // // `Reward: ${vcPresentation.verifiableCredential.credentialSubject.}` - // // ) // undefined - // } - - // console.log('🔍 All valid? ', verified) - // } else { - // console.log(`\n❌ Credential not found `) - // } + const { verified } = await cord.Exchange.Verify.verifyPresentation( + presentation, + session + ) + console.log(`\n📧 Received Credential `) + console.dir(presentation, { depth: null, colors: true }) + + let result = vcPresentation.verifiableCredential.proof.forEach(function ( + proof: any + ) { + console.log(proof) + if (proof.type === VCUtils.constants.CORD_ANCHORED_PROOF_TYPE) + VCUtils.verification.verifyStreamProof( + vcPresentation.verifiableCredential, + proof + ) + }) + console.log(result) + if (result && result.verified) { + console.log( + `Name of the crook: ${vcPresentation.verifiableCredential.credentialSubject.name}` + ) // prints 'Billy The Kid' + // console.log( + // `Reward: ${vcPresentation.verifiableCredential.credentialSubject.}` + // ) // undefined + } + + console.log('🔍 All valid? ', verified) + } else { + console.log(`\n❌ Credential not found `) + } // await utils.waitForEnter('\n⏎ Press Enter to continue..') } diff --git a/demo/src/demo-vc.ts b/demo/src/demo-vc.ts index f14dcd0b..af924ea9 100644 --- a/demo/src/demo-vc.ts +++ b/demo/src/demo-vc.ts @@ -1,7 +1,7 @@ import * as Cord from '@cord.network/api' import { UUID } from '@cord.network/utils' -import type { VerifiableCredential } from 'vc-export/src/types' -import * as VCUtils from 'vc-export/src' +import type { VerifiableCredential } from '@cord.network/vc-export/src/types.js' +import * as VCUtils from '@cord.network/vc-export' async function main() { await Cord.init({ address: 'ws://127.0.0.1:9944' }) @@ -45,7 +45,7 @@ async function main() { spaceContent.title = spaceTitle let newSpace = Cord.Space.fromSpaceProperties(spaceContent, employeeIdentity) - let spaceCreationExtrinsic = await newSpace.create() + let spaceCreationExtrinsic = await Cord.Space.create(newSpace) try { await Cord.ChainUtils.signAndSubmitTx( @@ -74,7 +74,7 @@ async function main() { newSpace.identifier ) - let schemaCreationExtrinsic = await newSchema.create() + let schemaCreationExtrinsic = await Cord.Schema.create(newSchema) try { await Cord.ChainUtils.signAndSubmitTx( @@ -102,7 +102,7 @@ async function main() { country: 'India', credit: 1000, } - let schemaStream = Cord.Content.fromProperties( + let schemaStream = Cord.Content.fromSchemaAndContent( newSchema, content, employeeIdentity.address, @@ -119,7 +119,7 @@ async function main() { let newStream = Cord.Stream.fromContentStream(newStreamContent) - let streamCreationExtrinsic = await newStream.create() + let streamCreationExtrinsic = await Cord.Stream.create(newStream) console.dir(newStream, { depth: null, colors: true }) try { @@ -141,7 +141,7 @@ async function main() { console.log(`🔗 ${newStream.identifier} `) const stream = await Cord.Stream.query(newStream.identifier) - let credential: Cord.Credential + let credential: Cord.ICredential if (!stream) { console.log(`Stream not anchored on CORD`) } else { diff --git a/demo/src/demo.ts b/demo/src/demo.ts index 9676437c..c1feb264 100644 --- a/demo/src/demo.ts +++ b/demo/src/demo.ts @@ -44,7 +44,7 @@ async function main() { let newSpace = Cord.Space.fromSpaceProperties(spaceContent, employeeIdentity) - let spaceCreationExtrinsic = await newSpace.create() + let spaceCreationExtrinsic = await Cord.Space.create(newSpace) console.dir(newSpace, { depth: null, colors: true }) @@ -75,9 +75,12 @@ async function main() { newSpace.identifier ) - let schemaCreationExtrinsic = await newSchema.create() + let schemaCreationExtrinsic = await Cord.Schema.create(newSchema) - console.dir(newSchema, { depth: null, colors: true }) + console.dir(newSchema, { + depth: null, + colors: true, + }) try { await Cord.ChainUtils.signAndSubmitTx( @@ -105,7 +108,7 @@ async function main() { country: 'India', credit: 1000, } - let schemaStream = Cord.Content.fromProperties( + let schemaStream = Cord.Content.fromSchemaAndContent( newSchema, content, employeeIdentity.address, @@ -122,7 +125,7 @@ async function main() { let newStream = Cord.Stream.fromContentStream(newStreamContent) - let streamCreationExtrinsic = await newStream.create() + let streamCreationExtrinsic = await Cord.Stream.create(newStream) console.dir(newStream, { depth: null, colors: true }) try { @@ -144,14 +147,14 @@ async function main() { const updateContent = JSON.parse(JSON.stringify(newStreamContent)) updateContent.content.contents.name = 'Alice Jackson' - let updateStreamContent = Cord.ContentStream.updateContentProperties( + let updateStreamContent = Cord.ContentStream.updateContent( updateContent, employeeIdentity ) console.dir(updateStreamContent, { depth: null, colors: true }) let updateStream = Cord.Stream.fromContentStream(updateStreamContent) - let updateStreamCreationExtrinsic = await updateStream.update() + let updateStreamCreationExtrinsic = await Cord.Stream.update(updateStream) console.dir(updateStream, { depth: null, colors: true }) try { @@ -178,32 +181,16 @@ async function main() { updateStreamContent, stream ) - const isCredentialValid = await credential.verify() + const isCredentialValid = await Cord.Credential.verify(credential) console.log(`Is Alices's credential valid? ${isCredentialValid}`) } - // Step 7: Validate a modified Credential - // TODO: fix error handling - // console.log(`\n❄️ Validate Credential - ${updateStream.identifier} `) - // const chainStream = await Cord.Stream.query(updateStream.identifier) - // if (!chainStream) { - // console.log(`Stream not anchored on CORD`) - // } else { - // console.dir(newStreamContent, { depth: null, colors: true }) - // const credential = Cord.Credential.fromRequestAndStream( - // newStreamContent, - // chainStream - // ) - - // const isCredentialValid = await credential.verify() - // console.log(`Is Alices's modified credential valid? ${isCredentialValid}`) - // } - // Step 8: Revoke a Stream console.log(`\n❄️ Revoke - ${updateStreamContent.identifier} `) let revokeStream = updateStream - let revokeStreamCreationExtrinsic = await revokeStream.revoke( + let revokeStreamCreationExtrinsic = await Cord.Stream.revoke( + revokeStream, employeeIdentity ) @@ -212,14 +199,28 @@ async function main() { revokeStreamCreationExtrinsic, entityIdentity, { - resolveOn: Cord.ChainUtils.IS_READY, + resolveOn: Cord.ChainUtils.IS_IN_BLOCK, rejectOn: Cord.ChainUtils.IS_ERROR, } ) - console.log('✅ Stream revoked!') + console.log(`✅ Alices's credential revoked!`) } catch (e: any) { console.log(e.errorCode, '-', e.message) } + + // Step 9: Re-verify a revoked Credential + console.log(`\n❄️ Verify - ${updateStreamContent.identifier} `) + const revstream = await Cord.Stream.query(updateStream.identifier) + if (!revstream) { + console.log(`Stream not anchored on CORD`) + } else { + const credential = Cord.Credential.fromRequestAndStream( + updateStreamContent, + revstream + ) + const isCredentialValid = await Cord.Credential.verify(credential) + console.log(`Is Alices's credential valid? ${isCredentialValid}`) + } } main() .then(() => console.log('\nBye! 👋 👋 👋 ')) diff --git a/demo/src/identifier.ts b/demo/src/identifier.ts index 143c4503..0cd1cdd9 100644 --- a/demo/src/identifier.ts +++ b/demo/src/identifier.ts @@ -1,8 +1,5 @@ -import * as cord from '@cord.network/api' -import { UUID } from '@cord.network/utils' -import * as json from 'multiformats/codecs/json' -import { blake2b256 as hasher } from '@multiformats/blake2/blake2b' -import { CID } from 'multiformats/cid' +import * as Cord from '@Cord.network/api' +import { UUID } from '@Cord.network/utils' import type { HexString } from '@polkadot/util/types' import { base58Decode, base58Encode, blake2AsU8a } from '@polkadot/util-crypto' @@ -129,21 +126,21 @@ export function decodeIdentifier( } async function main() { - await cord.init({ address: 'ws://127.0.0.1:9944' }) + await Cord.init({ address: 'ws://127.0.0.1:9944' }) // Step 1: Setup Org Identity console.log(`\n🏛 Creating Identities\n`) //3x4DHc1rxVAEqKWSx1DAAA8wZxLB4VhiRbMV997niBckUwSi - const entityIdentity = cord.Identity.buildFromURI('//Bob', { + const entityIdentity = Cord.Identity.buildFromURI('//Bob', { signingKeyPairType: 'sr25519', }) - const employeeIdentity = cord.Identity.buildFromURI('//Dave', { + const employeeIdentity = Cord.Identity.buildFromURI('//Dave', { signingKeyPairType: 'ed25519', }) - const holderIdentity = cord.Identity.buildFromURI('//Alice', { + const holderIdentity = Cord.Identity.buildFromURI('//Alice', { signingKeyPairType: 'sr25519', }) - const verifierIdentity = cord.Identity.buildFromURI('//Charlie', { + const verifierIdentity = Cord.Identity.buildFromURI('//Charlie', { signingKeyPairType: 'ed25519', }) console.log( @@ -166,16 +163,12 @@ async function main() { let newSchemaTitle = newSchemaContent.title + ':' + UUID.generate() newSchemaContent.title = newSchemaTitle - let newSchema = cord.Schema.fromSchemaProperties( + let newSchema = Cord.Schema.fromSchemaProperties( newSchemaContent, - employeeIdentity.address + employeeIdentity ) - let bytes = json.encode(newSchema.schema) - let encoded_hash = await hasher.digest(bytes) - const schemaCid = CID.create(1, 0xb240, encoded_hash) - console.log('Version', newSchema.version) - let schemaCreationExtrinsic = await newSchema.create(schemaCid.toString()) + let schemaCreationExtrinsic = await Cord.Schema.create(newSchema) // console.log('DerivED ', encodeIdentifier(newSchema.hash, 29)) // console.log( @@ -187,14 +180,13 @@ async function main() { // console.log('base58:', schemaEncodedHash) // console.log( // 'base58 Decode:', - // cord.StreamUtils.hexToString(schemaEncodedHash), + // Cord.StreamUtils.hexToString(schemaEncodedHash), // schemaEncodedHash // ) // // console.log(encodeDerivedAddress(newSchema.hash, 1031)) console.log(`📧 Schema Details `) console.dir(newSchema, { depth: null, colors: true }) - console.log(`CID: `, schemaCid.toString()) console.log('\n⛓ Anchoring Schema to the chain...') console.log(`🔑 Creator: ${employeeIdentity.address} `) console.log(`🔑 Controller: ${entityIdentity.address} `) @@ -202,10 +194,10 @@ async function main() { } main() .then(() => console.log('\nBye! 👋 👋 👋 ')) - .finally(cord.disconnect) + .finally(Cord.disconnect) // process.on('SIGINT', async () => { // console.log('\nBye! 👋 👋 👋 \n') -// cord.disconnect() +// Cord.disconnect() // process.exit(0) // }) diff --git a/demo/src/stream-bench.ts b/demo/src/stream-bench.ts index 064871e6..ad939bac 100644 --- a/demo/src/stream-bench.ts +++ b/demo/src/stream-bench.ts @@ -1,23 +1,17 @@ -import * as cord from '@cord.network/api' +import * as Cord from '@Cord.network/api' import * as utils from './utils' -import { UUID } from '@cord.network/utils' -// import BN from 'bn.js' +import { UUID } from '@Cord.network/utils' import moment from 'moment' import Keyring from '@polkadot/keyring' -import * as json from 'multiformats/codecs/json' -import { blake2b256 as hasher } from '@multiformats/blake2/blake2b' -import { CID } from 'multiformats/cid' - -// const amount: BN = new BN('1') async function main() { - await cord.init({ address: 'ws://127.0.0.1:9944' }) + await Cord.init({ address: 'ws://127.0.0.1:9944' }) // Step 1: Setup Identities - const Alice = cord.Identity.buildFromURI('//Alice', { + const Alice = Cord.Identity.buildFromURI('//Alice', { signingKeyPairType: 'sr25519', }) - const Bob = cord.Identity.buildFromURI('//Bob', { + const Bob = Cord.Identity.buildFromURI('//Bob', { signingKeyPairType: 'sr25519', }) @@ -27,20 +21,13 @@ async function main() { let newSchemaTitle = newSchemaContent.title + ':' + UUID.generate() newSchemaContent.title = newSchemaTitle - let newSchema = cord.Schema.fromSchemaProperties( - newSchemaContent, - Bob.address - ) - - let bytes = json.encode(newSchema.schema) - let encoded_hash = await hasher.digest(bytes) - const schemaCid = CID.create(1, 0xb240, encoded_hash) - let schemaCreationExtrinsic = await newSchema.create(schemaCid.toString()) + let newSchema = Cord.Schema.fromSchemaProperties(newSchemaContent, Bob) + let schemaCreationExtrinsic = await await Cord.Schema.create(newSchema) try { - await cord.ChainUtils.signAndSubmitTx(schemaCreationExtrinsic, Bob, { - resolveOn: cord.ChainUtils.IS_IN_BLOCK, - rejectOn: cord.ChainUtils.IS_ERROR, + await Cord.ChainUtils.signAndSubmitTx(schemaCreationExtrinsic, Bob, { + resolveOn: Cord.ChainUtils.IS_IN_BLOCK, + rejectOn: Cord.ChainUtils.IS_ERROR, }) console.log('✅ Schema created!') } catch (e: any) { @@ -53,8 +40,7 @@ async function main() { let startTxPrep = moment() let txCount = 500 - let newStreamContent: cord.MarkContent - // let link_id: string = '5P4oXCREF8Uw6pJHRMZfhgmoN6DDAtAN72hNuAMgGnCqkJn7' + let newStreamContent: Cord.IContentStream console.log(`\n ✨ Benchmark ${txCount} transactions `) for (let j = 0; j < txCount; j++) { @@ -65,40 +51,22 @@ async function main() { country: 'India', credit: 1000, } - // const nonceSaltValue = UUID.generate() - let schemaStream = cord.Content.fromContent( + let schemaStream = Cord.Content.fromSchemaAndContent( newSchema, content, Alice.address ) - newStreamContent = cord.MarkContent.fromContent( - schemaStream, - Alice - // { nonceSalt: nonceSaltValue } - ) - - // newStreamContent = cord.MarkContent.fromContent( - // schemaStream, - // Alice, - // { link: link_id, nonceSalt: nonceSaltValue } - // ) + newStreamContent = Cord.ContentStream.fromContent(schemaStream, Alice) + let newStream = Cord.Stream.fromContentStream(newStreamContent) - // bytes = json.encode(newStreamContent) - // encoded_hash = await hasher.digest(bytes) - // const streamCid = CID.create(1, 0xb220, encoded_hash) - - let newStream = cord.Stream.fromMarkContentProperties( - newStreamContent - // streamCid.toString() - ) process.stdout.write( ' 🔖 Extrinsic creation took ' + moment.duration(moment().diff(startTxPrep)).as('seconds').toFixed(3) + 's\r' ) try { - let txStream = await newStream.create() + let txStream = await Cord.Stream.create(newStream) tx_batch.push(txStream) } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -116,9 +84,9 @@ async function main() { 's\r' ) try { - await cord.ChainUtils.signAndSubmitTx(tx_batch[i], Bob, { - resolveOn: cord.ChainUtils.IS_READY, - rejectOn: cord.ChainUtils.IS_ERROR, + await Cord.ChainUtils.signAndSubmitTx(tx_batch[i], Bob, { + resolveOn: Cord.ChainUtils.IS_READY, + rejectOn: Cord.ChainUtils.IS_ERROR, }) } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -145,34 +113,22 @@ async function main() { country: 'India', credit: 1000, } - // const nonceSaltValue = UUID.generate() - let schemaStream = cord.Content.fromContent( + let schemaStream = Cord.Content.fromSchemaAndContent( newSchema, content, Alice.address ) - let newStreamContent = cord.MarkContent.fromContent( - schemaStream, - Alice - // { nonceSalt: nonceSaltValue } - ) + let newStreamContent = Cord.ContentStream.fromContent(schemaStream, Alice) + let newStream = Cord.Stream.fromContentStream(newStreamContent) - // bytes = json.encode(newStreamContent) - // encoded_hash = await hasher.digest(bytes) - // const streamCid = CID.create(1, 0xb220, encoded_hash) - - let newStream = cord.Stream.fromMarkContentProperties( - newStreamContent - // streamCid.toString() - ) process.stdout.write( ' 🔖 Extrinsic creation took ' + moment.duration(moment().diff(startTxPrep2)).as('seconds').toFixed(3) + 's\r' ) try { - let txStream = await newStream.create() + let txStream = await Cord.Stream.create(newStream) tx_new_batch.push(txStream) } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -180,7 +136,7 @@ async function main() { } const { api } = - await cord.ChainHelpers.ChainApiConnection.getConnectionOrConnect() + await Cord.ChainHelpers.ChainApiConnection.getConnectionOrConnect() let keyring = new Keyring({ type: 'sr25519' }) let BatchAuthor = keyring.addFromUri('//Charlie') let batchAncStartTime = moment() @@ -209,10 +165,10 @@ async function main() { main() .then(() => console.log('Bye! 👋 👋 👋 \n')) - .finally(cord.disconnect) + .finally(Cord.disconnect) process.on('SIGINT', async () => { console.log('Bye! 👋 👋 👋 \n') - cord.disconnect() + Cord.disconnect() process.exit(0) }) diff --git a/packages/config/src/ConfigService.ts b/packages/config/src/ConfigService.ts index 2a5996c4..d6d1495a 100644 --- a/packages/config/src/ConfigService.ts +++ b/packages/config/src/ConfigService.ts @@ -28,7 +28,7 @@ export type configOpts = { } & { [key: string]: any } /** - * Changes all existing Loggers of our default Factory with id 0 to the intended Level. + * Changes all existing Loggers of our default Factory with id 0 to the intended Level. * * @param level The intended LogLevel. LogLevel has a range of 0 to 5. * @returns The new set level. diff --git a/packages/messaging/src/Message.ts b/packages/messaging/src/Message.ts index 45b973ea..47c343f1 100644 --- a/packages/messaging/src/Message.ts +++ b/packages/messaging/src/Message.ts @@ -32,12 +32,12 @@ import { export class Message implements IMessage { /** - * [STATIC] Lists all possible body types of [[Message]]. + * Lists all possible body types of [[Message]]. */ public static readonly BodyType = MessageBodyType /** - * [STATIC] Verifies that the sender of a [[Message]] is also the owner of it, e.g the holder's and sender's public keys match. + * Verifies that the sender of a [[Message]] is also the owner of it, e.g the holder's and sender's public keys match. * * @param message The [[Message]] object which needs to be decrypted. * @param message.body The body of the [[Message]] which depends on the [[BodyType]]. @@ -81,7 +81,7 @@ export class Message implements IMessage { } /** - * [STATIC] Verifies that neither the hash of [[Message]] nor the sender's signature on the hash have been tampered with. + * Verifies that neither the hash of [[Message]] nor the sender's signature on the hash have been tampered with. * * @param encrypted The encrypted [[Message]] object which needs to be decrypted. * @param senderAddress The sender's public SS58 address of the [[Message]]. @@ -110,7 +110,7 @@ export class Message implements IMessage { } /** - * [STATIC] Symmetrically decrypts the result of [[Message.encrypt]]. + * Symmetrically decrypts the result of [[Message.encrypt]]. * * Uses [[Message.ensureHashAndSignature]] and [[Message.ensureOwnerIsSender]] internally. * diff --git a/packages/messaging/src/Message.utils.ts b/packages/messaging/src/Message.utils.ts index 24899bbb..9bc2dadd 100644 --- a/packages/messaging/src/Message.utils.ts +++ b/packages/messaging/src/Message.utils.ts @@ -4,11 +4,11 @@ */ import { - StreamUtils, - CredentialUtils, - ContentUtils, - SchemaUtils, - ContentStreamUtils, + Stream, + Credential, + Content, + Schema, + ContentStream, } from '@cord.network/modules' import type { ICredential, @@ -30,17 +30,17 @@ import { Message } from './Message.js' export function errorCheckMessageBody(body: MessageBody): boolean | void { switch (body.type) { case Message.BodyType.REQUEST_STREAM: { - ContentStreamUtils.errorCheck(body.content.requestStream) + ContentStream.verifyDataStructure(body.content.requestStream) if (body.content.prerequisiteStreams) { body.content.prerequisiteStreams.map( (content: IContent | PartialContent) => - ContentUtils.errorCheck(content) + Content.verifyDataStructure(content) ) } break } case Message.BodyType.ANCHOR_STREAM: { - StreamUtils.errorCheck(body.content.stream) + Stream.verifyDataStructure(body.content.stream) break } case Message.BodyType.REJECT_STREAM: { @@ -52,7 +52,7 @@ export function errorCheckMessageBody(body: MessageBody): boolean | void { case Message.BodyType.REQUEST_CREDENTIAL: { body.content.forEach( (requestStreamsForSchema: IRequestStreamForCredential): void => { - DataUtils.validateId(requestStreamsForSchema.id) + DataUtils.validateId(requestStreamsForSchema.id, 'Identifier') requestStreamsForSchema.acceptedIssuer?.map((address) => DataUtils.validateAddress(address, 'Invalid Schema Owner Address') ) @@ -69,15 +69,15 @@ export function errorCheckMessageBody(body: MessageBody): boolean | void { const creds: ICredential[] = body.content.map((credentials, i) => { return credentials[i].credentials }) - creds.map((cred) => CredentialUtils.errorCheck(cred)) + creds.map((cred) => Credential.verifyDataStructure(cred)) break } case Message.BodyType.ACCEPT_CREDENTIAL: { - body.content.map((id) => DataUtils.validateId(id)) + body.content.map((id) => DataUtils.validateId(id, 'Identifier')) break } case Message.BodyType.REJECT_CREDENTIAL: { - body.content.map((id) => DataUtils.validateId(id)) + body.content.map((id) => DataUtils.validateId(id, 'Identifier')) break } @@ -134,7 +134,7 @@ export function verifyRequiredSchemaProperties( requiredProperties: string[], schema: ISchema ): boolean { - SchemaUtils.errorCheck(schema as ISchema) + Schema.verifyDataStructure(schema as ISchema) const validProperties = requiredProperties.find( (property) => !(property in schema.schema.properties) @@ -159,17 +159,17 @@ export function compressMessage(body: MessageBody): CompressedMessageBody { switch (body.type) { case Message.BodyType.REQUEST_STREAM: { compressedContents = [ - ContentStreamUtils.compress(body.content.requestStream), + ContentStream.compress(body.content.requestStream), body.content.prerequisiteStreams ? body.content.prerequisiteStreams.map((content) => - ContentUtils.compress(content) + Content.compress(content) ) : undefined, ] break } case Message.BodyType.ANCHOR_STREAM: { - compressedContents = StreamUtils.compress(body.content.stream) + compressedContents = Stream.compress(body.content.stream) break } case Message.BodyType.REQUEST_CREDENTIAL: { @@ -188,7 +188,7 @@ export function compressMessage(body: MessageBody): CompressedMessageBody { (cordStream: ICredential | CompressedCredential) => Array.isArray(cordStream) ? cordStream - : CredentialUtils.compress(cordStream) + : Credential.compress(cordStream) ) break } @@ -215,9 +215,9 @@ export function decompressMessage(body: CompressedMessageBody): MessageBody { switch (body[0]) { case Message.BodyType.REQUEST_STREAM: { decompressedContents = { - requestStream: ContentStreamUtils.decompress(body[1][0]), + requestStream: ContentStream.decompress(body[1][0]), prerequisiteStreams: body[1][1] - ? body[1][1].map((stream) => ContentUtils.decompress(stream)) + ? body[1][1].map((stream) => Content.decompress(stream)) : undefined, } @@ -225,7 +225,7 @@ export function decompressMessage(body: CompressedMessageBody): MessageBody { } case Message.BodyType.ANCHOR_STREAM: { decompressedContents = { - stream: StreamUtils.decompress(body[1]), + stream: Stream.decompress(body[1]), } break } @@ -249,7 +249,7 @@ export function decompressMessage(body: CompressedMessageBody): MessageBody { // (cordStream: ICredential | CompressedCredential) => // !Array.isArray(cordStream) // ? cordStream - // : CredentialUtils.decompress(cordStream) + // : Credential.decompress(cordStream) // ) // break diff --git a/packages/modules/src/content/Content.ts b/packages/modules/src/content/Content.ts index 9aa45ac4..24b7695f 100644 --- a/packages/modules/src/content/Content.ts +++ b/packages/modules/src/content/Content.ts @@ -1,168 +1,387 @@ +import { hexToBn } from '@polkadot/util' +import type { HexString } from '@polkadot/util/types' import type { IContent, + ISchema, CompressedContent, CompressedPartialContent, PartialContent, IPublicIdentity, } from '@cord.network/types' -import { SDKErrors } from '@cord.network/utils' -import { Schema as ISchema } from '../schema/Schema.js' -import * as SchemaUtils from '../schema/Schema.utils.js' -import * as ContentUtils from './Content.utils.js' +import { + SDKErrors, + Identifier, + Crypto, + jsonabc, + DataUtils, +} from '@cord.network/utils' +import { + verifyContentWithSchema, + verifyContentWithNestedSchemas, +} from '../schema/index.js' + +const VC_VOCAB = 'https://www.w3.org/2018/credentials#' -function verifyContent( - contents: IContent['contents'], - schema: ISchema['schema'] -): boolean { - return SchemaUtils.verifyContentProperties(contents, schema) -} /** - * Input streams (content) are the core building block of the SDK. The input streams will be transformed to create a [[ContentStream]]. - * - * A content object has: - * * contents - details of the content to be transformed; - * * a [[Schema]] that represents its data structure. + * Produces JSON-LD readable representations of [[IContent]]['contents']. This is done by implicitly or explicitely transforming property keys to globally unique predicates. + * Where possible these predicates are taken directly from the Verifiable Credentials vocabulary. Properties that are unique to a [[Schema]] are transformed to predicates by prepending the [[Schema]][schema][$id]. * - * A content object's owner is (should be) the same entity as the issuer or delegator. + * @param content A (partial) [[IContent]] from to build a JSON-LD representation from. The `identifier` property is required. + * @param expanded Return an expanded instead of a compacted represenation. While property transformation is done explicitely in the expanded format, it is otherwise done implicitly via adding JSON-LD's reserved `@context` properties while leaving [[IContent]][contents] property keys untouched. + * @returns An object which can be serialized into valid JSON-LD representing an [[IContent]]'s ['contents']. + * @throws [[ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED]] in case the content's ['identifier'] property is undefined. */ -export class Content implements IContent { - /** - * [STATIC] Instantiates a new [[Content]] transformation from [[IContent]] and [[ISchema]]. - * - * @param input IContent to create the new stream from. - * @param schema ISchema['schema'] to verify input's contents. - * @throws [[ERROR_CONTENT_UNVERIFIABLE]] when input's contents could not be verified with the provided schema. - * - * @returns A validated [[Content]] stream. - */ - public static fromContentType( - input: IContent, - schema: ISchema['schema'] - ): Content { - if (!verifyContent(input.contents, schema)) { - throw new SDKErrors.ERROR_CONTENT_UNVERIFIABLE() +function jsonLDcontents( + content: PartialContent, + expanded = true +): Record { + const { schema, contents, holder } = content + if (!schema) new SDKErrors.ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED() + const vocabulary = `${schema}#` + const result: Record = {} + if (holder) result['@id'] = Identifier.getAccountIdentifierFromAddress(holder) + + if (!expanded) { + return { + ...result, + '@context': { '@vocab': vocabulary }, + ...contents, } - return new Content(input) } + Object.entries(contents || {}).forEach(([key, value]) => { + result[vocabulary + key] = value + }) + return result +} - /** - * [STATIC] Builds a [[Content]] stream from [[IContent]] and nested [[ISchema]]s. - * - * @param schema A [[Schema]] object that has nested [[Schema]]s. - * @param nestedSchemas The array of [[Schema]]s, which are used inside the main [[Schema]]. - * @param contents The data inside the [[Content]]. - * @param issuer The owner of the [[Content]]. - * @param holder The holder of the [[Content]]. - * - * @returns A validated [[Content]] stream. - */ - - public static fromNestedProperties( - schema: ISchema, - nestedSchemas: Array, - contents: IContent['contents'], - issuer: IPublicIdentity['address'], - holder?: IPublicIdentity['address'] - ): Content { - if ( - !SchemaUtils.validateNestedSchemas(schema.schema, nestedSchemas, contents) - ) { - throw new SDKErrors.ERROR_NESTED_CONTENT_UNVERIFIABLE() - } - return new Content({ - schema: schema.identifier, - contents: contents, - issuer: issuer, - holder: holder || null, - }) +/** + * Produces JSON-LD readable representations of the content. This is done by implicitly or explicitly transforming property keys to globally unique predicates. + * Where possible these predicates are taken directly from the Verifiable Credentials vocabulary. Properties that are unique to a [[Schema]] are transformed to predicates by prepending the [[Schema]][schema][$id]. + * + * @param claim A (partial) [[IContent]] from to build a JSON-LD representation from. The `identifier` property is required. + * @param expanded Return an expanded instead of a compacted representation. While property transformation is done explicitly in the expanded format, it is otherwise done implicitly via adding JSON-LD's reserved `@context` properties while leaving [[IContent]][contents] property keys untouched. + * @returns An object which can be serialized into valid JSON-LD representing an [[IContent]]. + * @throws [[ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED]] in case the content's ['identifier'] property is undefined. + */ +export function toJsonLD( + content: PartialContent, + expanded = true +): Record { + const credentialSubject = jsonLDcontents(content, expanded) + const prefix = expanded ? VC_VOCAB : '' + const result = { + [`${prefix}credentialSubject`]: credentialSubject, + } + result[`${prefix}credentialSchema`] = { + '@id': content.schema, } + if (!expanded) result['@context'] = { '@vocab': VC_VOCAB } + return result +} + +function makeStatementsJsonLD(content: PartialContent): string[] { + const normalized = jsonLDcontents(content, true) + return Object.entries(normalized).map(([key, value]) => + JSON.stringify({ [key]: value }) + ) +} + +/** + * Produces salted hashes of individual statements comprising a (partial) [[IContent]] to enable selective disclosure of contents. Can also be used to reproduce hashes for the purpose of validation. + * + * @param content Full or partial [[IContent]] to produce statement hashes from. + * @param options Object containing optional parameters. + * @param options.canonicalisation Canonicalisation routine that produces an array of statement strings from the [IContent]. Default produces individual `{"key":"value"}` JSON representations where keys are transformed to expanded JSON-LD. + * @param options.nonces Optional map of nonces as produced by this function. + * @param options.nonceGenerator Nonce generator as defined by [[hashStatements]] to be used if no `nonces` are given. Default produces random UUIDs (v4). + * @param options.hasher The hasher to be used. Required but defaults to 256 bit blake2 over `${nonce}${statement}`. + * @returns An array of salted `hashes` and a `nonceMap` where keys correspond to unsalted statement hashes. + * @throws [[ERROR_CONTENT_NONCE_MAP_MALFORMED]] if the nonceMap or the nonceGenerator was non-exhaustive for any statement. + */ +export function hashContents( + content: PartialContent, + options: Crypto.HashingOptions & { + canonicalisation?: (content: PartialContent) => string[] + } = {} +): { + hashes: HexString[] + nonceMap: Record +} { + // apply defaults + const defaults = { canonicalisation: makeStatementsJsonLD } + const canonicalisation = options.canonicalisation || defaults.canonicalisation + // use canonicalisation algorithm to make hashable statement strings + const statements = canonicalisation(content) + // iterate over statements to produce salted hashes + const processed = Crypto.hashStatements(statements, options) + // produce array of salted hashes to add to credential + const hashes = processed + .map(({ saltedHash }) => saltedHash) + .sort((a, b) => hexToBn(a).cmp(hexToBn(b))) + // produce nonce map, where each nonce is keyed with the unsalted hash + const nonceMap = {} + processed.forEach(({ digest, nonce, statement }) => { + // throw if we can't map a digest to a nonce - this should not happen if the nonce map is complete and the credential has not been tampered with + if (!nonce) throw new SDKErrors.ERROR_CONTENT_NONCE_MAP_MALFORMED(statement) + nonceMap[digest] = nonce + }, {}) + return { hashes, nonceMap } +} + +/** + * Used to verify the hash list based proof over the set of disclosed attributes in a [[Stream]]. + * + * @param content Full or partial [[IContent]] to verify proof against. + * @param proof Proof consisting of a map that matches nonces to statement digests and the resulting hashes. + * @param proof.nonces A map where a statement digest as produces by options.hasher is mapped to a nonce. + * @param proof.hashes Array containing hashes which are signed into the credential. Should result from feeding statement digests and nonces in proof.nonce to options.hasher. + * @param options Object containing optional parameters. + * @param options.canonicalisation Canonicalisation routine that produces an array of statement strings from the [IContent]. Default produces individual `{"key":"value"}` JSON representations where keys are transformed to expanded JSON-LD. + * @param options.hasher The hasher to be used. Required but defaults to 256 bit blake2 over `${nonce}${statement}`. + * @returns `verified` is a boolean indicating whether the proof is valid. `errors` is an array of all errors in case it is not. + */ +export function verifyDisclosedAttributes( + content: PartialContent, + proof: { + nonces: Record + hashes: string[] + }, + options: Pick & { + canonicalisation?: (content: PartialContent) => string[] + } = {} +): { verified: boolean; errors: Error[] } { + // apply defaults + const defaults = { canonicalisation: makeStatementsJsonLD } + const canonicalisation = options.canonicalisation || defaults.canonicalisation + const { nonces } = proof + // use canonicalisation algorithm to make hashable statement strings + const statements = canonicalisation(content) + // iterate over statements to produce salted hashes + const hashed = Crypto.hashStatements(statements, { ...options, nonces }) + // check resulting hashes + const digestsInProof = Object.keys(nonces) + return hashed.reduce<{ verified: boolean; errors: Error[] }>( + (status, { saltedHash, statement, digest, nonce }) => { + // check if the statement digest was contained in the proof and mapped it to a nonce + if (!digestsInProof.includes(digest) || !nonce) { + status.errors.push( + new SDKErrors.ERROR_NO_PROOF_FOR_STATEMENT(statement) + ) + return { ...status, verified: false } + } + // check if the hash is whitelisted in the proof + if (!proof.hashes.includes(saltedHash)) { + status.errors.push( + new SDKErrors.ERROR_INVALID_PROOF_FOR_STATEMENT(statement) + ) + return { ...status, verified: false } + } + return status + }, + { verified: true, errors: [] } + ) +} - /** - * [STATIC] Builds a new [[Content]] stream from [[ISchema]], IContent['contents'] and issuer's [[IPublicIdentity['address']]. - * - * @param schema [[ISchema]] on which the content is based on. - * @param contents IContent['contents'] to be used as the data of the instantiated Content stream. - * @throws [[ERROR_CONTENT_UNVERIFIABLE]] when the input stream could not be verified with the schema provided. - * - * @returns An instantiated Content. - */ - public static fromProperties( - schema: ISchema, - contents: IContent['contents'], - issuer: IPublicIdentity['address'], - holder?: IPublicIdentity['address'] - ): Content { - if (schema.schema) { - if (!verifyContent(contents, schema.schema)) { - throw new SDKErrors.ERROR_CONTENT_UNVERIFIABLE() +/** + * Checks whether the input meets all the required criteria of an [[IContent]] object. + * Throws on invalid input. + * + * @param input The potentially only partial IContent. + * @throws [[ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED]] when input's id do not exist. + * @throws [[ERROR_CONTENT_PROPERTIES_MALFORMED]] when any of the input's contents[key] is not of type 'number', 'boolean' or 'string'. + * + */ +export function verifyDataStructure(input: IContent | PartialContent): void { + if (!input.schema) { + throw new SDKErrors.ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED() + } + if (input.issuer) { + DataUtils.validateAddress(input.issuer, 'Content Creator') + } + if (input.contents !== undefined) { + Object.entries(input.contents).forEach(([key, value]) => { + if ( + !key || + typeof key !== 'string' || + !['string', 'number', 'boolean', 'object'].includes(typeof value) + ) { + throw new SDKErrors.ERROR_CONTENT_PROPERTIES_MALFORMED() } - } - return new Content({ - schema: schema.identifier, - issuer: issuer, - holder: holder || null, - contents: contents, }) } + DataUtils.validateId(input.schema, 'Identifier') +} + +function verifyWithSchema( + contents: IContent['contents'], + schema: ISchema['schema'] +): boolean { + return verifyContentWithSchema(contents, schema) +} + +/** + * Verifies the data structure and schema of the Content. + * + * @param contentInput IClaim to verify. + * @param typeSchema ISchema['schema'] to verify contents. + * @throws [[ERROR_CLAIM_UNVERIFIABLE]] when contents could not be verified with the provided typeSchema. + */ +export function verify( + contentInput: IContent, + typeSchema: ISchema['schema'] +): void { + if (!verifyWithSchema(contentInput.contents, typeSchema)) { + throw new SDKErrors.ERROR_CONTENT_UNVERIFIABLE() + } - /** - * [STATIC] Custom Type Guard to determine input being of type IContent using the ContentUtils errorCheck. - * - * @param input The potentially only partial IContent. - * - * @returns Boolean whether input is of type IContent. - */ - static isIContent(input: unknown): input is IContent { - try { - ContentUtils.errorCheck(input as IContent) - } catch (error) { - return false + verifyDataStructure(contentInput) +} + +/** + * Builds a [[Content]] stream from [[IContent]] and nested [[ISchema]]s. + * + * @param schema A [[Schema]] object that has nested [[Schema]]s. + * @param nestedSchemas The array of [[Schema]]s, which are used inside the main [[Schema]]. + * @param contents The data inside the [[Content]]. + * @param issuer The owner of the [[Content]]. + * @param holder The holder of the [[Content]]. + * + * @returns A validated [[Content]] stream. + */ + +export function fromNestedSchemaAndContent( + schema: ISchema, + nestedSchemas: Array, + contents: IContent['contents'], + issuer: IPublicIdentity['address'], + holder?: IPublicIdentity['address'] +): IContent { + if (!verifyContentWithNestedSchemas(schema.schema, nestedSchemas, contents)) { + throw new SDKErrors.ERROR_NESTED_CONTENT_UNVERIFIABLE() + } + const content = { + schema: schema.identifier, + contents: contents, + issuer: issuer, + holder: holder || null, + } + verifyDataStructure(content) + return content +} + +/** + * Builds a new [[Content]] stream from [[ISchema]], IContent['contents'] and issuer's [[IPublicIdentity['address']]. + * + * @param schema [[ISchema]] on which the content is based on. + * @param contents IContent['contents'] to be used as the data of the instantiated Content stream. + * @throws [[ERROR_CONTENT_UNVERIFIABLE]] when the input stream could not be verified with the schema provided. + * + * @returns An instantiated Content. + */ +export function fromSchemaAndContent( + schema: ISchema, + contents: IContent['contents'], + issuer: IPublicIdentity['address'], + holder?: IPublicIdentity['address'] +): IContent { + if (schema.schema) { + if (!verifyWithSchema(contents, schema.schema)) { + throw new SDKErrors.ERROR_CONTENT_UNVERIFIABLE() } - return true } + const content = { + schema: schema.identifier, + issuer: issuer, + holder: holder || null, + contents: contents, + } + verifyDataStructure(content) + return content +} - public schema: IContent['schema'] - public contents: IContent['contents'] - public issuer: IContent['issuer'] - public holder: IContent['holder'] - - public constructor(input: IContent) { - ContentUtils.errorCheck(input) - this.schema = input.schema - this.contents = input.contents - this.issuer = input.issuer - this.holder = input.holder +/** + * Custom Type Guard to determine input being of type IContent + * + * @param input The potentially only partial IContent. + * + * @returns Boolean whether input is of type IContent. + */ +export function isIContent(input: unknown): input is IContent { + try { + verifyDataStructure(input as IContent) + } catch (error) { + return false } + return true +} + +/** + * Compresses the [[Content]] for storage and/or messaging. + * + * @param content An [[IContent]] object that will be sorted and stripped for messaging or storage. + * + * @returns An ordered array of an [[CompressedContent]]. + */ - /** - * Compresses the [[Content]] stream object to a [[CompressedContent]]. - * - * @returns An array that contains the same properties of an [[Content]]. - */ +export function compress(content: IContent): CompressedContent - public compress(): CompressedContent { - return ContentUtils.compress(this) +/** + * Compresses a [[PartialContent]] for storage and/or messaging. + * + * @param content A [[PartialContent]] object that will be sorted and stripped for messaging or storage. + * + * @returns An ordered array of a [[CompressedPartialContent]]. + */ +export function compress(content: PartialContent): CompressedPartialContent + +/** + * Compresses a content object for storage and/or messaging. + * + * @param content A (partial) content object that will be sorted and stripped for messaging or storage. + * + * @returns An ordered array of that represents the underlying data in a more compact form. + */ +export function compress( + content: IContent | PartialContent +): CompressedContent | CompressedPartialContent { + verifyDataStructure(content) + let sortedContents + if (content.contents) { + sortedContents = jsonabc.sortObj(content.contents) } + return [content.schema, content.issuer, content.holder, sortedContents] +} + +/** + * Decompresses an [[IContent]] from storage and/or message. + * + * @param content A [[CompressedContent]] array that is reverted back into an object. + * @throws [[ERROR_DECOMPRESSION_ARRAY]] when a [[CompressedContent]] is not an Array or it's length is unequal 3. + * @returns An [[IContent]] object that has the same properties compressed representation. + */ +export function decompress(content: CompressedContent): IContent - /** - * Decompresses the [[IContent]] from storage and/or message. - * - * @param content A [[CompressedContent]] array that is reverted back into an object. - * @throws [[ERROR_DECOMPRESSION_ARRAY]] when an [[CompressedContent]] is not an Array or it's length is unequal 3. - * @returns An [[IContent]] object that has the same properties as the [[CompressedContent]]. - */ - public static decompress(content: CompressedContent): IContent - /** - * Decompresses the Partial [[IContent] from storage and/or message. - * - * @param content An [[CompressedPartialContent]] array that is reverted back into an object. - * @throws [[ERROR_DECOMPRESSION_ARRAY]] when an [[CompressedPartialContent]] is not an Array or it's length is unequal 3. - * @returns An [[PartialContent]] object that has the same properties as the [[CompressedPartialContent]]. - */ - public static decompress(content: CompressedPartialContent): PartialContent - public static decompress( - compressedContent: CompressedContent | CompressedPartialContent - ): IContent | PartialContent { - return ContentUtils.decompress(compressedContent) +/** + * Decompresses compressed representation of a (partial) [[IContent]] from storage and/or message. + * + * @param content A [[CompressedContent]] or [[CompressedPartialContent]] array that is reverted back into an object. + * @throws + * @throws [[ERROR_DECOMPRESSION_ARRAY]] if the `content` is not an Array or it's length is unequal 4. + * @returns An [[IContent]] or [[PartialContent]] object that has the same properties compressed representation. + */ +export function decompress(content: CompressedPartialContent): PartialContent +export function decompress( + content: CompressedContent | CompressedPartialContent +): IContent | PartialContent { + if (!Array.isArray(content) || content.length !== 4) { + throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Stream') + } + const decompressedContent = { + schema: content[0], + issuer: content[1], + holder: content[2], + contents: content[3], } + verifyDataStructure(decompressedContent) + return decompressedContent } diff --git a/packages/modules/src/content/Content.utils.ts b/packages/modules/src/content/Content.utils.ts deleted file mode 100644 index 646540d4..00000000 --- a/packages/modules/src/content/Content.utils.ts +++ /dev/null @@ -1,271 +0,0 @@ -import { hexToBn } from '@polkadot/util' -import type { HexString } from '@polkadot/util/types' -import type { - IContent, - CompressedContent, - PartialContent, - CompressedPartialContent, -} from '@cord.network/types' -import { - jsonabc, - DataUtils, - Crypto, - SDKErrors, - Identifier, -} from '@cord.network/utils' - -const VC_VOCAB = 'https://www.w3.org/2018/credentials#' - -/** - * Produces JSON-LD readable representations of [[IContent]]['contents']. This is done by implicitly or explicitely transforming property keys to globally unique predicates. - * Where possible these predicates are taken directly from the Verifiable Credentials vocabulary. Properties that are unique to a [[Schema]] are transformed to predicates by prepending the [[Schema]][schema][$id]. - * - * @param content A (partial) [[IContent]] from to build a JSON-LD representation from. The `identifier` property is required. - * @param expanded Return an expanded instead of a compacted represenation. While property transformation is done explicitely in the expanded format, it is otherwise done implicitly via adding JSON-LD's reserved `@context` properties while leaving [[IContent]][contents] property keys untouched. - * @returns An object which can be serialized into valid JSON-LD representing an [[IContent]]'s ['contents']. - * @throws [[ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED]] in case the content's ['identifier'] property is undefined. - */ -function jsonLDcontents( - content: PartialContent, - expanded = true -): Record { - const { schema, contents, holder } = content - if (!schema) new SDKErrors.ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED() - const vocabulary = `${schema}#` - const result: Record = {} - if (holder) result['@id'] = Identifier.getAccountIdentifierFromAddress(holder) - - if (!expanded) { - return { - ...result, - '@context': { '@vocab': vocabulary }, - ...contents, - } - } - Object.entries(contents || {}).forEach(([key, value]) => { - result[vocabulary + key] = value - }) - return result -} - -/** - * Produces JSON-LD readable representations of the content. This is done by implicitly or explicitly transforming property keys to globally unique predicates. - * Where possible these predicates are taken directly from the Verifiable Credentials vocabulary. Properties that are unique to a [[Schema]] are transformed to predicates by prepending the [[Schema]][schema][$id]. - * - * @param claim A (partial) [[IContent]] from to build a JSON-LD representation from. The `identifier` property is required. - * @param expanded Return an expanded instead of a compacted representation. While property transformation is done explicitly in the expanded format, it is otherwise done implicitly via adding JSON-LD's reserved `@context` properties while leaving [[IContent]][contents] property keys untouched. - * @returns An object which can be serialized into valid JSON-LD representing an [[IContent]]. - * @throws [[ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED]] in case the content's ['identifier'] property is undefined. - */ -export function toJsonLD( - content: PartialContent, - expanded = true -): Record { - const credentialSubject = jsonLDcontents(content, expanded) - const prefix = expanded ? VC_VOCAB : '' - const result = { - [`${prefix}credentialSubject`]: credentialSubject, - } - result[`${prefix}credentialSchema`] = { - '@id': content.schema, - } - if (!expanded) result['@context'] = { '@vocab': VC_VOCAB } - return result -} - -function makeStatementsJsonLD(content: PartialContent): string[] { - const normalized = jsonLDcontents(content, true) - return Object.entries(normalized).map(([key, value]) => - JSON.stringify({ [key]: value }) - ) -} - -/** - * Produces salted hashes of individual statements comprising a (partial) [[IContent]] to enable selective disclosure of contents. Can also be used to reproduce hashes for the purpose of validation. - * - * @param content Full or partial [[IContent]] to produce statement hashes from. - * @param options Object containing optional parameters. - * @param options.canonicalisation Canonicalisation routine that produces an array of statement strings from the [IContent]. Default produces individual `{"key":"value"}` JSON representations where keys are transformed to expanded JSON-LD. - * @param options.nonces Optional map of nonces as produced by this function. - * @param options.nonceGenerator Nonce generator as defined by [[hashStatements]] to be used if no `nonces` are given. Default produces random UUIDs (v4). - * @param options.hasher The hasher to be used. Required but defaults to 256 bit blake2 over `${nonce}${statement}`. - * @returns An array of salted `hashes` and a `nonceMap` where keys correspond to unsalted statement hashes. - * @throws [[ERROR_CONTENT_NONCE_MAP_MALFORMED]] if the nonceMap or the nonceGenerator was non-exhaustive for any statement. - */ -export function hashContents( - content: PartialContent, - options: Crypto.HashingOptions & { - canonicalisation?: (content: PartialContent) => string[] - } = {} -): { - hashes: HexString[] - nonceMap: Record -} { - // apply defaults - const defaults = { canonicalisation: makeStatementsJsonLD } - const canonicalisation = options.canonicalisation || defaults.canonicalisation - // use canonicalisation algorithm to make hashable statement strings - const statements = canonicalisation(content) - // iterate over statements to produce salted hashes - const processed = Crypto.hashStatements(statements, options) - // produce array of salted hashes to add to credential - const hashes = processed - .map(({ saltedHash }) => saltedHash) - .sort((a, b) => hexToBn(a).cmp(hexToBn(b))) - // produce nonce map, where each nonce is keyed with the unsalted hash - const nonceMap = {} - processed.forEach(({ digest, nonce, statement }) => { - // throw if we can't map a digest to a nonce - this should not happen if the nonce map is complete and the credential has not been tampered with - if (!nonce) throw new SDKErrors.ERROR_CONTENT_NONCE_MAP_MALFORMED(statement) - nonceMap[digest] = nonce - }, {}) - return { hashes, nonceMap } -} - -/** - * Used to verify the hash list based proof over the set of disclosed attributes in a [[Stream]]. - * - * @param content Full or partial [[IContent]] to verify proof against. - * @param proof Proof consisting of a map that matches nonces to statement digests and the resulting hashes. - * @param proof.nonces A map where a statement digest as produces by options.hasher is mapped to a nonce. - * @param proof.hashes Array containing hashes which are signed into the credential. Should result from feeding statement digests and nonces in proof.nonce to options.hasher. - * @param options Object containing optional parameters. - * @param options.canonicalisation Canonicalisation routine that produces an array of statement strings from the [IContent]. Default produces individual `{"key":"value"}` JSON representations where keys are transformed to expanded JSON-LD. - * @param options.hasher The hasher to be used. Required but defaults to 256 bit blake2 over `${nonce}${statement}`. - * @returns `verified` is a boolean indicating whether the proof is valid. `errors` is an array of all errors in case it is not. - */ -export function verifyDisclosedAttributes( - content: PartialContent, - proof: { - nonces: Record - hashes: string[] - }, - options: Pick & { - canonicalisation?: (content: PartialContent) => string[] - } = {} -): { verified: boolean; errors: SDKErrors.SDKError[] } { - // apply defaults - const defaults = { canonicalisation: makeStatementsJsonLD } - const canonicalisation = options.canonicalisation || defaults.canonicalisation - const { nonces } = proof - // use canonicalisation algorithm to make hashable statement strings - const statements = canonicalisation(content) - // iterate over statements to produce salted hashes - const hashed = Crypto.hashStatements(statements, { ...options, nonces }) - // check resulting hashes - const digestsInProof = Object.keys(nonces) - return hashed.reduce<{ verified: boolean; errors: SDKErrors.SDKError[] }>( - (status, { saltedHash, statement, digest, nonce }) => { - // check if the statement digest was contained in the proof and mapped it to a nonce - if (!digestsInProof.includes(digest) || !nonce) { - status.errors.push( - new SDKErrors.ERROR_NO_PROOF_FOR_STATEMENT(statement) - ) - return { ...status, verified: false } - } - // check if the hash is whitelisted in the proof - if (!proof.hashes.includes(saltedHash)) { - status.errors.push( - new SDKErrors.ERROR_INVALID_PROOF_FOR_STATEMENT(statement) - ) - return { ...status, verified: false } - } - return status - }, - { verified: true, errors: [] } - ) -} - -/** - * Checks whether the input meets all the required criteria of an [[IContent]] object. - * Throws on invalid input. - * - * @param input The potentially only partial IContent. - * @throws [[ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED]] when input's id do not exist. - * @throws [[ERROR_CONTENT_PROPERTIES_MALFORMED]] when any of the input's contents[key] is not of type 'number', 'boolean' or 'string'. - * - */ -export function errorCheck(input: IContent | PartialContent): void { - if (!input.schema) { - throw new SDKErrors.ERROR_SCHEMA_IDENTIFIER_NOT_PROVIDED() - } - if (input.issuer) { - DataUtils.validateAddress(input.issuer, 'Content Creator') - } - if (input.contents !== undefined) { - Object.entries(input.contents).forEach(([key, value]) => { - if ( - !key || - typeof key !== 'string' || - !['string', 'number', 'boolean', 'object'].includes(typeof value) - ) { - throw new SDKErrors.ERROR_CONTENT_PROPERTIES_MALFORMED() - } - }) - } - DataUtils.validateId(input.schema) -} - -/** - * Compresses the [[IContent]] for storage and/or messaging. - * - * @param content An [[IContent]] object that will be sorted and stripped for messaging or storage. - * - * @returns An ordered array of a [[CompressedContent]]. - */ -export function compress(content: IContent): CompressedContent -/** - * Compresses the [[PartialContent]] for storage and/or messaging. - * - * @param content A [[PartialContent]] object that will be sorted and stripped for messaging or storage. - * - * @returns An ordered array of a [[CompressedPartialContent]]. - */ -export function compress(content: PartialContent): CompressedPartialContent -/** - * Compresses a content object for storage and/or messaging. - * - * @param content A (partial) content object that will be sorted and stripped for messaging or storage. - * - * @returns An ordered array of that represents the underlying data in a more compact form. - */ -export function compress( - content: IContent | PartialContent -): CompressedContent | CompressedPartialContent { - errorCheck(content) - let sortedContents - if (content.contents) { - sortedContents = jsonabc.sortObj(content.contents) - } - return [content.schema, content.issuer, content.holder, sortedContents] -} -/** - * Decompresses an [[IContent]] from storage and/or message. - * - * @param content A [[CompressedContent]] array that is reverted back into an object. - * @throws [[ERROR_DECOMPRESSION_ARRAY]] when a [[CompressedContent]] is not an Array or it's length is unequal 3. - * @returns An [[IContent]] object that has the same properties compressed representation. - */ -export function decompress(content: CompressedContent): IContent -/** - * Decompresses compressed representation of a (partial) [[IContent]] from storage and/or message. - * - * @param content A [[CompressedContent]] or [[CompressedPartialContent]] array that is reverted back into an object. - * @throws - * @throws [[ERROR_DECOMPRESSION_ARRAY]] if the `content` is not an Array or it's length is unequal 3. - * @returns An [[IContent]] or [[PartialContent]] object that has the same properties compressed representation. - */ -export function decompress(content: CompressedPartialContent): PartialContent -export function decompress( - content: CompressedContent | CompressedPartialContent -): IContent | PartialContent { - if (!Array.isArray(content) || content.length !== 4) { - throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Stream') - } - return { - schema: content[0], - issuer: content[1], - holder: content[2], - contents: content[3], - } -} diff --git a/packages/modules/src/content/index.ts b/packages/modules/src/content/index.ts index 88470762..0a0cd357 100644 --- a/packages/modules/src/content/index.ts +++ b/packages/modules/src/content/index.ts @@ -1,2 +1 @@ -export { Content } from './Content.js' -export * as ContentUtils from './Content.utils.js' +export * from './Content.js' diff --git a/packages/modules/src/contentstream/ContentStream.ts b/packages/modules/src/contentstream/ContentStream.ts index 8d7433d6..96d1ee58 100644 --- a/packages/modules/src/contentstream/ContentStream.ts +++ b/packages/modules/src/contentstream/ContentStream.ts @@ -3,22 +3,36 @@ import type { CompressedContentStream, Hash, IContent, + ISchema, ICredential, + CompressedCredential, } from '@cord.network/types' -import { Crypto, SDKErrors } from '@cord.network/utils' -import * as ContentUtils from '../content/Content.utils.js' -import { Credential } from '../credential/Credential.js' +import { Crypto, SDKErrors, DataUtils } from '@cord.network/utils' +import * as Content from '../content/Content.js' +import * as Credential from '../credential/Credential.js' import { Identity } from '../identity/Identity.js' -import * as ContentStreamUtils from './ContentStream.utils.js' import { STREAM_IDENTIFIER, STREAM_PREFIX, DEFAULT_STREAM_VALIDITY, } from '@cord.network/types' import { Identifier } from '@cord.network/utils' -import { HexString } from '@polkadot/util/types.js' +import { verifyContentWithSchema } from '../schema/Schema.js' +import { HexString } from '@polkadot/util/types' -function verifyCreatorSignature(content: IContentStream): boolean { +export function makeSigningData( + input: IContentStream, + challenge?: string +): Uint8Array { + return new Uint8Array([ + ...Crypto.coToUInt8(input.rootHash), + ...Crypto.coToUInt8(challenge), + ]) +} + +export async function verifySignature( + content: IContentStream +): Promise { return Crypto.verify( content.rootHash, content.issuerSignature, @@ -31,372 +45,431 @@ function getHashRoot(leaves: Uint8Array[]): Uint8Array { return Crypto.hash(result) } -export type Options = { - evidenceIds?: Credential[] - link?: IContentStream['link'] - space?: IContentStream['space'] - expiry?: Date +function getHashLeaves( + contentHashes: Hash[], + evidenceIds: ICredential[], + issueDate: string, + expiryDate: string +): Uint8Array[] { + const result: Uint8Array[] = [] + contentHashes.forEach((item) => { + result.push(Crypto.coToUInt8(item)) + }) + if (evidenceIds) { + evidenceIds.forEach((evidence) => { + result.push(Crypto.coToUInt8(evidence.request.identifier)) + }) + } + result.push(Crypto.coToUInt8(issueDate)) + result.push(Crypto.coToUInt8(expiryDate)) + return result +} + +export function calculateRootHash( + credential: Partial, + issuanceDate: HexString, + expirationDate: HexString +): Hash { + const hashes: Uint8Array[] = getHashLeaves( + credential.contentHashes || [], + credential.evidenceIds || [], + issuanceDate, + expirationDate + ) + const root: Uint8Array = getHashRoot(hashes) + return Crypto.u8aToHex(root) +} + +export async function addSignature( + request: IContentStream, + sig: string | Uint8Array, + challenge?: string +): Promise { + const signature = typeof sig === 'string' ? sig : Crypto.u8aToHex(sig) + // eslint-disable-next-line no-param-reassign + ;(request.issuerSignature = signature), challenge +} + +function sign(identity: Identity, rootHash: Hash): string { + return identity.signStr(rootHash) } -export class ContentStream implements IContentStream { - /** - * [STATIC] Builds an instance of [[ContentStream]], from a simple object with the same properties. - * Used for deserialization. - * - * @param content - An object adhering to the [[IContentStream]] interface. - * @returns A new [[ContentStream]] `object`. - */ - public static fromRequest(content: IContentStream): ContentStream { - return new ContentStream(content) +export async function signWithKey( + request: IContentStream, + signer: Identity, + challenge?: string +): Promise { + const signature = await signer.signStr(makeSigningData(request, challenge)) + addSignature(request, signature, challenge) +} + +/** + * Removes [[Content] properties from the [[ContentStream]] object, provides anonymity and security when building the [[createPresentation]] method. + * + * @param contentStram - The ContentStream object to remove properties from. + * @param properties - Properties to remove from the [[Stream]] object. + * @throws [[ERROR_CONTENT_HASHTREE_MISMATCH]] when a property which should be deleted wasn't found. + * + */ +export function removeContentProperties( + contentStram: IContentStream, + properties: string[] +): void { + properties.forEach((key) => { + delete contentStram.content.contents[key] + }) + contentStram.contentNonceMap = Content.hashContents(contentStram.content, { + nonces: contentStram.contentNonceMap, + }).nonceMap +} + +export function verifyRootHash(input: IContentStream): boolean { + const issuanceDateHash = Crypto.hashObjectAsHexStr(input.issuanceDate) + const expirationDateHash = Crypto.hashObjectAsHexStr(input.expirationDate) + return ( + input.rootHash === + calculateRootHash(input, issuanceDateHash, expirationDateHash) + ) +} + +/** + * Verifies the data of the [[ContentStream]] object; used to check that the data was not tampered with, by checking the data against hashes. + * + * @param input - The [[ContentStream]] for which to verify data. + * @returns Whether the data is valid. + * @throws [[ERROR_CONTENT_NONCE_MAP_MALFORMED]] when any key of the stream marks could not be found in the streamHashTree. + * @throws [[ERROR_ROOT_HASH_UNVERIFIABLE]] or [[ERROR_SIGNATURE_UNVERIFIABLE]] when either the rootHash or the signature are not verifiable respectively. + * + */ +export function verifyDataIntegrity(input: IContentStream): boolean { + // check stream hash + if (!verifyRootHash(input)) { + throw new SDKErrors.ERROR_ROOT_HASH_UNVERIFIABLE() + } + // check signature + if (!verifySignature(input)) { + throw new SDKErrors.ERROR_SIGNATURE_UNVERIFIABLE() } - /** - * [STATIC] Builds a new instance of [[ContentStream]], from a complete set of required parameters. - * - * @param content An `IContentStream` object the request for credential is built for. - * @param issuer The Issuer's [[Identity]]. - * @param option Container for different options that can be passed to this method. - * @param option.evidenceIds Array of [[Credential]] objects the Issuer include as evidenceIds. - * @param option.link Identifier of the stream this credential is linked to. - * @param option.space Identifier of the space this credential is linked to. - * @throws [[ERROR_IDENTITY_MISMATCH]] when streamInput's issuer address does not match the supplied identity's address. - * @returns A new [[ContentStream]] object. - */ - public static fromContent( - content: IContent, - issuer: Identity, - { evidenceIds, link, space, expiry }: Options = {} - ): ContentStream { - if (content.issuer !== issuer.address) { - throw new SDKErrors.ERROR_IDENTITY_MISMATCH() - } - - const { hashes: contentHashes, nonceMap: contentNonceMap } = - ContentUtils.hashContents(content) - - const issuanceDate = new Date() - const issuanceDateString = issuanceDate.toISOString() - const issuanceDateHash = Crypto.hashObjectAsHexStr(issuanceDateString) - const expirationDate = - expiry || - new Date( - issuanceDate.setFullYear( - issuanceDate.getFullYear() + DEFAULT_STREAM_VALIDITY - ) - ) - const expirationDateString = expirationDate.toISOString() - const expirationDateHash = Crypto.hashObjectAsHexStr(expirationDateString) - - const rootHash = ContentStream.calculateRootHash( - { - evidenceIds, - contentHashes, - }, - issuanceDateHash, - expirationDateHash + // verify properties against selective disclosure proof + const verificationResult = Content.verifyDisclosedAttributes(input.content, { + nonces: input.contentNonceMap, + hashes: input.contentHashes, + }) + // TODO: how do we want to deal with multiple errors during stream verification? + if (!verificationResult.verified) + throw ( + verificationResult.errors[0] || new SDKErrors.ERROR_CONTENT_UNVERIFIABLE() ) - return new ContentStream({ - content, - contentHashes, - contentNonceMap, - evidenceIds: evidenceIds || [], - link: link || null, - space: space || null, - issuerSignature: ContentStream.sign(issuer, rootHash), - rootHash, - issuanceDate: issuanceDateString, - expirationDate: expirationDateString, - identifier: Identifier.getIdentifier( - rootHash, - STREAM_IDENTIFIER, - STREAM_PREFIX - ), - }) - } + // check proofs + Credential.validateEvidenceIds(input.evidenceIds) - /** - * [STATIC] Update instance of [[ContentStream]], from a complete set of required parameters. - * - * @param content An `IContentStream` object the request for credential is built for. - * @param issuer The Issuer's [[Identity]]. - * @param option Container for different options that can be passed to this method. - * @param option.evidenceIds Array of [[Credential]] objects the Issuer include as evidenceIds. - * @throws [[ERROR_IDENTITY_MISMATCH]] when streamInput's issuer address does not match the supplied identity's address. - * @returns An updated [[ContentStream]] object. - */ - public static updateContentProperties( - content: IContentStream, - issuer: Identity, - { evidenceIds, expiry }: Options = {} - ): ContentStream { - if (content.content.issuer !== issuer.address) { - throw new SDKErrors.ERROR_IDENTITY_MISMATCH() - } - let updateEvidenceIds = evidenceIds || content.evidenceIds - - const { hashes: contentHashes, nonceMap: contentNonceMap } = - ContentUtils.hashContents(content.content) - const issuanceDate = new Date() - const issuanceDateString = issuanceDate.toISOString() - const issuanceDateHash = Crypto.hashObjectAsHexStr(issuanceDateString) - const expirationDate = - expiry || - new Date( - issuanceDate.setFullYear( - issuanceDate.getFullYear() + DEFAULT_STREAM_VALIDITY - ) - ) - const expirationDateString = expirationDate.toISOString() - const expirationDateHash = Crypto.hashObjectAsHexStr(expirationDateString) - - const rootHash = ContentStream.calculateRootHash( - { - evidenceIds: updateEvidenceIds, - contentHashes, - }, - issuanceDateHash, - expirationDateHash + return true +} + +/** + * Checks whether the input meets all the required criteria of an IContentStream object. + * Throws on invalid input. + * + * @param input - A potentially only partial [[IContentStream]]. + * + */ +export function verifyDataStructure(input: IContentStream): void { + if (!input.content) { + throw new SDKErrors.ERROR_CONTENT_NOT_PROVIDED() + } else { + Content.verifyDataStructure(input.content) + } + if (!input.content.issuer) { + throw new SDKErrors.ERROR_OWNER_NOT_PROVIDED() + } + if (!input.evidenceIds && !Array.isArray(input.evidenceIds)) { + throw new SDKErrors.ERROR_EVIDENCE_ID_NOT_PROVIDED() + } + if (!input.contentNonceMap) { + throw new SDKErrors.ERROR_CONTENT_NONCE_MAP_NOT_PROVIDED() + } + if ( + typeof input.contentNonceMap !== 'object' || + Object.entries(input.contentNonceMap).some( + ([digest, nonce]) => + !digest || + !DataUtils.validateHash(digest, 'statement digest') || + typeof nonce !== 'string' || + !nonce ) + ) { + throw new SDKErrors.ERROR_CONTENT_NONCE_MAP_MALFORMED() + } +} - return new ContentStream({ - content: content.content, - contentHashes, - contentNonceMap, - evidenceIds: updateEvidenceIds || content.evidenceIds, - link: content.link, - space: content.space, - issuerSignature: ContentStream.sign(issuer, rootHash), - rootHash, - issuanceDate: issuanceDateString, - expirationDate: expirationDateString, - identifier: content.identifier, - }) +/** + * Checks the [[ContentStream]] with a given [[SchemaType]] to check if the claim meets the [[schema]] structure. + * + * @param contentStream A [[ContentStream]] object of an attested claim used for verification. + * @param schema A [[Schema]] to verify the [[Content]] structure. + * + * @returns A boolean if the [[Content]] structure in the [[Credential]] is valid. + */ + +export function verifyWithSchema( + contentStream: IContentStream, + schema: ISchema +): boolean { + try { + verifyDataStructure(contentStream) + } catch { + return false } + return verifyContentWithSchema(contentStream.content.contents, schema.schema) +} + +export type Options = { + evidenceIds?: ICredential[] + link?: IContentStream['link'] + space?: IContentStream['space'] + expiry?: Date +} - /** - * [STATIC] Custom Type Guard to determine input being of type IContentStream.. - * - * @param input - A potentially only partial [[IContentStream]]. - * - * @returns Boolean whether input is of type IContentStream. - */ - public static isIMarkContent(input: unknown): input is IContentStream { - try { - ContentStreamUtils.errorCheck(input as IContentStream) - } catch (error) { - return false - } - return true +/** + * Builds a new i [[ContentStream]] object, from a complete set of required parameters. + * + * @param content An `IContentStream` object the request for credential is built for. + * @param issuer The Issuer's [[Identity]]. + * @param option Container for different options that can be passed to this method. + * @param option.evidenceIds Array of [[Credential]] objects the Issuer include as evidenceIds. + * @param option.link Identifier of the stream this credential is linked to. + * @param option.space Identifier of the space this credential is linked to. + * @throws [[ERROR_IDENTITY_MISMATCH]] when streamInput's issuer address does not match the supplied identity's address. + * @returns A new [[ContentStream]] object. + */ +export function fromContent( + content: IContent, + issuer: Identity, + { evidenceIds, link, space, expiry }: Options = {} +): IContentStream { + if (content.issuer !== issuer.address) { + throw new SDKErrors.ERROR_IDENTITY_MISMATCH() } - public content: IContentStream['content'] - public contentHashes: IContentStream['contentHashes'] - public contentNonceMap: IContentStream['contentNonceMap'] - public evidenceIds: IContentStream['evidenceIds'] - public link: IContentStream['link'] | null - public space: IContentStream['space'] | null - public issuerSignature: string - public rootHash: IContentStream['rootHash'] - public identifier: IContentStream['identifier'] - public issuanceDate: string - public expirationDate: string - - /** - * Builds a new [[ContentStream]] instance. - * - * @param contentStreamRequest - The base object from which to create the input. - * - */ - public constructor(contentStreamRequest: IContentStream) { - ContentStreamUtils.errorCheck(contentStreamRequest) - this.identifier = contentStreamRequest.identifier - this.content = contentStreamRequest.content - this.contentHashes = contentStreamRequest.contentHashes - this.contentNonceMap = contentStreamRequest.contentNonceMap - if ( - contentStreamRequest.evidenceIds && - Array.isArray(contentStreamRequest.evidenceIds) && - contentStreamRequest.evidenceIds.length - ) { - this.evidenceIds = contentStreamRequest.evidenceIds.map((proof) => - Credential.fromCredential(proof) + const { hashes: contentHashes, nonceMap: contentNonceMap } = + Content.hashContents(content) + + const issuanceDate = new Date() + const issuanceDateString = issuanceDate.toISOString() + const issuanceDateHash = Crypto.hashObjectAsHexStr(issuanceDateString) + const expirationDate = + expiry || + new Date( + issuanceDate.setFullYear( + issuanceDate.getFullYear() + DEFAULT_STREAM_VALIDITY ) - } else { - this.evidenceIds = [] - } - this.link = contentStreamRequest.link - this.space = contentStreamRequest.space - this.issuanceDate = contentStreamRequest.issuanceDate - this.expirationDate = contentStreamRequest.expirationDate - this.rootHash = contentStreamRequest.rootHash - this.issuerSignature = contentStreamRequest.issuerSignature - this.verifySignature() - this.verifyData( - Crypto.hashObjectAsHexStr(contentStreamRequest.issuanceDate), - Crypto.hashObjectAsHexStr(contentStreamRequest.expirationDate) ) + const expirationDateString = expirationDate.toISOString() + const expirationDateHash = Crypto.hashObjectAsHexStr(expirationDateString) + + const rootHash = calculateRootHash( + { + evidenceIds, + contentHashes, + }, + issuanceDateHash, + expirationDateHash + ) + + const contentStream = { + content, + contentHashes, + contentNonceMap, + evidenceIds: evidenceIds || [], + link: link || null, + space: space || null, + issuerSignature: sign(issuer, rootHash), + rootHash, + issuanceDate: issuanceDateString, + expirationDate: expirationDateString, + identifier: Identifier.getIdentifier( + rootHash, + STREAM_IDENTIFIER, + STREAM_PREFIX + ), } + verifyDataStructure(contentStream) + return contentStream +} - /** - * Removes [[Content] properties from the [[ContentStream]] object, provides anonymity and security when building the [[createPresentation]] method. - * - * @param properties - Properties to remove from the [[Stream]] object. - * @throws [[ERROR_CONTENT_HASHTREE_MISMATCH]] when a property which should be deleted wasn't found. - * - */ - public removeContentProperties(properties: string[]): void { - properties.forEach((key) => { - delete this.content.contents[key] - }) - this.contentNonceMap = ContentUtils.hashContents(this.content, { - nonces: this.contentNonceMap, - }).nonceMap +/** + * Update instance of [[ContentStream]], from a complete set of required parameters. + * + * @param content An `IContentStream` object the request for credential is built for. + * @param issuer The Issuer's [[Identity]]. + * @param option Container for different options that can be passed to this method. + * @param option.legitimations Array of [[Credential]] objects the Issuer include as legitimations. + * @throws [[ERROR_IDENTITY_MISMATCH]] when streamInput's issuer address does not match the supplied identity's address. + * @returns An updated [[ContentStream]] object. + */ +export function updateContent( + content: IContentStream, + issuer: Identity, + { evidenceIds, expiry }: Options = {} +): IContentStream { + if (content.content.issuer !== issuer.address) { + throw new SDKErrors.ERROR_IDENTITY_MISMATCH() } + let updateEvidenceIds = evidenceIds || content.evidenceIds - /** - * Verifies the data of the [[ContentStream]] object; used to check that the data was not tampered with, by checking the data against hashes. - * - * @param input - The [[ContentStream]] for which to verify data. - * @returns Whether the data is valid. - * @throws [[ERROR_CONTENT_NONCE_MAP_MALFORMED]] when any key of the stream marks could not be found in the streamHashTree. - * @throws [[ERROR_ROOT_HASH_UNVERIFIABLE]] or [[ERROR_SIGNATURE_UNVERIFIABLE]] when either the rootHash or the signature are not verifiable respectively. - * - */ - public static verifyData( - input: IContentStream, - issuanceDate: HexString, - expirationDate: HexString - ): boolean { - // check stream hash - if (!ContentStream.verifyRootHash(input, issuanceDate, expirationDate)) { - throw new SDKErrors.ERROR_ROOT_HASH_UNVERIFIABLE() - } - // check signature - if (!ContentStream.verifySignature(input)) { - throw new SDKErrors.ERROR_SIGNATURE_UNVERIFIABLE() - } - - // verify properties against selective disclosure proof - const verificationResult = ContentUtils.verifyDisclosedAttributes( - input.content, - { - nonces: input.contentNonceMap, - hashes: input.contentHashes, - } - ) - // TODO: how do we want to deal with multiple errors during stream verification? - if (!verificationResult.verified) - throw ( - verificationResult.errors[0] || - new SDKErrors.ERROR_CONTENT_UNVERIFIABLE() - ) + const { hashes: contentHashes, nonceMap: contentNonceMap } = + Content.hashContents(content.content) - // check proofs - Credential.validateEvidenceIds(input.evidenceIds) + const issuanceDate = new Date().toISOString() + const issuanceDateHash = Crypto.hashObjectAsHexStr(issuanceDate) + const expirationDate = expiry?.toISOString() || content.expirationDate + const expirationDateHash = Crypto.hashObjectAsHexStr(expirationDate) - return true - } + const rootHash = calculateRootHash( + { + evidenceIds: updateEvidenceIds, + contentHashes, + }, + issuanceDateHash, + expirationDateHash + ) - public verifyData( - issuanceDate: HexString, - expirationDate: HexString - ): boolean { - return ContentStream.verifyData(this, issuanceDate, expirationDate) + const contentStream = { + content: content.content, + contentHashes, + contentNonceMap, + evidenceIds: updateEvidenceIds || content.evidenceIds, + link: content.link, + space: content.space, + issuerSignature: sign(issuer, rootHash), + rootHash, + issuanceDate, + expirationDate, + identifier: content.identifier, } + verifyDataStructure(contentStream) + return contentStream +} - /** - * Verifies the signature of the [[ContentStream]] object. - * - * @param input - [[ContentStream]] . - * @returns Whether the signature is correct. - * - */ - public static verifySignature(input: IContentStream): boolean { - return verifyCreatorSignature(input) - } +/** + * Verifies data structure and integrity. + * + * @param contentStream - The object to check. + * @param options - Additional parameter for more verification step. + * @param options.ctype - Ctype which the included claim should be checked against. + * @param options.challenge - The expected value of the challenge. Verification will fail in case of a mismatch. + * @param options.resolver - The resolver used to resolve the claimer's identity. Defaults to [[DidResolver]]. + * @throws - If a check fails. + */ +export async function verify( + contentStream: IContentStream, + schema?: ISchema +): Promise { + verifyDataStructure(contentStream) + verifyDataIntegrity(contentStream) + const isSignatureCorrect = verifySignature(contentStream) + if (!isSignatureCorrect) throw new SDKErrors.ERROR_SIGNATURE_UNVERIFIABLE() - public verifySignature(): boolean { - return ContentStream.verifySignature(this) + if (schema) { + const isSchemaValid = verifyWithSchema(contentStream, schema) + if (!isSchemaValid) throw new SDKErrors.ERROR_CREDENTIAL_UNVERIFIABLE() } +} - public static verifyRootHash( - input: IContentStream, - issuanceDate: HexString, - expirationDate: HexString - ): boolean { - return ( - input.rootHash === - ContentStream.calculateRootHash(input, issuanceDate, expirationDate) - ) +/** + * Custom Type Guard to determine input being of type IContentStream.. + * + * @param input - A potentially only partial [[IContentStream]]. + * + * @returns Boolean whether input is of type IContentStream. + */ +export function isIContentStream(input: unknown): input is IContentStream { + try { + verifyDataStructure(input as IContentStream) + } catch (error) { + return false } + return true +} - public verifyRootHash( - issuanceDate: HexString, - expirationDate: HexString - ): boolean { - return ContentStream.verifyRootHash(this, issuanceDate, expirationDate) - } +/** + * Compresses [[Credential]]s which are made up from [[Stream]] and [[ContentStream]] for storage and/or message. + * + * @param leg An array of [[Credential]] and [[ContentStream]] objects. + * + * @returns An ordered array of [[CordMark]]s. + */ - private static sign(identity: Identity, rootHash: Hash): string { - return identity.signStr(rootHash) - } +export function compressProof(leg: ICredential[]): CompressedCredential[] { + return leg.map(Credential.compress) +} - private static getHashLeaves( - contentHashes: Hash[], - evidenceIds: ICredential[], - issueDate: HexString, - expiryDate: HexString - ): Uint8Array[] { - const result: Uint8Array[] = [] - contentHashes.forEach((item) => { - result.push(Crypto.coToUInt8(item)) - }) - if (evidenceIds) { - evidenceIds.forEach((evidence) => { - result.push(Crypto.coToUInt8(evidence.request.identifier)) - }) - } - result.push(Crypto.coToUInt8(issueDate)) - result.push(Crypto.coToUInt8(expiryDate)) - return result - } +/** + * Decompresses [[Credential]]s which are [[Stream]] and [[ContentStream]] from storage and/or message. + * + * @param leg A compressed [[Credential]] and [[ContentStream]] array that is reverted back into an object. + * + * @returns An object that has the same properties as an [[Credential]]. + */ - /** - * Compresses an [[ContentStream]] object. - * - * @returns An array that contains the same properties of a [[ContentStream]]. - */ - public compress(): CompressedContentStream { - return ContentStreamUtils.compress(this) - } +function decompressProof(leg: CompressedCredential[]): ICredential[] { + return leg.map(Credential.decompress) +} - /** - * [STATIC] Builds an [[ContentStream]] from the decompressed array. - * - * @param requestForStream The [[CompressedContentStream]] that should get decompressed. - * @returns A new [[ContentStream]] object. - */ - public static decompress( - requestForStream: CompressedContentStream - ): ContentStream { - const decompressedContentStream = - ContentStreamUtils.decompress(requestForStream) - return ContentStream.fromRequest(decompressedContentStream) - } +/** + * Compresses a [[ContentStream]] for storage and/or messaging. + * + * @param contentStream A [[ContentStream]] object that will be sorted and stripped for messaging or storage. + * + * @returns An ordered array of a [[CompressedContentStream]]. + */ - private static calculateRootHash( - credential: Partial, - issuanceDate: HexString, - expirationDate: HexString - ): Hash { - const hashes: Uint8Array[] = ContentStream.getHashLeaves( - credential.contentHashes || [], - credential.evidenceIds || [], - issuanceDate, - expirationDate - ) - const root: Uint8Array = getHashRoot(hashes) - return Crypto.u8aToHex(root) +export function compress( + contentStream: IContentStream +): CompressedContentStream { + verifyDataStructure(contentStream) + return [ + Content.compress(contentStream.content), + contentStream.contentHashes, + contentStream.contentNonceMap, + contentStream.issuerSignature, + contentStream.link, + contentStream.space, + compressProof(contentStream.evidenceIds), + contentStream.rootHash, + contentStream.identifier, + contentStream.issuanceDate, + contentStream.expirationDate, + ] +} +/** + * Decompresses a [[ContentStream]] from storage and/or message. + * + * @param contentStream A compressed [[ContentStream]] array that is reverted back into an object. + * @throws [[ERROR_DECOMPRESSION_ARRAY]] when contentStream is not an Array and it's length is not equal to the defined length of 11. + * + * @returns An object that has the same properties as a [[ContentStream]]. + */ + +export function decompress( + contentStream: CompressedContentStream +): IContentStream { + if (!Array.isArray(contentStream) || contentStream.length !== 11) { + throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Request for Content Stream') + } + return { + content: Content.decompress(contentStream[0]), + contentHashes: contentStream[1], + contentNonceMap: contentStream[2], + issuerSignature: contentStream[3], + link: contentStream[4], + space: contentStream[5], + evidenceIds: decompressProof(contentStream[6]), + rootHash: contentStream[7], + identifier: contentStream[8], + issuanceDate: contentStream[9], + expirationDate: contentStream[10], } } diff --git a/packages/modules/src/contentstream/ContentStream.utils.ts b/packages/modules/src/contentstream/ContentStream.utils.ts deleted file mode 100644 index 571f520f..00000000 --- a/packages/modules/src/contentstream/ContentStream.utils.ts +++ /dev/null @@ -1,155 +0,0 @@ -import type { - ICredential, - CompressedCredential, - CompressedContentStream, - IContentStream, - ISchema, -} from '@cord.network/types' -import { Crypto, DataUtils, SDKErrors } from '@cord.network/utils' -import * as CredentialUtils from '../credential/Credential.utils.js' -import * as ContentUtils from '../content/Content.utils.js' -import { ContentStream } from './ContentStream.js' -import * as SchemaUtils from '../schema/Schema.utils.js' - -/** - * Checks whether the input meets all the required criteria of an IContentStream object. - * Throws on invalid input. - * - * @param input - A potentially only partial [[IContentStream]]. - * - */ -export function errorCheck(input: IContentStream): void { - if (!input.content) { - throw new SDKErrors.ERROR_CONTENT_NOT_PROVIDED() - } else { - ContentUtils.errorCheck(input.content) - } - if (!input.evidenceIds && !Array.isArray(input.evidenceIds)) { - throw new SDKErrors.ERROR_EVIDENCE_ID_NOT_PROVIDED() - } - if (!input.contentNonceMap) { - throw new SDKErrors.ERROR_CONTENT_NONCE_MAP_NOT_PROVIDED() - } - if ( - typeof input.contentNonceMap !== 'object' || - Object.entries(input.contentNonceMap).some( - ([digest, nonce]) => - !digest || - !DataUtils.validateHash(digest, 'statement digest') || - typeof nonce !== 'string' || - !nonce - ) - ) { - throw new SDKErrors.ERROR_CONTENT_NONCE_MAP_MALFORMED() - } - ContentStream.verifyData( - input as IContentStream, - Crypto.hashObjectAsHexStr(input.issuanceDate), - Crypto.hashObjectAsHexStr(input.expirationDate) - ) -} - -/** - * Compresses [[CordMark]]s which are made up from an [[Credential]] and [[ContentStream]] for storage and/or message. - * - * @param leg An array of [[Credential]] and [[ContentStream]] objects. - * - * @returns An ordered array of [[CordMark]]s. - */ - -export function compressProof(leg: ICredential[]): CompressedCredential[] { - return leg.map(CredentialUtils.compress) -} - -/** - * Decompresses [[CordMark]]s which are an [[Credential]] and [[ContentStream]] from storage and/or message. - * - * @param leg A compressed [[Credential]] and [[ContentStream]] array that is reverted back into an object. - * - * @returns An object that has the same properties as an [[CordMark]]. - */ - -function decompressProof(leg: CompressedCredential[]): ICredential[] { - return leg.map(CredentialUtils.decompress) -} - -/** - * Compresses a [[ContentStream]] for storage and/or messaging. - * - * @param contentStream A [[ContentStream]] object that will be sorted and stripped for messaging or storage. - * - * @returns An ordered array of a [[CompressedContentStream]]. - */ - -export function compress( - contentStream: IContentStream -): CompressedContentStream { - errorCheck(contentStream) - return [ - ContentUtils.compress(contentStream.content), - contentStream.contentHashes, - contentStream.contentNonceMap, - contentStream.issuerSignature, - contentStream.link, - contentStream.space, - compressProof(contentStream.evidenceIds), - contentStream.rootHash, - contentStream.identifier, - contentStream.issuanceDate, - contentStream.expirationDate, - ] -} - -/** - * Decompresses a [[ContentStream]] from storage and/or message. - * - * @param contentStream A compressed [[ContentStream]] array that is reverted back into an object. - * @throws [[ERROR_DECOMPRESSION_ARRAY]] when contentStream is not an Array and it's length is not equal to the defined length of 9. - * - * @returns An object that has the same properties as a [[ContentStream]]. - */ - -export function decompress( - contentStream: CompressedContentStream -): IContentStream { - if (!Array.isArray(contentStream) || contentStream.length !== 11) { - throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Request for Stream Content') - } - return { - content: ContentUtils.decompress(contentStream[0]), - contentHashes: contentStream[1], - contentNonceMap: contentStream[2], - issuerSignature: contentStream[3], - link: contentStream[4], - space: contentStream[5], - evidenceIds: decompressProof(contentStream[6]), - rootHash: contentStream[7], - identifier: contentStream[8], - issuanceDate: contentStream[9], - expirationDate: contentStream[10], - } -} - -/** - * Checks the [[ContentStream]] with a given [[SchemaType]] to check if the claim meets the [[schema]] structure. - * - * @param contentStream A [[ContentStream]] object of an attested claim used for verification. - * @param schema A [[Schema]] to verify the [[Content]] structure. - * - * @returns A boolean if the [[Content]] structure in the [[Credential]] is valid. - */ - -export function verifyStructure( - contentStream: IContentStream, - schema: ISchema -): boolean { - try { - errorCheck(contentStream) - } catch { - return false - } - return SchemaUtils.verifyContentProperties( - contentStream.content.contents, - schema.schema - ) -} diff --git a/packages/modules/src/contentstream/index.ts b/packages/modules/src/contentstream/index.ts index 9e1794d7..1cbf3763 100644 --- a/packages/modules/src/contentstream/index.ts +++ b/packages/modules/src/contentstream/index.ts @@ -1,2 +1 @@ -export { ContentStream } from './ContentStream.js' -export * as ContentStreamUtils from './ContentStream.utils.js' +export * from './ContentStream.js' diff --git a/packages/modules/src/credential/Credential.ts b/packages/modules/src/credential/Credential.ts index b388de27..3f643019 100644 --- a/packages/modules/src/credential/Credential.ts +++ b/packages/modules/src/credential/Credential.ts @@ -14,214 +14,241 @@ import type { CompressedCredential, IContentStream, IStream, - IPresentationOptions, - IPresentationSigningOptions, + ISchema, } from '@cord.network/types' -import { Crypto, SDKErrors, Identifier } from '@cord.network/utils' -import { Stream } from '../stream/Stream.js' -import { ContentStream } from '../contentstream/ContentStream.js' -import * as CredentialUtils from './Credential.utils.js' -import { Presentation, SignedPresentation } from './Presentation' +import { SDKErrors, Identifier } from '@cord.network/utils' +import * as Stream from '../stream/Stream.js' +import * as ContentStream from '../contentstream/ContentStream.js' +import { verifyContentWithSchema } from '../schema/index.js' +import { Identity } from '../identity/Identity.js' import { SCHEMA_PREFIX } from '@cord.network/types' -export class Credential implements ICredential { - /** - * [STATIC] Builds an instance of [[Credential]], from a simple object with the same properties. - * Used for deserialization. - * - * @param cred - The base object from which to create the Credential. - * @returns A new instantiated [[Credential]] object. - * - */ - public static fromCredential(cred: ICredential): Credential { - return new Credential(cred) +/** + * Verifies whether the data of the given credential is valid. It is valid if: + * * the [[ContentStream]] object associated with this credential has valid data (see [[ContentStream.verifyDataIntegrity]]); + * and + * * the hash of the [[ContentStream]] object for the credential, and the hash of the [[Content]] for the credential are the same. + * + * @param credential - The credential to verify. + * @returns Whether the credential's data is valid. + */ +export function verifyDataIntegrity(credential: ICredential): boolean { + if ( + Identifier.getIdentifierKey( + credential.request.content.schema, + SCHEMA_PREFIX + ) !== credential.stream.schema + ) + return false + return ( + credential.request.rootHash === credential.stream.streamHash && + ContentStream.verifyDataIntegrity(credential.request) + ) +} + +/** + * Checks whether the input meets all the required criteria of an ICredential object. + * Throws on invalid input. + * + * @param input The potentially only partial ICredential. + * @throws [[ERROR_STREAM_NOT_PROVIDED]] or [[ERROR_RFA_NOT_PROVIDED]] when input's attestation and request respectively do not exist. + * + */ +export function verifyDataStructure(input: ICredential): void { + if (input.stream) { + Stream.verifyDataStructure(input.stream) + } else throw new SDKErrors.ERROR_STREAM_NOT_PROVIDED() + + if (input.request) { + ContentStream.verifyDataStructure(input.request) + } else throw new SDKErrors.ERROR_CONTENT_STREAM_NOT_PROVIDED() +} + +/** + * Checks the [[Credential]] with a given [[Schema]] to check if the content meets the [[schema]] structure. + * + * @param credential A [[Credential]] object of an attested claim used for verification. + * @param schema A [[Schema]] to verify the [[Content]] structure. + * + * @returns A boolean if the [[Content]] structure in the [[Credential]] is valid. + */ +export function verifyAgainstCType( + credential: ICredential, + schema: ISchema +): boolean { + verifyDataStructure(credential) + return verifyContentWithSchema( + credential.request.content.contents, + schema.schema + ) +} + +/** + * Builds a new instance of [[Credential]], from all required properties. + * + * @param request - The content stream. + * @param stream - The credential stream. + * @returns A new [[Credential]] object. + * + */ +export function fromRequestAndStream( + request: IContentStream, + stream: IStream +): ICredential { + const credential = { + request, + stream, } + verifyDataStructure(credential) + return credential +} - /** - * [STATIC] Builds a new instance of [[Credential]], from all required properties. - * - * @param content - The content stream. - * @param stream - The credential stream. - * @returns A new [[Credential]] object. - * - */ - public static fromRequestAndStream( - request: IContentStream, - stream: IStream - ): Credential { - return new Credential({ - request, - stream, - }) +/** + * Custom Type Guard to determine input being of type ICredential using the CredentialUtils errorCheck. + * + * @param input The potentially only partial ICredential. + * + * @returns Boolean whether input is of type ICredential. + */ +export function isICredential(input: unknown): input is ICredential { + try { + verifyDataStructure(input as ICredential) + } catch (error) { + return false } + return true +} - /** - * [STATIC] Custom Type Guard to determine input being of type ICredential using the CredentialUtils errorCheck. - * - * @param input The potentially only partial ICredential. - * - * @returns Boolean whether input is of type ICredential. - */ - public static isICredential(input: unknown): input is ICredential { - try { - CredentialUtils.errorCheck(input as ICredential) - } catch (error) { - return false +/** + * Verifies whether the credential stream is valid. It is valid if: + * * the data is valid (see [[verifyData]]); + * and + * * the [[Stream]] object for this stream is valid (see [[Stream.checkValidity]], where the **chain** is queried). + * + * Upon presentation of a stream, a verifier would call this [[verify]] function. + * + * @param markedStream - The stream to check for validity. + * @returns A promise containing whether this attested stream is valid. + * + */ + +export async function verify(cred: ICredential): Promise { + return ( + verifyDataIntegrity(cred) && + (await ContentStream.verifySignature(cred.request)) && + Stream.checkValidity(cred.stream) + ) +} + +/** + * Verifies the data of each element of the given Array of IMarkedStreams. + * + * @param evidenceIds Array of IMarkedStreams to validate. + * @throws [[ERROR_EVIDENCE_ID_UNVERIFIABLE]] when one of the IMarkedStreams data is unable to be verified. + * + * @returns Boolean whether each element of the given Array of IMarkedStreams is verifiable. + */ +export function validateEvidenceIds(evidenceIds: ICredential[]): boolean { + evidenceIds.forEach((evidence: ICredential) => { + if (!verifyDataIntegrity(evidence)) { + throw new SDKErrors.ERROR_EVIDENCE_ID_UNVERIFIABLE() } - return true - } + }) + return true +} - public request: ContentStream - public stream: Stream - - /** - * Builds a new [[Credential]] instance. - * - * @param cred - The base object with all required input, from which to create the Credential. - * - */ - public constructor(cred: ICredential) { - CredentialUtils.errorCheck(cred) - this.request = ContentStream.fromRequest(cred.request) - this.stream = Stream.fromStream(cred.stream) - } +/** + * Gets the hash of the stream that corresponds to this credential. + * + * @returns The hash of the stream for this credential (streamHash). + * + */ +export function getHash(credential: ICredential): IStream['streamHash'] { + return credential.stream.streamHash +} - /** - * (ASYNC) Verifies whether the credential stream is valid. It is valid if: - * * the data is valid (see [[verifyData]]); - * and - * * the [[Stream]] object for this stream is valid (see [[Stream.checkValidity]], where the **chain** is queried). - * - * Upon presentation of a stream, a verifier would call this [[verify]] function. - * - * @param markedStream - The stream to check for validity. - * @returns A promise containing whether this attested stream is valid. - * - */ - - public static async verify(cred: ICredential): Promise { - return ( - Credential.verifyData(cred) && - (await ContentStream.verifySignature(cred.request)) && - Stream.checkValidity(cred.stream) - ) - } +export function getId(credential: ICredential): IStream['identifier'] { + return credential.stream.identifier +} - public async verify(challenge?: string): Promise { - return Credential.verify(this) - } +export function getAttributes(credential: ICredential): Set { + // TODO: move this to stream or contents + return new Set(Object.keys(credential.request.content.contents)) +} - /** - * Verifies whether the data of the given anchored stream is valid. It is valid if: - * * the [[RequestForMark]] object associated with this attested stream has valid data (see [[RequestForMark.verifyData]]); - * and - * * the hash of the [[RequestForMark]] object for the attested stream, and the hash of the [[Stream]] for the attested stream are the same. - * - * @param cred - The credential to verify. - * @returns Whether the attested stream's data is valid. - * - */ - public static verifyData(cred: ICredential): boolean { - const schemaIdentifier = cred.request.content.schema - ? Identifier.getIdentifierKey(cred.request.content.schema, SCHEMA_PREFIX) - : null - if (schemaIdentifier !== cred.stream.schema) return false - return ( - cred.request.rootHash === cred.stream.streamHash && - ContentStream.verifyData( - cred.request, - Crypto.hashObjectAsHexStr(cred.request.issuanceDate), - Crypto.hashObjectAsHexStr(cred.request.expirationDate) - ) - ) - } +/** + * Creates a public presentation which can be sent to a verifier. + * + * @param publicAttributes All properties of the stream which have been requested by the verifier and therefore must be publicly presented. + * If kept empty, we hide all attributes inside the stream for the presentation. + * + * @returns A deep copy of the MarkedStream with all but `publicAttributes` removed. + */ - public verifyData(): boolean { - return Credential.verifyData(this) - } +export async function createPresentation({ + credential, + selectedAttributes, + signer, + challenge, +}: { + credential: ICredential + selectedAttributes?: string[] + signer: Identity + challenge?: string +}): Promise { + const presentation = + // clone the attestation and request for attestation because properties will be deleted later. + // TODO: find a nice way to clone stuff + JSON.parse(JSON.stringify(credential)) + + // filter attributes that are not in public attributes + const excludedClaimProperties = selectedAttributes + ? Array.from(getAttributes(credential)).filter( + (property) => !selectedAttributes.includes(property) + ) + : [] - /** - * [STATIC] Verifies the data of each element of the given Array of IMarkedStreams. - * - * @param evidenceIds Array of IMarkedStreams to validate. - * @throws [[ERROR_EVIDENCE_ID_UNVERIFIABLE]] when one of the IMarkedStreams data is unable to be verified. - * - * @returns Boolean whether each element of the given Array of IMarkedStreams is verifiable. - */ - public static validateEvidenceIds(evidenceIds: ICredential[]): boolean { - evidenceIds.forEach((evidence: ICredential) => { - if (!Credential.verifyData(evidence)) { - throw new SDKErrors.ERROR_EVIDENCE_ID_UNVERIFIABLE() - } - }) - return true - } + // remove these attributes + ContentStream.removeContentProperties( + presentation.request, + excludedClaimProperties + ) - /** - * Gets the hash of the stream that corresponds to this credential. - * - * @returns The hash of the stream for this credential (streamHash). - * - */ - public getHash(): IStream['streamHash'] { - return this.stream.streamHash - } + await ContentStream.signWithKey(presentation.request, signer, challenge) - public getId(): IStream['identifier'] { - return this.stream.identifier - } + return presentation +} - public getAttributes(): Set { - // TODO: move this to stream or contents - return new Set(Object.keys(this.request.content.contents)) - } +/** + * Compresses a [[Credential]] object into an array for storage and/or messaging. + * + * @param credential - The credential to compress. + * @returns An array that contains the same properties of a [[Credential]]. + */ +export function compress(credential: ICredential): CompressedCredential { + verifyDataStructure(credential) - /** - * Creates a public presentation which can be sent to a verifier. - * - * @param publicAttributes All properties of the stream which have been requested by the verifier and therefore must be publicly presented. - * If kept empty, we hide all attributes inside the stream for the presentation. - * - * @returns A deep copy of the MarkedStream with all but `publicAttributes` removed. - */ - - public createPresentation({ - showAttributes, - hideAttributes = [], - signer, - request, - }: IPresentationOptions & Partial = {}): - | Presentation - | SignedPresentation { - const allAttributes = Array.from(this.getAttributes()) - const excludedProperties = showAttributes - ? allAttributes.filter((i) => !showAttributes.includes(i)) - : [] - excludedProperties.push(...hideAttributes) - const deepCopy = new Credential(JSON.parse(JSON.stringify(this))) - - deepCopy.request.removeContentProperties(excludedProperties) - const signingOpts = request && signer ? { request, signer } : undefined - return Presentation.fromCredentials([deepCopy], signingOpts) - } + return [ + ContentStream.compress(credential.request), + Stream.compress(credential.stream), + ] +} - /** - * Compresses an [[MarkedStream]] object. - * - * @returns An array that contains the same properties of an [[MarkedStream]]. - */ - public compress(): CompressedCredential { - return CredentialUtils.compress(this) +/** + * Decompresses a [[Credential]] array from storage and/or message into an object. + * + * @param credential The [[CompressedCredential]] that should get decompressed. + * @throws [[ERROR_DECOMPRESSION_ARRAY]] when credential is not an Array or it's length is unequal 2. + * @returns A new [[Credential]] object. + */ +export function decompress(credential: CompressedCredential): ICredential { + if (!Array.isArray(credential) || credential.length !== 2) { + throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Credential') } - - /** - * [STATIC] Builds an [[MarkedStream]] from the decompressed array. - * - * @param markedStream The [[CompressedMarkedStream]] that should get decompressed. - * @returns A new [[MarkedStream]] object. - */ - public static decompress(cred: CompressedCredential): Credential { - const decompressedCredential = CredentialUtils.decompress(cred) - return Credential.fromCredential(decompressedCredential) + const decompressedCredential = { + request: ContentStream.decompress(credential[0]), + stream: Stream.decompress(credential[1]), } + verifyDataStructure(decompressedCredential) + return decompressedCredential } diff --git a/packages/modules/src/credential/Credential.utils.ts b/packages/modules/src/credential/Credential.utils.ts deleted file mode 100644 index cac08c99..00000000 --- a/packages/modules/src/credential/Credential.utils.ts +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @packageDocumentation - * @module CredentialUtils - */ - -import type { - ICredential, - CompressedCredential, - ISchema, -} from '@cord.network/types' -import { SDKErrors } from '@cord.network/utils' -import * as StreamUtils from '../stream/Stream.utils.js' -import * as MarkContentUtils from '../contentstream/ContentStream.utils.js' -import { Credential } from './Credential.js' -import * as SchemaUtils from '../schema/Schema.utils.js' -/** - * Checks whether the input meets all the required criteria of an IMarkedStream object. - * Throws on invalid input. - * - * @param input The potentially only partial IMarkedStream. - * @throws [[ERROR_MARK_NOT_PROVIDED]] or [[ERROR_RFA_NOT_PROVIDED]] when input's credential and content respectively do not exist. - * @throws [[ERROR_STREAM_UNVERIFIABLE]] when input's data could not be verified. - * - */ -export function errorCheck(input: ICredential): void { - if (input.stream) { - StreamUtils.errorCheck(input.stream) - } else throw new SDKErrors.ERROR_CONTENT_NOT_PROVIDED() - - if (input.request) { - MarkContentUtils.errorCheck(input.request) - } else throw new SDKErrors.ERROR_MC_NOT_PROVIDED() - - if (!Credential.verifyData(input as ICredential)) { - throw new SDKErrors.ERROR_CONTENT_UNVERIFIABLE() - } -} - -/** - * Compresses an [[MarkedStream]] object into an array for storage and/or messaging. - * - * @param markedStream An [[MarkedStream]] that will be sorted and stripped for messaging or storage. - * - * @returns An ordered array of an [[MarkedStream]] that comprises of an [[Credential]] and [[RequestForMark]] arrays. - */ - -export function compress(stream: ICredential): CompressedCredential { - errorCheck(stream) - - return [ - MarkContentUtils.compress(stream.request), - StreamUtils.compress(stream.stream), - ] -} - -/** - * Decompresses an [[MarkedStream]] array from storage and/or message into an object. - * - * @param markedStream A compressed [[Credential]] and [[RequestForMark]] array that is reverted back into an object. - * @throws [[ERROR_DECOMPRESSION_ARRAY]] when markedStream is not an Array or it's length is unequal 2. - * - * @returns An object that has the same properties as an [[MarkedStream]]. - */ - -export function decompress(stream: CompressedCredential): ICredential { - if (!Array.isArray(stream) || stream.length !== 2) { - throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Cord Credential') - } - return { - request: MarkContentUtils.decompress(stream[0]), - stream: StreamUtils.decompress(stream[1]), - } -} - -/** - * Checks the [[Credential]] with a given [[SchemaType]] to check if the claim meets the [[schema]] structure. - * - * @param credential A [[Credential]] object of an attested claim used for verification. - * @param schema A [[Schema]] to verify the [[Content]] structure. - * - * @returns A boolean if the [[Content]] structure in the [[Credential]] is valid. - */ - -export function verifyStructure( - credential: ICredential, - schema: ISchema -): boolean { - errorCheck(credential) - return SchemaUtils.verifyContentProperties( - credential.request.content.contents, - schema.schema - ) -} diff --git a/packages/modules/src/credential/Presentation.ts b/packages/modules/src/credential/Presentation.ts deleted file mode 100644 index 8ef4073d..00000000 --- a/packages/modules/src/credential/Presentation.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Crypto, DataUtils } from '@cord.network/utils' -import type { - ICredential, - IContentStream, - IIdentity, - IPresentation, - IPresentationSigningOptions, -} from '@cord.network/types' -import { Credential } from './Credential.js' - -function ensureCredentialOwnership( - credentials: ICredential[] -): IContentStream['content']['holder'] { - const holders = credentials.reduce((owns, credential) => { - owns.add(credential.request.content.holder!) - return owns - }, new Set()) - if (holders.size !== 1) { - throw new Error( - 'all credentials in a presentation must be owned by one holder' - ) - } - const holder = holders.values().next().value - DataUtils.validateAddress(holder, 'credential holder') - return holder -} - -export type SignedPresentation = Presentation & - Pick, 'holderSignature'> - -export class Presentation implements IPresentation { - public credentials: Credential[] - public?: string - public holderSignature?: string - - constructor({ credentials, holderSignature }: IPresentation) { - ensureCredentialOwnership(credentials) - this.credentials = credentials.map((i) => new Credential(i)) - this.holderSignature = holderSignature - } - - public static fromPresentations( - presentations: IPresentation[], - signingOpts?: IPresentationSigningOptions - ): Presentation { - const credentials = ([] as ICredential[]).concat( - ...presentations.map((i) => i.credentials) - ) - const presentation = new Presentation({ - credentials, - }) - if (!signingOpts) return presentation - presentation.sign(signingOpts) - return presentation - } - - public static fromCredentials( - credentials: ICredential[], - options?: IPresentationSigningOptions - ): Presentation { - const presentation = new Presentation({ credentials }) - if (options) { - presentation.sign(options) - } - return presentation - } - - public sign({ signer }: IPresentationSigningOptions): SignedPresentation { - delete this.holderSignature - const signature = signer.sign(Crypto.coToUInt8(JSON.stringify(this))) - this.holderSignature = Crypto.u8aToHex(signature) - return this as SignedPresentation - } - - public isSigned(): this is SignedPresentation { - return !!this.holderSignature - } - - public verifySignature(): boolean { - if (!this.isSigned()) return false - const claimsOwner = ensureCredentialOwnership(this.credentials) - const { holderSignature, ...document } = this - return Crypto.verify( - JSON.stringify(document), - holderSignature, - claimsOwner! - ) - } - - public verifyData(): boolean { - if (this.isSigned() && !this.verifySignature()) return false - return this.credentials.every((cred) => cred.verifyData()) - } - - public async verify(): Promise { - if (this.isSigned() && !this.verifySignature()) return false - const results = await Promise.all( - this.credentials.map((cred) => cred.verify()) - ) - return results.every((r) => !!r) - } -} diff --git a/packages/modules/src/credential/index.ts b/packages/modules/src/credential/index.ts index d84f1b6c..949d5241 100644 --- a/packages/modules/src/credential/index.ts +++ b/packages/modules/src/credential/index.ts @@ -1,3 +1 @@ -export { Credential } from './Credential.js' -export * as CredentialUtils from './Credential.utils.js' -export * as Presenation from './Presentation.js' +export * from './Credential.js' diff --git a/packages/modules/src/identity/Identity.ts b/packages/modules/src/identity/Identity.ts index b2abc45a..00871d7d 100644 --- a/packages/modules/src/identity/Identity.ts +++ b/packages/modules/src/identity/Identity.ts @@ -28,10 +28,15 @@ import * as u8aUtil from '@polkadot/util/u8a' // as util-crypto is providing a wrapper only for signing keypair // and not for box keypair, we use TweetNaCl directly import nacl from 'tweetnacl' -import { Crypto, SDKErrors } from '@cord.network/utils' -import type { IIdentity, SubmittableExtrinsic } from '@cord.network/types' +import { Crypto, SDKErrors, UUID } from '@cord.network/utils' +import type { + IIdentity, + SubmittableExtrinsic, + SignProps, +} from '@cord.network/types' import { AnyNumber } from '@polkadot/types/types' import { PublicIdentity } from './PublicIdentity.js' +import { HexString } from '@polkadot/util/types.js' type BoxPublicKey = | PublicIdentity['boxPublicKeyAsHex'] @@ -246,6 +251,21 @@ export class Identity implements IIdentity { return Crypto.signStr(cryptoInput, this.signKeyringPair) } + /** + * Signs data with an [[Identity]] object's key and returns it as string. + * + * @param cryptoInput - The data to be signed. + * @returns The signed data. + * + */ + public signTx(cryptoInput: HexString): SignProps { + const txId = UUID.generate() + const hashVal = { txId, cryptoInput } + const txHash = Crypto.hashObjectAsHexStr(hashVal) + const txSignature = Crypto.signStr(txHash, this.signKeyringPair) + return { txSignature, txHash } + } + /** * Encrypts data asymmetrically and returns it as string. * diff --git a/packages/modules/src/index.ts b/packages/modules/src/index.ts index bb0404a1..de3da12e 100644 --- a/packages/modules/src/index.ts +++ b/packages/modules/src/index.ts @@ -1,15 +1,4 @@ -export { - Schema, - SchemaMetadata, - TypeSchema, - SchemaUtils, -} from './schema/index.js' export { Balance, BalanceUtils } from './balance/index.js' -export { Content, ContentUtils } from './content/index.js' -export { Space, SpaceUtils } from './space/index.js' -export { Stream, StreamUtils, StreamDetailUtils } from './stream/index.js' -export { ContentStream, ContentStreamUtils } from './contentstream/index.js' -export { Credential, CredentialUtils, Presenation } from './credential/index.js' export { Identity, IURLResolver, PublicIdentity } from './identity/index.js' export { Did, @@ -20,5 +9,12 @@ export { DidUtils, } from './did/index.js' +export * as Schema from './schema/index.js' +export * as Space from './space/index.js' +export * as Content from './content/index.js' +export * as ContentStream from './contentstream/index.js' +export * as Stream from './stream/index.js' +export * as Credential from './credential/index.js' + export { connect, disconnect, config, init } from './cordconfig/index.js' export { SDKErrors } from '@cord.network/utils' diff --git a/packages/modules/src/schema/Schema.chain.ts b/packages/modules/src/schema/Schema.chain.ts index 8e92bc26..ac26662c 100644 --- a/packages/modules/src/schema/Schema.chain.ts +++ b/packages/modules/src/schema/Schema.chain.ts @@ -15,7 +15,7 @@ import { SCHEMA_PREFIX, SPACE_PREFIX } from '@cord.network/types' import { DecoderUtils, Identifier } from '@cord.network/utils' import { ConfigService } from '@cord.network/config' import { ChainApiConnection } from '@cord.network/network' -import { SchemaDetails } from './Schema.js' +import { Identity } from '../identity/Identity.js' const log = ConfigService.LoggingFactory.getLogger('Schema') @@ -29,92 +29,82 @@ const log = ConfigService.LoggingFactory.getLogger('Schema') export async function create(schema: ISchema): Promise { const blockchain = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Create tx for 'schema'`) - const tx: SubmittableExtrinsic = blockchain.api.tx.schema.create( + return blockchain.api.tx.schema.create( schema.controller, schema.schemaHash, Identifier.getIdentifierKey(schema.space, SPACE_PREFIX), schema.controllerSignature ) - return tx } /** * TBD */ export async function revoke( - schema_id: string, - controller: string, - txHash: string, - txSignature: string, - spaceIdentifier?: string | null | undefined + schema: ISchema, + controller: Identity ): Promise { + const { txSignature, txHash } = controller.signTx(schema.schemaHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Revoking a schema with ID ${schema_id}`) - const space = spaceIdentifier - ? Identifier.getIdentifierKey(spaceIdentifier, SPACE_PREFIX) - : null - const tx: SubmittableExtrinsic = blockchain.api.tx.schema.revoke( + log.debug(() => `Revoking a schema with ID ${schema.identifier}`) + const space = Identifier.getIdentifierKey(schema.space, SPACE_PREFIX) || null + + return blockchain.api.tx.schema.revoke( controller, - Identifier.getIdentifierKey(schema_id, SCHEMA_PREFIX), + Identifier.getIdentifierKey(schema.identifier, SCHEMA_PREFIX), txHash, space, txSignature ) - return tx } /** * TBD */ export async function authorise( - identifier: string, - controller: string, - delegates: [string], - txHash: string, - txSignature: string, - spaceIdentifier?: string | null | undefined + schema: ISchema, + controller: Identity, + delegates: [string] ): Promise { + const { txSignature, txHash } = controller.signTx(schema.schemaHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Adding a delagate to ${identifier}`) - const space = spaceIdentifier - ? Identifier.getIdentifierKey(spaceIdentifier, SPACE_PREFIX) - : null - const tx: SubmittableExtrinsic = blockchain.api.tx.schema.authorise( + log.debug(() => `Adding a delagate to ${schema.identifier}`) + const space = Identifier.getIdentifierKey(schema.space, SPACE_PREFIX) || null + + return blockchain.api.tx.schema.authorise( controller, - Identifier.getIdentifierKey(identifier, SCHEMA_PREFIX), + Identifier.getIdentifierKey(schema.identifier, SCHEMA_PREFIX), txHash, delegates, space, txSignature ) - return tx } /** * TBD */ export async function deauthorise( - schema_id: string, - controller: string, - delegates: [string], - txHash: string, - txSignature: string, - spaceIdentifier?: string | null | undefined + schema: ISchema, + controller: Identity, + delegates: [string] ): Promise { + const { txSignature, txHash } = controller.signTx(schema.schemaHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Removing delagation from ${schema_id}`) - const space = spaceIdentifier - ? Identifier.getIdentifierKey(spaceIdentifier, SPACE_PREFIX) - : null - const tx: SubmittableExtrinsic = blockchain.api.tx.schema.deauthorise( + log.debug(() => `Removing delagation from ${schema.identifier}`) + const space = Identifier.getIdentifierKey(schema.space, SPACE_PREFIX) || null + + return blockchain.api.tx.schema.deauthorise( controller, - Identifier.getIdentifierKey(schema_id, SCHEMA_PREFIX), + Identifier.getIdentifierKey(schema.identifier, SCHEMA_PREFIX), txHash, delegates, space, txSignature ) - return tx } export interface AnchoredSchemaDetails extends Struct { @@ -127,7 +117,7 @@ export interface AnchoredSchemaDetails extends Struct { function decodeSchema( encodedSchema: Option, schemaId: string -): SchemaDetails | null { +): ISchemaDetails | null { DecoderUtils.assertCodecIsType(encodedSchema, [ 'Option', ]) @@ -140,7 +130,7 @@ function decodeSchema( space: DecoderUtils.hexToString(anchoredSchema.space.toString()) || null, revoked: anchoredSchema.revoked.valueOf(), } - return SchemaDetails.fromSchemaDetails(schema) + return schema } return null } @@ -171,7 +161,7 @@ async function queryRaw( */ export async function queryhash( schema_hash: string -): Promise { +): Promise { const encoded = await queryRawHash(schema_hash) return decodeSchema(encoded, schema_hash) } @@ -180,7 +170,7 @@ export async function queryhash( * @param identifier * @internal */ -export async function query(schema_id: string): Promise { +export async function query(schema_id: string): Promise { const schemaId: string = Identifier.getIdentifierKey(schema_id, SCHEMA_PREFIX) const encoded = await queryRaw(schemaId) return decodeSchema(encoded, schemaId) @@ -197,3 +187,17 @@ export async function getOwner( const queriedSchemaAccount = decodeSchema(encoded, schemaId) return queriedSchemaAccount!.controller } + +/** + * Queries the blockchain and returns whether a Schema with the provided ID exists. + * + * @param schemaId The ID of the Schema to check. + * @returns True if a Schema with the provided ID exists, false otherwise. + */ +export async function isStored( + schema_id: ISchema['identifier'] +): Promise { + const schemaId: string = Identifier.getIdentifierKey(schema_id, SCHEMA_PREFIX) + const encoded = await queryRaw(schemaId) + return encoded.isSome +} diff --git a/packages/modules/src/schema/Schema.ts b/packages/modules/src/schema/Schema.ts index c1057578..e1b95d53 100644 --- a/packages/modules/src/schema/Schema.ts +++ b/packages/modules/src/schema/Schema.ts @@ -13,248 +13,345 @@ import type { IContent, ISchema, - ISchemaDetails, + SchemaWithoutId, + ISchemaMetadata, CompressedSchemaType, - SubmittableExtrinsic, - ISpace, + CompressedSchema, } from '@cord.network/types' -import { Identifier, Crypto, UUID } from '@cord.network/utils' import { - query, - create, - authorise, - deauthorise, - revoke, -} from './Schema.chain.js' -import * as SchemaUtils from './Schema.utils.js' + Identifier, + Crypto, + JsonSchema, + SDKErrors, + DataUtils, + jsonabc, +} from '@cord.network/utils' +import { isStored, getOwner } from './Schema.chain.js' import { SCHEMA_IDENTIFIER, SCHEMA_PREFIX } from '@cord.network/types' import { Identity } from '../identity/Identity.js' +import { HexString } from '@polkadot/util/types' +import { + SchemaModel, + SchemaWrapperModel, + MetadataModel, +} from './Schema.types.js' +/** + * Utility for (re)creating schema hashes. For this, the $id property needs to be stripped from the schemaType. + * + * @param schemaType The Schema (with or without $id). + * @returns Schema without the $id property. + */ -export class Schema implements ISchema { - /** - * [STATIC] [ASYNC] Queries the chain for a given schema entry, by `identifier`. - * - * @param identifier - The identifier of the schema. - * @returns A promise containing the [[SchemaDetails] or null. - */ - public static async query(identifier: string): Promise { - return query(Identifier.getIdentifierKey(identifier, SCHEMA_PREFIX)) - } +export function getSchemaPropertiesForHash( + schemaType: SchemaWithoutId | ISchema['schema'] +): Partial { + const schemaWithoutId: Partial = + '$id' in schemaType + ? (schemaType as ISchema['schema']) + : (schemaType as SchemaWithoutId) + const shallowCopy = { ...schemaWithoutId } + delete shallowCopy.$id + return shallowCopy +} - /** - * [STATIC] Clone an already existing [[Schema]] - * or initializes from an [[ISchema]] object - * which has non-initialized and non-verified Schema data. - * - * @param schemaInput The [[Schema]] which shall be cloned. - * @returns A copy of the given [[Schema]]. - */ - public static fromSchemaType(schemaInput: ISchema): Schema { - return new Schema(schemaInput) - } +/** + * Calculates the Schema hash from schema properties. + * + * @param schema The Schema (with or without $id). + * @returns Hash as hex string. + */ - /** - * [STATIC] Creates a new [[Schema]] from an [[ISchemaType]]. - * - * @param schema The JSON schema from which the [[Schema]] should be generated. - * @param issuer The public SS58 address of the issuer of the [[Schema]]. - * @param schema The identity of the space to which the schema is linked.. - * @returns An instance of [[Schema]]. - */ - public static fromSchemaProperties( - schema: ISchema['schema'], - controller: Identity, - spaceId?: string - ): Schema { - const schemaHash = SchemaUtils.getHashForSchema(schema) - const schemaIdentifier = Identifier.getIdentifier( - schemaHash, - SCHEMA_IDENTIFIER, - SCHEMA_PREFIX - ) - return new Schema({ - identifier: schemaIdentifier, - schemaHash: schemaHash, - schema: { - ...schema, - $id: schemaIdentifier, - }, - space: spaceId || null, - controller: controller.address, - controllerSignature: controller.signStr(schemaHash), +export function getHashForSchema( + schema: SchemaWithoutId | ISchema['schema'] +): HexString { + const prepSchema = getSchemaPropertiesForHash(schema) + return Crypto.hashObjectAsHexStr(prepSchema) +} + +/** + * Verifies data against schema or schema against metaschema. + * + * @param object Data to be verified against schema. + * @param schema Schema to verify against. + * @param messages Optional empty array. If passed, this receives all verification errors. + * @returns Whether or not verification was successful. + */ +export function verifyObjectWithSchema( + object: Record, + schema: Record, + messages?: string[] +): boolean { + const validator = new JsonSchema.Validator(schema, '7', false) + if (schema.$id !== SchemaModel.$id) { + validator.addSchema(SchemaModel) + } + const result = validator.validate(object) + if (!result.valid && messages) { + result.errors.forEach((error: any) => { + messages.push(error.error) }) } + return result.valid +} - /** - * [STATIC] Custom Type Guard to determine input being of type ISchema using the SchemaUtils errorCheck. - * - * @param input The potentially only partial ISchema. - * @returns Boolean whether input is of type ISchema. - */ - static isISchema(input: unknown): input is ISchema { - try { - SchemaUtils.errorCheck(input as ISchema) - } catch (error) { - return false - } - return true +/** + * Verifies the structure of the provided IContent['contents'] with ISchema['schema']. + * + * @param contents IStream['contents'] to be verified against the schema. + * @param schema ISchema['schema'] to be verified against the [SchemaModel]. + * @throws [[ERROR_OBJECT_MALFORMED]] when schema does not correspond to the SchemaModel. + * + * @returns Boolean whether both streamContents and schema could be verified. + */ +export function verifyContentWithSchema( + contents: IContent['contents'], + schema: ISchema['schema'], + messages?: string[] +): boolean { + if (!verifyObjectWithSchema(schema, SchemaModel)) { + throw new SDKErrors.ERROR_OBJECT_MALFORMED() } + return verifyObjectWithSchema(contents, schema, messages) +} - public identifier: ISchema['identifier'] - public schemaHash: ISchema['schemaHash'] - public controller: ISchema['controller'] - public controllerSignature: string - public space: ISpace['identifier'] | null - public schema: ISchema['schema'] +export async function verifyStored(schema: ISchema): Promise { + return isStored(schema.identifier) +} - public constructor(schemaInput: ISchema) { - SchemaUtils.errorCheck(schemaInput) - this.identifier = schemaInput.identifier - this.schemaHash = schemaInput.schemaHash - this.space = schemaInput.space - this.controller = schemaInput.controller - this.controllerSignature = schemaInput.controllerSignature - this.schema = schemaInput.schema - } +export async function verifyOwner(schema: ISchema): Promise { + const issuer = await getOwner(schema.identifier) + return issuer ? issuer === schema.controller : false +} - /** - * [ASYNC] Stores the [[Schema]] on the blockchain. - * - * @param schemaCId The IPFS CID of the schema. - * @returns A promise of a unsigned SubmittableExtrinsic. - */ - public async create(): Promise { - return create(this) +/** + * Checks whether the input meets all the required criteria of an ISchema object. + * Throws on invalid input. + * + * @param input The potentially only partial ISchema. + * @throws [[ERROR_OBJECT_MALFORMED]] when input does not correspond to either it's schema, or the SchemaWrapperModel. + * @throws [[ERROR_HASH_MALFORMED]] when the input's hash does not match the hash calculated from ISchema's schema. + * @throws [[ERROR_MTYPE_OWNER_TYPE]] when the input's owner is not of type string or null. + * + */ +export function verifyDataStructure(input: ISchema): void { + if (!verifyObjectWithSchema(input, SchemaWrapperModel)) { + throw new SDKErrors.ERROR_OBJECT_MALFORMED() } - - public async authorise( - controller: Identity, - delegates: [string] - ): Promise { - const txId = UUID.generate() - const schemaHash = this.schemaHash - const hashVal = { txId, delegates, schemaHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = controller.signStr(txHash) - return authorise( - this.schema.$id, - controller.address, - delegates, - txHash, - txSignature, - this.space - ) + if (!input.schema || getHashForSchema(input.schema) !== input.schemaHash) { + throw new SDKErrors.ERROR_HASH_MALFORMED(input.schemaHash, 'Schema') } - - public async deauthorise( - controller: Identity, - delegates: [string], - spaceid?: string | undefined - ): Promise { - const txId = UUID.generate() - const schemaHash = this.schemaHash - const hashVal = { txId, delegates, schemaHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = controller.signStr(txHash) - return deauthorise( - this.schema.$id, - controller.address, - delegates, - txHash, - txSignature, - this.space - ) + if ( + typeof input.controller === 'string' + ? !DataUtils.validateAddress(input.controller, 'Schema issuer') + : !(input.controller === null) + ) { + throw new SDKErrors.ERROR_SCHEMA_OWNER_TYPE() } - - public async revoke(controller: Identity): Promise { - const txId = UUID.generate() - const schemaHash = this.schemaHash - const hashVal = { txId, schemaHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = controller.signStr(txHash) - return revoke( - this.identifier, - controller.address, - txHash, - txSignature, - this.space + if ( + Identifier.getIdentifier( + input.schemaHash, + SCHEMA_IDENTIFIER, + SCHEMA_PREFIX + ) !== input.schema.$id + ) { + throw new SDKErrors.ERROR_SCHEMA_ID_NOT_MATCHING( + Identifier.getIdentifier( + input.schemaHash, + SCHEMA_IDENTIFIER, + SCHEMA_PREFIX + ), + input.schema.$id ) } +} - /** - * Verifies whether a [[Stream]] follows this [[Schema]] definition. - * - * @param stream The [[Stream]] we want to check against. - * @returns Whether the [[Stream]] and the [[Schema]] align. - */ - public verifyContentStructure(content: IContent): boolean { - return SchemaUtils.verifySchema(content.contents, this.schema) - } +/** + * Validates an array of [[Schema]s against a [[Stream]]. + * + * @param schema - A [[Schema]] that has nested [[Schema]]s inside. + * @param nestedSchemas - An array of [[Schema]]s. + * @param streamContents - The contents of a [[Stream]] to be validated. + * @param messages + * + * @returns Whether the contents is valid. + */ - /** - * [ASYNC] Check whether the [[Schema]]'s hash has been registered to the blockchain. - * - * @returns Whether the [[Schema]] hash is registered to the blockchain. - */ - public async verifyStored(): Promise { - return SchemaUtils.verifyStored(this) +export function verifyContentWithNestedSchemas( + schema: ISchema['schema'], + nestedSchemas: Array, + streamContents: Record, + messages?: string[] +): boolean { + const validator = new JsonSchema.Validator(schema, '7', false) + nestedSchemas.forEach((schema) => { + validator.addSchema(schema) + }) + validator.addSchema(SchemaModel) + const result = validator.validate(streamContents) + if (!result.valid && messages) { + result.errors.forEach((error) => { + messages.push(error.error) + }) } + return result.valid +} - /** - * [ASYNC] Check whether the current owner of [[Schema]] matches the one stored on the blockchain. Returns true if: - * - The [[Schema]] is registered on-chain - * - The owner property of the [[Schema]] matches the registered owner - * If the owner property is not set this method will always return false because the blockchain always stores the - * submitter as owner. - * - * @returns Whether the owner of this [[Schema]] matches the one stored on the blockchain. - */ - public async verifyOwner(): Promise { - return SchemaUtils.verifyOwner(this) +/** + * Checks a SchemaMetadata object. + * + * @param metadata [[ISchemaMetadata]] that is to be instantiated. + * @throws [[ERROR_OBJECT_MALFORMED]] when metadata is not verifiable with the MetadataModel. + */ +export function verifySchemaMetadata(metadata: ISchemaMetadata): void { + if (!verifyObjectWithSchema(metadata, MetadataModel)) { + throw new SDKErrors.ERROR_OBJECT_MALFORMED() } +} - /** - * Compresses an [[Schema]] object. - * - * @returns An array that contains the same properties of an [[Schema]]. - */ +/** + * Creates a new [[Schema]] from an [[ISchemaType]]. + * + * @param schema The JSON schema from which the [[Schema]] should be generated. + * @param controller The public SS58 address of the issuer of the [[Schema]]. + * @param schema The identity of the space to which the schema is linked.. + * @returns An instance of [[Schema]]. + */ +export function fromSchemaProperties( + schema: ISchema['schema'], + controller: Identity, + spaceId?: string +): ISchema { + const schemaHash = getHashForSchema(schema) + const schemaIdentifier = Identifier.getIdentifier( + schemaHash, + SCHEMA_IDENTIFIER, + SCHEMA_PREFIX + ) + const newSchema = { + identifier: schemaIdentifier, + schemaHash: schemaHash, + schema: { + ...schema, + $id: schemaIdentifier, + }, + space: spaceId || null, + controller: controller.address, + controllerSignature: controller.signStr(schemaHash), + } + verifyDataStructure(newSchema) + return newSchema +} - public compress(): CompressedSchemaType { - return SchemaUtils.compress(this) +/** + * Custom Type Guard to determine input being of type ISchema. + * + * @param input The potentially only partial ISchema. + * @returns Boolean whether input is of type ISchema. + */ +export function isISchema(input: unknown): input is ISchema { + try { + verifyDataStructure(input as ISchema) + } catch (error) { + return false } + return true +} - /** - * [STATIC] Builds a [[Schema]] from the decompressed array. - * - * @param schema The [[CompressedSchema]] that should get decompressed. - * @returns A new [[Schema]] object. - */ - public static decompress(schema: CompressedSchemaType): Schema { - const decompressedSchemaType = SchemaUtils.decompress(schema) - return Schema.fromSchemaType(decompressedSchemaType) +/** + * Compresses a [[Schema]] schema for storage and/or messaging. + * + * @param typeSchema A [[Schema]] schema object that will be sorted and stripped for messaging or storage. + * @throws [[ERROR_COMPRESS_OBJECT]] when any of the four required properties of the cTypeSchema are missing. + * + * @returns An ordered array of a [[Schema]]. + */ +export function compressSchema( + typeSchema: ISchema['schema'] +): CompressedSchemaType { + if ( + !typeSchema.$id || + !typeSchema.$schema || + !typeSchema.title || + !typeSchema.properties || + !typeSchema.type + ) { + throw new SDKErrors.ERROR_COMPRESS_OBJECT(typeSchema, 'typeSchema') } + const sortedTypeSchema = jsonabc.sortObj(typeSchema) + return [ + sortedTypeSchema.$id, + sortedTypeSchema.$schema, + sortedTypeSchema.$metadata, + sortedTypeSchema.title, + sortedTypeSchema.description, + sortedTypeSchema.properties, + sortedTypeSchema.type, + ] } -export class SchemaDetails implements ISchemaDetails { - public static fromSchemaDetails(input: ISchemaDetails): SchemaDetails { - return new SchemaDetails(input) +/** + * Decompresses a [[Schema]] from storage and/or message. + * + * @param typeSchema A compressed [[Schema]] schema array that is reverted back into an object. + * @throws [[ERROR_DECOMPRESSION_ARRAY]] when either the typeSchema is not an Array or it's length is not equal to the defined length of 7. + * + * @returns An object that has the same properties as a [[Schema]]. + */ +export function decompressSchema( + typeSchema: CompressedSchemaType +): ISchema['schema'] { + if (!Array.isArray(typeSchema) || typeSchema.length !== 7) { + throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('typeSchema') } - /** - * Builds a new [[SchemaDetails]] instance. - * - */ + return { + $id: typeSchema[0], + $schema: typeSchema[1], + $metadata: typeSchema[2], + title: typeSchema[3], + description: typeSchema[4], + properties: typeSchema[5], + type: typeSchema[6], + } +} - public identifier: ISchemaDetails['identifier'] - public schemaHash: ISchemaDetails['schemaHash'] - public controller: ISchemaDetails['controller'] - public space: string | null - public revoked: ISchemaDetails['revoked'] +/** + * Compresses an [[Schema]] object for storage and/or messaging.. + * @param schema [[Schema]] object that will be sorted and stripped for messaging or storage. + * + * @returns An array that contains the same properties of an [[Schema]]. + */ +export function compress(schema: ISchema): CompressedSchema { + verifyDataStructure(schema) + return [ + schema.identifier, + schema.schemaHash, + schema.controller, + schema.controllerSignature, + schema.controllerSignature, + compressSchema(schema.schema), + ] +} - public constructor(details: ISchemaDetails) { - this.identifier = details.identifier - this.schemaHash = details.schemaHash - this.controller = details.controller - this.space = details.space - this.revoked = details.revoked +/** + * Builds a [[Schema]] from the decompressed array. + * + * @param schema The [[CompressedSchema]] that should get decompressed. + * @throws [[ERROR_DECOMPRESSION_ARRAY]] when either the Schema is not an Array or it's length is not equal to the defined length of 7. + + * @returns An object that has the same properties as a [[Schema]]. + */ +export function decompress(schema: CompressedSchema): ISchema { + if (!Array.isArray(schema) || schema.length !== 6) { + throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Schema') + } + const decompressedSchema = { + identifier: schema[0], + schemaHash: schema[1], + controller: schema[2], + controllerSignature: schema[3], + space: schema[4], + schema: decompressSchema(schema[5]), } + verifyDataStructure(decompressedSchema) + return decompressedSchema } diff --git a/packages/modules/src/schema/TypeSchema.ts b/packages/modules/src/schema/Schema.types.ts similarity index 100% rename from packages/modules/src/schema/TypeSchema.ts rename to packages/modules/src/schema/Schema.types.ts diff --git a/packages/modules/src/schema/Schema.utils.ts b/packages/modules/src/schema/Schema.utils.ts deleted file mode 100644 index f021200b..00000000 --- a/packages/modules/src/schema/Schema.utils.ts +++ /dev/null @@ -1,255 +0,0 @@ -/** - * @packageDocumentation - * @module SchemaUtils - */ - -import type { HexString } from '@polkadot/util/types' -import type { - ISchema, - IContent, - CompressedSchema, - CompressedSchemaType, - SchemaWithoutId, -} from '@cord.network/types' -import { - jsonabc, - Crypto, - DataUtils, - SDKErrors, - JsonSchema, -} from '@cord.network/utils' -import { getOwner } from './Schema.chain.js' -import { SchemaModel, SchemaWrapperModel } from './TypeSchema.js' - -export function verifySchemaProperties( - object: Record, - schema: Record, - messages?: string[] -): boolean { - const validator = new JsonSchema.Validator(schema, '7', false) - if (schema.$id !== SchemaModel.$id) { - validator.addSchema(SchemaModel) - } - const result = validator.validate(object) - if (!result.valid && messages) { - result.errors.forEach((error: any) => { - messages.push(error.error) - }) - } - return result.valid -} - -export function verifySchema( - object: Record, - schema: Record -): boolean { - return verifySchemaProperties(object, schema) -} - -/** - * Verifies the structure of the provided IStream['contents'] with ISchema['schema']. - * - * @param streamContents IStream['contents'] to be verified against the schema. - * @param schema ISchema['schema'] to be verified against the [SchemaModel]. - * @throws [[ERROR_OBJECT_MALFORMED]] when schema does not correspond to the SchemaModel. - * - * @returns Boolean whether both streamContents and schema could be verified. - */ -export function verifyContentProperties( - contents: IContent['contents'], - schema: ISchema['schema'] -): boolean { - if (!verifySchema(schema, SchemaModel)) { - throw new SDKErrors.ERROR_OBJECT_MALFORMED() - } - return verifySchema(contents, schema) -} - -export async function verifyStored(schema: ISchema): Promise { - return typeof (await getOwner(schema.identifier)) === 'string' -} - -export async function verifyOwner(schema: ISchema): Promise { - const issuer = await getOwner(schema.identifier) - return issuer ? issuer === schema.controller : false -} - -export function getSchemaPropertiesForHash( - schemaType: SchemaWithoutId | ISchema['schema'] -): Partial { - const schemaWithoutId: Partial = - '$id' in schemaType - ? (schemaType as ISchema['schema']) - : (schemaType as SchemaWithoutId) - const shallowCopy = { ...schemaWithoutId } - delete shallowCopy.$id - return shallowCopy -} - -export function getHashForSchema( - schema: SchemaWithoutId | ISchema['schema'] -): HexString { - const prepSchema = getSchemaPropertiesForHash(schema) - return Crypto.hashObjectAsHexStr(prepSchema) -} - -/** - * Checks whether the input meets all the required criteria of an ISchema object. - * Throws on invalid input. - * - * @param input The potentially only partial ISchema. - * @throws [[ERROR_OBJECT_MALFORMED]] when input does not correspond to either it's schema, or the SchemaWrapperModel. - * @throws [[ERROR_HASH_MALFORMED]] when the input's hash does not match the hash calculated from ISchema's schema. - * @throws [[ERROR_MTYPE_OWNER_TYPE]] when the input's owner is not of type string or null. - * - */ -export function errorCheck(input: ISchema): void { - if (!verifySchema(input, SchemaWrapperModel)) { - throw new SDKErrors.ERROR_OBJECT_MALFORMED() - } - if (!input.schema || getHashForSchema(input.schema) !== input.schemaHash) { - throw new SDKErrors.ERROR_HASH_MALFORMED(input.schemaHash, 'Schema') - } - if ( - typeof input.controller === 'string' - ? !DataUtils.validateAddress(input.controller, 'Schema issuer') - : !(input.controller === null) - ) { - throw new SDKErrors.ERROR_SCHEMA_OWNER_TYPE() - } -} - -/** - * Compresses a [[Schema]] for storage and/or messaging. - * - * @param typeSchema A [[Schema]] object that will be sorted and stripped for messaging or storage. - * @throws [[ERROR_COMPRESS_OBJECT]] when any of the four required properties of the typeSchema are missing. - * - * @returns An ordered array of a [[SchemaType]] schema. - */ - -export function compressSchema( - typeSchema: ISchema['schema'] -): CompressedSchema { - if ( - !typeSchema.$id || - !typeSchema.$schema || - !typeSchema.$metadata || - !typeSchema.title || - !typeSchema.description || - !typeSchema.properties || - !typeSchema.type - ) { - throw new SDKErrors.ERROR_COMPRESS_OBJECT(typeSchema, 'TypeSchema') - } - const sortedTypeSchema = jsonabc.sortObj(typeSchema) - return [ - sortedTypeSchema.$id, - sortedTypeSchema.$schema, - sortedTypeSchema.$metadata, - sortedTypeSchema.title, - sortedTypeSchema.description, - sortedTypeSchema.properties, - sortedTypeSchema.type, - ] -} - -/** - * Decompresses a schema of a [[Schema]] from storage and/or message. - * - * @param typeSchema A compressed [[Schema]] array that is reverted back into an object. - * @throws [[ERROR_DECOMPRESSION_ARRAY]] when either the typeSchema is not an Array or it's length is not equal to the defined length of 5. - * - * @returns An object that has the same properties as a [[Schema]]. - */ - -export function decompressSchema( - typeSchema: CompressedSchema -): ISchema['schema'] { - if (!Array.isArray(typeSchema) || typeSchema.length !== 7) { - throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('typeSchema') - } - return { - $id: typeSchema[0], - $schema: typeSchema[1], - $metadata: typeSchema[2], - title: typeSchema[3], - description: typeSchema[4], - properties: typeSchema[5], - type: typeSchema[6], - } -} - -/** - * Compresses a [[Schema]] for storage and/or messaging. - * - * @param schema [[Schema]] object that will be sorted and stripped for messaging or storage. - * - * @returns An ordered array of a [[Schema]]. - */ - -export function compress(schema: ISchema): CompressedSchemaType { - errorCheck(schema) - return [ - schema.identifier, - schema.schemaHash, - schema.controller, - schema.controllerSignature, - schema.space, - compressSchema(schema.schema), - ] -} - -/** - * Decompresses a [[Schema]] from storage and/or message. - * - * @param schema A compressed [[Schema]] array that is reverted back into an object. - * @throws [[ERROR_DECOMPRESSION_ARRAY]] when either the schema is not an Array or it's length is not equal to the defined length of 4. - * - * @returns An object that has the same properties as a [[Schema]]. - */ - -export function decompress(schema: CompressedSchemaType): ISchema { - if (!Array.isArray(schema) || schema.length !== 6) { - throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Schema') - } - return { - identifier: schema[0], - schemaHash: schema[1], - controller: schema[2], - controllerSignature: schema[3], - space: schema[4], - schema: decompressSchema(schema[5]), - } -} - -/** - * Validates an array of [[Schema]s against a [[Stream]]. - * - * @param schema - A [[Schema]] that has nested [[Schema]]s inside. - * @param nestedSchemas - An array of [[Schema]]s. - * @param streamContents - The contents of a [[Stream]] to be validated. - * @param messages - * - * @returns Whether the contents is valid. - */ - -export function validateNestedSchemas( - schema: ISchema['schema'], - nestedSchemas: Array, - streamContents: Record, - messages?: string[] -): boolean { - const validator = new JsonSchema.Validator(schema, '7', false) - nestedSchemas.forEach((schema) => { - validator.addSchema(schema) - }) - validator.addSchema(SchemaModel) - const result = validator.validate(streamContents) - if (!result.valid && messages) { - result.errors.forEach((error) => { - messages.push(error.error) - }) - } - return result.valid -} diff --git a/packages/modules/src/schema/SchemaMetadata.ts b/packages/modules/src/schema/SchemaMetadata.ts deleted file mode 100644 index 069a987c..00000000 --- a/packages/modules/src/schema/SchemaMetadata.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @packageDocumentation - * @module SchemaMetadata - */ - -import type { ISchemaMetadata } from '@cord.network/types' -import { SDKErrors } from '@cord.network/utils' -import * as SchemaUtils from './Schema.utils.js' -import { MetadataModel } from './TypeSchema.js' - -export class SchemaMetadata implements ISchemaMetadata { - public id: ISchemaMetadata['id'] - public hash: ISchemaMetadata['hash'] - public metadata: ISchemaMetadata['metadata'] - - /** - * Instantiates a new SchemaMetadata. - * - * @param metadata [[ISchemaMetadata]] that is to be instantiated. - * @throws [[ERROR_OBJECT_MALFORMED]] when metadata is not verifiable with the MetadataModel. - * @returns The verified and instantiated [[SchemaMetadata]]. - */ - public constructor(metadata: ISchemaMetadata) { - if (!SchemaUtils.verifySchema(metadata, MetadataModel)) { - throw new SDKErrors.ERROR_OBJECT_MALFORMED() - } - this.metadata = metadata.metadata - this.id = metadata.id - this.hash = metadata.hash - } -} diff --git a/packages/modules/src/schema/index.ts b/packages/modules/src/schema/index.ts index 3cd22ffd..d4223b24 100644 --- a/packages/modules/src/schema/index.ts +++ b/packages/modules/src/schema/index.ts @@ -1,4 +1,3 @@ -export { Schema } from './Schema.js' -export * as SchemaUtils from './Schema.utils.js' -export { SchemaMetadata } from './SchemaMetadata.js' -export * as TypeSchema from './TypeSchema.js' +export * from './Schema.js' +export * from './Schema.chain.js' +export * as TypeSchema from './Schema.types.js' diff --git a/packages/modules/src/space/Space.chain.ts b/packages/modules/src/space/Space.chain.ts index 6c6dbd52..b3d67c4a 100644 --- a/packages/modules/src/space/Space.chain.ts +++ b/packages/modules/src/space/Space.chain.ts @@ -15,7 +15,7 @@ import { SPACE_PREFIX } from '@cord.network/types' import { DecoderUtils, Identifier } from '@cord.network/utils' import { ConfigService } from '@cord.network/config' import { ChainApiConnection } from '@cord.network/network' -import { SpaceDetails } from './Space.js' +import { Identity } from '../identity/Identity.js' const log = ConfigService.LoggingFactory.getLogger('Schema') @@ -29,118 +29,107 @@ const log = ConfigService.LoggingFactory.getLogger('Schema') export async function create(space: ISpace): Promise { const blockchain = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Create tx for 'space'`) - const tx: SubmittableExtrinsic = blockchain.api.tx.space.create( + return blockchain.api.tx.space.create( space.controller, space.spaceHash, space.controllerSignature ) - return tx } /** * TBD */ export async function archive( - spaceId: string, - controller: string, - txHash: string, - txSignature: string + space: ISpace, + controller: Identity ): Promise { + const { txSignature, txHash } = controller.signTx(space.spaceHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Revoking a schema with ID ${spaceId}`) - const tx: SubmittableExtrinsic = blockchain.api.tx.space.archive( + return blockchain.api.tx.space.archive( controller, - Identifier.getIdentifierKey(spaceId, SPACE_PREFIX), + Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), txHash, txSignature ) - return tx } /** * TBD */ export async function restore( - spaceId: string, - controller: string, - txHash: string, - txSignature: string + space: ISpace, + controller: Identity ): Promise { + const { txSignature, txHash } = controller.signTx(space.spaceHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Revoking a schema with ID ${spaceId}`) - const tx: SubmittableExtrinsic = blockchain.api.tx.space.restore( + return blockchain.api.tx.space.restore( controller, - Identifier.getIdentifierKey(spaceId, SPACE_PREFIX), + Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), txHash, txSignature ) - return tx } /** * TBD */ export async function authorise( - spaceId: string, - controller: string, - delegates: [string], - txHash: string, - txSignature: string + space: ISpace, + controller: Identity, + delegates: [string] ): Promise { + const { txSignature, txHash } = controller.signTx(space.spaceHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Adding a delagate to ${spaceId}`) - const tx: SubmittableExtrinsic = blockchain.api.tx.space.authorise( + return blockchain.api.tx.space.authorise( controller, - Identifier.getIdentifierKey(spaceId, SPACE_PREFIX), + Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), txHash, delegates, txSignature ) - return tx } /** * TBD */ export async function deauthorise( - spaceId: string, - controller: string, - delegates: [string], - txHash: string, - txSignature: string + space: ISpace, + controller: Identity, + delegates: [string] ): Promise { + const { txSignature, txHash } = controller.signTx(space.spaceHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Removing delagation from ${spaceId}`) - const tx: SubmittableExtrinsic = blockchain.api.tx.space.deauthorise( + return blockchain.api.tx.space.deauthorise( controller, - Identifier.getIdentifierKey(spaceId, SPACE_PREFIX), + Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), txHash, delegates, txSignature ) - return tx } /** * TBD */ export async function transfer( - spaceId: string, - controller: string, - transfer: string, - txHash: string, - txSignature: string + space: ISpace, + controller: Identity, + transfer: Identity['address'] ): Promise { + const { txSignature, txHash } = controller.signTx(space.spaceHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Revoking a schema with ID ${spaceId}`) - const tx: SubmittableExtrinsic = blockchain.api.tx.space.transfer( + return blockchain.api.tx.space.transfer( controller, - Identifier.getIdentifierKey(spaceId, SPACE_PREFIX), + Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), transfer, txHash, txSignature ) - return tx } export interface AnchoredSpaceDetails extends Struct { @@ -153,7 +142,7 @@ export interface AnchoredSpaceDetails extends Struct { function decodeSpace( encodedSpace: Option, spaceId: string -): SpaceDetails | null { +): ISpaceDetails | null { DecoderUtils.assertCodecIsType(encodedSpace, [ 'Option', ]) @@ -161,11 +150,11 @@ function decodeSpace( const anchoredSpace = encodedSpace.unwrap() const space: ISpaceDetails = { identifier: spaceId, - spaceHash: anchoredSpace.spaceHash.toString(), + spaceHash: anchoredSpace.spaceHash.toHex(), controller: anchoredSpace.controller.toString(), archived: anchoredSpace.archived.valueOf(), } - return SpaceDetails.fromSpaceDetails(space) + return space } return null } @@ -196,7 +185,7 @@ async function queryRaw( */ export async function queryhash( space_hash: string -): Promise { +): Promise { const encoded = await queryRawHash(space_hash) return decodeSpace(encoded, space_hash) } @@ -205,7 +194,7 @@ export async function queryhash( * @param identifier * @internal */ -export async function query(space_id: string): Promise { +export async function query(space_id: string): Promise { const spaceId: string = Identifier.getIdentifierKey(space_id, SPACE_PREFIX) const encoded = await queryRaw(spaceId) return decodeSpace(encoded, spaceId) diff --git a/packages/modules/src/space/Space.ts b/packages/modules/src/space/Space.ts index f1bc3126..ca040d20 100644 --- a/packages/modules/src/space/Space.ts +++ b/packages/modules/src/space/Space.ts @@ -8,231 +8,74 @@ * @preferred */ -import type { - ISpace, - ISpaceDetails, - SubmittableExtrinsic, -} from '@cord.network/types' -import { Identifier, Crypto, UUID } from '@cord.network/utils' -import { - query, - create, - authorise, - deauthorise, - archive, - restore, - transfer, -} from './Space.chain.js' -import * as SpaceUtils from './Space.utils.js' +import type { ISpace, ISpaceType } from '@cord.network/types' +import { Identifier, Crypto, DataUtils, SDKErrors } from '@cord.network/utils' import { SPACE_IDENTIFIER, SPACE_PREFIX } from '@cord.network/types' import { Identity } from '../identity/Identity.js' -export class Space implements ISpace { - /** - * [STATIC] [ASYNC] Queries the chain for a given space entry, by `identifier`. - * - * @param identifier - The identifier of the space. - * @returns A promise containing the [[SpaceDetails] or null. - */ - public static async query(identifier: string): Promise { - return query(Identifier.getIdentifierKey(identifier, SPACE_PREFIX)) - } +/** + * Checks whether the input meets all the required criteria of an [[ISpace]] object. + * Throws on invalid input. + * + * @param input The potentially only partial [[IStream]]. + * + */ +export function verifyDataStructure(input: ISpace): void { + if (!input.identifier) { + throw new SDKErrors.ERROR_SPACE_ID_NOT_PROVIDED() + } else DataUtils.validateId(input.identifier, 'Identifier') + + if (!input.spaceHash) { + throw new SDKErrors.ERROR_SPACE_HASH_NOT_PROVIDED() + } else DataUtils.validateHash(input.spaceHash, 'Space hash') - /** - * [STATIC] Creates a new [[Space]] from an [[ISpaceType]]. + if (!input.controller) { + throw new SDKErrors.ERROR_SPACE_OWNER_NOT_PROVIDED() + } else DataUtils.validateAddress(input.controller, 'Space controller') +} + +/** + * Creates a new [[Space]] from an [[ISpaceType]]. * * @param space The request from which the [[Space]] should be generated. * @param controller The identity of the [[Space]] controller. * @returns An instance of [[Space]]. */ - public static fromSpaceProperties( - space: ISpace['space'], - controller: Identity - ): Space { - const spaceHash = Crypto.hashObjectAsHexStr(space) - const spaceId = Identifier.getIdentifier( - spaceHash, - SPACE_IDENTIFIER, - SPACE_PREFIX - ) - return new Space({ - identifier: spaceId, - spaceHash: spaceHash, - space: { - ...space, - }, - controller: controller.address, - controllerSignature: controller.signStr(spaceHash), - }) - } - /** - * [STATIC] Custom Type Guard to determine input being of type ISpace using the SpaceUtils errorCheck. - * - * @param input The potentially only partial ISpace. - * @returns Boolean whether input is of type ISpace. - */ - public static isISpace(input: unknown): input is ISpace { - try { - SpaceUtils.errorCheck(input as ISpace) - } catch (error) { - return false - } - return true - } - - public identifier: ISpace['identifier'] - public spaceHash: ISpace['spaceHash'] - public controller: ISpace['controller'] - public controllerSignature: string - public space: ISpace['space'] - - public constructor(spaceInput: ISpace) { - SpaceUtils.errorCheck(spaceInput) - this.identifier = spaceInput.identifier - this.spaceHash = spaceInput.spaceHash - this.controller = spaceInput.controller - this.controllerSignature = spaceInput.controllerSignature - this.space = spaceInput.space - } - - /** - * [ASYNC] Stores the [[Space]] on the blockchain. - * - * @returns A promise of a unsigned SubmittableExtrinsic. - */ - public async create(): Promise { - return create(this) - } - - /** - * [ASYNC] Add delegates to a [[Space]]. - * - * @param controller The identity of the [[Space]] controller. - * @param delegates Delegates to be added. - * - * @returns A promise of a unsigned SubmittableExtrinsic. - */ - public async authorise( - controller: Identity, - delegates: [string] - ): Promise { - const txId = UUID.generate() - const spaceHash = this.spaceHash - const hashVal = { txId, delegates, spaceHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = controller.signStr(txHash) - return authorise( - this.identifier, - controller.address, - delegates, - txHash, - txSignature - ) - } - - /** - * [ASYNC] Remove delegates from a [[Space]]. - * - * @param controller The identity of the [[Space]] controller. - * @param delegates Delegates to be removed. - * - * @returns A promise of a unsigned SubmittableExtrinsic. - */ - public async deauthorise( - controller: Identity, - delegates: [string] - ): Promise { - const txId = UUID.generate() - const spaceHash = this.spaceHash - const hashVal = { txId, delegates, spaceHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = controller.signStr(txHash) - return deauthorise( - this.identifier, - controller.address, - delegates, - txHash, - txSignature - ) - } - - /** - * [ASYNC] Archive a [[Space]]. - * - * @param controller The identity of the [[Space]] controller. - * - * @returns A promise of a unsigned SubmittableExtrinsic. - */ - public async archive(controller: Identity): Promise { - const txId = UUID.generate() - const spaceHash = this.spaceHash - const hashVal = { txId, spaceHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = controller.signStr(txHash) - return archive(this.identifier, controller.address, txHash, txSignature) - } - - /** - * [ASYNC] Restore a [[Space]]. - * - * @param controller The identity of the [[Space]] controller. - * - * @returns A promise of a unsigned SubmittableExtrinsic. - */ - public async restore(controller: Identity): Promise { - const txId = UUID.generate() - const spaceHash = this.spaceHash - const hashVal = { txId, spaceHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = controller.signStr(txHash) - return restore(this.identifier, controller.address, txHash, txSignature) - } - - /** - * [ASYNC] Transfer a [[Space]]. - * - * @param controller The identity of the [[Space]] controller. - * @param transfer_to The address of the new [[Space]] controller. - * - * @returns A promise of a unsigned SubmittableExtrinsic. - */ - public async transfer( - controller: Identity, - transfer_to: Identity['address'] - ): Promise { - const txId = UUID.generate() - const spaceHash = this.spaceHash - const hashVal = { txId, spaceHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = controller.signStr(txHash) - return transfer( - this.identifier, - controller.address, - transfer_to, - txHash, - txSignature - ) +export function fromSpaceProperties( + spaceProperties: ISpaceType, + controller: Identity +): ISpace { + const spaceHash = Crypto.hashObjectAsHexStr(spaceProperties) + const spaceId = Identifier.getIdentifier( + spaceHash, + SPACE_IDENTIFIER, + SPACE_PREFIX + ) + const space = { + identifier: spaceId, + spaceHash: spaceHash, + space: { + ...spaceProperties, + }, + controller: controller.address, + controllerSignature: controller.signStr(spaceHash), } + verifyDataStructure(space) + return space } -export class SpaceDetails implements ISpaceDetails { - public static fromSpaceDetails(input: ISpaceDetails): SpaceDetails { - return new SpaceDetails(input) - } - /** - * Builds a new [[SpaceDetails]] instance. - */ - - public identifier: ISpaceDetails['identifier'] - public spaceHash: ISpaceDetails['spaceHash'] - public controller: ISpaceDetails['controller'] - public archived: ISpaceDetails['archived'] - - public constructor(details: ISpaceDetails) { - this.identifier = details.identifier - this.spaceHash = details.spaceHash - this.controller = details.controller - this.archived = details.archived +/** + * Custom Type Guard to determine input being of type ISpace using the SpaceUtils errorCheck. + * + * @param input The potentially only partial ISpace. + * @returns Boolean whether input is of type ISpace. + */ +export function isISpace(input: unknown): input is ISpace { + try { + verifyDataStructure(input as ISpace) + } catch (error) { + return false } + return true } diff --git a/packages/modules/src/space/Space.utils.ts b/packages/modules/src/space/Space.utils.ts deleted file mode 100644 index e286bae4..00000000 --- a/packages/modules/src/space/Space.utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @packageDocumentation - * @module SUtils - */ - -import type { ISpace } from '@cord.network/types' -import { DataUtils, SDKErrors } from '@cord.network/utils' - -/** - * Checks whether the input meets all the required criteria of an [[ISpace]] object. - * Throws on invalid input. - * - * @param input The potentially only partial [[IStream]]. - * - */ -export function errorCheck(input: ISpace): void { - if (!input.identifier) { - throw new SDKErrors.ERROR_SPACE_ID_NOT_PROVIDED() - } else DataUtils.validateId(input.identifier) - - if (!input.spaceHash) { - throw new SDKErrors.ERROR_SPACE_HASH_NOT_PROVIDED() - } else DataUtils.validateHash(input.spaceHash, 'Space hash') - - if (!input.controller) { - throw new SDKErrors.ERROR_SPACE_OWNER_NOT_PROVIDED() - } else DataUtils.validateAddress(input.controller, 'Space controller') -} diff --git a/packages/modules/src/space/index.ts b/packages/modules/src/space/index.ts index b0e2338f..7e780d1e 100644 --- a/packages/modules/src/space/index.ts +++ b/packages/modules/src/space/index.ts @@ -1,2 +1,2 @@ -export { Space } from './Space.js' -export * as SpaceUtils from './Space.utils.js' +export * from './Space.js' +export * from './Space.chain.js' diff --git a/packages/modules/src/stream/Stream.chain.ts b/packages/modules/src/stream/Stream.chain.ts index 9c21f30d..1d2ffd50 100644 --- a/packages/modules/src/stream/Stream.chain.ts +++ b/packages/modules/src/stream/Stream.chain.ts @@ -10,10 +10,11 @@ import { DecoderUtils, Identifier } from '@cord.network/utils' import type { AccountId, Hash } from '@polkadot/types/interfaces' import { ConfigService } from '@cord.network/config' import { ChainApiConnection } from '@cord.network/network' -import { StreamDetails } from './Stream.js' -import { STREAM_PREFIX } from '@cord.network/types' +import { STREAM_PREFIX, SPACE_PREFIX } from '@cord.network/types' +import { Identity } from '../identity/Identity.js' +import { HexString } from '@polkadot/util/types.js' -const log = ConfigService.LoggingFactory.getLogger('Credential') +const log = ConfigService.LoggingFactory.getLogger('Stream') /** * Generate the extrinsic to store the provided [[IStream]]. @@ -23,7 +24,7 @@ const log = ConfigService.LoggingFactory.getLogger('Credential') */ export async function create(stream: IStream): Promise { const blockchain = await ChainApiConnection.getConnectionOrConnect() - const tx: SubmittableExtrinsic = blockchain.api.tx.stream.create( + return blockchain.api.tx.stream.create( stream.issuer, stream.streamHash, stream.holder, @@ -32,7 +33,6 @@ export async function create(stream: IStream): Promise { stream.space, stream.issuerSignature ) - return tx } /** @@ -43,45 +43,39 @@ export async function create(stream: IStream): Promise { */ export async function update(stream: IStream): Promise { const blockchain = await ChainApiConnection.getConnectionOrConnect() - const tx: SubmittableExtrinsic = blockchain.api.tx.stream.update( + return blockchain.api.tx.stream.update( stream.identifier, stream.issuer, stream.streamHash, stream.issuerSignature, stream.space ) - return tx } /** * Generate the extrinsic to set the status of a given stream. The submitter can * be the owner of the stream or an authorized delegator of the linked schema. * - * @param streamIdentifier The stream Identifier. + * @param stream The stream to revoke * @param updater TThe transaction creator - * @param txHash Transaction Hash - * @param txSignature Transaction signature of the transaction creator - * @param [spaceIdentifier] Linked Space Identifier * @returns The [[SubmittableExtrinsic]] for the `revoke` call. */ export async function revoke( - streamIdentifier: string, - updater: string, - txHash: string, - txSignature: string, - spaceIdentifier?: string | null | undefined + stream: IStream, + updater: Identity ): Promise { + const { txSignature, txHash } = updater.signTx(stream.streamHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Revoking stream with ID ${streamIdentifier}`) - const space = spaceIdentifier ? spaceIdentifier : null - const tx: SubmittableExtrinsic = blockchain.api.tx.stream.revoke( - streamIdentifier, - updater, + log.debug(() => `Revoking stream with ID ${stream.identifier}`) + const space = Identifier.getIdentifierKey(stream.space, SPACE_PREFIX) || null + return blockchain.api.tx.stream.revoke( + Identifier.getIdentifierKey(stream.identifier, STREAM_PREFIX), + updater.address, txHash, txSignature, space ) - return tx } /** @@ -98,11 +92,10 @@ export async function removeSpaceStream( ): Promise { const blockchain = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Revoking stream with ID ${streamIdentifier}`) - const tx: SubmittableExtrinsic = blockchain.api.tx.stream.removeSpaceStream( + return blockchain.api.tx.stream.removeSpaceStream( streamIdentifier, spaceIdentifier ) - return tx } /** @@ -112,24 +105,23 @@ export async function removeSpaceStream( * @param streamIdentifier The stream Identifier. * @param creator The transaction creator * @param digestHash Hash of the presentation - * @param txSignature Transaction signature of the submitter * @returns The [[SubmittableExtrinsic]] for the `digest` call. */ export async function digest( streamIdentifier: string, - creator: string, - digestHash: string, - txSignature: string + creator: Identity, + digestHash: HexString ): Promise { + const txSignature = creator.signStr(digestHash) + const blockchain = await ChainApiConnection.getConnectionOrConnect() - log.debug(() => `Revoking stream with ID ${streamIdentifier}`) - const tx: SubmittableExtrinsic = blockchain.api.tx.stream.digest( + log.debug(() => `Adding a stream Digest ${streamIdentifier}`) + return blockchain.api.tx.stream.digest( streamIdentifier, creator, digestHash, txSignature ) - return tx } export interface AnchoredStreamDetails extends Struct { @@ -145,7 +137,7 @@ export interface AnchoredStreamDetails extends Struct { function decodeStream( encodedStream: Option, streamIdentifier: IContentStream['identifier'] -): StreamDetails | null { +): IStreamDetails | null { DecoderUtils.assertCodecIsType(encodedStream, [ 'Option', ]) @@ -162,7 +154,7 @@ function decodeStream( space: DecoderUtils.hexToString(anchoredStream.space.toString()) || null, revoked: anchoredStream.revoked.valueOf(), } - return StreamDetails.fromStreamDetails(stream) + return stream } return null } @@ -191,7 +183,7 @@ export async function queryRaw( */ export async function query( streamIdentifier: IContentStream['identifier'] -): Promise { +): Promise { const encoded = await queryRaw(streamIdentifier) return decodeStream(encoded, streamIdentifier) } diff --git a/packages/modules/src/stream/Stream.ts b/packages/modules/src/stream/Stream.ts index fb125555..9f64489e 100644 --- a/packages/modules/src/stream/Stream.ts +++ b/packages/modules/src/stream/Stream.ts @@ -1,297 +1,149 @@ -import type { SubmittableExtrinsic } from '@polkadot/api/promise/types' import type { IStream, - IStreamDetails, IContentStream, CompressedStream, } from '@cord.network/types' -import { Identity } from '../identity/Identity.js' -import { Crypto, UUID, SDKErrors, Identifier } from '@cord.network/utils' -import { - revoke, - removeSpaceStream, - query, - create, - update, - digest, -} from './Stream.chain.js' -import * as StreamUtils from './Stream.utils.js' +import { DataUtils, SDKErrors, Identifier } from '@cord.network/utils' +import { query } from './Stream.chain.js' import { SCHEMA_PREFIX, STREAM_PREFIX, SPACE_PREFIX } from '@cord.network/types' -export class Stream implements IStream { - /** - * [STATIC] [ASYNC] Queries the chain for a given stream entry, by `streamIdentifier`. - * - * @param streamIdentifier - The identifier of the stream. - * @returns A promise containing the [[Stream] or null. - * - */ - public static async query( - streamIdentifier: IContentStream['identifier'] - ): Promise { - return query(Identifier.getIdentifierKey(streamIdentifier, STREAM_PREFIX)) - } - - /** - * [STATIC] Builds an instance of [[Stream]], from a simple object with the same properties. - * Used for deserialization. - * - * @param streamInput - The base object from which to create the stream stream. - * @returns A new [[Stream]] object. - * - */ - public static fromStream(streamInput: IStream): Stream { - return new Stream(streamInput) - } - - /** - * [STATIC] Builds a new instance of an [[Stream]], from a complete set of input required for an stream. - * - * @param content - The base request for stream. - * @param creatorPublicIdentity - Public Identity of the issuer, used to anchor the underlying stream. - * @returns A new [[Stream]] object. - * - */ - public static fromContentStream(content: IContentStream): Stream { - const link = content.link - ? Identifier.getIdentifierKey(content.link, STREAM_PREFIX) - : null - const space = content.space - ? Identifier.getIdentifierKey(content.space, SPACE_PREFIX) - : null - return new Stream({ - identifier: Identifier.getIdentifierKey( - content.identifier, - STREAM_PREFIX - ), - streamHash: content.rootHash, - issuer: content.content.issuer, - holder: content.content.holder, - schema: Identifier.getIdentifierKey( - content.content.schema, - SCHEMA_PREFIX - ), - link, - space, - issuerSignature: content.issuerSignature, - }) - } - - /** - * [STATIC] Custom Type Guard to determine input being of type IStream using the StreamUtils errorCheck. - * - * @param input The potentially only partial IStream. - * @returns Boolean whether input is of type IStream. - */ - public static isIStream(input: unknown): input is IStream { - try { - StreamUtils.errorCheck(input as IStream) - } catch (error) { - return false - } - return true - } - - public identifier: IStream['identifier'] - public streamHash: IStream['streamHash'] - public issuer: IStream['issuer'] - public holder: IStream['holder'] | null - public schema: IStream['schema'] | null - public link: IStream['link'] | null - public space: IStream['space'] | null - public issuerSignature: IStream['issuerSignature'] | null - /** - * Builds a new [[Stream]] instance. - * - * @param stream - The base object from which to create the stream. - * - */ - public constructor(stream: IStream) { - StreamUtils.errorCheck(stream) - this.identifier = stream.identifier - this.streamHash = stream.streamHash - this.issuer = stream.issuer - this.holder = stream.holder - this.schema = stream.schema - this.link = stream.link - this.space = stream.space - this.issuerSignature = stream.issuerSignature - } - - /** - * [ASYNC] Prepares an extrinsic to store a stream on chain. - * @returns A promise containing the unsigned SubmittableExtrinsic (submittable transaction). - * - */ - public async create(): Promise { - return create(this) - } - - /** - * [ASYNC] Prepares an extrinsic to update a stream on chain. - * @returns A promise containing the unsigned SubmittableExtrinsic (submittable transaction). - * - */ - public async update(): Promise { - return update(this) - } - - /** - * [ASYNC] Prepares an extrinsic to revoked a stream on chain. - * - * @param controller - Identity of the transaction creator. - * @returns A promise containing the unsigned SubmittableExtrinsic (submittable transaction). - * - */ - public async revoke(controller: Identity): Promise { - const txId = UUID.generate() - const streamHash = this.streamHash - const hashVal = { txId, streamHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = StreamUtils.sign(controller, txHash) - return revoke( - this.identifier, - controller.address, - txHash, - txSignature, - this.space - ) - } - - /** - * [ASYNC] Prepares an extrinsic to remove a stream anchored on the chain. - * Note: This transaction can only be submitted by an owner of delegator of the space - * this stream is linked to. - * - * @returns A promise containing the unsigned SubmittableExtrinsic (submittable transaction). - * - */ - public async removeSpaceStream(): Promise { - if (!this.space) { - throw new SDKErrors.ERROR_SPACE_ID_NOT_PROVIDED() - } else return removeSpaceStream(this.identifier, this.space) - } - - public async digest( - issuer: Identity, - digestHash: string - ): Promise { - if (this.issuer !== issuer.address) { - throw new SDKErrors.ERROR_IDENTITY_MISMATCH() - } - const txId = UUID.generate() - const hashVal = { txId, digestHash } - const txHash = Crypto.hashObjectAsHexStr(hashVal) - const txSignature = StreamUtils.sign(issuer, txHash) - return digest( - Identifier.getIdentifierKey(this.identifier, STREAM_PREFIX), - issuer.address, - txHash, - txSignature - ) - } - - /** - * [STATIC] [ASYNC] Queries a stream from the chain and checks its validity. - * - * @param stream - The Stream to verify. - * @param streamIdentifier - The Identifier that corresponds to the stream. Defaults to the - * identifier for the stream onto which "verify" is called. - * @returns A promise containing whether the stream is valid. - * - */ - public static async checkValidity( - stream: IStream, - streamIdentifier: IStream['identifier'] = stream.identifier - ): Promise { - // Query stream by identifier. null if no stream is found on-chain for this identifier - const chainStream: StreamDetails | null = await Stream.query( - streamIdentifier - ) - //TODO - add holder checks - return !!( - chainStream !== null && - chainStream.issuer === stream.issuer && - chainStream.holder === stream.holder && - chainStream.streamHash === stream.streamHash && - !chainStream.revoked - ) - } - - public async checkValidity(): Promise { - return Stream.checkValidity(this) - } - - /** - * Compresses an [[Stream]] object. - * - * @returns An array that contains the same properties of an [[Stream]]. - */ - public compress(): CompressedStream { - return StreamUtils.compress(this) - } - - /** - * [STATIC] Builds an [[Stream]] from the compressed array. - * - * @param stream The [[CompressedStream]] that should get decompressed. - * @returns A new [[Stream]] object. - */ - public static decompress(stream: CompressedStream): Stream { - const decompressedStream = StreamUtils.decompress(stream) - return Stream.fromStream(decompressedStream) - } +/** + * Checks whether the input meets all the required criteria of an [[IStream]] object. + * Throws on invalid input. + * + * @param input The potentially only partial [[IStreamDetail]]. + * @throws [[ERROR_STREAM_ID_NOT_PROVIDED]], [[ERROR_STREAM_HASH_NOT_PROVIDED]], [[ERROR_STREAM_SCHEMA_ID_NOT_PROVIDED]] or [[ERROR_STREAM_OWNER_NOT_PROVIDED]] when input's streamIdentifier, streamHash, schemaIdentifier or issuer respectively do not exist. + * + */ +export function verifyDataStructure(input: IStream): void { + if (!input.identifier) { + throw new SDKErrors.ERROR_STREAM_ID_NOT_PROVIDED() + } else DataUtils.validateId(input.identifier, 'Stream Identiifier') + + if (!input.streamHash) { + throw new SDKErrors.ERROR_STREAM_HASH_NOT_PROVIDED() + } else DataUtils.validateHash(input.streamHash, 'Stream hash') + + if (!input.schema) { + throw new SDKErrors.ERROR_STREAM_SCHEMA_ID_NOT_PROVIDED() + } else DataUtils.validateId(input.schema, 'Schema Identifier') + + if (!input.issuer) { + throw new SDKErrors.ERROR_STREAM_OWNER_NOT_PROVIDED() + } else DataUtils.validateAddress(input.issuer, 'Stream controller') } -export class StreamDetails implements IStreamDetails { - public static fromStreamDetails(input: IStreamDetails): StreamDetails { - return new StreamDetails(input) - } - - public static async checkValidity( - stream: IStreamDetails, - identifier: IStream['identifier'] = stream.identifier - ): Promise { - // Query stream by stream identifier. null if no stream is found on-chain for this hash - const chainStream: StreamDetails | null = await Stream.query(identifier) - //TODO - add holder checks - return !!( - chainStream !== null && - chainStream.issuer === stream.issuer && - chainStream.streamHash === stream.streamHash && - !chainStream.revoked - ) - } +/** + * Builds a new instance of an [[Stream]], from a complete set of input required for an stream. + * + * @param content - The base request for stream. + * @param creatorPublicIdentity - Public Identity of the issuer, used to anchor the underlying stream. + * @returns A new [[Stream]] object. + * + */ +export function fromContentStream(content: IContentStream): IStream { + const link = content.link + ? Identifier.getIdentifierKey(content.link, STREAM_PREFIX) + : null + const space = content.space + ? Identifier.getIdentifierKey(content.space, SPACE_PREFIX) + : null + const stream = { + identifier: Identifier.getIdentifierKey(content.identifier, STREAM_PREFIX), + streamHash: content.rootHash, + issuer: content.content.issuer, + holder: content.content.holder, + schema: Identifier.getIdentifierKey(content.content.schema, SCHEMA_PREFIX), + link, + space, + issuerSignature: content.issuerSignature, + } + verifyDataStructure(stream) + return stream +} - public async checkValidity(): Promise { - return StreamDetails.checkValidity(this) - } +/** + * Custom Type Guard to determine input being of type IStream using the StreamUtils errorCheck. + * + * @param input The potentially only partial IStream. + * @returns Boolean whether input is of type IStream. + */ +export function isIStream(input: unknown): input is IStream { + try { + verifyDataStructure(input as IStream) + } catch (error) { + return false + } + return true +} - /** - * Builds a new [[Stream]] instance. - * - * @param stream - The base object from which to create the stream. - * - */ +/** + * Queries a stream from the chain and checks its validity. + * + * @param stream - The Stream to verify. + * @param streamIdentifier - The Identifier that corresponds to the stream. Defaults to the + * identifier for the stream onto which "verify" is called. + * @returns A promise containing whether the stream is valid. + * + */ +export async function checkValidity( + stream: IStream, + streamIdentifier: IStream['identifier'] = stream.identifier +): Promise { + verifyDataStructure(stream) + // Query stream by identifier. null if no stream is found on-chain for this identifier + const chainStream = await query(streamIdentifier) + return !!( + chainStream !== null && + chainStream.issuer === stream.issuer && + chainStream.holder === stream.holder && + chainStream.streamHash === stream.streamHash && + !chainStream.revoked + ) +} - public identifier: IStreamDetails['identifier'] - public streamHash: IStreamDetails['streamHash'] - public issuer: IStreamDetails['issuer'] - public holder: IStreamDetails['holder'] - public schema: IStreamDetails['schema'] - public link: IStreamDetails['link'] - public space: IStreamDetails['space'] - public revoked: IStreamDetails['revoked'] +/** + * Compresses a [[Stream]] object into an array for storage and/or messaging. + * + * @param stream A [[Stream]] object that will be sorted and stripped for messaging or storage. + * @returns An ordered array of an [[Stream]]. + */ +export function compress(stream: IStream): CompressedStream { + verifyDataStructure(stream) + return [ + stream.identifier, + stream.streamHash, + stream.issuer, + stream.holder, + stream.schema, + stream.link, + stream.space, + stream.issuerSignature, + ] +} - public constructor(details: IStreamDetails) { - // StreamUtils.errorCheck(details) - this.identifier = details.identifier - this.streamHash = details.streamHash - this.issuer = details.issuer - this.holder = details.holder - this.schema = details.schema - this.link = details.link - this.space = details.space - this.revoked = details.revoked - } +/** + * Decompresses a [[Stream]] from storage and/or message into an object. + * + * @param stream A compressed [[Stream]] array that is decompressed back into an object. + * @throws [[ERROR_DECOMPRESSION_ARRAY]] when the attestation is not an array or its length is not equal to 5. + * + * @returns An object that has the same properties as an [[Attestation]]. + */ +export function decompress(stream: CompressedStream): IStream { + if (!Array.isArray(stream) || stream.length !== 8) { + throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Stream') + } + const decompressedStream = { + identifier: stream[0], + streamHash: stream[1], + issuer: stream[2], + holder: stream[3], + schema: stream[4], + link: stream[5], + space: stream[6], + issuerSignature: stream[7], + } + verifyDataStructure(decompressedStream) + return decompressedStream } diff --git a/packages/modules/src/stream/Stream.utils.ts b/packages/modules/src/stream/Stream.utils.ts deleted file mode 100644 index ed6c173a..00000000 --- a/packages/modules/src/stream/Stream.utils.ts +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @packageDocumentation - * @module StreamUtils - */ - -import type { IStream, CompressedStream, Hash } from '@cord.network/types' -import { DataUtils, SDKErrors } from '@cord.network/utils' -import { Identity } from '../identity/Identity.js' - -/** - * Checks whether the input meets all the required criteria of an [[IStream]] object. - * Throws on invalid input. - * - * @param input The potentially only partial [[IStream]]. - * - */ -export function errorCheck(input: IStream): void { - if (!input.identifier) { - throw new SDKErrors.ERROR_STREAM_ID_NOT_PROVIDED() - } else DataUtils.validateId(input.identifier) - - if (!input.streamHash) { - throw new SDKErrors.ERROR_STREAM_HASH_NOT_PROVIDED() - } else DataUtils.validateHash(input.streamHash, 'Stream hash') - - if (!input.schema) { - throw new SDKErrors.ERROR_STREAM_SCHEMA_ID_NOT_PROVIDED() - } else DataUtils.validateId(input.schema) - - if (input.link) { - DataUtils.validateId(input.link) - } - - if (input.space) { - DataUtils.validateId(input.space) - } - - if (!input.issuer) { - throw new SDKErrors.ERROR_STREAM_OWNER_NOT_PROVIDED() - } else DataUtils.validateAddress(input.issuer, 'Stream controller') -} - -/** - * Compresses an [[Credential]] object into an array for storage and/or messaging. - * - * @param stream An [[Credential]] object that will be sorted and stripped for messaging or storage. - * - * @returns An ordered array of an [[Credential]]. - */ - -export function compress(stream: IStream): CompressedStream { - errorCheck(stream) - return [ - stream.identifier, - stream.streamHash, - stream.issuer, - stream.holder, - stream.schema, - stream.link, - stream.space, - stream.issuerSignature, - ] -} - -/** - * Decompresses an [[Credential]] from storage and/or message into an object. - * - * @param stream A compressed [[Credential]] array that is decompressed back into an object. - * @throws [[ERROR_DECOMPRESSION_ARRAY]] when the stream is not an array or its length is not equal to 5. - * - * @returns An object that has the same properties as an [[Credential]]. - */ - -export function decompress(stream: CompressedStream): IStream { - if (!Array.isArray(stream) || stream.length !== 8) { - throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Credential') - } - return { - identifier: stream[0], - streamHash: stream[1], - issuer: stream[2], - holder: stream[3], - schema: stream[4], - link: stream[5], - space: stream[6], - issuerSignature: stream[7], - } -} - -export function sign(identity: Identity, txHash: Hash): string { - return identity.signStr(txHash) -} diff --git a/packages/modules/src/stream/StreamDetails.utils.ts b/packages/modules/src/stream/StreamDetails.utils.ts deleted file mode 100644 index 5b331236..00000000 --- a/packages/modules/src/stream/StreamDetails.utils.ts +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @packageDocumentation - * @module StreamDetailUtils - */ - -import type { - IStreamDetails, - CompressedStreamDetails, -} from '@cord.network/types' -import { DataUtils, SDKErrors } from '@cord.network/utils' - -/** - * Checks whether the input meets all the required criteria of an [[IStreamDetail]] object. - * Throws on invalid input. - * - * @param input The potentially only partial [[IStreamDetail]]. - * - */ -export function errorCheck(input: IStreamDetails): void { - if (!input.identifier) { - throw new SDKErrors.ERROR_STREAM_ID_NOT_PROVIDED() - } else DataUtils.validateId(input.identifier) - - if (!input.streamHash) { - throw new SDKErrors.ERROR_STREAM_HASH_NOT_PROVIDED() - } else DataUtils.validateHash(input.streamHash, 'Stream hash') - - if (!input.schema) { - throw new SDKErrors.ERROR_STREAM_SCHEMA_ID_NOT_PROVIDED() - } else DataUtils.validateId(input.schema) - - if (!input.issuer) { - throw new SDKErrors.ERROR_STREAM_OWNER_NOT_PROVIDED() - } else DataUtils.validateAddress(input.issuer, 'Stream controller') -} - -/** - * Compresses an [[Credential]] object into an array for storage and/or messaging. - * - * @param stream An [[Credential]] object that will be sorted and stripped for messaging or storage. - * - * @returns An ordered array of an [[Credential]]. - */ - -export function compress(stream: IStreamDetails): CompressedStreamDetails { - errorCheck(stream) - return [ - stream.identifier, - stream.streamHash, - stream.issuer, - stream.holder, - stream.schema, - stream.link, - stream.space, - stream.revoked, - ] -} - -/** - * Decompresses an [[Credential]] from storage and/or message into an object. - * - * @param stream A compressed [[Credential]] array that is decompressed back into an object. - * @throws [[ERROR_DECOMPRESSION_ARRAY]] when the stream is not an array or its length is not equal to 5. - * - * @returns An object that has the same properties as an [[Credential]]. - */ - -export function decompress(stream: CompressedStreamDetails): IStreamDetails { - if (!Array.isArray(stream) || stream.length !== 8) { - throw new SDKErrors.ERROR_DECOMPRESSION_ARRAY('Stream') - } - return { - identifier: stream[0], - streamHash: stream[1], - issuer: stream[2], - holder: stream[3], - schema: stream[4], - link: stream[5], - space: stream[6], - revoked: stream[7], - } -} diff --git a/packages/modules/src/stream/index.ts b/packages/modules/src/stream/index.ts index dfa7d3fd..e07bffad 100644 --- a/packages/modules/src/stream/index.ts +++ b/packages/modules/src/stream/index.ts @@ -1,3 +1,2 @@ -export { Stream } from './Stream.js' -export * as StreamUtils from './Stream.utils.js' -export * as StreamDetailUtils from './StreamDetails.utils.js' +export * from './Stream.js' +export * from './Stream.chain.js' diff --git a/packages/network/src/chain/Chain.ts b/packages/network/src/chain/Chain.ts index 021d4a0a..a1619607 100644 --- a/packages/network/src/chain/Chain.ts +++ b/packages/network/src/chain/Chain.ts @@ -65,7 +65,7 @@ export class Chain implements IChainApi { return this.api.rpc.chain.subscribeNewHeads(listener) } /** - * [ASYNC] Signs the SubmittableExtrinsic with the given identity. + * Signs the SubmittableExtrinsic with the given identity. * * @param signer The [[Identity]] to sign the tx with. * @param tx The unsigned SubmittableExtrinsic. @@ -86,7 +86,7 @@ export class Chain implements IChainApi { } /** - * [ASYNC] Submits a signed SubmittableExtrinsic with imported function [[submitSignedTx]]. + * Submits a signed SubmittableExtrinsic with imported function [[submitSignedTx]]. * Handles recoverable errors if identity is provided by re-signing and re-sending the tx up to two times. * Uses [[parseSubscriptionOptions]] to provide complete potentially defaulted options to the called [[submitSignedTx]]. * @@ -115,7 +115,7 @@ export class Chain implements IChainApi { } /** - * [ASYNC] Retrieves the Nonce for Transaction signing for the specified account and increments the in accountNonces mapped Index. + * Retrieves the Nonce for Transaction signing for the specified account and increments the in accountNonces mapped Index. * * @param accountAddress The address of the identity that we retrieve the nonce for. * @returns Representation of the Tx nonce for the identity. @@ -142,7 +142,7 @@ export class Chain implements IChainApi { } /** - * [ASYNC] Re-signs the given SubmittableExtrinsic with an updated Nonce. + * Re-signs the given SubmittableExtrinsic with an updated Nonce. * * @param signer The [[Identity]] to re-sign the Tx with. * @param tx The tx with recoverable Error that failed. diff --git a/packages/network/src/chain/Chain.utils.ts b/packages/network/src/chain/Chain.utils.ts index 1accd0d1..ee0b9a24 100644 --- a/packages/network/src/chain/Chain.utils.ts +++ b/packages/network/src/chain/Chain.utils.ts @@ -61,7 +61,7 @@ export function parseSubscriptionOptions( } /** - * [ASYNC] Submits a signed SubmittableExtrinsic and attaches a callback to monitor the inclusion status of the transaction + * Submits a signed SubmittableExtrinsic and attaches a callback to monitor the inclusion status of the transaction * and possible errors in the execution of extrinsics. Returns a promise to that end which by default resolves upon * finalization and rejects any errors occur during submission or execution of extrinsics. This behavior can be adjusted via optional parameters. * @@ -138,7 +138,7 @@ export function isRecoverableTxError( } /** - * [ASYNC] Signs and submits the SubmittableExtrinsic with optional resolution and rejection criteria. + * Signs and submits the SubmittableExtrinsic with optional resolution and rejection criteria. * * @param tx The generated unsigned SubmittableExtrinsic to submit. * @param signer The [[Identity]] used to sign and potentially re-sign the tx. diff --git a/packages/types/src/ContentStream.ts b/packages/types/src/ContentStream.ts index dd01c5d8..62d6373d 100644 --- a/packages/types/src/ContentStream.ts +++ b/packages/types/src/ContentStream.ts @@ -23,7 +23,7 @@ export interface IContentStream { evidenceIds: ICredential[] link: string | null space: string | null - issuerSignature: string + issuerSignature: string & { challenge?: string } rootHash: Hash identifier: string issuanceDate: string diff --git a/packages/types/src/Identity.ts b/packages/types/src/Identity.ts index 9e46dada..44d2c8dd 100644 --- a/packages/types/src/Identity.ts +++ b/packages/types/src/Identity.ts @@ -7,6 +7,7 @@ import type { SubmittableExtrinsic } from '@polkadot/api/promise/types' import type { BoxKeyPair } from 'tweetnacl' import type { Index } from '@polkadot/types/interfaces' import { AnyNumber } from '@polkadot/types/types' +import { HexString } from '@polkadot/util/types.js' export const ACCOUNT_IDENTIFIER_PREFIX: string = 'id:cord:' @@ -24,3 +25,8 @@ export interface IIdentity { tip?: AnyNumber ): Promise } + +export interface SignProps { + txSignature: string + txHash: HexString +} diff --git a/packages/types/src/Schema.ts b/packages/types/src/Schema.ts index 54dd2522..27358910 100644 --- a/packages/types/src/Schema.ts +++ b/packages/types/src/Schema.ts @@ -42,7 +42,7 @@ export interface ISchema { schema: ISchemaType } -export type CompressedSchema = [ +export type CompressedSchemaType = [ ISchemaType['$id'], ISchemaType['$schema'], ISchemaType['$metadata'], @@ -52,13 +52,13 @@ export type CompressedSchema = [ ISchemaType['type'] ] -export type CompressedSchemaType = [ +export type CompressedSchema = [ ISchema['identifier'], ISchema['schemaHash'], ISchema['controller'], ISchema['controllerSignature'], ISchema['space'], - CompressedSchema + CompressedSchemaType ] export interface ISchemaDetails { diff --git a/packages/types/src/Space.ts b/packages/types/src/Space.ts index 2bf9b263..4739d7b5 100644 --- a/packages/types/src/Space.ts +++ b/packages/types/src/Space.ts @@ -2,6 +2,7 @@ * @packageDocumentation * @module ISpace */ +import { HexString } from '@polkadot/util/types.js' import type { IPublicIdentity } from './PublicIdentity.js' export const SPACE_IDENTIFIER: number = 13 @@ -14,7 +15,7 @@ export interface ISpaceType { export interface ISpace { identifier: string - spaceHash: string + spaceHash: HexString controller: IPublicIdentity['address'] controllerSignature: string space: ISpaceType diff --git a/packages/utils/src/DataUtils.ts b/packages/utils/src/DataUtils.ts index bcb5f8da..24809040 100644 --- a/packages/utils/src/DataUtils.ts +++ b/packages/utils/src/DataUtils.ts @@ -66,11 +66,10 @@ export function validateHash(hash: string, name: string): boolean { * * @returns Boolean whether the given hash string checks out against the Format. */ -export function validateId(id: string): boolean { +export function validateId(id: string, name: string): boolean { if (typeof id !== 'string') { - throw new SDKErrors.ERROR_HASH_TYPE() + throw new SDKErrors.ERROR_IDENTIFIER_TYPE() } - // const blake2bPattern = new RegExp('^[1S][a-km-zA-HJ-NP-Z1-9]${64}', 'i') if (!checkIdentifier(id)) { throw new SDKErrors.ERROR_ID_MALFORMED() } diff --git a/packages/utils/src/SDKErrors.ts b/packages/utils/src/SDKErrors.ts index d2590ee0..79cffee1 100644 --- a/packages/utils/src/SDKErrors.ts +++ b/packages/utils/src/SDKErrors.ts @@ -61,7 +61,9 @@ export class ERROR_SCHEMA_PROPERTIES_NOT_MATCHING extends SDKError { export class ERROR_UNSUPPORTED_KEY extends SDKError { constructor(keyType: string) { - super(`The provided key type "${keyType}" is currently not supported.`) + super( + `The provided key tyERROR_HASH_TYPEpe "${keyType}" is currently not supported.` + ) } } @@ -135,6 +137,12 @@ export class ERROR_CONTENT_NOT_PROVIDED extends SDKError { } } +export class ERROR_CONTENT_STREAM_NOT_PROVIDED extends SDKError { + constructor() { + super('Content stream missing') + } +} + export class ERROR_ADDRESS_TYPE extends SDKError { constructor() { super('Address of wrong type') @@ -147,6 +155,11 @@ export class ERROR_HASH_TYPE extends SDKError { } } +export class ERROR_IDENTIFIER_TYPE extends SDKError { + constructor() { + super('Identifier of wrong type') + } +} export class ERROR_HASH_MALFORMED extends SDKError { constructor(hash?: string, type?: string) { let message = '' diff --git a/packages/vc-export/src/exportToVerifiableCredential.ts b/packages/vc-export/src/exportToVerifiableCredential.ts index 07150f12..7888bce5 100644 --- a/packages/vc-export/src/exportToVerifiableCredential.ts +++ b/packages/vc-export/src/exportToVerifiableCredential.ts @@ -6,7 +6,7 @@ import { decodeAddress } from '@polkadot/keyring' import { u8aToHex } from '@polkadot/util' import type { AnyJson } from '@polkadot/types/types' -import { ContentUtils, Identity } from '@cord.network/modules' +import { Content, Identity } from '@cord.network/modules' import type { ICredential, ISchema } from '@cord.network/types' import { signatureVerify } from '@polkadot/util-crypto' import { @@ -66,7 +66,7 @@ export function fromCredential( ) // transform & annotate stream to be json-ld and VC conformant - const { credentialSubject } = ContentUtils.toJsonLD(content, false) as Record< + const { credentialSubject } = Content.toJsonLD(content, false) as Record< string, Record > diff --git a/packages/vc-export/src/index.ts b/packages/vc-export/src/index.ts index 84b41794..5c06b013 100644 --- a/packages/vc-export/src/index.ts +++ b/packages/vc-export/src/index.ts @@ -1,8 +1,10 @@ import '@polkadot/api-augment' -export * from './types.js' +import type * as types from './types.js' export * as constants from './constants.js' export * as verification from './verificationUtils.js' export * as presentation from './presentationUtils.js' export { fromCredential } from './exportToVerifiableCredential.js' export * as vcjsSuites from './vc-js/index.js' + +export type { types } diff --git a/packages/vc-export/src/vc-js/context/context.json b/packages/vc-export/src/vc-js/context/context.json index 691b7fe0..cb9b628a 100644 --- a/packages/vc-export/src/vc-js/context/context.json +++ b/packages/vc-export/src/vc-js/context/context.json @@ -25,8 +25,12 @@ "@context": { "@version": 1.1, "@protected": true, + "credentialStatus": { + "@id": "cordCred:credentialHash", + "@type": "@id" + }, "evidence": { - "@id": "cordCred:evidence", + "@id": "cred:evidence", "@type": "@id", "@container": "@set" }, diff --git a/packages/vc-export/src/vc-js/suites/CordAbstractSuite.ts b/packages/vc-export/src/vc-js/suites/CordAbstractSuite.ts index 15e3415e..bb75d7ac 100644 --- a/packages/vc-export/src/vc-js/suites/CordAbstractSuite.ts +++ b/packages/vc-export/src/vc-js/suites/CordAbstractSuite.ts @@ -77,6 +77,7 @@ export default abstract class CordAbstractSuite extends suites.LinkedDataProof { return type instanceof Array ? type.includes(this.type) : type === this.type } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public async createProof(options: { document: JsonLdObj purpose?: purposes.ProofPurpose diff --git a/packages/vc-export/src/verificationUtils.ts b/packages/vc-export/src/verificationUtils.ts index 0b71497d..f1bcc47a 100644 --- a/packages/vc-export/src/verificationUtils.ts +++ b/packages/vc-export/src/verificationUtils.ts @@ -6,7 +6,7 @@ // import { u8aConcat, hexToU8a, u8aToHex } from '@polkadot/util' import { signatureVerify, blake2AsHex } from '@polkadot/util-crypto' import jsonld from 'jsonld' -import { Stream, TypeSchema } from '@cord.network/modules' +import { Stream, Schema } from '@cord.network/modules' import { Crypto, JsonSchema, Identifier } from '@cord.network/utils' import { CORD_SIGNATURE_PROOF_TYPE, @@ -291,7 +291,7 @@ export function validateSchema( // there's no rule against additional properties, so we can just validate the ones that are there const validator = new JsonSchema.Validator(schema) - validator.addSchema(TypeSchema.SchemaModel) + validator.addSchema(Schema.TypeSchema.SchemaModel) const result = validator.validate(credential.credentialSubject) return { verified: result.valid, diff --git a/tsconfig.json b/tsconfig.json index 9fae67b5..41c4a2c3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,7 @@ "@cord.network/types": ["types/src"], "@cord.network/utils": ["utils/src"], "@cord.network/credential": ["credential/src"], + "@cord.network/vc-export": ["vc-export/src"], } }, "skipLibCheck": true From bc41850bb190cea1a970bfa35bf62243f8cc1052 Mon Sep 17 00:00:00 2001 From: Satish Mohan <54302767+smohan-dw@users.noreply.github.com> Date: Mon, 4 Jul 2022 11:42:28 +0530 Subject: [PATCH 7/8] Messaging and Signature updates (#17) * messaging demo updates * signatures and messaging * signatureProofs and demo updates * remove unused files and deps * deps update * vc deps update * remove unused modules * remove unnecessary const types * remove chain class and re-signing * ss58Format constant * message utils cleanup * build updates --- .eslintrc.js | 1 + .yarnrc.yml | 6 - README.md | 4 +- demo/src/bench.ts | 10 +- demo/src/demo-messaging.ts | 180 +- demo/src/demo-vc.ts | 108 +- demo/src/demo.ts | 58 +- demo/src/identifier.ts | 4 +- demo/src/stream-bench.ts | 6 +- demo/src/utils.ts | 82 - jest.config.js | 4 - package.json | 18 +- packages/messaging/src/Message.ts | 22 +- packages/messaging/src/Message.utils.ts | 100 +- packages/modules/src/balance/Balance.chain.ts | 12 +- .../src/contentstream/ContentStream.ts | 72 +- packages/modules/src/cordconfig/CordConfig.ts | 7 +- packages/modules/src/credential/Credential.ts | 7 +- packages/modules/src/did/Did.chain.ts | 65 - packages/modules/src/did/Did.ts | 255 -- packages/modules/src/did/Did.utils.ts | 166 -- packages/modules/src/did/index.ts | 9 - packages/modules/src/identity/Identity.ts | 42 +- .../modules/src/identity/PublicIdentity.ts | 186 -- packages/modules/src/identity/index.ts | 3 +- packages/modules/src/index.ts | 12 +- packages/modules/src/schema/Schema.chain.ts | 32 +- packages/modules/src/space/Space.chain.ts | 40 +- packages/modules/src/stream/Stream.chain.ts | 35 +- packages/modules/src/stream/Stream.ts | 6 +- packages/network/src/chain/Chain.ts | 275 +- packages/network/src/chain/Chain.utils.ts | 165 -- packages/network/src/chain/index.ts | 3 +- .../chainApiConnection/ChainApiConnection.ts | 20 +- packages/network/src/index.ts | 2 +- packages/{api => sdk}/LICENSE | 0 packages/{api => sdk}/package.json | 8 +- packages/{api => sdk}/src/index.ts | 4 +- packages/{api => sdk}/tsconfig.build.json | 0 packages/{api => sdk}/tsconfig.esm.json | 0 packages/{api => sdk}/webpack.config.js | 13 +- packages/types/src/Chain.ts | 2 + packages/types/src/ContentStream.ts | 10 +- packages/types/src/Message.ts | 99 +- packages/types/src/Presentation.ts | 20 - packages/types/src/PublicIdentity.ts | 7 + packages/types/src/SchemaMetadata.ts | 32 +- packages/types/src/Stream.ts | 4 +- packages/types/src/index.ts | 1 - packages/utils/src/Crypto.ts | 4 +- packages/utils/src/DataUtils.ts | 6 +- packages/utils/src/json-schema/dereference.ts | 2 +- packages/vc-export/package.json | 9 +- packages/vc-export/src/constants.ts | 4 +- .../src/exportToVerifiableCredential.ts | 48 +- packages/vc-export/src/index.ts | 2 +- packages/vc-export/src/presentationUtils.ts | 69 +- .../{vc-js => suites}/context/context.json | 0 .../src/{vc-js => suites}/context/index.ts | 0 .../src/{vc-js => suites}/documentLoader.ts | 2 +- .../examples/example-vc-old.json | 0 .../vc-export/src/{vc-js => suites}/index.ts | 0 .../suites/CordAbstractSuite.ts | 0 .../suites/CordAnchoredSuite.ts | 12 +- .../suites/CordIntegritySuite.ts | 0 .../suites/CordSelfSignatureSuite.ts} | 17 +- .../suites/suites/CordStreamSignatureSuite.ts | 66 + packages/vc-export/src/suites/suites/index.ts | 4 + .../{vc-js => suites}/types/crypto-ld.d.ts | 0 .../types/jsonld-signatures.d.ts | 0 .../src/{vc-js => suites}/types/vc.d.ts | 2 +- packages/vc-export/src/types.ts | 22 +- .../src/vc-js/suites/IntegritySuite.spec.ts | 152 -- packages/vc-export/src/vc-js/suites/index.ts | 3 - packages/vc-export/src/verificationUtils.ts | 85 +- tsconfig.build.json | 14 +- tsconfig.json | 8 +- typedoc.js | 26 - yarn.lock | 2322 +++++++---------- 79 files changed, 1865 insertions(+), 3231 deletions(-) delete mode 100644 demo/src/utils.ts delete mode 100644 packages/modules/src/did/Did.chain.ts delete mode 100644 packages/modules/src/did/Did.ts delete mode 100644 packages/modules/src/did/Did.utils.ts delete mode 100644 packages/modules/src/did/index.ts delete mode 100644 packages/modules/src/identity/PublicIdentity.ts delete mode 100644 packages/network/src/chain/Chain.utils.ts rename packages/{api => sdk}/LICENSE (100%) rename packages/{api => sdk}/package.json (92%) rename packages/{api => sdk}/src/index.ts (77%) rename packages/{api => sdk}/tsconfig.build.json (100%) rename packages/{api => sdk}/tsconfig.esm.json (100%) rename packages/{api => sdk}/webpack.config.js (81%) delete mode 100644 packages/types/src/Presentation.ts rename packages/vc-export/src/{vc-js => suites}/context/context.json (100%) rename packages/vc-export/src/{vc-js => suites}/context/index.ts (100%) rename packages/vc-export/src/{vc-js => suites}/documentLoader.ts (90%) rename packages/vc-export/src/{vc-js => suites}/examples/example-vc-old.json (100%) rename packages/vc-export/src/{vc-js => suites}/index.ts (100%) rename packages/vc-export/src/{vc-js => suites}/suites/CordAbstractSuite.ts (100%) rename packages/vc-export/src/{vc-js => suites}/suites/CordAnchoredSuite.ts (87%) rename packages/vc-export/src/{vc-js => suites}/suites/CordIntegritySuite.ts (100%) rename packages/vc-export/src/{vc-js/suites/CordSignatureSuite.ts => suites/suites/CordSelfSignatureSuite.ts} (77%) create mode 100644 packages/vc-export/src/suites/suites/CordStreamSignatureSuite.ts create mode 100644 packages/vc-export/src/suites/suites/index.ts rename packages/vc-export/src/{vc-js => suites}/types/crypto-ld.d.ts (100%) rename packages/vc-export/src/{vc-js => suites}/types/jsonld-signatures.d.ts (100%) rename packages/vc-export/src/{vc-js => suites}/types/vc.d.ts (95%) delete mode 100644 packages/vc-export/src/vc-js/suites/IntegritySuite.spec.ts delete mode 100644 packages/vc-export/src/vc-js/suites/index.ts delete mode 100644 typedoc.js diff --git a/.eslintrc.js b/.eslintrc.js index 7150849c..cb3dbaee 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -36,6 +36,7 @@ module.exports = { devDependencies: [ '**/*.test.ts', '**/*.spec.ts', + '**/__integrationtests__/*', '**/webpack.config.js', ], }, diff --git a/.yarnrc.yml b/.yarnrc.yml index 82e3de5f..122b1648 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1,9 +1,5 @@ enableColors: true -enableInlineBuilds: true - -enableProgressBars: true - nodeLinker: node-modules npmPublishAccess: public @@ -11,8 +7,6 @@ npmPublishAccess: public npmPublishRegistry: 'https://registry.npmjs.org' plugins: - - path: .yarn/plugins/@ojkelly/plugin-all.cjs - spec: 'https://yarn.build/latest' - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs spec: '@yarnpkg/plugin-interactive-tools' - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs diff --git a/README.md b/README.md index 5e3c42b8..4e055662 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,13 @@ Provides a collection of classes and methods to interact with the Cord network. Install the SDK by running the following commands: ```bash -npm install @cord.network/api +npm install @cord.network/sdk ``` Or with `yarn`: ```bash -yarn add @cord.network/api +yarn add @cord.network/sdk ``` ## Build to see changes diff --git a/demo/src/bench.ts b/demo/src/bench.ts index 71e7886d..ebb9ee7d 100644 --- a/demo/src/bench.ts +++ b/demo/src/bench.ts @@ -1,11 +1,14 @@ -import * as cord from '@cord.network/api' -import * as utils from './utils' +import * as cord from '@cord.network/sdk' import BN from 'bn.js' import moment from 'moment' import Keyring from '@polkadot/keyring' const amount: BN = new BN('1') +function delay(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)) +} + async function main() { await cord.init({ address: 'ws://127.0.0.1:9944' }) @@ -58,6 +61,7 @@ async function main() { } catch (e: any) { console.log(e.errorCode, '-', e.message) } + delay(4000) } let ancEndTime = moment() @@ -93,7 +97,7 @@ async function main() { txCount / batchAncDuration.as('seconds') ).toFixed(0)} ` ) - await utils.waitForEnter('\n⏎ Press Enter to continue..') + delay(4000) } main() diff --git a/demo/src/demo-messaging.ts b/demo/src/demo-messaging.ts index 1ff6b7d2..0b5ecf13 100644 --- a/demo/src/demo-messaging.ts +++ b/demo/src/demo-messaging.ts @@ -1,6 +1,5 @@ -import * as Cord from '@cord.network/api' +import * as Cord from '@cord.network/sdk' import { UUID } from '@cord.network/utils' -// import { SCHEMA_PREFIX, SPACE_PREFIX } from '@cord.network/types' async function main() { await Cord.init({ address: 'ws://127.0.0.1:9944' }) @@ -50,14 +49,10 @@ async function main() { console.dir(newSpace, { depth: null, colors: true }) try { - await Cord.ChainUtils.signAndSubmitTx( - spaceCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) + await Cord.Chain.signAndSubmitTx(spaceCreationExtrinsic, entityIdentity, { + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, + }) console.log('✅ Space created!') } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -81,14 +76,10 @@ async function main() { console.dir(newSchema, { depth: null, colors: true }) try { - await Cord.ChainUtils.signAndSubmitTx( - schemaCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) + await Cord.Chain.signAndSubmitTx(schemaCreationExtrinsic, entityIdentity, { + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, + }) console.log('✅ Schema created!') } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -96,8 +87,8 @@ async function main() { // Step 2: Create a new Stream console.log(`\n❄️ Stream Creation `) - console.log(`🔗 ${newSpace.identifier} `) - console.log(`🔗 ${newSchema.identifier} `) + console.log(`🔗 ${newSpace.identifier} `) + console.log(`🔗 ${newSchema.identifier} `) const content = { name: 'Alice', @@ -127,107 +118,110 @@ async function main() { console.dir(newStream, { depth: null, colors: true }) try { - await Cord.ChainUtils.signAndSubmitTx( - streamCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) + await Cord.Chain.signAndSubmitTx(streamCreationExtrinsic, entityIdentity, { + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, + }) console.log('✅ Stream created!') } catch (e: any) { console.log(e.errorCode, '-', e.message) } - // await utils.waitForEnter('\n⏎ Press Enter to continue..') - // Step 7: Credential exchange via messaging console.log(`\n\n📩 Credential Exchange - Selective Disclosure (Verifier)`) console.log(`🔑 Verifier Address: ${verifierIdentity.address}`) - const purpose = 'Account Opening Request' - const validUntil = Date.now() + 864000000 - const relatedData = true - const messageBodyForClaimer: Cord.MessageBody = { + const msgChallenge = UUID.generate() + const messageBodyForHolder: Cord.MessageBody = { type: Cord.Message.BodyType.REQUEST_CREDENTIAL, - content: { schemas: [{ schemaIdentifier: schemaStream.schema }] }, + content: { + schemas: [ + { + schemaIdentifier: schemaStream.schema, + trustedIssuers: [schemaStream.issuer], + requiredProperties: ['name', 'age'], + }, + ], + challenge: msgChallenge, + }, } - const messageForClaimer = new Kilt.Message( - messageBodyForClaimer, - verifierLightDID.did, - claimerLightDid.did + const messageForHolder = new Cord.Message( + messageBodyForHolder, + verifierIdentity, + holderIdentity.getPublicIdentity() ) - const { session, message: message } = - cord.Exchange.Request.newRequestBuilder() - .requestPresentation({ - id: schemaStream.schemaId, - properties: ['name', 'age'], - }) - .finalize( - purpose, - verifierIdentity, - holderIdentity.getPublicIdentity(), - validUntil, - relatedData - ) - console.log(`\n📧 Selective Disclosure Request`) - console.dir(message, { depth: null, colors: true }) + console.dir(messageForHolder, { depth: null, colors: true }) - const chainStream = await cord.Stream.query(newStream.streamId) + const chainStream = await Cord.Stream.query(newStream.identifier) if (chainStream) { - let credential: cord.Credential - credential = cord.Credential.fromMarkContentStream( + let credential: Cord.ICredential + credential = await Cord.Credential.fromRequestAndStream( newStreamContent, chainStream ) - const presentation = cord.Exchange.Share.createPresentation( - holderIdentity, - message, - verifierIdentity.getPublicIdentity(), - [credential], - { - showAttributes: message.body.content[0].requiredProperties, - signer: holderIdentity, - request: message.body.request, - } - ) + const presentation = await Cord.Credential.createPresentation({ + credential, + selectedAttributes: + messageForHolder.body.content['schemas'][0]['requiredProperties'], + signer: holderIdentity, + challenge: messageForHolder.body.content['challenge'], + }) - const { verified } = await cord.Exchange.Verify.verifyPresentation( - presentation, - session + const messageBodyForRequestor: Cord.MessageBody = { + type: Cord.Message.BodyType.SUBMIT_CREDENTIAL, + content: [presentation], + } + + const messageForRequestor = new Cord.Message( + messageBodyForRequestor, + verifierIdentity, + holderIdentity.getPublicIdentity() ) - console.log(`\n📧 Received Credential `) - console.dir(presentation, { depth: null, colors: true }) + console.log(`\n📧 Selective Disclosure Response`) + console.dir(messageForRequestor, { depth: null, colors: true }) + console.log(`\n❄️ Verifiy Presentation`) - let result = vcPresentation.verifiableCredential.proof.forEach(function ( - proof: any + if ( + messageForRequestor.body.type === Cord.Message.BodyType.SUBMIT_CREDENTIAL ) { - console.log(proof) - if (proof.type === VCUtils.constants.CORD_ANCHORED_PROOF_TYPE) - VCUtils.verification.verifyStreamProof( - vcPresentation.verifiableCredential, - proof + const claims = messageForRequestor.body.content + + // Using detail verification model to capture results seperately + // await Cord.Credential.verify(claims[0], msgChallenge) + // is the one - line alternative + const credIntegrity = await Cord.Credential.verifyDataIntegrity(claims[0]) + const credSignature = await Cord.ContentStream.verifySignature( + claims[0].request, + { challenge: msgChallenge } + ) + const credValidity = await Cord.Stream.checkValidity(claims[0].stream) + if (credIntegrity && credSignature && credValidity) { + console.log( + '✅', + 'Credential-Integity', + credIntegrity, + '✧ Credential-Signature', + credSignature, + '✧ Credential-Validity', + credValidity ) - }) - console.log(result) - if (result && result.verified) { - console.log( - `Name of the crook: ${vcPresentation.verifiableCredential.credentialSubject.name}` - ) // prints 'Billy The Kid' - // console.log( - // `Reward: ${vcPresentation.verifiableCredential.credentialSubject.}` - // ) // undefined + } else { + console.log( + `❌`, + 'Credential-Integity', + credIntegrity, + '| Credential-Signature', + credSignature, + '| Credential-Validity', + credValidity + ) + } } - - console.log('🔍 All valid? ', verified) } else { console.log(`\n❌ Credential not found `) } - - // await utils.waitForEnter('\n⏎ Press Enter to continue..') } main() .then(() => console.log('\nBye! 👋 👋 👋 ')) diff --git a/demo/src/demo-vc.ts b/demo/src/demo-vc.ts index af924ea9..af7550cc 100644 --- a/demo/src/demo-vc.ts +++ b/demo/src/demo-vc.ts @@ -1,4 +1,4 @@ -import * as Cord from '@cord.network/api' +import * as Cord from '@cord.network/sdk' import { UUID } from '@cord.network/utils' import type { VerifiableCredential } from '@cord.network/vc-export/src/types.js' import * as VCUtils from '@cord.network/vc-export' @@ -48,14 +48,10 @@ async function main() { let spaceCreationExtrinsic = await Cord.Space.create(newSpace) try { - await Cord.ChainUtils.signAndSubmitTx( - spaceCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) + await Cord.Chain.signAndSubmitTx(spaceCreationExtrinsic, entityIdentity, { + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, + }) console.log(`✅ ${newSpace.identifier} created!`) } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -77,14 +73,10 @@ async function main() { let schemaCreationExtrinsic = await Cord.Schema.create(newSchema) try { - await Cord.ChainUtils.signAndSubmitTx( - schemaCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) + await Cord.Chain.signAndSubmitTx(schemaCreationExtrinsic, entityIdentity, { + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, + }) console.log(`✅ ${newSchema.identifier} created!`) } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -92,8 +84,8 @@ async function main() { // Step 4: Create a new Stream console.log(`\n❄️ Stream Creation `) - console.log(`🔗 ${newSpace.identifier} `) - console.log(`🔗 ${newSchema.identifier} `) + console.log(`🔗 ${newSpace.identifier} `) + console.log(`🔗 ${newSchema.identifier} `) const content = { name: 'Alice', @@ -123,20 +115,16 @@ async function main() { console.dir(newStream, { depth: null, colors: true }) try { - await Cord.ChainUtils.signAndSubmitTx( - streamCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) + await Cord.Chain.signAndSubmitTx(streamCreationExtrinsic, entityIdentity, { + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, + }) console.log('✅ Stream created!') } catch (e: any) { console.log(e.errorCode, '-', e.message) } - // Step 4: Verifiable Credentials & Presentation + // Step 5: Verifiable Credential & Presentation console.log(`\n❄️ Verifiable Credentials & Presentation `) console.log(`🔗 ${newStream.identifier} `) const stream = await Cord.Stream.query(newStream.identifier) @@ -146,15 +134,18 @@ async function main() { console.log(`Stream not anchored on CORD`) } else { credential = Cord.Credential.fromRequestAndStream(newStreamContent, stream) - const VC = VCUtils.fromCredential(credential, holderIdentity, newSchema) + const VC = VCUtils.fromCredential(credential, newSchema) console.dir(VC, { depth: null, colors: true }) console.log('✅ Verifiable Credential created!') console.log(`\n❄️ Verifiable Presentation - Selective Disclosure `) const sharedCredential = JSON.parse(JSON.stringify(VC)) + const vcChallenge = UUID.generate() const vcPresentation = await VCUtils.presentation.makePresentation( sharedCredential, - ['name', 'country'] + ['name', 'country'], + holderIdentity, + vcChallenge ) console.dir(vcPresentation, { depth: null, colors: true }) console.log('✅ Verifiable Presentation created!') @@ -164,10 +155,11 @@ async function main() { const VCfromPresentation = vcPresentation.verifiableCredential as VerifiableCredential - const signatureResult = await VCUtils.verification.verifyCordSignatureProof( - VCfromPresentation, - VCfromPresentation.proof[0] - ) + const streamSignatureResult = + await VCUtils.verification.verifyStreamSignatureProof( + VCfromPresentation, + VCfromPresentation.proof[0] + ) const streamResult = await VCUtils.verification.verifyStreamProof( VCfromPresentation, VCfromPresentation.proof[1] @@ -177,34 +169,48 @@ async function main() { VCfromPresentation, VCfromPresentation.proof[2] ) + const selfSignatureResult = + await VCUtils.verification.verifySelfSignatureProof( + VCfromPresentation, + vcPresentation.proof[0], + vcChallenge + ) + if ( - (!streamResult && !streamResult['verified']) || - (!digestResult && !digestResult['verified']) || - (!signatureResult && !signatureResult['verified']) + streamResult && + streamResult['verified'] && + digestResult && + digestResult['verified'] && + streamSignatureResult && + streamSignatureResult['verified'] && + selfSignatureResult && + selfSignatureResult['verified'] ) { console.log( - `❌ Verification failed `, - 'Signature-Proof', - signatureResult['verified'], - ', Stream-Proof', + '✅', + 'Stream-Signature-Proof', + streamSignatureResult['verified'], + '✧ Stream-Proof', streamResult['verified'], - ', Digest-Proof', - digestResult['verified'] + '✧ Digest-Proof', + digestResult['verified'], + '✧ Self-Signature-Proof', + selfSignatureResult['verified'] ) } else { console.log( - '✅ All valid? ', - 'Signature-Proof', - signatureResult['verified'], - ', Stream-Proof', + `❌`, + 'Stream-Signature-Proof', + streamSignatureResult['verified'], + '✧ Stream-Proof', streamResult['verified'], - ', Digest-Proof', - digestResult['verified'] + '✧ Digest-Proof', + digestResult['verified'], + '✧ Self-Signature-Proof', + selfSignatureResult['verified'] ) } } - - // await utils.waitForEnter('\n⏎ Press Enter to continue..') } main() .then(() => console.log('\nBye! 👋 👋 👋 ')) diff --git a/demo/src/demo.ts b/demo/src/demo.ts index c1feb264..5bd26717 100644 --- a/demo/src/demo.ts +++ b/demo/src/demo.ts @@ -1,4 +1,4 @@ -import * as Cord from '@cord.network/api' +import * as Cord from '@cord.network/sdk' import { UUID } from '@cord.network/utils' async function main() { @@ -49,14 +49,10 @@ async function main() { console.dir(newSpace, { depth: null, colors: true }) try { - await Cord.ChainUtils.signAndSubmitTx( - spaceCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) + await Cord.Chain.signAndSubmitTx(spaceCreationExtrinsic, entityIdentity, { + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, + }) console.log('✅ Space created!') } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -83,14 +79,10 @@ async function main() { }) try { - await Cord.ChainUtils.signAndSubmitTx( - schemaCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) + await Cord.Chain.signAndSubmitTx(schemaCreationExtrinsic, entityIdentity, { + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, + }) console.log('✅ Schema created!') } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -98,8 +90,8 @@ async function main() { // Step 4: Create a new Stream console.log(`\n❄️ Stream Creation `) - console.log(`🔗 ${newSpace.identifier} `) - console.log(`🔗 ${newSchema.identifier} `) + console.log(`🔗 ${newSpace.identifier} `) + console.log(`🔗 ${newSchema.identifier} `) const content = { name: 'Alice', @@ -129,14 +121,10 @@ async function main() { console.dir(newStream, { depth: null, colors: true }) try { - await Cord.ChainUtils.signAndSubmitTx( - streamCreationExtrinsic, - entityIdentity, - { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, - } - ) + await Cord.Chain.signAndSubmitTx(streamCreationExtrinsic, entityIdentity, { + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, + }) console.log('✅ Stream created!') } catch (e: any) { console.log(e.errorCode, '-', e.message) @@ -158,12 +146,12 @@ async function main() { console.dir(updateStream, { depth: null, colors: true }) try { - await Cord.ChainUtils.signAndSubmitTx( + await Cord.Chain.signAndSubmitTx( updateStreamCreationExtrinsic, entityIdentity, { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, } ) console.log('✅ Stream updated!') @@ -185,7 +173,7 @@ async function main() { console.log(`Is Alices's credential valid? ${isCredentialValid}`) } - // Step 8: Revoke a Stream + // Step 7: Revoke a Stream console.log(`\n❄️ Revoke - ${updateStreamContent.identifier} `) let revokeStream = updateStream @@ -195,12 +183,12 @@ async function main() { ) try { - await Cord.ChainUtils.signAndSubmitTx( + await Cord.Chain.signAndSubmitTx( revokeStreamCreationExtrinsic, entityIdentity, { - resolveOn: Cord.ChainUtils.IS_IN_BLOCK, - rejectOn: Cord.ChainUtils.IS_ERROR, + resolveOn: Cord.Chain.IS_IN_BLOCK, + rejectOn: Cord.Chain.IS_ERROR, } ) console.log(`✅ Alices's credential revoked!`) @@ -208,7 +196,7 @@ async function main() { console.log(e.errorCode, '-', e.message) } - // Step 9: Re-verify a revoked Credential + // Step 8: Re-verify a revoked Credential console.log(`\n❄️ Verify - ${updateStreamContent.identifier} `) const revstream = await Cord.Stream.query(updateStream.identifier) if (!revstream) { diff --git a/demo/src/identifier.ts b/demo/src/identifier.ts index 0cd1cdd9..734981f4 100644 --- a/demo/src/identifier.ts +++ b/demo/src/identifier.ts @@ -1,5 +1,5 @@ -import * as Cord from '@Cord.network/api' -import { UUID } from '@Cord.network/utils' +import * as Cord from '@cord.network/sdk' +import { UUID } from '@cord.network/utils' import type { HexString } from '@polkadot/util/types' import { base58Decode, base58Encode, blake2AsU8a } from '@polkadot/util-crypto' diff --git a/demo/src/stream-bench.ts b/demo/src/stream-bench.ts index ad939bac..feb56e5f 100644 --- a/demo/src/stream-bench.ts +++ b/demo/src/stream-bench.ts @@ -1,6 +1,5 @@ -import * as Cord from '@Cord.network/api' -import * as utils from './utils' -import { UUID } from '@Cord.network/utils' +import * as Cord from '@cord.network/sdk' +import { UUID } from '@cord.network/utils' import moment from 'moment' import Keyring from '@polkadot/keyring' @@ -160,7 +159,6 @@ async function main() { txCount / batchAncDuration.as('seconds') ).toFixed(0)} ` ) - await utils.waitForEnter('\n⏎ Press Enter to continue..') } main() diff --git a/demo/src/utils.ts b/demo/src/utils.ts deleted file mode 100644 index a626c3dd..00000000 --- a/demo/src/utils.ts +++ /dev/null @@ -1,82 +0,0 @@ -import * as cord from '@cord.network/api' - -import type { KeyringPair } from '@polkadot/keyring/types' - -const AUTH_SEED = - '0x0000000000000000000000000000000000000000000000000000000000000000' -const ENC_SEED = - '0x0000000000000000000000000000000000000000000000000000000000000001' -const ATT_SEED = - '0x0000000000000000000000000000000000000000000000000000000000000002' -const DEL_SEED = - '0x0000000000000000000000000000000000000000000000000000000000000003' - -export function generate_ed25519_authentication_key(): KeyringPair { - return cord.Identity.buildFromSeedString(AUTH_SEED, { - signingKeyPairType: 'ed25519', - }).signKeyringPair -} -export function get_ed25519_authentication_key_id(): string { - return '0xed52d866f75a5e57641b6ca68a7618312564de787cda3d0664d15471ec1d12b5' -} - -export function generate_sr25519_authentication_key(): KeyringPair { - return cord.Identity.buildFromSeedString(AUTH_SEED, { - signingKeyPairType: 'sr25519', - }).signKeyringPair -} -export function get_sr25519_authentication_key_id(): string { - return '0x1eb4134f8acf477337de6b208c1044b19b9ac09e20e4c6f6c1561d1cef6cad8b' -} - -export function generate_encryption_key(): nacl.BoxKeyPair { - return cord.Identity.buildFromSeedString(ENC_SEED, { - signingKeyPairType: 'ed25519', - }).boxKeyPair -} -export function get_encryption_key_id(): string { - return '0xd8752aed376a12f17ee8c5e06aa19df1cea571da1c9241fc50c330504513b350' -} - -export function generate_ed25519_anchor_key(): KeyringPair { - return cord.Identity.buildFromSeedString(ATT_SEED, { - signingKeyPairType: 'ed25519', - }).signKeyringPair -} -export function get_ed25519_anchor_key_id(): string { - return '0xee643cd1b9567e60b913ef6d7b99e117277413736955051b891b07fa2cff1ca2' -} - -export function generate_sr25519_anchor_key(): KeyringPair { - return cord.Identity.buildFromSeedString(ATT_SEED, { - signingKeyPairType: 'sr25519', - }).signKeyringPair -} -export function get_sr25519_anchor_key_id(): string { - return '0x8ab41dc8ddfecb44ca18658b0a34becdcc0580096855c9f7cbb8575b02356286' -} - -export function generate_ed25519_delegation_key(): KeyringPair { - return cord.Identity.buildFromSeedString(DEL_SEED, { - signingKeyPairType: 'ed25519', - }).signKeyringPair -} -export function get_ed25519_delegation_key_id(): string { - return '0xe8633ac00f7cf860d6310624c721e4229d7f661de9afd885cd2d422fd15b7669' -} - -export function generate_sr25519_delegation_key(): KeyringPair { - return cord.Identity.buildFromSeedString(DEL_SEED, { - signingKeyPairType: 'sr25519', - }).signKeyringPair -} -export function get_sr25519_delegation_key_id(): string { - return '0x81dc5bf133b998d615b70563ee94e92296e1219f8235b008b38a2ddb40168a35' -} - -export async function waitForEnter(message?: string) { - const waitForEnter = require('wait-for-enter') - message = message || 'Press Enter to continue: ' - console.log(message) - await waitForEnter() -} diff --git a/jest.config.js b/jest.config.js index 06d6470d..04e96f52 100644 --- a/jest.config.js +++ b/jest.config.js @@ -34,9 +34,5 @@ module.exports = { moduleDirectories: [ "node_modules", "packages/*/src", - "packages/**" - ], - "modulePathIgnorePatterns": [ - "/cord-utils/src/chainApiConnection/__mocks__/" ], } diff --git a/package.json b/package.json index 78f6ea05..c5c4dd6b 100644 --- a/package.json +++ b/package.json @@ -5,14 +5,16 @@ "packages/*" ], "scripts": { + "analyze": "yarn clean && BUILD_ANALYZE=1 yarn run build:code && yarn source-map-explorer packages/apps/build/main.*.js", "check": "tsc -p tsconfig.json --noEmit", "build": "yarn workspaces foreach -p --topological-dev --exclude '{root-workspace}' run build", "build:docs": "typedoc --theme default --out docs/api --tsconfig tsconfig.docs.json && touch docs/.nojekyll", - "bundle": "yarn workspace @cord.network/api run bundle", + "bundle": "yarn workspace @cord.network/sdk run bundle", "clean": "rimraf tests/dist && yarn workspaces foreach -p --exclude '{root-workspace}' run clean", "clean:docs": "rimraf docs/api", - "demo": "tsx demo/src/demo.ts", - "demo-vc": "tsx --no-cache demo/src/demo-vc.ts", + "demo": "tsx --no-cache demo/src/demo.ts", + "demo-vc": "tsx --no-cache --no-warnings demo/src/demo-vc.ts", + "demo-messaging": "tsx --no-cache --no-warnings demo/src/demo-messaging.ts", "bench": "tsx demo/src/bench.ts", "set:version": "yarn workspaces foreach -pt exec npm version --no-git-tag-version", "prepublish": "yarn workspaces foreach -p --no-private exec cp -f ../../LICENSE .", @@ -40,7 +42,6 @@ "@commitlint/cli": "^9.0.1", "@commitlint/config-conventional": "^9.0.1", "@types/jest": "^27.4.0", - "@types/node": "^17.0.35", "@typescript-eslint/eslint-plugin": "^5.7.0", "@typescript-eslint/parser": "^5.7.0", "eslint": "^7.32.0", @@ -63,13 +64,8 @@ "ts-jest-resolver": "^2.0.0", "tsx": "^3.4.3", "typedoc": "^0.22.7", - "typescript": "^4.5.4", - "wait-for-enter": "^1.0.0" + "typescript": "^4.5.4" }, "version": "0.7.3-0", - "packageManager": "yarn@3.2.1", - "dependencies": { - "@multiformats/blake2": "^1.0.5", - "multiformats": "^9.4.7" - } + "packageManager": "yarn@3.2.1" } diff --git a/packages/messaging/src/Message.ts b/packages/messaging/src/Message.ts index 47c343f1..0e65489c 100644 --- a/packages/messaging/src/Message.ts +++ b/packages/messaging/src/Message.ts @@ -15,13 +15,12 @@ import type { IPublicIdentity, CompressedMessageBody, IMessage, - ISubmitCredential, IEncryptedMessage, MessageBody, ISchema, } from '@cord.network/types' import { MessageBodyType } from '@cord.network/types' -import { Crypto, DataUtils, SDKErrors } from '@cord.network/utils' +import { Crypto, DataUtils, SDKErrors, UUID } from '@cord.network/utils' import { compressMessage, decompressMessage, @@ -57,7 +56,7 @@ export class Message implements IMessage { } } break - case Message.BodyType.ANCHOR_STREAM: + case Message.BodyType.SUBMIT_STREAM: { const submitStream = body //TODO - Add schema delegation checks @@ -68,9 +67,9 @@ export class Message implements IMessage { break case Message.BodyType.SUBMIT_CREDENTIAL: { - const submitStreamsForSchema: ISubmitCredential = body - submitStreamsForSchema.content.forEach((stream, i) => { - if (stream.credentials[i].stream.issuer !== senderAddress) { + const submitStreamsForSchema = body + submitStreamsForSchema.content.forEach((stream) => { + if (stream.request.content.issuer !== senderAddress) { throw new SDKErrors.ERROR_IDENTITY_MISMATCH('Schema', 'Holder') } }) @@ -104,7 +103,7 @@ export class Message implements IMessage { } DataUtils.validateSignature( encrypted.hash, - encrypted.requestorSignature, + encrypted.signature, senderAddress ) } @@ -163,7 +162,7 @@ export class Message implements IMessage { public messageId?: string public receivedAt?: number public body: MessageBody - public createdAt: number + public createdAt: string public validUntil?: number public receiverAddress: IMessage['receiverAddress'] public senderAddress: IMessage['senderAddress'] @@ -186,10 +185,11 @@ export class Message implements IMessage { } else { this.body = body } - this.createdAt = Date.now() + this.messageId = UUID.generate() this.receiverAddress = receiver.address this.senderAddress = sender.address this.senderPublicKey = sender.getBoxPublicKey() + this.createdAt = new Date().toISOString() } /** @@ -213,14 +213,14 @@ export class Message implements IMessage { const hashInput: string = encryptedStream + nonce + this.createdAt const hash = Crypto.hashStr(hashInput) - const requestorSignature = sender.signStr(hash) + const signature = sender.signStr(hash) return { receivedAt: this.receivedAt, encryptedStream, nonce, createdAt: this.createdAt, hash, - requestorSignature, + signature, receiverAddress: this.receiverAddress, senderAddress: this.senderAddress, senderPublicKey: this.senderPublicKey, diff --git a/packages/messaging/src/Message.utils.ts b/packages/messaging/src/Message.utils.ts index 9bc2dadd..6c18d553 100644 --- a/packages/messaging/src/Message.utils.ts +++ b/packages/messaging/src/Message.utils.ts @@ -6,7 +6,7 @@ import { Stream, Credential, - Content, + // Content, Schema, ContentStream, } from '@cord.network/modules' @@ -16,11 +16,11 @@ import type { CompressedMessageBody, MessageBody, CompressedRequestCredentialContent, - IRequestStreamForCredential, + // IRequestCredentialContent, ISchema, IMessage, - PartialContent, - IContent, + // PartialContent, + // IContent, } from '@cord.network/types' import { DataUtils, SDKErrors } from '@cord.network/utils' import { isHex } from '@polkadot/util' @@ -31,15 +31,15 @@ export function errorCheckMessageBody(body: MessageBody): boolean | void { switch (body.type) { case Message.BodyType.REQUEST_STREAM: { ContentStream.verifyDataStructure(body.content.requestStream) - if (body.content.prerequisiteStreams) { - body.content.prerequisiteStreams.map( - (content: IContent | PartialContent) => - Content.verifyDataStructure(content) - ) - } + // if (body.content.prerequisiteStreams) { + // body.content.prerequisiteStreams.map( + // (content: IContent | PartialContent) => + // Content.verifyDataStructure(content) + // ) + // } break } - case Message.BodyType.ANCHOR_STREAM: { + case Message.BodyType.SUBMIT_STREAM: { Stream.verifyDataStructure(body.content.stream) break } @@ -50,13 +50,13 @@ export function errorCheckMessageBody(body: MessageBody): boolean | void { break } case Message.BodyType.REQUEST_CREDENTIAL: { - body.content.forEach( - (requestStreamsForSchema: IRequestStreamForCredential): void => { - DataUtils.validateId(requestStreamsForSchema.id, 'Identifier') - requestStreamsForSchema.acceptedIssuer?.map((address) => + body.content.schemas.forEach( + ({ schemaIdentifier, trustedIssuers, requiredProperties }): void => { + DataUtils.validateId(schemaIdentifier, 'Identifier') + trustedIssuers?.map((address) => DataUtils.validateAddress(address, 'Invalid Schema Owner Address') ) - requestStreamsForSchema.requiredProperties?.forEach( + requiredProperties?.forEach( (requiredProps) => typeof requiredProps !== 'string' && new TypeError('Required properties is expected to be a string') @@ -66,10 +66,9 @@ export function errorCheckMessageBody(body: MessageBody): boolean | void { break } case Message.BodyType.SUBMIT_CREDENTIAL: { - const creds: ICredential[] = body.content.map((credentials, i) => { - return credentials[i].credentials - }) - creds.map((cred) => Credential.verifyDataStructure(cred)) + body.content.map((credential) => + Credential.verifyDataStructure(credential) + ) break } case Message.BodyType.ACCEPT_CREDENTIAL: { @@ -91,7 +90,7 @@ export function errorCheckMessageBody(body: MessageBody): boolean | void { export function errorCheckMessage(message: IMessage): boolean | void { const { body, - request, + messageId, createdAt, receiverAddress, senderAddress, @@ -99,11 +98,11 @@ export function errorCheckMessage(message: IMessage): boolean | void { senderPublicKey, inReplyTo, } = message - if (request && typeof request !== 'string') { + if (messageId && typeof messageId !== 'string') { throw new TypeError('message id is expected to be a string') } - if (createdAt && typeof createdAt !== 'number') { - throw new TypeError('created at is expected to be a number') + if (createdAt && typeof createdAt !== 'string') { + throw new TypeError('created at is expected to be a string') } if (receivedAt && typeof receivedAt !== 'number') { throw new TypeError('received at is expected to be a number') @@ -158,26 +157,24 @@ export function compressMessage(body: MessageBody): CompressedMessageBody { let compressedContents: CompressedMessageBody[1] switch (body.type) { case Message.BodyType.REQUEST_STREAM: { - compressedContents = [ - ContentStream.compress(body.content.requestStream), - body.content.prerequisiteStreams - ? body.content.prerequisiteStreams.map((content) => - Content.compress(content) - ) - : undefined, - ] + compressedContents = [ContentStream.compress(body.content.requestStream)] break } - case Message.BodyType.ANCHOR_STREAM: { + case Message.BodyType.SUBMIT_STREAM: { compressedContents = Stream.compress(body.content.stream) break } case Message.BodyType.REQUEST_CREDENTIAL: { - compressedContents = body.content.map( - (val): CompressedRequestCredentialContent => { - return [val.id, val.acceptedIssuer, val.requiredProperties] - } - ) + const compressedSchemas: CompressedRequestCredentialContent[0] = + body.content.schemas.map( + ({ schemaIdentifier, trustedIssuers, requiredProperties }) => [ + schemaIdentifier, + trustedIssuers, + requiredProperties, + ] + ) + compressedContents = [compressedSchemas, body.content.challenge] + break } case Message.BodyType.SUBMIT_CREDENTIAL: { @@ -216,31 +213,28 @@ export function decompressMessage(body: CompressedMessageBody): MessageBody { case Message.BodyType.REQUEST_STREAM: { decompressedContents = { requestStream: ContentStream.decompress(body[1][0]), - prerequisiteStreams: body[1][1] - ? body[1][1].map((stream) => Content.decompress(stream)) - : undefined, + // prerequisiteStreams: body[1][1] + // ? body[1][1].map((stream) => Content.decompress(stream)) + // : undefined, } break } - case Message.BodyType.ANCHOR_STREAM: { + case Message.BodyType.SUBMIT_STREAM: { decompressedContents = { stream: Stream.decompress(body[1]), } break } case Message.BodyType.REQUEST_CREDENTIAL: { - decompressedContents = body[1].map( - ( - val: CompressedRequestCredentialContent - ): IRequestStreamForCredential => { - return { - id: val[0], - acceptedIssuer: val[1], - requiredProperties: val[2], - } - } - ) + decompressedContents = { + schemas: body[1][0].map((val) => ({ + schemaIdentifier: val[0], + trustedIssuers: val[1], + requiredProperties: val[2], + })), + challenge: body[1][1], + } break } diff --git a/packages/modules/src/balance/Balance.chain.ts b/packages/modules/src/balance/Balance.chain.ts index fead7318..acf3d6ec 100644 --- a/packages/modules/src/balance/Balance.chain.ts +++ b/packages/modules/src/balance/Balance.chain.ts @@ -28,9 +28,9 @@ import * as BalanceUtils from './Balance.utils.js' export async function getBalances( accountAddress: IPublicIdentity['address'] ): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() - return (await blockchain.api.query.system.account(accountAddress)).data + return (await api.query.system.account(accountAddress)).data } /** @@ -50,10 +50,10 @@ export async function listenToBalanceChanges( changes: Balances ) => void ): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() let previousBalances = await getBalances(accountAddress) - return blockchain.api.query.system.account( + return api.query.system.account( accountAddress, ({ data: { free, reserved, miscFrozen, feeFrozen } }) => { const balancesChange = { @@ -91,10 +91,10 @@ export async function makeTransfer( amount: BN, exponent = -12 ): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() const cleanExponent = (exponent >= 0 ? 1 : -1) * Math.floor(Math.abs(exponent)) - const transfer = blockchain.api.tx.balances.transfer( + const transfer = api.tx.balances.transfer( accountAddressTo, cleanExponent === -12 ? amount diff --git a/packages/modules/src/contentstream/ContentStream.ts b/packages/modules/src/contentstream/ContentStream.ts index 96d1ee58..5b0ddf11 100644 --- a/packages/modules/src/contentstream/ContentStream.ts +++ b/packages/modules/src/contentstream/ContentStream.ts @@ -6,6 +6,7 @@ import type { ISchema, ICredential, CompressedCredential, + IPublicIdentity, } from '@cord.network/types' import { Crypto, SDKErrors, DataUtils } from '@cord.network/utils' import * as Content from '../content/Content.js' @@ -22,7 +23,7 @@ import { HexString } from '@polkadot/util/types' export function makeSigningData( input: IContentStream, - challenge?: string + challenge?: string | null ): Uint8Array { return new Uint8Array([ ...Crypto.coToUInt8(input.rootHash), @@ -31,13 +32,22 @@ export function makeSigningData( } export async function verifySignature( - content: IContentStream + content: IContentStream, + { + challenge, + }: { + challenge?: string + } = {} ): Promise { - return Crypto.verify( - content.rootHash, - content.issuerSignature, - content.content.issuer + const { signatureProof } = content + if (!signatureProof) return false + const signingData = makeSigningData(content, challenge) + const verified = Crypto.verify( + signingData, + signatureProof.signature, + signatureProof.keyId ) + return verified } function getHashRoot(leaves: Uint8Array[]): Uint8Array { @@ -51,10 +61,8 @@ function getHashLeaves( issueDate: string, expiryDate: string ): Uint8Array[] { - const result: Uint8Array[] = [] - contentHashes.forEach((item) => { - result.push(Crypto.coToUInt8(item)) - }) + const result = contentHashes.map((item) => Crypto.coToUInt8(item)) + if (evidenceIds) { evidenceIds.forEach((evidence) => { result.push(Crypto.coToUInt8(evidence.request.identifier)) @@ -70,37 +78,37 @@ export function calculateRootHash( issuanceDate: HexString, expirationDate: HexString ): Hash { - const hashes: Uint8Array[] = getHashLeaves( + const hashes = getHashLeaves( credential.contentHashes || [], credential.evidenceIds || [], issuanceDate, expirationDate ) - const root: Uint8Array = getHashRoot(hashes) + const root = getHashRoot(hashes) return Crypto.u8aToHex(root) } -export async function addSignature( +export function addSignature( request: IContentStream, sig: string | Uint8Array, - challenge?: string -): Promise { + keyId: IPublicIdentity['address'], + { + challenge, + }: { + challenge?: string + } = {} +): void { const signature = typeof sig === 'string' ? sig : Crypto.u8aToHex(sig) - // eslint-disable-next-line no-param-reassign - ;(request.issuerSignature = signature), challenge + request.signatureProof = { keyId, signature } } -function sign(identity: Identity, rootHash: Hash): string { - return identity.signStr(rootHash) -} - -export async function signWithKey( +export function signWithKey( request: IContentStream, signer: Identity, challenge?: string -): Promise { - const signature = await signer.signStr(makeSigningData(request, challenge)) - addSignature(request, signature, challenge) +): void { + const signature = signer.signStr(makeSigningData(request, challenge)) + addSignature(request, signature, signer.address, { challenge }) } /** @@ -285,7 +293,6 @@ export function fromContent( evidenceIds: evidenceIds || [], link: link || null, space: space || null, - issuerSignature: sign(issuer, rootHash), rootHash, issuanceDate: issuanceDateString, expirationDate: expirationDateString, @@ -295,6 +302,8 @@ export function fromContent( STREAM_PREFIX ), } + signWithKey(contentStream, issuer) + verifyDataStructure(contentStream) return contentStream } @@ -343,12 +352,12 @@ export function updateContent( evidenceIds: updateEvidenceIds || content.evidenceIds, link: content.link, space: content.space, - issuerSignature: sign(issuer, rootHash), rootHash, issuanceDate, expirationDate, identifier: content.identifier, } + signWithKey(contentStream, issuer) verifyDataStructure(contentStream) return contentStream } @@ -365,11 +374,12 @@ export function updateContent( */ export async function verify( contentStream: IContentStream, - schema?: ISchema + schema?: ISchema, + challenge?: string ): Promise { verifyDataStructure(contentStream) verifyDataIntegrity(contentStream) - const isSignatureCorrect = verifySignature(contentStream) + const isSignatureCorrect = verifySignature(contentStream, { challenge }) if (!isSignatureCorrect) throw new SDKErrors.ERROR_SIGNATURE_UNVERIFIABLE() if (schema) { @@ -434,7 +444,7 @@ export function compress( Content.compress(contentStream.content), contentStream.contentHashes, contentStream.contentNonceMap, - contentStream.issuerSignature, + contentStream.signatureProof, contentStream.link, contentStream.space, compressProof(contentStream.evidenceIds), @@ -463,7 +473,7 @@ export function decompress( content: Content.decompress(contentStream[0]), contentHashes: contentStream[1], contentNonceMap: contentStream[2], - issuerSignature: contentStream[3], + signatureProof: contentStream[3], link: contentStream[4], space: contentStream[5], evidenceIds: decompressProof(contentStream[6]), diff --git a/packages/modules/src/cordconfig/CordConfig.ts b/packages/modules/src/cordconfig/CordConfig.ts index 1d8f4988..a651a4ad 100644 --- a/packages/modules/src/cordconfig/CordConfig.ts +++ b/packages/modules/src/cordconfig/CordConfig.ts @@ -6,16 +6,17 @@ */ import { ConfigService } from '@cord.network/config' -import { ChainApiConnection, Chain } from '@cord.network/network' +import { ChainApiConnection } from '@cord.network/network' import { Identity } from '../identity/index.js' +import { ApiPromise } from '@polkadot/api' /** * Connects to the CORD Blockchain and caches the connection. * When used again, the cached instance is returned. * - * @returns An instance of [[Blockchain]]. + * @returns An instance of [[ApiPromise]]. */ -export function connect(): Promise { +export function connect(): Promise { return ChainApiConnection.getConnectionOrConnect() } diff --git a/packages/modules/src/credential/Credential.ts b/packages/modules/src/credential/Credential.ts index 3f643019..f38d1726 100644 --- a/packages/modules/src/credential/Credential.ts +++ b/packages/modules/src/credential/Credential.ts @@ -132,10 +132,13 @@ export function isICredential(input: unknown): input is ICredential { * */ -export async function verify(cred: ICredential): Promise { +export async function verify( + cred: ICredential, + challenge?: string +): Promise { return ( verifyDataIntegrity(cred) && - (await ContentStream.verifySignature(cred.request)) && + (await ContentStream.verifySignature(cred.request, { challenge })) && Stream.checkValidity(cred.stream) ) } diff --git a/packages/modules/src/did/Did.chain.ts b/packages/modules/src/did/Did.chain.ts deleted file mode 100644 index ebbfb04a..00000000 --- a/packages/modules/src/did/Did.chain.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Option } from '@polkadot/types' -import type { IPublicIdentity, SubmittableExtrinsic } from '@cord.network/types' -import { ChainApiConnection } from '@cord.network/network' -import type { IDid } from './Did.js' -import { - decodeDid, - getAddressFromIdentifier, - getIdentifierFromAddress, - IEncodedDidRecord, -} from './Did.utils.js' - -/** - * @param identifier - * @internal - */ -export async function queryByIdentifier( - identifier: IDid['identifier'] -): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - const address = getAddressFromIdentifier(identifier) - const decoded = decodeDid( - identifier, - await blockchain.api.query.did.dIDs>(address) - ) - return decoded -} - -/** - * @param address - * @internal - */ -export async function queryByAddress( - address: IPublicIdentity['address'] -): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - const identifier = getIdentifierFromAddress(address) - const decoded = decodeDid( - identifier, - await blockchain.api.query.did.dIDs>(address) - ) - return decoded -} - -/** - * @internal - */ -export async function remove(): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - const tx: SubmittableExtrinsic = blockchain.api.tx.did.remove() - return tx -} - -/** - * @param did - * @internal - */ -export async function store(did: IDid): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - const tx: SubmittableExtrinsic = blockchain.api.tx.did.add( - did.publicBoxKey, - did.publicSigningKey, - did.documentStore - ) - return tx -} diff --git a/packages/modules/src/did/Did.ts b/packages/modules/src/did/Did.ts deleted file mode 100644 index e36213e9..00000000 --- a/packages/modules/src/did/Did.ts +++ /dev/null @@ -1,255 +0,0 @@ -/** - * A Decentralized Identifier (DID) is a new type of identifier that is globally unique, resolvable with high availability, and cryptographically verifiable. - * Although it's not mandatory in CORD, users can optionally create a DID and anchor it to the CORD blockchain. - * - * Official DID specification: [[https://w3c-ccg.github.io/did-primer/]]. - * - * The [[Did]] class exposes methods to build, store and query decentralized identifiers. - * - */ - -import { AnyJson } from '@polkadot/types/types' -import type { IPublicIdentity, SubmittableExtrinsic } from '@cord.network/types' -import { ConfigService } from '@cord.network/config' -import { Identity } from '../identity/Identity.js' -import { - queryByAddress, - queryByIdentifier, - remove, - store, -} from './Did.chain.js' -import { - createDefaultDidDocument, - getAddressFromIdentifier, - getIdentifierFromAddress, - signDidDocument, - verifyDidDocumentSignature, -} from './Did.utils.js' - -const log = ConfigService.LoggingFactory.getLogger('DID') - -export const IDENTIFIER_PREFIX = 'did:cord:' -export const ACCOUNT_IDENTIFIER_PREFIX = 'id:cord:' -export const SERVICE_DWAY_MESSAGING = 'CordMessagingService' -export const KEY_TYPE_SIGNATURE = 'Ed25519VerificationKey2018' -export const KEY_TYPE_ENCRYPTION = 'X25519Salsa20Poly1305Key2018' -export const KEY_TYPE_AUTHENTICATION = 'Ed25519SignatureAuthentication2018' -export const CONTEXT = 'https://w3id.org/did/v1' - -export interface IDid { - /** - * The DID identifier under which this DID object is stored on-chain. - */ - identifier: string - /** - * The public box key of the associated identity. - */ - publicBoxKey: string - /** - * The public signing key of the associated identity. - */ - publicSigningKey: string - /** - * The document store reference, usually a URL. - */ - documentStore: string | null -} -export interface IDidDocumentCore { - // id and context are the only mandatory properties, described as "MUST"s in the w3c spec https://w3c.github.io/did-core/ - id: string - '@context': string -} - -export interface IDidDocumentPublicKey { - id: string - type: string - controller: string - publicKeyHex: string -} - -export interface IDidDocumentProperties { - authentication: Array - publicKey: IDidDocumentPublicKey[] - service: IDidService[] -} - -export interface IDidService { - type: string - serviceEndpoint: string | AnyJson - id?: string - [key: string]: AnyJson -} - -export interface IDidDocument - extends IDidDocumentCore, - Partial {} - -export interface IDidDocumentSigned extends IDidDocument { - signature: string -} - -export class Did implements IDid { - public readonly identifier: string - public readonly publicBoxKey: string - public readonly publicSigningKey: string - public readonly documentStore: string | null - - private constructor( - identifier: string, - publicBoxKey: string, - publicSigningKey: string, - documentStore: string | null = null - ) { - this.identifier = identifier - this.publicBoxKey = publicBoxKey - this.publicSigningKey = publicSigningKey - this.documentStore = documentStore - } - - /** - * [STATIC] Builds a [[Did]] object from the given [[Identity]]. - * - * @param identity The identity used to build the [[Did]] object. - * @param documentStore The storage location of the associated DID Document; usually a URL. - * @returns The [[Did]] object. - */ - public static fromIdentity(identity: Identity, documentStore?: string): Did { - const identifier = getIdentifierFromAddress(identity.address) - return new Did( - identifier, - identity.getBoxPublicKey(), - identity.signPublicKeyAsHex, - documentStore - ) - } - - /** - * [ASYNC] Stores the [[Did]] object on-chain. - * - * @returns A promise containing the unsigned SubmittableExtrinsic (transaction status). - */ - public async store(): Promise { - log.debug(`Create tx for 'did.add'`) - return store(this) - } - - /** - * [STATIC] Queries the [[Did]] object from the chain using the [identifier]. - * - * @param identifier A CORD DID identifier, e.g. "did:cord:5CtPYoDuQQF...". - * @returns A promise containing the [[Did]] or [null]. - */ - public static queryByIdentifier(identifier: string): Promise { - return queryByIdentifier(identifier) - } - - /** - * [STATIC] Queries the [[Did]] object from the chain using the [address]. - * - * @param address The address associated to this [[Did]]. - * @returns A promise containing the [[Did]] or [null]. - */ - public static queryByAddress(address: string): Promise { - return queryByAddress(address) - } - - /** - * [STATIC] Removes the [[Did]] object attached to a given [[Identity]] from the chain. - * - * @returns A promise containing an unsigned SubmittableExtrinsic (submittable transaction). - */ - public static async remove(): Promise { - log.debug(`Create tx for 'did.remove'`) - return remove() - } - - /** - * [STATIC] Gets the complete CORD DID from an [address] (in CORD, the method-specific ID is an address). Reverse of [[getAddressFromIdentifier]]. - * - * @param address An address, e.g. "5CtPYoDuQQF...". - * @returns The associated CORD DID identifier, e.g. "did:cord:5CtPYoDuQQF...". - */ - public static getIdentifierFromAddress( - address: IPublicIdentity['address'] - ): IDid['identifier'] { - return getIdentifierFromAddress(address) - } - - /** - * [STATIC] Gets the [address] from a complete CORD DID (in CORD, the method-specific ID is an address). Reverse of [[getIdentifierFromAddress]]. - * - * @param identifier A CORD DID identifier, e.g. "did:cord:5CtPYoDuQQF...". - * @returns The associated address, e.g. "5CtPYoDuQQF...". - */ - public static getAddressFromIdentifier( - identifier: IDid['identifier'] - ): IPublicIdentity['address'] { - return getAddressFromIdentifier(identifier) - } - - /** - * [STATIC] Signs (the hash of) a DID Document. - * - * @param didDocument A DID Document, e.g. Created via [[createDefaultDidDocument]]. - * @param identity [[Identity]] representing the DID subject for this DID Document, and used for signature. - * @returns The signed DID Document. - */ - public static signDidDocument( - didDocument: IDidDocument, - identity: Identity - ): IDidDocumentSigned { - return signDidDocument(didDocument, identity) - } - - /** - * [STATIC] Verifies the signature of a DID Document, to check whether the data has been tampered with. - * - * @param didDocument A signed DID Document. - * @param identifier A CORD DID identifier, e.g. "did:cord:5CtPYoDuQQF...". - * @returns Whether the DID Document's signature is valid. - */ - public static verifyDidDocumentSignature( - didDocument: IDidDocumentSigned, - identifier: string - ): boolean { - return verifyDidDocumentSignature(didDocument, identifier) - } - - /** - * Builds the default DID Document from this [[Did]] object. - * - * @param cordServiceEndpoint A URI pointing to the service endpoint. - * @returns The default DID Document. - */ - public createDefaultDidDocument(cordServiceEndpoint?: string): IDidDocument { - return createDefaultDidDocument( - this.identifier, - this.publicBoxKey, - this.publicSigningKey, - cordServiceEndpoint - ) - } - - /** - * [STATIC] Builds a default DID Document. - * - * @param identifier A CORD DID identifier, e.g. "did:cord:5CtPYoDuQQF...". - * @param publicBoxKey The public encryption key of the DID subject of this CORD DID identifier. - * @param publicSigningKey The public signing key of the DID subject of this CORD DID identifier. - * @param cordServiceEndpoint A URI pointing to the service endpoint. - * @returns The default DID Document. - */ - public static createDefaultDidDocument( - identifier: string, - publicBoxKey: string, - publicSigningKey: string, - cordServiceEndpoint?: string - ): IDidDocument { - return createDefaultDidDocument( - identifier, - publicBoxKey, - publicSigningKey, - cordServiceEndpoint - ) - } -} diff --git a/packages/modules/src/did/Did.utils.ts b/packages/modules/src/did/Did.utils.ts deleted file mode 100644 index 72e597b5..00000000 --- a/packages/modules/src/did/Did.utils.ts +++ /dev/null @@ -1,166 +0,0 @@ -/** - * @packageDocumentation - * @module DIDUtils - */ - -import type { Option, Struct, u8, Vec } from '@polkadot/types' -import type { IPublicIdentity } from '@cord.network/types' -import { Crypto, DecoderUtils, SDKErrors } from '@cord.network/utils' -import type { Hash } from '@polkadot/types/interfaces' -import { hexToString } from '@polkadot/util' -import { Identity } from '../identity/Identity.js' -import { - CONTEXT, - IDENTIFIER_PREFIX, - // ACCOUNT_IDENTIFIER_PREFIX, - IDid, - IDidDocument, - IDidDocumentSigned, - KEY_TYPE_AUTHENTICATION, - KEY_TYPE_ENCRYPTION, - KEY_TYPE_SIGNATURE, - SERVICE_DWAY_MESSAGING, -} from './Did.js' - -export interface IEncodedDidRecord extends Struct { - readonly signKey: Hash - readonly boxKey: Hash - readonly docRef: Option> -} - -export function decodeDid( - identifier: string, - encoded: Option -): IDid | null { - DecoderUtils.assertCodecIsType(encoded, ['Option']) - if (encoded.isSome) { - const did = encoded.unwrap() - const documentStore = did.docRef.isSome - ? hexToString(did.docRef.unwrap().toHex()) - : null - return { - identifier, - publicSigningKey: did.signKey.toHex(), - publicBoxKey: did.boxKey.toHex(), - documentStore, - } - } - - return null -} - -export function getIdentifierFromAddress( - address: IPublicIdentity['address'] -): IDid['identifier'] { - return address.startsWith(IDENTIFIER_PREFIX) - ? address - : IDENTIFIER_PREFIX + address -} - -/** - * Fetches the root of this delegation node. - * - * @param identifier IDid identifier to derive it's address from. - * @throws When the identifier is not prefixed with the defined Cord IDENTIFIER_PREFIX. - * @throws [[ERROR_INVALID_DID_PREFIX]]. - * - * @returns The Address derived from the IDid Identifier. - */ -export function getAddressFromIdentifier( - identifier: IDid['identifier'] -): IPublicIdentity['address'] { - if (!identifier.startsWith(IDENTIFIER_PREFIX)) { - throw new SDKErrors.ERROR_INVALID_DID_PREFIX(identifier) - } - return identifier.substr(IDENTIFIER_PREFIX.length) -} - -export function createDefaultDidDocument( - identifier: string, - publicBoxKey: string, - publicSigningKey: string, - cordServiceEndpoint?: string -): IDidDocument { - return { - id: identifier, - '@context': CONTEXT, - authentication: [ - { - type: KEY_TYPE_AUTHENTICATION, - publicKey: [`${identifier}#key-1`], - }, - ], - publicKey: [ - { - id: `${identifier}#key-1`, - type: KEY_TYPE_SIGNATURE, - controller: identifier, - publicKeyHex: publicSigningKey, - }, - { - id: `${identifier}#key-2`, - type: KEY_TYPE_ENCRYPTION, - controller: identifier, - publicKeyHex: publicBoxKey, - }, - ], - service: cordServiceEndpoint - ? [ - { - type: SERVICE_DWAY_MESSAGING, - serviceEndpoint: cordServiceEndpoint, - }, - ] - : [], - } -} - -/** - * Verifies the signature of a [[IDidDocumentSigned]]. - * - * @param didDocument [[IDidDocumentSigned]] to verify it's signature. - * @param identifier IDid identifier to match the IDidDocumentSigned id and to verify the signature with. - * @throws When didDocument and it's signature as well as the identifier are missing. - * @throws When identifier does not match didDocument's id. - * @throws [[ERROR_DID_IDENTIFIER_MISMATCH]]. - * - * @returns The Address derived from the IDid Identifier. - */ -export function verifyDidDocumentSignature( - didDocument: IDidDocumentSigned, - identifier: IDid['identifier'] -): boolean { - if (!didDocument || !didDocument.signature || !identifier) { - throw new Error( - `Missing data for verification (either didDocument, didDocumentHash, signature, or address is missing):\n - didDocument:\n - ${didDocument}\n - signature:\n - ${didDocument.signature}\n - address:\n - ${identifier}\n - ` - ) - } - const { id } = didDocument - if (identifier !== id) { - throw new SDKErrors.ERROR_DID_IDENTIFIER_MISMATCH(identifier, id) - } - const { signature, ...unsignedDidDocument } = didDocument - return Crypto.verify( - Crypto.hashObjectAsHexStr(unsignedDidDocument), - signature, - getAddressFromIdentifier(identifier) - ) -} - -export function signDidDocument( - didDocument: IDidDocument, - identity: Identity -): IDidDocumentSigned { - const didDocumentHash = Crypto.hashObjectAsHexStr(didDocument) - return { - ...didDocument, - signature: identity.signStr(didDocumentHash), - } -} diff --git a/packages/modules/src/did/index.ts b/packages/modules/src/did/index.ts deleted file mode 100644 index 34937958..00000000 --- a/packages/modules/src/did/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export { - Did, - IDid, - IDidDocument, - IDidDocumentPublicKey, - IDidDocumentSigned, -} from './Did.js' - -export * as DidUtils from './Did.utils.js' diff --git a/packages/modules/src/identity/Identity.ts b/packages/modules/src/identity/Identity.ts index 00871d7d..5c22d965 100644 --- a/packages/modules/src/identity/Identity.ts +++ b/packages/modules/src/identity/Identity.ts @@ -29,13 +29,14 @@ import * as u8aUtil from '@polkadot/util/u8a' // and not for box keypair, we use TweetNaCl directly import nacl from 'tweetnacl' import { Crypto, SDKErrors, UUID } from '@cord.network/utils' -import type { +import { IIdentity, SubmittableExtrinsic, SignProps, + IPublicIdentity, + ss58Format, } from '@cord.network/types' import { AnyNumber } from '@polkadot/types/types' -import { PublicIdentity } from './PublicIdentity.js' import { HexString } from '@polkadot/util/types.js' type BoxPublicKey = @@ -127,7 +128,7 @@ export class Identity implements IIdentity { return new Keyring({ type, // CORD has registered the ss58 prefix 29 - ss58Format: 29, + ss58Format: ss58Format, }) } @@ -375,3 +376,38 @@ export class Identity implements IIdentity { return nacl.box.keyPair.fromSecretKey(hash) } } + +export class PublicIdentity implements IPublicIdentity { + /** + * The SS58 account address of the identity on the CORD blockchain. + */ + public readonly address: IPublicIdentity['address'] + + /** + * The public encryption key, encoded as a hexadecimal string. + */ + public readonly boxPublicKeyAsHex: IPublicIdentity['boxPublicKeyAsHex'] + + /** + * The URL where the identity can be reached at. + */ + public readonly serviceAddress?: IPublicIdentity['serviceAddress'] + + /** + * Builds a new [[PublicIdentity]] instance. + * + * @param address - A public address. + * @param boxPublicKeyAsHex - The public encryption key. + * @param serviceAddress - The address of the service used to retrieve the DID. + * + */ + public constructor( + address: IPublicIdentity['address'], + boxPublicKeyAsHex: IPublicIdentity['boxPublicKeyAsHex'], + serviceAddress?: IPublicIdentity['serviceAddress'] + ) { + this.address = address + this.boxPublicKeyAsHex = boxPublicKeyAsHex + this.serviceAddress = serviceAddress + } +} diff --git a/packages/modules/src/identity/PublicIdentity.ts b/packages/modules/src/identity/PublicIdentity.ts deleted file mode 100644 index e3ebe25b..00000000 --- a/packages/modules/src/identity/PublicIdentity.ts +++ /dev/null @@ -1,186 +0,0 @@ -/** - * - * A [[PublicIdentity]] object exposes only public information such as the public address, but doesn't expose any secrets such as private keys. - * - */ - -import type { IPublicIdentity } from '@cord.network/types' -import { - Did, - IDENTIFIER_PREFIX, - KEY_TYPE_ENCRYPTION, - SERVICE_DWAY_MESSAGING, -} from '../did/Did.js' -import { getAddressFromIdentifier } from '../did/Did.utils.js' - -export interface IURLResolver { - resolve(url: string): Promise | null> -} - -type DIDPublicKey = { - id: string - type: string - publicKeyHex: string -} - -type DIDService = { - id: string - type: string - serviceEndpoint: string -} - -type DIDDocument = { - id: string - publicKey: DIDPublicKey[] - service: DIDService[] -} - -type DIDResult = { - didDocument: DIDDocument -} - -function isDIDDocument(object: Record): object is DIDDocument { - const didDocument = object as DIDDocument - return !!didDocument.id && !!didDocument.publicKey && !!didDocument.service -} - -function isDIDResult(object: Record): object is DIDResult { - return isDIDDocument((object as DIDResult).didDocument) -} - -export class PublicIdentity implements IPublicIdentity { - /** - * [STATIC] Creates a new Public Identity from a DID document (DID - Decentralized Identifiers: https://w3c-ccg.github.io/did-spec/). - * - * @param didDocument - Contains the public key, external ID and service endpoint. - * @returns A new [[PublicIdentity]] object. - * - */ - public static fromDidDocument( - didDocument: Record - ): IPublicIdentity | null { - if (!isDIDDocument(didDocument)) { - return null - } - - try { - return new PublicIdentity( - didDocument.id.startsWith(IDENTIFIER_PREFIX) - ? getAddressFromIdentifier(didDocument.id) - : didDocument.id, - this.getJSONProperty( - didDocument, - 'publicKey', - 'type', - KEY_TYPE_ENCRYPTION, - 'publicKeyHex' - ), - this.getJSONProperty( - didDocument, - 'service', - 'type', - SERVICE_DWAY_MESSAGING, - 'serviceEndpoint' - ) - ) - } catch (e) { - return null - } - } - - /** - * [STATIC] [ASYNC] Resolves a decentralized identifier (DID) into a [[PublicIdentity]]. - * - * @param identifier - The Decentralized Identifier to be resolved. - * @param urlResolver - A URL resolver, which is used to query the did document. - * @returns A new [[PublicIdentity]] object. - * - */ - public static async resolveFromDid( - identifier: string, - urlResolver: IURLResolver - ): Promise { - if (identifier.startsWith(IDENTIFIER_PREFIX)) { - const did = await Did.queryByIdentifier(identifier) - if (did !== null) { - const didDocument = did.documentStore - ? await urlResolver.resolve(did.documentStore) - : null - // TODO: check, if did document is complete - if (didDocument) { - return this.fromDidDocument(didDocument) - } - return new PublicIdentity( - getAddressFromIdentifier(did.identifier), - did.publicBoxKey - ) - } - } else { - const didResult = await urlResolver.resolve( - `https://uniresolver.io/1.0/identifiers/${encodeURIComponent( - identifier - )}` - ) - if (didResult && isDIDResult(didResult)) { - return this.fromDidDocument(didResult.didDocument) - } - } - return null - } - - /** - * The SS58 account address of the identity on the CORD blockchain. - */ - public readonly address: IPublicIdentity['address'] - - /** - * The public encryption key, encoded as a hexadecimal string. - */ - public readonly boxPublicKeyAsHex: IPublicIdentity['boxPublicKeyAsHex'] - - /** - * The URL where the identity can be reached at. - */ - public readonly serviceAddress?: IPublicIdentity['serviceAddress'] - - /** - * Builds a new [[PublicIdentity]] instance. - * - * @param address - A public address. - * @param boxPublicKeyAsHex - The public encryption key. - * @param serviceAddress - The address of the service used to retrieve the DID. - * - */ - public constructor( - address: IPublicIdentity['address'], - boxPublicKeyAsHex: IPublicIdentity['boxPublicKeyAsHex'], - serviceAddress?: IPublicIdentity['serviceAddress'] - ) { - this.address = address - this.boxPublicKeyAsHex = boxPublicKeyAsHex - this.serviceAddress = serviceAddress - } - - private static getJSONProperty( - did: Record, - listProperty: string, - filterKey: string, - filterValue: string, - property: string - ): string { - if (!did[listProperty]) { - throw Error() - } - const listOfObjects: Array> = did[listProperty] - - const correctObj = listOfObjects.find((object) => { - return object[filterKey] && object[filterKey] === filterValue - }) - - if (correctObj && correctObj[property]) { - return correctObj[property] - } - - throw new Error() - } -} diff --git a/packages/modules/src/identity/index.ts b/packages/modules/src/identity/index.ts index fec3aeb6..4f9fa054 100644 --- a/packages/modules/src/identity/index.ts +++ b/packages/modules/src/identity/index.ts @@ -1,2 +1 @@ -export { Identity } from './Identity.js' -export { PublicIdentity, IURLResolver } from './PublicIdentity.js' +export { Identity, PublicIdentity } from './Identity.js' diff --git a/packages/modules/src/index.ts b/packages/modules/src/index.ts index de3da12e..6cfc950c 100644 --- a/packages/modules/src/index.ts +++ b/packages/modules/src/index.ts @@ -1,20 +1,10 @@ export { Balance, BalanceUtils } from './balance/index.js' -export { Identity, IURLResolver, PublicIdentity } from './identity/index.js' -export { - Did, - IDid, - IDidDocument, - IDidDocumentPublicKey, - IDidDocumentSigned, - DidUtils, -} from './did/index.js' - +export { Identity, PublicIdentity } from './identity/index.js' export * as Schema from './schema/index.js' export * as Space from './space/index.js' export * as Content from './content/index.js' export * as ContentStream from './contentstream/index.js' export * as Stream from './stream/index.js' export * as Credential from './credential/index.js' - export { connect, disconnect, config, init } from './cordconfig/index.js' export { SDKErrors } from '@cord.network/utils' diff --git a/packages/modules/src/schema/Schema.chain.ts b/packages/modules/src/schema/Schema.chain.ts index ac26662c..4c368c9a 100644 --- a/packages/modules/src/schema/Schema.chain.ts +++ b/packages/modules/src/schema/Schema.chain.ts @@ -27,9 +27,9 @@ const log = ConfigService.LoggingFactory.getLogger('Schema') */ export async function create(schema: ISchema): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Create tx for 'schema'`) - return blockchain.api.tx.schema.create( + return api.tx.schema.create( schema.controller, schema.schemaHash, Identifier.getIdentifierKey(schema.space, SPACE_PREFIX), @@ -46,11 +46,11 @@ export async function revoke( ): Promise { const { txSignature, txHash } = controller.signTx(schema.schemaHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Revoking a schema with ID ${schema.identifier}`) const space = Identifier.getIdentifierKey(schema.space, SPACE_PREFIX) || null - return blockchain.api.tx.schema.revoke( + return api.tx.schema.revoke( controller, Identifier.getIdentifierKey(schema.identifier, SCHEMA_PREFIX), txHash, @@ -69,11 +69,11 @@ export async function authorise( ): Promise { const { txSignature, txHash } = controller.signTx(schema.schemaHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Adding a delagate to ${schema.identifier}`) const space = Identifier.getIdentifierKey(schema.space, SPACE_PREFIX) || null - return blockchain.api.tx.schema.authorise( + return api.tx.schema.authorise( controller, Identifier.getIdentifierKey(schema.identifier, SCHEMA_PREFIX), txHash, @@ -93,11 +93,11 @@ export async function deauthorise( ): Promise { const { txSignature, txHash } = controller.signTx(schema.schemaHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Removing delagation from ${schema.identifier}`) const space = Identifier.getIdentifierKey(schema.space, SPACE_PREFIX) || null - return blockchain.api.tx.schema.deauthorise( + return api.tx.schema.deauthorise( controller, Identifier.getIdentifierKey(schema.identifier, SCHEMA_PREFIX), txHash, @@ -138,20 +138,20 @@ function decodeSchema( async function queryRawHash( schema_hash: string ): Promise> { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - const result = await blockchain.api.query.schema.schemas< - Option - >(schema_hash) + const api = await ChainApiConnection.getConnectionOrConnect() + const result = await api.query.schema.schemas>( + schema_hash + ) return result } async function queryRaw( schema_id: string ): Promise> { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - const result = await blockchain.api.query.schema.schemas< - Option - >(schema_id) + const api = await ChainApiConnection.getConnectionOrConnect() + const result = await api.query.schema.schemas>( + schema_id + ) return result } diff --git a/packages/modules/src/space/Space.chain.ts b/packages/modules/src/space/Space.chain.ts index b3d67c4a..159b2f44 100644 --- a/packages/modules/src/space/Space.chain.ts +++ b/packages/modules/src/space/Space.chain.ts @@ -27,9 +27,9 @@ const log = ConfigService.LoggingFactory.getLogger('Schema') */ export async function create(space: ISpace): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Create tx for 'space'`) - return blockchain.api.tx.space.create( + return api.tx.space.create( space.controller, space.spaceHash, space.controllerSignature @@ -45,8 +45,8 @@ export async function archive( ): Promise { const { txSignature, txHash } = controller.signTx(space.spaceHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() - return blockchain.api.tx.space.archive( + const api = await ChainApiConnection.getConnectionOrConnect() + return api.tx.space.archive( controller, Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), txHash, @@ -63,8 +63,8 @@ export async function restore( ): Promise { const { txSignature, txHash } = controller.signTx(space.spaceHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() - return blockchain.api.tx.space.restore( + const api = await ChainApiConnection.getConnectionOrConnect() + return api.tx.space.restore( controller, Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), txHash, @@ -82,8 +82,8 @@ export async function authorise( ): Promise { const { txSignature, txHash } = controller.signTx(space.spaceHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() - return blockchain.api.tx.space.authorise( + const api = await ChainApiConnection.getConnectionOrConnect() + return api.tx.space.authorise( controller, Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), txHash, @@ -102,8 +102,8 @@ export async function deauthorise( ): Promise { const { txSignature, txHash } = controller.signTx(space.spaceHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() - return blockchain.api.tx.space.deauthorise( + const api = await ChainApiConnection.getConnectionOrConnect() + return api.tx.space.deauthorise( controller, Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), txHash, @@ -122,8 +122,8 @@ export async function transfer( ): Promise { const { txSignature, txHash } = controller.signTx(space.spaceHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() - return blockchain.api.tx.space.transfer( + const api = await ChainApiConnection.getConnectionOrConnect() + return api.tx.space.transfer( controller, Identifier.getIdentifierKey(space.identifier, SPACE_PREFIX), transfer, @@ -162,20 +162,20 @@ function decodeSpace( async function queryRawHash( spaceId: string ): Promise> { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - const result = await blockchain.api.query.space.spaces< - Option - >(spaceId) + const api = await ChainApiConnection.getConnectionOrConnect() + const result = await api.query.space.spaces>( + spaceId + ) return result } async function queryRaw( spaceId: string ): Promise> { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - const result = await blockchain.api.query.space.spaces< - Option - >(spaceId) + const api = await ChainApiConnection.getConnectionOrConnect() + const result = await api.query.space.spaces>( + spaceId + ) return result } diff --git a/packages/modules/src/stream/Stream.chain.ts b/packages/modules/src/stream/Stream.chain.ts index 1d2ffd50..1a752958 100644 --- a/packages/modules/src/stream/Stream.chain.ts +++ b/packages/modules/src/stream/Stream.chain.ts @@ -23,15 +23,15 @@ const log = ConfigService.LoggingFactory.getLogger('Stream') * @returns The [[SubmittableExtrinsic]] for the `create` call. */ export async function create(stream: IStream): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - return blockchain.api.tx.stream.create( + const api = await ChainApiConnection.getConnectionOrConnect() + return api.tx.stream.create( stream.issuer, stream.streamHash, stream.holder, stream.schema, stream.link, stream.space, - stream.issuerSignature + stream.signatureProof?.signature ) } @@ -42,12 +42,12 @@ export async function create(stream: IStream): Promise { * @returns The [[SubmittableExtrinsic]] for the `update` call. */ export async function update(stream: IStream): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - return blockchain.api.tx.stream.update( + const api = await ChainApiConnection.getConnectionOrConnect() + return api.tx.stream.update( stream.identifier, stream.issuer, stream.streamHash, - stream.issuerSignature, + stream.signatureProof?.signature, stream.space ) } @@ -66,10 +66,10 @@ export async function revoke( ): Promise { const { txSignature, txHash } = updater.signTx(stream.streamHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Revoking stream with ID ${stream.identifier}`) const space = Identifier.getIdentifierKey(stream.space, SPACE_PREFIX) || null - return blockchain.api.tx.stream.revoke( + return api.tx.stream.revoke( Identifier.getIdentifierKey(stream.identifier, STREAM_PREFIX), updater.address, txHash, @@ -90,12 +90,9 @@ export async function removeSpaceStream( streamIdentifier: string, spaceIdentifier: string ): Promise { - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Revoking stream with ID ${streamIdentifier}`) - return blockchain.api.tx.stream.removeSpaceStream( - streamIdentifier, - spaceIdentifier - ) + return api.tx.stream.removeSpaceStream(streamIdentifier, spaceIdentifier) } /** @@ -114,9 +111,9 @@ export async function digest( ): Promise { const txSignature = creator.signStr(digestHash) - const blockchain = await ChainApiConnection.getConnectionOrConnect() + const api = await ChainApiConnection.getConnectionOrConnect() log.debug(() => `Adding a stream Digest ${streamIdentifier}`) - return blockchain.api.tx.stream.digest( + return api.tx.stream.digest( streamIdentifier, creator, digestHash, @@ -168,10 +165,10 @@ function decodeStream( export async function queryRaw( streamIdentifier: IContentStream['identifier'] ): Promise> { - const blockchain = await ChainApiConnection.getConnectionOrConnect() - const result = await blockchain.api.query.stream.streams< - Option - >(streamIdentifier) + const api = await ChainApiConnection.getConnectionOrConnect() + const result = await api.query.stream.streams>( + streamIdentifier + ) return result } diff --git a/packages/modules/src/stream/Stream.ts b/packages/modules/src/stream/Stream.ts index 9f64489e..e917a657 100644 --- a/packages/modules/src/stream/Stream.ts +++ b/packages/modules/src/stream/Stream.ts @@ -56,7 +56,7 @@ export function fromContentStream(content: IContentStream): IStream { schema: Identifier.getIdentifierKey(content.content.schema, SCHEMA_PREFIX), link, space, - issuerSignature: content.issuerSignature, + signatureProof: content.signatureProof, } verifyDataStructure(stream) return stream @@ -118,7 +118,7 @@ export function compress(stream: IStream): CompressedStream { stream.schema, stream.link, stream.space, - stream.issuerSignature, + stream.signatureProof, ] } @@ -142,7 +142,7 @@ export function decompress(stream: CompressedStream): IStream { schema: stream[4], link: stream[5], space: stream[6], - issuerSignature: stream[7], + signature: stream[7], } verifyDataStructure(decompressedStream) return decompressedStream diff --git a/packages/network/src/chain/Chain.ts b/packages/network/src/chain/Chain.ts index a1619607..bb4e087d 100644 --- a/packages/network/src/chain/Chain.ts +++ b/packages/network/src/chain/Chain.ts @@ -6,174 +6,159 @@ * @packageDocumentation * @module Chain */ -import type { ApiPromise } from '@polkadot/api' -import type { Header } from '@polkadot/types/interfaces/types' -import type { AnyJson, AnyNumber, Codec } from '@polkadot/types/types' -import type { Text } from '@polkadot/types' -import type { SignerPayloadJSON } from '@polkadot/types/types/extrinsic' -import { BN } from '@polkadot/util' import { ConfigService } from '@cord.network/config' import type { IIdentity, ISubmittableResult, SubmittableExtrinsic, - IChainApi, - ChainStats, SubscriptionPromise, } from '@cord.network/types' -import { isRecoverableTxError, submitSignedTx } from './Chain.utils.js' +import { SubmittableResult } from '@polkadot/api' +import { AnyNumber } from '@polkadot/types/types' +import { ErrorHandler } from '../errorhandling/index.js' +import { makeSubscriptionPromise } from './SubscriptionPromise.js' +import { getConnectionOrConnect } from '../chainApiConnection/ChainApiConnection.js' const log = ConfigService.LoggingFactory.getLogger('Chain') -// Code taken from -// https://polkadot.js.org/api/api/classes/_promise_index_.apipromise.html +export const TxOutdated = 'Transaction is outdated' +export const TxPriority = 'Priority is too low:' +export const TxDuplicate = 'Transaction Already Imported' + +export const IS_READY: SubscriptionPromise.ResultEvaluator = (result) => + result.status.isReady +export const IS_IN_BLOCK: SubscriptionPromise.ResultEvaluator = (result) => + result.isInBlock +export const EXTRINSIC_EXECUTED: SubscriptionPromise.ResultEvaluator = ( + result +) => ErrorHandler.extrinsicSuccessful(result) +export const IS_FINALIZED: SubscriptionPromise.ResultEvaluator = (result) => + result.isFinalized + +export const IS_ERROR: SubscriptionPromise.ResultEvaluator = (result) => + result.isError || result.internalError +export const EXTRINSIC_FAILED: SubscriptionPromise.ResultEvaluator = (result) => + ErrorHandler.extrinsicFailed(result) /** - * Blockchain bridges that connects the SDK and the CORD Blockchain. + * Parses potentially incomplete or undefined options and returns complete [[Options]]. * - * Communicates with the chain via WebSockets and can [[listenToBlocks]]. It exposes the [[signTx]] function that performs the necessary tx signing. + * @param opts Potentially undefined or partial [[Options]] . + * @returns Complete [[Options]], with potentially defaulted values. */ -export class Chain implements IChainApi { - public static asArray(queryResult: Codec): AnyJson[] { - const json = queryResult.toJSON() - if (json instanceof Array) return json - return [] - } +export function parseSubscriptionOptions( + opts?: Partial +): SubscriptionPromise.Options { + const { + resolveOn = IS_FINALIZED, + rejectOn = (result: ISubmittableResult) => + EXTRINSIC_FAILED(result) || IS_ERROR(result), + timeout, + } = { ...opts } - public api: ApiPromise - private accountNonces: Map - - public constructor(api: ApiPromise) { - this.api = api - this.accountNonces = new Map() + return { + resolveOn, + rejectOn, + timeout, } +} - public async getStats(): Promise { - const encoded: Text[] = await Promise.all([ - this.api.rpc.system.chain(), - this.api.rpc.system.name(), - this.api.rpc.system.version(), - ]) - const [chain, nodeName, nodeVersion] = encoded.map((el) => el.toString()) - return { chain, nodeName, nodeVersion } - } +/** + * Submits a signed SubmittableExtrinsic and attaches a callback to monitor the inclusion status of the transaction + * and possible errors in the execution of extrinsics. Returns a promise to that end which by default resolves upon + * finalization and rejects any errors occur during submission or execution of extrinsics. This behavior can be adjusted via optional parameters. + * + * Transaction fees will apply whenever a transaction fee makes it into a block, even if extrinsics fail to execute correctly! + * + * @param tx The SubmittableExtrinsic to be submitted. Most transactions need to be signed, this must be done beforehand. + * @param opts Partial optional [[SubscriptionPromise]]to be parsed: Criteria for resolving/rejecting the promise. + * @returns A promise which can be used to track transaction status. + * If resolved, this promise returns ISubmittableResult that has led to its resolution. + */ +export async function submitSignedTx( + tx: SubmittableExtrinsic, + opts?: Partial +): Promise { + log.info(`Submitting ${tx.method}`) + const options = parseSubscriptionOptions(opts) + const { promise, subscription } = makeSubscriptionPromise(options) - // TODO: implement unsubscribe as subscriptionId continuously increases - public async listenToBlocks( - listener: (header: Header) => void - ): Promise<() => void> { - return this.api.rpc.chain.subscribeNewHeads(listener) - } - /** - * Signs the SubmittableExtrinsic with the given identity. - * - * @param signer The [[Identity]] to sign the tx with. - * @param tx The unsigned SubmittableExtrinsic. - * @param tip The amount of tip the validator. - * @returns Signed [[SubmittableExtrinsic]]. - * - */ - public async signTx( - signer: IIdentity, - tx: SubmittableExtrinsic, - tip?: AnyNumber - ): Promise { - const nonce = await this.getNonce(signer.address) - return tx.signAsync(signer.signKeyringPair, { - nonce, - tip, + let latestResult: SubmittableResult + const unsubscribe = await tx.send((result) => { + latestResult = result + subscription(result) + }) + + const api = await getConnectionOrConnect() + const handleDisconnect = (): void => { + const result = new SubmittableResult({ + events: latestResult.events || [], + internalError: new Error('connection error'), + status: + latestResult.status || + api.registry.createType('ExtrinsicStatus', 'future'), + txHash: api.registry.createType('Hash'), }) + subscription(result) } + api.once('disconnected', handleDisconnect) - /** - * Submits a signed SubmittableExtrinsic with imported function [[submitSignedTx]]. - * Handles recoverable errors if identity is provided by re-signing and re-sending the tx up to two times. - * Uses [[parseSubscriptionOptions]] to provide complete potentially defaulted options to the called [[submitSignedTx]]. - * - * Transaction fees will apply whenever a transaction fee makes it into a block, even if extrinsics fail to execute correctly! - * - * @param tx The SubmittableExtrinsic to be submitted. Most transactions need to be signed, this must be done beforehand. - * @param signer Optional [[Identity]] to potentially re-sign the tx with. - * @param opts Optional partial criteria for resolving/rejecting the promise. - * @returns A promise which can be used to track transaction status. - * If resolved, this promise returns the eventually resolved ISubmittableResult. - */ - async submitSignedTxWithReSign( - tx: SubmittableExtrinsic, - signer?: IIdentity, - opts?: Partial - ): Promise { - const retry = async ( - reason: Error | ISubmittableResult - ): Promise => { - if (isRecoverableTxError(reason) && signer) { - return submitSignedTx(await this.reSignTx(signer, tx), opts) - } - return Promise.reject(reason) - } - return submitSignedTx(tx, opts).catch(retry).catch(retry) - } + return promise + .catch((e) => Promise.reject(ErrorHandler.getExtrinsicError(e) || e)) + .finally(() => { + unsubscribe() + api.off('disconnected', handleDisconnect) + }) +} - /** - * Retrieves the Nonce for Transaction signing for the specified account and increments the in accountNonces mapped Index. - * - * @param accountAddress The address of the identity that we retrieve the nonce for. - * @returns Representation of the Tx nonce for the identity. - * - */ - public async getNonce(accountAddress: IIdentity['address']): Promise { - let nonce = this.accountNonces.get(accountAddress) - if (!nonce) { - // the account nonce is unknown, we will query it from chain - const chainNonce = await this.api.rpc.system - .accountNextIndex(accountAddress) - .catch((reason) => { - log.error( - `On-chain nonce retrieval failed for account ${accountAddress}\nwith reason: ${reason}` - ) - throw Error(`Chain failed to retrieve nonce for : ${accountAddress}`) - }) - // ensure that the nonce we queried is still up to date and no newer nonce was queried during the await above - const secondQuery = this.accountNonces.get(accountAddress) - nonce = BN.max(chainNonce, secondQuery || new BN(0)) - } - this.accountNonces.set(accountAddress, nonce.addn(1)) - return nonce - } +export const dispatchTx = submitSignedTx - /** - * Re-signs the given SubmittableExtrinsic with an updated Nonce. - * - * @param signer The [[Identity]] to re-sign the Tx with. - * @param tx The tx with recoverable Error that failed. - * @returns Original Tx, injected with signature payload with updated nonce. - * - */ - public async reSignTx( - signer: IIdentity, - tx: SubmittableExtrinsic - ): Promise { - this.accountNonces.delete(signer.address) - const nonce: BN = await this.getNonce(signer.address) - const signerPayload: SignerPayloadJSON = this.api - .createType('SignerPayload', { - method: tx.method.toHex(), - nonce, - genesisHash: this.api.genesisHash, - blockHash: this.api.genesisHash, - runtimeVersion: this.api.runtimeVersion, - version: this.api.extrinsicVersion, - }) - .toPayload() - tx.addSignature( - signer.address, - this.api - .createType('ExtrinsicPayload', signerPayload, { - version: this.api.extrinsicVersion, - }) - .sign(signer.signKeyringPair).signature, - signerPayload +/** + * Checks the TxError/TxStatus for issues that may be resolved via resigning. + * + * @param reason Polkadot API returned error or ISubmittableResult. + * @returns Whether or not this issue may be resolved via resigning. + */ +export function isRecoverableTxError( + reason: Error | ISubmittableResult +): boolean { + if (reason instanceof Error) { + return ( + reason.message.includes(TxOutdated) || + reason.message.includes(TxPriority) || + reason.message.includes(TxDuplicate) || + false ) - return tx } + if ( + reason && + typeof reason === 'object' && + typeof reason.status === 'object' + ) { + const { status } = reason as ISubmittableResult + if (status.isUsurped) return true + } + return false +} + +/** + * Signs and submits the SubmittableExtrinsic with optional resolution and rejection criteria. + * + * @param tx The generated unsigned SubmittableExtrinsic to submit. + * @param signer The [[IIdentity]] or KeyringPair used to sign and potentially re-sign the tx. + * @param opts Partial optional criteria for resolving/rejecting the promise. + * @param opts.tip Optional amount of Femto-KILT to tip the validator. + * @returns Promise result of executing the extrinsic, of type ISubmittableResult. + */ +export async function signAndSubmitTx( + tx: SubmittableExtrinsic, + signer: IIdentity, + { + tip, + ...opts + }: Partial & Partial<{ tip: AnyNumber }> = {} +): Promise { + const signKeyringPair = (signer as IIdentity).signKeyringPair || signer + const signedTx = await tx.signAsync(signKeyringPair, { tip }) + return submitSignedTx(signedTx, opts) } diff --git a/packages/network/src/chain/Chain.utils.ts b/packages/network/src/chain/Chain.utils.ts deleted file mode 100644 index ee0b9a24..00000000 --- a/packages/network/src/chain/Chain.utils.ts +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @packageDocumentation - * @module BlockchchainUtils - * @typedef {SubscriptionPromise.Options} Options - */ - -import { ConfigService } from '@cord.network/config' -import type { - IIdentity, - ISubmittableResult, - ReSignOpts, - SubmittableExtrinsic, - SubscriptionPromise, -} from '@cord.network/types' -import { SubmittableResult } from '@polkadot/api' -import { ErrorHandler } from '../errorhandling/index.js' -import { makeSubscriptionPromise } from './SubscriptionPromise.js' -import { getConnectionOrConnect } from '../chainApiConnection/ChainApiConnection.js' - -const log = ConfigService.LoggingFactory.getLogger('Chain') - -export const TxOutdated = 'Transaction is outdated' -export const TxPriority = 'Priority is too low:' -export const TxDuplicate = 'Transaction Already Imported' - -export const IS_READY: SubscriptionPromise.ResultEvaluator = (result) => - result.status.isReady -export const IS_IN_BLOCK: SubscriptionPromise.ResultEvaluator = (result) => - result.isInBlock -export const EXTRINSIC_EXECUTED: SubscriptionPromise.ResultEvaluator = ( - result -) => ErrorHandler.extrinsicSuccessful(result) -export const IS_FINALIZED: SubscriptionPromise.ResultEvaluator = (result) => - result.isFinalized -export const IS_ERROR: SubscriptionPromise.ResultEvaluator = (result) => - result.isError -export const EXTRINSIC_FAILED: SubscriptionPromise.ResultEvaluator = (result) => - ErrorHandler.extrinsicFailed(result) - -/** - * Parses potentially incomplete or undefined options and returns complete [[Options]]. - * - * @param opts Potentially undefined or partial [[Options]] . - * @returns Complete [[Options]], with potentially defaulted values. - */ -export function parseSubscriptionOptions( - opts?: Partial -): SubscriptionPromise.Options { - const { - resolveOn = IS_FINALIZED, - rejectOn = (result: ISubmittableResult) => - EXTRINSIC_FAILED(result) || IS_ERROR(result), - timeout, - } = { ...opts } - - return { - resolveOn, - rejectOn, - timeout, - } -} - -/** - * Submits a signed SubmittableExtrinsic and attaches a callback to monitor the inclusion status of the transaction - * and possible errors in the execution of extrinsics. Returns a promise to that end which by default resolves upon - * finalization and rejects any errors occur during submission or execution of extrinsics. This behavior can be adjusted via optional parameters. - * - * Transaction fees will apply whenever a transaction fee makes it into a block, even if extrinsics fail to execute correctly! - * - * @param tx The SubmittableExtrinsic to be submitted. Most transactions need to be signed, this must be done beforehand. - * @param opts Partial optional [[SubscriptionPromise]]to be parsed: Criteria for resolving/rejecting the promise. - * @returns A promise which can be used to track transaction status. - * If resolved, this promise returns ISubmittableResult that has led to its resolution. - */ -export async function submitSignedTx( - tx: SubmittableExtrinsic, - opts?: Partial -): Promise { - log.info(`Submitting ${tx.method}`) - const options = parseSubscriptionOptions(opts) - const { promise, subscription } = makeSubscriptionPromise(options) - - let latestResult: SubmittableResult - const unsubscribe = await tx.send((result) => { - latestResult = result - subscription(result) - }) - - const { api } = await getConnectionOrConnect() - const handleDisconnect = (): void => { - const result = new SubmittableResult({ - events: latestResult.events || [], - internalError: new Error('connection error'), - status: - latestResult.status || - api.registry.createType('ExtrinsicStatus', 'future'), - txHash: api.registry.createType('Hash'), - }) - subscription(result) - } - api.once('disconnected', handleDisconnect) - - return promise - .catch((e) => Promise.reject(ErrorHandler.getExtrinsicError(e) || e)) - .finally(() => { - unsubscribe() - api.off('disconnected', handleDisconnect) - }) -} -export const dispatchTx = submitSignedTx - -/** - * Checks the TxError/TxStatus for issues that may be resolved via resigning. - * - * @param reason Polkadot API returned error or ISubmittableResult. - * @returns Whether or not this issue may be resolved via resigning. - */ -export function isRecoverableTxError( - reason: Error | ISubmittableResult -): boolean { - if (reason instanceof Error) { - return ( - reason.message.includes(TxOutdated) || - reason.message.includes(TxPriority) || - reason.message.includes(TxDuplicate) || - false - ) - } - if ( - reason && - typeof reason === 'object' && - typeof reason.status === 'object' - ) { - const { status } = reason as ISubmittableResult - if (status.isUsurped) return true - } - return false -} - -/** - * Signs and submits the SubmittableExtrinsic with optional resolution and rejection criteria. - * - * @param tx The generated unsigned SubmittableExtrinsic to submit. - * @param signer The [[Identity]] used to sign and potentially re-sign the tx. - * @param opts Partial optional criteria for resolving/rejecting the promise. - * @param opts.reSign Optional flag for re-attempting to send recoverably failed Tx. - * @param opts.tip Optional amount of Femto-CORD to tip the validator. - * @returns Promise result of executing the extrinsic, of type ISubmittableResult. - * - */ -export async function signAndSubmitTx( - tx: SubmittableExtrinsic, - signer: IIdentity, - { - reSign = false, - tip, - ...opts - }: Partial & Partial = {} -): Promise { - const chain = await getConnectionOrConnect() - const signedTx = await chain.signTx(signer, tx, tip) - return reSign - ? chain.submitSignedTxWithReSign(signedTx, signer, opts) - : submitSignedTx(signedTx, opts) -} diff --git a/packages/network/src/chain/index.ts b/packages/network/src/chain/index.ts index 5b986a1b..ac4cfc07 100644 --- a/packages/network/src/chain/index.ts +++ b/packages/network/src/chain/index.ts @@ -1,3 +1,2 @@ -export { Chain } from './Chain.js' -export * as ChainUtils from './Chain.utils.js' +export * as Chain from './Chain.js' export * as SubscriptionPromise from './SubscriptionPromise.js' diff --git a/packages/network/src/chainApiConnection/ChainApiConnection.ts b/packages/network/src/chainApiConnection/ChainApiConnection.ts index 39b37ed2..2d6e6398 100644 --- a/packages/network/src/chainApiConnection/ChainApiConnection.ts +++ b/packages/network/src/chainApiConnection/ChainApiConnection.ts @@ -9,9 +9,8 @@ import { ApiPromise, WsProvider } from '@polkadot/api' import { ConfigService } from '@cord.network/config' -import { Chain } from '../chain/Chain.js' -let instance: Promise | null +let instance: Promise | null /** * Builds a new blockchain connection instance. @@ -21,12 +20,11 @@ let instance: Promise | null */ export async function buildConnection( host: string = ConfigService.get('address') -): Promise { +): Promise { const provider = new WsProvider(host) - const api: ApiPromise = await ApiPromise.create({ + return ApiPromise.create({ provider, }) - return new Chain(api) } /** @@ -37,7 +35,7 @@ export async function buildConnection( * * @param connectionInstance The Chain instance, which should be cached. */ -export function setConnection(connectionInstance: Promise): void { +export function setConnection(connectionInstance: Promise): void { instance = connectionInstance } @@ -46,7 +44,7 @@ export function setConnection(connectionInstance: Promise): void { * * @returns Cached blockchain connection. */ -export function getConnection(): Promise | null { +export function getConnection(): Promise | null { return instance } @@ -55,7 +53,7 @@ export function getConnection(): Promise | null { * * @returns The cached or newly built blockchain connection instance. */ -export async function getConnectionOrConnect(): Promise { +export async function getConnectionOrConnect(): Promise { if (!instance) { instance = buildConnection() } @@ -78,7 +76,7 @@ export function clearCache(): void { export async function connected(): Promise { if (!instance) return false const resolved = await instance - return resolved.api.isConnected + return resolved.isConnected } /** @@ -93,8 +91,8 @@ export async function disconnect(): Promise { if (!oldInstance) return false const resolved = await oldInstance - const { isConnected } = resolved.api - await resolved.api.disconnect() + const { isConnected } = resolved + await resolved.disconnect() return isConnected } diff --git a/packages/network/src/index.ts b/packages/network/src/index.ts index b2432ef8..b290bd8d 100644 --- a/packages/network/src/index.ts +++ b/packages/network/src/index.ts @@ -1,3 +1,3 @@ export { ErrorHandler } from './errorhandling/index.js' export { ChainApiConnection } from './chainApiConnection/index.js' -export { Chain, ChainUtils, SubscriptionPromise } from './chain/index.js' +export { Chain, SubscriptionPromise } from './chain/index.js' diff --git a/packages/api/LICENSE b/packages/sdk/LICENSE similarity index 100% rename from packages/api/LICENSE rename to packages/sdk/LICENSE diff --git a/packages/api/package.json b/packages/sdk/package.json similarity index 92% rename from packages/api/package.json rename to packages/sdk/package.json index a54c6504..ad74676b 100644 --- a/packages/api/package.json +++ b/packages/sdk/package.json @@ -1,5 +1,5 @@ { - "name": "@cord.network/api", + "name": "@cord.network/sdk", "version": "0.7.3-0", "description": "", "main": "./lib/cjs/index.js", @@ -16,7 +16,7 @@ "dist/*" ], "scripts": { - "clean": "rimraf ./lib", + "clean": "rimraf ./lib dist", "build": "yarn clean && yarn build:ts", "build:ts": "yarn build:cjs && yarn build:esm", "build:cjs": "tsc --declaration -p tsconfig.build.json && echo '{\"type\":\"commonjs\"}' > ./lib/cjs/package.json", @@ -40,8 +40,8 @@ "typescript": "^4.5.4", "url": "^0.11.0", "util": "^0.12.4", - "webpack": "^5.27.0", - "webpack-cli": "^4.5.0" + "webpack": "^5.70.0", + "webpack-cli": "^4.9.2" }, "dependencies": { "@cord.network/messaging": "workspace:*", diff --git a/packages/api/src/index.ts b/packages/sdk/src/index.ts similarity index 77% rename from packages/api/src/index.ts rename to packages/sdk/src/index.ts index fa6a27bd..80998937 100644 --- a/packages/api/src/index.ts +++ b/packages/sdk/src/index.ts @@ -1,7 +1,9 @@ +import '@polkadot/api-augment' + export * from '@cord.network/modules' export { Message } from '@cord.network/messaging' export * as Messaging from '@cord.network/messaging' -export { ChainUtils } from '@cord.network/network' +export { Chain } from '@cord.network/network' export * as ChainHelpers from '@cord.network/network' export * as Utils from '@cord.network/utils' export * from '@cord.network/types' diff --git a/packages/api/tsconfig.build.json b/packages/sdk/tsconfig.build.json similarity index 100% rename from packages/api/tsconfig.build.json rename to packages/sdk/tsconfig.build.json diff --git a/packages/api/tsconfig.esm.json b/packages/sdk/tsconfig.esm.json similarity index 100% rename from packages/api/tsconfig.esm.json rename to packages/sdk/tsconfig.esm.json diff --git a/packages/api/webpack.config.js b/packages/sdk/webpack.config.js similarity index 81% rename from packages/api/webpack.config.js rename to packages/sdk/webpack.config.js index 40e20492..d1873277 100644 --- a/packages/api/webpack.config.js +++ b/packages/sdk/webpack.config.js @@ -17,14 +17,10 @@ module.exports = { library: 'cord', umdNamedDefine: true, }, - resolve: { +resolve: { extensions: ['.ts', '.js', '.d.ts', '.mjs', '.json'], symlinks: false, // Explicit fallbacks to include these in bundle - alias: { - buffer: 'buffer', - process: 'process', - }, fallback: { buffer: require.resolve('buffer'), crypto: require.resolve('crypto-browserify'), @@ -39,11 +35,8 @@ module.exports = { optimization: { minimize: true, // only minimize the *.min* bundle output - minimizer: [new TerserPlugin({ extractComments: false, terserOptions: { - format: { - comments: false, - }, - },include: /\.min\.umd\.js$/ })], + // only minimize the *.min* bundle output + minimizer: [new TerserPlugin({ include: /\.min\.umd\.js$/ })], }, plugins: [ new webpack.ProvidePlugin({ diff --git a/packages/types/src/Chain.ts b/packages/types/src/Chain.ts index 740d24a8..1eefb4bf 100644 --- a/packages/types/src/Chain.ts +++ b/packages/types/src/Chain.ts @@ -15,6 +15,8 @@ import type { SubscriptionPromise, } from './index.js' +export const ss58Format = 29 + export type ReSignOpts = { reSign: boolean; tip: AnyNumber } export type ChainStats = { chain: string diff --git a/packages/types/src/ContentStream.ts b/packages/types/src/ContentStream.ts index 62d6373d..44e60b20 100644 --- a/packages/types/src/ContentStream.ts +++ b/packages/types/src/ContentStream.ts @@ -6,6 +6,7 @@ import type { HexString } from '@polkadot/util/types' import type { ICredential, CompressedCredential } from './Credential.js' import type { IContent, CompressedContent } from './Content.js' +import type { IPublicIdentity } from './PublicIdentity.js' export const DEFAULT_STREAM_VALIDITY: number = 99 @@ -16,6 +17,11 @@ export type NonceHash = { nonce?: string } +export type AccountSignature = { + keyId: IPublicIdentity['address'] + signature: string +} + export interface IContentStream { content: IContent contentHashes: Hash[] @@ -23,7 +29,7 @@ export interface IContentStream { evidenceIds: ICredential[] link: string | null space: string | null - issuerSignature: string & { challenge?: string } + signatureProof?: AccountSignature & { challenge?: string } rootHash: Hash identifier: string issuanceDate: string @@ -34,7 +40,7 @@ export type CompressedContentStream = [ CompressedContent, IContentStream['contentHashes'], IContentStream['contentNonceMap'], - IContentStream['issuerSignature'], + IContentStream['signatureProof'], IContentStream['link'] | null, IContentStream['space'] | null, CompressedCredential[], diff --git a/packages/types/src/Message.ts b/packages/types/src/Message.ts index 1a8a4ffc..d8da46e4 100644 --- a/packages/types/src/Message.ts +++ b/packages/types/src/Message.ts @@ -4,13 +4,13 @@ */ import type { CompressedStream, IStream } from './Stream.js' -import type { CompressedCredential } from './Credential.js' +import type { CompressedCredential, ICredential } from './Credential.js' import type { - CompressedContent, + // CompressedContent, IContent, IContents, - PartialContent, + // PartialContent, } from './Content.js' import type { ISchema } from './Schema.js' import type { IPublicIdentity } from './PublicIdentity.js' @@ -18,11 +18,13 @@ import type { CompressedContentStream, IContentStream, } from './ContentStream.js' -import { IPresentation } from './Presentation.js' export enum MessageBodyType { + ERROR = 'error', + REJECT = 'reject', + REQUEST_STREAM = 'request-stream', - ANCHOR_STREAM = 'anchor-stream', + SUBMIT_STREAM = 'anchor-stream', REJECT_STREAM = 'reject-stream', REQUEST_CREDENTIAL = 'request-credential', @@ -43,15 +45,15 @@ export enum MessageBodyType { */ export interface IMessage { body: MessageBody - createdAt: number + createdAt: string purpose?: string receiverAddress: IPublicIdentity['address'] senderAddress: IPublicIdentity['address'] senderPublicKey: IPublicIdentity['boxPublicKeyAsHex'] - request?: string + messageId?: string receivedAt?: number - inReplyTo?: IMessage['request'] - references?: Array + inReplyTo?: IMessage['messageId'] + references?: Array } /** @@ -68,31 +70,46 @@ export type IEncryptedMessage = Pick< | 'receiverAddress' | 'senderAddress' | 'senderPublicKey' - | 'request' + | 'messageId' | 'receivedAt' > & { encryptedStream: string nonce: string hash: string - requestorSignature: string + signature: string } interface IMessageBodyBase { content: any type: MessageBodyType - request: string - purpose?: string - validUntil?: number - relatedData?: boolean - requestorSignature?: string +} + +export interface IError extends IMessageBodyBase { + content: { + /** Optional machine-readable type of the error. */ + name?: string + /** Optional human-readable description of the error. */ + message?: string + } + type: MessageBodyType.ERROR +} + +export interface IReject extends IMessageBodyBase { + content: { + /** Optional machine-readable type of the rejection. */ + name?: string + /** Optional human-readable description of the rejection. */ + message?: string + } + type: MessageBodyType.REJECT } export interface IRequestStream extends IMessageBodyBase { content: IRequestStreamContent type: MessageBodyType.REQUEST_STREAM } -export interface IAnchorStream extends IMessageBodyBase { - content: IAnchorStreamContent - type: MessageBodyType.ANCHOR_STREAM +export interface ISubmitStream extends IMessageBodyBase { + content: ISubmitStreamContent + type: MessageBodyType.SUBMIT_STREAM } export interface IRejectStream extends IMessageBodyBase { content: IContentStream['identifier'] @@ -100,11 +117,11 @@ export interface IRejectStream extends IMessageBodyBase { } export interface IRequestCredential extends IMessageBodyBase { - content: IRequestStreamForCredential[] + content: IRequestCredentialContent type: MessageBodyType.REQUEST_CREDENTIAL } export interface ISubmitCredential extends IMessageBodyBase { - content: IPresentation[] + content: ICredential[] type: MessageBodyType.SUBMIT_CREDENTIAL } export interface IAcceptCredential extends IMessageBodyBase { @@ -120,8 +137,8 @@ export type CompressedRequestStream = [ MessageBodyType.REQUEST_STREAM, CompressedRequestStreamContent ] -export type CompressedAnchorStream = [ - MessageBodyType.ANCHOR_STREAM, +export type CompressedSubmitStream = [ + MessageBodyType.SUBMIT_STREAM, CompressedStream ] export type CompressedRejectStream = [ @@ -131,7 +148,7 @@ export type CompressedRejectStream = [ export type CompressedRequestCredential = [ MessageBodyType.REQUEST_CREDENTIAL, - CompressedRequestCredentialContent[] + CompressedRequestCredentialContent ] export type CompressedSubmitCredential = [ MessageBodyType.SUBMIT_CREDENTIAL, @@ -148,16 +165,19 @@ export type CompressedRejectCredential = [ export interface IRequestStreamContent { requestStream: IContentStream - prerequisiteStreams?: Array + // prerequisiteStreams?: Array } // Seems this can be removed -export interface IAnchorStreamContent { +export interface ISubmitStreamContent { stream: IStream } -export interface IRequestStreamForCredential { - id: ISchema['identifier'] - acceptedIssuer?: Array - requiredProperties?: string[] +export interface IRequestCredentialContent { + schemas: Array<{ + schemaIdentifier: ISchema['identifier'] + trustedIssuers?: Array + requiredProperties?: string[] + }> + challenge?: string } export type CompressedPartialContent = [ @@ -168,20 +188,25 @@ export type CompressedPartialContent = [ ] export type CompressedRequestCredentialContent = [ - ISchema['identifier'], - Array | undefined, - string[] | undefined + Array< + [ + ISchema['identifier'], + Array | undefined, + string[] | undefined + ] + >, + string? ] export type CompressedRequestStreamContent = [ - CompressedContentStream, - Array | undefined + CompressedContentStream + // Array | undefined ] export type MessageBody = // | IRequestStream - | IAnchorStream + | ISubmitStream | IRejectStream // | IRequestCredential @@ -191,7 +216,7 @@ export type MessageBody = export type CompressedMessageBody = | CompressedRequestStream - | CompressedAnchorStream + | CompressedSubmitStream | CompressedRejectStream // | CompressedRequestCredential diff --git a/packages/types/src/Presentation.ts b/packages/types/src/Presentation.ts deleted file mode 100644 index 7fea959e..00000000 --- a/packages/types/src/Presentation.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ICredential } from './Credential.js' - -export interface IPresentation { - credentials: ICredential[] - holderSignature?: string -} - -export interface Signer { - sign: (data: Uint8Array) => Uint8Array -} - -export interface IPresentationSigningOptions { - request: string - signer: Signer -} - -export interface IPresentationOptions { - showAttributes?: string[] - hideAttributes?: string[] -} diff --git a/packages/types/src/PublicIdentity.ts b/packages/types/src/PublicIdentity.ts index d237b9e3..678c149e 100644 --- a/packages/types/src/PublicIdentity.ts +++ b/packages/types/src/PublicIdentity.ts @@ -7,3 +7,10 @@ export interface IPublicIdentity { boxPublicKeyAsHex: string serviceAddress?: string } + +export interface IIdentityPublicKey { + id: string + type: string + controller: string + publicKeyHex: string +} diff --git a/packages/types/src/SchemaMetadata.ts b/packages/types/src/SchemaMetadata.ts index ac5de0be..0042b3e2 100644 --- a/packages/types/src/SchemaMetadata.ts +++ b/packages/types/src/SchemaMetadata.ts @@ -5,22 +5,6 @@ import type { ISchema } from './Schema' -export interface ISchemaMetadata { - metadata: IMetadata - id: ISchema['identifier'] | null - hash: ISchema['schemaHash'] | null -} - -export interface IMetadata { - title: IMultilangLabel - description?: IMultilangLabel - properties: IMetadataProperties -} - -export type IMetadataProperties = { - [key: string]: { title: IMultilangLabel; description?: IMultilangLabel } -} - /** * String struct with string keys and a mandatory `default` field. * Meant to contain a default label/description and an arbitrary number of translations, @@ -32,3 +16,19 @@ export interface IMultilangLabel { /** An arbitrary number of translations where the key indicates the language. */ [key: string]: string } + +export type IMetadataProperties = { + [key: string]: { title: IMultilangLabel; description?: IMultilangLabel } +} + +export interface IMetadata { + title: IMultilangLabel + description?: IMultilangLabel + properties: IMetadataProperties +} + +export interface ISchemaMetadata { + metadata: IMetadata + id: ISchema['identifier'] | null + hash: ISchema['schemaHash'] | null +} diff --git a/packages/types/src/Stream.ts b/packages/types/src/Stream.ts index 3fd8c3b2..f575c112 100644 --- a/packages/types/src/Stream.ts +++ b/packages/types/src/Stream.ts @@ -17,7 +17,7 @@ export interface IStream { schema: ISchema['identifier'] | null link: IContentStream['link'] | null space: IContentStream['space'] | null - issuerSignature?: IContentStream['issuerSignature'] | null + signatureProof?: IContentStream['signatureProof'] | null } export type CompressedStream = [ @@ -28,7 +28,7 @@ export type CompressedStream = [ IStream['schema'], IStream['link'], IStream['space'], - IStream['issuerSignature'] + IStream['signatureProof'] ] export interface IStreamDetails { diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 99740dcb..63bc2c02 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -16,4 +16,3 @@ export * from './Credential.js' export * from './Balance.js' export * from './Chain.js' export * from './Message.js' -export * from './Presentation.js' diff --git a/packages/utils/src/Crypto.ts b/packages/utils/src/Crypto.ts index e6220daf..12be9003 100644 --- a/packages/utils/src/Crypto.ts +++ b/packages/utils/src/Crypto.ts @@ -296,8 +296,8 @@ export function encryptAsymmetricAsStr( secretKeyB: CryptoInput ): EncryptedAsymmetricString { const encrypted = encryptAsymmetric(message, publicKeyA, secretKeyB) - const box: string = u8aToHex(encrypted.box) - const nonce: string = u8aToHex(encrypted.nonce) + const box = u8aToHex(encrypted.box) + const nonce = u8aToHex(encrypted.nonce) return { box, nonce } } diff --git a/packages/utils/src/DataUtils.ts b/packages/utils/src/DataUtils.ts index 24809040..8fc5a248 100644 --- a/packages/utils/src/DataUtils.ts +++ b/packages/utils/src/DataUtils.ts @@ -8,12 +8,12 @@ * Dummy comment needed for correct doc display, do not remove. */ import '@polkadot/api-augment' -import type { IPublicIdentity } from '@cord.network/types/src/index.js' +import type { IPublicIdentity } from '@cord.network/types' import { checkAddress } from '@polkadot/util-crypto' import * as SDKErrors from './SDKErrors.js' import { verify } from './Crypto.js' import { checkIdentifier } from './Identifier.js' - +import { ss58Format } from '@cord.network/types' /** * Validates an given address string against the External Address Format (SS58) with our Prefix of 29. * @@ -31,7 +31,7 @@ export function validateAddress( throw new SDKErrors.ERROR_ADDRESS_TYPE() } // CORD has registered ss58 prefix 29 - if (!checkAddress(address, 29)[0]) { + if (!checkAddress(address, ss58Format)[0]) { throw new SDKErrors.ERROR_ADDRESS_INVALID(address, name) } return true diff --git a/packages/utils/src/json-schema/dereference.ts b/packages/utils/src/json-schema/dereference.ts index 7ae37a26..60fff0ed 100644 --- a/packages/utils/src/json-schema/dereference.ts +++ b/packages/utils/src/json-schema/dereference.ts @@ -79,7 +79,7 @@ export function dereference( basePointer = '' ) { if (schema && typeof schema === 'object' && !Array.isArray(schema)) { - const id: string = schema.$id || schema.id + const id = schema.$id || schema.id if (id) { const url = new URL(id, baseURI) if (url.hash.length > 1) { diff --git a/packages/vc-export/package.json b/packages/vc-export/package.json index 83f0b49e..361f6958 100644 --- a/packages/vc-export/package.json +++ b/packages/vc-export/package.json @@ -30,7 +30,7 @@ "homepage": "https://github.com/dhiway/cord.js#readme", "devDependencies": { "@types/jsonld": "1.5.1", - "crypto-ld": "^3.7.0", + "crypto-ld": "^7.0.0", "rimraf": "^3.0.2", "typescript": "4.5.4" }, @@ -40,13 +40,14 @@ "@cord.network/network": "workspace:*", "@cord.network/types": "workspace:*", "@cord.network/utils": "workspace:*", + "@digitalbazaar/vc": "^4.0.0", + "@polkadot/api": "^8.0.0", "@polkadot/api-augment": "^8.0.0", "@polkadot/keyring": "^9.0.0", "@polkadot/types": "^8.0.0", "@polkadot/util": "^9.0.0", "@polkadot/util-crypto": "^9.0.0", - "jsonld": "^5.0.0", - "jsonld-signatures": "^9.0.0", - "vc-js": "^0.6.4" + "jsonld": "^6.0.0", + "jsonld-signatures": "^10.0.0" } } diff --git a/packages/vc-export/src/constants.ts b/packages/vc-export/src/constants.ts index d998af4c..3b08b697 100644 --- a/packages/vc-export/src/constants.ts +++ b/packages/vc-export/src/constants.ts @@ -6,6 +6,7 @@ export const DEFAULT_VERIFIABLE_CREDENTIAL_CONTEXT = export const CORD_CREDENTIAL_CONTEXT_URL = 'https://cord.network/contexts/credentials' + /** * Constant for default type. */ @@ -17,7 +18,8 @@ export const DEFAULT_VERIFIABLEPRESENTATION_TYPE = 'VerifiablePresentation' export const CORD_VERIFIABLE_CREDENTIAL_TYPE = 'CordCredential2020' -export const CORD_SIGNATURE_PROOF_TYPE = 'CordSignature2020' +export const CORD_STREAM_SIGNATURE_PROOF_TYPE = 'CordStreamSignature2020' +export const CORD_SELF_SIGNATURE_PROOF_TYPE = 'CordSelfSignature2020' export const CORD_ANCHORED_PROOF_TYPE = 'CordCredential2020' export const CORD_CREDENTIAL_DIGEST_PROOF_TYPE = 'CordCredentialDigest2020' diff --git a/packages/vc-export/src/exportToVerifiableCredential.ts b/packages/vc-export/src/exportToVerifiableCredential.ts index 7888bce5..f658a02d 100644 --- a/packages/vc-export/src/exportToVerifiableCredential.ts +++ b/packages/vc-export/src/exportToVerifiableCredential.ts @@ -6,7 +6,7 @@ import { decodeAddress } from '@polkadot/keyring' import { u8aToHex } from '@polkadot/util' import type { AnyJson } from '@polkadot/types/types' -import { Content, Identity } from '@cord.network/modules' +import { Content } from '@cord.network/modules' import type { ICredential, ISchema } from '@cord.network/types' import { signatureVerify } from '@polkadot/util-crypto' import { @@ -16,7 +16,7 @@ import { KeyTypesMap, CORD_ANCHORED_PROOF_TYPE, CORD_CREDENTIAL_DIGEST_PROOF_TYPE, - CORD_SIGNATURE_PROOF_TYPE, + CORD_STREAM_SIGNATURE_PROOF_TYPE, CORD_CREDENTIAL_CONTEXT_URL, CORD_VERIFIABLE_CREDENTIAL_TYPE, CORD_CREDENTIAL_IRI_PREFIX, @@ -26,10 +26,10 @@ import type { CredentialDigestProof, CredentialSchema, Proof, - CordSignatureProof, + CordStreamSignatureProof, VerifiableCredential, } from './types.js' -import { SDKErrors, Identifier } from '@cord.network/utils' +import { Identifier } from '@cord.network/utils' import { STREAM_PREFIX } from '@cord.network/types' export function fromCredentialIRI(credentialId: string): string { @@ -48,14 +48,13 @@ export function toCredentialIRI(streamId: string): string { export function fromCredential( input: ICredential, - holder: Identity, schemaType?: ISchema ): VerifiableCredential { const { contentHashes, evidenceIds, rootHash, - issuerSignature, + signatureProof, content, identifier, } = input.request @@ -112,8 +111,14 @@ export function fromCredential( credentialSchema, } - const keyType: string | undefined = - KeyTypesMap[signatureVerify('', issuerSignature, content.issuer).crypto] + let keyType: string | undefined + if (signatureProof) { + keyType = + KeyTypesMap[ + signatureVerify('', signatureProof?.signature, content.issuer).crypto + ] + } + if (!keyType) throw new TypeError( `Unknown signature type on credential.\nCurrently this handles ${JSON.stringify( @@ -121,23 +126,18 @@ export function fromCredential( )}\nReceived: ${keyType}` ) - // add cord signature proof (issuer) - // infer key type - if (input.stream.holder !== holder.address) { - throw new SDKErrors.ERROR_IDENTITY_MISMATCH() - } - - const sSProof: CordSignatureProof = { - type: CORD_SIGNATURE_PROOF_TYPE, - proofPurpose: 'assertionMethod', - verificationMethod: { - type: keyType, - publicKeyHex: u8aToHex(decodeAddress(content.holder)), - }, - signature: holder.signStr(rootHash), + if (signatureProof) { + const sSProof: CordStreamSignatureProof = { + type: CORD_STREAM_SIGNATURE_PROOF_TYPE, + proofPurpose: 'assertionMethod', + verificationMethod: { + type: keyType, + publicKeyHex: u8aToHex(decodeAddress(signatureProof.keyId)), + }, + signature: signatureProof.signature, + } + VC.proof.push(sSProof) } - VC.proof.push(sSProof) - // add credential proof const streamProof: CordStreamProof = { type: CORD_ANCHORED_PROOF_TYPE, diff --git a/packages/vc-export/src/index.ts b/packages/vc-export/src/index.ts index 5c06b013..92befd86 100644 --- a/packages/vc-export/src/index.ts +++ b/packages/vc-export/src/index.ts @@ -5,6 +5,6 @@ export * as constants from './constants.js' export * as verification from './verificationUtils.js' export * as presentation from './presentationUtils.js' export { fromCredential } from './exportToVerifiableCredential.js' -export * as vcjsSuites from './vc-js/index.js' +export * as vcjsSuites from './suites/index.js' export type { types } diff --git a/packages/vc-export/src/presentationUtils.ts b/packages/vc-export/src/presentationUtils.ts index 2f1aee4d..732c2447 100644 --- a/packages/vc-export/src/presentationUtils.ts +++ b/packages/vc-export/src/presentationUtils.ts @@ -2,20 +2,38 @@ * @packageDocumentation * @module PresentationUtils */ - -import { blake2AsHex } from '@polkadot/util-crypto' +import { decodeAddress } from '@polkadot/keyring' +import { blake2AsHex, signatureVerify } from '@polkadot/util-crypto' +import { u8aToHex } from '@polkadot/util' import jsonld from 'jsonld' -import { Crypto } from '@cord.network/utils' +import { SDKErrors, Identifier, Crypto } from '@cord.network/utils' +import { Identity } from '@cord.network/modules' import { CORD_CREDENTIAL_DIGEST_PROOF_TYPE, DEFAULT_VERIFIABLE_CREDENTIAL_CONTEXT, DEFAULT_VERIFIABLEPRESENTATION_TYPE, + CORD_SELF_SIGNATURE_PROOF_TYPE, + KeyTypesMap, } from './constants.js' import type { VerifiableCredential, VerifiablePresentation, CredentialDigestProof, + CordSelfSignatureProof, } from './types.js' +import { ACCOUNT_IDENTIFIER_PREFIX } from '@cord.network/types' + +export function makeSigningData( + rootHash: string, + createdAt: string, + challenge?: string | null +): Uint8Array { + return new Uint8Array([ + ...Crypto.coToUInt8(rootHash), + ...Crypto.coToUInt8(createdAt), + ...Crypto.coToUInt8(challenge), + ]) +} /** * This proof is added to a credential to prove that revealed properties were attested in the original credential. @@ -115,14 +133,55 @@ export async function removeProperties( */ export async function makePresentation( VC: VerifiableCredential, - showProperties: string[] + showProperties: string[], + creator: Identity, + challenge?: string ): Promise { const copied = await removeProperties(VC, showProperties) + + if ( + creator?.address !== + Identifier.getIdentifierKey( + VC.credentialSubject['@id']?.toString(), + ACCOUNT_IDENTIFIER_PREFIX + ) + ) { + throw new SDKErrors.ERROR_IDENTITY_MISMATCH() + } + const createdAt = new Date().toISOString() + const selfSignature = creator.signStr( + makeSigningData( + Identifier.getIdentifierHash(VC.credentialHash), + createdAt, + challenge + ) + ) + + const keyType: string | undefined = + KeyTypesMap[signatureVerify('', selfSignature, creator.address).crypto] + if (!keyType) + throw new TypeError( + `Unknown signature type on credential.\nCurrently this handles ${JSON.stringify( + Object.keys(KeyTypesMap) + )}\nReceived: ${keyType}` + ) + + const selfSProof: CordSelfSignatureProof = { + created: createdAt, + type: CORD_SELF_SIGNATURE_PROOF_TYPE, + proofPurpose: 'assertionMethod', + verificationMethod: { + type: keyType, + publicKeyHex: u8aToHex(decodeAddress(creator.address)), + }, + signature: selfSignature, + } + return { '@context': [DEFAULT_VERIFIABLE_CREDENTIAL_CONTEXT], type: [DEFAULT_VERIFIABLEPRESENTATION_TYPE], verifiableCredential: copied, holder: copied.credentialSubject['@id'] as string, - proof: [], + proof: [selfSProof], } } diff --git a/packages/vc-export/src/vc-js/context/context.json b/packages/vc-export/src/suites/context/context.json similarity index 100% rename from packages/vc-export/src/vc-js/context/context.json rename to packages/vc-export/src/suites/context/context.json diff --git a/packages/vc-export/src/vc-js/context/index.ts b/packages/vc-export/src/suites/context/index.ts similarity index 100% rename from packages/vc-export/src/vc-js/context/index.ts rename to packages/vc-export/src/suites/context/index.ts diff --git a/packages/vc-export/src/vc-js/documentLoader.ts b/packages/vc-export/src/suites/documentLoader.ts similarity index 90% rename from packages/vc-export/src/vc-js/documentLoader.ts rename to packages/vc-export/src/suites/documentLoader.ts index d2ea2f3e..616dc0b2 100644 --- a/packages/vc-export/src/vc-js/documentLoader.ts +++ b/packages/vc-export/src/suites/documentLoader.ts @@ -1,5 +1,5 @@ import type { RemoteDocument, Url } from 'jsonld/jsonld-spec' -import vcjs from 'vc-js' +import vcjs from '@digitalbazaar/vc' import { validationContexts } from './context/index.js' export async function documentLoader(url: Url): Promise { diff --git a/packages/vc-export/src/vc-js/examples/example-vc-old.json b/packages/vc-export/src/suites/examples/example-vc-old.json similarity index 100% rename from packages/vc-export/src/vc-js/examples/example-vc-old.json rename to packages/vc-export/src/suites/examples/example-vc-old.json diff --git a/packages/vc-export/src/vc-js/index.ts b/packages/vc-export/src/suites/index.ts similarity index 100% rename from packages/vc-export/src/vc-js/index.ts rename to packages/vc-export/src/suites/index.ts diff --git a/packages/vc-export/src/vc-js/suites/CordAbstractSuite.ts b/packages/vc-export/src/suites/suites/CordAbstractSuite.ts similarity index 100% rename from packages/vc-export/src/vc-js/suites/CordAbstractSuite.ts rename to packages/vc-export/src/suites/suites/CordAbstractSuite.ts diff --git a/packages/vc-export/src/vc-js/suites/CordAnchoredSuite.ts b/packages/vc-export/src/suites/suites/CordAnchoredSuite.ts similarity index 87% rename from packages/vc-export/src/vc-js/suites/CordAnchoredSuite.ts rename to packages/vc-export/src/suites/suites/CordAnchoredSuite.ts index 047dd767..da51a5c0 100644 --- a/packages/vc-export/src/vc-js/suites/CordAnchoredSuite.ts +++ b/packages/vc-export/src/suites/suites/CordAnchoredSuite.ts @@ -1,5 +1,6 @@ /* eslint-disable max-classes-per-file */ -import { Chain, ChainApiConnection } from '@cord.network/network' +import { ApiPromise } from '@polkadot/api' +import { ChainApiConnection } from '@cord.network/network' import type { DocumentLoader, ExpansionMap, @@ -24,12 +25,15 @@ class StreamError extends Error { } export default class CordAnchoredSuite extends CordAbstractSuite { - private readonly provider: Chain + private readonly provider: ApiPromise - constructor(options: { CordConnection: Chain }) { + constructor(options: { CordConnection: ApiPromise }) { // vc-js complains when there is no verificationMethod super({ type: CORD_ANCHORED_PROOF_TYPE, verificationMethod: '' }) - if (!options.CordConnection || !(options.CordConnection instanceof Chain)) + if ( + !options.CordConnection || + !(options.CordConnection instanceof ApiPromise) + ) throw new TypeError('CordConnection must be a Cord blockchain connection') this.provider = options.CordConnection } diff --git a/packages/vc-export/src/vc-js/suites/CordIntegritySuite.ts b/packages/vc-export/src/suites/suites/CordIntegritySuite.ts similarity index 100% rename from packages/vc-export/src/vc-js/suites/CordIntegritySuite.ts rename to packages/vc-export/src/suites/suites/CordIntegritySuite.ts diff --git a/packages/vc-export/src/vc-js/suites/CordSignatureSuite.ts b/packages/vc-export/src/suites/suites/CordSelfSignatureSuite.ts similarity index 77% rename from packages/vc-export/src/vc-js/suites/CordSignatureSuite.ts rename to packages/vc-export/src/suites/suites/CordSelfSignatureSuite.ts index 04cca9d7..1a6995df 100644 --- a/packages/vc-export/src/vc-js/suites/CordSignatureSuite.ts +++ b/packages/vc-export/src/suites/suites/CordSelfSignatureSuite.ts @@ -5,14 +5,17 @@ import type { VerificationResult, } from 'jsonld-signatures' import type { JsonLdObj } from 'jsonld/jsonld-spec' -import type { IPublicKeyRecord, CordSignatureProof } from '../../types.js' -import { verifyCordSignatureProof } from '../../verificationUtils.js' +import type { IPublicKeyRecord, CordSelfSignatureProof } from '../../types.js' +import { verifySelfSignatureProof } from '../../verificationUtils.js' import CordAbstractSuite from './CordAbstractSuite.js' -import { CORD_SIGNATURE_PROOF_TYPE } from '../../constants.js' +import { CORD_SELF_SIGNATURE_PROOF_TYPE } from '../../constants.js' -export default class CordSignatureSuite extends CordAbstractSuite { +export default class CordSelfSignatureSuite extends CordAbstractSuite { constructor() { - super({ type: CORD_SIGNATURE_PROOF_TYPE, verificationMethod: '' }) + super({ + type: CORD_SELF_SIGNATURE_PROOF_TYPE, + verificationMethod: '', + }) } public async verifyProof(options: { @@ -29,7 +32,7 @@ export default class CordSignatureSuite extends CordAbstractSuite { if (!proof || typeof proof !== 'object') throw new TypeError('proof must be a JsonLd object') const compactedDoc = await this.compactDoc(document, options) - const compactedProof = await this.compactProof( + const compactedProof = await this.compactProof( proof, options ) @@ -46,7 +49,7 @@ export default class CordSignatureSuite extends CordAbstractSuite { dereferenced.document as IPublicKeyRecord } // note that we currently don't check whether the public key in the proof is linked to the credential subject - const { verified, errors } = verifyCordSignatureProof( + const { verified, errors } = verifySelfSignatureProof( compactedDoc, compactedProof ) diff --git a/packages/vc-export/src/suites/suites/CordStreamSignatureSuite.ts b/packages/vc-export/src/suites/suites/CordStreamSignatureSuite.ts new file mode 100644 index 00000000..57a4d2b8 --- /dev/null +++ b/packages/vc-export/src/suites/suites/CordStreamSignatureSuite.ts @@ -0,0 +1,66 @@ +import type { + DocumentLoader, + ExpansionMap, + purposes, + VerificationResult, +} from 'jsonld-signatures' +import type { JsonLdObj } from 'jsonld/jsonld-spec' +import type { IPublicKeyRecord, CordStreamSignatureProof } from '../../types.js' +import { verifyStreamSignatureProof } from '../../verificationUtils.js' +import CordAbstractSuite from './CordAbstractSuite.js' +import { CORD_STREAM_SIGNATURE_PROOF_TYPE } from '../../constants.js' + +export default class CordStreamSignatureSuite extends CordAbstractSuite { + constructor() { + super({ + type: CORD_STREAM_SIGNATURE_PROOF_TYPE, + verificationMethod: '', + }) + } + + public async verifyProof(options: { + proof: JsonLdObj + document?: JsonLdObj + purpose?: purposes.ProofPurpose + documentLoader?: DocumentLoader + expansionMap?: ExpansionMap + }): Promise { + try { + const { document, proof, documentLoader } = options + if (!document || typeof document !== 'object') + throw new TypeError('document must be a JsonLd object') + if (!proof || typeof proof !== 'object') + throw new TypeError('proof must be a JsonLd object') + const compactedDoc = await this.compactDoc(document, options) + const compactedProof = await this.compactProof( + proof, + options + ) + if (typeof compactedProof.verificationMethod === 'string') { + const dereferenced = documentLoader + ? await documentLoader(compactedProof.verificationMethod) + : undefined + if (!dereferenced?.document) { + throw new Error( + 'verificationMethod could not be dereferenced; did you select an appropriate document loader?' + ) + } + compactedProof.verificationMethod = + dereferenced.document as IPublicKeyRecord + } + // note that we currently don't check whether the public key in the proof is linked to the credential subject + const { verified, errors } = verifyStreamSignatureProof( + compactedDoc, + compactedProof + ) + if (errors.length > 0) + return { + verified, + error: errors[0], + } + return { verified } + } catch (e: any) { + return { verified: false, error: e } + } + } +} diff --git a/packages/vc-export/src/suites/suites/index.ts b/packages/vc-export/src/suites/suites/index.ts new file mode 100644 index 00000000..3dc00276 --- /dev/null +++ b/packages/vc-export/src/suites/suites/index.ts @@ -0,0 +1,4 @@ +export * as CordIntegritySuite from './CordIntegritySuite.js' +export * as CordStreamSignatureSuite from './CordStreamSignatureSuite.js' +export * as CordSelfignatureSuite from './CordSelfSignatureSuite.js' +export * as CordAnchoredSuite from './CordAnchoredSuite.js' diff --git a/packages/vc-export/src/vc-js/types/crypto-ld.d.ts b/packages/vc-export/src/suites/types/crypto-ld.d.ts similarity index 100% rename from packages/vc-export/src/vc-js/types/crypto-ld.d.ts rename to packages/vc-export/src/suites/types/crypto-ld.d.ts diff --git a/packages/vc-export/src/vc-js/types/jsonld-signatures.d.ts b/packages/vc-export/src/suites/types/jsonld-signatures.d.ts similarity index 100% rename from packages/vc-export/src/vc-js/types/jsonld-signatures.d.ts rename to packages/vc-export/src/suites/types/jsonld-signatures.d.ts diff --git a/packages/vc-export/src/vc-js/types/vc.d.ts b/packages/vc-export/src/suites/types/vc.d.ts similarity index 95% rename from packages/vc-export/src/vc-js/types/vc.d.ts rename to packages/vc-export/src/suites/types/vc.d.ts index f4446fe4..97fae368 100644 --- a/packages/vc-export/src/vc-js/types/vc.d.ts +++ b/packages/vc-export/src/suites/types/vc.d.ts @@ -1,4 +1,4 @@ -declare module 'vc-js' { +declare module '@digitalbazaar/vc' { import type { DocumentLoader, ExpansionMap, diff --git a/packages/vc-export/src/types.ts b/packages/vc-export/src/types.ts index aa019d3d..c1a6be48 100644 --- a/packages/vc-export/src/types.ts +++ b/packages/vc-export/src/types.ts @@ -3,8 +3,8 @@ * @module VCExportTypes */ import type { AnyJson } from '@polkadot/types/types' -import type { IDidDocumentPublicKey } from '@cord.network/modules' -import type { ISchema } from '@cord.network/types' +// import type { IDidDocumentPublicKey } from '@cord.network/modules' +import type { ISchema, IIdentityPublicKey } from '@cord.network/types' import type { DEFAULT_VERIFIABLE_CREDENTIAL_CONTEXT, DEFAULT_VERIFIABLE_CREDENTIAL_TYPE, @@ -12,7 +12,8 @@ import type { JSON_SCHEMA_TYPE, CORD_ANCHORED_PROOF_TYPE, CORD_CREDENTIAL_DIGEST_PROOF_TYPE, - CORD_SIGNATURE_PROOF_TYPE, + CORD_STREAM_SIGNATURE_PROOF_TYPE, + CORD_SELF_SIGNATURE_PROOF_TYPE, } from './constants.js' export interface Proof { @@ -22,11 +23,11 @@ export interface Proof { [key: string]: any } -export type IPublicKeyRecord = Partial & - Pick +export type IPublicKeyRecord = Partial & + Pick -export interface CordSignatureProof extends Proof { - type: typeof CORD_SIGNATURE_PROOF_TYPE +export interface CordStreamSignatureProof extends Proof { + type: typeof CORD_STREAM_SIGNATURE_PROOF_TYPE verificationMethod: string | IPublicKeyRecord signature: string } @@ -41,6 +42,13 @@ export interface CredentialDigestProof extends Proof { // salted hashes of statements in credentialSubject to allow selective disclosure. contentHashes: string[] } +export interface CordSelfSignatureProof extends Proof { + created: string + type: typeof CORD_SELF_SIGNATURE_PROOF_TYPE + verificationMethod: string | IPublicKeyRecord + signature: string + challenge?: string +} export interface CredentialSchema { '@id': string diff --git a/packages/vc-export/src/vc-js/suites/IntegritySuite.spec.ts b/packages/vc-export/src/vc-js/suites/IntegritySuite.spec.ts deleted file mode 100644 index 99b0605b..00000000 --- a/packages/vc-export/src/vc-js/suites/IntegritySuite.spec.ts +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @group unit/vc-js - */ - -import jsigs, { purposes } from 'jsonld-signatures' -import vcjs from 'vc-js' -import jsonld from 'jsonld' -import Suite from './CordIntegritySuite' -import credential from '../examples/example-vc.json' -import documentLoader from '../documentLoader' -import type { CredentialDigestProof, VerifiableCredential } from '../../types' -import { CORD_CREDENTIAL_DIGEST_PROOF_TYPE } from '../../constants' - -let suite: Suite -let purpose: purposes.ProofPurpose -let proof: CredentialDigestProof - -beforeAll(async () => { - suite = new Suite() - purpose = new purposes.AssertionProofPurpose() - credential.proof.some((p) => { - if (p.type === CORD_CREDENTIAL_DIGEST_PROOF_TYPE) { - proof = p as CredentialDigestProof - return true - } - return false - }) -}) - -describe('jsigs', () => { - describe('proof matching', () => { - it('purpose matches compacted proof', async () => { - const compactedProof = await jsonld.compact( - { ...proof, '@context': credential['@context'] }, - 'https://w3id.org/security/v2', - { documentLoader, compactToRelative: false } - ) - await expect(purpose.match(compactedProof, {})).resolves.toBe(true) - await expect( - purpose.match(compactedProof, { document: credential, documentLoader }) - ).resolves.toBe(true) - }) - - it('suite matches proof', async () => { - const proofWithContext = { ...proof, '@context': credential['@context'] } - await expect(suite.matchProof({ proof: proofWithContext })).resolves.toBe( - true - ) - await expect( - suite.matchProof({ - proof: proofWithContext, - document: credential, - purpose, - documentLoader, - }) - ).resolves.toBe(true) - }) - }) - - describe('verification', () => { - beforeAll(async () => { - suite = new Suite() - }) - - it('verifies Cord Credential Digest Proof', async () => { - await expect( - jsigs.verify(credential, { suite, purpose, documentLoader }) - ).resolves.toMatchObject({ verified: true }) - }) - - it('verifies Cord Credential Digest Proof with props removed', async () => { - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - const { name, ...credentialSubject } = credential.credentialSubject - expect(credentialSubject).not.toHaveProperty('name') - await expect( - jsigs.verify( - { ...credential, credentialSubject }, - { suite, purpose, documentLoader } - ) - ).resolves.toMatchObject({ verified: true }) - }) - }) - - describe('tamper detection', () => { - beforeAll(async () => { - suite = new Suite() - }) - - let tamperCred: VerifiableCredential - beforeEach(() => { - tamperCred = JSON.parse(JSON.stringify(credential)) - }) - - it('detects tampering on props', async () => { - tamperCred.credentialSubject.name = 'MacGyver' - await expect( - jsigs.verify(tamperCred, { suite, purpose, documentLoader }) - ).resolves.toMatchObject({ verified: false }) - }) - }) -}) - -describe('vc-js', () => { - describe('verification', () => { - beforeAll(async () => { - suite = new Suite() - }) - - it('verifies Cord Credential Digest Proof', async () => { - await expect( - vcjs.verifyCredential({ credential, suite, purpose, documentLoader }) - ).resolves.toMatchObject({ verified: true }) - }) - - it('verifies Cord Credential Digest Proof with props removed', async () => { - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - const { name, ...credentialSubject } = credential.credentialSubject - expect(credentialSubject).not.toHaveProperty('name') - await expect( - vcjs.verifyCredential({ - credential: { ...credential, credentialSubject }, - suite, - purpose, - documentLoader, - }) - ).resolves.toMatchObject({ verified: true }) - }) - }) - - describe('tamper detection', () => { - beforeAll(async () => { - suite = new Suite() - }) - - let tamperCred: VerifiableCredential - beforeEach(() => { - tamperCred = JSON.parse(JSON.stringify(credential)) - }) - - it('detects tampering on props', async () => { - tamperCred.credentialSubject.name = 'MacGyver' - await expect( - vcjs.verifyCredential({ - credential: tamperCred, - suite, - purpose, - documentLoader, - }) - ).resolves.toMatchObject({ verified: false }) - }) - }) -}) diff --git a/packages/vc-export/src/vc-js/suites/index.ts b/packages/vc-export/src/vc-js/suites/index.ts deleted file mode 100644 index 29ab620e..00000000 --- a/packages/vc-export/src/vc-js/suites/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * as CordIntegritySuite from './CordIntegritySuite.js' -export * as CordSignatureSuite from './CordSignatureSuite.js' -export * as CordAnchoredSuite from './CordAnchoredSuite.js' diff --git a/packages/vc-export/src/verificationUtils.ts b/packages/vc-export/src/verificationUtils.ts index f1bcc47a..05917a59 100644 --- a/packages/vc-export/src/verificationUtils.ts +++ b/packages/vc-export/src/verificationUtils.ts @@ -3,25 +3,27 @@ * @module VerificationUtils */ -// import { u8aConcat, hexToU8a, u8aToHex } from '@polkadot/util' import { signatureVerify, blake2AsHex } from '@polkadot/util-crypto' import jsonld from 'jsonld' import { Stream, Schema } from '@cord.network/modules' import { Crypto, JsonSchema, Identifier } from '@cord.network/utils' import { - CORD_SIGNATURE_PROOF_TYPE, + CORD_STREAM_SIGNATURE_PROOF_TYPE, + CORD_SELF_SIGNATURE_PROOF_TYPE, CORD_ANCHORED_PROOF_TYPE, CORD_CREDENTIAL_DIGEST_PROOF_TYPE, KeyTypesMap, } from './constants.js' import type { VerifiableCredential, - CordSignatureProof, + CordStreamSignatureProof, + CordSelfSignatureProof, CordStreamProof, CredentialDigestProof, } from './types.js' import { Hash } from '@cord.network/types' import { fromCredentialIRI } from './exportToVerifiableCredential.js' +import { makeSigningData } from './presentationUtils.js' import { HexString } from '@polkadot/util/types.js' export interface VerificationResult { @@ -47,7 +49,7 @@ const PROOF_MALFORMED_ERROR = (reason: string): Error => new Error(`Proof malformed: ${reason}`) /** - * Verifies a self signed proof (holder signature) against a CORD Verifiable Credential. + * Verifies a stream signed proof (holder signature) against a CORD Verifiable Credential. * This entails computing the root hash from the hashes contained in the `protected` section of the credentialSubject. * The resulting hash is then verified against the signature and public key contained in the proof (the latter * could be a DID URI in the future). It is also expected to by identical to the credential id. @@ -56,15 +58,15 @@ const PROOF_MALFORMED_ERROR = (reason: string): Error => * @param proof CORD self signed proof object. * @returns Object indicating whether proof could be verified. */ -export function verifyCordSignatureProof( +export function verifyStreamSignatureProof( credential: VerifiableCredential, - proof: CordSignatureProof + proof: CordStreamSignatureProof ): VerificationResult { const result: VerificationResult = { verified: true, errors: [] } try { // check proof const type = proof['@type'] || proof.type - if (type !== CORD_SIGNATURE_PROOF_TYPE) + if (type !== CORD_STREAM_SIGNATURE_PROOF_TYPE) throw new Error('Proof type mismatch') if (!proof.signature) throw PROOF_MALFORMED_ERROR('signature missing') const { verificationMethod } = proof @@ -231,6 +233,7 @@ export async function verifyCredentialDigestProof( } if (typeof credential.credentialSubject !== 'object') throw CREDENTIAL_MALFORMED_ERROR('credential subject missing') + const rootHash = verifyRootHash(credential, proof) // throw if root hash does not match expected (=id) const expectedRootHash = Identifier.getIdentifierHash( @@ -282,6 +285,74 @@ export async function verifyCredentialDigestProof( } } +/** + * Verifies a self signed proof (holder signature) + * This entails computing the root hash from the hashes contained in the `protected` section of the credentialSubject. + * The resulting hash is then verified against the signature, created date, + * challenge and thepublic key contained in the proof. + * + * @param credential Verifiable Credential to verify proof against. + * @param proof CORD self signed proof object. + * @returns Object indicating whether proof could be verified. + */ +export function verifySelfSignatureProof( + credential: VerifiableCredential, + proof: CordSelfSignatureProof, + challenge?: string +): VerificationResult { + const result: VerificationResult = { verified: true, errors: [] } + try { + // check proof + const type = proof['@type'] || proof.type + if (type !== CORD_SELF_SIGNATURE_PROOF_TYPE) + throw new Error('Proof type mismatch') + if (!proof.signature) throw PROOF_MALFORMED_ERROR('signature missing') + if (!proof.created) throw PROOF_MALFORMED_ERROR('creattion time missing') + const { verificationMethod } = proof + if ( + !( + typeof verificationMethod === 'object' && + verificationMethod.publicKeyHex + ) + ) { + throw PROOF_MALFORMED_ERROR( + 'proof must contain public key; resolve did key references beforehand' + ) + } + const keyType = verificationMethod.type || verificationMethod['@type'] + if (!Object.values(KeyTypesMap).includes(keyType)) + throw PROOF_MALFORMED_ERROR( + `signature type unknown; expected one of ${JSON.stringify( + Object.values(KeyTypesMap) + )}, got "${verificationMethod.type}"` + ) + const signerPubKey = verificationMethod.publicKeyHex + + const rootHash = Identifier.getIdentifierHash( + fromCredentialIRI(credential.credentialHash) + ) + const proofData = makeSigningData(rootHash, proof.created, challenge) + + // validate signature over calculated proofData + // signatureVerify can handle all required signature types out of the box + const verification = signatureVerify( + proofData, + proof.signature, + signerPubKey + ) + if ( + !(verification.isValid && KeyTypesMap[verification.crypto] === keyType) + ) { + throw new Error('signature could not be verified') + } + return result + } catch (e) { + result.verified = false + result.errors = [e as Error] + return result + } +} + export function validateSchema( credential: VerifiableCredential ): VerificationResult { diff --git a/tsconfig.build.json b/tsconfig.build.json index cc04ed66..243c14fb 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -2,9 +2,7 @@ "compilerOptions": { "module": "CommonJS", "target": "es2017", - "lib": [ - "es6" - ], + "lib": ["es6"], "sourceMap": false, "strict": true, "allowJs": true, @@ -20,12 +18,10 @@ "strictNullChecks": true, "suppressImplicitAnyIndexErrors": true, "noUnusedLocals": true, - "outDir": "./dist", - "skipLibCheck": true, + "skipLibCheck": true }, "exclude": [ - "node_modules/**/*", - "lib/**/*", - "./dist/**/*" + "node_modules", + "lib" ] -} \ No newline at end of file +} diff --git a/tsconfig.json b/tsconfig.json index 41c4a2c3..19a78894 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,6 @@ { "extends": "./tsconfig.build.json", - "exclude": [ - "docs/**/*" - ], + "include": ["packages/**/*", "jest-setup/*", "docs/*"], "compilerOptions": { "baseUrl": "./packages", "sourceMap": true, @@ -11,11 +9,11 @@ "@cord.network/config": ["config/src"], "@cord.network/modules": ["modules/src"], "@cord.network/messaging": ["messaging/src"], - "@cord.network/api": ["api/src"], + "@cord.network/sdk": ["sdk/src"], "@cord.network/types": ["types/src"], "@cord.network/utils": ["utils/src"], - "@cord.network/credential": ["credential/src"], "@cord.network/vc-export": ["vc-export/src"], + "@cord.network/docs": ["docs/src"], } }, "skipLibCheck": true diff --git a/typedoc.js b/typedoc.js deleted file mode 100644 index cf289d67..00000000 --- a/typedoc.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - exclude: [ - 'demo/**/**', - '**/*spec.ts', - '**/__mocks__/**', - '**/testingTools/**', - '**/*.js', - '**/node_modules/**', - '**/__integrationtests__/**', - '**/index.ts', - ], - entryPoints: [ - "packages/api/src/index.ts" - ], - excludeExternals: true, - //excludeNotExported: true, - excludePrivate: true, - //stripInternal: true, - hideGenerator: true, - name: '@cord.network/api', - validation: { - invalidLink: true, - }, - tsconfig: 'tsconfig.json', - readme: 'README.md', -} diff --git a/yarn.lock b/yarn.lock index 79b34634..c53bef6f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,190 +24,188 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7": - version: 7.16.7 - resolution: "@babel/code-frame@npm:7.16.7" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/code-frame@npm:7.18.6" dependencies: - "@babel/highlight": ^7.16.7 - checksum: db2f7faa31bc2c9cf63197b481b30ea57147a5fc1a6fab60e5d6c02cdfbf6de8e17b5121f99917b3dabb5eeb572da078312e70697415940383efc140d4e0808b + "@babel/highlight": ^7.18.6 + checksum: 195e2be3172d7684bf95cff69ae3b7a15a9841ea9d27d3c843662d50cdd7d6470fd9c8e64be84d031117e4a4083486effba39f9aef6bbb2c89f7f21bcfba33ba languageName: node linkType: hard -"@babel/compat-data@npm:^7.17.10": - version: 7.17.10 - resolution: "@babel/compat-data@npm:7.17.10" - checksum: e85051087cd4690de5061909a2dd2d7f8b6434a3c2e30be6c119758db2027ae1845bcd75a81127423dd568b706ac6994a1a3d7d701069a23bf5cfe900728290b +"@babel/compat-data@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/compat-data@npm:7.18.6" + checksum: fd73a1bd7bc29be5528d2ef78248929ed3ee72e0edb69cef6051e0aad0bf8087594db6cd9e981f0d7f5bfc274fdbb77306d8abea8ceb71e95c18afc3ebd81828 languageName: node linkType: hard "@babel/core@npm:^7.1.0, @babel/core@npm:^7.12.3, @babel/core@npm:^7.7.2, @babel/core@npm:^7.8.0": - version: 7.18.0 - resolution: "@babel/core@npm:7.18.0" + version: 7.18.6 + resolution: "@babel/core@npm:7.18.6" dependencies: "@ampproject/remapping": ^2.1.0 - "@babel/code-frame": ^7.16.7 - "@babel/generator": ^7.18.0 - "@babel/helper-compilation-targets": ^7.17.10 - "@babel/helper-module-transforms": ^7.18.0 - "@babel/helpers": ^7.18.0 - "@babel/parser": ^7.18.0 - "@babel/template": ^7.16.7 - "@babel/traverse": ^7.18.0 - "@babel/types": ^7.18.0 + "@babel/code-frame": ^7.18.6 + "@babel/generator": ^7.18.6 + "@babel/helper-compilation-targets": ^7.18.6 + "@babel/helper-module-transforms": ^7.18.6 + "@babel/helpers": ^7.18.6 + "@babel/parser": ^7.18.6 + "@babel/template": ^7.18.6 + "@babel/traverse": ^7.18.6 + "@babel/types": ^7.18.6 convert-source-map: ^1.7.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.1 semver: ^6.3.0 - checksum: 350b7724a48c80b76f8af11e3cac1ad8ec9021325389f5ae20c713b10d4359c5e60aa7e71a309a3e1893826c46e72eef5df4978eb63eaabc403e8cc4ce5e94fc + checksum: 711459ebf7afab7b8eff88b7155c3f4a62690545f1c8c2eb6ba5ebaed01abeecb984cf9657847a2151ad24a5645efce765832aa343ce0f0386f311b67b59589a languageName: node linkType: hard -"@babel/generator@npm:^7.18.0, @babel/generator@npm:^7.7.2": - version: 7.18.0 - resolution: "@babel/generator@npm:7.18.0" +"@babel/generator@npm:^7.18.6, @babel/generator@npm:^7.7.2": + version: 7.18.7 + resolution: "@babel/generator@npm:7.18.7" dependencies: - "@babel/types": ^7.18.0 - "@jridgewell/gen-mapping": ^0.3.0 + "@babel/types": ^7.18.7 + "@jridgewell/gen-mapping": ^0.3.2 jsesc: ^2.5.1 - checksum: 0854b21d94f99e3ac68249a9bbaa0c3a914a600c69c12fffa4a01377d89282174a67e619654e401be4c791414a1d5e825671f089f1c2407694a494dcfab8b06c + checksum: aad4b6873130165e9483af2888bce5a3a5ad9cca0757fc90ae11a0396757d0b295a3bff49282c8df8ab01b31972cc855ae88fd9ddc9ab00d9427dc0e01caeea9 languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.17.10": - version: 7.17.10 - resolution: "@babel/helper-compilation-targets@npm:7.17.10" +"@babel/helper-compilation-targets@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-compilation-targets@npm:7.18.6" dependencies: - "@babel/compat-data": ^7.17.10 - "@babel/helper-validator-option": ^7.16.7 + "@babel/compat-data": ^7.18.6 + "@babel/helper-validator-option": ^7.18.6 browserslist: ^4.20.2 semver: ^6.3.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 5f547c7ebd372e90fa72c2aaea867e7193166e9f469dec5acde4f0e18a78b80bdca8e02a0f641f3e998be984fb5b802c729a9034faaee8b1a9ef6670cb76f120 + checksum: f09ddaddc83c241cb7a040025e2ba558daa1c950ce878604d91230aed8d8a90f10dfd5bb0b67bc5b3db8af1576a0d0dac1d65959a06a17259243dbb5730d0ed1 languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.16.7": - version: 7.16.7 - resolution: "@babel/helper-environment-visitor@npm:7.16.7" - dependencies: - "@babel/types": ^7.16.7 - checksum: c03a10105d9ebd1fe632a77356b2e6e2f3c44edba9a93b0dc3591b6a66bd7a2e323dd9502f9ce96fc6401234abff1907aa877b6674f7826b61c953f7c8204bbe +"@babel/helper-environment-visitor@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-environment-visitor@npm:7.18.6" + checksum: 64fce65a26efb50d2496061ab2de669dc4c42175a8e05c82279497127e5c542538ed22b38194f6f5a4e86bed6ef5a4890aed23408480db0555728b4ca660fc9c languageName: node linkType: hard -"@babel/helper-function-name@npm:^7.17.9": - version: 7.17.9 - resolution: "@babel/helper-function-name@npm:7.17.9" +"@babel/helper-function-name@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-function-name@npm:7.18.6" dependencies: - "@babel/template": ^7.16.7 - "@babel/types": ^7.17.0 - checksum: a59b2e5af56d8f43b9b0019939a43774754beb7cb01a211809ca8031c71890999d07739e955343135ec566c4d8ff725435f1f60fb0af3bb546837c1f9f84f496 + "@babel/template": ^7.18.6 + "@babel/types": ^7.18.6 + checksum: bf84c2e0699aa07c3559d4262d199d4a9d0320037c2932efe3246866c3e01ce042c9c2131b5db32ba2409a9af01fb468171052819af759babc8ca93bdc6c9aeb languageName: node linkType: hard -"@babel/helper-hoist-variables@npm:^7.16.7": - version: 7.16.7 - resolution: "@babel/helper-hoist-variables@npm:7.16.7" +"@babel/helper-hoist-variables@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-hoist-variables@npm:7.18.6" dependencies: - "@babel/types": ^7.16.7 - checksum: 6ae1641f4a751cd9045346e3f61c3d9ec1312fd779ab6d6fecfe2a96e59a481ad5d7e40d2a840894c13b3fd6114345b157f9e3062fc5f1580f284636e722de60 + "@babel/types": ^7.18.6 + checksum: fd9c35bb435fda802bf9ff7b6f2df06308a21277c6dec2120a35b09f9de68f68a33972e2c15505c1a1a04b36ec64c9ace97d4a9e26d6097b76b4396b7c5fa20f languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.16.7": - version: 7.16.7 - resolution: "@babel/helper-module-imports@npm:7.16.7" +"@babel/helper-module-imports@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-module-imports@npm:7.18.6" dependencies: - "@babel/types": ^7.16.7 - checksum: ddd2c4a600a2e9a4fee192ab92bf35a627c5461dbab4af31b903d9ba4d6b6e59e0ff3499fde4e2e9a0eebe24906f00b636f8b4d9bd72ff24d50e6618215c3212 + "@babel/types": ^7.18.6 + checksum: f393f8a3b3304b1b7a288a38c10989de754f01d29caf62ce7c4e5835daf0a27b81f3ac687d9d2780d39685aae7b55267324b512150e7b2be967b0c493b6a1def languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.18.0": - version: 7.18.0 - resolution: "@babel/helper-module-transforms@npm:7.18.0" +"@babel/helper-module-transforms@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-module-transforms@npm:7.18.6" dependencies: - "@babel/helper-environment-visitor": ^7.16.7 - "@babel/helper-module-imports": ^7.16.7 - "@babel/helper-simple-access": ^7.17.7 - "@babel/helper-split-export-declaration": ^7.16.7 - "@babel/helper-validator-identifier": ^7.16.7 - "@babel/template": ^7.16.7 - "@babel/traverse": ^7.18.0 - "@babel/types": ^7.18.0 - checksum: 824c3967c08d75bb36adc18c31dcafebcd495b75b723e2e17c6185e88daf5c6db62a6a75d9f791b5f38618a349e7cb32503e715a1b9a4e8bad4d0f43e3e6b523 + "@babel/helper-environment-visitor": ^7.18.6 + "@babel/helper-module-imports": ^7.18.6 + "@babel/helper-simple-access": ^7.18.6 + "@babel/helper-split-export-declaration": ^7.18.6 + "@babel/helper-validator-identifier": ^7.18.6 + "@babel/template": ^7.18.6 + "@babel/traverse": ^7.18.6 + "@babel/types": ^7.18.6 + checksum: 75d90be9ecd314fe2f1b668ce065d7e8b3dff82eddea88480259c5d4bd54f73a909d0998909ffe734a44ba8be85ba233359033071cc800db209d37173bd26db2 languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.17.12, @babel/helper-plugin-utils@npm:^7.8.0": - version: 7.17.12 - resolution: "@babel/helper-plugin-utils@npm:7.17.12" - checksum: 4813cf0ddb0f143de032cb88d4207024a2334951db330f8216d6fa253ea320c02c9b2667429ef1a34b5e95d4cfbd085f6cb72d418999751c31d0baf2422cc61d +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.8.0": + version: 7.18.6 + resolution: "@babel/helper-plugin-utils@npm:7.18.6" + checksum: 3dbfceb6c10fdf6c78a0e57f24e991ff8967b8a0bd45fe0314fb4a8ccf7c8ad4c3778c319a32286e7b1f63d507173df56b4e69fb31b71e1b447a73efa1ca723e languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.17.7": - version: 7.17.7 - resolution: "@babel/helper-simple-access@npm:7.17.7" +"@babel/helper-simple-access@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-simple-access@npm:7.18.6" dependencies: - "@babel/types": ^7.17.0 - checksum: 58a9bfd054720024f6ff47fbb113c96061dc2bd31a5e5285756bd3c2e83918c6926900e00150d0fb175d899494fe7d69bf2a8b278c32ef6f6bea8d032e6a3831 + "@babel/types": ^7.18.6 + checksum: 37cd36eef199e0517845763c1e6ff6ea5e7876d6d707a6f59c9267c547a50aa0e84260ba9285d49acfaf2cfa0a74a772d92967f32ac1024c961517d40b6c16a5 languageName: node linkType: hard -"@babel/helper-split-export-declaration@npm:^7.16.7": - version: 7.16.7 - resolution: "@babel/helper-split-export-declaration@npm:7.16.7" +"@babel/helper-split-export-declaration@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-split-export-declaration@npm:7.18.6" dependencies: - "@babel/types": ^7.16.7 - checksum: e10aaf135465c55114627951b79115f24bc7af72ecbb58d541d66daf1edaee5dde7cae3ec8c3639afaf74526c03ae3ce723444e3b5b3dc77140c456cd84bcaa1 + "@babel/types": ^7.18.6 + checksum: c6d3dede53878f6be1d869e03e9ffbbb36f4897c7cc1527dc96c56d127d834ffe4520a6f7e467f5b6f3c2843ea0e81a7819d66ae02f707f6ac057f3d57943a2b languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.16.7": - version: 7.16.7 - resolution: "@babel/helper-validator-identifier@npm:7.16.7" - checksum: dbb3db9d184343152520a209b5684f5e0ed416109cde82b428ca9c759c29b10c7450657785a8b5c5256aa74acc6da491c1f0cf6b784939f7931ef82982051b69 +"@babel/helper-validator-identifier@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-validator-identifier@npm:7.18.6" + checksum: e295254d616bbe26e48c196a198476ab4d42a73b90478c9842536cf910ead887f5af6b5c4df544d3052a25ccb3614866fa808dc1e3a5a4291acd444e243c0648 languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.16.7": - version: 7.16.7 - resolution: "@babel/helper-validator-option@npm:7.16.7" - checksum: c5ccc451911883cc9f12125d47be69434f28094475c1b9d2ada7c3452e6ac98a1ee8ddd364ca9e3f9855fcdee96cdeafa32543ebd9d17fee7a1062c202e80570 +"@babel/helper-validator-option@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-validator-option@npm:7.18.6" + checksum: f9cc6eb7cc5d759c5abf006402180f8d5e4251e9198197428a97e05d65eb2f8ae5a0ce73b1dfd2d35af41d0eb780627a64edf98a4e71f064eeeacef8de58f2cf languageName: node linkType: hard -"@babel/helpers@npm:^7.18.0": - version: 7.18.0 - resolution: "@babel/helpers@npm:7.18.0" +"@babel/helpers@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helpers@npm:7.18.6" dependencies: - "@babel/template": ^7.16.7 - "@babel/traverse": ^7.18.0 - "@babel/types": ^7.18.0 - checksum: 3f41631c0797b052cc22337ee56290700fe7db7bc06b847fcdf2c0043cddc35861855a1acc4c948397838675d2dc694f4fb1b102d1c7eb484ea01e9029916b55 + "@babel/template": ^7.18.6 + "@babel/traverse": ^7.18.6 + "@babel/types": ^7.18.6 + checksum: 5dea4fa53776703ae4190cacd3f81464e6e00cf0b6908ea9b0af2b3d9992153f3746dd8c33d22ec198f77a8eaf13a273d83cd8847f7aef983801e7bfafa856ec languageName: node linkType: hard -"@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.16.7": - version: 7.17.12 - resolution: "@babel/highlight@npm:7.17.12" +"@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/highlight@npm:7.18.6" dependencies: - "@babel/helper-validator-identifier": ^7.16.7 + "@babel/helper-validator-identifier": ^7.18.6 chalk: ^2.0.0 js-tokens: ^4.0.0 - checksum: 841a11aa353113bcce662b47085085a379251bf8b09054e37e1e082da1bf0d59355a556192a6b5e9ee98e8ee6f1f2831ac42510633c5e7043e3744dda2d6b9d6 + checksum: 92d8ee61549de5ff5120e945e774728e5ccd57fd3b2ed6eace020ec744823d4a98e242be1453d21764a30a14769ecd62170fba28539b211799bbaf232bbb2789 languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.16.7, @babel/parser@npm:^7.18.0": - version: 7.18.0 - resolution: "@babel/parser@npm:7.18.0" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/parser@npm:7.18.6" bin: parser: ./bin/babel-parser.js - checksum: 253b5828bf4a0b443301baedc5993d6f7f35aa0d81cf8f2f2f53940904b7067eab7bd2380aee4b3be1d8efd5ae1008eb0fad19bde28f5fbc213c0fdf9a414466 + checksum: 533ffc26667b7e2e0d87ae11368d90b6a3a468734d6dfe9c4697c24f48373cf9cc35ee08e416728f087fc56531b68022f752097941feddc60e0223d69a4d4cad languageName: node linkType: hard @@ -344,70 +342,61 @@ __metadata: linkType: hard "@babel/plugin-syntax-typescript@npm:^7.7.2": - version: 7.17.12 - resolution: "@babel/plugin-syntax-typescript@npm:7.17.12" + version: 7.18.6 + resolution: "@babel/plugin-syntax-typescript@npm:7.18.6" dependencies: - "@babel/helper-plugin-utils": ^7.17.12 + "@babel/helper-plugin-utils": ^7.18.6 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 50ab09f1953a2b0586cff9e29bf7cea3d886b48c1361a861687c2aef46356c6d73778c3341b0c051dc82a34417f19e9d759ae918353c5a98d25e85f2f6d24181 - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.17.9, @babel/runtime@npm:^7.18.3": - version: 7.18.3 - resolution: "@babel/runtime@npm:7.18.3" - dependencies: - regenerator-runtime: ^0.13.4 - checksum: db8526226aa02cfa35a5a7ac1a34b5f303c62a1f000c7db48cb06c6290e616483e5036ab3c4e7a84d0f3be6d4e2148d5fe5cec9564bf955f505c3e764b83d7f1 + checksum: 2cde73725ec51118ebf410bf02d78781c03fa4d3185993fcc9d253b97443381b621c44810084c5dd68b92eb8bdfae0e5b163e91b32bebbb33852383d1815c05d languageName: node linkType: hard -"@babel/runtime@npm:^7.9.6": - version: 7.18.0 - resolution: "@babel/runtime@npm:7.18.0" +"@babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.9.6": + version: 7.18.6 + resolution: "@babel/runtime@npm:7.18.6" dependencies: regenerator-runtime: ^0.13.4 - checksum: 9d0caa5fe690623fb6c5df6fb3b3581d227b55ef9f7c35eba0da83d10aa756669a81fe521ac4dbc007e5790716bac40ebe71ff098e2d1a9599dd696a282a3e95 + checksum: 8b707b64ae0524db617d0c49933b258b96376a38307dc0be8fb42db5697608bcc1eba459acce541e376cff5ed5c5287d24db5780bd776b7c75ba2c2e26ff8a2c languageName: node linkType: hard -"@babel/template@npm:^7.16.7, @babel/template@npm:^7.3.3": - version: 7.16.7 - resolution: "@babel/template@npm:7.16.7" +"@babel/template@npm:^7.18.6, @babel/template@npm:^7.3.3": + version: 7.18.6 + resolution: "@babel/template@npm:7.18.6" dependencies: - "@babel/code-frame": ^7.16.7 - "@babel/parser": ^7.16.7 - "@babel/types": ^7.16.7 - checksum: 10cd112e89276e00f8b11b55a51c8b2f1262c318283a980f4d6cdb0286dc05734b9aaeeb9f3ad3311900b09bc913e02343fcaa9d4a4f413964aaab04eb84ac4a + "@babel/code-frame": ^7.18.6 + "@babel/parser": ^7.18.6 + "@babel/types": ^7.18.6 + checksum: cb02ed804b7b1938dbecef4e01562013b80681843dd391933315b3dd9880820def3b5b1bff6320d6e4c6a1d63d1d5799630d658ec6b0369c5505e7e4029c38fb languageName: node linkType: hard -"@babel/traverse@npm:^7.18.0, @babel/traverse@npm:^7.7.2": - version: 7.18.0 - resolution: "@babel/traverse@npm:7.18.0" +"@babel/traverse@npm:^7.18.6, @babel/traverse@npm:^7.7.2": + version: 7.18.6 + resolution: "@babel/traverse@npm:7.18.6" dependencies: - "@babel/code-frame": ^7.16.7 - "@babel/generator": ^7.18.0 - "@babel/helper-environment-visitor": ^7.16.7 - "@babel/helper-function-name": ^7.17.9 - "@babel/helper-hoist-variables": ^7.16.7 - "@babel/helper-split-export-declaration": ^7.16.7 - "@babel/parser": ^7.18.0 - "@babel/types": ^7.18.0 + "@babel/code-frame": ^7.18.6 + "@babel/generator": ^7.18.6 + "@babel/helper-environment-visitor": ^7.18.6 + "@babel/helper-function-name": ^7.18.6 + "@babel/helper-hoist-variables": ^7.18.6 + "@babel/helper-split-export-declaration": ^7.18.6 + "@babel/parser": ^7.18.6 + "@babel/types": ^7.18.6 debug: ^4.1.0 globals: ^11.1.0 - checksum: b80b49ba5cead42c4b09bdfbe926d94179f884d35319a0a3ab5a798c85f16102a7342799fac928b3041337ea2c3f5194f17c4a08f611a474de6eea719b640dd4 + checksum: 5427a9db63984b2600f62b257dab18e3fc057997b69d708573bfc88eb5eacd6678fb24fddba082d6ac050734b8846ce110960be841ea1e461d66e2cde72b6b07 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.16.7, @babel/types@npm:^7.17.0, @babel/types@npm:^7.18.0, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": - version: 7.18.0 - resolution: "@babel/types@npm:7.18.0" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.7, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": + version: 7.18.7 + resolution: "@babel/types@npm:7.18.7" dependencies: - "@babel/helper-validator-identifier": ^7.16.7 + "@babel/helper-validator-identifier": ^7.18.6 to-fast-properties: ^2.0.0 - checksum: 151485f94c929171fd6539430c0ae519e8bb67fbc0d856b285328f5e6ecbaf4237b52d7a581b413f5e7b6268d31a4db6ca9bc01372b284b2966aa473fc902f27 + checksum: 3114ce161c4ebcb70271e168aa5af5cecedf3278209161d5ba6124bd3f9cb02e3f3ace587ad1b53f7baa153b6b3714720721c72a9ef3ec451663862f9cc1f014 languageName: node linkType: hard @@ -588,30 +577,6 @@ __metadata: languageName: node linkType: hard -"@cord.network/api@workspace:packages/api": - version: 0.0.0-use.local - resolution: "@cord.network/api@workspace:packages/api" - dependencies: - "@cord.network/messaging": "workspace:*" - "@cord.network/modules": "workspace:*" - "@cord.network/network": "workspace:*" - "@cord.network/types": "workspace:*" - "@cord.network/utils": "workspace:*" - "@polkadot/api-augment": ^8.0.0 - buffer: ^6.0.3 - crypto-browserify: ^3.12.0 - process: ^0.11.10 - rimraf: ^3.0.2 - stream-browserify: ^3.0.0 - terser-webpack-plugin: ^5.1.1 - typescript: ^4.5.4 - url: ^0.11.0 - util: ^0.12.4 - webpack: ^5.27.0 - webpack-cli: ^4.5.0 - languageName: unknown - linkType: soft - "@cord.network/config@workspace:*, @cord.network/config@workspace:packages/config": version: 0.0.0-use.local resolution: "@cord.network/config@workspace:packages/config" @@ -680,6 +645,30 @@ __metadata: languageName: unknown linkType: soft +"@cord.network/sdk@workspace:packages/sdk": + version: 0.0.0-use.local + resolution: "@cord.network/sdk@workspace:packages/sdk" + dependencies: + "@cord.network/messaging": "workspace:*" + "@cord.network/modules": "workspace:*" + "@cord.network/network": "workspace:*" + "@cord.network/types": "workspace:*" + "@cord.network/utils": "workspace:*" + "@polkadot/api-augment": ^8.0.0 + buffer: ^6.0.3 + crypto-browserify: ^3.12.0 + process: ^0.11.10 + rimraf: ^3.0.2 + stream-browserify: ^3.0.0 + terser-webpack-plugin: ^5.1.1 + typescript: ^4.5.4 + url: ^0.11.0 + util: ^0.12.4 + webpack: ^5.70.0 + webpack-cli: ^4.9.2 + languageName: unknown + linkType: soft + "@cord.network/types@workspace:*, @cord.network/types@workspace:packages/types": version: 0.0.0-use.local resolution: "@cord.network/types@workspace:packages/types" @@ -720,29 +709,41 @@ __metadata: "@cord.network/network": "workspace:*" "@cord.network/types": "workspace:*" "@cord.network/utils": "workspace:*" + "@digitalbazaar/vc": ^4.0.0 + "@polkadot/api": ^8.0.0 "@polkadot/api-augment": ^8.0.0 "@polkadot/keyring": ^9.0.0 "@polkadot/types": ^8.0.0 "@polkadot/util": ^9.0.0 "@polkadot/util-crypto": ^9.0.0 "@types/jsonld": 1.5.1 - crypto-ld: ^3.7.0 - jsonld: ^5.0.0 - jsonld-signatures: ^9.0.0 + crypto-ld: ^7.0.0 + jsonld: ^6.0.0 + jsonld-signatures: ^10.0.0 rimraf: ^3.0.2 typescript: 4.5.4 - vc-js: ^0.6.4 languageName: unknown linkType: soft -"@digitalbazaar/http-client@npm:^1.1.0": - version: 1.2.0 - resolution: "@digitalbazaar/http-client@npm:1.2.0" +"@digitalbazaar/http-client@npm:^3.2.0": + version: 3.2.0 + resolution: "@digitalbazaar/http-client@npm:3.2.0" + dependencies: + ky: ^0.30.0 + ky-universal: ^0.10.1 + undici: ^5.2.0 + checksum: f8409a66977623a8f946b80169a4008d13af097f422ba9aa17beafe9a3fb243d274512b46bd08c0f9821d32fc12708f4237950bef1d0a37b1c1c86f85c9d2990 + languageName: node + linkType: hard + +"@digitalbazaar/vc@npm:^4.0.0": + version: 4.0.0 + resolution: "@digitalbazaar/vc@npm:4.0.0" dependencies: - esm: ^3.2.22 - ky: ^0.25.1 - ky-universal: ^0.8.2 - checksum: 24e2ebec5189a8a406fbe56731a456f6eb731cbb7f30dce945f3685f9b462b6660ee9181b195714d4f586f62243b995f61b78092c9a15e0d188745e39504eaa5 + credentials-context: ^2.0.0 + jsonld: ^6.0.0 + jsonld-signatures: ^10.0.0 + checksum: 7e30fc56bdcdb6d1a7c4ec1483c546a2892ff0d5891ee0ee2a0ed21614be2c4537faa3867f27f921d0b0a86be45a7230e0d74b1370fb43f99da0d1b8eee41916 languageName: node linkType: hard @@ -764,33 +765,33 @@ __metadata: languageName: node linkType: hard -"@esbuild-kit/cjs-loader@npm:^2.1.0": - version: 2.1.0 - resolution: "@esbuild-kit/cjs-loader@npm:2.1.0" +"@esbuild-kit/cjs-loader@npm:^2.3.0": + version: 2.3.0 + resolution: "@esbuild-kit/cjs-loader@npm:2.3.0" dependencies: - "@esbuild-kit/core-utils": ^1.3.0 - get-tsconfig: ^4.0.0 - checksum: 7f1e594d9e924244f04957e9b322d03dd8de2d9af51419b159fb850ae21f6bd155c1ae1d7df58f2aa1be28a3bff23130ae38bdfa3ca3ba0a0663b6c18ba80a55 + "@esbuild-kit/core-utils": ^2.0.0 + get-tsconfig: ^4.1.0 + checksum: 2a2b377bcc9a81895479d308389d4ec7a162e4b75465a7b8ea156288ef451b64a1a219668106aa34483258b8ffbf9dda2f52c77bb5d81ddd358af2560b4f5795 languageName: node linkType: hard -"@esbuild-kit/core-utils@npm:^1.3.0, @esbuild-kit/core-utils@npm:^1.3.1": - version: 1.3.3 - resolution: "@esbuild-kit/core-utils@npm:1.3.3" +"@esbuild-kit/core-utils@npm:^2.0.0, @esbuild-kit/core-utils@npm:^2.0.2": + version: 2.0.2 + resolution: "@esbuild-kit/core-utils@npm:2.0.2" dependencies: - esbuild: 0.14.38 + esbuild: ~0.14.47 source-map-support: ^0.5.21 - checksum: 56c11c3925c64875e9bfb29280e5a439f7112d13a156874ccf0fafc8b340127f8cbda91a9b4ada8896b1226349fb564048c562609271a803f75a4ba82bf711a5 + checksum: 5292e0d7eaa225f4e7784a7edcb04b23b2d9aa8f6e7cc9b65535f6b647c8607a16138539e52bdf7634cb9d9fde6f4dcd3d04c13390f264919fd28576f8f5937e languageName: node linkType: hard -"@esbuild-kit/esm-loader@npm:^2.2.0": - version: 2.2.0 - resolution: "@esbuild-kit/esm-loader@npm:2.2.0" +"@esbuild-kit/esm-loader@npm:^2.4.0": + version: 2.4.0 + resolution: "@esbuild-kit/esm-loader@npm:2.4.0" dependencies: - "@esbuild-kit/core-utils": ^1.3.1 - get-tsconfig: ^4.0.0 - checksum: 65911e915ac8e985d1a5a7f33b6b6937cdc8fdeb12992db96d28d88cc4de3eb04ae06b143a90a1764bf900c7847899c6106871525bdcc3d858415e9dfbe44faf + "@esbuild-kit/core-utils": ^2.0.0 + get-tsconfig: ^4.1.0 + checksum: 866e4ce46e425657434796c40e046c1e40395a0e0680d8a2cde792f97d57190c5962fb74ef2206d843ae0a4672ee742848891a09a4807a4179881c1b6dc16543 languageName: node linkType: hard @@ -1067,69 +1068,69 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.0": - version: 0.3.1 - resolution: "@jridgewell/gen-mapping@npm:0.3.1" +"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.2": + version: 0.3.2 + resolution: "@jridgewell/gen-mapping@npm:0.3.2" dependencies: - "@jridgewell/set-array": ^1.0.0 + "@jridgewell/set-array": ^1.0.1 "@jridgewell/sourcemap-codec": ^1.4.10 "@jridgewell/trace-mapping": ^0.3.9 - checksum: e9e7bb3335dea9e60872089761d4e8e089597360cdb1af90370e9d53b7d67232c1e0a3ab65fbfef4fc785745193fbc56bff9f3a6cab6c6ce3f15e12b4191f86b + checksum: 1832707a1c476afebe4d0fbbd4b9434fdb51a4c3e009ab1e9938648e21b7a97049fa6009393bdf05cab7504108413441df26d8a3c12193996e65493a4efb6882 languageName: node linkType: hard "@jridgewell/resolve-uri@npm:^3.0.3": - version: 3.0.7 - resolution: "@jridgewell/resolve-uri@npm:3.0.7" - checksum: 94f454f4cef8f0acaad85745fd3ca6cd0d62ef731cf9f952ecb89b8b2ce5e20998cd52be31311cedc5fa5b28b1708a15f3ad9df0fe1447ee4f42959b036c4b5b + version: 3.0.8 + resolution: "@jridgewell/resolve-uri@npm:3.0.8" + checksum: 28d739f49b4a52a95843b15669dcb2daaab48f0eaef8f457b9aacd0bdebeb60468d0684f73244f613b786e9d871c25abdbe6f55991bba36814cdadc399dbb3a8 languageName: node linkType: hard -"@jridgewell/set-array@npm:^1.0.0": - version: 1.1.1 - resolution: "@jridgewell/set-array@npm:1.1.1" - checksum: cc5d91e0381c347e3edee4ca90b3c292df9e6e55f29acbe0dd97de8651b4730e9ab761406fd572effa79972a0edc55647b627f8c72315e276d959508853d9bf2 +"@jridgewell/set-array@npm:^1.0.0, @jridgewell/set-array@npm:^1.0.1": + version: 1.1.2 + resolution: "@jridgewell/set-array@npm:1.1.2" + checksum: 69a84d5980385f396ff60a175f7177af0b8da4ddb81824cb7016a9ef914eee9806c72b6b65942003c63f7983d4f39a5c6c27185bbca88eb4690b62075602e28e languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10": - version: 1.4.13 - resolution: "@jridgewell/sourcemap-codec@npm:1.4.13" - checksum: f14449096f60a5f921262322fef65ce0bbbfb778080b3b20212080bcefdeba621c43a58c27065bd536ecb4cc767b18eb9c45f15b6b98a4970139572b60603a1c +"@jridgewell/source-map@npm:^0.3.2": + version: 0.3.2 + resolution: "@jridgewell/source-map@npm:0.3.2" + dependencies: + "@jridgewell/gen-mapping": ^0.3.0 + "@jridgewell/trace-mapping": ^0.3.9 + checksum: 1b83f0eb944e77b70559a394d5d3b3f98a81fcc186946aceb3ef42d036762b52ef71493c6c0a3b7c1d2f08785f53ba2df1277fe629a06e6109588ff4cdcf7482 languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.9": - version: 0.3.13 - resolution: "@jridgewell/trace-mapping@npm:0.3.13" - dependencies: - "@jridgewell/resolve-uri": ^3.0.3 - "@jridgewell/sourcemap-codec": ^1.4.10 - checksum: e38254e830472248ca10a6ed1ae75af5e8514f0680245a5e7b53bc3c030fd8691d4d3115d80595b45d3badead68269769ed47ecbbdd67db1343a11f05700e75a +"@jridgewell/sourcemap-codec@npm:^1.4.10": + version: 1.4.14 + resolution: "@jridgewell/sourcemap-codec@npm:1.4.14" + checksum: 61100637b6d173d3ba786a5dff019e1a74b1f394f323c1fee337ff390239f053b87266c7a948777f4b1ee68c01a8ad0ab61e5ff4abb5a012a0b091bec391ab97 languageName: node linkType: hard -"@multiformats/blake2@npm:^1.0.5": - version: 1.0.9 - resolution: "@multiformats/blake2@npm:1.0.9" +"@jridgewell/trace-mapping@npm:^0.3.7, @jridgewell/trace-mapping@npm:^0.3.9": + version: 0.3.14 + resolution: "@jridgewell/trace-mapping@npm:0.3.14" dependencies: - blakejs: ^1.1.1 - multiformats: ^9.5.4 - checksum: 8d134570efde89acd7fb60ca766ddc45e37ad152559b8cc7158c2ffeed137105303cd1ff3507ff50f24f222f4a36925af35da1f4f7756b5cf09243c9c5514ce3 + "@jridgewell/resolve-uri": ^3.0.3 + "@jridgewell/sourcemap-codec": ^1.4.10 + checksum: b9537b9630ffb631aef9651a085fe361881cde1772cd482c257fe3c78c8fd5388d681f504a9c9fe1081b1c05e8f75edf55ee10fdb58d92bbaa8dbf6a7bd6b18c languageName: node linkType: hard -"@noble/hashes@npm:1.0.0": - version: 1.0.0 - resolution: "@noble/hashes@npm:1.0.0" - checksum: bdf1c28a4b587e72ec6b0c504903239c6f96680b2c15a6d90d367512f468eeca12f2ee7bd25967a9529be2bedbf3f8d0a50c33368937f8dfef2a973d0661c7b5 +"@noble/hashes@npm:1.1.2": + version: 1.1.2 + resolution: "@noble/hashes@npm:1.1.2" + checksum: 3c2a8cb7c2e053811032f242155d870c5eb98844d924d69702244d48804cb03b42d4a666c49c2b71164420d8229cb9a6f242b972d50d5bb2f1d673b98b041de2 languageName: node linkType: hard -"@noble/secp256k1@npm:1.5.5": - version: 1.5.5 - resolution: "@noble/secp256k1@npm:1.5.5" - checksum: 8a144e8469b29e94107ca4bcf442fc5d9410974239f8e42013f8604d602ab73cfc0c113c24170d41c25e2c40d6d1c46319c439c3bc26a7581c79060fabc3ea8c +"@noble/secp256k1@npm:1.6.0": + version: 1.6.0 + resolution: "@noble/secp256k1@npm:1.6.0" + checksum: e99df3b776515e6a8b3193870e69ff3a7d22c6a4733245dceb9d1d229d5b0859bd478b7213f31d556ba3745647ec07262d0f9df845d79204b7ce4ae1648b27c7 languageName: node linkType: hard @@ -1180,413 +1181,416 @@ __metadata: languageName: node linkType: hard -"@polkadot/api-augment@npm:8.8.2, @polkadot/api-augment@npm:^8.0.0": - version: 8.8.2 - resolution: "@polkadot/api-augment@npm:8.8.2" +"@polkadot/api-augment@npm:8.11.1, @polkadot/api-augment@npm:^8.0.0": + version: 8.11.1 + resolution: "@polkadot/api-augment@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/api-base": 8.8.2 - "@polkadot/rpc-augment": 8.8.2 - "@polkadot/types": 8.8.2 - "@polkadot/types-augment": 8.8.2 - "@polkadot/types-codec": 8.8.2 - "@polkadot/util": ^9.4.1 - checksum: 5a0fc636de1910cd9e5b91dc76b2b87deb0c1763c3b17d9649e3530a18bc062ff093d74fd7e7b2da7f5fc8d8f5d0b4765770b2af4f8be9e3b2a6c03e4c9a3153 + "@babel/runtime": ^7.18.6 + "@polkadot/api-base": 8.11.1 + "@polkadot/rpc-augment": 8.11.1 + "@polkadot/types": 8.11.1 + "@polkadot/types-augment": 8.11.1 + "@polkadot/types-codec": 8.11.1 + "@polkadot/util": ^9.7.1 + checksum: fa11b7951198b5beea5361df749efe17322d41b765d5b6bd7413bd902b428c12cab91cbd2fd10c708a3cfdc300a751d3b6e3a065d857bd6dc1e372b1562fbed4 languageName: node linkType: hard -"@polkadot/api-base@npm:8.8.2": - version: 8.8.2 - resolution: "@polkadot/api-base@npm:8.8.2" +"@polkadot/api-base@npm:8.11.1": + version: 8.11.1 + resolution: "@polkadot/api-base@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/rpc-core": 8.8.2 - "@polkadot/types": 8.8.2 - "@polkadot/util": ^9.4.1 + "@babel/runtime": ^7.18.6 + "@polkadot/rpc-core": 8.11.1 + "@polkadot/types": 8.11.1 + "@polkadot/util": ^9.7.1 rxjs: ^7.5.5 - checksum: 2765eab948f863e971dd5116554d853706ef670957b1d21fbc5900393b1c7f000df46a67fa01c74c9cd2875675ca135f7d29843156cbf16452490a99e7afb4db + checksum: 5d49a2a222a064fb2c9544fb50b368f52d6d347fa00451eaa2067af543479837803afb254b36f3486b9aa5ba6842e108bdd323e30e9d04682f681677aff1f2a5 languageName: node linkType: hard -"@polkadot/api-derive@npm:8.8.2": - version: 8.8.2 - resolution: "@polkadot/api-derive@npm:8.8.2" +"@polkadot/api-derive@npm:8.11.1": + version: 8.11.1 + resolution: "@polkadot/api-derive@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/api": 8.8.2 - "@polkadot/api-augment": 8.8.2 - "@polkadot/api-base": 8.8.2 - "@polkadot/rpc-core": 8.8.2 - "@polkadot/types": 8.8.2 - "@polkadot/types-codec": 8.8.2 - "@polkadot/util": ^9.4.1 - "@polkadot/util-crypto": ^9.4.1 + "@babel/runtime": ^7.18.6 + "@polkadot/api": 8.11.1 + "@polkadot/api-augment": 8.11.1 + "@polkadot/api-base": 8.11.1 + "@polkadot/rpc-core": 8.11.1 + "@polkadot/types": 8.11.1 + "@polkadot/types-codec": 8.11.1 + "@polkadot/util": ^9.7.1 + "@polkadot/util-crypto": ^9.7.1 rxjs: ^7.5.5 - checksum: 21c4041e86406a8ecf894445a653c1cb49e509fe35fd7e91e1d7b811da7bcdf01e5e315c8d1a4cfbd756ef7d8e239c38802dda1a3109aa982a3ad32584496fca - languageName: node - linkType: hard - -"@polkadot/api@npm:8.8.2, @polkadot/api@npm:^8.0.0": - version: 8.8.2 - resolution: "@polkadot/api@npm:8.8.2" - dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/api-augment": 8.8.2 - "@polkadot/api-base": 8.8.2 - "@polkadot/api-derive": 8.8.2 - "@polkadot/keyring": ^9.4.1 - "@polkadot/rpc-augment": 8.8.2 - "@polkadot/rpc-core": 8.8.2 - "@polkadot/rpc-provider": 8.8.2 - "@polkadot/types": 8.8.2 - "@polkadot/types-augment": 8.8.2 - "@polkadot/types-codec": 8.8.2 - "@polkadot/types-create": 8.8.2 - "@polkadot/types-known": 8.8.2 - "@polkadot/util": ^9.4.1 - "@polkadot/util-crypto": ^9.4.1 + checksum: c8d4f286672c2cde80c528b41f852a3e2809fce8e35cf7e6ca74d6f45d4c4db7c70089df3ce983ba2b48c8ea6c448579cc13dcc17c82d74747888e5c2c23288d + languageName: node + linkType: hard + +"@polkadot/api@npm:8.11.1, @polkadot/api@npm:^8.0.0": + version: 8.11.1 + resolution: "@polkadot/api@npm:8.11.1" + dependencies: + "@babel/runtime": ^7.18.6 + "@polkadot/api-augment": 8.11.1 + "@polkadot/api-base": 8.11.1 + "@polkadot/api-derive": 8.11.1 + "@polkadot/keyring": ^9.7.1 + "@polkadot/rpc-augment": 8.11.1 + "@polkadot/rpc-core": 8.11.1 + "@polkadot/rpc-provider": 8.11.1 + "@polkadot/types": 8.11.1 + "@polkadot/types-augment": 8.11.1 + "@polkadot/types-codec": 8.11.1 + "@polkadot/types-create": 8.11.1 + "@polkadot/types-known": 8.11.1 + "@polkadot/util": ^9.7.1 + "@polkadot/util-crypto": ^9.7.1 eventemitter3: ^4.0.7 rxjs: ^7.5.5 - checksum: 5d56448e9eed104d7442761aad5aa1e7f514f8942aa47b6da6bf32d4d847dfd561a0c43d03caf9664ef9b314d14096be4c2f1c669b04d9016e5deeaa2e0df97e + checksum: d8805863d80d9bfca149b4e7b28cd314d8144ef2f684dba92bd8345b068952c694770841978497d4153476e7777d1f6d8a68207c062da97541b80fba72642523 languageName: node linkType: hard -"@polkadot/keyring@npm:^9.0.0, @polkadot/keyring@npm:^9.4.1": - version: 9.4.1 - resolution: "@polkadot/keyring@npm:9.4.1" +"@polkadot/keyring@npm:^9.0.0, @polkadot/keyring@npm:^9.7.1": + version: 9.7.1 + resolution: "@polkadot/keyring@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/util": 9.4.1 - "@polkadot/util-crypto": 9.4.1 + "@babel/runtime": ^7.18.6 + "@polkadot/util": 9.7.1 + "@polkadot/util-crypto": 9.7.1 peerDependencies: - "@polkadot/util": 9.4.1 - "@polkadot/util-crypto": 9.4.1 - checksum: e2ad67f683441bee22a57845b9d7961bfbfbdc8ee268b7fc8fcec12aee22e0b7f3da41bcee157426c748b775ffff2eb6a2f7ebae481143a91a10f45f1ed1ad08 + "@polkadot/util": 9.7.1 + "@polkadot/util-crypto": 9.7.1 + checksum: a01b54837ce2b4c9833e9ba4f3929ce8e832cf2f7f721e4ff141577a9c3fe1c477d26ce43f064873da1f2f5d0ba494d8a388fe6a8bce052e32e4def2a3bc2f69 languageName: node linkType: hard -"@polkadot/networks@npm:9.4.1, @polkadot/networks@npm:^9.4.1": - version: 9.4.1 - resolution: "@polkadot/networks@npm:9.4.1" +"@polkadot/networks@npm:9.7.1, @polkadot/networks@npm:^9.7.1": + version: 9.7.1 + resolution: "@polkadot/networks@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/util": 9.4.1 - "@substrate/ss58-registry": ^1.22.0 - checksum: 2342ec4937541e826ed40e245b136ae3344d30fde11bffb97f90e3dd7e944f8a94434d835ff7ae789f39442624c908d2069c89789f1f6ab920e5d172de0f5bce + "@babel/runtime": ^7.18.6 + "@polkadot/util": 9.7.1 + "@substrate/ss58-registry": ^1.23.0 + checksum: 87b5c31d497c19b8c0bb069f19d8a09f5cbf25376bb3ebfdf5d05b7b24719cdd0546e93be27057d3e86915d926dec0361c344648460eb7f5b5bc151c84ae1e23 languageName: node linkType: hard -"@polkadot/rpc-augment@npm:8.8.2": - version: 8.8.2 - resolution: "@polkadot/rpc-augment@npm:8.8.2" +"@polkadot/rpc-augment@npm:8.11.1": + version: 8.11.1 + resolution: "@polkadot/rpc-augment@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/rpc-core": 8.8.2 - "@polkadot/types": 8.8.2 - "@polkadot/types-codec": 8.8.2 - "@polkadot/util": ^9.4.1 - checksum: 85c59ff8084c0c01f24ad6d17d384a57f4b5172910c862956161b742114e8ccbff259fff0db417cadbdaa56a12ba512325b4fcada1bd88461f109c39e98491be + "@babel/runtime": ^7.18.6 + "@polkadot/rpc-core": 8.11.1 + "@polkadot/types": 8.11.1 + "@polkadot/types-codec": 8.11.1 + "@polkadot/util": ^9.7.1 + checksum: 9e27c83c7a3e640d8a6ecfd23f3f459a6fd2b2d026ddbed6d98eeefd12754d306cd196e65c8a34a0b6e721a40d6bb426a15be68193a19e7b9b44de1b774194ad languageName: node linkType: hard -"@polkadot/rpc-core@npm:8.8.2": - version: 8.8.2 - resolution: "@polkadot/rpc-core@npm:8.8.2" +"@polkadot/rpc-core@npm:8.11.1": + version: 8.11.1 + resolution: "@polkadot/rpc-core@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/rpc-augment": 8.8.2 - "@polkadot/rpc-provider": 8.8.2 - "@polkadot/types": 8.8.2 - "@polkadot/util": ^9.4.1 + "@babel/runtime": ^7.18.6 + "@polkadot/rpc-augment": 8.11.1 + "@polkadot/rpc-provider": 8.11.1 + "@polkadot/types": 8.11.1 + "@polkadot/util": ^9.7.1 rxjs: ^7.5.5 - checksum: c48925dff5334574c39ac5325177d90752d97870a132c33a790ed8bf0cffdd407e4fe1582b21a691b76c0c1dcdec9e4ecba4dc7a3f034368bf1bdcac29385234 + checksum: 1432a2328eb07dbd3f56d876a56e82e83d208290567f327ffb7f7695ca33151b17348859371105871b3e2aba0479a182cf5c30521bf19e90efc648debc67bc78 languageName: node linkType: hard -"@polkadot/rpc-provider@npm:8.8.2": - version: 8.8.2 - resolution: "@polkadot/rpc-provider@npm:8.8.2" +"@polkadot/rpc-provider@npm:8.11.1": + version: 8.11.1 + resolution: "@polkadot/rpc-provider@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/keyring": ^9.4.1 - "@polkadot/types": 8.8.2 - "@polkadot/types-support": 8.8.2 - "@polkadot/util": ^9.4.1 - "@polkadot/util-crypto": ^9.4.1 - "@polkadot/x-fetch": ^9.4.1 - "@polkadot/x-global": ^9.4.1 - "@polkadot/x-ws": ^9.4.1 - "@substrate/connect": 0.7.5 + "@babel/runtime": ^7.18.6 + "@polkadot/keyring": ^9.7.1 + "@polkadot/types": 8.11.1 + "@polkadot/types-support": 8.11.1 + "@polkadot/util": ^9.7.1 + "@polkadot/util-crypto": ^9.7.1 + "@polkadot/x-fetch": ^9.7.1 + "@polkadot/x-global": ^9.7.1 + "@polkadot/x-ws": ^9.7.1 + "@substrate/connect": 0.7.7 eventemitter3: ^4.0.7 mock-socket: ^9.1.5 - nock: ^13.2.6 - checksum: f8f33bddc37a723ab31808fbfd264beb31affe086e7ef0b5d0811f254200862203129f4ebf8bdaafe376ffb38594af28eee211229482c5a91b829f811ba02459 + nock: ^13.2.8 + checksum: aa8b427d0f60d4ad10cfcef3703cf4b339945063cc1c2bcef773cb2f46ee1dbd3a354c4a71ff5eb3bb73fa032b72f6cbb540b63d9fb6b7894e5eca6f507da2fd languageName: node linkType: hard -"@polkadot/types-augment@npm:8.8.2": - version: 8.8.2 - resolution: "@polkadot/types-augment@npm:8.8.2" +"@polkadot/types-augment@npm:8.11.1": + version: 8.11.1 + resolution: "@polkadot/types-augment@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/types": 8.8.2 - "@polkadot/types-codec": 8.8.2 - "@polkadot/util": ^9.4.1 - checksum: e51efd9e1fb2c18f916150be9e2f9445b95ecb87ee80f6f22b84162eadeb73c3fbdbbe1c8cae0b24194e7be04800f5f9d15c5741a53bcb6c96eee1b3c33539fa + "@babel/runtime": ^7.18.6 + "@polkadot/types": 8.11.1 + "@polkadot/types-codec": 8.11.1 + "@polkadot/util": ^9.7.1 + checksum: 899d6d1763d2def0b1d868d2518c7f0e6e50fb1aa876c832f25f9c16f245a29470cff355846d5d0184cc0363e19ed5aab92532aa1b565c10ab5b8d4c9d82b82d languageName: node linkType: hard -"@polkadot/types-codec@npm:8.8.2": - version: 8.8.2 - resolution: "@polkadot/types-codec@npm:8.8.2" +"@polkadot/types-codec@npm:8.11.1": + version: 8.11.1 + resolution: "@polkadot/types-codec@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/util": ^9.4.1 - checksum: 42eca67b70c5c468d0eb16774779c9ab19450cc66454bc4dc7b2699f414bf841e7a87254c5af8d95eed974f579265b2fa1b3bac339ad1847efe07926b1f1e800 + "@babel/runtime": ^7.18.6 + "@polkadot/util": ^9.7.1 + "@polkadot/x-bigint": ^9.7.1 + checksum: df895f575c3687a791d1b4def3f41bd136dd3ad50e250e75ecb64ab99f139a696ccc41e77c8e22252ce950d99b5bd76f0753c39adc000b699a20b07d98390c28 languageName: node linkType: hard -"@polkadot/types-create@npm:8.8.2": - version: 8.8.2 - resolution: "@polkadot/types-create@npm:8.8.2" +"@polkadot/types-create@npm:8.11.1": + version: 8.11.1 + resolution: "@polkadot/types-create@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/types-codec": 8.8.2 - "@polkadot/util": ^9.4.1 - checksum: c4908ca5c55707620649c97e07d99fe90f292f41cd4c82c1a26c0db2c22680889dc576336f905dda5e179566883d8653e40f8ee27be169695b6930d15eee36f7 + "@babel/runtime": ^7.18.6 + "@polkadot/types-codec": 8.11.1 + "@polkadot/util": ^9.7.1 + checksum: 5255941d8770914163bb94366077079b968d468992eb38058b853361d883e6a8919587ad14528f5c0f922e70fe394ab86953fb09abe9fb14c536e61787fb24d0 languageName: node linkType: hard -"@polkadot/types-known@npm:8.8.2, @polkadot/types-known@npm:^8.0.0": - version: 8.8.2 - resolution: "@polkadot/types-known@npm:8.8.2" +"@polkadot/types-known@npm:8.11.1, @polkadot/types-known@npm:^8.0.0": + version: 8.11.1 + resolution: "@polkadot/types-known@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/networks": ^9.4.1 - "@polkadot/types": 8.8.2 - "@polkadot/types-codec": 8.8.2 - "@polkadot/types-create": 8.8.2 - "@polkadot/util": ^9.4.1 - checksum: 5cac1930ad39d1d709171e0e477d97bc8b03faffc7ca407e2a9f6a0a283094b74e8ddcc86450cd0df272b9e2781c87f9dee7ea885f95e30a4a77f0530f5ac4ca + "@babel/runtime": ^7.18.6 + "@polkadot/networks": ^9.7.1 + "@polkadot/types": 8.11.1 + "@polkadot/types-codec": 8.11.1 + "@polkadot/types-create": 8.11.1 + "@polkadot/util": ^9.7.1 + checksum: d65392b6da74adea606ff1105c7e8b0a4b23e786e7846daa34c479e99a4cc40b0ba3ebf060ebb03073168819537d3a4f42b2dd613afb892e91e0ad8381779597 languageName: node linkType: hard -"@polkadot/types-support@npm:8.8.2": - version: 8.8.2 - resolution: "@polkadot/types-support@npm:8.8.2" +"@polkadot/types-support@npm:8.11.1": + version: 8.11.1 + resolution: "@polkadot/types-support@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/util": ^9.4.1 - checksum: 7550004c464c383b9272ace6774ecf6ddfd765d18aea97658ebb0c35902467c31ce3c957eb293db84c79085ae0de475565e6499bd053cf8d86d7e59b10ca2ebb + "@babel/runtime": ^7.18.6 + "@polkadot/util": ^9.7.1 + checksum: e39a52dd021b78d9f64595ecb1b8b27256adffccd5bdfd9a6bb321d1b34e0ae3a55e0cbb83e5c8d32dac2fa49d536c094a5fd296ab1d845d01c1ee5ea4cb5db6 languageName: node linkType: hard -"@polkadot/types@npm:8.8.2, @polkadot/types@npm:^8.0.0": - version: 8.8.2 - resolution: "@polkadot/types@npm:8.8.2" +"@polkadot/types@npm:8.11.1, @polkadot/types@npm:^8.0.0": + version: 8.11.1 + resolution: "@polkadot/types@npm:8.11.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/keyring": ^9.4.1 - "@polkadot/types-augment": 8.8.2 - "@polkadot/types-codec": 8.8.2 - "@polkadot/types-create": 8.8.2 - "@polkadot/util": ^9.4.1 - "@polkadot/util-crypto": ^9.4.1 + "@babel/runtime": ^7.18.6 + "@polkadot/keyring": ^9.7.1 + "@polkadot/types-augment": 8.11.1 + "@polkadot/types-codec": 8.11.1 + "@polkadot/types-create": 8.11.1 + "@polkadot/util": ^9.7.1 + "@polkadot/util-crypto": ^9.7.1 rxjs: ^7.5.5 - checksum: eaa14caecd8361f35637de9e97427a763908c51560bf6e5657508b384f0c10c1d9099c5ef2a4f05ca47a52273a34e187d645bd63d2f21d726b8d53518d743b52 + checksum: 1279fa0d0005d6748855ff418c266bc655fe7896dd6607b71fc87893aef28ef664ef76a7d3fc56db774c9b126e4ba24f9875116d2f1699b70d046cfe527f72ff languageName: node linkType: hard -"@polkadot/util-crypto@npm:9.4.1, @polkadot/util-crypto@npm:^9.0.0, @polkadot/util-crypto@npm:^9.4.1": - version: 9.4.1 - resolution: "@polkadot/util-crypto@npm:9.4.1" +"@polkadot/util-crypto@npm:9.7.1, @polkadot/util-crypto@npm:^9.0.0, @polkadot/util-crypto@npm:^9.7.1": + version: 9.7.1 + resolution: "@polkadot/util-crypto@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@noble/hashes": 1.0.0 - "@noble/secp256k1": 1.5.5 - "@polkadot/networks": 9.4.1 - "@polkadot/util": 9.4.1 - "@polkadot/wasm-crypto": ^6.1.1 - "@polkadot/x-bigint": 9.4.1 - "@polkadot/x-randomvalues": 9.4.1 - "@scure/base": 1.0.0 + "@babel/runtime": ^7.18.6 + "@noble/hashes": 1.1.2 + "@noble/secp256k1": 1.6.0 + "@polkadot/networks": 9.7.1 + "@polkadot/util": 9.7.1 + "@polkadot/wasm-crypto": ^6.2.1 + "@polkadot/x-bigint": 9.7.1 + "@polkadot/x-randomvalues": 9.7.1 + "@scure/base": 1.1.1 ed2curve: ^0.3.0 tweetnacl: ^1.0.3 peerDependencies: - "@polkadot/util": 9.4.1 - checksum: 089341eb7c86063073f00b66a90648e24a4eb13f7c10d4f2308238e0e183ae53fd31516be108e8a9d98e1cf668023057c7bdca684d81d71cd747d1167f433f6f + "@polkadot/util": 9.7.1 + checksum: 69dff4c3417a564bf98c08967e2197c3b64b87e9cc47b83a49924983c00fd8de5e295dc2015fa3911b23712e331a6cfe709bf87ac655d9f14efeb748f06f8514 languageName: node linkType: hard -"@polkadot/util@npm:9.4.1, @polkadot/util@npm:^9.0.0, @polkadot/util@npm:^9.4.1": - version: 9.4.1 - resolution: "@polkadot/util@npm:9.4.1" +"@polkadot/util@npm:9.7.1, @polkadot/util@npm:^9.0.0, @polkadot/util@npm:^9.7.1": + version: 9.7.1 + resolution: "@polkadot/util@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/x-bigint": 9.4.1 - "@polkadot/x-global": 9.4.1 - "@polkadot/x-textdecoder": 9.4.1 - "@polkadot/x-textencoder": 9.4.1 + "@babel/runtime": ^7.18.6 + "@polkadot/x-bigint": 9.7.1 + "@polkadot/x-global": 9.7.1 + "@polkadot/x-textdecoder": 9.7.1 + "@polkadot/x-textencoder": 9.7.1 "@types/bn.js": ^5.1.0 bn.js: ^5.2.1 ip-regex: ^4.3.0 - checksum: 9bda687519fd00cdb233699c7cbc4565745aacf57112af60184b7ade21b9006a52dd745c8534970561b92f2a76334524e95bf60a88cae7add3e49946722f236a + checksum: 4e8cf7aef0b3cdb94cb464dfdd90b86ff0ce8b37cb1ccd4248b667ff14ce94bc833ee6ae731d38991af28444790ba998864d6e70d82fc416872b762826f070af languageName: node linkType: hard -"@polkadot/wasm-bridge@npm:6.1.1": - version: 6.1.1 - resolution: "@polkadot/wasm-bridge@npm:6.1.1" +"@polkadot/wasm-bridge@npm:6.2.1": + version: 6.2.1 + resolution: "@polkadot/wasm-bridge@npm:6.2.1" dependencies: - "@babel/runtime": ^7.17.9 + "@babel/runtime": ^7.18.6 peerDependencies: "@polkadot/util": "*" "@polkadot/x-randomvalues": "*" - checksum: 2280101d71d497a5c86de4c43b3ace5ac24942e7672c12e254de231bed5cd90c30ed06c364ff36e8b96b2fff51a5a47e03918a54325d1dc68b94c2b8f26c3df9 + checksum: 4e07c7bed0f0706d406bb19ed85f86ff733ce2cf6452306553f1da66ac27f8421266c040cebbbd07d34f11456a63513e55253c0b4d650a0a6b0325d1f8670d87 languageName: node linkType: hard -"@polkadot/wasm-crypto-asmjs@npm:6.1.1": - version: 6.1.1 - resolution: "@polkadot/wasm-crypto-asmjs@npm:6.1.1" +"@polkadot/wasm-crypto-asmjs@npm:6.2.1": + version: 6.2.1 + resolution: "@polkadot/wasm-crypto-asmjs@npm:6.2.1" dependencies: - "@babel/runtime": ^7.17.9 + "@babel/runtime": ^7.18.6 peerDependencies: "@polkadot/util": "*" - checksum: f33afe2325f230b32cfa9bd809a362d45d1690b210a6703eae3b74bcc1cd68f7d2a46a6fd458144481c57580ac12d6d8d2950e8fc353b77401898b14e9ba4aa5 + checksum: 18dae8a9a084bd7e876cecaf2730f931aa1f4428439bdca329e6bdcb8d59b2f58f1857a8eb474e481b5b519b9d86915422d7b6baa15905498e7023c9c1557a5c languageName: node linkType: hard -"@polkadot/wasm-crypto-init@npm:6.1.1": - version: 6.1.1 - resolution: "@polkadot/wasm-crypto-init@npm:6.1.1" +"@polkadot/wasm-crypto-init@npm:6.2.1": + version: 6.2.1 + resolution: "@polkadot/wasm-crypto-init@npm:6.2.1" dependencies: - "@babel/runtime": ^7.17.9 - "@polkadot/wasm-bridge": 6.1.1 - "@polkadot/wasm-crypto-asmjs": 6.1.1 - "@polkadot/wasm-crypto-wasm": 6.1.1 + "@babel/runtime": ^7.18.6 + "@polkadot/wasm-bridge": 6.2.1 + "@polkadot/wasm-crypto-asmjs": 6.2.1 + "@polkadot/wasm-crypto-wasm": 6.2.1 peerDependencies: "@polkadot/util": "*" - checksum: 9e283bc6fa37c658bbac0598b9f86be5c1ae41b715188c5b1120b2fe10eb276f094dfbe0e515592d0a4c1aaef3694aa653a70d411214e49bedc8578ede8c1ec1 + "@polkadot/x-randomvalues": "*" + checksum: be96206ea47d2b45a8bee9bcd9d695acf1e06cbbce130296a1513cdbe96910816069110fc848ab0ec8314b0ddb519c0bb03aa670a06a6dc184553ccb15bf2eec languageName: node linkType: hard -"@polkadot/wasm-crypto-wasm@npm:6.1.1": - version: 6.1.1 - resolution: "@polkadot/wasm-crypto-wasm@npm:6.1.1" +"@polkadot/wasm-crypto-wasm@npm:6.2.1": + version: 6.2.1 + resolution: "@polkadot/wasm-crypto-wasm@npm:6.2.1" dependencies: - "@babel/runtime": ^7.17.9 - "@polkadot/wasm-util": 6.1.1 + "@babel/runtime": ^7.18.6 + "@polkadot/wasm-util": 6.2.1 peerDependencies: "@polkadot/util": "*" - checksum: 53c46a60dc69b3f8a2a2897c9daf4b888f80abdb421fd4d5576b06673cf69b5598c2d9773620c1be7cff20fc7f4e310fd66eb8a235bdc0040a692bef2d761be5 + checksum: e3557def1ddf7a3195ab82e34c4eb30ea9789df0e2872ffbf486914001ae9928eb8deaac0fc9dfefcc00c34d3dc64d21398d84e0f5631bda9b4055cd98645d09 languageName: node linkType: hard -"@polkadot/wasm-crypto@npm:^6.1.1": - version: 6.1.1 - resolution: "@polkadot/wasm-crypto@npm:6.1.1" - dependencies: - "@babel/runtime": ^7.17.9 - "@polkadot/wasm-bridge": 6.1.1 - "@polkadot/wasm-crypto-asmjs": 6.1.1 - "@polkadot/wasm-crypto-init": 6.1.1 - "@polkadot/wasm-crypto-wasm": 6.1.1 - "@polkadot/wasm-util": 6.1.1 +"@polkadot/wasm-crypto@npm:^6.2.1": + version: 6.2.1 + resolution: "@polkadot/wasm-crypto@npm:6.2.1" + dependencies: + "@babel/runtime": ^7.18.6 + "@polkadot/wasm-bridge": 6.2.1 + "@polkadot/wasm-crypto-asmjs": 6.2.1 + "@polkadot/wasm-crypto-init": 6.2.1 + "@polkadot/wasm-crypto-wasm": 6.2.1 + "@polkadot/wasm-util": 6.2.1 peerDependencies: "@polkadot/util": "*" - checksum: 957754f2ada301941b17f1123ed25290b03ce2cf8dbcb1acdc764cf646cb5d373d93f58f352b2f62cfd84b2056c062215ad89fefbfb26377863419bfe16ed98e + "@polkadot/x-randomvalues": "*" + checksum: ce4582294f915a469d3acd57a4871b10fd3f1f8a83b4331ecbd7c3013006e415e5ec30a2ecc358e3ad1c484a65e0e8a6ead07a80b51d973bfd459faaba06105d languageName: node linkType: hard -"@polkadot/wasm-util@npm:6.1.1": - version: 6.1.1 - resolution: "@polkadot/wasm-util@npm:6.1.1" +"@polkadot/wasm-util@npm:6.2.1": + version: 6.2.1 + resolution: "@polkadot/wasm-util@npm:6.2.1" dependencies: - "@babel/runtime": ^7.17.9 + "@babel/runtime": ^7.18.6 peerDependencies: "@polkadot/util": "*" - checksum: 7b8e61d149e6a7a3c56c396aad982ef0ef23f1b5e0bdfbd08f046bd7d7b9ee1c423e89cc58cf567b4a69c7f40e4f07642d0134b86123861e98bf2c6dd53e5ad3 + checksum: 3efdbab34bb33fef95c5b6fa6194155461962d9121adc89203a6b72c51c8af37b7e8b0289ef390a2f1fb008211ad6a97aaaeb79395cacdb831992af23799d34c languageName: node linkType: hard -"@polkadot/x-bigint@npm:9.4.1": - version: 9.4.1 - resolution: "@polkadot/x-bigint@npm:9.4.1" +"@polkadot/x-bigint@npm:9.7.1, @polkadot/x-bigint@npm:^9.7.1": + version: 9.7.1 + resolution: "@polkadot/x-bigint@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/x-global": 9.4.1 - checksum: 596a5174b8a03ea0cf0fd43e4018f057d6b2fbec7bbcb7d5f65add8230ac6b7c1324d90c533f7f5a299232bb49ccb881f6e23708f91439d69f7f399e8c68c547 + "@babel/runtime": ^7.18.6 + "@polkadot/x-global": 9.7.1 + checksum: c741f2079c6d68422da6bc972bb77fc5d4092c2a44fa007148a3cef4c2e61acf4fdb7e759dcc93a53c7b1a36eba4b923f3e0acf2efc22f2190890563d43e03f8 languageName: node linkType: hard -"@polkadot/x-fetch@npm:^9.4.1": - version: 9.4.1 - resolution: "@polkadot/x-fetch@npm:9.4.1" +"@polkadot/x-fetch@npm:^9.7.1": + version: 9.7.1 + resolution: "@polkadot/x-fetch@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/x-global": 9.4.1 - "@types/node-fetch": ^2.6.1 + "@babel/runtime": ^7.18.6 + "@polkadot/x-global": 9.7.1 + "@types/node-fetch": ^2.6.2 node-fetch: ^2.6.7 - checksum: 92e009a25f4c5134b9b31c64104f50e448a09d21ba4aa599c4e226e19281d0448d2ec9cc63c28cdab05e1918c0d1efb413dbac6b36c76c56722f72b783e5b067 + checksum: 091435b014966b2cbe54640ef23a0b3c1609715b8249752cec1130e0e1cca630a6c0e9034c0c7230d1f6d36f111a01ad8c5c38420f7f65a816a79e85a5a55d01 languageName: node linkType: hard -"@polkadot/x-global@npm:9.4.1, @polkadot/x-global@npm:^9.4.1": - version: 9.4.1 - resolution: "@polkadot/x-global@npm:9.4.1" +"@polkadot/x-global@npm:9.7.1, @polkadot/x-global@npm:^9.7.1": + version: 9.7.1 + resolution: "@polkadot/x-global@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - checksum: eb29518680a52228d4bc8e79a9ef57340a6db57088f91eaadf4e72c50fe1f4e7af380b90eafa3441d472312a19df899bdcd568073abbcb90fd85bc758c90769e + "@babel/runtime": ^7.18.6 + checksum: 9d8927ac687e3cd4872144dd196198750a3119d60e7a36f28d2673894aba1c97a65ebc905b211a6de5da9b4a98212673e453ff5df20d5ca5f040afc1534575ed languageName: node linkType: hard -"@polkadot/x-randomvalues@npm:9.4.1": - version: 9.4.1 - resolution: "@polkadot/x-randomvalues@npm:9.4.1" +"@polkadot/x-randomvalues@npm:9.7.1": + version: 9.7.1 + resolution: "@polkadot/x-randomvalues@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/x-global": 9.4.1 - checksum: da06ad2ddd395e0e81a48ad57d82781d0be06fc8d1aba6bb9cde29cd1a6810f565df190299adee403e39bfe94e1c10d93ebb9522cef3218336db8964eb9f0a7b + "@babel/runtime": ^7.18.6 + "@polkadot/x-global": 9.7.1 + checksum: 951692a6f438a00331d74927e812896cf73094827db3dfffe16a949300d4a4cdda8c6678da475e8fd23179df9479a708e3450e291c9b690424202ef16292656e languageName: node linkType: hard -"@polkadot/x-textdecoder@npm:9.4.1": - version: 9.4.1 - resolution: "@polkadot/x-textdecoder@npm:9.4.1" +"@polkadot/x-textdecoder@npm:9.7.1": + version: 9.7.1 + resolution: "@polkadot/x-textdecoder@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/x-global": 9.4.1 - checksum: bf8ad474f03a258db761212e3cf7fc514c49feb0a60dce9bfadea5587a429649ff9175af587f11631e948b3e26c34acecad77f0e1be4b0f5268dc4479ab08053 + "@babel/runtime": ^7.18.6 + "@polkadot/x-global": 9.7.1 + checksum: 8f25e83b2b4297b5bbf59627bcdb2dbf8df2464a203aa2b4a69883e16ce929ee3a70aa5fb4b683d3d53db201b4c460d2801f83d4bca1b3c6ca612fad82eecccb languageName: node linkType: hard -"@polkadot/x-textencoder@npm:9.4.1": - version: 9.4.1 - resolution: "@polkadot/x-textencoder@npm:9.4.1" +"@polkadot/x-textencoder@npm:9.7.1": + version: 9.7.1 + resolution: "@polkadot/x-textencoder@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/x-global": 9.4.1 - checksum: cb80ff374a0c154ba1bead5c3a99354fde97d32139366197b63bcf33d383566b390b6b77f8d9cda7aa2c46ed6e73364c75f8d830d619f05b259d709a0bf47d63 + "@babel/runtime": ^7.18.6 + "@polkadot/x-global": 9.7.1 + checksum: fe5b4045b790742ff54cef2bcc408a6c1e6a92b3d1816ffbd0b9ed90259a990d02d897ea099a0797cb4c6854ff82ec7b16f73c83149f21eaae4e6503e4d2396c languageName: node linkType: hard -"@polkadot/x-ws@npm:^9.4.1": - version: 9.4.1 - resolution: "@polkadot/x-ws@npm:9.4.1" +"@polkadot/x-ws@npm:^9.7.1": + version: 9.7.1 + resolution: "@polkadot/x-ws@npm:9.7.1" dependencies: - "@babel/runtime": ^7.18.3 - "@polkadot/x-global": 9.4.1 + "@babel/runtime": ^7.18.6 + "@polkadot/x-global": 9.7.1 "@types/websocket": ^1.0.5 websocket: ^1.0.34 - checksum: 9707197d80c475598ae8f326129b0d9f071291617adf88cc500de03b27ec6050226185b23d1076221bcc827f5c7664cc5f815c838ff265a2e3057e74ac045ba5 + checksum: acab2d65149109f4b829eb918fb01415e651f0bcb477a26705ef82501ce0188b263b81d98a80cdd01c4f2156aa11a26f2eeb4451154666534b958ef8df55927b languageName: node linkType: hard -"@scure/base@npm:1.0.0": - version: 1.0.0 - resolution: "@scure/base@npm:1.0.0" - checksum: 4bff6fd46fa4afeff58410a157edbb93e6d1aaeca8be18ecd9ec439d5e86e297e52d9288ab269d0ec5f861d55cf1664f26bd14812dd631784f6a9cc11276ff91 +"@scure/base@npm:1.1.1": + version: 1.1.1 + resolution: "@scure/base@npm:1.1.1" + checksum: b4fc810b492693e7e8d0107313ac74c3646970c198bbe26d7332820886fa4f09441991023ec9aa3a2a51246b74409ab5ebae2e8ef148bbc253da79ac49130309 languageName: node linkType: hard @@ -1615,32 +1619,32 @@ __metadata: languageName: node linkType: hard -"@substrate/connect@npm:0.7.5": - version: 0.7.5 - resolution: "@substrate/connect@npm:0.7.5" +"@substrate/connect@npm:0.7.7": + version: 0.7.7 + resolution: "@substrate/connect@npm:0.7.7" dependencies: "@substrate/connect-extension-protocol": ^1.0.0 - "@substrate/smoldot-light": 0.6.16 + "@substrate/smoldot-light": 0.6.19 eventemitter3: ^4.0.7 - checksum: fcebff1d5df50dcd4e26a43532f078add3eb36f12c85e52321b28990a7d5d6cc4540220027d26669c75578c6b25c4c0be6a7c0e8bb546ca1386770d1a13bb385 + checksum: a4c663415d57731cb435ce19e766040688201f5af5002a882d3858f0ff0607356025c6b3a40e2ce5c810fb1e41ac881c3d76e68276e1cede6b81e21bee2274ef languageName: node linkType: hard -"@substrate/smoldot-light@npm:0.6.16": - version: 0.6.16 - resolution: "@substrate/smoldot-light@npm:0.6.16" +"@substrate/smoldot-light@npm:0.6.19": + version: 0.6.19 + resolution: "@substrate/smoldot-light@npm:0.6.19" dependencies: buffer: ^6.0.1 pako: ^2.0.4 websocket: ^1.0.32 - checksum: 2e7d350ad8b77de847c3cf8153a5a63f44c307a937e698e0bd9f4706dc5c672607704648bfc4155b6ff63319367a8f13741647f843e41679d3756709295877e6 + checksum: 5d276c44d1782826fd1bbe3c517c70cdf3d0dc558c34615dcc4480b407fccf90b8a9d33c6058aefc50cdb47349fc65595312b4f6fd9f199d93a7b562f20759f6 languageName: node linkType: hard -"@substrate/ss58-registry@npm:^1.22.0": - version: 1.22.0 - resolution: "@substrate/ss58-registry@npm:1.22.0" - checksum: 5674b586680bd0d83a5da1bb790f84ed5184221e1b2935aed4f539c2e72311c53affb9d8a93e9a30727a409f874f7493569bd4e6990473957409dbf0a165b24d +"@substrate/ss58-registry@npm:^1.23.0": + version: 1.23.0 + resolution: "@substrate/ss58-registry@npm:1.23.0" + checksum: 6544c713f4200c32ed8cdc3dfe6296bbc5f6f32c27f05c725004eab10f2c0e17f56a44631c35ab58612b5e143de98321aa599b3bdc8c2a9ff6fc41e6e9b8c26b languageName: node linkType: hard @@ -1709,26 +1713,33 @@ __metadata: linkType: hard "@types/eslint-scope@npm:^3.7.3": - version: 3.7.3 - resolution: "@types/eslint-scope@npm:3.7.3" + version: 3.7.4 + resolution: "@types/eslint-scope@npm:3.7.4" dependencies: "@types/eslint": "*" "@types/estree": "*" - checksum: 6772b05e1b92003d1f295e81bc847a61f4fbe8ddab77ffa49e84ed3f9552513bdde677eb53ef167753901282857dd1d604d9f82eddb34a233495932b2dc3dc17 + checksum: ea6a9363e92f301cd3888194469f9ec9d0021fe0a397a97a6dd689e7545c75de0bd2153dfb13d3ab532853a278b6572c6f678ce846980669e41029d205653460 languageName: node linkType: hard "@types/eslint@npm:*": - version: 8.4.2 - resolution: "@types/eslint@npm:8.4.2" + version: 8.4.5 + resolution: "@types/eslint@npm:8.4.5" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: e81268cdeb8d64d84af649344df88f064ece0f05db62072657c976b6162ffe16f94b6480a5367d627c629272c2d86d0ee8c24f7095e98f8e743b16f98500673b + checksum: 428b0c971a50adb0d08621e76f21b284580a0052a31341a0e6d553f72b54cd0142d549aa1497c7e3bc56e9f6bcc27286e66e0216e1ba76d1a5ecd2279c40bc8c + languageName: node + linkType: hard + +"@types/estree@npm:*": + version: 0.0.52 + resolution: "@types/estree@npm:0.0.52" + checksum: d1cba22160e7aebf865ea0dbc30807bee272fdafdb57d8dd25749f4b312cd9a99e9e933340b7b26284d7a47c8805aba43bb46cf5f1df00cdaaec67bbdc894d4a languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:^0.0.51": +"@types/estree@npm:^0.0.51": version: 0.0.51 resolution: "@types/estree@npm:0.0.51" checksum: e56a3bcf759fd9185e992e7fdb3c6a5f81e8ff120e871641607581fb3728d16c811702a7d40fa5f869b7f7b4437ab6a87eb8d98ffafeee51e85bbe955932a189 @@ -1770,12 +1781,12 @@ __metadata: linkType: hard "@types/jest@npm:^27.4.0": - version: 27.5.1 - resolution: "@types/jest@npm:27.5.1" + version: 27.5.2 + resolution: "@types/jest@npm:27.5.2" dependencies: jest-matcher-utils: ^27.0.0 pretty-format: ^27.0.0 - checksum: be20e39f7aaf17179109c0060d0a0489cec2034d4e2e28a631284c7ecd13c5ae52f62697a33a0e89b03b6cfe54e9d5e8c2bd387ab2bd90d6071d68c63b86d1e3 + checksum: 7e11c6826aa429ad990dc262e4e4b54aa36573287fddf15773e4137f07d11d3105f0dd9f1baff73252160a057df23f5529bb83b1bf83cd3f45f9460a5ca5c22e languageName: node linkType: hard @@ -1807,20 +1818,20 @@ __metadata: languageName: node linkType: hard -"@types/node-fetch@npm:^2.6.1": - version: 2.6.1 - resolution: "@types/node-fetch@npm:2.6.1" +"@types/node-fetch@npm:^2.6.2": + version: 2.6.2 + resolution: "@types/node-fetch@npm:2.6.2" dependencies: "@types/node": "*" form-data: ^3.0.0 - checksum: a3e5d7f413d1638d795dff03f7b142b1b0e0c109ed210479000ce7b3ea11f9a6d89d9a024c96578d9249570c5fe5287a5f0f4aaba98199222230196ff2d6b283 + checksum: 6f73b1470000d303d25a6fb92875ea837a216656cb7474f66cdd67bb014aa81a5a11e7ac9c21fe19bee9ecb2ef87c1962bceeaec31386119d1ac86e4c30ad7a6 languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^17.0.35": - version: 17.0.35 - resolution: "@types/node@npm:17.0.35" - checksum: 7a24946ae7fd20267ed92466384f594e448bfb151081158d565cc635d406ecb29ea8fb85fcd2a1f71efccf26fb5bd3c6f509bde56077eb8b832b847a6664bc62 +"@types/node@npm:*": + version: 18.0.1 + resolution: "@types/node@npm:18.0.1" + checksum: be14b251c54cc2b4ca78ac6eadf2fe5e831e487f2e17848f21d576295945b538271dcc674d0bba582b3f8d95b84f6826e99b6ba4710c76f165a8bdd4d4f0618e languageName: node linkType: hard @@ -1839,9 +1850,9 @@ __metadata: linkType: hard "@types/prettier@npm:^2.1.5": - version: 2.6.1 - resolution: "@types/prettier@npm:2.6.1" - checksum: b25ec46d18129fa40c1a1f42feb7406e8f19901ba5261ba3c71600ad14996ae07b4f4b727a9b83da673948011e59d870fc519166f05b5d49e9ad39db1aea8c93 + version: 2.6.3 + resolution: "@types/prettier@npm:2.6.3" + checksum: e1836699ca189fff6d2a73dc22e028b6a6f693ed1180d5998ac29fa197caf8f85aa92cb38db642e4a370e616b451cb5722ad2395dab11c78e025a1455f37d1f0 languageName: node linkType: hard @@ -1885,12 +1896,12 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^5.7.0": - version: 5.25.0 - resolution: "@typescript-eslint/eslint-plugin@npm:5.25.0" + version: 5.30.4 + resolution: "@typescript-eslint/eslint-plugin@npm:5.30.4" dependencies: - "@typescript-eslint/scope-manager": 5.25.0 - "@typescript-eslint/type-utils": 5.25.0 - "@typescript-eslint/utils": 5.25.0 + "@typescript-eslint/scope-manager": 5.30.4 + "@typescript-eslint/type-utils": 5.30.4 + "@typescript-eslint/utils": 5.30.4 debug: ^4.3.4 functional-red-black-tree: ^1.0.1 ignore: ^5.2.0 @@ -1903,42 +1914,42 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 7a47dc9b95031ab9e8d94a062b95c124486d471fa385335ef0129eff0854043b1894233fe28a2832cbf1c2be235242cf1eba087f4da1f4262599f18147ee1edd + checksum: 9b9290448b3009b93dc9bbc263049103f48c006d395351695486f7ab156f24b3f3e9e83a9f68a8cf73afc036c2d1092005446085f171afc9cdcb0b1b475443e3 languageName: node linkType: hard "@typescript-eslint/parser@npm:^5.7.0": - version: 5.25.0 - resolution: "@typescript-eslint/parser@npm:5.25.0" + version: 5.30.4 + resolution: "@typescript-eslint/parser@npm:5.30.4" dependencies: - "@typescript-eslint/scope-manager": 5.25.0 - "@typescript-eslint/types": 5.25.0 - "@typescript-eslint/typescript-estree": 5.25.0 + "@typescript-eslint/scope-manager": 5.30.4 + "@typescript-eslint/types": 5.30.4 + "@typescript-eslint/typescript-estree": 5.30.4 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 9bd53d6f5f5e7b64282760a4f68411f6f6e272754aa8b4c54951bd03c18981183277dfefff1207c3d549d25d34dbe162472f7fa102ec5306113a7811f263fc00 + checksum: e13ffd0cbb691b5b82038a5a1475a7771409398bc90e0430e9b3818174926c5af7c637d5915f7c2949f38201c04bfe57dfc91f4d9052a48ee551faba3b8c7349 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.25.0": - version: 5.25.0 - resolution: "@typescript-eslint/scope-manager@npm:5.25.0" +"@typescript-eslint/scope-manager@npm:5.30.4": + version: 5.30.4 + resolution: "@typescript-eslint/scope-manager@npm:5.30.4" dependencies: - "@typescript-eslint/types": 5.25.0 - "@typescript-eslint/visitor-keys": 5.25.0 - checksum: 0616bad66bd3fe885df3401bbc3ab6631dca3b70ca3d2e8a9881d9a27654e3df9fd219abc9b7e1c23668c113d54bbb049c6231af3a2d86abcd919329b1cb4ff4 + "@typescript-eslint/types": 5.30.4 + "@typescript-eslint/visitor-keys": 5.30.4 + checksum: 3da442dc113ee821c6b1c4510ee4cfd6f6f34838587785b7c486d262af913dca66229a47ebb9a63ad605f8edbe57a8387be24c817c8091783b57c33b7862cbcc languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.25.0": - version: 5.25.0 - resolution: "@typescript-eslint/type-utils@npm:5.25.0" +"@typescript-eslint/type-utils@npm:5.30.4": + version: 5.30.4 + resolution: "@typescript-eslint/type-utils@npm:5.30.4" dependencies: - "@typescript-eslint/utils": 5.25.0 + "@typescript-eslint/utils": 5.30.4 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -1946,23 +1957,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: f733b42437e7a023985ad9324e57171c8b358f54a0c5a3be3b7bc7f317f1eeee4a60d14a1873efd820a3f9011c395f5e3a75eac4eaac520948aeba4d3e4e4953 + checksum: 552eb1a5b11787d3b98dc454a80153b05bcb6d58aeb97c861d6b006f3eb6af95d117a3f9a679b41a8b6d58ac0dceaaeafd23ce28d83881a363e51bbc1a088936 languageName: node linkType: hard -"@typescript-eslint/types@npm:5.25.0": - version: 5.25.0 - resolution: "@typescript-eslint/types@npm:5.25.0" - checksum: 0fa7eba1e35bbc32d865ce38cc5800aedf2b1d8aa17e8a20ff1cf05b59a92a684c0727f7ac2a26ecdf17483957bea163fe03fc1556503f23e0d974a8d9c33b82 +"@typescript-eslint/types@npm:5.30.4": + version: 5.30.4 + resolution: "@typescript-eslint/types@npm:5.30.4" + checksum: 06181c33551850492ccfd48232f93083c6cf9205d26b26fe6e356b7a4ebb08beffd89ae3b84011da94ffd0e6948422d91d94df7005edeca1c8348117d4776715 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.25.0": - version: 5.25.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.25.0" +"@typescript-eslint/typescript-estree@npm:5.30.4": + version: 5.30.4 + resolution: "@typescript-eslint/typescript-estree@npm:5.30.4" dependencies: - "@typescript-eslint/types": 5.25.0 - "@typescript-eslint/visitor-keys": 5.25.0 + "@typescript-eslint/types": 5.30.4 + "@typescript-eslint/visitor-keys": 5.30.4 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -1971,33 +1982,33 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 72638b1a9826a3062f629e23d3c9147646dc2740add1aa8bb2e63131215eed3309bc86647f7e52acecf3c169e94677d869690a050de37b7cd880ea89c63bde2a + checksum: 1aaa414993a4e35927e93f929d34a6e07cb8ec46c4ea9a58f018c36ff1fc3027ca5007e6abe922c5869557cd2d7f319e8c57cccd618517781979e669d3b704d0 languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.25.0": - version: 5.25.0 - resolution: "@typescript-eslint/utils@npm:5.25.0" +"@typescript-eslint/utils@npm:5.30.4": + version: 5.30.4 + resolution: "@typescript-eslint/utils@npm:5.30.4" dependencies: "@types/json-schema": ^7.0.9 - "@typescript-eslint/scope-manager": 5.25.0 - "@typescript-eslint/types": 5.25.0 - "@typescript-eslint/typescript-estree": 5.25.0 + "@typescript-eslint/scope-manager": 5.30.4 + "@typescript-eslint/types": 5.30.4 + "@typescript-eslint/typescript-estree": 5.30.4 eslint-scope: ^5.1.1 eslint-utils: ^3.0.0 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 744ab15cf003882db2f63b4cef1b788d5f3ab0f4b2f2fb0c1eee942cf899df9c66a34e2f6f614f1c562257041119ec03c12446f4ae72147b5f7cc0a2e5276ea6 + checksum: 0f680d366701c6ca5a4e1fc53247876e6f6acaee498400d32a7cb767e6187d0d75bc4488350cf6dc6e7c373ea023d62e395ea14ba56ad246b458d6853b213782 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.25.0": - version: 5.25.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.25.0" +"@typescript-eslint/visitor-keys@npm:5.30.4": + version: 5.30.4 + resolution: "@typescript-eslint/visitor-keys@npm:5.30.4" dependencies: - "@typescript-eslint/types": 5.25.0 + "@typescript-eslint/types": 5.30.4 eslint-visitor-keys: ^3.3.0 - checksum: ec4d0558cf53305703c18dfd7e1cd53fc0736303a51d93a875227896a230fd049951cc0600c539719cc351d2c96cb4abc6aa9dd9b3a8401f27bb8033093f35b7 + checksum: ec39680a89b058e8350adc084c2a957e83161e87ac9732c9fef8fd3045ce5004e059b2ddb0c366192806e3998bf3263c8bbb2cc74a4f2ad3313154ed35dd479a languageName: node linkType: hard @@ -2152,36 +2163,36 @@ __metadata: languageName: node linkType: hard -"@webpack-cli/configtest@npm:^1.1.1": - version: 1.1.1 - resolution: "@webpack-cli/configtest@npm:1.1.1" +"@webpack-cli/configtest@npm:^1.2.0": + version: 1.2.0 + resolution: "@webpack-cli/configtest@npm:1.2.0" peerDependencies: webpack: 4.x.x || 5.x.x webpack-cli: 4.x.x - checksum: c4e7fca21315e487655fbdc7d079092c3f88b274a720d245ca2e13dce7553009fb3f9d82218c33f5c9b208832d72bb4114a9cca97d53b66212eff5da1d3ad44b + checksum: a2726cd9ec601d2b57e5fc15e0ebf5200a8892065e735911269ac2038e62be4bfc176ea1f88c2c46ff09b4d05d4c10ae045e87b3679372483d47da625a327e28 languageName: node linkType: hard -"@webpack-cli/info@npm:^1.4.1": - version: 1.4.1 - resolution: "@webpack-cli/info@npm:1.4.1" +"@webpack-cli/info@npm:^1.5.0": + version: 1.5.0 + resolution: "@webpack-cli/info@npm:1.5.0" dependencies: envinfo: ^7.7.3 peerDependencies: webpack-cli: 4.x.x - checksum: 7a7cac2ba4f2528caa329311599da1685b1bc099bfc5b7210932b7c86024c1277fd7857b08557902b187ea01247a8e8f72f7f5719af72b0c8d97f22087aa0c14 + checksum: 7f56fe037cd7d1fd5c7428588519fbf04a0cad33925ee4202ffbafd00f8ec1f2f67d991245e687d50e0f3e23f7b7814273d56cb9f7da4b05eed47c8d815c6296 languageName: node linkType: hard -"@webpack-cli/serve@npm:^1.6.1": - version: 1.6.1 - resolution: "@webpack-cli/serve@npm:1.6.1" +"@webpack-cli/serve@npm:^1.7.0": + version: 1.7.0 + resolution: "@webpack-cli/serve@npm:1.7.0" peerDependencies: webpack-cli: 4.x.x peerDependenciesMeta: webpack-dev-server: optional: true - checksum: 8b273f906aeffa60c7d5700ae25f98d4b66b7e922cad38acb9575d55ff83872cd20b9894aacfa81c4d54e5b51b16253ae0e70c5e9e0608dc8768276e15c74536 + checksum: d475e8effa23eb7ff9a48b14d4de425989fd82f906ce71c210921cc3852327c22873be00c35e181a25a6bd03d424ae2b83e7f3b3f410ac7ee31b128ab4ac7713 languageName: node linkType: hard @@ -2326,7 +2337,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.10.0, ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5": +"ajv@npm:^6.10.0, ajv@npm:^6.12.4, ajv@npm:^6.12.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -2492,22 +2503,6 @@ __metadata: languageName: node linkType: hard -"asn1@npm:~0.2.3": - version: 0.2.6 - resolution: "asn1@npm:0.2.6" - dependencies: - safer-buffer: ~2.1.0 - checksum: 39f2ae343b03c15ad4f238ba561e626602a3de8d94ae536c46a4a93e69578826305366dc09fbb9b56aec39b4982a463682f259c38e59f6fa380cd72cd61e493d - languageName: node - linkType: hard - -"assert-plus@npm:1.0.0, assert-plus@npm:^1.0.0": - version: 1.0.0 - resolution: "assert-plus@npm:1.0.0" - checksum: 19b4340cb8f0e6a981c07225eacac0e9d52c2644c080198765d63398f0075f83bbc0c8e95474d54224e297555ad0d631c1dcd058adb1ddc2437b41a6b424ac64 - languageName: node - linkType: hard - "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -2529,20 +2524,6 @@ __metadata: languageName: node linkType: hard -"aws-sign2@npm:~0.7.0": - version: 0.7.0 - resolution: "aws-sign2@npm:0.7.0" - checksum: b148b0bb0778098ad8cf7e5fc619768bcb51236707ca1d3e5b49e41b171166d8be9fdc2ea2ae43d7decf02989d0aaa3a9c4caa6f320af95d684de9b548a71525 - languageName: node - linkType: hard - -"aws4@npm:^1.8.0": - version: 1.11.0 - resolution: "aws4@npm:1.11.0" - checksum: 5a00d045fd0385926d20ebebcfba5ec79d4482fe706f63c27b324d489a04c68edb0db99ed991e19eda09cb8c97dc2452059a34d97545cebf591d7a2b5a10999f - languageName: node - linkType: hard - "babel-jest@npm:^27.5.1": version: 27.5.1 resolution: "babel-jest@npm:27.5.1" @@ -2627,15 +2608,6 @@ __metadata: languageName: node linkType: hard -"base-x@npm:^3.0.2": - version: 3.0.9 - resolution: "base-x@npm:3.0.9" - dependencies: - safe-buffer: ^5.0.1 - checksum: 957101d6fd09e1903e846fd8f69fd7e5e3e50254383e61ab667c725866bec54e5ece5ba49ce385128ae48f9ec93a26567d1d5ebb91f4d56ef4a9cc0d5a5481e8 - languageName: node - linkType: hard - "base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -2643,38 +2615,6 @@ __metadata: languageName: node linkType: hard -"base64url-universal@npm:^1.0.1": - version: 1.1.0 - resolution: "base64url-universal@npm:1.1.0" - dependencies: - base64url: ^3.0.0 - checksum: ccc38572082df79ba845ddb84cc064b2e16490687fb1d138ef0e64f0e14d1ca2800b1cbe976f3d59ce79dc31a6cb3985aec7b64e295a8001becbf032bac26276 - languageName: node - linkType: hard - -"base64url@npm:^3.0.0, base64url@npm:^3.0.1": - version: 3.0.1 - resolution: "base64url@npm:3.0.1" - checksum: a77b2a3a526b3343e25be424de3ae0aa937d78f6af7c813ef9020ef98001c0f4e2323afcd7d8b2d2978996bf8c42445c3e9f60c218c622593e5fdfd54a3d6e18 - languageName: node - linkType: hard - -"bcrypt-pbkdf@npm:^1.0.0": - version: 1.0.2 - resolution: "bcrypt-pbkdf@npm:1.0.2" - dependencies: - tweetnacl: ^0.14.3 - checksum: 4edfc9fe7d07019609ccf797a2af28351736e9d012c8402a07120c4453a3b789a15f2ee1530dc49eee8f7eb9379331a8dd4b3766042b9e502f74a68e7f662291 - languageName: node - linkType: hard - -"blakejs@npm:^1.1.1": - version: 1.2.1 - resolution: "blakejs@npm:1.2.1" - checksum: d699ba116cfa21d0b01d12014a03e484dd76d483133e6dc9eb415aa70a119f08beb3bcefb8c71840106a00b542cba77383f8be60cd1f0d4589cb8afb922eefbe - languageName: node - linkType: hard - "bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9": version: 4.12.0 resolution: "bn.js@npm:4.12.0" @@ -2682,14 +2622,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.0.0, bn.js@npm:^5.1.1": - version: 5.2.0 - resolution: "bn.js@npm:5.2.0" - checksum: 6117170393200f68b35a061ecbf55d01dd989302e7b3c798a3012354fa638d124f0b2f79e63f77be5556be80322a09c40339eda6413ba7468524c0b6d4b4cb7a - languageName: node - linkType: hard - -"bn.js@npm:^5.2.1": +"bn.js@npm:^5.0.0, bn.js@npm:^5.1.1, bn.js@npm:^5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 @@ -2803,17 +2736,16 @@ __metadata: linkType: hard "browserslist@npm:^4.14.5, browserslist@npm:^4.20.2": - version: 4.20.3 - resolution: "browserslist@npm:4.20.3" + version: 4.21.1 + resolution: "browserslist@npm:4.21.1" dependencies: - caniuse-lite: ^1.0.30001332 - electron-to-chromium: ^1.4.118 - escalade: ^3.1.1 - node-releases: ^2.0.3 - picocolors: ^1.0.0 + caniuse-lite: ^1.0.30001359 + electron-to-chromium: ^1.4.172 + node-releases: ^2.0.5 + update-browserslist-db: ^1.0.4 bin: browserslist: cli.js - checksum: 1e4b719ac2ca0fe235218a606e8b8ef16b8809e0973b924158c39fbc435a0b0fe43437ea52dd6ef5ad2efcb83fcb07431244e472270177814217f7c563651f7d + checksum: 4904a9ded0702381adc495e003e7f77970abb7f8c8b8edd9e54f026354b5a96b1bddc26e6d9a7df9f043e468ecd2fcff2c8f40fc489909a042880117c2aca8ff languageName: node linkType: hard @@ -2826,15 +2758,6 @@ __metadata: languageName: node linkType: hard -"bs58@npm:^4.0.1": - version: 4.0.1 - resolution: "bs58@npm:4.0.1" - dependencies: - base-x: ^3.0.2 - checksum: b3c5365bb9e0c561e1a82f1a2d809a1a692059fae016be233a6127ad2f50a6b986467c3a50669ce4c18929dcccb297c5909314dd347a25a68c21b68eb3e95ac2 - languageName: node - linkType: hard - "bser@npm:2.1.1": version: 2.1.1 resolution: "bser@npm:2.1.1" @@ -2879,8 +2802,8 @@ __metadata: linkType: hard "cacache@npm:^16.1.0": - version: 16.1.0 - resolution: "cacache@npm:16.1.0" + version: 16.1.1 + resolution: "cacache@npm:16.1.1" dependencies: "@npmcli/fs": ^2.1.0 "@npmcli/move-file": ^2.0.0 @@ -2900,7 +2823,7 @@ __metadata: ssri: ^9.0.0 tar: ^6.1.11 unique-filename: ^1.1.1 - checksum: ddfcf92f079f24ccecef4e2ca1e4428443787b61429b921803b020fd0f33d9ac829ac47837b74b40868d8ae4f1b2ed82e164cdaa5508fbd790eee005a9d88469 + checksum: 488524617008b793f0249b0c4ea2c330c710ca997921376e15650cc2415a8054491ae2dee9f01382c2015602c0641f3f977faf2fa7361aa33d2637dcfb03907a languageName: node linkType: hard @@ -2946,10 +2869,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001332": - version: 1.0.30001341 - resolution: "caniuse-lite@npm:1.0.30001341" - checksum: 7262b093fb0bf49dbc5328418f5ce4e3dbb0b13e39c015f986ba1807634c123ac214efc94df7d095a336f57f86852b4b63ee61838f18dcc3a4a35f87b390c8f5 +"caniuse-lite@npm:^1.0.30001359": + version: 1.0.30001362 + resolution: "caniuse-lite@npm:1.0.30001362" + checksum: bd35704a81aa8ca12e952c2276d205109a5d10bd7d0fb767c27ee9bdbc8011c5c99a9772833701d68ed2fe7143f1744258c1cc440dd7ea4584a1354f6dac9f0a languageName: node linkType: hard @@ -2960,13 +2883,6 @@ __metadata: languageName: node linkType: hard -"caseless@npm:~0.12.0": - version: 0.12.0 - resolution: "caseless@npm:0.12.0" - checksum: b43bd4c440aa1e8ee6baefee8063b4850fd0d7b378f6aabc796c9ec8cb26d27fb30b46885350777d9bd079c5256c0e1329ad0dc7c2817e0bb466810ebb353751 - languageName: node - linkType: hard - "chalk@npm:4.1.0": version: 4.1.0 resolution: "chalk@npm:4.1.0" @@ -3020,9 +2936,9 @@ __metadata: linkType: hard "ci-info@npm:^3.2.0": - version: 3.3.1 - resolution: "ci-info@npm:3.3.1" - checksum: 244546317cca96955860d2cb8d0bf47dd66d9078bbe83a215fa87464ab24b352c6fc6f56027d1c82f002e3f833be253f1320d35ed7199bd81134f7788c657f3a + version: 3.3.2 + resolution: "ci-info@npm:3.3.2" + checksum: fd81f1edd2d3b0f6cb077b2e84365136d87b9db8c055928c1ad69da8a76c2c2f19cba8ea51b90238302157ca927f91f92b653e933f2398dde4867500f08d6e62 languageName: node linkType: hard @@ -3139,13 +3055,13 @@ __metadata: linkType: hard "colorette@npm:^2.0.14": - version: 2.0.16 - resolution: "colorette@npm:2.0.16" - checksum: cd55596a3a2d1071c1a28eee7fd8a5387593ff1bd10a3e8d0a6221499311fe34a9f2b9272d77c391e0e003dcdc8934fb2f8d106e7ef1f7516f8060c901d41a27 + version: 2.0.19 + resolution: "colorette@npm:2.0.19" + checksum: 888cf5493f781e5fcf54ce4d49e9d7d698f96ea2b2ef67906834bb319a392c667f9ec69f4a10e268d2946d13a9503d2d19b3abaaaf174e3451bfe91fb9d82427 languageName: node linkType: hard -"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8, combined-stream@npm:~1.0.6": +"combined-stream@npm:^1.0.8": version: 1.0.8 resolution: "combined-stream@npm:1.0.8" dependencies: @@ -3154,7 +3070,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^2.20.0, commander@npm:^2.20.3": +"commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e @@ -3263,16 +3179,9 @@ __metadata: linkType: hard "core-js@npm:^3.6.1": - version: 3.22.5 - resolution: "core-js@npm:3.22.5" - checksum: d3d7495d7cdde01cf9ac3debc5087afc3c8dd56baa4953d9ccbb46b1a80872c79d14c1e6343c664c9c0fade288ab44c70b54dd34f879a71e6eff6fffeab84e00 - languageName: node - linkType: hard - -"core-util-is@npm:1.0.2": - version: 1.0.2 - resolution: "core-util-is@npm:1.0.2" - checksum: 7a4c925b497a2c91421e25bf76d6d8190f0b2359a9200dbeed136e63b2931d6294d3b1893eda378883ed363cd950f44a12a401384c609839ea616befb7927dab + version: 3.23.3 + resolution: "core-js@npm:3.23.3" + checksum: f517546388e468bd3155afbf06f38f8fe0448134fe086c4ed9c4d371d52db71e80585073b59362948777e01f2377ef7064925e1a3d9312a1c56da47eadfaca9a languageName: node linkType: hard @@ -3326,10 +3235,10 @@ __metadata: languageName: node linkType: hard -"credentials-context@npm:^1.0.0": - version: 1.0.0 - resolution: "credentials-context@npm:1.0.0" - checksum: f7c1df5339e15a6496e4760ad8a3a75cad22dbdd263f23b9c13fd4c8da49c4f5258f2940e92cd5628c1882da54d895c014bbabd7c1f87e9c8b68f02bba0feca2 +"credentials-context@npm:^2.0.0": + version: 2.0.0 + resolution: "credentials-context@npm:2.0.0" + checksum: c5ba6d257ef2fb1c21399238f5b1e0b2f7622b1f496f499edbac2d2e0faba40ebc06e0c5acee4bb2fbe712abfa3cbebdcc152f4bcf5a7481430f2731f2c514db languageName: node linkType: hard @@ -3363,19 +3272,10 @@ __metadata: languageName: node linkType: hard -"crypto-ld@npm:^3.7.0": - version: 3.9.0 - resolution: "crypto-ld@npm:3.9.0" - dependencies: - base64url-universal: ^1.0.1 - bs58: ^4.0.1 - node-forge: ~0.10.0 - semver: ^6.2.0 - sodium-native: ^3.2.0 - dependenciesMeta: - sodium-native: - optional: true - checksum: d1d24e946d0b35bfe7b063d596e19dbaebe2420b7ec4a03b21b81bf7e05ce7e8ec6c85b1b84f87cb684f96789dcccf984af8f12e41c69d0dd5a9299ef66c11f7 +"crypto-ld@npm:^7.0.0": + version: 7.0.0 + resolution: "crypto-ld@npm:7.0.0" + checksum: dcea2f482a0c19d714379fada30e7cb940a3c264b19ab92df0b3cc0f3f6f7ce9a5422b4d6827f6ece8942f24157f441c79178137eff1a65bd62164e0a3f819ad languageName: node linkType: hard @@ -3419,19 +3319,10 @@ __metadata: languageName: node linkType: hard -"dashdash@npm:^1.12.0": - version: 1.14.1 - resolution: "dashdash@npm:1.14.1" - dependencies: - assert-plus: ^1.0.0 - checksum: 3634c249570f7f34e3d34f866c93f866c5b417f0dd616275decae08147dcdf8fccfaa5947380ccfb0473998ea3a8057c0b4cd90c875740ee685d0624b2983598 - languageName: node - linkType: hard - -"data-uri-to-buffer@npm:^3.0.1": - version: 3.0.1 - resolution: "data-uri-to-buffer@npm:3.0.1" - checksum: c59c3009686a78c071806b72f4810856ec28222f0f4e252aa495ec027ed9732298ceea99c50328cf59b151dd34cbc3ad6150bbb43e41fc56fa19f48c99e9fc30 +"data-uri-to-buffer@npm:^4.0.0": + version: 4.0.0 + resolution: "data-uri-to-buffer@npm:4.0.0" + checksum: a010653869abe8bb51259432894ac62c52bf79ad761d418d94396f48c346f2ae739c46b254e8bb5987bded8a653d467db1968db3a69bab1d33aa5567baa5cfc7 languageName: node linkType: hard @@ -3641,16 +3532,6 @@ __metadata: languageName: node linkType: hard -"ecc-jsbn@npm:~0.1.1": - version: 0.1.2 - resolution: "ecc-jsbn@npm:0.1.2" - dependencies: - jsbn: ~0.1.0 - safer-buffer: ^2.1.0 - checksum: 22fef4b6203e5f31d425f5b711eb389e4c6c2723402e389af394f8411b76a488fa414d309d866e2b577ce3e8462d344205545c88a8143cc21752a5172818888a - languageName: node - linkType: hard - "ed2curve@npm:^0.3.0": version: 0.3.0 resolution: "ed2curve@npm:0.3.0" @@ -3660,10 +3541,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.118": - version: 1.4.137 - resolution: "electron-to-chromium@npm:1.4.137" - checksum: 639d7b94906efafcf363519c3698eecc44be46755a6a5cdc9088954329978866cc93fbd57e08b97290599b68d5226243d21de9fa50be416b8a5d3fa8fd42c3a0 +"electron-to-chromium@npm:^1.4.172": + version: 1.4.177 + resolution: "electron-to-chromium@npm:1.4.177" + checksum: e373df9b001c9a77a33b78ab4b8dbe6ee4175eb630c7d8dbe3671eb50be62a91c220cec71d56c2da3c532679ee692fe34715b915b900dec0962c08a983d06a86 languageName: node linkType: hard @@ -3706,12 +3587,12 @@ __metadata: linkType: hard "enhanced-resolve@npm:^5.9.3": - version: 5.9.3 - resolution: "enhanced-resolve@npm:5.9.3" + version: 5.10.0 + resolution: "enhanced-resolve@npm:5.10.0" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: 64c2dbbdd608d1a4df93b6e60786c603a1faf3b2e66dfd051d62cf4cfaeeb5e800166183685587208d62e9f7afff3f78f3d5978e32cd80125ba0c83b59a79d78 + checksum: 0bb9830704db271610f900e8d79d70a740ea16f251263362b0c91af545576d09fe50103496606c1300a05e588372d6f9780a9bc2e30ce8ef9b827ec8f44687ff languageName: node linkType: hard @@ -3855,170 +3736,170 @@ __metadata: languageName: node linkType: hard -"esbuild-android-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-android-64@npm:0.14.38" +"esbuild-android-64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-android-64@npm:0.14.48" conditions: os=android & cpu=x64 languageName: node linkType: hard -"esbuild-android-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-android-arm64@npm:0.14.38" +"esbuild-android-arm64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-android-arm64@npm:0.14.48" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"esbuild-darwin-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-darwin-64@npm:0.14.38" +"esbuild-darwin-64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-darwin-64@npm:0.14.48" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"esbuild-darwin-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-darwin-arm64@npm:0.14.38" +"esbuild-darwin-arm64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-darwin-arm64@npm:0.14.48" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"esbuild-freebsd-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-freebsd-64@npm:0.14.38" +"esbuild-freebsd-64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-freebsd-64@npm:0.14.48" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"esbuild-freebsd-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-freebsd-arm64@npm:0.14.38" +"esbuild-freebsd-arm64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-freebsd-arm64@npm:0.14.48" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"esbuild-linux-32@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-32@npm:0.14.38" +"esbuild-linux-32@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-linux-32@npm:0.14.48" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"esbuild-linux-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-64@npm:0.14.38" +"esbuild-linux-64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-linux-64@npm:0.14.48" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"esbuild-linux-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-arm64@npm:0.14.38" +"esbuild-linux-arm64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-linux-arm64@npm:0.14.48" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"esbuild-linux-arm@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-arm@npm:0.14.38" +"esbuild-linux-arm@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-linux-arm@npm:0.14.48" conditions: os=linux & cpu=arm languageName: node linkType: hard -"esbuild-linux-mips64le@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-mips64le@npm:0.14.38" +"esbuild-linux-mips64le@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-linux-mips64le@npm:0.14.48" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"esbuild-linux-ppc64le@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-ppc64le@npm:0.14.38" +"esbuild-linux-ppc64le@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-linux-ppc64le@npm:0.14.48" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"esbuild-linux-riscv64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-riscv64@npm:0.14.38" +"esbuild-linux-riscv64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-linux-riscv64@npm:0.14.48" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"esbuild-linux-s390x@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-s390x@npm:0.14.38" +"esbuild-linux-s390x@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-linux-s390x@npm:0.14.48" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"esbuild-netbsd-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-netbsd-64@npm:0.14.38" +"esbuild-netbsd-64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-netbsd-64@npm:0.14.48" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"esbuild-openbsd-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-openbsd-64@npm:0.14.38" +"esbuild-openbsd-64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-openbsd-64@npm:0.14.48" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"esbuild-sunos-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-sunos-64@npm:0.14.38" +"esbuild-sunos-64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-sunos-64@npm:0.14.48" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"esbuild-windows-32@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-windows-32@npm:0.14.38" +"esbuild-windows-32@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-windows-32@npm:0.14.48" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"esbuild-windows-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-windows-64@npm:0.14.38" +"esbuild-windows-64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-windows-64@npm:0.14.48" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"esbuild-windows-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-windows-arm64@npm:0.14.38" +"esbuild-windows-arm64@npm:0.14.48": + version: 0.14.48 + resolution: "esbuild-windows-arm64@npm:0.14.48" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"esbuild@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild@npm:0.14.38" - dependencies: - esbuild-android-64: 0.14.38 - esbuild-android-arm64: 0.14.38 - esbuild-darwin-64: 0.14.38 - esbuild-darwin-arm64: 0.14.38 - esbuild-freebsd-64: 0.14.38 - esbuild-freebsd-arm64: 0.14.38 - esbuild-linux-32: 0.14.38 - esbuild-linux-64: 0.14.38 - esbuild-linux-arm: 0.14.38 - esbuild-linux-arm64: 0.14.38 - esbuild-linux-mips64le: 0.14.38 - esbuild-linux-ppc64le: 0.14.38 - esbuild-linux-riscv64: 0.14.38 - esbuild-linux-s390x: 0.14.38 - esbuild-netbsd-64: 0.14.38 - esbuild-openbsd-64: 0.14.38 - esbuild-sunos-64: 0.14.38 - esbuild-windows-32: 0.14.38 - esbuild-windows-64: 0.14.38 - esbuild-windows-arm64: 0.14.38 +"esbuild@npm:~0.14.47": + version: 0.14.48 + resolution: "esbuild@npm:0.14.48" + dependencies: + esbuild-android-64: 0.14.48 + esbuild-android-arm64: 0.14.48 + esbuild-darwin-64: 0.14.48 + esbuild-darwin-arm64: 0.14.48 + esbuild-freebsd-64: 0.14.48 + esbuild-freebsd-arm64: 0.14.48 + esbuild-linux-32: 0.14.48 + esbuild-linux-64: 0.14.48 + esbuild-linux-arm: 0.14.48 + esbuild-linux-arm64: 0.14.48 + esbuild-linux-mips64le: 0.14.48 + esbuild-linux-ppc64le: 0.14.48 + esbuild-linux-riscv64: 0.14.48 + esbuild-linux-s390x: 0.14.48 + esbuild-netbsd-64: 0.14.48 + esbuild-openbsd-64: 0.14.48 + esbuild-sunos-64: 0.14.48 + esbuild-windows-32: 0.14.48 + esbuild-windows-64: 0.14.48 + esbuild-windows-arm64: 0.14.48 dependenciesMeta: esbuild-android-64: optional: true @@ -4062,7 +3943,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: d7523a36bd28016c010829c527386dbc0c6b9f514920abf5ac8003f346665161aa61026fd6822c5091fc1c1af52fe26c9281a81740fc06f2994cdbb7c2880297 + checksum: 352d5f5678b697eaafe0bb3374e3da013b31df98c2da17e94266f0bd9d421c531733df038d5b3548d1e8bc86daac0417f1ba2df1cc184685fdb899e1f309f47d languageName: node linkType: hard @@ -4239,8 +4120,8 @@ __metadata: linkType: hard "eslint-plugin-prettier@npm:^4.0.0": - version: 4.0.0 - resolution: "eslint-plugin-prettier@npm:4.0.0" + version: 4.2.1 + resolution: "eslint-plugin-prettier@npm:4.2.1" dependencies: prettier-linter-helpers: ^1.0.0 peerDependencies: @@ -4249,7 +4130,7 @@ __metadata: peerDependenciesMeta: eslint-config-prettier: optional: true - checksum: 03d69177a3c21fa2229c7e427ce604429f0b20ab7f411e2e824912f572a207c7f5a41fd1f0a95b9b8afe121e291c1b1f1dc1d44c7aad4b0837487f9c19f5210d + checksum: b9e839d2334ad8ec7a5589c5cb0f219bded260839a857d7a486997f9870e95106aa59b8756ff3f37202085ebab658de382b0267cae44c3a7f0eb0bcc03a4f6d6 languageName: node linkType: hard @@ -4354,13 +4235,6 @@ __metadata: languageName: node linkType: hard -"esm@npm:^3.2.22": - version: 3.2.25 - resolution: "esm@npm:3.2.25" - checksum: 978aabe2de83541c105605a6d60a26ed8e627ef6bb0a7605fe15a95bbdea6b8348bd045255cb22219c054dd09a81a94823df00843d9e97f42419c92015ce3a64 - languageName: node - linkType: hard - "espree@npm:^7.3.0, espree@npm:^7.3.1": version: 7.3.1 resolution: "espree@npm:7.3.1" @@ -4498,27 +4372,6 @@ __metadata: languageName: node linkType: hard -"extend@npm:~3.0.2": - version: 3.0.2 - resolution: "extend@npm:3.0.2" - checksum: a50a8309ca65ea5d426382ff09f33586527882cf532931cb08ca786ea3146c0553310bda688710ff61d7668eba9f96b923fe1420cdf56a2c3eaf30fcab87b515 - languageName: node - linkType: hard - -"extsprintf@npm:1.3.0": - version: 1.3.0 - resolution: "extsprintf@npm:1.3.0" - checksum: cee7a4a1e34cffeeec18559109de92c27517e5641991ec6bab849aa64e3081022903dd53084f2080d0d2530803aa5ee84f1e9de642c365452f9e67be8f958ce2 - languageName: node - linkType: hard - -"extsprintf@npm:^1.2.0": - version: 1.4.1 - resolution: "extsprintf@npm:1.4.1" - checksum: a2f29b241914a8d2bad64363de684821b6b1609d06ae68d5b539e4de6b28659715b5bea94a7265201603713b7027d35399d10b0548f09071c5513e65e8323d33 - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -4585,13 +4438,13 @@ __metadata: languageName: node linkType: hard -"fetch-blob@npm:^2.1.1": - version: 2.1.2 - resolution: "fetch-blob@npm:2.1.2" - peerDependenciesMeta: - domexception: - optional: true - checksum: 22d4487ce78ea4e52b432b0057d8d42922d5d93c0374b0bc2692cebdcb11bf8fac4f6d141b31f1633db1e9212effd38385adbd765a2c7412a621307058499214 +"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4": + version: 3.1.5 + resolution: "fetch-blob@npm:3.1.5" + dependencies: + node-domexception: ^1.0.0 + web-streams-polyfill: ^3.0.3 + checksum: 6493f21bfe196798343431d20c0284835202728d076dd2cbf502a2846679f9265f3b0c3a7224750ae1a770b925da09e592b05fe7c3a22ca27794a39a0039ab21 languageName: node linkType: hard @@ -4643,9 +4496,9 @@ __metadata: linkType: hard "flatted@npm:^3.1.0": - version: 3.2.5 - resolution: "flatted@npm:3.2.5" - checksum: 3c436e9695ccca29620b4be5671dd72e5dd0a7500e0856611b7ca9bd8169f177f408c3b9abfa78dfe1493ee2d873e2c119080a8a9bee4e1a186a9e60ca6c89f1 + version: 3.2.6 + resolution: "flatted@npm:3.2.6" + checksum: 33b87aa88dfa40ca6ee31d7df61712bbbad3d3c05c132c23e59b9b61d34631b337a18ff2b8dc5553acdc871ec72b741e485f78969cf006124a3f57174de29a0e languageName: node linkType: hard @@ -4658,13 +4511,6 @@ __metadata: languageName: node linkType: hard -"forever-agent@npm:~0.6.1": - version: 0.6.1 - resolution: "forever-agent@npm:0.6.1" - checksum: 766ae6e220f5fe23676bb4c6a99387cec5b7b62ceb99e10923376e27bfea72f3c3aeec2ba5f45f3f7ba65d6616965aa7c20b15002b6860833bb6e394dea546a8 - languageName: node - linkType: hard - "form-data@npm:^3.0.0": version: 3.0.1 resolution: "form-data@npm:3.0.1" @@ -4676,14 +4522,12 @@ __metadata: languageName: node linkType: hard -"form-data@npm:~2.3.2": - version: 2.3.3 - resolution: "form-data@npm:2.3.3" +"formdata-polyfill@npm:^4.0.10": + version: 4.0.10 + resolution: "formdata-polyfill@npm:4.0.10" dependencies: - asynckit: ^0.4.0 - combined-stream: ^1.0.6 - mime-types: ^2.1.12 - checksum: 10c1780fa13dbe1ff3100114c2ce1f9307f8be10b14bf16e103815356ff567b6be39d70fc4a40f8990b9660012dc24b0f5e1dde1b6426166eb23a445ba068ca3 + fetch-blob: ^3.1.2 + checksum: 82a34df292afadd82b43d4a740ce387bc08541e0a534358425193017bf9fb3567875dc5f69564984b1da979979b70703aa73dee715a17b6c229752ae736dd9db languageName: node linkType: hard @@ -4797,13 +4641,13 @@ __metadata: linkType: hard "get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1": - version: 1.1.1 - resolution: "get-intrinsic@npm:1.1.1" + version: 1.1.2 + resolution: "get-intrinsic@npm:1.1.2" dependencies: function-bind: ^1.1.1 has: ^1.0.3 - has-symbols: ^1.0.1 - checksum: a9fe2ca8fa3f07f9b0d30fb202bcd01f3d9b9b6b732452e79c48e79f7d6d8d003af3f9e38514250e3553fdc83c61650851cb6870832ac89deaaceb08e3721a17 + has-symbols: ^1.0.3 + checksum: 252f45491f2ba88ebf5b38018020c7cc3279de54b1d67ffb70c0cdf1dfa8ab31cd56467b5d117a8b4275b7a4dde91f86766b163a17a850f036528a7b2faafb2b languageName: node linkType: hard @@ -4814,7 +4658,7 @@ __metadata: languageName: node linkType: hard -"get-stdin@npm:7.0.0, get-stdin@npm:^7.0.0": +"get-stdin@npm:7.0.0": version: 7.0.0 resolution: "get-stdin@npm:7.0.0" checksum: a24ab2cf8ee35bf5d3460c0d8145f2624715d864485789b7101a7cf1b6c1ce0a57319e25304872074121fa60e7104f1af3583a7014e9974c84c61d0702beae24 @@ -4845,19 +4689,10 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.0.0": - version: 4.0.3 - resolution: "get-tsconfig@npm:4.0.3" - checksum: b55e3289dd58862ef15b4f47c6ede1ab46fc8149f6c1aa093bde27c7c89646b78067f8d442e7571b48c76b6745084f0ed78547d12e2b015c49b7816002cdf970 - languageName: node - linkType: hard - -"getpass@npm:^0.1.1": - version: 0.1.7 - resolution: "getpass@npm:0.1.7" - dependencies: - assert-plus: ^1.0.0 - checksum: ab18d55661db264e3eac6012c2d3daeafaab7a501c035ae0ccb193c3c23e9849c6e29b6ac762b9c2adae460266f925d55a3a2a3a3c8b94be2f222df94d70c046 +"get-tsconfig@npm:^4.1.0": + version: 4.1.0 + resolution: "get-tsconfig@npm:4.1.0" + checksum: a1a29cdf53609a1e9e111bf863ea209494c03e425964ed2603e3a2657ed1d38213d4a8e3efbfd945f2ec908fe99b76d3ee87422fac5d8ec4fdd858bbb502efbf languageName: node linkType: hard @@ -4892,7 +4727,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.2.0": +"glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -4906,7 +4741,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.0.1": +"glob@npm:^8.0.1, glob@npm:^8.0.3": version: 8.0.3 resolution: "glob@npm:8.0.3" dependencies: @@ -4965,23 +4800,6 @@ __metadata: languageName: node linkType: hard -"har-schema@npm:^2.0.0": - version: 2.0.0 - resolution: "har-schema@npm:2.0.0" - checksum: d8946348f333fb09e2bf24cc4c67eabb47c8e1d1aa1c14184c7ffec1140a49ec8aa78aa93677ae452d71d5fc0fdeec20f0c8c1237291fc2bcb3f502a5d204f9b - languageName: node - linkType: hard - -"har-validator@npm:~5.1.3": - version: 5.1.5 - resolution: "har-validator@npm:5.1.5" - dependencies: - ajv: ^6.12.3 - har-schema: ^2.0.0 - checksum: b998a7269ca560d7f219eedc53e2c664cd87d487e428ae854a6af4573fc94f182fe9d2e3b92ab968249baec7ebaf9ead69cf975c931dc2ab282ec182ee988280 - languageName: node - linkType: hard - "hard-rejection@npm:^2.1.0": version: 2.1.0 resolution: "hard-rejection@npm:2.1.0" @@ -5144,17 +4962,6 @@ __metadata: languageName: node linkType: hard -"http-signature@npm:~1.2.0": - version: 1.2.0 - resolution: "http-signature@npm:1.2.0" - dependencies: - assert-plus: ^1.0.0 - jsprim: ^1.2.2 - sshpk: ^1.7.0 - checksum: 3324598712266a9683585bb84a75dec4fd550567d5e0dd4a0fff6ff3f74348793404d3eeac4918fa0902c810eeee1a86419e4a2e92a164132dfe6b26743fb47c - languageName: node - linkType: hard - "https-proxy-agent@npm:^5.0.0": version: 5.0.1 resolution: "https-proxy-agent@npm:5.0.1" @@ -5371,7 +5178,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.5.0, is-core-module@npm:^2.8.1": +"is-core-module@npm:^2.5.0, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": version: 2.9.0 resolution: "is-core-module@npm:2.9.0" dependencies: @@ -5561,7 +5368,7 @@ __metadata: languageName: node linkType: hard -"is-typedarray@npm:^1.0.0, is-typedarray@npm:~1.0.0": +"is-typedarray@npm:^1.0.0": version: 1.0.0 resolution: "is-typedarray@npm:1.0.0" checksum: 3508c6cd0a9ee2e0df2fa2e9baabcdc89e911c7bd5cf64604586697212feec525aa21050e48affb5ffc3df20f0f5d2e2cf79b08caa64e1ccc9578e251763aef7 @@ -5591,13 +5398,6 @@ __metadata: languageName: node linkType: hard -"isstream@npm:~0.1.2": - version: 0.1.2 - resolution: "isstream@npm:0.1.2" - checksum: 1eb2fe63a729f7bdd8a559ab552c69055f4f48eb5c2f03724430587c6f450783c8f1cd936c1c952d0a927925180fcc892ebd5b174236cf1065d4bd5bdb37e963 - languageName: node - linkType: hard - "istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": version: 3.2.0 resolution: "istanbul-lib-coverage@npm:3.2.0" @@ -6168,13 +5968,6 @@ __metadata: languageName: node linkType: hard -"jsbn@npm:~0.1.0": - version: 0.1.1 - resolution: "jsbn@npm:0.1.1" - checksum: e5ff29c1b8d965017ef3f9c219dacd6e40ad355c664e277d31246c90545a02e6047018c16c60a00f36d561b3647215c41894f5d869ada6908a2e0ce4200c88f2 - languageName: node - linkType: hard - "jsdoc-type-pratt-parser@npm:~2.2.3": version: 2.2.5 resolution: "jsdoc-type-pratt-parser@npm:2.2.5" @@ -6252,13 +6045,6 @@ __metadata: languageName: node linkType: hard -"json-schema@npm:0.4.0": - version: 0.4.0 - resolution: "json-schema@npm:0.4.0" - checksum: 66389434c3469e698da0df2e7ac5a3281bcff75e797a5c127db7c5b56270e01ae13d9afa3c03344f76e32e81678337a8c912bdbb75101c62e487dc3778461d72 - languageName: node - linkType: hard - "json-stable-stringify-without-jsonify@npm:^1.0.1": version: 1.0.1 resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" @@ -6266,7 +6052,7 @@ __metadata: languageName: node linkType: hard -"json-stringify-safe@npm:^5.0.1, json-stringify-safe@npm:~5.0.1": +"json-stringify-safe@npm:^5.0.1": version: 5.0.1 resolution: "json-stringify-safe@npm:5.0.1" checksum: 48ec0adad5280b8a96bb93f4563aa1667fd7a36334f79149abd42446d0989f2ddc58274b479f4819f1f00617957e6344c886c55d05a4e15ebb4ab931e4a6a8ee @@ -6312,54 +6098,26 @@ __metadata: languageName: node linkType: hard -"jsonld-signatures@npm:^5.0.0": - version: 5.2.0 - resolution: "jsonld-signatures@npm:5.2.0" +"jsonld-signatures@npm:^10.0.0": + version: 10.0.0 + resolution: "jsonld-signatures@npm:10.0.0" dependencies: - base64url: ^3.0.1 - crypto-ld: ^3.7.0 - jsonld: ^2.0.2 - node-forge: ^0.10.0 - security-context: ^4.0.0 - serialize-error: ^5.0.0 - checksum: 642370e1375fc3c4e33f9678294828737465163b29141273de64bb3785d28927367805ebfd8ca3097338924d315c9126055e06a0311d45301f214f7aaaefdb83 - languageName: node - linkType: hard - -"jsonld-signatures@npm:^9.0.0": - version: 9.3.1 - resolution: "jsonld-signatures@npm:9.3.1" - dependencies: - jsonld: ^5.0.0 + jsonld: ^6.0.0 security-context: ^4.0.0 serialize-error: ^8.0.1 - checksum: 60f8ef3e2927b614c5beb4532b546c6561fecc52e4cfe7420793538975e4e7a2d527151206e727dd4e5056e9a919512c17eb0b5101565290d4c455f9ac685c6d - languageName: node - linkType: hard - -"jsonld@npm:^2.0.2": - version: 2.0.2 - resolution: "jsonld@npm:2.0.2" - dependencies: - canonicalize: ^1.0.1 - lru-cache: ^5.1.1 - rdf-canonize: ^1.0.2 - request: ^2.88.0 - semver: ^6.3.0 - xmldom: 0.1.19 - checksum: 2aa30e6d624dfdd0bb2152b02f95ff240059cb6b9c92e3948e9e464a0cbf414fcd0df635298f56ff05e00a76f6de3d1da814d7e45cde213a13a5998e67510333 + checksum: 9e19a1bcbb8982594e35fc9ffae9b64da1de203f95d823861b0ba41f8f826b7e88770e0206fb62606d3cf1eaa59ef03ffbac657dabf537971e4a5eceb868d8a7 languageName: node linkType: hard -"jsonld@npm:^5.0.0": - version: 5.2.0 - resolution: "jsonld@npm:5.2.0" +"jsonld@npm:^6.0.0": + version: 6.0.0 + resolution: "jsonld@npm:6.0.0" dependencies: - "@digitalbazaar/http-client": ^1.1.0 + "@digitalbazaar/http-client": ^3.2.0 canonicalize: ^1.0.1 lru-cache: ^6.0.0 rdf-canonize: ^3.0.0 - checksum: 059e87a38115d108a45ab4f73ea97e607f4203aa37a11ef627039b6b3f683d84b73a6c8c04d480c6c243c3e2a951be0b3ea4f028a69f934f3c768b5b8cbdca99 + checksum: b062cecc01ed1c68ada8e3179532c4f514c49427781c41bd19f34a0d52fb758c13eb3b2ada548558630e4c5ac3b697f8dbe64499a6f214912684cbf5bf68aea8 languageName: node linkType: hard @@ -6370,18 +6128,6 @@ __metadata: languageName: node linkType: hard -"jsprim@npm:^1.2.2": - version: 1.4.2 - resolution: "jsprim@npm:1.4.2" - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - checksum: 2ad1b9fdcccae8b3d580fa6ced25de930eaa1ad154db21bbf8478a4d30bbbec7925b5f5ff29b933fba9412b16a17bd484a8da4fdb3663b5e27af95dd693bab2a - languageName: node - linkType: hard - "kind-of@npm:^6.0.2, kind-of@npm:^6.0.3": version: 6.0.3 resolution: "kind-of@npm:6.0.3" @@ -6396,26 +6142,26 @@ __metadata: languageName: node linkType: hard -"ky-universal@npm:^0.8.2": - version: 0.8.2 - resolution: "ky-universal@npm:0.8.2" +"ky-universal@npm:^0.10.1": + version: 0.10.1 + resolution: "ky-universal@npm:0.10.1" dependencies: abort-controller: ^3.0.0 - node-fetch: 3.0.0-beta.9 + node-fetch: ^3.2.2 peerDependencies: - ky: ">=0.17.0" - web-streams-polyfill: ">=2.0.0" + ky: ">=0.26.0" + web-streams-polyfill: ">=3.0.1" peerDependenciesMeta: web-streams-polyfill: optional: true - checksum: 87ed38c5c5a5b4448502fd5a64b68f30db69d366e148e5321cd9c0cb57d616519578ff0ae50146ff92ad037ef5cd77fbc40d893675459eead0d3f13101374570 + checksum: 61459a8bf62a9c3d2f3efe7893b9a621b21a68208acae6fb7f571d64a57be802d713a1cd147928e734b82539ffab23c12c8cffd6e5b2fa550c22e9d7510035b1 languageName: node linkType: hard -"ky@npm:^0.25.1": - version: 0.25.1 - resolution: "ky@npm:0.25.1" - checksum: ae1b7bebb48001d00d53e386e077939eeef7398a36b4fb45660f988ddb17d583d077290f2adb9706b4761f9d3b74918eb8d9f45ce799760143e104e1053b33ef +"ky@npm:^0.30.0": + version: 0.30.0 + resolution: "ky@npm:0.30.0" + checksum: d6ec6461e18cd2e4abb809b0574ff704c2e17bd61248843471c2492dd9486dfeadd4d139a5a6ec194b0175f9bc7b8c634685880d1ac646553a9f440c0982e8d3 languageName: node linkType: hard @@ -6493,13 +6239,6 @@ __metadata: languageName: node linkType: hard -"lodash.sortby@npm:^4.7.0": - version: 4.7.0 - resolution: "lodash.sortby@npm:4.7.0" - checksum: db170c9396d29d11fe9a9f25668c4993e0c1331bcb941ddbd48fb76f492e732add7f2a47cfdf8e9d740fa59ac41bbfaf931d268bc72aab3ab49e9f89354d718c - languageName: node - linkType: hard - "lodash.truncate@npm:^4.4.2": version: 4.4.2 resolution: "lodash.truncate@npm:4.4.2" @@ -6514,15 +6253,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^5.1.1": - version: 5.1.1 - resolution: "lru-cache@npm:5.1.1" - dependencies: - yallist: ^3.0.2 - checksum: c154ae1cbb0c2206d1501a0e94df349653c92c8cbb25236d7e85190bcaf4567a03ac6eb43166fabfa36fd35623694da7233e88d9601fbf411a9a481d85dbd2cb - languageName: node - linkType: hard - "lru-cache@npm:^6.0.0": version: 6.0.0 resolution: "lru-cache@npm:6.0.0" @@ -6533,9 +6263,9 @@ __metadata: linkType: hard "lru-cache@npm:^7.7.1": - version: 7.10.1 - resolution: "lru-cache@npm:7.10.1" - checksum: e8b190d71ed0fcd7b29c71a3e9b01f851c92d1ef8865ff06b5581ca991db1e5e006920ed4da8b56da1910664ed51abfd76c46fb55e82ac252ff6c970ff910d72 + version: 7.12.0 + resolution: "lru-cache@npm:7.12.0" + checksum: fdb62262978393df7a4bd46a072bc5c3808c50ca5a347a82bb9459410efd841b7bae50655c3cf9004c70d12c756cf6d018f6bff155a16cdde9eba9a82899b5eb languageName: node linkType: hard @@ -6563,8 +6293,8 @@ __metadata: linkType: hard "make-fetch-happen@npm:^10.0.3": - version: 10.1.5 - resolution: "make-fetch-happen@npm:10.1.5" + version: 10.1.8 + resolution: "make-fetch-happen@npm:10.1.8" dependencies: agentkeepalive: ^4.2.1 cacache: ^16.1.0 @@ -6580,9 +6310,9 @@ __metadata: minipass-pipeline: ^1.2.4 negotiator: ^0.6.3 promise-retry: ^2.0.1 - socks-proxy-agent: ^6.1.1 + socks-proxy-agent: ^7.0.0 ssri: ^9.0.0 - checksum: b0b42a1ccdcbc3180749727a52cf6887d9df6218d8ca35101bb9f7ab35729dd166d99203b70149a19a818d1ba72de40b982002ddb0b308c548457f5725d6e7f6 + checksum: 5fe9fd9da5368a8a4fe9a3ea5b9aa15f1e91c9ab703cd9027a6b33840ecc8a57c182fbe1c767c139330a88c46a448b1f00da5e32065cec373aff2450b3da54ee languageName: node linkType: hard @@ -6609,12 +6339,12 @@ __metadata: languageName: node linkType: hard -"marked@npm:^4.0.12": - version: 4.0.16 - resolution: "marked@npm:4.0.16" +"marked@npm:^4.0.16": + version: 4.0.17 + resolution: "marked@npm:4.0.17" bin: marked: bin/marked.js - checksum: c0ef780bf56c9bb49c15b66683e5648410c924c1d725f1489fc3c7dc3bd01194c50d720052bb0282ad7907f472dfdc8fa278acbc7903c5db3be4b83487e0d684 + checksum: 33a3c43a20b47bddaf045a59bfc7c3d41cc321931cc663ed231ca3b5b3b195fb2ac2973e687c2afd65b79539c14619baa07d19793f70130160f0af80c06d9b3a languageName: node linkType: hard @@ -6691,7 +6421,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:~2.1.19": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -6737,7 +6467,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^5.0.1": +"minimatch@npm:^5.0.1, minimatch@npm:^5.1.0": version: 5.1.0 resolution: "minimatch@npm:5.1.0" dependencies: @@ -6816,11 +6546,11 @@ __metadata: linkType: hard "minipass@npm:^3.0.0, minipass@npm:^3.1.1, minipass@npm:^3.1.6": - version: 3.1.6 - resolution: "minipass@npm:3.1.6" + version: 3.3.4 + resolution: "minipass@npm:3.3.4" dependencies: yallist: ^4.0.0 - checksum: 57a04041413a3531a65062452cb5175f93383ef245d6f4a2961d34386eb9aa8ac11ac7f16f791f5e8bbaf1dfb1ef01596870c88e8822215db57aa591a5bb0a77 + checksum: 5d95a7738c54852ba78d484141e850c792e062666a2d0c681a5ac1021275beb7e1acb077e59f9523ff1defb80901aea4e30fac10ded9a20a25d819a42916ef1b languageName: node linkType: hard @@ -6878,13 +6608,6 @@ __metadata: languageName: node linkType: hard -"multiformats@npm:^9.4.7, multiformats@npm:^9.5.4": - version: 9.6.5 - resolution: "multiformats@npm:9.6.5" - checksum: f4fce459bf19e1c38e4daa0e6de3aeea55ab000620d23ef599943495ab65d1c0351c5aa53d15eb365181d30a4b0629785a0d8901d17b5d153c48f4f1a683cd47 - languageName: node - linkType: hard - "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -6913,25 +6636,22 @@ __metadata: languageName: node linkType: hard -"nock@npm:^13.2.6": - version: 13.2.7 - resolution: "nock@npm:13.2.7" +"nock@npm:^13.2.8": + version: 13.2.8 + resolution: "nock@npm:13.2.8" dependencies: debug: ^4.1.0 json-stringify-safe: ^5.0.1 lodash: ^4.17.21 propagate: ^2.0.0 - checksum: 0d7d3163ca973393d43a0334aafe59677ca6e7eea133338166be9bd06e577667da2dd2d5148046022b9e9dd4339f5ae5d0ef0274abc1462c4e896f8729c24b40 + checksum: 656f696d3c1b6267b8ec366f5cc464306d2aa308ce9b41414e9992eea5b0b71e475a582945b936e16263961c3a0f9e1c388a3a36da53c1e300398a7826550f96 languageName: node linkType: hard -"node-fetch@npm:3.0.0-beta.9": - version: 3.0.0-beta.9 - resolution: "node-fetch@npm:3.0.0-beta.9" - dependencies: - data-uri-to-buffer: ^3.0.1 - fetch-blob: ^2.1.1 - checksum: 586af0910649cb62f1c044ddac41e71c0b0f48133fba406ad5e0fab51baff18f22cd187ea65ef690ceed7386a71910e904348105dc8eae55f907fa94df7e76ca +"node-domexception@npm:^1.0.0": + version: 1.0.0 + resolution: "node-domexception@npm:1.0.0" + checksum: ee1d37dd2a4eb26a8a92cd6b64dfc29caec72bff5e1ed9aba80c294f57a31ba4895a60fd48347cf17dd6e766da0ae87d75657dfd1f384ebfa60462c2283f5c7f languageName: node linkType: hard @@ -6949,21 +6669,25 @@ __metadata: languageName: node linkType: hard -"node-forge@npm:^0.10.0, node-forge@npm:~0.10.0": - version: 0.10.0 - resolution: "node-forge@npm:0.10.0" - checksum: 5aa6dc9922e424a20ef101d2f517418e2bc9cfc0255dd22e0701c0fad1568445f510ee67f6f3fcdf085812c4ca1b847b8ba45683b34776828e41f5c1794e42e1 +"node-fetch@npm:^3.2.2": + version: 3.2.6 + resolution: "node-fetch@npm:3.2.6" + dependencies: + data-uri-to-buffer: ^4.0.0 + fetch-blob: ^3.1.4 + formdata-polyfill: ^4.0.10 + checksum: ece307ace3a3ff28638ccb0fa0545bb5c0cfd673a9d06fc314d937a73ae6a55917d5bacd7f080f9a9f1449ca20a5c01b1281d0e616acb20315e5ac315971da46 languageName: node linkType: hard "node-gyp-build@npm:^4.3.0": - version: 4.4.0 - resolution: "node-gyp-build@npm:4.4.0" + version: 4.5.0 + resolution: "node-gyp-build@npm:4.5.0" bin: node-gyp-build: bin.js node-gyp-build-optional: optional.js node-gyp-build-test: build-test.js - checksum: 972a059f960253d254e0b23ce10f54c8982236fc0edcab85166d0b7f87443b2ce98391c877cfb2f6eeafcf03c538c5f4dd3e0bfff03828eb48634f58f4c64343 + checksum: d888bae0fb88335f69af1b57a2294a931c5042f36e413d8d364c992c9ebfa0b96ffe773179a5a2c8f04b73856e8634e09cce108dbb9804396d3cc8c5455ff2db languageName: node linkType: hard @@ -6994,10 +6718,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.3": - version: 2.0.4 - resolution: "node-releases@npm:2.0.4" - checksum: b32d6c2032c7b169ae3938b416fc50f123f5bd577d54a79b2ae201febf27b22846b01c803dd35ac8689afe840f8ba4e5f7154723db629b80f359836b6707b92f +"node-releases@npm:^2.0.5": + version: 2.0.5 + resolution: "node-releases@npm:2.0.5" + checksum: e85d949addd19f8827f32569d2be5751e7812ccf6cc47879d49f79b5234ff4982225e39a3929315f96370823b070640fb04d79fc0ddec8b515a969a03493a42f languageName: node linkType: hard @@ -7065,23 +6789,16 @@ __metadata: linkType: hard "nwsapi@npm:^2.2.0": - version: 2.2.0 - resolution: "nwsapi@npm:2.2.0" - checksum: 5ef4a9bc0c1a5b7f2e014aa6a4b359a257503b796618ed1ef0eb852098f77e772305bb0e92856e4bbfa3e6c75da48c0113505c76f144555ff38867229c2400a7 - languageName: node - linkType: hard - -"oauth-sign@npm:~0.9.0": - version: 0.9.0 - resolution: "oauth-sign@npm:0.9.0" - checksum: 8f5497a127967866a3c67094c21efd295e46013a94e6e828573c62220e9af568cc1d2d04b16865ba583e430510fa168baf821ea78f355146d8ed7e350fc44c64 + version: 2.2.1 + resolution: "nwsapi@npm:2.2.1" + checksum: 6c21fcb6950538012516b39137ed9b53ed56843e521362e977282c781169f229e7bca8ec6e207165b19912550f360806b222f77b6c9202bb8d66818456875c3d languageName: node linkType: hard "object-inspect@npm:^1.12.0, object-inspect@npm:^1.9.0": - version: 1.12.0 - resolution: "object-inspect@npm:1.12.0" - checksum: 2b36d4001a9c921c6b342e2965734519c9c58c355822243c3207fbf0aac271f8d44d30d2d570d450b2cc6f0f00b72bcdba515c37827d2560e5f22b1899a31cf4 + version: 1.12.2 + resolution: "object-inspect@npm:1.12.2" + checksum: a534fc1b8534284ed71f25ce3a496013b7ea030f3d1b77118f6b7b1713829262be9e6243acbcb3ef8c626e2b64186112cb7f6db74e37b2789b9c789ca23048b2 languageName: node linkType: hard @@ -7334,13 +7051,6 @@ __metadata: languageName: node linkType: hard -"performance-now@npm:^2.1.0": - version: 2.1.0 - resolution: "performance-now@npm:2.1.0" - checksum: 534e641aa8f7cba160f0afec0599b6cecefbb516a2e837b512be0adbe6c1da5550e89c78059c7fabc5c9ffdf6627edabe23eb7c518c4500067a898fa65c2b550 - languageName: node - linkType: hard - "picocolors@npm:^1.0.0": version: 1.0.0 resolution: "picocolors@npm:1.0.0" @@ -7395,11 +7105,11 @@ __metadata: linkType: hard "prettier@npm:^2.4.1": - version: 2.6.2 - resolution: "prettier@npm:2.6.2" + version: 2.7.1 + resolution: "prettier@npm:2.7.1" bin: prettier: bin-prettier.js - checksum: 48d08dde8e9fb1f5bccdd205baa7f192e9fc8bc98f86e1b97d919de804e28c806b0e6cc685e4a88211aa7987fa9668f30baae19580d87ced3ed0f2ec6572106f + checksum: 55a4409182260866ab31284d929b3cb961e5fdb91fe0d2e099dac92eaecec890f36e524b4c19e6ceae839c99c6d7195817579cdffc8e2c80da0cb794463a748b languageName: node linkType: hard @@ -7462,7 +7172,7 @@ __metadata: languageName: node linkType: hard -"psl@npm:^1.1.28, psl@npm:^1.1.33": +"psl@npm:^1.1.33": version: 1.8.0 resolution: "psl@npm:1.8.0" checksum: 6150048ed2da3f919478bee8a82f3828303bc0fc730fb015a48f83c9977682c7b28c60ab01425a72d82a2891a1681627aa530a991d50c086b48a3be27744bde7 @@ -7504,13 +7214,6 @@ __metadata: languageName: node linkType: hard -"qs@npm:~6.5.2": - version: 6.5.3 - resolution: "qs@npm:6.5.3" - checksum: 6f20bf08cabd90c458e50855559539a28d00b2f2e7dddcb66082b16a43188418cb3cb77cbd09268bcef6022935650f0534357b8af9eeb29bf0f27ccb17655692 - languageName: node - linkType: hard - "querystring@npm:0.2.0": version: 0.2.0 resolution: "querystring@npm:0.2.0" @@ -7551,16 +7254,6 @@ __metadata: languageName: node linkType: hard -"rdf-canonize@npm:^1.0.2": - version: 1.2.0 - resolution: "rdf-canonize@npm:1.2.0" - dependencies: - node-forge: ^0.10.0 - semver: ^6.3.0 - checksum: 4b704f83ba77f09edfa3c77ad804069ba56ded49e3a91871dfaa0456e0b04e9129fab5a99eb758edf44b25bee0e2c91c27bfc6b91d715e8d96b42296efefbe97 - languageName: node - linkType: hard - "rdf-canonize@npm:^3.0.0": version: 3.0.0 resolution: "rdf-canonize@npm:3.0.0" @@ -7662,34 +7355,6 @@ __metadata: languageName: node linkType: hard -"request@npm:^2.88.0": - version: 2.88.2 - resolution: "request@npm:2.88.2" - dependencies: - aws-sign2: ~0.7.0 - aws4: ^1.8.0 - caseless: ~0.12.0 - combined-stream: ~1.0.6 - extend: ~3.0.2 - forever-agent: ~0.6.1 - form-data: ~2.3.2 - har-validator: ~5.1.3 - http-signature: ~1.2.0 - is-typedarray: ~1.0.0 - isstream: ~0.1.2 - json-stringify-safe: ~5.0.1 - mime-types: ~2.1.19 - oauth-sign: ~0.9.0 - performance-now: ^2.1.0 - qs: ~6.5.2 - safe-buffer: ^5.1.2 - tough-cookie: ~2.5.0 - tunnel-agent: ^0.6.0 - uuid: ^3.3.2 - checksum: 4e112c087f6eabe7327869da2417e9d28fcd0910419edd2eb17b6acfc4bfa1dad61954525949c228705805882d8a98a86a0ea12d7f739c01ee92af7062996983 - languageName: node - linkType: hard - "require-directory@npm:^2.1.1": version: 2.1.1 resolution: "require-directory@npm:2.1.1" @@ -7758,28 +7423,28 @@ __metadata: linkType: hard "resolve@npm:^1.10.0, resolve@npm:^1.10.1, resolve@npm:^1.20.0, resolve@npm:^1.22.0, resolve@npm:^1.9.0": - version: 1.22.0 - resolution: "resolve@npm:1.22.0" + version: 1.22.1 + resolution: "resolve@npm:1.22.1" dependencies: - is-core-module: ^2.8.1 + is-core-module: ^2.9.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: a2d14cc437b3a23996f8c7367eee5c7cf8149c586b07ca2ae00e96581ce59455555a1190be9aa92154785cf9f2042646c200d0e00e0bbd2b8a995a93a0ed3e4e + checksum: 07af5fc1e81aa1d866cbc9e9460fbb67318a10fa3c4deadc35c3ad8a898ee9a71a86a65e4755ac3195e0ea0cfbe201eb323ebe655ce90526fd61917313a34e4e languageName: node linkType: hard "resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.10.1#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin, resolve@patch:resolve@^1.9.0#~builtin": - version: 1.22.0 - resolution: "resolve@patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b" + version: 1.22.1 + resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=07638b" dependencies: - is-core-module: ^2.8.1 + is-core-module: ^2.9.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: c79ecaea36c872ee4a79e3db0d3d4160b593f2ca16e031d8283735acd01715a203607e9ded3f91f68899c2937fa0d49390cddbe0fb2852629212f3cda283f4a7 + checksum: 5656f4d0bedcf8eb52685c1abdf8fbe73a1603bb1160a24d716e27a57f6cecbe2432ff9c89c2bd57542c3a7b9d14b1882b73bfe2e9d7849c9a4c0b8b39f02b8b languageName: node linkType: hard @@ -7824,9 +7489,7 @@ __metadata: dependencies: "@commitlint/cli": ^9.0.1 "@commitlint/config-conventional": ^9.0.1 - "@multiformats/blake2": ^1.0.5 "@types/jest": ^27.4.0 - "@types/node": ^17.0.35 "@typescript-eslint/eslint-plugin": ^5.7.0 "@typescript-eslint/parser": ^5.7.0 eslint: ^7.32.0 @@ -7843,7 +7506,6 @@ __metadata: jest-runner: ^27.4.6 jest-runner-groups: ^2.1.0 moment: ^2.29.1 - multiformats: ^9.4.7 prettier: ^2.4.1 rimraf: ^3.0.2 ts-jest: ^27.1.2 @@ -7851,7 +7513,6 @@ __metadata: tsx: ^3.4.3 typedoc: ^0.22.7 typescript: ^4.5.4 - wait-for-enter: ^1.0.0 languageName: unknown linkType: soft @@ -7887,7 +7548,7 @@ __metadata: languageName: node linkType: hard -"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.0.2, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0": +"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.1.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 @@ -7950,7 +7611,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.0.0, semver@npm:^6.1.0, semver@npm:^6.2.0, semver@npm:^6.3.0": +"semver@npm:^6.0.0, semver@npm:^6.1.0, semver@npm:^6.3.0": version: 6.3.0 resolution: "semver@npm:6.3.0" bin: @@ -7959,15 +7620,6 @@ __metadata: languageName: node linkType: hard -"serialize-error@npm:^5.0.0": - version: 5.0.0 - resolution: "serialize-error@npm:5.0.0" - dependencies: - type-fest: ^0.8.0 - checksum: d298700c4e5350ff812f69fb2024f6e9110b48d8d9e50af1f6c7516446de75bb25ceaa29548ab67165f0c9bf265347c5271f7f1766b0732a0c1582315bf305f0 - languageName: node - linkType: hard - "serialize-error@npm:^8.0.1": version: 8.1.0 resolution: "serialize-error@npm:8.1.0" @@ -8098,14 +7750,14 @@ __metadata: languageName: node linkType: hard -"socks-proxy-agent@npm:^6.1.1": - version: 6.2.0 - resolution: "socks-proxy-agent@npm:6.2.0" +"socks-proxy-agent@npm:^7.0.0": + version: 7.0.0 + resolution: "socks-proxy-agent@npm:7.0.0" dependencies: agent-base: ^6.0.2 debug: ^4.3.3 socks: ^2.6.2 - checksum: 6723fd64fb50334e2b340fd0a80fd8488ffc5bc43d85b7cf1d25612044f814dd7d6ea417fd47602159941236f7f4bd15669fa5d7e1f852598a31288e1a43967b + checksum: 720554370154cbc979e2e9ce6a6ec6ced205d02757d8f5d93fe95adae454fc187a5cbfc6b022afab850a5ce9b4c7d73e0f98e381879cf45f66317a4895953846 languageName: node linkType: hard @@ -8119,16 +7771,6 @@ __metadata: languageName: node linkType: hard -"sodium-native@npm:^3.2.0": - version: 3.3.0 - resolution: "sodium-native@npm:3.3.0" - dependencies: - node-gyp: latest - node-gyp-build: ^4.3.0 - checksum: 4412bc90155261e2006c979788d3b33e3bdba1c41669c7054a876b8731a68886e1450b356791abd2c4e7b217d21f50adfdc1e194d8909dd003223195bd8ddc0a - languageName: node - linkType: hard - "source-map-support@npm:^0.5.21, source-map-support@npm:^0.5.6, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" @@ -8154,18 +7796,9 @@ __metadata: linkType: hard "source-map@npm:^0.7.3": - version: 0.7.3 - resolution: "source-map@npm:0.7.3" - checksum: cd24efb3b8fa69b64bf28e3c1b1a500de77e84260c5b7f2b873f88284df17974157cc88d386ee9b6d081f08fdd8242f3fc05c953685a6ad81aad94c7393dedea - languageName: node - linkType: hard - -"source-map@npm:~0.8.0-beta.0": - version: 0.8.0-beta.0 - resolution: "source-map@npm:0.8.0-beta.0" - dependencies: - whatwg-url: ^7.0.0 - checksum: e94169be6461ab0ac0913313ad1719a14c60d402bd22b0ad96f4a6cffd79130d91ab5df0a5336a326b04d2df131c1409f563c9dc0d21a6ca6239a44b6c8dbd92 + version: 0.7.4 + resolution: "source-map@npm:0.7.4" + checksum: 01cc5a74b1f0e1d626a58d36ad6898ea820567e87f18dfc9d24a9843a351aaa2ec09b87422589906d6ff1deed29693e176194dc88bcae7c9a852dc74b311dbf5 languageName: node linkType: hard @@ -8219,27 +7852,6 @@ __metadata: languageName: node linkType: hard -"sshpk@npm:^1.7.0": - version: 1.17.0 - resolution: "sshpk@npm:1.17.0" - dependencies: - asn1: ~0.2.3 - assert-plus: ^1.0.0 - bcrypt-pbkdf: ^1.0.0 - dashdash: ^1.12.0 - ecc-jsbn: ~0.1.1 - getpass: ^0.1.1 - jsbn: ~0.1.0 - safer-buffer: ^2.0.2 - tweetnacl: ~0.14.0 - bin: - sshpk-conv: bin/sshpk-conv - sshpk-sign: bin/sshpk-sign - sshpk-verify: bin/sshpk-verify - checksum: ba109f65c8e6c35133b8e6ed5576abeff8aa8d614824b7275ec3ca308f081fef483607c28d97780c1e235818b0f93ed8c8b56d0a5968d5a23fd6af57718c7597 - languageName: node - linkType: hard - "ssri@npm:^9.0.0": version: 9.0.1 resolution: "ssri@npm:9.0.1" @@ -8275,9 +7887,9 @@ __metadata: linkType: hard "stackframe@npm:^1.0.2": - version: 1.2.1 - resolution: "stackframe@npm:1.2.1" - checksum: 1a3f281014bb1d2178b7c2ab26d657fb0f83c21d7d34ab33d858fd0b652a035254619fce8601278a2cf22ddb3382af21c4ea29b429806da75f3077fbd5e5bf17 + version: 1.3.4 + resolution: "stackframe@npm:1.3.4" + checksum: bae1596873595c4610993fa84f86a3387d67586401c1816ea048c0196800c0646c4d2da98c2ee80557fd9eff05877efe33b91ba6cd052658ed96ddc85d19067d languageName: node linkType: hard @@ -8506,13 +8118,13 @@ __metadata: linkType: hard "terser-webpack-plugin@npm:^5.1.1, terser-webpack-plugin@npm:^5.1.3": - version: 5.3.1 - resolution: "terser-webpack-plugin@npm:5.3.1" + version: 5.3.3 + resolution: "terser-webpack-plugin@npm:5.3.3" dependencies: + "@jridgewell/trace-mapping": ^0.3.7 jest-worker: ^27.4.5 schema-utils: ^3.1.1 serialize-javascript: ^6.0.0 - source-map: ^0.6.1 terser: ^5.7.2 peerDependencies: webpack: ^5.1.0 @@ -8523,21 +8135,21 @@ __metadata: optional: true uglify-js: optional: true - checksum: 1b808fd4f58ce0b532baacc50b9a850fc69ce0077a0e9e5076d4156c52fab3d40b02d5d9148a3eba64630cf7f40057de54f6a5a87fac1849b1f11d6bfdb42072 + checksum: 4b8d508d8a0f6e604addb286975f1fa670f8c3964a67abc03a7cfcfd4cdeca4b07dda6655e1c4425427fb62e4d2b0ca59d84f1b2cd83262ff73616d5d3ccdeb5 languageName: node linkType: hard "terser@npm:^5.7.2": - version: 5.13.1 - resolution: "terser@npm:5.13.1" + version: 5.14.1 + resolution: "terser@npm:5.14.1" dependencies: + "@jridgewell/source-map": ^0.3.2 acorn: ^8.5.0 commander: ^2.20.0 - source-map: ~0.8.0-beta.0 source-map-support: ~0.5.20 bin: terser: bin/terser - checksum: 0b1f5043cf5c3973005fe2ae4ff3be82511c336a6430599dacd4e2acf77c974d4474b0f1eec4823977c1f33823147e736ff712ca8e098bee3db25946480fa29d + checksum: 7b0e51f3d193a11cad82f07e3b0c1d62122eec786f809bdf2a54b865aaa1450872c3a7b6c33b5a40e264834060ffc1d4e197f971a76da5b0137997d756eb7548 languageName: node linkType: hard @@ -8623,25 +8235,6 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:~2.5.0": - version: 2.5.0 - resolution: "tough-cookie@npm:2.5.0" - dependencies: - psl: ^1.1.28 - punycode: ^2.1.1 - checksum: 16a8cd090224dd176eee23837cbe7573ca0fa297d7e468ab5e1c02d49a4e9a97bb05fef11320605eac516f91d54c57838a25864e8680e27b069a5231d8264977 - languageName: node - linkType: hard - -"tr46@npm:^1.0.1": - version: 1.0.1 - resolution: "tr46@npm:1.0.1" - dependencies: - punycode: ^2.1.0 - checksum: 96d4ed46bc161db75dbf9247a236ea0bfcaf5758baae6749e92afab0bc5a09cb59af21788ede7e55080f2bf02dce3e4a8f2a484cc45164e29f4b5e68f7cbcc1a - languageName: node - linkType: hard - "tr46@npm:^2.1.0": version: 2.1.0 resolution: "tr46@npm:2.1.0" @@ -8745,28 +8338,19 @@ __metadata: linkType: hard "tsx@npm:^3.4.3": - version: 3.4.3 - resolution: "tsx@npm:3.4.3" + version: 3.7.1 + resolution: "tsx@npm:3.7.1" dependencies: - "@esbuild-kit/cjs-loader": ^2.1.0 - "@esbuild-kit/core-utils": ^1.3.1 - "@esbuild-kit/esm-loader": ^2.2.0 + "@esbuild-kit/cjs-loader": ^2.3.0 + "@esbuild-kit/core-utils": ^2.0.2 + "@esbuild-kit/esm-loader": ^2.4.0 fsevents: ~2.3.2 dependenciesMeta: fsevents: optional: true bin: tsx: dist/cli.js - checksum: f471eb7e3ca68183d90192e7e81ddd3cc4872608fe6ce6d04652531461aedb2c50cbc57f2a72cb55b5f25c20ae91444a399f46181c4475639956bcab5fdaac2e - languageName: node - linkType: hard - -"tunnel-agent@npm:^0.6.0": - version: 0.6.0 - resolution: "tunnel-agent@npm:0.6.0" - dependencies: - safe-buffer: ^5.0.1 - checksum: 05f6510358f8afc62a057b8b692f05d70c1782b70db86d6a1e0d5e28a32389e52fa6e7707b6c5ecccacc031462e4bc35af85ecfe4bbc341767917b7cf6965711 + checksum: 0f9ab83033d759e0b2147237683cf156d23c76a8ecb059df716dfb2a224d404dbbf62b9c394d226310f7f07e8247829c4af042afa600b6191da9e758ebf5af40 languageName: node linkType: hard @@ -8777,13 +8361,6 @@ __metadata: languageName: node linkType: hard -"tweetnacl@npm:^0.14.3, tweetnacl@npm:~0.14.0": - version: 0.14.5 - resolution: "tweetnacl@npm:0.14.5" - checksum: 6061daba1724f59473d99a7bb82e13f211cdf6e31315510ae9656fefd4779851cb927adad90f3b488c8ed77c106adc0421ea8055f6f976ff21b27c5c4e918487 - languageName: node - linkType: hard - "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -8837,7 +8414,7 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.8.0, type-fest@npm:^0.8.1": +"type-fest@npm:^0.8.1": version: 0.8.1 resolution: "type-fest@npm:0.8.1" checksum: d61c4b2eba24009033ae4500d7d818a94fd6d1b481a8111612ee141400d5f1db46f199c014766b9fa9b31a6a7374d96fc748c6d688a78a3ce5a33123839becb7 @@ -8868,19 +8445,19 @@ __metadata: linkType: hard "typedoc@npm:^0.22.7": - version: 0.22.15 - resolution: "typedoc@npm:0.22.15" + version: 0.22.18 + resolution: "typedoc@npm:0.22.18" dependencies: - glob: ^7.2.0 + glob: ^8.0.3 lunr: ^2.3.9 - marked: ^4.0.12 - minimatch: ^5.0.1 + marked: ^4.0.16 + minimatch: ^5.1.0 shiki: ^0.10.1 peerDependencies: - typescript: 4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x + typescript: 4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x bin: typedoc: bin/typedoc - checksum: 3f5f1cb9288bf811f42df59750c7062a026a23257b38dfe227515a30007a28e3d8139187949fcd19300fd6b2ef76bcdc4cf54549100bff3e000e61bb19958fb2 + checksum: b813d8129682f6ed5a4e96bacaf019e4da1d2744ca89fef850d6bb4c034616567ce67e6a7f5cfc5f00aac573f0b45d44b1427aafa262ab88dce6b460cb9e744c languageName: node linkType: hard @@ -8904,12 +8481,12 @@ __metadata: linkType: hard "typescript@npm:^4.5.4": - version: 4.6.4 - resolution: "typescript@npm:4.6.4" + version: 4.7.4 + resolution: "typescript@npm:4.7.4" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: e7bfcc39cd4571a63a54e5ea21f16b8445268b9900bf55aee0e02ad981be576acc140eba24f1af5e3c1457767c96cea6d12861768fb386cf3ffb34013718631a + checksum: 5750181b1cd7e6482c4195825547e70f944114fb47e58e4aa7553e62f11b3f3173766aef9c281783edfd881f7b8299cf35e3ca8caebe73d8464528c907a164df languageName: node linkType: hard @@ -8924,12 +8501,12 @@ __metadata: linkType: hard "typescript@patch:typescript@^4.5.4#~builtin": - version: 4.6.4 - resolution: "typescript@patch:typescript@npm%3A4.6.4#~builtin::version=4.6.4&hash=7ad353" + version: 4.7.4 + resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin::version=4.7.4&hash=7ad353" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 1cb434fbc637d347be90e3a0c6cd05e33c38f941713c8786d3031faf1842c2c148ba91d2fac01e7276b0ae3249b8633f1660e32686cc7a8c6a8fd5361dc52c66 + checksum: 9096d8f6c16cb80ef3bf96fcbbd055bf1c4a43bd14f3b7be45a9fbe7ada46ec977f604d5feed3263b4f2aa7d4c7477ce5f9cd87de0d6feedec69a983f3a4f93e languageName: node linkType: hard @@ -8945,6 +8522,13 @@ __metadata: languageName: node linkType: hard +"undici@npm:^5.2.0": + version: 5.6.0 + resolution: "undici@npm:5.6.0" + checksum: b9052c2cb9c44b000d375468c266b629032fc72d2024fb07b2988fd42d54937bedb54f44e76bb0ee6ca4c4960c0eee0e77573d178c156647da7ebaa088174baf + languageName: node + linkType: hard + "unique-filename@npm:^1.1.1": version: 1.1.1 resolution: "unique-filename@npm:1.1.1" @@ -8970,6 +8554,20 @@ __metadata: languageName: node linkType: hard +"update-browserslist-db@npm:^1.0.4": + version: 1.0.4 + resolution: "update-browserslist-db@npm:1.0.4" + dependencies: + escalade: ^3.1.1 + picocolors: ^1.0.0 + peerDependencies: + browserslist: ">= 4.21.0" + bin: + browserslist-lint: cli.js + checksum: 7c7da28d0fc733b17e01c8fa9385ab909eadce64b8ea644e9603867dc368c2e2a6611af8247e72612b23f9e7cb87ac7c7585a05ff94e1759e9d646cbe9bf49a7 + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -9020,15 +8618,6 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^3.3.2": - version: 3.4.0 - resolution: "uuid@npm:3.4.0" - bin: - uuid: ./bin/uuid - checksum: 58de2feed61c59060b40f8203c0e4ed7fd6f99d42534a499f1741218a1dd0c129f4aa1de797bcf822c8ea5da7e4137aa3673431a96dae729047f7aca7b27866f - languageName: node - linkType: hard - "uuid@npm:^8.1.0": version: 8.3.2 resolution: "uuid@npm:8.3.2" @@ -9066,35 +8655,6 @@ __metadata: languageName: node linkType: hard -"vc-js@npm:^0.6.4": - version: 0.6.4 - resolution: "vc-js@npm:0.6.4" - dependencies: - commander: ^2.20.3 - credentials-context: ^1.0.0 - debug: ^4.1.1 - fs-extra: ^8.1.0 - get-stdin: ^7.0.0 - jsonld: ^2.0.2 - jsonld-signatures: ^5.0.0 - supports-color: ^7.1.0 - bin: - vc-js: bin/vc-js - checksum: 3242fcae63e4829794f25ecc4787c97c229cd7a287b2d38a7c4cbf3ee87d79528d18921c4e0abbd1f0cc1ab2106988d3ba2c5124bb85ed3c927c12d06b056071 - languageName: node - linkType: hard - -"verror@npm:1.10.0": - version: 1.10.0 - resolution: "verror@npm:1.10.0" - dependencies: - assert-plus: ^1.0.0 - core-util-is: 1.0.2 - extsprintf: ^1.2.0 - checksum: c431df0bedf2088b227a4e051e0ff4ca54df2c114096b0c01e1cbaadb021c30a04d7dd5b41ab277bcd51246ca135bf931d4c4c796ecae7a4fef6d744ecef36ea - languageName: node - linkType: hard - "vscode-oniguruma@npm:^1.6.1": version: 1.6.2 resolution: "vscode-oniguruma@npm:1.6.2" @@ -9127,13 +8687,6 @@ __metadata: languageName: node linkType: hard -"wait-for-enter@npm:^1.0.0": - version: 1.0.0 - resolution: "wait-for-enter@npm:1.0.0" - checksum: 1e12977a6abe5d8d8e4d523f9f4daafde4f8fc43468e280c9d83ca430606d3b02871d78d2d1255c6899a104bd62c1ae38fae5bd5c11093f1c4bd0de1ffee79cb - languageName: node - linkType: hard - "walker@npm:^1.0.7": version: 1.0.8 resolution: "walker@npm:1.0.8" @@ -9144,12 +8697,19 @@ __metadata: linkType: hard "watchpack@npm:^2.3.1": - version: 2.3.1 - resolution: "watchpack@npm:2.3.1" + version: 2.4.0 + resolution: "watchpack@npm:2.4.0" dependencies: glob-to-regexp: ^0.4.1 graceful-fs: ^4.1.2 - checksum: 70a34f92842d94b5d842980f866d568d7a467de667c96ae5759c759f46587e49265863171f4650bdbafc5f3870a28f2b4453e9e847098ec4b718b38926d47d22 + checksum: 23d4bc58634dbe13b86093e01c6a68d8096028b664ab7139d58f0c37d962d549a940e98f2f201cecdabd6f9c340338dc73ef8bf094a2249ef582f35183d1a131 + languageName: node + linkType: hard + +"web-streams-polyfill@npm:^3.0.3": + version: 3.2.1 + resolution: "web-streams-polyfill@npm:3.2.1" + checksum: b119c78574b6d65935e35098c2afdcd752b84268e18746606af149e3c424e15621b6f1ff0b42b2676dc012fc4f0d313f964b41a4b5031e525faa03997457da02 languageName: node linkType: hard @@ -9160,13 +8720,6 @@ __metadata: languageName: node linkType: hard -"webidl-conversions@npm:^4.0.2": - version: 4.0.2 - resolution: "webidl-conversions@npm:4.0.2" - checksum: c93d8dfe908a0140a4ae9c0ebc87a33805b416a33ee638a605b551523eec94a9632165e54632f6d57a39c5f948c4bab10e0e066525e9a4b87a79f0d04fbca374 - languageName: node - linkType: hard - "webidl-conversions@npm:^5.0.0": version: 5.0.0 resolution: "webidl-conversions@npm:5.0.0" @@ -9181,17 +8734,17 @@ __metadata: languageName: node linkType: hard -"webpack-cli@npm:^4.5.0": - version: 4.9.2 - resolution: "webpack-cli@npm:4.9.2" +"webpack-cli@npm:^4.9.2": + version: 4.10.0 + resolution: "webpack-cli@npm:4.10.0" dependencies: "@discoveryjs/json-ext": ^0.5.0 - "@webpack-cli/configtest": ^1.1.1 - "@webpack-cli/info": ^1.4.1 - "@webpack-cli/serve": ^1.6.1 + "@webpack-cli/configtest": ^1.2.0 + "@webpack-cli/info": ^1.5.0 + "@webpack-cli/serve": ^1.7.0 colorette: ^2.0.14 commander: ^7.0.0 - execa: ^5.0.0 + cross-spawn: ^7.0.3 fastest-levenshtein: ^1.0.12 import-local: ^3.0.2 interpret: ^2.2.0 @@ -9210,7 +8763,7 @@ __metadata: optional: true bin: webpack-cli: bin/cli.js - checksum: ffb4c5d53ab65ce9f1e8efd34fca4cb858ec6afc91ece0d9375094edff2e7615708c8a586991057fd9cc8d37aab0eb0511913b178daac534e51bcf7d3583e61c + checksum: 2ff5355ac348e6b40f2630a203b981728834dca96d6d621be96249764b2d0fc01dd54edfcc37f02214d02935de2cf0eefd6ce689d970d154ef493f01ba922390 languageName: node linkType: hard @@ -9231,9 +8784,9 @@ __metadata: languageName: node linkType: hard -"webpack@npm:^5.27.0": - version: 5.72.1 - resolution: "webpack@npm:5.72.1" +"webpack@npm:^5.70.0": + version: 5.73.0 + resolution: "webpack@npm:5.73.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^0.0.51 @@ -9264,7 +8817,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: d1eff085eee1c67a68f7bf1d077ea202c1e68a0de0e0866274984769838c3f224fbc64e847e1a1bbc6eba9fb6a9965098809cc0be9292b573767bb5d8d2df96e + checksum: aa434a241bad6176b68e1bf0feb1972da4dcbf27cb3d94ae24f6eb31acc37dceb9c4aae55e068edca75817bfe91f13cd20b023ac55d9b1b2f8b66a4037c9468f languageName: node linkType: hard @@ -9308,17 +8861,6 @@ __metadata: languageName: node linkType: hard -"whatwg-url@npm:^7.0.0": - version: 7.1.0 - resolution: "whatwg-url@npm:7.1.0" - dependencies: - lodash.sortby: ^4.7.0 - tr46: ^1.0.1 - webidl-conversions: ^4.0.2 - checksum: fecb07c87290b47d2ec2fb6d6ca26daad3c9e211e0e531dd7566e7ff95b5b3525a57d4f32640ad4adf057717e0c215731db842ad761e61d947e81010e05cf5fd - languageName: node - linkType: hard - "whatwg-url@npm:^8.0.0, whatwg-url@npm:^8.5.0": version: 8.7.0 resolution: "whatwg-url@npm:8.7.0" @@ -9440,8 +8982,8 @@ __metadata: linkType: hard "ws@npm:^7.4.6": - version: 7.5.7 - resolution: "ws@npm:7.5.7" + version: 7.5.8 + resolution: "ws@npm:7.5.8" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ^5.0.2 @@ -9450,7 +8992,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 5c1f669a166fb57560b4e07f201375137fa31d9186afde78b1508926345ce546332f109081574ddc4e38cc474c5406b5fc71c18d71eb75f6e2d2245576976cba + checksum: 49479ccf3ddab6500c5906fbcc316e9c8cd44b0ffb3903a6c1caf9b38cb9e06691685722a4c642cfa7d4c6eb390424fc3142cd4f8b940cfc7a9ce9761b1cd65b languageName: node linkType: hard @@ -9468,13 +9010,6 @@ __metadata: languageName: node linkType: hard -"xmldom@npm:0.1.19": - version: 0.1.19 - resolution: "xmldom@npm:0.1.19" - checksum: e7dca2a3e2b33b4c968e8efe3e1609ea6c2b7d73b618ebc23b8dfbde3cad35e03007c72b7887a029d336fb3645a425638db0826d66798cd1a87440c839964285 - languageName: node - linkType: hard - "y18n@npm:^4.0.0": version: 4.0.3 resolution: "y18n@npm:4.0.3" @@ -9496,13 +9031,6 @@ __metadata: languageName: node linkType: hard -"yallist@npm:^3.0.2": - version: 3.1.1 - resolution: "yallist@npm:3.1.1" - checksum: 48f7bb00dc19fc635a13a39fe547f527b10c9290e7b3e836b9a8f1ca04d4d342e85714416b3c2ab74949c9c66f9cebb0473e6bc353b79035356103b47641285d - languageName: node - linkType: hard - "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0" From ad5dd3f951966b5004272cd76b83f93c3c76fccb Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Mon, 4 Jul 2022 12:57:12 +0530 Subject: [PATCH 8/8] change the version to 0.7.4-0 Signed-off-by: Amar Tumballi --- .gitignore | 2 +- package.json | 2 +- packages/config/package.json | 2 +- packages/messaging/package.json | 2 +- packages/modules/package.json | 2 +- packages/network/package.json | 2 +- packages/sdk/package.json | 2 +- packages/types/package.json | 2 +- packages/utils/package.json | 2 +- packages/vc-export/package.json | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 2ce0c4ac..523da6e3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,7 @@ yarn-error.log* !.yarn/sdks .yarn/versions .pnp.* - +.yarnrc.yml # testing coverage diff --git a/package.json b/package.json index c5c4dd6b..727113a5 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,6 @@ "typedoc": "^0.22.7", "typescript": "^4.5.4" }, - "version": "0.7.3-0", + "version": "0.7.4-0", "packageManager": "yarn@3.2.1" } diff --git a/packages/config/package.json b/packages/config/package.json index 29b186e2..f8e30f25 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,6 +1,6 @@ { "name": "@cord.network/config", - "version": "0.7.3-0", + "version": "0.7.4-0", "description": "", "main": "./lib/cjs/index.js", "module": "./lib/esm/index.js", diff --git a/packages/messaging/package.json b/packages/messaging/package.json index 77305a71..c4c6ca52 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -1,6 +1,6 @@ { "name": "@cord.network/messaging", - "version": "0.7.3-0", + "version": "0.7.4-0", "description": "", "main": "./lib/cjs/index.js", "module": "./lib/esm/index.js", diff --git a/packages/modules/package.json b/packages/modules/package.json index e28f9a0e..dc0a791f 100644 --- a/packages/modules/package.json +++ b/packages/modules/package.json @@ -1,6 +1,6 @@ { "name": "@cord.network/modules", - "version": "0.7.3-0", + "version": "0.7.4-0", "description": "Core Modules", "main": "./lib/cjs/index.js", "module": "./lib/esm/index.js", diff --git a/packages/network/package.json b/packages/network/package.json index 34624ecf..62d6c748 100644 --- a/packages/network/package.json +++ b/packages/network/package.json @@ -1,6 +1,6 @@ { "name": "@cord.network/network", - "version": "0.7.3-0", + "version": "0.7.4-0", "description": "", "main": "./lib/index.js", "module": "./lib/esm/index.js", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index ad74676b..96986eb6 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@cord.network/sdk", - "version": "0.7.3-0", + "version": "0.7.4-0", "description": "", "main": "./lib/cjs/index.js", "module": "./lib/esm/index.js", diff --git a/packages/types/package.json b/packages/types/package.json index 33fc11a1..bb68ad31 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@cord.network/types", - "version": "0.7.3-0", + "version": "0.7.4-0", "description": "", "main": "./lib/cjs/index.js", "module": "./lib/esm/index.js", diff --git a/packages/utils/package.json b/packages/utils/package.json index 300ae468..e3274b0c 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@cord.network/utils", - "version": "0.7.3-0", + "version": "0.7.4-0", "description": "", "main": "./lib/cjs/index.js", "module": "./lib/esm/index.js", diff --git a/packages/vc-export/package.json b/packages/vc-export/package.json index 361f6958..ecdd59a8 100644 --- a/packages/vc-export/package.json +++ b/packages/vc-export/package.json @@ -1,6 +1,6 @@ { "name": "@cord.network/vc-export", - "version": "0.7.3-0", + "version": "0.7.4-0", "description": "Verifiable Credentials", "main": "./lib/cjs/index.js", "module": "./lib/esm/index.js",