@didit-protocol/sdk-node

中文文档
2.15.0发布于 2026/11/13MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 2323

官方Didit TypeScript和JavaScript库:身份验证(KYC),KYB,AML筛选,活性,交易监控,旅行规则和客户认证从你的后端.

中文使用文档
文档目录18 节
  1. 安装
  2. 快速启动
  3. 配置
  4. 使用 API
  5. 倾斜
  6. 文件
  7. 错误
  8. 检索
  9. 原始回应
  10. 网络呼号
  11. 交易、钱包筛选和旅行规则
  12. 认证
  13. 日志
  14. 支持的运行时间
  15. 语言说明
  16. 版本
  17. 链接
  18. 许可证

Didit 类型脚本 / JavaScript SDK

官方Didit TypeScript和JavaScript库. 身份验证(KYC),业务验证(KYB),AML筛选,生物鉴别,交易监测,出行规则和客户认证,从你的后端.

  • 每个服务器端点 Didit API (英语),带有完整类型,由OpenAPI合同生成.
  • 使用已键入事件进行 Webhook 校验, 以及 Didit 认证符 校验 .
  • 没有运行时间依赖 。 运行在节点.js 18或以后, Bun, Deno 和边缘运行时间 fetch 和网络加密(Cloudflare Workers, Vercel Edge).
  • 无害环境管理和普通JS, TypeScript严格.

安装

npm install @didit-protocol/sdk-node
# or: pnpm add @didit-protocol/sdk-node / yarn add @didit-protocol/sdk-node / bun add @didit-protocol/sdk-node

快速启动

创建一个校验会话,发送用户到其URL,读取决定,并在状态变化时验证webhook Didit发送.

import Didit from "@didit-protocol/sdk-node";

const didit = new Didit(); // reads DIDIT_API_KEY

// 1. Create a session and send the user to session.url.
const session = await didit.sessions.create({
  workflow_id: "11111111-2222-3333-4444-555555555555",
  vendor_data: "user-42",
  callback: "https://example.com/verification/done",
});
console.log(session.url);

// 2. Later, read the decision.
const decision = await didit.sessions.retrieveDecision(session.session_id);
console.log(decision.status, decision.created_at); // "Approved", a Date
// 3. Verify the webhook (Express). Pass the raw body, not parsed JSON.
import express from "express";
import { webhooks, WebhookVerificationError } from "@didit-protocol/sdk-node";

const app = express();
app.post("/webhooks/didit", express.raw({ type: "application/json" }), async (req, res) => {
  // express.raw leaves req.body empty for other content types.
  if (!Buffer.isBuffer(req.body)) return res.status(400).send("expected a JSON body");
  try {
    const event = await webhooks.verify(req.body, req.headers, process.env.DIDIT_WEBHOOK_SECRET!);
    if (event.webhook_type === "status.updated") {
      console.log(event.session_id, event.status);
    }
    res.sendStatus(200);
  } catch (error) {
    if (error instanceof WebhookVerificationError) return res.status(400).send(error.reason);
    throw error;
  }
});

更多可操作的例子,包括快递、快递、Hono、Next.js、Cloudflare Workers、Bun和Deno的网络接收器 examples/。 。 。 .

配置

const didit = new Didit({
  apiKey: "...", // default: DIDIT_API_KEY
  organizationId: "...", // default: DIDIT_ORGANIZATION_ID
  applicationId: "...", // default: DIDIT_APPLICATION_ID
  timeout: 60_000, // milliseconds per attempt
  maxRetries: 2,
});
选项默认页:1
apiKeyDIDIT_API_KEY发送为 x-api-key时,仅改为 baseURL。没有密钥的客户端仍然可以使用 didit.account 并校验网友.
baseURLhttps://verification.didit.me
organizationId, (中文(简体) ), applicationIdDIDIT_ORGANIZATION_ID, (中文(简体) ), DIDIT_APPLICATION_ID需要应用范围的方法(案例、网络、持续监测等);见 日记) (中文(简体) ).
accountBaseURLhttps://apx.didit.me/auth/v2账户管理didit.account) (中文(简体) ).
accountToken无这个 access_token 从 didit.account.login(...)。 。 。 .
timeout60_000毫秒,每次尝试,包括阅读身体.
maxRetries2见 检索。 。 。 .
defaultHeaders无添加到每个请求中. 他们不能取代全权证书(第2段)x-api-key, (中文(简体) ), Authorization) (中文(简体) ).
fetch全球 fetch属于你的 fetch (代,仪也.
fetchOptions无额外 fetch 每个请求的选项,例如undici dispatcherA级 signal 在此取消每个请求.
logLevel, (中文(简体) ), loggerDIDIT_LOG, (中文(简体) ), consoledebug 每个请求记录一行.

环境变量在Node.js、Bun和Deno(与 --allow-env) (中文(简体) ). Cloudflare Workers等边缘运行时间将配置传递给处理器,所以交给客户端: new Didit({ apiKey: env.DIDIT_API_KEY })。 。 。 .

创建一个客户端并重用它 . didit.withOptions({ ... }) 返回带有一些选项的新客户端。 每种方法还把请求选项作为其最后的论点:

await didit.sessions.create(
  { workflow_id },
  {
    timeout: 10_000,
    maxRetries: 0,
    idempotencyKey: "order-123",
    headers: { "X-Trace": "abc" },
    signal,
  },
);

signal 取消请求、其重复和之间的等待; a signal 内 fetchOptions 做同样的.

使用 API

资源和方法遵循API: didit.<resource>.<method>(...),有巢资源,例如 didit.sessions.imports 或者说 didit.cases.notes。 。 。 . 路径参数是位置;其他所有东西都是在一个参数中运行的对象,其字段保留了API的名称(snake case). 日记 以 HTTP 路由和类型列出从 openapi/。 。 。 .

import { fileFromPath } from "@didit-protocol/sdk-node";

await didit.idVerification.verify({ front_image: await fileFromPath("id-front.jpg") });
await didit.aml.screen({ full_name: "Ada Lovelace", date_of_birth: "1815-12-10" });
await didit.users.updateStatus("user-42", { status: "FLAGGED" });
await didit.cases.notes.create(caseUuid, { comment: "Checked with the customer" });

每个请求和响应都有一个类型,从包中导出:

import type {
  SessionsCreateParams,
  SessionsCreateResponse,
  TransactionDetail,
} from "@didit-protocol/sdk-node";

Enums 打开("Approved" | "Declined" | (string & {}): API的附加值后来从未突破你的构建. 以后添加的 API 字段会保存在您收到的对象上 . 可选领域是 ?:; 字段 API 可发送为 null 包含 | null。 。 。 . 日期字段为 Date 对象(没有时区的 API 发送日期- 时间读取为 UTC); 在参数中, 您可以通过一个 Date 或 ISO 8601 字符串.

账户管理 API(组织和应用程序) didit.account数字 :

const { access_token } = await didit.account.login({ email, password });
const account = didit.withOptions({ accountToken: access_token });
const organizations = await account.account.organizations.list();

倾斜

分页列表方法(在 日记返回页与 count, (中文(简体) ), next, (中文(简体) ), previous 财务报告和审定财务报表 results. Iterate with for await 以行走每页的每一行:

for await (const session of didit.sessions.list({ limit: 100 })) {
  console.log(session.session_id);
}

const page = await didit.sessions.list({ limit: 100 });
if (page.hasNextPage()) {
  const next = await page.getNextPage();
}

SDK跟着API的 next 链接并拒绝链接到另一个来源,因此您的 API 密钥永远不会离开 API .

文件

上传参数接受 a Blob 或者说 File页:1 Uint8Array 或者说 ArrayBuffer网络 ReadableStream,如: fs.createReadStream("id.jpg"),或 { data, filename, contentType }。 。 。 . fileFromPath(path) (一) 在Node.js、Bun和Deno上读取文件; toFile(bytes, filename) 名称字节. 无名称的上传发送为 file 加上其内容类型或第一个字节给定的扩展名(file.jpg, (中文(简体) ), file.pdf) (中文(简体) ). 附有文件的请求作为多部分形式数据发送:其中的对象作为JSON文本运行,以及 null 字段被忽略(多块不为空).

二进制响应(会话和用户PDF、网络报告、钱包筛选PDF、导入模板、大小写附件)返回 a Blob数字 :

import { writeFile } from "node:fs/promises";

const pdf = await didit.sessions.generatePdf(sessionId);
await writeFile("report.pdf", new Uint8Array(await pdf.arrayBuffer()));

错误

错误何时
DiditError下面每个错误的基级.
APIConnectionError 编号 : APITimeoutError无响应( 网络失败, 超时) .
APIStatusError任何非-2xx的答复,与 status, (中文(简体) ), body (如果可能的话,分出JSON), headers 财务报告和审定财务报表 requestId。 。 。 .
BadRequestError 400块, AuthenticationError 401 (英语), PermissionDeniedError 403号, NotFoundError 404号, ConflictError 409号, UnprocessableEntityError 422号, RateLimitError 429号, InternalServerError 5 (简体中文)子类 APIStatusError。 。 。 .
APIResponseValidationError2xx 回答 SDK 无法使用(不是 JSON,一个与另一个来源的 pagination 链接).
WebhookVerificationErrorWebhook 验证失败 ; reason 说为什么.
TokenVerificationError验证符号失败 ; reason 说为什么.
ConfigurationError缺少 API 密钥, 组织或应用程序 ID, 一个空的 Webhook 密钥, 一个无效的选项 。 抛出之前,任何东西发送.
import { APIStatusError, NotFoundError } from "@didit-protocol/sdk-node";

try {
  await didit.sessions.retrieveDecision(sessionId);
} catch (error) {
  if (error instanceof NotFoundError) {
    // ...
  } else if (error instanceof APIStatusError) {
    console.error(error.status, error.body, error.requestId);
  } else {
    throw error;
  }
}

API 密钥从不出现在错误消息,日志行或已登录的客户端中.

检索

失败请求被重审到 maxRetries 乘数( 默认 2) , 由 0. 5 s 的指数后退, 满时焦, 封顶为 8 s , 遵守 Retry-After (封顶为60 s. GET, (中文(简体) ), HEAD, (中文(简体) ), PUT 财务报告和审定财务报表 DELETE 在连接错误、超时、408、429和5xx上重审. POST 财务报告和审定财务报表 PATCH 一旦请求可能已经到达服务器,就永远不会再被重审:仅在429年或在发送任何信息之前连接失败.

原始回应

const { data, response, requestId } = await didit.sessions.create({ workflow_id }).withResponse();
const raw: Response = await didit.sessions.generatePdf(sessionId).asResponse(); // unread, for streaming

网络呼号

webhooks.verify(rawBody, headers, secret, options?) 检查签名和时间戳并返回一个已键入的事件; 它扔出 WebhookVerificationError 否则. 该表还作为 didit.webhooks.verify(...)。 。 。 .

  • rawBody: 确切的身体字节(a) Buffer, (中文(简体) ), Uint8Array, (中文(简体) ), ArrayBuffer 或字符串)。 配置您的框架, 以赋予您原始的身体 .
  • headers(单位:千美元) Headers 对象,节点.js req.headers,或 [name, value] 双人.
  • secret:目的地的秘密,或旋转时的秘密清单.
  • options.tolerance: 交货时间戳与现在之间的秒(默认为300).

它有三种标志: X-Signature (生的躯体), X-Signature-V2 (一种能活过重编码JSON的中件的Canonic JSON形式)和被腐烂的 X-Signature-Simple; 在秘密旋转时 -Previous 变体与旧密相签. 任何前两个,有 任何一个秘密,被接受.

const event = await webhooks.verify(rawBody, headers, [currentSecret, previousSecret]);
switch (event.webhook_type) {
  case "status.updated":
  case "data.updated":
    console.log(event.session_id, event.status, event.decision?.status);
    break;
  case "transaction.status.updated":
    console.log(event.transaction_id, event.status, event.score);
    break;
  default:
    console.log("unhandled event", event.webhook_type);
}

活动是受歧视的工会 webhook_type: 会 议status.updated, (中文(简体) ), data.updated),用户,业务,交易和旅行规则事件, activity.created, (中文(简体) ), workflow.compliance_changed, (中文(简体) ), kyb.registry_search.resolved,以及 UnknownEvent 用于任何其他类型. 每次活动也都有 event.verifiedBy (签名匹配)和 event.bodyAuthenticated。 。 。 . 该活动是所发送的机构,但会议 decision 是生成的决定类型,所以日期时间是 Date 对象.

KYB 注册检索回调( E)kyb.registry_search.resolved)今天未签署(X-Didit-Unsigned-Callback: true),这样 verify 拒绝它 missing_signature。不要信任它的身体:用它的 request_id 换句话说.

如果你的框架只给你解剖过的JSON身体, webhooks.verifyParsed(payload, headers, secret) 检查 X-Signature-V2 2^53以上的整数失败 JSON.parse 已经四舍五入。 偏取生体相. X-Signature-Simple 只签信封,不签尸体;它被接受 { allowSimple: true },然后则 event.bodyAuthenticated 实值 false:在采取行动之前,从API中重排记录.

交易、钱包筛选和旅行规则

const txn = await didit.transactions.create({
  transaction_id: "txn-1001",
  transaction_category: "finance",
  transaction_details: { direction: "outbound", amount: 2500, currency: "EUR" },
  subject: { vendor_data: "user-42", full_name: "Ada Lovelace" },
});
console.log(txn.status, txn.score); // "APPROVED" | "IN_REVIEW" | "DECLINED" | ...

const screening = await didit.walletScreening.screen({
  wallet_address: "0x...",
  blockchain: "ETH",
});
for await (const rule of didit.transactions.rules.list()) console.log(rule.title, rule.mode);
const settings = await didit.travelRule.retrieveSettings();
const vasps = await didit.travelRule.listVasps({ limit: 20 });

这个 transaction.created, (中文(简体) ), transaction.status.updated 财务报告和审定财务报表 travel_rule.status.updated webhooks是被键入的事件.

认证

Didit认证给每个应用程序自己的OpenID Connect发行器,供终端用户使用. 这个 Authentication 帮助者验证它标记的ES256符号,并从后端调取它的符号,会话和起步端点. 它从来不用你的API密钥.

import { Authentication, TokenVerificationError } from "@didit-protocol/sdk-node";

const auth = Authentication.fromPublishableKey(process.env.DIDIT_PUBLISHABLE_KEY!, {
  clientId: process.env.DIDIT_APPLICATION_ID!,
});
// or: new Authentication({ issuer: "https://acme.auth.didit.me", clientId: "<application id>" })

try {
  const claims = await auth.verifyAccessToken(accessToken);
  console.log(claims.sub, claims.org?.role);
} catch (error) {
  if (error instanceof TokenVerificationError)
    console.log(error.reason); // e.g. "expired"
  else throw error;
}
  • 选项 : issuer (或可公布的密钥), clientId (应用程序编号:默认受众,并作为 client_id 以符号结尾, leeway (秒,默认为60), timeout (每期发行人申请毫升,默认为一万元), fetch, (中文(简体) ), logLevel, (中文(简体) ), logger。 。 。 .
  • verifyAccessToken(token, { audience? }) 财务报告和审定财务报表 verifyIdToken(token, { nonce, audience? }):仅ES256;发行者,观众,到期后,不在并发后使用60s回放. 密钥出自发行人的JWKS,当新密钥出现后被缓存并刷新. 过 nonce: null 当没有寄出非ce时(从 refresh;然后,标志必须携带一无所有。 用于某人的代理工具还验证: act 声称是代理人.
  • createPkce(), (中文(简体) ), createState() 财务报告和审定财务报表 createNonce() 属于独立职能(import { createPkce } from "@didit-protocol/sdk-node"用于授权代码流;然后 auth.exchangeCode({ code, codeVerifier, redirectUri })。 。 。 .
  • refresh(refreshToken):一个会话的序列式刷新;重新使用已消耗的刷新令牌取消会话.
  • getSession(accessToken) 即时撤销检查, revokeSession(accessToken)。 。 。 .
  • createStepUp(accessToken, { action, amount?, currency?, returnTo? }) 财务报告和审定财务报表 retrieveStepUp(accessToken, id): 只按地位行事 approved。当前需要 returnTo 并回答400没有它.
  • submitAgentConsent(accessToken, { challenge, decision, assertion?, scopes?, organizationIds?, lifetime? }) 批准或拒绝代理请求(核准返回) { code, redirect_uri, state },拒绝 { status: "denied" }; 测试 "code" in result和 createAgentApprovalOptions(accessToken, { challenge }) 返回 WebAuthn 数据 options 仅限人类申请的新密码(403) passkey_required 没有它。 也没有经过复审;质疑和断言从未记录在案.

认证在早期进入,随着2026-11-01 Didit发行而达到生产.

日志

设定 DIDIT_LOG=debug (或 logLevel: "debug")以每HTTP请求记录一行:方法,路径,状态,持续时间和请求id. 机构,信头,查询字符串和证书从未被记录.

支持的运行时间

运行时间版本数
节点.js第18、20、22、24条
阿宝1.x 运算
德诺2.x 数据
边缘运行时间Cloudflare工人、Vercel Edge和其他运行时间 fetch,网络加密和网络流

CI运行着每个Node.js版本的测试套件,并在Node.js 18, Bun, Deno 和workd(Cloudflare Workers runtime)上运行了已建成的套件的烟雾测试.

SDK拒绝将您的 API 密钥发送到除了 API 以外的任何地方,但它是一个服务器侧库: 永远不要将您的 API 密钥传送到浏览器 .

语言说明

SDK的选择是共享设计留给每种语言:

  • 名称. 资源和方法为骆驼 Case(第1款)didit.idVerification.verify, (中文(简体) ), retrieveDecision); 请求和响应字段保留API的蛇名 case name. 类似正文字段命名的查询参数需要 _query 参数对象中的后缀(node_id_query) (中文(简体) ). SDK添加的字段为骆驼Case: requestId 关于错误和原始答复, verifiedBy 财务报告和审定财务报表 bodyAuthenticated 在网络上的活动.
  • 选项. 选项是对象,而不是位置参数 : new Didit({ apiKey }), (中文(简体) ), new Authentication({ issuer }), (中文(简体) ), verifyIdToken(token, { nonce, audience }), (中文(简体) ), exchangeCode({ code, codeVerifier, redirectUri }), (中文(简体) ), createStepUp(token, { action, ... })设计 http_client 这是 fetch 选项(加) fetchOptions(三); logLevel 财务报告和审定财务报表 logger 选择调试行去向。 在边缘运行时,通过API键作为选项(环境变量只在Node.js,Bun和Deno上被读取).
  • 错误. APITimeoutError 扩展 APIConnectionError。 。 。 . TokenVerificationError (核证)和 APIResponseValidationError (a 2xx 回答 SDK 无法使用) 完成设计表.
  • 时代. timeout 以毫秒为单位; webhook tolerance 和认证 leeway 几秒钟,就像他们比对的时间戳.
  • 约会. 答复日期 Date 对象,保持毫秒精度(API发送微秒);没有时区的一个读取为UTC. 只约会字段( O)format: date留下来 YYYY-MM-DD 字符串。 Webhook事件和认证主张是JSON有效载荷的发送,所以它们的时间戳是数字或字符串,除了会话事件 decision,是生成的决定类型 Date 对象.
  • Async (英语). 每个API方法, webhooks.verify 认证帮助者返回承诺(Web Crypto是同步的). createPkce, (中文(简体) ), createState 财务报告和审定财务报表 createNonce 也是因为同样的原因.
  • 结果. 方法返回 a APIPromise:等待数据,或打电话 .withResponse() 编号 : .asResponse()。 。 。 .
  • 缺席而无所取. 可选领域是 ?:; 无效字段添加 | null; 离开的字段 undefined 未发送.
  • 大整数. 在生体上检查Webhook的签名, 并用一个解析器来保存每个数字的位数, 因此2^53以上的整数被精确验证 。 您返回的已键入事件解析 JSON.parse就像每个反应.
  • 常见JS. const { Didit } = require("@didit-protocol/sdk-node");无害环境管理默认出口也是 require(...).default。 。 。 .
  • 档案. 路径读取方式 fileFromPath(path);其他的都以字节, Blob 或一行来传递.
  • 客户端头. User-Agent: didit-node/<version> (<runtime> <version>; <os>) 财务报告和审定财务报表 X-Didit-Client: node/<version>,在寄存器名称之后,在每次运行时间.

版本

此软件包随后 语义版本中,每个 Didit 服务器 SDK 共享一个 API 更改规则(文件/DESIGN.md 第13节:

  • 反射 Didit API 的更改是一个次要版本,即使它可以打破打入的代码: 类型更改,一个字段现在可以是无效的,或者一个已删除的字段,操作或enum值. API已经对每个呼叫者都这样了,所以这个软件包的更老版本并不安全. 发行注释在"API更改可以打出代码"下列出此类更改.
  • 一个主要版本仅用于更改SDK自己的设计:重命名或去除API仍然拥有的一种方法或资源,改变客户端配置,出错,重试,页码或webhook校验,或丢弃所支持的运行时版本.
  • API更新,只更改文档不会单独发布任何内容.

版本编号是本套件自有:在更早的规则下于2026-11-05被移动到 2.x,并从那里继续. 释放和 CHANGELOG.md 由常规承诺释放产生. 当API去掉或重命名一个端点时,SDK保留了旧方法为再一个小版本的去皮.

许可证

麻省理工学院

版本与发布记录

@didit-protocol/sdk-node 共发布 21 个版本,首次发布于 2026/10/29;过去 12 个月发布了 21 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.15.0latest2026/11/13今天
2.14.02026/11/13今天
2.13.12026/11/121 天前
2.13.02026/11/112 天前
2.12.02026/11/112 天前
2.11.12026/11/112 天前

关于 @didit-protocol/sdk-node 的常见问题

@didit-protocol/sdk-node 是什么?

官方Didit TypeScript和JavaScript库:身份验证(KYC),KYB,AML筛选,活性,交易监控,旅行规则和客户认证从你的后端.

如何安装 @didit-protocol/sdk-node?

在项目目录运行 npm install @didit-protocol/sdk-node,或使用 pnpm add / yarn add / bun add。

@didit-protocol/sdk-node 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@didit-protocol/sdk-node 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@didit-protocol/sdk-node 需要什么版本的 Node.js?

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

@didit-protocol/sdk-node 可以商用吗?

@didit-protocol/sdk-node 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@didit-protocol/sdk-node 的下载量有多少?

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

@didit-protocol/sdk-node 还在维护吗?

最新版本 2.15.0 发布于 2026/11/13(今天);至今共发布 21 个版本,其中过去 12 个月发布了 21 个;首次发布于 2026/10/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。