{"id":25417413,"url":"https://github.com/zcloak-network/zkid-sdk-example","last_synced_at":"2025-09-04T05:11:05.488Z","repository":{"id":156878610,"uuid":"616828571","full_name":"zCloak-Network/zkid-sdk-example","owner":"zCloak-Network","description":"Demo for how to use our zkid-sdk.","archived":false,"fork":false,"pushed_at":"2024-01-25T02:49:50.000Z","size":7811,"stargazers_count":3,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"sdk-v2","last_synced_at":"2024-01-25T03:41:25.756Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zCloak-Network.png","metadata":{"files":{"readme":"README-zh.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-03-21T06:59:15.000Z","updated_at":"2023-12-27T08:04:51.000Z","dependencies_parsed_at":"2023-10-30T11:28:35.605Z","dependency_job_id":"f8b5eb2c-471c-4762-aa9b-f5b494cccaaf","html_url":"https://github.com/zCloak-Network/zkid-sdk-example","commit_stats":null,"previous_names":["zcloak-network/credential-api-example"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zCloak-Network%2Fzkid-sdk-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zCloak-Network%2Fzkid-sdk-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zCloak-Network%2Fzkid-sdk-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zCloak-Network%2Fzkid-sdk-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zCloak-Network","download_url":"https://codeload.github.com/zCloak-Network/zkid-sdk-example/tar.gz/refs/heads/sdk-v2","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239171869,"owners_count":19594047,"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":"2025-02-16T17:58:37.398Z","updated_at":"2025-02-16T17:58:37.984Z","avatar_url":"https://github.com/zCloak-Network.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zkid-SDK 使用说明\n\nHi👋，各位开发者🧑‍💻，本教程将向你展示如何使用 SDK来完成 credential分发的 **request模式**（claimer发起 attestation请求，attester批准或拒绝请求）与 **issue模式**（attester 直接向指定 claimer发送 VC）。\n\n各位Attester🧑🏻‍⚖️，准备好了么?🚀 让我们出发吧！！！\n\n⚠️ 最新的代码分支为 **sdk-v2**，请确保您的服务是基于 **sdk-v2**分支进行开发。\n\n## 快速使用\n\n请确保使用最新兼容版本，您可以使用 `npm update` 命令来升级依赖。\n\n```bash\ngit clone https://github.com/zCloak-Network/zkid-sdk-example.git\ncd zkid-sdk-example/\nnpm install\n\nnpm run create-did\nnpm run ctype\nnpm run claim\nnpm run attest\nnpm run multiAttest\nnpm run issue\nnpm run vp-send\nnpm run vp-send-verify\nnpm run zkp\n```\n\n## ⚠️ Issue Verifiable Credential ⚠️\n如果您的需求只是使用 SDK向用户直接发送 VC（即 issue模式），那么您只需参考 `/src/issue/issue.ts`文件。\n\n## 使用向导\n\n### Demo文件说明\n所有 Demo文件位于 `src/`文件夹中，以下将根据文件夹的归类来分别介绍几个主要功能模块。\n\n**claim-attest**\n在 claim-attest文件夹下，包含了 claim.ts脚本与 attest.ts脚本，二者用于展示签发 VC的 request模式，即 claimer发起 attestation请求，attester批准/拒绝请求，attester批准请求后签发 VC。\n\n**issue**\n在 issue文件夹下，只包含一个 issue.ts脚本文件，该文件用于展示签发 VC的 issue模式，即 attester直接向指定用户签发一个 VC，用户不需要提前请求。\n\n**ctype**\n在 ctype文件夹中，只包含一个 createCtype.ts脚本文件，该文件用于展示如何创建一个 ctype。建议各位开发者使用 [card center 平台](https://card.zkid.app/#/)创建 ctype。Card Maker =\u003e Create New Template，其中 Template 为 CType 的上层结构体，创建 Template 后，Data Field Hash 即为 ctype hash。\n\n### 📨 Issue Credential API Tutorial\n\n🤓 在 issue模式的教程中，我们将以 `src/issue/issue.ts`文件为基础，详细介绍一下如何使用 API来 Issue Credential。\n\n**前置条件**\n```typescript\nawait initCrypto();\n```\n在前置步骤中，我们需要对密码学库进行初始化操作：\n调用 `initCrypto()`接口，初始化 @noble密码学库与 wasm，此步骤为必需，因为我们的 API基于此开发。\n1. 生成 resolver，resolver指定了具体的环境，其中 `server`为正式环境或者测试环境的 URL，通过 resolver，可以解析 DID或者通过给定的 DID URL来获取对应的 DID Document。\n\n**Step 0: 根据 claimer DID URL 获取其 DID对象**\n```typescript\nconst holderDidDoc = await resolver.resolve(holderDidUrl);\nconst holder = fromDidDocument(holderDidDoc);\n\nconst keyring = new Keyring();\nconst json = readDidKeysFile();\nconst password = \"12345678\"; // password to decrypt your DID-keys-file\nconst attester = restore(keyring, json, password);\n\n// src/utils/resolverHelper.ts\nexport const resolver = new ArweaveDidResolver();\n\n// src/utils/didHelper.ts\nexport function readDidKeysFile() {\n  const attesterKeysFile = fs.readFileSync(\n    path.resolve(__dirname, \"../../attester-DID-keys-file.json\"),\n    { encoding: \"utf-8\" }\n  );\n  return JSON.parse(attesterKeysFile) as DidKeys$Json;\n}\n\n```\n在本步骤中，我们用到以下API，\n1. `fromDidDocument(document: DidDocument, keyring?: KeyringInstance)`该 API可通过 DID Document恢复 DID，其中 Document的获取通过调用接口 `resoler.resolve(didUrl: string)`。注意⚠️：resolver可以作为某些 API的参数，对于这类 API，开发者应当在使用中明确指定 resolver，特别是当您在我们的开发环境中进行测试时。这是因为我们的 resolver默认连接生产环境，如果您没有指定 resolver，则可能会出现 DID Method找不到等情况;\n2. `restore(keyring: Keyring, json: DidKeys$Json, password: string)`该 API旨在通过 DID-keys-file来恢复 DID，需要注意一点：password参数为创建 DID时的密码，正确的使用该密码才可以解密 DID-keys-file并恢复 DID。\n\n除了使用上述方法恢复 DID外，我们还提供了通过助记词来恢复 DID，具体接口为：`fromMnemonic(keyring: KeyringInstance, mnemonic: string, signingKeyType?: 'ecdsa' | 'ed25519', index?: number)`。\n\n```typescript\nimport { keys } from \"@zcloak/did\";\nimport { Keyring } from \"@zcloak/keyring\";\n\nconst keyring = new Keyring();\nconst mnemonic = 'xxx';\nconst attester = keys.fromMnemonic(keyring, mnemonic, \"ecdsa\");\n```\n\n**Step 1: 根据 cType hash值获取 CType对象**\n```typescript\nconst ctype: CType = await getCtypeFromHash(ctypeHash);\n\n// src/utils/ctypeHelper.ts\nexport async function getCtypeFromHash(\n  hash: string | undefined,\n  url = process.env.BASE_URL\n): Promise\u003cCType\u003e {\n  if (hash === undefined) {\n    throw new Error(\"ctype hash undefined !!!\");\n  }\n\n  const res = await axios.get(`${url}/ctype?${qs.stringify({ id: hash })}`);\n  if (res.status !== 200) {\n    throw new Error(`ctype query failed ${hash}`);\n  }\n  const ctype: CType = res.data.data.rawData;\n  return ctype;\n}\n```\n在本步骤中，我们使用 axios方法向我们的 RESTful API发起 GET请求，将ctype hash作为查询参数请求 ctype对象。\n\n**Step 2: 构建 Raw对象**\n```typescript\nconst raw = new Raw({\n    contents: {\n      id: 9870456,\n      name: \"vss-claimer\",\n    },\n    owner: holderDidUrl,\n    ctype: ctype,\n    hashType: \"Keccak256\",\n});\n```\n在本步骤中，我们构建了一个 Raw对象，该对象用于后续构建 RawCredential使用。下面解释一下各个参数：\n- contents: 对应 ctype构建时要求用户填入的字段\n- owner: claimer，接收该 credential的用户\n- ctype: 对应的 ctype对象\n- hashType: 加密算法类型，此处选择 Keccak256（我们还支持 Blake2、Blake3、RescuePrimeOptimized等加密算法。注意：考虑到 Keccak256的哈希效率在链上最高，因此如果您的 vc使用场景不包括 zk计算，那么建议使用 Keccak256作为构建 Raw时的哈希，否则使用 RescuePrimeOptimized哈希。）\n\n**Step 3: 构建 Raw Credential**\n```typescript\nconst rawCredential: RawCredential = raw.toRawCredential(\"Keccak256\");\n```\n在这一步中，我们基于上一步生成的 Raw对象，调用 `toRawCredential(digestHashType?: HashType)`接口生成 Raw Credential，这一步用到的加密算法默认为 Keccak256（同时我们还支持其他加密算法，与构建 Raw时可用的加密算法一致）。\n\n**Step 4: 构建 vcBuilder**\n```typescript\nconst vcBuilder = VerifiableCredentialBuilder.fromRawCredential(\n    rawCredential,\n    ctype\n  )\n    .setExpirationDate(null)\n    .setIssuanceDate(Date.now());\n```\n在该步骤中，我们构建了一个 vcBuilder对象，后续的 VC可由该 vcBuilder构建。vcBuilder 提供多个方法，对于一般通用型的 VC，一般设置其为永不过期，签发时间设置为当前时间。\n\n**Step 5: 构建 VC**\n```typescript\nconst vc: VerifiableCredential\u003cfalse\u003e = await vcBuilder.build(\n    attester,\n    false\n);\n```\n在该步骤中，我们通过 vcBuilder的 `build(issuer: Did, isPublic?: false)`接口成功的构建了 VC。\n该接口的两个参数需要说明一下：\n- issuer: 一个 DID对象，这里的角色为 issuer，即签发人，一般指某个 attester；\n- isPublic: 当该参数为 `false`时，生成的 VC为 private VC，如果为 `true`则生成 public VC，如果此参数指定为 `false`，则生成的 VC类型为 `VerifiableCredential\u003cfalse\u003e`；一般意义上的 VC均为 private VC，因此默认的VC均指 private VC，考虑到日后某些 VC可以公开，因此我们也设计了可公开的 public VC。\n\n**Step 6: 构建加密 message**\n```typescript\nconst message = await encryptMessage(\n    \"Send_issuedVC\",\n    vc,\n    attester,\n    holder.getKeyUrl(\"keyAgreement\"),\n    undefined,\n    resolver\n  );\n```\n在该步骤中，我们使用 `encryptMessage\u003cT extends MessageType\u003e(type: T, data: MessageData[T], sender: IDidKeyring, receiverUrl: DidUrl, reply?: string, resolver?: DidResolver)`接口生成加密信息，其中在 issue credential过程中会用到以下几个参数：\n- type: 消息类型，issue 对应的消息类型为 “Send_issuedVC”；\n- MessageData: 消息数据，这里指VC；\n- sender: issuer，或者前面构建的 attester；\n- receiverUrl: 用户 DID对应的 keyAgreement类型的 key，该 key在此处用于加密 MessageData；\n- resolver: 环境 DID resolver\n\n**Step 7: 发送加密后的 message至服务器**\n```typescript\nawait sendMessage2Server(message);\n\n// src/utils/messageHelper.ts\nexport async function sendMessage2Server(\n  message: any,\n  templateId = -1,\n  token = null,\n  url = process.env.BASE_URL\n): Promise\u003cvoid\u003e {\n  const sendRes = await axios.post(`${url}/message`, {\n    templateId,\n    msg: message,\n    token,\n  });\n  if (sendRes.status === 200) {\n    console.log(`SUCCESS: send encrypted message to server`);\n  } else {\n    console.log(`send encrypted message response status: ${sendRes.status}`);\n  }\n}\n```\n在该步骤中，我们通过 axios向服务器发送加密后的消息，我们的后端服务在接收到该加密消息后会将消息推送到 card center平台。\n使用该加密通信方式是为了保护用户的 VC隐私，所有经过 zCloak服务器的内容均为加密后的信息；对于发送 VC的情景，只有 claimer (即用户自己)才能解密该 message，zCloak 只做中间邮递人。","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzcloak-network%2Fzkid-sdk-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzcloak-network%2Fzkid-sdk-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzcloak-network%2Fzkid-sdk-example/lists"}