@verifiables/request-converter
v0.1.1
Published
Convert DIF Presentation Exchange Presentation Definitions and DCQL queries to ISO 18013-5 mDoc DeviceRequest structures
Maintainers
Readme
Presentation Definition & DCQL to mDoc DeviceRequest Converter
A TypeScript library for converting DIF Presentation Exchange Presentation Definitions and DCQL (Digital Credentials Query Language) queries to ISO 18013-5 mDoc DeviceRequest structures.
Overview
This library bridges important standards in the digital identity space:
- DIF Presentation Exchange v2.x: A specification that defines how Verifiers can express proof requirements and how Holders can describe proof submissions.
- DCQL (Digital Credentials Query Language): The new query language defined in OpenID4VP for requesting verifiable credentials in a more flexible way.
- ISO 18013-5 (mDL): The international standard for mobile driver's licenses, which defines the DeviceRequest structure for requesting credential data.
The converter is particularly useful for:
- OpenID4VP implementations that use Presentation Exchange or DCQL with mDoc credentials
- EUDI Wallet ecosystem implementations
- Any system bridging W3C/DIF/OpenID standards with ISO 18013-5 mDoc credentials
Installation
npm install @verifiables/request-converterOr with your preferred package manager:
yarn add @verifiables/request-converter
pnpm add @verifiables/request-converterQuick Start
DCQL Query Conversion
import { convertDcqlQueryToDeviceRequest } from '@verifiables/request-converter';
// DCQL query (as used in OpenID4VP)
const dcqlQuery = {
credentials: [{
id: 'my_mdl',
format: 'mso_mdoc',
meta: { doctype_value: 'org.iso.18013.5.1.mDL' },
claims: [
{ path: ['org.iso.18013.5.1', 'family_name'], intent_to_retain: false },
{ path: ['org.iso.18013.5.1', 'given_name'], intent_to_retain: false },
]
}]
};
const result = convertDcqlQueryToDeviceRequest(dcqlQuery);
console.log(result.deviceRequest);
// {
// version: "1.0",
// docRequests: [{
// itemsRequest: {
// docType: "org.iso.18013.5.1.mDL",
// nameSpaces: {
// "org.iso.18013.5.1": {
// family_name: false,
// given_name: false
// }
// }
// }
// }]
// }Presentation Definition Conversion
import { convertPresentationDefinitionToDeviceRequest } from '@verifiables/request-converter';
const presentationDefinition = {
id: "mDL-request",
input_descriptors: [{
id: "org.iso.18013.5.1.mDL",
format: { mso_mdoc: { alg: ["ES256"] } },
constraints: {
limit_disclosure: "required",
fields: [
{ path: ["$['org.iso.18013.5.1']['family_name']"], intent_to_retain: false },
{ path: ["$['org.iso.18013.5.1']['given_name']"], intent_to_retain: false }
]
}
}]
};
const result = convertPresentationDefinitionToDeviceRequest(presentationDefinition);Auto-detect Input Type
import { convertToDeviceRequest } from '@verifiables/request-converter';
// Works with both DCQL and Presentation Definition
const result = convertToDeviceRequest(input); // Auto-detects input typeAPI Reference
DCQL Conversion
convertDcqlQueryToDeviceRequest(dcqlQuery, options?)
Converts a DCQL query to a DeviceRequest.
Parameters:
dcqlQuery: The DCQL query object withcredentialsarrayoptions(optional): Conversion optionsversion: DeviceRequest version string (default:"1.0")defaultIntentToRetain: Default intent_to_retain value if not specified (default:false)mdocOnly: Only process mso_mdoc format credentials (default:true)validate: Whether to validate input (default:true)
Presentation Definition Conversion
convertPresentationDefinitionToDeviceRequest(presentationDefinition, options?)
Converts a Presentation Definition to a DeviceRequest.
Parameters:
presentationDefinition: The DIF Presentation Exchange Presentation Definitionoptions(optional): Conversion options (same as above)
Unified Conversion
convertToDeviceRequest(input, options?)
Auto-detects input type and converts to DeviceRequest.
Utility Functions
createDeviceRequest(docType, elements, version?)
Creates a DeviceRequest directly from docType and elements.
const deviceRequest = createDeviceRequest(
'org.iso.18013.5.1.mDL',
[
{ namespace: 'org.iso.18013.5.1', element: 'family_name', intentToRetain: false },
{ namespace: 'org.iso.18013.5.1', element: 'given_name', intentToRetain: false },
]
);createDcqlQueryFromDeviceRequest(deviceRequest, options?)
Reverse conversion: creates a DCQL query from a DeviceRequest.
const dcqlQuery = createDcqlQueryFromDeviceRequest(deviceRequest);createPresentationDefinitionFromDeviceRequest(deviceRequest, options?)
Reverse conversion: creates a Presentation Definition from a DeviceRequest.
Interoperability Functions
convertDcqlCredentialQueryToInputDescriptor(credentialQuery)
Converts a single DCQL credential query to a Presentation Definition input descriptor.
convertInputDescriptorToDcqlCredentialQuery(inputDescriptor)
Converts a Presentation Definition input descriptor to a DCQL credential query.
Validation
validateDeviceRequest(deviceRequest)
Validates a DeviceRequest structure.
const { valid, errors } = validateDeviceRequest(deviceRequest);DCQL Path Format
For mDoc credentials, DCQL uses a simple path format:
claims: [
{ path: ['namespace', 'element'], intent_to_retain: boolean }
]Examples:
['org.iso.18013.5.1', 'family_name']['eu.europa.ec.eudi.pid.1', 'birth_date']['org.iso.7367.1', 'vehicle_holder']
Presentation Definition Path Format
Presentation Definitions use JSONPath-style expressions:
$['namespace']['element']Examples:
$['org.iso.18013.5.1']['family_name']$['eu.europa.ec.eudi.pid.1']['nationality']
Supported Document Types
The converter recognizes common mDoc document types:
| Document Type | Default Namespace |
|--------------|-------------------|
| org.iso.18013.5.1.mDL | org.iso.18013.5.1 |
| eu.europa.ec.eudi.pid.1 | eu.europa.ec.eudi.pid.1 |
| org.iso.7367.1.mVRC | org.iso.7367.1 |
Examples
DCQL: Multiple Credentials
const dcqlQuery = {
credentials: [
{
id: 'pid',
format: 'mso_mdoc',
meta: { doctype_value: 'eu.europa.ec.eudi.pid.1' },
claims: [
{ path: ['eu.europa.ec.eudi.pid.1', 'family_name'] },
{ path: ['eu.europa.ec.eudi.pid.1', 'age_over_18'] },
]
},
{
id: 'mdl',
format: 'mso_mdoc',
meta: { doctype_value: 'org.iso.18013.5.1.mDL' },
claims: [
{ path: ['org.iso.18013.5.1', 'driving_privileges'] },
]
}
],
credential_sets: [
{ options: [['pid'], ['pid', 'mdl']], required: true }
]
};
const result = convertDcqlQueryToDeviceRequest(dcqlQuery);
// Result contains two docRequests, one for PID and one for mDLKYC with Data Retention
const kycQuery = {
credentials: [{
id: 'kyc',
format: 'mso_mdoc',
meta: { doctype_value: 'org.iso.18013.5.1.mDL' },
claims: [
{ path: ['org.iso.18013.5.1', 'family_name'], intent_to_retain: true },
{ path: ['org.iso.18013.5.1', 'document_number'], intent_to_retain: true },
{ path: ['org.iso.18013.5.1', 'portrait'], intent_to_retain: false }, // Only verify
]
}]
};Type Definitions
The library exports comprehensive TypeScript types:
import type {
// DCQL types
DcqlQuery,
DcqlCredentialQuery,
DcqlCredentialMeta,
DcqlClaimQuery,
DcqlClaimSetQuery,
DcqlCredentialSetQuery,
// Presentation Definition types
PresentationDefinition,
InputDescriptor,
Constraints,
Field,
// DeviceRequest types
DeviceRequest,
DocRequest,
ItemsRequest,
NameSpaces,
DataElements,
// Conversion types
ConversionResult,
ConversionOptions,
DcqlConversionOptions,
} from '@verifiables/request-converter';Integration with Other Libraries
With @animo-id/mdoc
The DeviceRequest output is designed to work directly with @animo-id/mdoc's holder functions:
import {
createDeviceResponseForDeviceRequest,
DataItem
} from '@animo-id/mdoc';
import {
convertDcqlQueryToDeviceRequest,
} from '@verifiables/request-converter';
// Convert DCQL query (from OID4VP authorization request) to DeviceRequest
const dcqlQuery = {
credentials: [{
id: 'mdl',
format: 'mso_mdoc',
meta: { doctype_value: 'org.iso.18013.5.1.mDL' },
claims: [
{ path: ['org.iso.18013.5.1', 'family_name'], intent_to_retain: false },
{ path: ['org.iso.18013.5.1', 'portrait'], intent_to_retain: false },
]
}]
};
const { deviceRequest } = convertDcqlQueryToDeviceRequest(dcqlQuery);
deviceRequest.docRequests = deviceRequest.docRequests.map((docRequest: any) => {
docRequest.itemsRequest = DataItem.fromData(docRequest.itemsRequest)
return docRequest
})
// Use the DeviceRequest directly with @animo-id/mdoc holder
const deviceResponse = await createDeviceResponseForDeviceRequest({
deviceRequest,
sessionTranscript, // SessionTranscript bytes,
issuerSigned, // issuerSigned from mDoc,
signature, // a signature object including a CoseKey signingKey
}, context); // the mdoc context
// deviceResponse is ready to send back to the verifierWith dcql-ts
import { DcqlQuery } from 'dcql';
import { convertDcqlQueryToDeviceRequest } from '@verifiables/request-converter';
// Parse and validate DCQL query using dcql-ts
const parsedQuery = DcqlQuery.parse(rawQuery);
DcqlQuery.validate(parsedQuery);
// Convert to DeviceRequest
const { deviceRequest } = convertDcqlQueryToDeviceRequest(parsedQuery);Why Proper intent_to_retain Handling Matters
The intent_to_retain field is crucial for privacy compliance (GDPR, etc.):
false: Data is only verified in real-time, not storedtrue: Verifier intends to retain the data
This library properly extracts intent_to_retain from DCQL claims, unlike simplistic implementations that hardcode it to false.
Related Standards
- DCQL (OpenID4VP)
- DIF Presentation Exchange v2.x
- ISO 18013-5:2021 - Mobile driving licence (mDL) application
- ISO 18013-7 - Mobile driving licence add-on functions
- dcql-ts - DCQL TypeScript implementation
License
Apache-2.0
Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
