{"id":13565563,"url":"https://github.com/digitalbazaar/vc","last_synced_at":"2025-05-15T09:06:58.380Z","repository":{"id":38007798,"uuid":"108181615","full_name":"digitalbazaar/vc","owner":"digitalbazaar","description":"W3C Verifiable Credentials implementation in JavaScript","archived":false,"fork":false,"pushed_at":"2025-04-15T01:25:24.000Z","size":405,"stargazers_count":200,"open_issues_count":28,"forks_count":52,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-05-11T22:46:21.850Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/digitalbazaar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-10-24T20:45:37.000Z","updated_at":"2025-04-21T15:39:32.000Z","dependencies_parsed_at":"2024-01-02T18:48:07.319Z","dependency_job_id":"2f49ad2b-7b21-44c4-9966-13da44a60e19","html_url":"https://github.com/digitalbazaar/vc","commit_stats":{"total_commits":517,"total_committers":17,"mean_commits":30.41176470588235,"dds":0.678916827852998,"last_synced_commit":"545a4eba6e2678a65c5e9060475e2045542c2d5e"},"previous_names":["digitalbazaar/vc-js"],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fvc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fvc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fvc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fvc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalbazaar","download_url":"https://codeload.github.com/digitalbazaar/vc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253645495,"owners_count":21941316,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:01:50.215Z","updated_at":"2025-05-15T09:06:58.354Z","avatar_url":"https://github.com/digitalbazaar.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Verifiable Credentials JS Library _(@digitalbazaar/vc)_\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/digitalbazaar/vc/main.yml)](https://github.com/digitalbazaar/vc/actions/workflow/main.yml)\n[![NPM Version](https://img.shields.io/npm/v/@digitalbazaar/vc.svg)](https://npm.im/@digitalbazaar/vc)\n\n\u003e A Javascript library for issuing and verifying Verifiable Credentials.\n\n## Table of Contents\n\n- [Security](#security)\n- [Background](#background)\n- [Install](#install)\n- [Usage](#usage)\n- [Testing](#testing)\n- [Contribute](#contribute)\n- [Commercial Support](#commercial-support)\n- [License](#license)\n\n## Security\n\nAs with most security- and cryptography-related tools, the overall security of\nyour system will largely depend on your design decisions (which key types\nyou will use, where you'll store the private keys, what you put into your\ncredentials, and so on.)\n\n## Background\n\nThis library is a Javascript (Node.js and browser) implementation of the\n[Verifiable Credentials Data Model 1.0](https://w3c.github.io/vc-data-model/)\nspecification (the JWT serialization is not currently supported).\n\nIt allows you to perform the following basic operations:\n\n1. Signing (issuing) a Verifiable Credential (VC).\n2. Creating a Verifiable Presentation (VP), signed or unsigned\n3. Verifying a VP\n4. Verifying a standalone VC\n\n**Pre-requisites:** Usage of this library assumes you have the ability to do\nthe following:\n\n* [Generate LD key pairs and signature suites](BACKGROUND.md#generating-keys-and-suites)\n* Publish the corresponding public keys somewhere that is accessible to the\n  verifier.\n* Make sure your custom `@context`s, verification methods (such as public keys)\n  and their corresponding controller documents, and any other resolvable\n  objects, are reachable via a `documentLoader`.\n\n## Install\n\n- Browsers and Node.js 18+ are supported.\n\nTo install from NPM:\n\n```\nnpm install @digitalbazaar/vc\n```\n\nTo install locally (for development):\n\n```\ngit clone https://github.com/digitalbazaar/vc.git\ncd vc\nnpm install\n```\n\n## Usage\n\n### Setting up a signature suite\n\nFor signing, when setting up a signature suite, you will need to pass in\na key pair containing a private key.\n\n```js\nimport * as vc from '@digitalbazaar/vc';\n\n// Required to set up a suite instance with private key\nimport {Ed25519VerificationKey2020} from\n  '@digitalbazaar/ed25519-verification-key-2020';\nimport {Ed25519Signature2020} from '@digitalbazaar/ed25519-signature-2020';\n\nconst keyPair = await Ed25519VerificationKey2020.generate();\n\nconst suite = new Ed25519Signature2020({key: keyPair});\n```\n\n### Issuing a Verifiable Credential\n\nPre-requisites:\n\n* You have a private key (with id and controller) and corresponding suite\n* If you're using a custom `@context`, make sure it's resolvable\n* (Recommended) You have a strategy for where to publish your Controller\n  Document and Public Key\n\n```js\nimport * as vc from '@digitalbazaar/vc';\n\n// Sample unsigned credential\nconst credential = {\n  \"@context\": [\n    \"https://www.w3.org/2018/credentials/v1\",\n    \"https://www.w3.org/2018/credentials/examples/v1\"\n  ],\n  \"id\": \"https://example.com/credentials/1872\",\n  \"type\": [\"VerifiableCredential\", \"AlumniCredential\"],\n  \"issuer\": \"https://example.edu/issuers/565049\",\n  \"issuanceDate\": \"2010-01-01T19:23:24Z\",\n  \"credentialSubject\": {\n    \"id\": \"did:example:ebfeb1f712ebc6f1c276e12ec21\",\n    \"alumniOf\": \"Example University\"\n  }\n};\n\nconst signedVC = await vc.issue({credential, suite, documentLoader});\nconsole.log(JSON.stringify(signedVC, null, 2));\n```\n\n### Issuing a Selective Disclosure Verifiable Credential\n\nPre-requisites:\n\n* You have a private key (with id and controller) and corresponding suite\n* You have are using a cryptosuite that supports selective disclosure, such\n  as `ecdsa-sd-2023` or `bbs-2023`\n* If you're using a custom `@context`, make sure it's resolvable\n* (Recommended) You have a strategy for where to publish your Controller\n  Document and Public Key\n\nIssuing using `ecdsa-sd-2023`:\n\n```js\nimport * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey';\nimport * as ecdsaSd2023Cryptosuite from\n  '@digitalbazaar/ecdsa-sd-2023-cryptosuite';\nimport * as vc from '@digitalbazaar/vc';\nimport {DataIntegrityProof} from '@digitalbazaar/data-integrity';\n\nconst ecdsaKeyPair = await EcdsaMultikey.generate({\n  curve: 'P-256',\n  id: 'https://example.edu/issuers/keys/2',\n  controller: 'https://example.edu/issuers/565049'\n});\n\n// sample exported key pair\n/*\n{\n  \"@context\": \"https://w3id.org/security/multikey/v1\",\n  \"id\": \"https://example.edu/issuers/keys/2\",\n  \"type\": \"Multikey\",\n  \"controller\": \"https://example.edu/issuers/565049\",\n  \"publicKeyMultibase\": \"zDnaeWJjGpXnQAbEpRur3kSWFapGZbwGnFCkzyhiq7nDeXXrM\",\n  \"secretKeyMultibase\": \"z42trzSpncjWFaB9cKE2Gg5hxtbuAQa5mVJgGwjrugHMacdM\"\n}\n*/\n\n// sample unsigned credential\nconst credential = {\n  \"@context\": [\n    \"https://www.w3.org/2018/credentials/v1\",\n    \"https://www.w3.org/2018/credentials/examples/v1\"\n  ],\n  \"id\": \"https://example.com/credentials/1872\",\n  \"type\": [\"VerifiableCredential\", \"AlumniCredential\"],\n  \"issuer\": \"https://example.edu/issuers/565049\",\n  \"issuanceDate\": \"2010-01-01T19:23:24Z\",\n  \"credentialSubject\": {\n    \"id\": \"did:example:ebfeb1f712ebc6f1c276e12ec21\",\n    \"alumniOf\": \"Example University\"\n  }\n};\n\n// setup ecdsa-sd-2023 suite for signing selective disclosure VCs\nconst suite = new DataIntegrityProof({\n  signer: ecdsaKeyPair.signer(),\n  cryptosuite: createSignCryptosuite({\n    // require the `issuer` and `issuanceDate` fields to always be disclosed\n    // by the holder (presenter)\n    mandatoryPointers: [\n      '/issuanceDate',\n      '/issuer'\n    ]\n  })\n});\n// use a proof ID to enable it to be found and transformed into a disclosure\n// proof by the holder later\nconst proofId = `urn:uuid:${uuid()}`;\nsuite.proof = {id: proofId};\n\nconst signedVC = await vc.issue({credential, suite, documentLoader});\nconsole.log(JSON.stringify(signedVC, null, 2));\n```\n\nIssuing using `bbs-2023`:\n\n```js\nimport * as bbs2023Cryptosuite from '@digitalbazaar/bbs-2023-cryptosuite';\nimport * as bls12381Multikey from '@digitalbazaar/bls12-381-multikey';\nimport * as vc from '@digitalbazaar/vc';\nimport {DataIntegrityProof} from '@digitalbazaar/data-integrity';\n\nconst bbsKeyPair = await bls12381Multikey.generate({\n  algorithm: 'BBS-BLS12-381-SHA-256';\n  id: 'https://example.edu/issuers/keys/3',\n  controller: 'https://example.edu/issuers/565049'\n});\n\n// sample exported key pair\n/*\n{\n  \"@context\": \"https://w3id.org/security/multikey/v1\",\n  \"id\": \"https://example.edu/issuers/keys/3\",\n  \"type\": \"Multikey\",\n  \"controller\": \"https://example.edu/issuers/565049\",\n  \"publicKeyMultibase\": \"zUC72jQrt2BfyE57AVgHgThKCsH6HNo85X9SLNpAJaHb42cNDXhsRWL2KkrFtaiztPbbZjfDVQnQQMw2nMqAPUHnaQ3xEr7kUmcnBgv7S2wQSbRbr7mqsP153nU7yMh3ZN4ZryL\",\n  \"secretKeyMultibase\": \"z488y1niFCWnaV2i86q1raaa7qwBWZ6WTLeS1W1PrsbcsoNg\"\n}\n*/\n\n// sample unsigned credential\nconst credential = {\n  \"@context\": [\n    \"https://www.w3.org/2018/credentials/v1\",\n    \"https://www.w3.org/2018/credentials/examples/v1\"\n  ],\n  // omit `id` to enable unlinkable disclosure\n  \"type\": [\"VerifiableCredential\", \"AlumniCredential\"],\n  \"issuer\": \"https://example.edu/issuers/565049\",\n  // use less precise date that is shared by a sufficiently large group\n  // of VCs to enable unlinkable disclosure\n  \"issuanceDate\": \"2010-01-01T01:00:00Z\",\n  \"credentialSubject\": {\n    // omit `id` to enable unlinkable disclosure\n    \"alumniOf\": \"Example University\"\n  }\n};\n\n// setup bbs-2023 suite for signing unlinkable selective disclosure VCs\nconst suite = new DataIntegrityProof({\n  signer: bbsKeyPair.signer(),\n  cryptosuite: createSignCryptosuite({\n    // require the `issuer` and `issuanceDate` fields to always be disclosed\n    // by the holder (presenter)\n    mandatoryPointers: [\n      '/issuanceDate',\n      '/issuer'\n    ]\n  })\n});\n// note: do not include a proof ID to enable unlinkable selective disclosure\n\nconst signedVC = await vc.issue({credential, suite, documentLoader});\nconsole.log(JSON.stringify(signedVC, null, 2));\n```\n\n### Deriving a Selective Disclosure Verifiable Credential\n\nNote: This step is performed as a holder of a verifiable credential, not as\nan issuer.\n\nPre-requisites:\n\n* You have a verifiable credential that was issued using a cryptosuite that\n  supports selective disclosure, such as `ecdsa-sd-2023` or `bbs-2023`\n* If you're using a custom `@context`, make sure it's resolvable\n\nDeriving using `ecdsa-sd-2023`:\n\n```js\nimport * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey';\nimport * as ecdsaSd2023Cryptosuite from\n  '@digitalbazaar/ecdsa-sd-2023-cryptosuite';\nimport * as vc from '@digitalbazaar/vc';\nimport {DataIntegrityProof} from '@digitalbazaar/data-integrity';\n\nconst {\n  createDiscloseCryptosuite,\n  createSignCryptosuite,\n  createVerifyCryptosuite\n} = ecdsaSd2023Cryptosuite;\n\n// sample VC\nconst verifiableCredential = {\n  \"@context\": [\n    \"https://www.w3.org/2018/credentials/v1\",\n    \"https://www.w3.org/2018/credentials/examples/v1\",\n    \"https://w3id.org/security/data-integrity/v2\"\n  ],\n  \"id\": \"http://example.edu/credentials/1872\",\n  \"type\": [\n    \"VerifiableCredential\",\n    \"AlumniCredential\"\n  ],\n  \"issuer\": \"https://example.edu/issuers/565049\",\n  \"issuanceDate\": \"2010-01-01T19:23:24Z\",\n  \"credentialSubject\": {\n    \"id\": \"did:example:ebfeb1f712ebc6f1c276e12ec21\",\n    \"alumniOf\": \"\u003cspan lang=\\\"en\\\"\u003eExample University\u003c/span\u003e\"\n  },\n  \"proof\": {\n    \"id\": \"urn:uuid:318d9dce-bc7b-40b9-a956-c9160bf910db\",\n    \"type\": \"DataIntegrityProof\",\n    \"created\": \"2024-01-12T21:53:11Z\",\n    \"verificationMethod\": \"https://example.edu/issuers/keys/2\",\n    \"cryptosuite\": \"ecdsa-sd-2023\",\n    \"proofPurpose\": \"assertionMethod\",\n    \"proofValue\": \"u2V0AhVhAsl6PQKYE15R0O5Qd267ntwHGNH6JRvZ1y8A-fTCQLUoupP8SCZzzmyc0a1AnabHEVKhpHtYV8j9Kapp-fHFBtFgjgCQCIMn2L1R7D5VPnNn_2foxdj8qvsuUTGFqA34YBkguzCpYILfJ-qNQpn6_dJGpkG24FynqbHpnzoHWVJc2kiLqEKHRglhAUmZtstR9MOLrZjcR8J303MXFvRiE6J3bbaPT1_I9-6578-Wj-eydv2TEGBq_dmsjxsOh4_2Va0etw8CXXMAzaVhA9fr7_Sl9D67AfvLhkJTZ0uJCAXcbL2MaS-DmoC7K-ABxroL1_wj119J8yTMlazxzYBwYkihrdp4ZWJZxraX9tIJtL2lzc3VhbmNlRGF0ZWcvaXNzdWVy\"\n  }\n};\n\n// note no `signer` needed; the selective disclosure credential will be\n// derived from the base proof already provided by the issuer\nconst suite = new DataIntegrityProof({\n  cryptosuite: createDiscloseCryptosuite({\n    // the ID of the base proof to convert to a disclosure proof\n    proofId: 'urn:uuid:da088899-3439-41ea-a580-af3f1cf98cd3',\n    // selectively disclose the entire credential subject; different JSON\n    // pointers could be provided to selectively disclose different information;\n    // the issuer will have mandatory fields that will be automatically\n    // disclosed such as the `issuer` and `issuanceDate` fields\n    selectivePointers: [\n      '/credentialSubject'\n    ]\n  })\n});\n\nconst derivedVC = await vc.derive({\n  verifiableCredential, suite, documentLoader\n});\nconsole.log(JSON.stringify(derivedVC, null, 2));\n```\n\nDeriving using `bbs-2023`:\n\n```js\nimport * as bbs2023Cryptosuite from '@digitalbazaar/bbs-2023-cryptosuite';\nimport * as bls12381Multikey from '@digitalbazaar/bls12-381-multikey';\nimport * as vc from '@digitalbazaar/vc';\nimport {DataIntegrityProof} from '@digitalbazaar/data-integrity';\n\nconst {\n  createDiscloseCryptosuite,\n  createSignCryptosuite,\n  createVerifyCryptosuite\n} = bbs2023Cryptosuite;\n\n// sample VC\nconst verifiableCredential = {\n  \"@context\": [\n    \"https://www.w3.org/2018/credentials/v1\",\n    \"https://www.w3.org/2018/credentials/examples/v1\",\n    \"https://w3id.org/security/data-integrity/v2\"\n  ],\n  \"type\": [\n    \"VerifiableCredential\",\n    \"AlumniCredential\"\n  ],\n  \"issuer\": \"https://example.edu/issuers/565049\",\n  \"issuanceDate\": \"2010-01-01T01:00:00Z\",\n  \"credentialSubject\": {\n    \"alumniOf\": \"\u003cspan lang=\\\"en\\\"\u003eExample University\u003c/span\u003e\"\n  },\n  \"proof\": {\n    \"type\": \"DataIntegrityProof\",\n    \"verificationMethod\": \"https://example.edu/issuers/keys/3\",\n    \"cryptosuite\": \"bbs-2023\",\n    \"proofPurpose\": \"assertionMethod\",\n    \"proofValue\": \"u2V0ChVhQp1smqO-Qmc-1KpNkShjevTeylTdVlpH_RNXeJ_cNniErWPbEWILvsoH5mYjnun5ibZHq0m7BEIaLv8sfMtLfcmgPj6tbAFwDWvEcbRWg7CFYQGWqCAnvTpL_Aao3aVCg5svdzFuvKqnvneA0UwaN0lagvGpWT7fCDGgcYPyNPKaCX94Xo06aTcSwOXgyGUbtN1xYYIU6t5wv20lVdESfzkYOFXTxIZa1HSBAZYWDyEgQ3A3ajzWX5qeFc3cwmnnrGUfJYwawgGLQAY3vBi3LTM2i3jCOPvxCEJALPIjK4tEmWb6uFjT4PWLlIEeTtYj_0yEv91ggsm9vw1PPlK6q8wQiw2i2joZ-OKkvHz7rDSxPYfmQNrqCbS9pc3N1YW5jZURhdGVnL2lzc3Vlcg\"\n  }\n};\n\n// note no `signer` needed; the selective disclosure credential will be\n// derived from the base proof already provided by the issuer\nconst suite = new DataIntegrityProof({\n  cryptosuite: createDiscloseCryptosuite({\n    // selectively disclose the entire credential subject; different JSON\n    // pointers could be provided to selectively disclose different information;\n    // the issuer will have mandatory fields that will be automatically\n    // disclosed such as the `issuer` and `issuanceDate` fields\n    selectivePointers: [\n      '/credentialSubject'\n    ]\n  })\n});\n\nconst derivedVC = await vc.derive({\n  verifiableCredential, suite, documentLoader\n});\nconsole.log(JSON.stringify(derivedVC, null, 2));\n```\n\n### Creating a Verifiable Presentation\n\nPre-requisites:\n\n* You have the requisite private keys (with id and controller) and\n  corresponding suites\n* If you're using a custom `@context`, make sure it's resolvable\n* (Recommended) You have a strategy for where to publish your Controller\n  Documents and Public Keys\n\n#### Creating an unsigned presentation\n\nTo create a presentation out of one or more verifiable credentials, you can\nuse the `createPresentation()` convenience function. Alternatively, you can\ncreate the presentation object manually (don't forget to set the `@context` and\n`type` properties).\n\nTo create a verifiable presentation with a custom `@context` field use a\n[custom documentLoader](#custom-documentLoader)\n\n```js\nconst verifiableCredential = [vc1, vc2]; // either array or single object\n\n// optional `id` and `holder`\nconst id = 'ebc6f1c2';\nconst holder = 'did:ex:12345';\n\nconst presentation = vc.createPresentation({\n  verifiableCredential, id, holder\n});\n\nconsole.log(JSON.stringify(presentation, null, 2));\n// -\u003e\n{\n  \"@context\": [\n    \"https://www.w3.org/2018/credentials/v1\"\n  ],\n  \"type\": [\n    \"VerifiablePresentation\"\n  ],\n  \"id\": \"ebc6f1c2\",\n  \"holder\": \"did:ex:12345\",\n  \"verifiableCredential\": [\n    // vc1:\n    {\n      \"@context\": [\n        \"https://www.w3.org/2018/credentials/v1\",\n        \"https://www.w3.org/2018/credentials/examples/v1\"\n      ],\n      \"id\": \"http://example.edu/credentials/1872\",\n      \"type\": [\n        \"VerifiableCredential\",\n        \"AlumniCredential\"\n      ],\n      \"issuer\": \"https://example.edu/issuers/565049\",\n      \"issuanceDate\": \"2010-01-01T19:23:24Z\",\n      \"credentialSubject\": {\n        \"id\": \"did:example:ebfeb1f712ebc6f1c276e12ec21\",\n        \"alumniOf\": \"\u003cspan lang=\\\"en\\\"\u003eExample University\u003c/span\u003e\"\n      },\n      \"proof\": {\n        \"type\": \"Ed25519Signature2018\",\n        \"created\": \"2020-02-03T17:23:49Z\",\n        \"jws\": \"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..AUQ3AJ23WM5vMOWNtYKuqZBekRAOUibOMH9XuvOd39my1sO-X9R4QyAXLD2ospssLvIuwmQVhJa-F0xMOnkvBg\",\n        \"proofPurpose\": \"assertionMethod\",\n        \"verificationMethod\": \"https://example.edu/issuers/keys/1\"\n      }\n    },\n    // vc2 goes here ...\n  ]\n}\n```\n\nNote that this creates an _unsigned_ presentation (which may be valid\nfor some use cases).\n\n### Custom documentLoader\n\nPre-requisites:\n\n* You have an existing valid JSON-LD `@context`.\n* Your custom context is resolvable at an address.\n\n```js\n// jsonld-signatures has a secure context loader\n// by requiring this first you ensure security\n// contexts are loaded from jsonld-signatures\n// and not an insecure source.\nimport * as vc from '@digitalbazaar/vc';\nconst {extendContextLoader} = require('jsonld-signatures');\n// @digitalbazaar/vc exports its own secure documentLoader.\nconst {defaultDocumentLoader} = vc;\n// a valid json-ld @context.\nconst myCustomContext = require('./myCustomContext');\n\nconst documentLoader = extendContextLoader(async url =\u003e {\n  if(url === 'did:test:context:foo') {\n    return {\n      contextUrl: null,\n      documentUrl: url,\n      document: myCustomContext\n    };\n  }\n  return defaultDocumentLoader(url);\n});\n\n// you can now use your custom documentLoader\n// with multiple vc methods such as:\n\nconst vp = await vc.signPresentation({\n  presentation, suite, challenge, documentLoader\n});\n\n// or\nconst signedVC = await vc.issue({credential, suite, documentLoader});\n\n// or\nconst result = await vc.verifyCredential({credential: signedVC, suite, documentLoader});\n\n```\n\n#### Signing the Presentation\n\nOnce you've created the presentation (either via `createPresentation()` or\nmanually), you can sign it using `signPresentation()`:\n\n```js\nimport * as vc from '@digitalbazaar/vc';\n\nconst vp = await vc.signPresentation({\n  presentation, suite, challenge, documentLoader\n});\n\nconsole.log(JSON.stringify(vp, null, 2));\n// -\u003e\n{\n  \"@context\": [\n    \"https://www.w3.org/2018/credentials/v1\"\n  ],\n  \"type\": [\n    \"VerifiablePresentation\"\n  ],\n  \"verifiableCredential\": [\n    {\n      \"@context\": [\n        \"https://www.w3.org/2018/credentials/v1\",\n        \"https://www.w3.org/2018/credentials/examples/v1\"\n      ],\n      \"id\": \"http://example.edu/credentials/1872\",\n      \"type\": [\n        \"VerifiableCredential\",\n        \"AlumniCredential\"\n      ],\n      \"issuer\": \"https://example.edu/issuers/565049\",\n      \"issuanceDate\": \"2010-01-01T19:23:24Z\",\n      \"credentialSubject\": {\n        \"id\": \"did:example:ebfeb1f712ebc6f1c276e12ec21\",\n        \"alumniOf\": \"\u003cspan lang=\\\"en\\\"\u003eExample University\u003c/span\u003e\"\n      },\n      \"proof\": {\n        \"type\": \"Ed25519Signature2018\",\n        \"created\": \"2020-02-03T17:23:49Z\",\n        \"jws\": \"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..AUQ3AJ23WM5vMOWNtYKuqZBekRAOUibOMH9XuvOd39my1sO-X9R4QyAXLD2ospssLvIuwmQVhJa-F0xMOnkvBg\",\n        \"proofPurpose\": \"assertionMethod\",\n        \"verificationMethod\": \"https://example.edu/issuers/keys/1\"\n      }\n    }\n  ],\n  \"id\": \"ebc6f1c2\",\n  \"holder\": \"did:ex:holder123\",\n  \"proof\": {\n    \"type\": \"Ed25519Signature2018\",\n    \"created\": \"2019-02-03T17:23:49Z\",\n    \"challenge\": \"12ec21\",\n    \"jws\": \"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..ZO4Lkq8-fOruE4oUvuMaxepGX-vLD2gPyNIsz-iA7X0tzC3_96djaBYDxxl6wD1xKrx0h60NjI9i9p_MxoXkDQ\",\n    \"proofPurpose\": \"authentication\",\n    \"verificationMethod\": \"https://example.edu/issuers/keys/1\"\n  }\n}\n```\n\n### Verifying a Verifiable Presentation\n\nPre-requisites:\n\n* Your custom `@context`s, verification methods (like public keys) and their\n  corresponding controller documents are reachable via a `documentLoader`.\n\nTo verify a verifiable presentation:\n\n```js\nimport * as vc from '@digitalbazaar/vc';\n\n// challenge has been received from the requesting party - see 'challenge'\n// section below\n\nconst result = await vc.verify({presentation, challenge, suite, documentLoader});\n// {valid: true}\n```\n\nBy default, `verify()` will throw an error if the `proof` section is missing.\nTo verify an unsigned presentation, you must set the `unsignedPresentation`\nflag:\n\n```js\nimport * as vc from '@digitalbazaar/vc';\n\nconst result = await vc.verify({\n  presentation, suite, documentLoader, unsignedPresentation: true\n});\n// {valid: true}\n```\n\n#### `challenge` parameter\n\nVerifiable Presentations are typically used for authentication purposes.\nA `challenge` param (similar to a `nonce` in OAuth2/OpenID Connect) is provided\nby the party that's receiving the VP, and serves to prevent presentation replay\nattacks. The workflow is:\n\n1. Receiving party asks for the VerifiablePresentation, and provides a\n  `challenge` parameter.\n2. The client code creating the VP passes in that challenge (from the requesting\n  party), and it gets included in the VP.\n3. The client code passes the VP to the receiving party, which then checks to\n  make sure the `challenge` is the same as the one it provided in the request\n  in 1).\n\n### Verifying a Verifiable Credential\nFor most situations, Verifiable Credentials will be wrapped in a Verifiable\nPresentation and the entire VP should be verified. However, this library\nprovides a utility function to verify a Verifiable Credential on its own.\n\nPre-requisites:\n\n* Your custom `@context`s, verification methods (like public keys) and their\n  corresponding controller documents are reachable via a `documentLoader`.\n\nTo verify a verifiable credential:\n\n```js\nconst result = await vc.verifyCredential({credential, suite, documentLoader});\n// {valid: true}\n```\n\nTo verify a selective disclosure verifiable credential ensure the suite\nsupports it, for example:\n\n```js\nimport * as ecdsaSd2023Cryptosuite from\n  '@digitalbazaar/ecdsa-sd-2023-cryptosuite';\nimport {DataIntegrityProof} from '@digitalbazaar/data-integrity';\n\nconst {\n  createDiscloseCryptosuite,\n  createSignCryptosuite,\n  createVerifyCryptosuite\n} = ecdsaSd2023Cryptosuite;\n\nconst suite = new DataIntegrityProof({\n  cryptosuite: createVerifyCryptosuite()\n});\nconst result = await vc.verifyCredential({credential, suite, documentLoader});\n// {valid: true}\n```\n\nTo verify a verifiable credential with a custom `@context` field use a\n[custom documentLoader](#custom-documentLoader)\n\n### CLI\n\nTo use on the command line, see\n[`vc-js-cli`](https://github.com/digitalbazaar/vc-js-cli).\n\n## Testing\n\nTo run Mocha tests:\n\n```\nnpm run test-node\n```\n\nTo run Karma (in-browser) tests:\n\n```\nnpm run test-karma\n```\n\n## Contribute\n\nSee [the contribute file](https://github.com/digitalbazaar/bedrock/blob/master/CONTRIBUTING.md)!\n\nPRs accepted.\n\nNote: If editing the Readme, please conform to the\n[standard-readme](https://github.com/RichardLitt/standard-readme) specification.\n\n## Commercial Support\n\nCommercial support for this library is available upon request from\nDigital Bazaar: support@digitalbazaar.com\n\n## License\n\n[New BSD License (3-clause)](LICENSE) © Digital Bazaar\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbazaar%2Fvc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalbazaar%2Fvc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbazaar%2Fvc/lists"}