[INJIMOB-3367] add support for sd-jwt vc parsing and rendering (#2042)

* [INJIMOB-3367] add support for sd-jwt vc parsing and rendering

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3367] add sha384 and sha 512 support for sd jwt parsing

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3367] fix bottom sectionview fields rendering for sdjwt

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3367] remove logs

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3367] add dc+sd-jwt support

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

---------

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>
This commit is contained in:
abhip2565
2025-08-13 08:06:35 +05:30
committed by GitHub
parent b0168c31df
commit f2c6211b95
21 changed files with 884 additions and 124 deletions

View File

@@ -3,4 +3,6 @@
export enum VCFormat {
ldp_vc = 'ldp_vc',
mso_mdoc = 'mso_mdoc',
vc_sd_jwt = 'vc+sd-jwt',
dc_sd_jwt = 'dc+sd-jwt',
}

View File

@@ -7,6 +7,7 @@ import {VCProcessor} from '../../components/VC/common/VCProcessor';
import {
BOTTOM_SECTION_FIELDS_WITH_DETAILED_ADDRESS_FIELDS,
DETAIL_VIEW_ADD_ON_FIELDS,
DETAIL_VIEW_BOTTOM_SECTION_FIELDS,
getCredentialTypeFromWellKnown,
} from '../../components/VC/common/VCUtils';
import {displayType} from '../../machines/Issuers/IssuersMachine';
@@ -77,6 +78,12 @@ export const updateCredentialInformation = async (
context.selectedCredentialType.format,
);
}
if( context.selectedCredentialType.format === VCFormat.vc_sd_jwt || context.selectedCredentialType.format === VCFormat.dc_sd_jwt) {
processedCredential = await VCProcessor.processForRendering(
credential,
context.selectedCredentialType.format,
)
}
let verifiableCredential;
try {
verifiableCredential = {
@@ -168,7 +175,16 @@ export const getCredentialIssuersWellKnownConfig = async (
fields = ldpFields;
wellknownFieldsFlag = true;
}
} else {
}
else if( format === VCFormat.vc_sd_jwt || format === VCFormat.dc_sd_jwt) {
const sdJwtFields = flattenClaimPaths(matchingWellknownDetails.claims);
if (sdJwtFields.length > 0) {
fields = sdJwtFields;
wellknownFieldsFlag = true
}
}
else {
console.error(`Unsupported credential format - ${format} found`);
throw new UnsupportedVcFormat(format);
}
@@ -193,6 +209,28 @@ export const getCredentialIssuersWellKnownConfig = async (
wellknownFieldsFlag || matchingWellknownDetails?.order?.length > 0,
};
};
const flattenClaimPaths = (
claims: Record<string, any>,
prefix = '',
): string[] => {
return Object.entries(claims).flatMap(([key, value]) => {
const currentPath = prefix ? `${prefix}.${key}` : key;
if (
value &&
typeof value === 'object' &&
!Array.isArray(value) &&
Object.keys(value).some(k => typeof value[k] === 'object')
) {
// Has nested objects inside, so recurse
return flattenClaimPaths(value, currentPath);
} else {
// Either a primitive or an empty object or a leaf with no metadata
return [currentPath];
}
});
};
export const getDetailedViewFields = async (
issuer: string,
@@ -211,8 +249,7 @@ export const getDetailedViewFields = async (
let updatedFieldsList = response.fields.concat(DETAIL_VIEW_ADD_ON_FIELDS);
updatedFieldsList = removeBottomSectionFields(updatedFieldsList);
updatedFieldsList = removeBottomSectionFields(updatedFieldsList,format);
return {
matchingCredentialIssuerMetadata: response.matchingCredentialIssuerMetadata,
fields: updatedFieldsList,
@@ -221,7 +258,13 @@ export const getDetailedViewFields = async (
};
};
export const removeBottomSectionFields = fields => {
export const removeBottomSectionFields = (fields, format) => {
if (format === VCFormat.vc_sd_jwt || format === VCFormat.dc_sd_jwt) {
return fields.filter(
fieldName => !DETAIL_VIEW_BOTTOM_SECTION_FIELDS.includes(fieldName),
);
}
return fields.filter(
fieldName =>
!BOTTOM_SECTION_FIELDS_WITH_DETAILED_ADDRESS_FIELDS.includes(fieldName) &&

View File

@@ -61,7 +61,6 @@ async function verifyCredentialForAndroid(
typeof verifiableCredential === 'string'
? verifiableCredential
: JSON.stringify(verifiableCredential);
const vcVerifierResult = await vcVerifier.verifyCredentials(
credentialString,
credentialFormat,
@@ -73,7 +72,7 @@ async function verifyCredentialForIos(
verifiableCredential: Credential,
credentialFormat: string,
): Promise<VerificationResult> {
if (credentialFormat === VCFormat.mso_mdoc) {
if (credentialFormat === VCFormat.mso_mdoc || credentialFormat === VCFormat.vc_sd_jwt || credentialFormat === VCFormat.dc_sd_jwt) {
return createSuccessfulVerificationResult();
}
/*