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

NFT Gated Access


This example demonstrates how to restrict access to specific content or features by verifying a user's ownership of a particular NFT. Using DID Connect, your application can request proof that a user holds a required digital asset in their wallet.

This is a common pattern for token-gated communities, exclusive content drops, or verifying participation in an event.

The Workflow#

The process involves the application requesting an asset claim, which the user fulfills by presenting an NFT from their DID Wallet. The application then verifies this asset's properties to grant access.

Here is a diagram of the interaction flow:


Implementation#

Implementing NFT-gated access requires defining an asset claim in your DID Connect handler and then verifying the response in the onAuth callback.

1. Requesting a Specific NFT#

To gate access based on a single, specific type of NFT, you define the criteria for the asset the user must present. You can specify the NFT's creator (trustedIssuers) or the collection it belongs to (trustedParents).

In this example, we request a test NFT issued by a specific wallet address from a known collection.

// In your DID Connect handler configuration

const { factories } = require('../../libs/factory');
const { wallet } = require('../../libs/auth');
const { verifyAssetClaim } = require('../../libs/util');

module.exports = {
action: 'claim_asset',
claims: {
asset: ({ userDid, extraParams: { type } }) => {
// This configuration asks for a specific NFT
if (type === 'legacy') {
return {
description: 'Please provide asset and prove ownership',
// The NFT must be a child of this factory address (i.e., from this collection)
trustedParents: [factories.nftTest],
// The NFT must have been issued by this wallet address
trustedIssuers: [wallet.address],
// An optional tag for easy identification in the wallet
tag: 'TestNFT',
};
}
// ... other types
},
},

onAuth: async ({ challenge, claims }) => {
const assetClaim = claims.find(x => x.type === 'asset');
if (!assetClaim) {
throw new Error('Asset claim not provided.');
}

// The verifyAssetClaim utility handles the cryptographic verification
const assetState = await verifyAssetClaim({ claim: assetClaim, challenge });

// Your business logic here: check if the verified asset meets your criteria
console.log(`Successfully verified ownership of asset with tags: ${assetState.tags.join(',')}`);

// Grant access to the user
return { successMessage: `Access granted! You own an asset with tag: ${assetState.tags.join(',')}` };
},
};

In the onAuth callback, the verifyAssetClaim helper function is used. It cryptographically verifies that the user who signed the response is the true owner of the presented asset on the blockchain. After verification, you can implement your own logic to grant access, such as creating a web session or returning an access token.

2. Allowing Multiple NFT Types#

In some cases, you might want to grant access to owners of several different NFTs. Instead of creating separate sessions, you can use a filters array to allow the user to present any asset that matches one of the specified criteria.

This example allows a user to present either an NFT from a specific collection OR an NFT they created themselves that has a specific tag.

// In your DID Connect handler configuration

// ... imports

module.exports = {
action: 'claim_asset',
claims: {
asset: async ({ userDid, extraParams: { type } }) => {
if (type === 'either') {
return {
description: 'Please provide asset and prove ownership',
filters: [
{
// Option 1: An NFT from a specific, trusted collection
trustedParents: [factories.nftTest],
trustedIssuers: [wallet.address],
tag: 'TestNFT',
},
{
// Option 2: Any NFT created by the user with a specific tag
tag: 'NFTCreatedByMe',
},
],
};
}
// ... other types
},
},

onAuth: async ({ challenge, claims }) => {
const assetClaim = claims.find(x => x.type === 'asset');
const assetState = await verifyAssetClaim({ claim: assetClaim, challenge });

// Add your logic here to check which NFT was provided and grant access accordingly
console.log(`Successfully verified ownership of asset with tags: ${assetState.tags.join(',')}`);

return { successMessage: 'Access granted based on the asset you provided.' };
},
};

This flexible approach allows for more complex access rules without complicating the user experience. The wallet will automatically show the user all of their assets that satisfy at least one of the filters.

Alternative: Gating with Verifiable Credentials#

Another method for gating access is to use a Verifiable Credential (VC). An NFT can be represented as a VC, such as a NodeOwnershipCredential or a BlockletPurchaseCredential. This approach can be useful when you want to verify ownership without a direct on-chain check at the time of login, or when the proof of ownership contains additional off-chain metadata.

For more details on this method, see the Verifiable Credential Claim documentation.


This example covered how to secure resources by verifying NFT ownership. You can now build applications that offer exclusive access to token holders. To continue exploring, learn how to handle on-chain transactions in the Transaction Payment example.