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

Verifiable Credential Claim


The verifiableCredential claim allows your application to request proof of an attribute, qualification, or ownership from a user. The user provides this proof by presenting a Verifiable Credential (VC) from their DID Wallet. This is a powerful mechanism for scenarios like proving identity, verifying ownership for gated access, or confirming personal information like an email address, without sharing the raw data itself.

How It Works#

The process involves the application specifying criteria for a credential, the user selecting a matching credential from their wallet, and the wallet returning it to the application inside a secure, verifiable presentation.


Parameters#

The verifiableCredential claim can be configured with several parameters to specify the exact credential you need. The most flexible and recommended method is using the filters array.

Parameter

Type

Description

description

string

Required. Text displayed to the user in the wallet, explaining why the credential is being requested.

optional

boolean

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

filters

FilterObject[]

An array of filter objects. The wallet searches for credentials that match any of the filters (OR logic). This is the recommended approach for all new implementations.

claimUrl

string

A URL where the user can learn more about the credential being requested. Can be specified at the top level or within a filter.

acquireUrl

string

A URL where the user can obtain the required credential if they don't have it. Can be specified at the top level or within a filter.

Filter Object#

When using the filters array, each object within the array defines a set of criteria. All criteria within a single filter object must be met (AND logic).

Parameter

Type

Description

type

string[]

An array of acceptable VC type names (e.g., ['EmailVerificationCredential']).

trustedIssuers

(string | object)[]

An array of DIDs for issuers you trust. The credential must be issued by one of these DIDs. An issuer can be a DID string or an object { did: string, endpoint: string }.

tag

string

A specific string that may be present in the credential's metadata or subject, used for fine-grained filtering. For instance, for an email VC, this could be a digest of the email address.

target

string

The DID of the credential itself.

ownerDid

string[]

An array of DIDs. The owner of the credential must be one of these DIDs.

Legacy Parameters#

For simple requests, you can use top-level parameters as a shorthand for a single filter. It is recommended to use the filters array for clarity and future compatibility.

Parameter

Type

Description

item

string[]

Alias for type in a single filter.

trustedIssuers

(string | object)[]

Alias for trustedIssuers in a single filter.

tag

string

Alias for tag in a single filter.

target

string

Alias for target in a single filter.

ownerDid

string[]

Alias for ownerDid in a single filter.

Example: Requesting a Specific Credential#

This example demonstrates how to request an EmailVerificationCredential. It specifies the credential type, a list of trusted issuers, and a claimUrl to provide more context to the user.

Requesting the Claim

This configuration is placed within your DID Connect handler.

// From an auth handler file, e.g., api/routes/auth/consume-vc.js
const joinUrl = require('url-join');
const env = require('../../libs/env');
const { wallet } = require('../../libs/auth');

// ... handler definition
{
action: 'consume_vc',
claims: {
verifiableCredential: async ({ userDid }) => {
const trustedIssuers = (env.trustedIssuers || []).concat(wallet.address);

return {
description: 'Please provide your Email Verification Credential',
item: ['EmailVerificationCredential'], // Using legacy 'item' for simplicity
trustedIssuers,
claimUrl: joinUrl(env.appUrl, '/claim/email'),
};
},
},
onAuth: async ({ userDid, claims, challenge }) => {
// Verification logic goes here, see below
},
}

Handling the Response

Once the user provides the credential, your onAuth callback receives it within a verifiable presentation. You must parse and verify this presentation to ensure its authenticity and integrity.

// In the onAuth callback of the handler
const { verifyPresentation } = require('@arcblock/vc');

const vcClaim = claims.find(x => x.type === 'verifiableCredential');
if (!vcClaim || !vcClaim.presentation) {
throw new Error('Verifiable credential was not provided');
}

const presentation = JSON.parse(vcClaim.presentation);

// 1. Verify the challenge to prevent replay attacks
if (challenge !== presentation.challenge) {
throw Error('Invalid presentation: challenge mismatch');
}

// 2. Verify the presentation's signature and issuer trust
const trustedIssuers = (env.trustedIssuers || []).concat(wallet.address);
await verifyPresentation({ presentation, trustedIssuers, challenge });

// 3. (Optional) Perform business-specific checks on the credential content
const vc = JSON.parse(presentation.verifiableCredential[0]);
if (vc.type.indexOf('EmailVerificationCredential') === -1) {
throw Error('Incorrect credential type provided');
}

// Business logic passed
console.log('VC Verified Successfully!');

Example: Requesting One of Multiple Credential Types#

By using the filters array, you can allow the user to provide any credential that matches one of several criteria. This is useful for granting access based on different qualifications, such as owning one of several possible NFTs.

Requesting the Claim

This example asks for either a BlockletPurchaseCredential or a NodeOwnershipCredential.

// From an auth handler file, e.g., api/routes/auth/verify-vc.js
{
action: 'verify-vc',
claims: {
verifiableCredential: () => {
return {
description: 'Please provide your blocklet or node NFT to continue',
filters: [
{
type: ['BlockletPurchaseCredential'],
trustedIssuers: [wallet.address],
tag: 'your-blocklet-did', // A specific identifier for the blocklet
},
{
type: ['NodeOwnershipCredential'],
trustedIssuers: [wallet.address],
tag: 'your-node-id', // A specific identifier for the node
},
],
};
},
},
onAuth: async ({ claims, challenge }) => {
// Verification logic
const presentation = JSON.parse(claims.find(x => x.type === 'verifiableCredential').presentation);
await verifyPresentation({ presentation, trustedIssuers: [wallet.address], challenge });

const vc = JSON.parse(presentation.verifiableCredential[0]);

if (vc.credentialSubject.isOwnerOf) {
console.log('Node ownership verified!');
} else if (vc.credentialSubject.purchased) {
console.log('Blocklet purchase verified!');
} else {
throw new Error('Presented credential is not valid for this scenario.');
}
},
}

In this case, the onAuth logic needs to inspect the content (credentialSubject) of the presented VC to determine which condition was met and proceed with the appropriate business logic.


Now that you understand how to request Verifiable Credentials, you may want to learn how to request on-chain items. Continue to the Asset Claim documentation for more details.