npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jccdex/vc-vocabularies

v0.1.2

Published

VC vocabulary and issuance profiles for JCCDEx DID ecosystem

Readme

@jccdex/vc-vocabularies

VC 业务词汇表与签发 Profile,配合 @jccdex/didissueVC() 使用。

安装

yarn add @jccdex/vc-vocabularies @jccdex/did

支持的 VC 类型

| 常量 | 类型字符串 | 场景 | |------|-----------|------| | VC_TYPES.NFT_OWNERSHIP | NFTOwnership | 证明持有某个 NFT | | VC_TYPES.NFT_USAGE_AUTHORIZATION | NFTUsageAuthorization | 授权他人使用 NFT | | VC_TYPES.PHONE_VERIFICATION | PhoneVerificationCredential | 手机号实名验证 | | VC_TYPES.FILE_ACCESS_AUTHORIZATION | FileAccessAuthorization | 授权访问 IPFS/IPNS 上的文件或目录 |

品牌 ID:"ccdao"ccda.ooo)、"jdid"jdid.cn)。


VC 签发示例

以下示例展示签发描述符(Descriptor)的组装方式。描述符传入 @jccdex/didissueVC() 后完成签名,最终产出标准 W3C VC JSON。

1. NFT 所有权(NFTOwnership)

证明某个地址持有特定 NFT。

import { issueVC } from "@jccdex/did";
import { buildNftOwnershipDescriptor } from "@jccdex/vc-vocabularies";

const descriptor = buildNftOwnershipDescriptor(
  "ccdao",
  {
    id: holderDid,
    owner: holderDid,
    chainId: 1,
    contractAddress: "0xAbCd...",  // EVM 链填 contractAddress
    // tokenName: "TokenSymbol",   // SWTC 链改用 tokenName + nftIssuer
    // nftIssuer: "rXxx...",
    tokenId: "123",
    standard: "ERC-721",
    status: "Active"
  },
  {
    id: `${holderDid}#vc-1`,
    expirationDate: "2099-01-01T00:00:00.000Z"
  }
);

const vcJSON = await issueVC(descriptor, { sign, keyDoc });
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    {
      "NFTOwnership": "https://ccda.ooo/vc/v1#NFTOwnership",
      "version": "https://ccda.ooo/did/v1",
      "chainId": "https://ccda.ooo/did/v1#chainId",
      "contractAddress": "https://ccda.ooo/did/v1#contractAddress",
      "tokenName": "https://ccda.ooo/did/v1#tokenName",
      "tokenId": "https://ccda.ooo/did/v1#tokenId",
      "owner": "https://ccda.ooo/did/v1#owner",
      "nftIssuer": "https://ccda.ooo/did/v1#nftIssuer",
      "standard": "https://ccda.ooo/did/v1#standard",
      "status": "https://ccda.ooo/did/v1#status"
    }
  ],
  "type": ["VerifiableCredential", "NFTOwnership"],
  "id": "did:ethr:0x1234...#vc-1",
  "issuer": "did:ethr:0x1234...",
  "issuanceDate": "2026-06-23T00:00:00Z",
  "expirationDate": "2099-01-01T00:00:00Z",
  "credentialSubject": {
    "id": "did:ethr:0x1234...",
    "owner": "did:ethr:0x1234...",
    "chainId": 1,
    "contractAddress": "0xAbCd...",
    "tokenId": "123",
    "standard": "ERC-721",
    "status": "Active"
  }
}

2. NFT 使用授权(NFTUsageAuthorization)

所有者授权他人在指定范围内使用 NFT(如商业用途、衍生作品等)。

import { buildNftUsageAuthorizationDescriptor } from "@jccdex/vc-vocabularies";

const descriptor = buildNftUsageAuthorizationDescriptor(
  "ccdao",
  {
    id: granteeDid,
    grantee: granteeDid,
    owner: ownerDid,
    chainId: 1,
    contractAddress: "0xAbCd...",
    tokenId: "123",
    standard: "ERC-721",
    status: "Active",
    usageRights: "exclusive",
    restrictions: {
      commercial: true,
      derivative: false,
      sublicense: false,
      territories: ["CN", "US"],
      platforms: ["web", "mobile"]
    }
  },
  {
    id: `${ownerDid}#vc-auth-1`,
    expirationDate: "2027-01-01T00:00:00.000Z"
  }
);
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    {
      "NFTUsageAuthorization": "https://ccda.ooo/vc/v1#NFTUsageAuthorization",
      "version": "https://ccda.ooo/did/v1",
      "grantee": "https://ccda.ooo/vc/v1#grantee",
      "usageRights": "https://ccda.ooo/vc/v1#usageRights",
      "restrictions": {
        "@id": "https://ccda.ooo/vc/v1#restrictions",
        "@context": {
          "commercial": "https://ccda.ooo/vc/v1#commercial",
          "derivative": "https://ccda.ooo/vc/v1#derivative",
          "sublicense": "https://ccda.ooo/vc/v1#sublicense",
          "territories": "https://ccda.ooo/vc/v1#territories",
          "platforms": "https://ccda.ooo/vc/v1#platforms"
        }
      },
      "chainId": "https://ccda.ooo/did/v1#chainId",
      "contractAddress": "https://ccda.ooo/did/v1#contractAddress",
      "tokenId": "https://ccda.ooo/did/v1#tokenId",
      "owner": "https://ccda.ooo/did/v1#owner",
      "standard": "https://ccda.ooo/did/v1#standard",
      "status": "https://ccda.ooo/did/v1#status"
    }
  ],
  "type": ["VerifiableCredential", "NFTUsageAuthorization"],
  "id": "did:ethr:0x1234...#vc-auth-1",
  "issuer": "did:ethr:0x1234...",
  "issuanceDate": "2026-06-23T00:00:00Z",
  "expirationDate": "2027-01-01T00:00:00Z",
  "credentialSubject": {
    "id": "did:ethr:0xABCD...",
    "grantee": "did:ethr:0xABCD...",
    "owner": "did:ethr:0x1234...",
    "chainId": 1,
    "contractAddress": "0xAbCd...",
    "tokenId": "123",
    "standard": "ERC-721",
    "status": "Active",
    "usageRights": "exclusive",
    "restrictions": {
      "commercial": true,
      "derivative": false,
      "sublicense": false,
      "territories": ["CN", "US"],
      "platforms": ["web", "mobile"]
    }
  }
}

3. 电话验证(PhoneVerificationCredential)

证明某个 DID 完成了手机号实名验证。

import { buildPhoneVerificationDescriptor } from "@jccdex/vc-vocabularies";

const descriptor = buildPhoneVerificationDescriptor(
  "jdid",
  {
    id: userDid,
    standard: "1.0",
    status: "active",
    verificationMethod: "sms-otp",
    verificationProcess: {
      verifiedAt: "2026-06-23T06:00:00Z",
      updateAt: "2026-06-23T06:00:00Z",
      verifierId: "did:ethr:0xVERIFIER..."
    }
  },
  {
    id: `${userDid}#vc-phone-1`,
    expirationDate: "2027-06-23T00:00:00.000Z"
  }
);
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    {
      "PhoneVerificationCredential": "https://jdid.cn/vc/v1#PhoneVerificationCredential",
      "version": "https://jdid.cn/did/v1",
      "standard": "https://jdid.cn/did/v1#standard",
      "status": "https://jdid.cn/did/v1#status",
      "verificationMethod": "https://jdid.cn/did/v1#verificationMethod",
      "verificationProcess": {
        "@id": "https://jdid.cn/did/v1#verificationProcess",
        "@context": {
          "verifiedAt": "https://jdid.cn/did/v1#verifiedAt",
          "updateAt": "https://jdid.cn/did/v1#updateAt",
          "verifierId": "https://jdid.cn/did/v1#verifierId"
        }
      }
    }
  ],
  "type": ["VerifiableCredential", "PhoneVerificationCredential"],
  "id": "did:ethr:0xUSER...#vc-phone-1",
  "issuer": "did:ethr:0xVERIFIER...",
  "issuanceDate": "2026-06-23T06:00:00Z",
  "expirationDate": "2027-06-23T00:00:00Z",
  "credentialSubject": {
    "id": "did:ethr:0xUSER...",
    "standard": "1.0",
    "status": "active",
    "verificationMethod": "sms-otp",
    "verificationProcess": {
      "verifiedAt": "2026-06-23T06:00:00Z",
      "updateAt": "2026-06-23T06:00:00Z",
      "verifierId": "did:ethr:0xVERIFIER..."
    }
  }
}

4. 文件访问授权(FileAccessAuthorization)

基于 IPFS/IPNS 存储模型,授权他人访问链上文件或目录。

设计说明:

  • ipnsName:IPNS 固定入口,所有者更新文件后入口不变,被授权方始终可通过它访问最新内容。
  • 不存 CID:CID 随文件更新而变化;IPFS 内容寻址协议在取回内容时自动验证完整性,无需在 VC 层声明。
  • resourceType:区分授权粒度为单文件("file")或目录("directory")。
  • resourcePath:目录授权时可指定子路径,为空则整个 IPNS 目录均可访问。
import { buildFileAccessAuthorizationDescriptor } from "@jccdex/vc-vocabularies";

const descriptor = buildFileAccessAuthorizationDescriptor(
  "ccdao",
  {
    id: granteeDid,
    grantee: granteeDid,
    ipnsName: "k51qzi5uqu5dh9ihj4g2s7qopkrpwhvy49rlcdmqbcg58k8q8z32lkj7k8s",
    resourceType: "directory",
    resourcePath: "/reports/2026",   // 省略则整个目录
    owner: ownerDid,
    accessRights: ["read", "download"],
    accessRestrictions: {
      expiresAt: "2027-06-23T00:00:00.000Z",
      maxDownloads: 50,              // 0 = 不限次数
      ipWhitelist: []                // 空 = 不限 IP
    },
    standard: "1.0",
    status: "active"
  },
  {
    id: `${ownerDid}#vc-file-1`,
    expirationDate: "2027-06-23T00:00:00.000Z"
  }
);
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    {
      "FileAccessAuthorization": "https://ccda.ooo/vc/v1#FileAccessAuthorization",
      "version": "https://ccda.ooo/did/v1",
      "grantee": "https://ccda.ooo/vc/v1#grantee",
      "accessRights": "https://ccda.ooo/vc/v1#accessRights",
      "accessRestrictions": {
        "@id": "https://ccda.ooo/vc/v1#accessRestrictions",
        "@context": {
          "expiresAt": "https://ccda.ooo/vc/v1#expiresAt",
          "maxDownloads": "https://ccda.ooo/vc/v1#maxDownloads",
          "ipWhitelist": "https://ccda.ooo/vc/v1#ipWhitelist"
        }
      },
      "ipnsName": "https://ccda.ooo/did/v1#ipnsName",
      "resourceType": "https://ccda.ooo/did/v1#resourceType",
      "resourcePath": "https://ccda.ooo/did/v1#resourcePath",
      "owner": "https://ccda.ooo/did/v1#owner",
      "standard": "https://ccda.ooo/did/v1#standard",
      "status": "https://ccda.ooo/did/v1#status"
    }
  ],
  "type": ["VerifiableCredential", "FileAccessAuthorization"],
  "id": "did:ethr:0x1234...#vc-file-1",
  "issuer": "did:ethr:0x1234...",
  "issuanceDate": "2026-06-23T06:34:00Z",
  "expirationDate": "2027-06-23T00:00:00Z",
  "credentialSubject": {
    "id": "did:ethr:0xABCD...",
    "grantee": "did:ethr:0xABCD...",
    "ipnsName": "k51qzi5uqu5dh9ihj4g2s7qopkrpwhvy49rlcdmqbcg58k8q8z32lkj7k8s",
    "resourceType": "directory",
    "resourcePath": "/reports/2026",
    "owner": "did:ethr:0x1234...",
    "accessRights": ["read", "download"],
    "accessRestrictions": {
      "expiresAt": "2027-06-23T00:00:00Z",
      "maxDownloads": 50,
      "ipWhitelist": []
    },
    "standard": "1.0",
    "status": "active"
  }
}

被授权方访问流程:

1. 持 VC 向资源服务方出示,服务方验证签名
2. 从 credentialSubject.ipnsName 解析当前 CID(IPNS 查询)
3. 按 resourcePath 限定可访问范围
4. 从 IPFS 取内容,协议层自动以 CID 验证完整性(内容寻址天然自验证)
5. 检查 accessRestrictions(到期时间、下载次数、IP 白名单)

主要 API

| 导出 | 说明 | |------|------| | buildNftOwnershipDescriptor | NFT 所有权 VC 签发 Profile | | buildNftUsageAuthorizationDescriptor | NFT 使用授权 VC 签发 Profile | | buildPhoneVerificationDescriptor | 电话验证 VC 签发 Profile | | buildFileAccessAuthorizationDescriptor | 文件访问授权 VC 签发 Profile | | buildInlineContext | 按字段生成最小内联 @context | | VC_TYPES | VC 业务类型常量 | | getNftOwnershipContext 等 | 按品牌获取完整内联 context 对象 | | CCDAO_*_CONTEXT / JDID_*_CONTEXT | 各类型品牌具名 context 常量 |


自定义 Descriptor

不经过 Profile 时,可用 buildInlineContext 按需裁剪字段,减小 VC 体积:

import {
  buildInlineContext,
  VC_TYPES,
  W3C_VC_CONTEXT_URL
} from "@jccdex/vc-vocabularies";

// 仅携带本次 subject 用到的字段,忽略 contractAddress 等未用术语
const descriptor = {
  types: [VC_TYPES.NFT_OWNERSHIP],
  contexts: [
    W3C_VC_CONTEXT_URL,
    buildInlineContext("jdid", {
      types: ["NFTOwnership"],
      fields: ["chainId", "tokenId", "tokenName", "nftIssuer", "owner", "standard", "status"]
    })
  ],
  subject: { id: holderDid, /* ... */ },
  id: `${holderDid}#vc-1`,
  expirationDate: "2099-01-01T00:00:00.000Z"
};

// 文件授权最小 context(仅携带访问必需字段)
const fileDescriptor = {
  types: [VC_TYPES.FILE_ACCESS_AUTHORIZATION],
  contexts: [
    W3C_VC_CONTEXT_URL,
    buildInlineContext("ccdao", {
      types: ["FileAccessAuthorization"],
      fields: ["ipnsName", "resourceType", "resourcePath", "accessRights", "accessRestrictions"]
    })
  ],
  subject: { id: granteeDid, /* ... */ },
  id: `${ownerDid}#vc-file-2`,
  expirationDate: "2027-01-01T00:00:00.000Z"
};

词汇表 JSON(高级)

验签缓存与品牌服务器部署使用 contexts/*.json,可通过子路径引用:

import ccdaoDidV1 from "@jccdex/vc-vocabularies/contexts/ccda-did-v1.json";
import jdidDidV1  from "@jccdex/vc-vocabularies/contexts/jdid-did-v1.json";
import ccdaoVcV1  from "@jccdex/vc-vocabularies/contexts/ccda-vc-v1.json";
import jdidVcV1   from "@jccdex/vc-vocabularies/contexts/jdid-vc-v1.json";

一般由 @jccdex/did 内部引用,应用层通常无需直接 import。


开发

yarn build
yarn test

相关包