资产声明用于请求用户出示特定链上数字资产(如非同质化代币 NFT)的所有权证明。这对于 NFT 门控访问等场景尤其有用,在此类场景中,服务或内容的准入仅限于特定资产的所有者。
该声明允许你的应用程序通过指定各种标准(包括资产地址、发行者或其父集合)来验证资产所有权。
对于可以接受资产或可验证凭证(Verifiable Credential)的更通用请求,请参阅资产或 VC 声明。
工作原理
当你请求资产声明时,DID Connect 会提示用户从钱包中选择一个符合条件的资产。钱包会根据你在声明请求中定义的标准筛选用户的资产。一旦用户选择并出示有效资产,你的应用程序将收到其详细信息以供验证。
参数
asset 声明通过一个包含以下属性的对象进行配置。请求的核心是 filters 数组,它允许你定义一组或多组标准。
| 参数 | 类型 | 描述 |
|---|---|---|
description | string | 必需。 向用户显示的消息,解释为什么他们需要出示该资产。 |
optional | boolean | 如果为 true,用户可以跳过此声明。默认为 false。 |
filters | Array<Object> | 过滤器对象数组。钱包将查找匹配任何过滤器(或逻辑)的资产。 |
acquireUrl | string | 一个可选的 URL,如果用户尚未拥有所需资产,可以前往该地址获取。 |
过滤器对象属性
filters 数组中的每个对象都可以包含以下属性。单个过滤器中的所有属性都通过“与”逻辑(AND logic)进行组合。
| 属性 | 类型 | 描述 |
|---|---|---|
address | string | 资产的特定 DID 地址。 |
trustedIssuers | Array<string | Object> | 受信任的资产发行者 DID 列表。发行者可以是一个简单的 DID 字符串,也可以是一个 { did: string, endpoint: string } 对象。 |
trustedParents | Array<string> | 受信任的父资产 DID 列表。通常用于验证某个 NFT 是否属于特定的集合。 |
tag | string | 必须与资产关联的特定标签。 |
ownerDid | Array<string> | DID 数组。资产的所有者必须是此列表中的 DID 之一。 |
consumed | boolean | 指定资产必须处于已消费(true)还是未消费(false)状态。 |
请求资产
以下是一些如何在传递给身份验证器的 claims 对象中构建 asset 声明请求的示例。
示例 1:使用 NFT 集合进行门控访问
此示例请求父级为特定 NFT 集合 DID 的任何资产。这是向特定 NFT 项目的持有者授予访问权限的常用方法。
请求来自特定集合的 NFT
const claims = {
asset: {
description: '请出示您的会员 NFT 以访问私密社区。',
filters: [
{
// NFT 集合的父级 DID
trustedParents: ['zNKjDm4Xsoaffb19UE6QxVeevuaTaLCS1n1S'],
},
],
acquireUrl: 'https://example.com/mint-nft',
},
};
// 在你的路由处理程序中
const { authInfo } = await authenticator.sign({ context, claims });示例 2:按地址请求特定资产
如果你需要用户出示一个非常特定的资产,可以按其唯一地址进行筛选。
按地址请求特定资产
const claims = {
asset: {
description: '请出示您的黄金票券 NFT 以继续。',
filters: [
{
// 黄金票券 NFT 的唯一 DID 地址
address: 'zjddPDAK5rm1E4syjTkgoiskGBAfve5YYN2s',
},
],
},
};示例 3:使用多个过滤器
你可以提供多个过滤器对象,为用户提供更多选择。在此示例中,用户可以出示来自受信任发行者的资产,或来自受信任集合的资产。
使用多个过滤器以获得更大的灵活性
const claims = {
asset: {
description: '请出示来自我们官方发行者或合作伙伴集合的资产。',
optional: true, // 将此项设为可选
filters: [
{
// 选项 1:来自受信任发行者的资产
trustedIssuers: ['zNKjDm4Xsoaffb19UE6QxVeevuaTaLCS1n1S'],
tag: 'official-badge',
},
{
// 选项 2:来自合作伙伴 NFT 集合的资产
trustedParents: ['z9f9aE3E6d4c4b2A1c8f8b6e2d0F0g2H2i4j6k8m'],
},
],
},
};钱包响应
如果用户成功出示有效资产,你处理程序中的 onAuth 或 onConnect 回调将收到资产的详细信息。出示的资产将包含在会话上下文的 claims 数组中。
你可以像这样访问它:
处理钱包响应
const handlers = new WalletHandlers({
authenticator,
// ...其他处理程序
onAuth: async (req, res) => {
const { userDid, claims } = req.context.did_connect;
// 在响应中查找出示的资产声明
const presentedAsset = claims.find(x => x.type === 'asset');
if (presentedAsset) {
console.log(`用户 ${userDid} 出示了资产:`, presentedAsset.asset);
// presentedAsset.asset 将包含所出示 NFT 的完整详细信息
// 例如,其地址、发行者、所有者等。
} else {
console.log('用户未出示所需资产。');
}
res.redirect('/profile');
},
});接下来,探索如何请求可验证凭证(Verifiable Credential),这是验证用户属性的另一种强大方式。