跳到主要内容

请求声明

在 DID Connect 会话中,“声明”是你向用户钱包请求的特定信息或操作。这可以是任何内容,从他们的姓名和电子邮件,到证明资产所有权的加密签名。本指南将引导你了解向用户请求声明的不同方式。

所有声明请求都在 handlers.attach 方法的 claims 属性中配置。有关可用声明类型及其参数的完整列表,请参阅声明参考

请求单个声明

最直接的用例是请求单条信息。你定义一个 claims 对象,其中每个键代表你想要请求的特定声明。该值通常是一个返回声明定义对象的函数。

例如,要请求包含用户全名和电子邮件的个人资料,你可以按如下方式配置:

Basic Profile Claim

javascript
handlers.attach({
  action: 'profile',
  claims: {
    // 键 'profile' 指定了声明类型。
    // 值是一个返回声明参数的函数。
    profile: () => ({
      fields: ['fullName', 'email'],
      description: '请提供您的姓名和电子邮件以继续',
    }),
  },

  onAuth: async ({ userDid, claims }) => {
    // 'claims' 数组包含用户提交的数据。
    try {
      const profile = claims.find((x) => x.type === 'profile');
      console.info('login.success', { userDid, profile });
    } catch (err) {
      console.error('login.error', err);
    }
  },
});

在此示例中,我们请求了一个 profile 声明。钱包将提示用户分享他们的全名和电子邮件。一旦用户批准,onAuth 回调将在 claims 数组中收到提交的信息。

请求多个声明

DID Connect 允许你在单个会话中请求多条信息,这非常高效。根据声明是不同类型还是相同类型,有两种方法可以实现。

多个不同类型的声明

要一次请求几种不同类型的声明,只需向 claims 对象添加更多的键值对。例如,你可以在同一个会话中请求用户的个人资料和特定资产的所有权证明。

Multiple Different Claims

javascript
handlers.attach({
  action: 'multiple-claims',
  claims: {
    profile: () => ({
      fields: ['fullName', 'email'],
      description: '请提供您的姓名和电子邮件以继续',
    }),
    asset: ({ userDid, extraParams }) => {
      // asset 声明可以是一个函数,用于动态设置参数
      return {
        description: '请证明您拥有一个有效的 NFT',
        trustedIssuers: ['z1...', 'z2...'], // 可选:按受信任的 NFT 发行方进行筛选
      };
    },
  },
  onAuth: async ({ claims, userDid }) => {
    // `claims` 是一个数组,包含个人资料和资产声明的结果。
    const profile = claims.find(c => c.type === 'profile');
    const asset = claims.find(c => c.type === 'asset');
    console.log({ userDid, profile, asset });
  },
});

多个相同类型的声明

如果你需要请求多个相同类型的声明(例如,要求用户签署两条不同的消息),你需要使用稍微不同的语法。你为每个请求使用一个唯一的键,并提供声明类型及其定义作为一个双元素数组。

以下是如何请求两个不同的 signature 声明:

Multiple Same-Type Claims

javascript
handlers.attach({
  action: 'multiple-signatures',
  claims: {
    // 'signText' 是此特定请求的唯一标识符。
    signText: [
      'signature', // 第一个元素是作为字符串的声明类型。
      {          // 第二个元素是声明定义对象。
        type: 'mime:text/plain',
        data: '我同意服务条款。',
        description: '请签署文本以继续',
      },
    ],
    // 'signHtml' 是另一个唯一标识符。
    signHtml: [
      'signature',
      {
        type: 'mime:text/html',
        data: `<h2>交易摘要</h2><p>金额:100 ABC</p>`,
        description: '请签署以确认交易',
      },
    ],
  },
  onAuth: async ({ claims, userDid }) => {
    // `claims` 将包含两个签名请求的结果。
    console.log('用户已签署消息:', claims);
  },
});

动态声明

在某些情况下,你需要请求的信息取决于用户是谁。例如,你可能只想在用户之前没有提供过 KYC(了解你的客户)凭证时才请求该凭证。这可以通过使用 onConnect 生命周期回调的动态声明来实现。

onConnect 回调在用户扫描二维码并在其钱包中选择一个 DID 之后,但在声明发送给他们之前运行。这使你可以访问用户的 DID(userDid)来执行业务逻辑。

Dynamic Claims with onConnect

javascript
handlers.attach({
  action: 'dynamic-claims',

  // 此函数在钱包连接后、请求声明前运行。
  onConnect: async ({ userDid }) => {
    // 示例:检查用户是否需要提供个人资料。
    const userExists = await checkUserInDatabase(userDid);

    if (!userExists) {
      // 返回一个声明对象以请求所需信息。
      return {
        profile: () => ({
          fields: ['fullName', 'email'],
          description: '请创建您的个人资料以继续',
        }),
      };
    }

    // 如果不需要声明,则返回 null 或空对象。
    return {};
  },

  onAuth: async ({ claims, userDid }) => {
    // `claims` 将包含动态请求的声明(如果有)的结果。
    if (claims.length > 0) {
      console.log('用户提交了动态声明:', claims);
    }
  },
});

通过从 onConnect 返回一个声明对象,你可以根据每个用户的特定上下文定制 DID Connect 会话,从而创造更智能、更流畅的体验。

既然你已经知道如何向用户请求信息,下一步就是学习如何处理他们的响应。

下一步:处理钱包响应

了解 onAuth、onDecline 和 onError 等各种生命周期回调,以管理整个会话流程。

阅读更多