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

Asset Claim


The Asset Claim is used to request that a user prove ownership of a specific on-chain digital asset, such as a Non-Fungible Token (NFT). This is a common requirement for token-gated access, digital ticketing, or verifying possession of a required digital item. The wallet will prompt the user to select an asset that meets the criteria specified by the application.

How it Works#

The process involves the application specifying criteria for an asset. The user's wallet filters their assets and allows them to select one that matches. The wallet then returns the asset's DID and a signature to the application for verification.


Requesting an Asset Claim#

To request an asset, you include an asset object within the claims field of your DID Connect request. The claim can be structured in two ways:

  1. Single Filter Set (Legacy): Define filtering criteria directly on the top-level asset object. All criteria are treated as an "AND" condition.
  2. Multiple Filter Sets (Recommended): Use the filters array. Each object within the array is a distinct set of criteria ("OR" condition). A user can satisfy the request by providing an asset that matches any one of these sets. The criteria within each object are combined with "AND". This approach provides greater flexibility.

Parameters#

The following parameters can be used to define the criteria for the requested asset, either at the top level (for a single filter set) or within an object in the filters array.

Parameter

Type

Description

description

string

A message displayed to the user in the wallet, explaining why the asset is needed.

optional

boolean

If true, the user can skip this claim. Defaults to false.

address

string

The specific DID address of the asset being requested.

trustedIssuers

(string | object)[]

An array of trusted issuer DIDs. The user must present an asset issued by one of these DIDs. An entry can be a DID string or an object like { did: string, endpoint: string }.

trustedParents

string[]

An array of DIDs of trusted asset factories. The asset must have been created by one of these factories.

tag

string

A specific tag that the asset must have.

ownerDid

string[]

An array of DIDs. The asset's owner must be one of these DIDs. This is rarely used, as the wallet user is typically the owner.

consumed

boolean

A flag to filter assets based on whether they have been consumed. false for unconsumed, true for consumed.

acquireUrl

string

A URL where the user can obtain the required asset if they do not already have one.

filters

object[]

An array of filter objects. Each object can contain the parameters listed above. This enables complex "OR" logic.


Example 1: Request a Specific Type of NFT#

This example demonstrates how to request an NFT that meets a single, strict set of criteria. The application requires an asset that was created by a specific factory, issued by the application's own DID, and has a specific tag.

// From your DID Connect request handler
const claims = {
asset: {
description: 'Please provide your TestNFT to continue.',
trustedParents: ['z82n2iL5e2rzK8j8LgAwe3e4o8a7d6e5f4g3'], // Example Factory DID
trustedIssuers: ['zNKk3iL5e2rzK8j8LgAwe3e4o8a7d6e5f4g3'], // Example App DID
tag: 'TestNFT',
}
};

In this scenario, the user's wallet will filter their assets and only show those that match all three conditions: trustedParents, trustedIssuers, and tag.


Example 2: Request an Asset from Multiple Options#

This example uses the filters array to give the user more flexibility. The application will accept an asset that matches any of the specified conditions. This is useful for accepting different kinds of NFTs that grant the same level of access.

// From your DID Connect request handler
const claims = {
asset: async ({ userDid }) => {
// Dynamically find an asset the user might have created
const { transactions: [tx] } = await client.listTransactions({
accountFilter: { accounts: [userDid] },
typeFilter: { types: ['create_asset'] },
validityFilter: { validity: 'VALID' },
});

const filters = [
// Option 1: A specific type of NFT from our official factory
{
trustedParents: ['z82n2iL5e2rzK8j8LgAwe3e4o8a7d6e5f4g3'], // Official Factory DID
trustedIssuers: ['zNKk3iL5e2rzK8j8LgAwe3e4o8a7d6e5f4g3'], // Official App DID
tag: 'TestNFT',
},
// Option 2: Any NFT created by the user with a specific tag
{
tag: 'NFTCreatedByMe',
},
];

// Option 3: A very specific asset we know the user has created
if (tx) {
filters.push({
address: tx.tx.itxJson.address,
});
}

return {
description: 'Please provide an asset to prove your status.',
filters: filters,
};
},
};

Here, the user can proceed if they have:

  • An TestNFT from the official factory, OR
  • An asset with the tag NFTCreatedByMe, OR
  • The specific asset identified by tx.tx.itxJson.address.


Handling the Wallet Response#

After the user selects an asset and approves the request, the wallet sends a response to your application's onAuth callback. This response contains the DID of the presented asset (claim.assetDid) and a signature (claim.signature) proving that the user controls the private key associated with the asset's owner.

Your application is responsible for verifying this information.

// Example onAuth callback
const onAuth = async ({ challenge, claims }) => {
const assetClaim = claims.find(x => x.type === 'asset');
if (assetClaim) {
try {
// This function is crucial for security. It must perform three checks:
// 1. Fetch the asset's state from the chain using assetClaim.assetDid
// 2. Verify that the asset state matches the criteria from your original request
// 3. Verify the signature against the challenge and the asset owner's public key
const assetState = await verifyAssetClaim({ claim: assetClaim, challenge });

console.log(`Successfully verified ownership of asset: ${assetState.address}`);
return { successMessage: `You've proven ownership of asset: ${assetState.tags.join(',')}` };
} catch (error) {
console.error('Asset claim verification failed:', error);
return { errorMessage: 'Failed to verify the presented asset.' };
}
}
};

The verifyAssetClaim function is a critical security step. It ensures the user isn't presenting a fraudulent claim. The implementation will typically involve using a client library (like @ocap/client) to fetch the asset's current state from the blockchain and then performing cryptographic verification of the signature.

Next Steps#

Verifying ownership is often just the first step. You might want to perform an on-chain action with the asset, such as marking it as "used" or "consumed." This is typically done by requesting a Signature Claim for a ConsumeAssetTx in a subsequent step. This pattern ensures the user who presented the asset also authorizes its use. For a detailed walkthrough, see the Signature Claim documentation.

To explore other ways of requesting proof from a user, you can proceed to the following sections.