{"_id":"@caict-bif/bid-typescript-sdk","_rev":"2-f23ea71e14c65c65befc94a0cf13d608","name":"@caict-bif/bid-typescript-sdk","dist-tags":{"latest":"1.0.0"},"versions":{"0.1.0":{"name":"@caict-bif/bid-typescript-sdk","version":"0.1.0","_id":"@caict-bif/bid-typescript-sdk@0.1.0","maintainers":[{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"}],"dist":{"shasum":"50288d92c6334449b5c04cacb682a98798b2782e","tarball":"https://registry.npmjs.org/@caict-bif/bid-typescript-sdk/-/bid-typescript-sdk-0.1.0.tgz","fileCount":62,"integrity":"sha512-80p4BqRrGhk+GFyfHu606wIre2Ua3R4mkcmfBMB2ljActMfmc9MvLA7wE7ht/D2v11vRvJx79GClS5EMEdrNGg==","signatures":[{"sig":"MEQCIEAFoehlZCyVwj1U5488AtcmsCLJyURUj0oqSEroSAWTAiB688ToXRECFMIx7fmMKSb9e53PvTLeQX4no/PE6a4/1Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":117047},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"65ae0c5aa15aef4ee059e0881c8ca898b8a3c6cf","scripts":{"test":"node --import tsx --test test/bid-document-builder.test.ts test/bid-sdk.test.ts test/direct-writer.test.ts test/keypair.test.ts test/payload.test.ts test/parser-reader.test.ts test/transaction-failure.test.ts test/transaction-options.test.ts","build":"tsc --project tsconfig.build.json","check":"npm run typecheck && npm test","sample":"tsx sample/bif-usage.ts","typecheck":"tsc --noEmit","sample:bop":"tsx sample/bop-usage.ts"},"_npmUser":{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"},"_npmVersion":"10.8.2","description":"BID document SDK for Xinghuo BIF","directories":{},"_nodeVersion":"20.20.2","dependencies":{"zod":"^4.0.1","@caict-bif/bif-encryption":"^1.2.2","@caict-bif/bif-typescript-sdk":"^0.1.1","@caict-bif/bop-typescript-sdk":"^1.1.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"~5.7.0","@types/node":"^20.17.0"},"_npmOperationalInternal":{"tmp":"tmp/bid-typescript-sdk_0.1.0_1786902726498_0.19143110031109178","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@caict-bif/bid-typescript-sdk","version":"1.0.0","description":"BID document SDK for Xinghuo BIF","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./mobile":{"types":"./dist/vc/mobile.d.ts","default":"./dist/vc/mobile.js"},"./config":{"types":"./dist/config.d.ts","default":"./dist/config.js"},"./vc":{"types":"./dist/vc/index.d.ts","default":"./dist/vc/index.js"},"./dist/vc/mobile.js":{"types":"./dist/vc/mobile.d.ts","default":"./dist/vc/mobile.js"},"./package.json":"./package.json"},"engines":{"node":">=20"},"scripts":{"build":"tsc --project tsconfig.build.json","typecheck":"tsc --noEmit","test":"node --import tsx --test test/bid-document-builder.test.ts test/bid-sdk.test.ts test/direct-writer.test.ts test/keypair.test.ts test/payload.test.ts test/parser-reader.test.ts test/sdk-config.test.ts test/transaction-failure.test.ts test/transaction-options.test.ts","test:vc":"node --import tsx --test test/vc-jws.test.ts test/vc-platform-auth.test.ts test/vc-roles.test.ts test/vc-verifier.test.ts test/vc-local-protocol.test.ts test/vc-trust.test.ts test/vc-disclosure.test.ts test/vc-flow.test.ts test/vc-interop-vector.test.ts test/vc-mobile.test.ts test/vc-presentation.test.ts","typecheck:vc":"tsc --project tsconfig.vc.json","check:vc":"npm run typecheck:vc && npm run test:vc","sample:holder":"node --env-file=.env.holder --import tsx sample/holder.ts","sample:issuer":"node --env-file-if-exists=.env.issuer --import tsx sample/issuer.ts","sample:verifier":"node --env-file-if-exists=.env.verifier --import tsx sample/verifier.ts","sample:verifier-bop":"node --env-file-if-exists=.env.verifier --import tsx sample/verifier-bop.ts","sample":"node --env-file=.env --import tsx sample/usage.ts","check":"npm run typecheck && npm test"},"dependencies":{"@caict-bif/bif-encryption":"^1.2.2","@caict-bif/bif-typescript-sdk":"^0.2.0","@caict-bif/bop-typescript-sdk":"^1.2.0","brdc-sm-crypto":"^0.3.7","canonicalize":"^4.0.0","zod":"^4.0.1"},"devDependencies":{"@types/node":"^20.17.0","tsx":"^4.19.2","typescript":"~5.7.0"},"_id":"@caict-bif/bid-typescript-sdk@1.0.0","gitHead":"bf2489e4e25d5a649e1fc46f3ac69f0f5f847e87","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-GLtgZ7FIvs2ETZX262BBZGzWmjiMtGuXpOacVqZDyNJz+DM7ByvuyeWzALIC8N9j6ZsQTU5XtD1XHvU20vt4lA==","shasum":"361bc75977b7a73d1220b95b768d0c924eb665c7","tarball":"https://registry.npmjs.org/@caict-bif/bid-typescript-sdk/-/bid-typescript-sdk-1.0.0.tgz","fileCount":116,"unpackedSize":350070,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDtBcuXba7Z0wSNjyRKp3QOLLF9tqAfMfWl2QCJAWSeWgIhALSvCppLHBY2i2m0YmpTNJYJiuPUCImrmIsBFxKk7ba4"}]},"_npmUser":{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"},"directories":{},"maintainers":[{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/bid-typescript-sdk_1.0.0_1789303838738_0.18737462450747766"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-16T17:52:06.338Z","modified":"2026-09-13T12:50:39.079Z","0.1.0":"2026-08-16T17:52:06.645Z","1.0.0":"2026-09-13T12:50:38.881Z"},"description":"BID document SDK for Xinghuo BIF","maintainers":[{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"}],"readme":"# BID TypeScript SDK\n\n星火链 BID（去中心化身份标识）TypeScript SDK，覆盖密码学、DID 文档与可验证凭证（VC）三角色（发证方、持证方、验证方）。链上操作统一经开放平台（BOP）同步完成。\n\n```bash\nnpm install @caict-bif/bid-typescript-sdk\n```\n\n- 依赖会一并安装：`@caict-bif/bif-encryption`（密码学）、`@caict-bif/bop-typescript-sdk`（开放平台），无需额外配置。\n- 要求 Node >= 20。\n- 入口：主包 `@caict-bif/bid-typescript-sdk`（全量能力）；`@caict-bif/bid-typescript-sdk/mobile`（App 轻量核验入口，见第六节）。\n\n## 一、快速开始\n\n应用启动时先配置节点与平台地址，再创建 SDK 实例；密钥生成与 DID 文档构建可离线使用，写链、解析和 VC 操作前需要 `connect()`：\n\n```ts\nimport { configureBidSdk, createBidSdk } from \"@caict-bif/bid-typescript-sdk\"\n\nconfigureBidSdk({\n  bopUrl: \"https://你的开放平台地址\",\n  parserUrl: \"https://你的解析服务地址/bid/\",\n  vcPlatformUrl: \"https://你的VC钱包平台主机根地址\",   // 不要包含 /server\n  vcCredentialUrl: \"https://你的VC凭证平台地址\",        // 与钱包平台同域时可省略\n  vcVerificationUrl: \"https://你的VC验证服务地址\",\n})\n\nconst sdk = createBidSdk()\nsdk.connect({\n  mode: \"bop\",\n  apiKey: \"你的开放平台 API Key\",\n  apiSecret: \"\",          // 没有 API Secret 时保持空值\n})\n```\n\n- 星火链域名的证书链可能不被 Node 内置 CA 信任。生产环境请通过 `NODE_EXTRA_CA_CERTS` 提供证书链；本机联调可临时设置 `NODE_TLS_REJECT_UNAUTHORIZED=0`，不要在代码里默认关闭证书校验。\n- 写链源账户必须在链上激活且有燃料费（星火令）余额，否则错误信息会提示去开放平台领取/激活。\n\n## 二、密码学：公私钥与助记词\n\n密钥算法支持 ED25519 与 SM2（国密），私钥/公钥均为星火编码格式（`priSPK...` / `b0656...`），可直接用于签名、验签与身份地址推导。\n\n### 生成密钥对\n\n```ts\nconst identity = sdk.keypair.generate()\n// { privateKey: \"priSPK...\", publicKey: \"b0656...\", address: \"did:bid:ef...\" }\n```\n\n### 签名与验签\n\n```ts\nconst signer = sdk.keypair.signer(identity.privateKey)\nconst signature = signer.sign(\"deadbeef\")                 // 对 hex 消息签名\nconst ok = signer.verify(\"deadbeef\", signature)           // 本地验签\n```\n\n### 助记词（HD 派生）\n\n```ts\nimport * as enc from \"@caict-bif/bif-encryption\"\nimport { createEncSigner } from \"@caict-bif/bid-typescript-sdk\"\n\n// 生成 12 词助记词（entropy 为 16 字节随机数的 hex）\nconst mnemonic = enc.generateMnemonicCode(\"0123456789abcdef0123456789abcdef\")\n\n// 按硬化派生路径导出私钥（ED25519 要求全硬化路径）\nconst privateKey = enc.privateKeyFromMnemonicCode(mnemonic, \"m/44'/526'/1'/0'/0'\")\nconst signer = createEncSigner(privateKey)\nsigner.address    // did:bid:ef...  同一助记词 + 同一路径推导结果恒定\n```\n\n### 密钥格式转换与 Keystore\n\n```ts\n// 星火编码 <-> 原始 hex（跨系统对接时使用）\nconst raw = sdk.keypair.convert.toRawPrivateKey(identity.privateKey, \"ED25519\")\nconst back = sdk.keypair.convert.toEncPrivateKey(raw.keyHex, \"ED25519\")\n\n// Keystore（密码加密的私钥文件）解密，密码错误会直接报错\nconst privateKey = sdk.keypair.keystore.toPrivateKey(keystoreJson, password)\n```\n\nSDK 不保存助记词、私钥或密码；密钥材料由调用方妥善保管，不要提交到代码仓库。\n\n## 三、DID：文档构建与链上操作\n\nBID 是星火链上的 DID 标识（`did:bid:ef...`）。DID 文档（DDO）描述该身份的公钥、认证方式与服务端点，上链后可被解析。\n\n### 构建文档\n\nbuilder 按字段构建，未设置的字段自动使用默认值（`@context=[\"https://www.w3.org/ns/did/v1\"]`、`version=\"1.0.0\"`、`extension.ttl=86400`、`extension.type=206`、`created/updated`=当前 UTC 时间）：\n\n```ts\nconst document = sdk.document\n  .create(identity.address)\n  .addPublicKey({\n    id: `${identity.address}#key-1`,\n    type: \"Ed25519\",\n    controller: identity.address,\n    publicKeyHex: identity.publicKey,\n  })\n  .addAuthentication(`${identity.address}#key-1`)\n  .addRecovery(`${identity.address}#key-1`)\n  .build()\n```\n\n- `publicKey`、`authentication`、`service` 是数组，可多次 `add*` 追加；追加 context 用 `.addContext(...)`，自定义扩展字段用 `.setExtensionField(...)`。\n\n### 上链与解析\n\n写链需要链上已激活、有余额的账户，私钥只在单次交易里传入；交易同步提交并等待确认：\n\n```ts\nconst transaction = { privateKey: \"已激活账户私钥\" }\n\nconst created = await sdk.bid.create(document, transaction)\nconsole.log(created.id)         // 交易 hash\nconsole.log(created.transport)  // \"bop\"\n\nawait sdk.bid.update(document, transaction)\nawait sdk.bid.reAuth({ id: identity.address, authentication: [`${identity.address}#key-1`], transaction })\n\nconst resolved = await sdk.bid.resolve(identity.address)   // 读取 DID 文档\n```\n\n- `feeLimit`、`gasPrice` 有默认值（1_000_000 / 1），需要调整时在单次交易里覆盖：`{ privateKey, feeLimit: 2_000_000 }`。\n- `resolve()` 读取 BID 文档：配置了 `parserUrl` 时使用解析服务，否则直接对 DDO 合约执行 `queryBid`。\n- 当前合约没有删除方法，SDK 也不提供删除接口。\n\n### 写链账户与文档权限\n\n`update` 要求签名账户在文档 `authentication` 中；`reAuth` 要求签名账户在 `extension.recovery` 中或就是文档 id 本身。权限不符时错误信息会直接提示\"当前账户无权执行该操作\"。\n\n## 四、发证方（Issuer）\n\n发证方身份需已在平台完成注册（准入流程在 SDK 之外）。签发/撤销/建模板都会产生链上合约交易，由平台预构建（`bcTxBlob`）→ 发证方本地签名授权 → 平台广播上链；燃料费记在发证方账户上，账户需保持激活、有星火令余额。\n\n```ts\nconst platform = sdk.vc.platform.create({ routes: ISSUER_PORTAL_ROUTES })\nconst issuer = sdk.vc.issuer.create(platform)\n\n// 登录：两步（平台 BID 挑战登录 → 门户令牌交换，SDK 内部完成）\nconst session = await platform.loginAsIssuerPortal({ bid: signer.address, signer })\n\n// 查询名下申请：status=1 待审核 / 2 已签发 / 3 已拒绝\nawait issuer.listApplications(session, { status: [1], pageStart: 1, pageSize: 20 })\n\n// 申请详情（content 为持证方填写的表单，可透传为签发 auditContent）\nawait issuer.getApplicationDetail(session, { applyNo: \"...\" })\n\n// 签发：blob → 本地签名 → submit，返回凭证 BID（certBid）\nconst issued = await issuer.issue(session, {\n  issuer: { bid: signer.address, signer },\n  applyNo,\n  status: 2,\n  auditContent,          // 通常透传申请详情的 content\n})\n\n// 拒绝申请（无链上交易）\nawait issuer.reject(session, { issuer: { bid: signer.address, signer }, applyNo })\n\n// 创建模板（需超级节点审核通过后持证方才能申请）\nawait issuer.createTemplate(session, {\n  issuer: { bid: signer.address, signer },\n  name: \"身份凭证\", industryId: \"A\", categoryId: \"socialCertification\",\n  version: \"1.0.0\", userType: \"0\",\n  data: JSON.stringify([{ key: \"name\", label: \"姓名\", type: \"2\", format: \"String\", value: \"\" }]),\n})\nawait issuer.listTemplates(session, { pageStart: 1, pageSize: 20 })   // auditStatus 0/1/2\n\n// 撤销（从签发记录取 credentialBid）\nawait issuer.revoke(session, { issuer: { bid: signer.address, signer }, credentialBid: issued.credentialId! })\n\n// 字典（建模板需要 industryId / categoryId）\nawait issuer.listIndustries(session)\nawait issuer.listCategories(session)\n```\n\n角色 CLI（真实环境完整流程）：\n\n```bash\nnpm run sample:issuer -- login        # 登录自检\nnpm run sample:issuer -- industries   # 行业字典\nnpm run sample:issuer -- categories   # 凭证类别字典\nnpm run sample:issuer -- template --name=身份凭证 --industry-id=A --category-id=socialCertification\nnpm run sample:issuer -- templates    # 名下模板列表（auditStatus：0 待审/1 通过/2 拒绝）\nnpm run sample:issuer -- pending      # 待审核申请（拿 applyNo）\nnpm run sample:issuer -- approve --apply-no=<申请编号>\nnpm run sample:issuer -- reject --apply-no=<申请编号>\nnpm run sample:issuer -- issued       # 已签发列表\nnpm run sample:issuer -- revoke [--credential=<凭证BID>]\n```\n\n配置在 `.env.issuer`（复制自 `.env.issuer.example`）：`VC_ISSUER_PRIVATE_KEY`（发证方自己的私钥）、`VC_PLATFORM_BASE_URL`（登录主机，不含 `/server`）、`VC_CREDENTIAL_BASE_URL`（门户业务主机）。签发记录保存在 `sample/output/issuer-issuances.json` 供撤销使用。完整实战细节见 [持证方 sample 实战指南](docs/holder-sample-guide.md)。\n\n## 五、持证方（Holder）\n\n持证方只依赖 VC 平台 HTTP 接口（登录、推荐列表、申请、状态、下载、导出），不写链。\n\n```ts\nconst platform = sdk.vc.platform.create()\nconst holder = sdk.vc.holder.create(platform)\nconst session = await platform.login({ bid: signer.address, signer })\n\n// 查询可申请凭证（SDK 固定查询 type=2 持证方普通凭证）\nawait holder.listRecommendedCredentials(session, { pageStart: 1, pageSize: 20 })\n\n// 申请：subject 用模板通用的 attributes 结构\nconst applyNo = await holder.applyCredential(session, {\n  templateId: \"did:bid:ef...\",\n  subject: {\n    attributes: [\n      { key: \"name\", label: \"姓名\", type: \"2\", format: \"String\", value: \"张三\" },\n    ],\n  },\n})\n\n// 进度（1 申请中 / 2 已通过 / 3 已拒绝；2 时返回 credentialId）\nawait holder.getApplicationStatus(session, applyNo)\n\n// 下载与解析\nconst downloaded = await holder.downloadCredential(session, { credentialId })\nconst parsed = holder.parseCredential(downloaded.jws)\n```\n\n角色 CLI：\n\n```bash\nnpm run sample:holder -- generate    # 生成持证方密钥并保存身份文件\nnpm run sample:holder -- list        # 可申请凭证列表\nnpm run sample:holder -- apply --template-id=<模板ID> --subject='{...attributes...}'\nnpm run sample:holder -- status\nnpm run sample:holder -- download\nnpm run sample:holder -- export      # 导出标准 VC 出示信封（demo.json 同款）\n```\n\n- 配置在 `.env.holder`（复制自 `.env.holder.example`）：只需 `VC_PLATFORM_BASE_URL`。\n- `--subject` 必须是非空 JSON 对象；Windows PowerShell 下 JSON 引号会被 npm run 剥掉，需直接执行 `node --env-file=.env.holder --import tsx sample/holder.ts apply ...`（见实战指南）。\n- 身份/申请/凭证文件都在 `sample/output/`（已被 gitignore），不要提交私钥。\n- 完整流程（含 App 实现边界）见 [持证方 sample 实战指南](docs/holder-sample-guide.md)。\n\n## 六、验证方（Verifier）\n\n验证方独立核验凭证：读 DDO 合约取发行方公钥验签、查 IAM/TDS 合约信任名单、查询发证方平台撤销状态、校验选择性披露——不依赖平台自证。\n\n```ts\n// 方式一：SDK facade（复用 configureBidSdk + connect 配置）\nconst result = await sdk.vc.verifier.verifyCredential({ jws })\n// { verified, checks: { format, issuerTrust, issuerSignature, validity, disclosure, revocation }, errors }\n\n// 方式二：App 轻量入口（React Native / 浏览器，不加载写链与开放平台依赖）\nimport { createDirectVcVerifier } from \"@caict-bif/bid-typescript-sdk/mobile\"\n\nconst verifier = createDirectVcVerifier({\n  directNodeUrl: \"https://bif.example.com\",\n  vcRevocationUrl: \"https://vc-issuer.example.com\",\n  fetcher: fetch,   // RN 传入网络层 fetch\n})\nconst result = await verifier.verifyCredential({ jws })\n```\n\n- 撤销检查是在线 issuer-service 状态，不是独立的链上状态证明。\n- 出示信封（export 输出的 JSON）会先校验外层字段与 `proof.jwt` 内 JWS payload 一致，任一字段被篡改即返回 `presentation-mismatch` 终止验证。\n\n角色 CLI（BOP 传输）：\n\n```bash\nnpm run sample:verifier-bop -- --file=sample/output/holder-presentation.json\n```\n\n配置在 `.env.verifier`（复制自 `.env.verifier.example`）：`BID_BOP_URL`、`BID_BOP_API_KEY`、`BID_BOP_API_SECRET`、`VC_REVOCATION_BASE_URL`。输出 `{ verified, checks, errors }`，验证不通过时以非零状态退出。\n\n## 开发验证\n\n```bash\nnpm run check        # typecheck + 全量单测\nnpm run check:vc     # VC 模块 typecheck + 测试（覆盖三角色流程，不需要真实链节点）\nnpm run build\n```\n\n真实环境示例：`npm run sample:issuer -- login`、`npm run sample:holder -- list`（需先填好对应 `.env.*` 凭据）。\n","readmeFilename":"README.md"}