Used to check for browser translation.
用于检测浏览器翻译。
ブラウザの翻訳を検出する
How-to Guides

Request a Digital Asset (NFT)


Many applications need to verify that a user possesses a specific on-chain digital asset, such as an NFT ticket for an event, a membership badge, or a special in-game item. DID Connect provides the asset claim type to request that a user present a digital asset from their wallet, proving ownership without a complex lookup process.

This guide will walk you through using the asset claim to request and verify NFTs or other digital assets from a user.

The Filtering Mechanism#

The most flexible way to request an asset is by using the filters property. This property allows you to define one or more sets of criteria. The wallet will find an asset that matches at least one of the filter objects you provide.

Here's the logic:

  • The filters array acts as an OR condition. The user only needs to satisfy one of the filter objects within the array.
  • The properties inside a single filter object act as an AND condition. An asset must match all properties specified in that filter object.

This logic allows you to create flexible requests, such as "show me a ticket for DevCon or a VIP pass from the same organizer."

Filter 2 Criteria (AND)

AND

Property X

Property Y

Filter 1 Criteria (AND)

AND

Property A

Property B

Start Asset Request

User has an asset that matches...

Filter 1

Filter 2

...

Success


How to Request a Digital Asset#

To request an asset, you define an asset claim in the claims configuration of your WalletHandlers instance. The primary configuration happens within the filters array.

Here is an example of setting up an endpoint to request a "DevCon 2024 Ticket" NFT or a VIP pass for the same event.

const { WalletHandlers } = require('@arcblock/did-connect');

// Assuming 'app' is your Express app and 'auth' is your WalletAuthenticator instance
const handlers = new WalletHandlers({ authenticator: auth /*, ...other options */ });

handlers.attach({
app,
action: 'request-ticket',
onAuth: async (req, res) => {
const { claims } = res.locals.auth;
const presentedTicket = claims.find(x => x.type === 'asset');

if (presentedTicket) {
console.log('User presented ticket:', presentedTicket.value);
// You now have proof of ownership. Grant access.
res.json({ status: 'ok', message: 'Ticket verified!' });
} else {
res.status(400).json({ status: 'error', message: 'Ticket not provided.' });
}
},
claims: {
asset: {
description: 'Please present your DevCon 2024 Ticket NFT to enter.',
optional: false, // The user must provide this asset
filters: [
{
// Option 1: The official DevCon 2024 Ticket NFT
// The asset must be from this specific creator AND have this tag
trustedIssuers: ['zNKjDm4Xsoaffb19UE6QxVeevuaTaLCS1n1S'], // DID of the event organizer
tag: 'devcon-2024-ticket',
},
{
// Option 2: A special VIP pass NFT for the same event
trustedIssuers: ['zNKjDm4Xsoaffb19UE6QxVeevuaTaLCS1n1S'], // DID of the event organizer
tag: 'devcon-2024-vip-pass',
},
],
},
},
});

In the onAuth callback, presentedTicket.value will contain the full details of the asset that the user presented, allowing for further verification or record-keeping.

Filter Properties#

You can use the following properties within each filter object to specify the asset you're looking for.

Property

Type

Description

address

string

The DID address of a specific asset. Use this to request one particular NFT.

trustedIssuers

string[]

An array of issuer DIDs. The asset's creator must be in this list.

trustedParents

string[]

An array of parent DIDs. Useful for NFT collections where each NFT is a child of a parent contract/asset.

tag

string

A string tag associated with the asset. Case-sensitive.

consumed

boolean

If true, requests an asset that has been marked as consumed. If false or undefined, requests an unconsumed asset.

acquireUrl

string

A URL where the user can obtain the asset if they don't already have it. The wallet may display this link to the user.

Top-Level Properties#

These properties are defined at the root of the asset claim object.

Property

Type

Description

description

string

Required. Text displayed to the user in their wallet, e.g., "Please present your ticket to continue."

optional

boolean

If true, the user can skip this claim. If false (default), the user must provide a matching asset to proceed.

Example Scenarios#

1. Request a Specific NFT by Address#

This is the most direct way to ask for a single, known asset.

{
description: 'Please present the Golden Ticket NFT.',
filters: [{
address: 'zje98f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c',
}]
}

2. Request any NFT from a Collection#

Use trustedParents to request any asset that belongs to a specific collection, such as asking a user to prove they are part of a club.

{
description: 'Show proof of membership by presenting a CryptoPunks Club NFT.',
filters: [{
trustedParents: ['zjeNFTCollectionParentDIDGoesHere'],
}]
}

3. Request a Consumed (Used) Ticket#

This can be used for exit verification or to prevent re-entry with the same ticket.

{
description: 'Please present your used event ticket to exit.',
filters: [{
trustedIssuers: ['zNKjDm4Xsoaffb19UE6QxVeevuaTaLCS1n1S'],
tag: 'devcon-2024-ticket',
consumed: true, // Specifically look for a consumed asset
}]
}


Now that you know how to request digital assets, you can combine this with other claims. To learn how to request different types of credentials, see the Request a Verifiable Credential guide. To link multiple requests together, visit the Chain Multiple Workflows guide.