diff --git a/CHANGELOG.md b/CHANGELOG.md index 88d15efe..87d37f0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # @digitalbazaar/vc ChangeLog +## 6.1.0 - 2023-11-dd + +### Added +- Add `derive()` API for deriving new verifiable credentials from + existing ones, for the purpose of selective disclosure or + unlinkable presentation. + ## 6.0.2 - 2023-08-04 ### Fixed diff --git a/lib/index.js b/lib/index.js index b223917c..e47b6378 100644 --- a/lib/index.js +++ b/lib/index.js @@ -42,7 +42,7 @@ export const defaultDocumentLoader = jsigs.extendContextLoader(_documentLoader); import * as credentialsContext from 'credentials-context'; -const {AuthenticationProofPurpose} = jsigs.purposes; +const {AssertionProofPurpose, AuthenticationProofPurpose} = jsigs.purposes; const {constants: {CREDENTIALS_CONTEXT_V1_URL}} = credentialsContext; export {CredentialIssuancePurpose}; @@ -99,7 +99,7 @@ export const dateRegex = new RegExp('^(\\d{4})-(0[1-9]|1[0-2])-' + * * @param {object} options.credential - Base credential document. * @param {LinkedDataSignature} options.suite - Signature suite (with private - * key material), passed in to sign(). + * key material or an API to use it), passed in to sign(). * * @param {ProofPurpose} [options.purpose] - A ProofPurpose. If not specified, * a default purpose will be created. @@ -144,6 +144,45 @@ export async function issue({ return jsigs.sign(credential, {purpose, documentLoader, suite}); } +/** + * Derives a proof from the given verifiable credential, resulting in a new + * verifiable credential. This method is usually used to generate selective + * disclosure and / or unlinkable proofs. + * + * @param {object} [options={}] - The options to use. + * + * @param {object} options.verifiableCredential - The verifiable credential + * containing a base proof to derive another proof from. + * @param {LinkedDataSignature} options.suite - Derived proof signature suite. + * + * Other optional params passed to `derive()`: + * @param {object} [options.documentLoader] - A document loader. + * + * @throws {Error} If missing required properties. + * + * @returns {Promise} Resolves on completion. + */ +export async function derive({ + verifiableCredential, suite, + documentLoader = defaultDocumentLoader +} = {}) { + if(!verifiableCredential) { + throw new TypeError('"credential" parameter is required for deriving.'); + } + if(!suite) { + throw new TypeError('"suite" parameter is required for deriving.'); + } + + // run common credential checks + _checkCredential({credential: verifiableCredential, mode: 'issue'}); + + return jsigs.derive(verifiableCredential, { + purpose: AssertionProofPurpose, + documentLoader, + suite + }); +} + /** * Verifies a verifiable presentation: * - Checks that the presentation is well-formed