@digitalbazaar/vc

中文文档
7.3.0发布于 2026/02/06BSD-3-ClauseES Module近 30 天下载 8.9万

可验证的证书 JavaScript 库.

中文使用文档
文档目录18 节
  1. 目录
  2. 警卫
  3. 背景情况
  4. 安装
  5. 使用量
  6. 建立一个签名套房
  7. 签发一份可核证的证书
  8. 发布选择性披露
  9. 衍生出一种选择性披露
  10. 创建可验证的演示文稿
  11. 自定义文档Loader
  12. 验证可验证的演示文稿
  13. 验证可验证的证书
  14. 国 际
  15. 测试
  16. 贡献
  17. 商业支助
  18. 许可证

可核实的身份证件 (@数字集市/vc)

Build Status NPM Version

一个 Javascript 库,用于发布和验证可验证的证书.

目录

警卫

同大多数与安全和密码学有关的工具一样 您的系统将在很大程度上取决于您的设计决定( 哪些关键类型) 你将使用,你将储存 私钥,你放进你的 证书等. )

背景情况

此库是 Javascript (Node.js 和浏览器) 执行 可核实的证书数据模型 1.0 规格(目前不支持JWT序列化).

它允许您执行以下基本操作:

  1. 签署(签发)可核证的证书.
  2. 创建可验证的演示文稿(VP),签名或未签名
  3. 正在验证 VP
  4. 核查独立的《维也纳公约》

先决条件: 这个图书馆的使用假设你有能力做 目标如下:

  • 生成 LD 密钥对和签名套件
  • 将相应的公钥发布到可供用户访问的地方 审取者.
  • 确定您的习惯 @contexts,核查方法(如公用钥匙) 及其相应的控制文档,以及任何其他可解决的 对象,可通过 documentLoader。 。 。 .

安装

  • 浏览器和Node.js 18+得到支持.

从国家预防机制安装:

npm install @digitalbazaar/vc

在当地安装(用于开发):

git clone https://github.com/digitalbazaar/vc.git
cd vc
npm install

使用量

建立一个签名套房

签字时,设置签名套房时,需要通过 包含私钥的密钥对.

import * as vc from '@digitalbazaar/vc';

// Required to set up a suite instance with private key
import {Ed25519VerificationKey2020} from
  '@digitalbazaar/ed25519-verification-key-2020';
import {Ed25519Signature2020} from '@digitalbazaar/ed25519-signature-2020';

const keyPair = await Ed25519VerificationKey2020.generate();

const suite = new Ed25519Signature2020({key: keyPair});

签发一份可核证的证书

先决条件:

  • 您有私人密钥( 带有 ID 和控制器) 和相应的套件
  • 如果你使用习惯 @context,确保它可以解决
  • (建议) 你有一个策略 在哪里发布你的主计长 文档和公钥
import * as vc from '@digitalbazaar/vc';

// Sample unsigned credential
const credential = {
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1"
  ],
  "id": "https://example.com/credentials/1872",
  "type": ["VerifiableCredential", "AlumniCredential"],
  "issuer": "https://example.edu/issuers/565049",
  "issuanceDate": "2010-01-01T19:23:24Z",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "alumniOf": "Example University"
  }
};

const signedVC = await vc.issue({credential, suite, documentLoader});
console.log(JSON.stringify(signedVC, null, 2));

发布选择性披露

先决条件:

  • 您有私人密钥( 带有 ID 和控制器) 和相应的套件
  • 您正在使用一个密码套件 支持选择性的披露,例如 作为 ecdsa-sd-2023 或者说 bbs-2023
  • 如果你使用习惯 @context,确保它可以解决
  • (建议) 你有一个策略 在哪里发布你的主计长 文档和公钥

使用 ecdsa-sd-2023数字 :

import * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey';
import * as ecdsaSd2023Cryptosuite from
  '@digitalbazaar/ecdsa-sd-2023-cryptosuite';
import * as vc from '@digitalbazaar/vc';
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';

const ecdsaKeyPair = await EcdsaMultikey.generate({
  curve: 'P-256',
  id: 'https://example.edu/issuers/keys/2',
  controller: 'https://example.edu/issuers/565049'
});

// sample exported key pair
/*
{
  "@context": "https://w3id.org/security/multikey/v1",
  "id": "https://example.edu/issuers/keys/2",
  "type": "Multikey",
  "controller": "https://example.edu/issuers/565049",
  "publicKeyMultibase": "zDnaeWJjGpXnQAbEpRur3kSWFapGZbwGnFCkzyhiq7nDeXXrM",
  "secretKeyMultibase": "z42trzSpncjWFaB9cKE2Gg5hxtbuAQa5mVJgGwjrugHMacdM"
}
*/

// sample unsigned credential
const credential = {
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1"
  ],
  "id": "https://example.com/credentials/1872",
  "type": ["VerifiableCredential", "AlumniCredential"],
  "issuer": "https://example.edu/issuers/565049",
  "issuanceDate": "2010-01-01T19:23:24Z",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "alumniOf": "Example University"
  }
};

// setup ecdsa-sd-2023 suite for signing selective disclosure VCs
const suite = new DataIntegrityProof({
  signer: ecdsaKeyPair.signer(),
  cryptosuite: createSignCryptosuite({
    // require the `issuer` and `issuanceDate` fields to always be disclosed
    // by the holder (presenter)
    mandatoryPointers: [
      '/issuanceDate',
      '/issuer'
    ]
  })
});
// use a proof ID to enable it to be found and transformed into a disclosure
// proof by the holder later
const proofId = `urn:uuid:${uuid()}`;
suite.proof = {id: proofId};

const signedVC = await vc.issue({credential, suite, documentLoader});
console.log(JSON.stringify(signedVC, null, 2));

使用 bbs-2023数字 :

import * as bbs2023Cryptosuite from '@digitalbazaar/bbs-2023-cryptosuite';
import * as bls12381Multikey from '@digitalbazaar/bls12-381-multikey';
import * as vc from '@digitalbazaar/vc';
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';

const bbsKeyPair = await bls12381Multikey.generate({
  algorithm: 'BBS-BLS12-381-SHA-256';
  id: 'https://example.edu/issuers/keys/3',
  controller: 'https://example.edu/issuers/565049'
});

// sample exported key pair
/*
{
  "@context": "https://w3id.org/security/multikey/v1",
  "id": "https://example.edu/issuers/keys/3",
  "type": "Multikey",
  "controller": "https://example.edu/issuers/565049",
  "publicKeyMultibase": "zUC72jQrt2BfyE57AVgHgThKCsH6HNo85X9SLNpAJaHb42cNDXhsRWL2KkrFtaiztPbbZjfDVQnQQMw2nMqAPUHnaQ3xEr7kUmcnBgv7S2wQSbRbr7mqsP153nU7yMh3ZN4ZryL",
  "secretKeyMultibase": "z488y1niFCWnaV2i86q1raaa7qwBWZ6WTLeS1W1PrsbcsoNg"
}
*/

// sample unsigned credential
const credential = {
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1"
  ],
  // omit `id` to enable unlinkable disclosure
  "type": ["VerifiableCredential", "AlumniCredential"],
  "issuer": "https://example.edu/issuers/565049",
  // use less precise date that is shared by a sufficiently large group
  // of VCs to enable unlinkable disclosure
  "issuanceDate": "2010-01-01T01:00:00Z",
  "credentialSubject": {
    // omit `id` to enable unlinkable disclosure
    "alumniOf": "Example University"
  }
};

// setup bbs-2023 suite for signing unlinkable selective disclosure VCs
const suite = new DataIntegrityProof({
  signer: bbsKeyPair.signer(),
  cryptosuite: createSignCryptosuite({
    // require the `issuer` and `issuanceDate` fields to always be disclosed
    // by the holder (presenter)
    mandatoryPointers: [
      '/issuanceDate',
      '/issuer'
    ]
  })
});
// note: do not include a proof ID to enable unlinkable selective disclosure

const signedVC = await vc.issue({credential, suite, documentLoader});
console.log(JSON.stringify(signedVC, null, 2));

衍生出一种选择性披露

说明: 这一步骤是作为可核查证书的持有者履行的,而不是作为 一个发行商.

先决条件:

  • 你有一个可核查的证书 发行使用密码套件 支持选择性披露,例如: ecdsa-sd-2023 或者说 bbs-2023
  • 如果你使用习惯 @context,确保它可以解决

使用 ecdsa-sd-2023数字 :

import * as EcdsaMultikey from '@digitalbazaar/ecdsa-multikey';
import * as ecdsaSd2023Cryptosuite from
  '@digitalbazaar/ecdsa-sd-2023-cryptosuite';
import * as vc from '@digitalbazaar/vc';
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';

const {
  createDiscloseCryptosuite,
  createSignCryptosuite,
  createVerifyCryptosuite
} = ecdsaSd2023Cryptosuite;

// sample VC
const verifiableCredential = {
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1",
    "https://w3id.org/security/data-integrity/v2"
  ],
  "id": "http://example.edu/credentials/1872",
  "type": [
    "VerifiableCredential",
    "AlumniCredential"
  ],
  "issuer": "https://example.edu/issuers/565049",
  "issuanceDate": "2010-01-01T19:23:24Z",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "alumniOf": "<span lang=\"en\">Example University</span>"
  },
  "proof": {
    "id": "urn:uuid:318d9dce-bc7b-40b9-a956-c9160bf910db",
    "type": "DataIntegrityProof",
    "created": "2024-01-12T21:53:11Z",
    "verificationMethod": "https://example.edu/issuers/keys/2",
    "cryptosuite": "ecdsa-sd-2023",
    "proofPurpose": "assertionMethod",
    "proofValue": "u2V0AhVhAsl6PQKYE15R0O5Qd267ntwHGNH6JRvZ1y8A-fTCQLUoupP8SCZzzmyc0a1AnabHEVKhpHtYV8j9Kapp-fHFBtFgjgCQCIMn2L1R7D5VPnNn_2foxdj8qvsuUTGFqA34YBkguzCpYILfJ-qNQpn6_dJGpkG24FynqbHpnzoHWVJc2kiLqEKHRglhAUmZtstR9MOLrZjcR8J303MXFvRiE6J3bbaPT1_I9-6578-Wj-eydv2TEGBq_dmsjxsOh4_2Va0etw8CXXMAzaVhA9fr7_Sl9D67AfvLhkJTZ0uJCAXcbL2MaS-DmoC7K-ABxroL1_wj119J8yTMlazxzYBwYkihrdp4ZWJZxraX9tIJtL2lzc3VhbmNlRGF0ZWcvaXNzdWVy"
  }
};

// note no `signer` needed; the selective disclosure credential will be
// derived from the base proof already provided by the issuer
const suite = new DataIntegrityProof({
  cryptosuite: createDiscloseCryptosuite({
    // the ID of the base proof to convert to a disclosure proof
    proofId: 'urn:uuid:da088899-3439-41ea-a580-af3f1cf98cd3',
    // selectively disclose the entire credential subject; different JSON
    // pointers could be provided to selectively disclose different information;
    // the issuer will have mandatory fields that will be automatically
    // disclosed such as the `issuer` and `issuanceDate` fields
    selectivePointers: [
      '/credentialSubject'
    ]
  })
});

const derivedVC = await vc.derive({
  verifiableCredential, suite, documentLoader
});
console.log(JSON.stringify(derivedVC, null, 2));

使用 bbs-2023数字 :

import * as bbs2023Cryptosuite from '@digitalbazaar/bbs-2023-cryptosuite';
import * as bls12381Multikey from '@digitalbazaar/bls12-381-multikey';
import * as vc from '@digitalbazaar/vc';
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';

const {
  createDiscloseCryptosuite,
  createSignCryptosuite,
  createVerifyCryptosuite
} = bbs2023Cryptosuite;

// sample VC
const verifiableCredential = {
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1",
    "https://w3id.org/security/data-integrity/v2"
  ],
  "type": [
    "VerifiableCredential",
    "AlumniCredential"
  ],
  "issuer": "https://example.edu/issuers/565049",
  "issuanceDate": "2010-01-01T01:00:00Z",
  "credentialSubject": {
    "alumniOf": "<span lang=\"en\">Example University</span>"
  },
  "proof": {
    "type": "DataIntegrityProof",
    "verificationMethod": "https://example.edu/issuers/keys/3",
    "cryptosuite": "bbs-2023",
    "proofPurpose": "assertionMethod",
    "proofValue": "u2V0ChVhQp1smqO-Qmc-1KpNkShjevTeylTdVlpH_RNXeJ_cNniErWPbEWILvsoH5mYjnun5ibZHq0m7BEIaLv8sfMtLfcmgPj6tbAFwDWvEcbRWg7CFYQGWqCAnvTpL_Aao3aVCg5svdzFuvKqnvneA0UwaN0lagvGpWT7fCDGgcYPyNPKaCX94Xo06aTcSwOXgyGUbtN1xYYIU6t5wv20lVdESfzkYOFXTxIZa1HSBAZYWDyEgQ3A3ajzWX5qeFc3cwmnnrGUfJYwawgGLQAY3vBi3LTM2i3jCOPvxCEJALPIjK4tEmWb6uFjT4PWLlIEeTtYj_0yEv91ggsm9vw1PPlK6q8wQiw2i2joZ-OKkvHz7rDSxPYfmQNrqCbS9pc3N1YW5jZURhdGVnL2lzc3Vlcg"
  }
};

// note no `signer` needed; the selective disclosure credential will be
// derived from the base proof already provided by the issuer
const suite = new DataIntegrityProof({
  cryptosuite: createDiscloseCryptosuite({
    // selectively disclose the entire credential subject; different JSON
    // pointers could be provided to selectively disclose different information;
    // the issuer will have mandatory fields that will be automatically
    // disclosed such as the `issuer` and `issuanceDate` fields
    selectivePointers: [
      '/credentialSubject'
    ]
  })
});

const derivedVC = await vc.derive({
  verifiableCredential, suite, documentLoader
});
console.log(JSON.stringify(derivedVC, null, 2));

创建可验证的演示文稿

先决条件:

  • 您拥有必要的私人密钥( 带有 ID 和控制器) 和 相应套间
  • 如果你使用习惯 @context,确保它可以解决
  • (建议) 你有一个策略 在哪里发布你的主计长 文件和公用钥匙

创建未签名的演示文稿

要从一个或多个可核查的证书创建演示文稿,您可以 使用该 createPresentation() 方便功能. 或者,你可以 手动创建演示文稿对象(不要忘记设置) @context 财务报告和审定财务报表 type 属性).

用自定义创建可核查的演示文稿 @context 字段使用 a 自定义文档Loader

const verifiableCredential = [vc1, vc2]; // either array or single object

// optional `id` and `holder`
const id = 'ebc6f1c2';
const holder = 'did:ex:12345';

const presentation = vc.createPresentation({
  verifiableCredential, id, holder
});

console.log(JSON.stringify(presentation, null, 2));
// ->
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1"
  ],
  "type": [
    "VerifiablePresentation"
  ],
  "id": "ebc6f1c2",
  "holder": "did:ex:12345",
  "verifiableCredential": [
    // vc1:
    {
      "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://www.w3.org/2018/credentials/examples/v1"
      ],
      "id": "http://example.edu/credentials/1872",
      "type": [
        "VerifiableCredential",
        "AlumniCredential"
      ],
      "issuer": "https://example.edu/issuers/565049",
      "issuanceDate": "2010-01-01T19:23:24Z",
      "credentialSubject": {
        "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
        "alumniOf": "<span lang=\"en\">Example University</span>"
      },
      "proof": {
        "type": "Ed25519Signature2018",
        "created": "2020-02-03T17:23:49Z",
        "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..AUQ3AJ23WM5vMOWNtYKuqZBekRAOUibOMH9XuvOd39my1sO-X9R4QyAXLD2ospssLvIuwmQVhJa-F0xMOnkvBg",
        "proofPurpose": "assertionMethod",
        "verificationMethod": "https://example.edu/issuers/keys/1"
      }
    },
    // vc2 goes here ...
  ]
}

请注意,这会造成 未签名 演示文稿( 可能有效) (有些情况).

自定义文档Loader

先决条件:

  • 您有一个有效的 JSON- LD @context。 。 。 .
  • 您的自定义上下文可以在地址中解决 .
// jsonld-signatures has a secure context loader
// by requiring this first you ensure security
// contexts are loaded from jsonld-signatures
// and not an insecure source.
import * as vc from '@digitalbazaar/vc';
const {extendContextLoader} = require('jsonld-signatures');
// @digitalbazaar/vc exports its own secure documentLoader.
const {defaultDocumentLoader} = vc;
// a valid json-ld @context.
const myCustomContext = require('./myCustomContext');

const documentLoader = extendContextLoader(async url => {
  if(url === 'did:test:context:foo') {
    return {
      contextUrl: null,
      documentUrl: url,
      document: myCustomContext
    };
  }
  return defaultDocumentLoader(url);
});

// you can now use your custom documentLoader
// with multiple vc methods such as:

const vp = await vc.signPresentation({
  presentation, suite, challenge, documentLoader
});

// or
const signedVC = await vc.issue({credential, suite, documentLoader});

// or
const result = await vc.verifyCredential({credential: signedVC, suite, documentLoader});

签署陈述

一旦你创建了演示文稿(或者通过 createPresentation() 或者说 手动,可以使用 signPresentation()数字 :

import * as vc from '@digitalbazaar/vc';

const vp = await vc.signPresentation({
  presentation, suite, challenge, documentLoader
});

console.log(JSON.stringify(vp, null, 2));
// ->
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1"
  ],
  "type": [
    "VerifiablePresentation"
  ],
  "verifiableCredential": [
    {
      "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://www.w3.org/2018/credentials/examples/v1"
      ],
      "id": "http://example.edu/credentials/1872",
      "type": [
        "VerifiableCredential",
        "AlumniCredential"
      ],
      "issuer": "https://example.edu/issuers/565049",
      "issuanceDate": "2010-01-01T19:23:24Z",
      "credentialSubject": {
        "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
        "alumniOf": "<span lang=\"en\">Example University</span>"
      },
      "proof": {
        "type": "Ed25519Signature2018",
        "created": "2020-02-03T17:23:49Z",
        "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..AUQ3AJ23WM5vMOWNtYKuqZBekRAOUibOMH9XuvOd39my1sO-X9R4QyAXLD2ospssLvIuwmQVhJa-F0xMOnkvBg",
        "proofPurpose": "assertionMethod",
        "verificationMethod": "https://example.edu/issuers/keys/1"
      }
    }
  ],
  "id": "ebc6f1c2",
  "holder": "did:ex:holder123",
  "proof": {
    "type": "Ed25519Signature2018",
    "created": "2019-02-03T17:23:49Z",
    "challenge": "12ec21",
    "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..ZO4Lkq8-fOruE4oUvuMaxepGX-vLD2gPyNIsz-iA7X0tzC3_96djaBYDxxl6wD1xKrx0h60NjI9i9p_MxoXkDQ",
    "proofPurpose": "authentication",
    "verificationMethod": "https://example.edu/issuers/keys/1"
  }
}

验证可验证的演示文稿

先决条件:

  • 您的风俗 @contexts、核查方法(如公用钥匙)及其 相应的控制器文档可以通过一个 documentLoader。 。 。 .

为核实可核查的列报:

import * as vc from '@digitalbazaar/vc';

// challenge has been received from the requesting party - see 'challenge'
// section below

const result = await vc.verify({presentation, challenge, suite, documentLoader});
// {valid: true}

默认, verify() 如果出现错误,则会投出错误 proof 区域缺失. 为了验证未签名的演示文稿,您必须设置 unsignedPresentation 旗帜 :

import * as vc from '@digitalbazaar/vc';

const result = await vc.verify({
  presentation, suite, documentLoader, unsignedPresentation: true
});
// {valid: true}

challenge 参数

可核查的演示文稿通常用于认证目的. A 类 challenge parm (类似于 nonce 在 OAuth2/ OpenID 连接中提供 并阻止节目重播 攻击。 工作流程如下:

  1. 接收方要求提供可核实的陈述,并提供 challenge 参数.
  2. 创建 VP 的客户端代码在此挑战中通过(来自请求) 党),并被包括在"副总统"中.
  3. 客户端代码将VP传递给接收方,接收方随后检查到 确保 challenge 与请求中提供的相同 在1页.

验证可验证的证书

在大多数情况下,可核查的全权证书将用可核查的 演示文稿和整个副总统应加以核实。 然而,这个图书馆 提供一种功能来验证可验证的证书.

先决条件:

  • 您的风俗 @contexts、核查方法(如公用钥匙)及其 相应的控制器文档可以通过一个 documentLoader。 。 。 .

核查可核查的证明:

const result = await vc.verifyCredential({credential, suite, documentLoader});
// {valid: true}

核查可核查的选择性披露证书,确保套件 支持,例如:

import * as ecdsaSd2023Cryptosuite from
  '@digitalbazaar/ecdsa-sd-2023-cryptosuite';
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';

const {
  createDiscloseCryptosuite,
  createSignCryptosuite,
  createVerifyCryptosuite
} = ecdsaSd2023Cryptosuite;

const suite = new DataIntegrityProof({
  cryptosuite: createVerifyCryptosuite()
});
const result = await vc.verifyCredential({credential, suite, documentLoader});
// {valid: true}

以习惯验证可核查的证书 @context 字段使用 a 自定义文档Loader

国 际

要在命令行上使用, 请见 vc-js-cli。 。 。 .

测试

进行Mocha测试:

npm run test-node

进行Karma(浏览器)测试:

npm run test-karma

贡献

见 贡献文件来啊!

公关接受.

注:如果编辑Readme,请遵照 标准读取 规格.

商业支助

该图书馆的商务支助可应下列请求提供: 数字集市: 支持@ digitalbazaar.com

许可证

新建 BSD 许可证( 3- clause) 数字集市

版本与发布记录

@digitalbazaar/vc 共发布 18 个版本,首次发布于 2021/04/22;过去 12 个月发布了 1 个版本。

版本发布日期距今
7.3.0latest2026/02/069 个月前
7.2.02025/04/151.6 年前
7.1.22025/03/181.7 年前
7.1.12025/03/081.7 年前
7.1.02024/10/112 年前
7.0.02024/08/022 年前

关于 @digitalbazaar/vc 的常见问题

@digitalbazaar/vc 是什么?

可验证的证书 JavaScript 库.

如何安装 @digitalbazaar/vc?

在项目目录运行 npm install @digitalbazaar/vc,或使用 pnpm add / yarn add / bun add。

@digitalbazaar/vc 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/digitalbazaar__vc 是否存在。

@digitalbazaar/vc 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@digitalbazaar/vc 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@digitalbazaar/vc 可以商用吗?

@digitalbazaar/vc 使用 BSD-3-Clause 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。另外不得用原作者名义为衍生产品背书。以上为概括,不构成法律意见,请以许可原文为准。

@digitalbazaar/vc 的下载量有多少?

根据 npm 官方下载统计,@digitalbazaar/vc 在 2026/10/12 – 2026/11/10 这 30 天内被下载 88,764 次,日均约 2,959 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@digitalbazaar/vc 还在维护吗?

最新版本 7.3.0 发布于 2026/02/06(9 个月前);至今共发布 18 个版本,其中过去 12 个月发布了 1 个;首次发布于 2021/04/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。