DCQL Library

An implementation of the Digital Credentials Query Language (DCQL) for requesting and sharing data.

The Affinidi DCQL library implements the Digital Credentials Query Language (DCQL, pronounced [ˈdakl̩] 📣) to simplify and enable verifiers to request credentials in a verifiable presentation format from a user’s digital wallet. It is a JSON-encoded query language that defines the type of credentials that must be presented by the user, such as a verified identity credentials.

It is a flexible and granular standard query, enabling holders of credentials with enhanced security, privacy, and control to share their verifiable information selectively.

The DCQL library also leverages the open-sourced SSI and Selective Disclosure-JWT (SD-JWT) libraries by Affinidi to support data models from W3C and SD-JWT specifications.

Core Concepts

  • Verifiable Credential (VC): A digital representation of a claim created by the issuer about the subject (e.g., Individual). VC is cryptographically signed and verifiable.

  • Verifiable Presentation (VP): A collection of one or more Verifiable Credentials (VCs) that an individual shares with the verifier to prove specific claims. VP is cryptographically signed and verifiable.

  • Selective Disclosure: Claims can be selectively disclosed based on the required verifiable presentation of the verifier.

Key Features

  • Support various credential formats, such as ldp_vc and dc+sd-jwt.
  • Complex claim path evaluation, including arrays, wildcards, null or index.
  • Support for querying credential sets, including exact match or matching from different values provided in the query.
  • Support for filtering by metadata, like type_values (W3C) and vct_values (SD-JWT).

NOTE: This DCQL library does not include cryptographic operations such as signature verification and holder binding proof checks. It also does not include top‑level OpenID4VP request/response serialisation.

Get Started

Prerequisite

  • Dart SDK version ^3.5.3

Installation

Run:

dart pub add dcql

or manually, add the package into your pubspec.yaml file:

dependencies: dcql: ^<version_number>

and then run the command below to install the package:

dart pub get

Visit the pub.dev install page of the Dart package for more information.

Sample Usage

Refer to the sample usage below on how to query a credential for specific requirements from the verifier.

Query Specific Issuer Example

Sample Verifiable Credential (VC):

{ '@context': [ 'https://www.w3.org/2018/credentials/v1', 'https://schema.affinidi.io/TEmailV1R0.jsonld', ], 'credentialSchema': { 'id': 'https://schema.affinidi.io/TEmailV1R0.json', 'type': 'JsonSchemaValidator2018', }, 'credentialSubject': {'email': 'alice.doe@test.com'}, 'holder': { 'id': 'did:key:zQ3shnHRFYxDpASTxaTFBMcqtFASxyzctDx8xYj2USw7QUaLb', }, 'id': 'claimId:ee3882a6b3058195', 'issuanceDate': '2025-01-23T21:01:23.162Z', 'issuer': 'did:key:zQ3shXLA2cHanJgCUsDfXxBi2BGnMLArHVz5NWoC9axr8pEy6', 'proof': { 'type': 'EcdsaSecp256k1Signature2019', 'created': '2025-01-23T21:01:31Z', 'verificationMethod': 'did:key:zQ3shXLA2cHanJgCUsDfXxBi2BGnMLArHVz5NWoC9axr8pEy6#zQ3shXLA2cHanJgCUsDfXxBi2BGnMLArHVz5NWoC9axr8pEy6', 'proofPurpose': 'assertionMethod', 'jws': 'eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..ZwNL-5Gva80Xc0FR6v1R6wCVPPMAYzriWu6_szFD48YGPNQJPV66XsDHNjTGyQOyuRy7a3srX3diI5_1527Ttg', }, 'type': ['VerifiableCredential', 'Email'], }

Given the sample credential above, using the DCQL library, we can query the user’s digital wallet to request a credential issued by a specific issuer.

For example, as an employer (verifier), you want to request the verified identity of a candidate applying for a job from a specific background screening company.

You can do this by querying the Verifiable Credentials (VC) stored in the user’s digital wallet with the issuer field using the published DID of the background screening company that issued the credential.

import 'package:dcql/src/dcql_base.dart'; import 'package:ssi/ssi.dart'; void main() async { final verifiableCredentials = [ VcDataModelV1.fromJson(<SAMPLE_CREDENTIALS>), ]; final issuerQuery = DcqlCredentialQuery( credentials: [ DcqlCredential( id: 'pid', format: CredentialFormat.ldpVc, claims: [ DcqlClaim( path: ['issuer', 'id'], values: [ 'did:key:zQ3shXLA2cHanJgCUsDfXxBi2BGnMLArHVz5NWoC9axr8pEy6' ], ), ], ), ], ); final issuerResult = issuerQuery.query(digitalCredentials); print('Query issuer'); print('Fulfilled: ${issuerResult.fulfilled}'); print('VCs: ${issuerResult.verifiableCredentials}'); }

Query W3C Credential (ldp_vc) Example

final query = DcqlCredentialQuery( credentials: [ DcqlCredential( id: 'pid', format: CredentialFormat.ldpVc, meta: DcqlMeta.forW3C(typeValues: [ ['Email'] ]), claims: [ DcqlClaim( path: ['credentialSubject','email'], values: ['alice.doe@test.com'], ), ], ), ], ); final vcs = [ W3CDigitalCredential.fromLdVcDataModelV1(yourVcJsonMap), ]; final result = query.query(vcs); print(result.fulfilled); // true if matched

Query SD-JWT Credential (Array + Wildcard) Example

final query = DcqlCredentialQuery( credentials: [ DcqlCredential( id: 'pid', format: CredentialFormat.dcSdJwt, claims: [ DcqlClaim(path: ['given_name'], values: ['Alice']), DcqlClaim(path: ['citizenship', null, 'country'], values: ['Germany']), ], ), ], ); final sdJwt = await SdJwtHandlerV1().sign(/* ... */); final result = query.query([SdJwtDigitalCredential.fromSdJwt(sdJwt)]);

If there’s a match from the query, it returns the Verifiable Credential/s (VCs) to generate a Verifiable Presentation (VP) format for the verifier to parse and verify.

For more examples of how to query credentials using the DCQL Dart library, refer to the example folder.

DCQL Structure

DCQL structure when creating a query.

Claim Path Semantics

path is an array of segments that specifies how to navigate through the credential’s JSON structure. Each item in the array represents a key or index to locate the value, starting from the root.

  • null segment inside a list is a wildcard. First element for which the remaining path resolves non‑null.
  • Integer segment inside a list is a fixed index.

Examples:

  • ["credentialSubject", "email"] → simple property
  • ["citizenship", null, "country"] → any array element whose country matches
  • ["education", 0, "masterDegree"] → first array element’s masterDegree

Claim Sets (Per Credential)

claimSets: [["name","age"], ["email"]] - in this example, the credential matches if (name AND age) are satisfied OR (email) is satisfied.

Credential Sets (Query Level)

credential_sets is a collection of one or more credentials (called options) that are evaluated together during a query. The query succeeds if one of the options satisfies the requirements.

Interpreting Query Result

Refer to the table below on interpreting the DcqlQueryResult from executing a DCQL query.

FieldMeaning
fulfilledOverall boolean according to credential + query sets.
verifiableCredentialsMap: credential ID → iterable of matched DigitalCredential(s).
satisfiedClaimsByCredential(Optional) VC evidence of which claim IDs were satisfied (used when claimSets is present).

Error Handling Notes

Existing validation helpers:

  • DcqlClaim.validate()
  • DcqlCredential.validate()
  • DcqlMeta.validate()

Detailed spec error taxonomy implementation is unavailable; expect simple validation failure aggregation.