@sphereon/ssi-sdk.sd-jwt 0.34.1-fix.80 → 0.34.1-next.278
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +254 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -8
- package/dist/index.d.ts +68 -8
- package/dist/index.js +252 -41
- package/dist/index.js.map +1 -1
- package/package.json +21 -20
- package/src/__tests__/{sd-jwt.test.ts → sd-jwt-vc.test.ts} +6 -4
- package/src/__tests__/sd-jwt-vcdm2.test.ts +316 -0
- package/src/action-handler.ts +83 -36
- package/src/index.ts +1 -0
- package/src/sdJwtVcdm2Instance.ts +155 -0
- package/src/types.ts +40 -6
- package/src/utils.ts +32 -1
package/dist/index.js
CHANGED
|
@@ -3,9 +3,8 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
3
3
|
|
|
4
4
|
// src/action-handler.ts
|
|
5
5
|
import { SDJwt } from "@sd-jwt/core";
|
|
6
|
-
import { SDJwtVcInstance } from "@sd-jwt/sd-jwt-vc";
|
|
6
|
+
import { SDJwtVcInstance as SDJwtVcInstance2 } from "@sd-jwt/sd-jwt-vc";
|
|
7
7
|
import { calculateJwkThumbprint, signatureAlgorithmFromKey } from "@sphereon/ssi-sdk-ext.key-utils";
|
|
8
|
-
import { decodeBase64url } from "@veramo/utils";
|
|
9
8
|
import Debug from "debug";
|
|
10
9
|
|
|
11
10
|
// src/defaultCallbacks.ts
|
|
@@ -81,8 +80,189 @@ function assertValidTypeMetadata(metadata, vct) {
|
|
|
81
80
|
}
|
|
82
81
|
}
|
|
83
82
|
__name(assertValidTypeMetadata, "assertValidTypeMetadata");
|
|
83
|
+
function isVcdm2SdJwtPayload(payload) {
|
|
84
|
+
return "type" in payload && Array.isArray(payload.type) && payload.type.includes("VerifiableCredential") && "@context" in payload && (typeof payload["@context"] === "string" && payload["@context"].length > 0 || Array.isArray(payload["@context"]) && payload["@context"].length > 0 && payload["@context"].includes("https://www.w3.org/ns/credentials/v2"));
|
|
85
|
+
}
|
|
86
|
+
__name(isVcdm2SdJwtPayload, "isVcdm2SdJwtPayload");
|
|
87
|
+
function isSdjwtVcPayload(payload) {
|
|
88
|
+
return !isVcdm2SdJwtPayload(payload) && "vct" in payload && typeof payload.vct === "string";
|
|
89
|
+
}
|
|
90
|
+
__name(isSdjwtVcPayload, "isSdjwtVcPayload");
|
|
91
|
+
function getIssuerFromSdJwt(payload) {
|
|
92
|
+
let issuer;
|
|
93
|
+
if (isSdjwtVcPayload(payload) || "iss" in payload) {
|
|
94
|
+
issuer = payload.iss;
|
|
95
|
+
} else if (isVcdm2SdJwtPayload(payload) || "issuer" in payload && payload.issuer) {
|
|
96
|
+
issuer = typeof payload.issuer === "string" ? payload.issuer : payload.issuer?.id;
|
|
97
|
+
}
|
|
98
|
+
if (!issuer) {
|
|
99
|
+
throw new Error("No issuer (iss or VCDM 2 issuer) found in SD-JWT or no VCDM2 SD-JWT or SD-JWT VC");
|
|
100
|
+
}
|
|
101
|
+
return issuer;
|
|
102
|
+
}
|
|
103
|
+
__name(getIssuerFromSdJwt, "getIssuerFromSdJwt");
|
|
104
|
+
|
|
105
|
+
// src/sdJwtVcdm2Instance.ts
|
|
106
|
+
import { SDJwtInstance } from "@sd-jwt/core";
|
|
107
|
+
import { SDJWTException } from "@sd-jwt/utils";
|
|
108
|
+
import { SDJwtVcInstance } from "@sd-jwt/sd-jwt-vc";
|
|
109
|
+
|
|
110
|
+
// src/types.ts
|
|
111
|
+
import { contextHasPlugin } from "@sphereon/ssi-sdk.agent-config";
|
|
112
|
+
var sdJwtPluginContextMethods = [
|
|
113
|
+
"createSdJwtVc",
|
|
114
|
+
"createSdJwtPresentation",
|
|
115
|
+
"verifySdJwtVc",
|
|
116
|
+
"verifySdJwtPresentation"
|
|
117
|
+
];
|
|
118
|
+
function contextHasSDJwtPlugin(context) {
|
|
119
|
+
return contextHasPlugin(context, "verifySdJwtVc");
|
|
120
|
+
}
|
|
121
|
+
__name(contextHasSDJwtPlugin, "contextHasSDJwtPlugin");
|
|
122
|
+
function isVcdm2SdJwt(type) {
|
|
123
|
+
return type === "vc+sd-jwt" || type === "vp+sd-jwt";
|
|
124
|
+
}
|
|
125
|
+
__name(isVcdm2SdJwt, "isVcdm2SdJwt");
|
|
126
|
+
|
|
127
|
+
// src/sdJwtVcdm2Instance.ts
|
|
128
|
+
var SDJwtVcdmInstanceFactory = class {
|
|
129
|
+
static {
|
|
130
|
+
__name(this, "SDJwtVcdmInstanceFactory");
|
|
131
|
+
}
|
|
132
|
+
static create(type, config) {
|
|
133
|
+
if (isVcdm2SdJwt(type)) {
|
|
134
|
+
return new SDJwtVcdm2Instance(config);
|
|
135
|
+
}
|
|
136
|
+
return new SDJwtVcInstance(config);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
var SDJwtVcdm2Instance = class extends SDJwtInstance {
|
|
140
|
+
static {
|
|
141
|
+
__name(this, "SDJwtVcdm2Instance");
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The type of the SD-JWT VCDM2 set in the header.typ field.
|
|
145
|
+
*/
|
|
146
|
+
static type = "vc+sd-jwt";
|
|
147
|
+
userConfig = {};
|
|
148
|
+
constructor(userConfig) {
|
|
149
|
+
super(userConfig);
|
|
150
|
+
if (userConfig) {
|
|
151
|
+
this.userConfig = userConfig;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
|
|
156
|
+
* @param disclosureFrame
|
|
157
|
+
*/
|
|
158
|
+
validateReservedFields(disclosureFrame) {
|
|
159
|
+
if (disclosureFrame?._sd && Array.isArray(disclosureFrame._sd) && disclosureFrame._sd.length > 0) {
|
|
160
|
+
const reservedNames = [
|
|
161
|
+
"iss",
|
|
162
|
+
"nbf",
|
|
163
|
+
"exp",
|
|
164
|
+
"cnf",
|
|
165
|
+
"@context",
|
|
166
|
+
"type",
|
|
167
|
+
"credentialStatus",
|
|
168
|
+
"credentialSchema",
|
|
169
|
+
"relatedResource"
|
|
170
|
+
];
|
|
171
|
+
const reservedNamesInDisclosureFrame = disclosureFrame._sd.filter((key) => reservedNames.includes(key));
|
|
172
|
+
if (reservedNamesInDisclosureFrame.length > 0) {
|
|
173
|
+
throw new SDJWTException(`Cannot disclose protected field(s): ${reservedNamesInDisclosureFrame.join(", ")}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Verifies the SD-JWT-VC. It will validate the signature, the keybindings when required, the status, and the VCT.
|
|
179
|
+
* @param encodedSDJwt
|
|
180
|
+
* @param options
|
|
181
|
+
*/
|
|
182
|
+
async verify(encodedSDJwt, options) {
|
|
183
|
+
const result = await super.verify(encodedSDJwt, options).then((res) => {
|
|
184
|
+
return {
|
|
185
|
+
payload: res.payload,
|
|
186
|
+
header: res.header,
|
|
187
|
+
kb: res.kb
|
|
188
|
+
};
|
|
189
|
+
});
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Validates the integrity of the response if the integrity is passed. If the integrity does not match, an error is thrown.
|
|
194
|
+
* @param integrity
|
|
195
|
+
* @param response
|
|
196
|
+
*/
|
|
197
|
+
async validateIntegrity(response, url, integrity) {
|
|
198
|
+
if (integrity) {
|
|
199
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
200
|
+
const alg = integrity.split("-")[0];
|
|
201
|
+
const hashBuffer = await this.userConfig.hasher(arrayBuffer, alg);
|
|
202
|
+
const integrityHash = integrity.split("-")[1];
|
|
203
|
+
const hash = Array.from(new Uint8Array(hashBuffer)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
204
|
+
if (hash !== integrityHash) {
|
|
205
|
+
throw new Error(`Integrity check for ${url} failed: is ${hash}, but expected ${integrityHash}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Fetches the content from the url with a timeout of 10 seconds.
|
|
211
|
+
* @param url
|
|
212
|
+
* @param integrity
|
|
213
|
+
* @returns
|
|
214
|
+
*/
|
|
215
|
+
async fetch(url, integrity) {
|
|
216
|
+
try {
|
|
217
|
+
const response = await fetch(url, {
|
|
218
|
+
signal: AbortSignal.timeout(this.userConfig.timeout ?? 1e4)
|
|
219
|
+
});
|
|
220
|
+
if (!response.ok) {
|
|
221
|
+
const errorText = await response.text();
|
|
222
|
+
return Promise.reject(new Error(`Error fetching ${url}: ${response.status} ${response.statusText} - ${errorText}`));
|
|
223
|
+
}
|
|
224
|
+
await this.validateIntegrity(response.clone(), url, integrity);
|
|
225
|
+
return response.json();
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (error.name === "TimeoutError") {
|
|
228
|
+
throw new Error(`Request to ${url} timed out`);
|
|
229
|
+
}
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
async issue(payload, disclosureFrame, options) {
|
|
234
|
+
if (payload.iss && !payload.issuer) {
|
|
235
|
+
payload.issuer = {
|
|
236
|
+
id: payload.iss
|
|
237
|
+
};
|
|
238
|
+
delete payload.iss;
|
|
239
|
+
}
|
|
240
|
+
if (payload.nbf && !payload.validFrom) {
|
|
241
|
+
payload.validFrom = toVcdm2Date(payload.nbf);
|
|
242
|
+
delete payload.nbf;
|
|
243
|
+
}
|
|
244
|
+
if (payload.exp && !payload.validUntil) {
|
|
245
|
+
payload.validUntil = toVcdm2Date(payload.exp);
|
|
246
|
+
delete payload.exp;
|
|
247
|
+
}
|
|
248
|
+
if (payload.sub && !Array.isArray(payload.credentialSubject) && !payload.credentialSubject.id) {
|
|
249
|
+
payload.credentialSubject.id = payload.sub;
|
|
250
|
+
delete payload.sub;
|
|
251
|
+
}
|
|
252
|
+
return super.issue(payload, disclosureFrame, options);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
function toVcdm2Date(value) {
|
|
256
|
+
const num = typeof value === "string" ? Number(value) : value;
|
|
257
|
+
if (!Number.isFinite(num)) {
|
|
258
|
+
throw new SDJWTException(`Invalid numeric date: ${value}`);
|
|
259
|
+
}
|
|
260
|
+
return new Date(num * 1e3).toISOString();
|
|
261
|
+
}
|
|
262
|
+
__name(toVcdm2Date, "toVcdm2Date");
|
|
84
263
|
|
|
85
264
|
// src/action-handler.ts
|
|
265
|
+
import * as u8a from "uint8arrays";
|
|
86
266
|
var debug = Debug("@sphereon/ssi-sdk.sd-jwt");
|
|
87
267
|
var SDJwtPlugin = class {
|
|
88
268
|
static {
|
|
@@ -152,7 +332,11 @@ var SDJwtPlugin = class {
|
|
|
152
332
|
* @returns A signed SD-JWT credential.
|
|
153
333
|
*/
|
|
154
334
|
async createSdJwtVc(args, context) {
|
|
155
|
-
const
|
|
335
|
+
const payload = args.credentialPayload;
|
|
336
|
+
const isVcdm2 = isVcdm2SdJwtPayload(payload);
|
|
337
|
+
const isSdJwtVc = isSdjwtVcPayload(payload);
|
|
338
|
+
const type = args.type ?? (isVcdm2 ? "vc+sd-jwt" : "dc+sd-jwt");
|
|
339
|
+
const issuer = getIssuerFromSdJwt(args.credentialPayload);
|
|
156
340
|
if (!issuer) {
|
|
157
341
|
throw new Error("credential.issuer must not be empty");
|
|
158
342
|
}
|
|
@@ -160,24 +344,46 @@ var SDJwtPlugin = class {
|
|
|
160
344
|
identifier: issuer,
|
|
161
345
|
resolution: args.resolution
|
|
162
346
|
}, context);
|
|
163
|
-
const
|
|
347
|
+
const signAlg = alg ?? signingKey?.alg ?? "ES256";
|
|
348
|
+
const hashAlg = /(\d{3})$/.test(signAlg) ? `sha-${signAlg.slice(-3)}` : "sha-256";
|
|
349
|
+
const sdjwt = SDJwtVcdmInstanceFactory.create(type, {
|
|
350
|
+
omitTyp: true,
|
|
164
351
|
signer,
|
|
165
352
|
hasher: this.registeredImplementations.hasher,
|
|
166
353
|
saltGenerator: this.registeredImplementations.saltGenerator,
|
|
167
|
-
signAlg
|
|
168
|
-
hashAlg
|
|
354
|
+
signAlg,
|
|
355
|
+
hashAlg
|
|
169
356
|
});
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
357
|
+
const header = {
|
|
358
|
+
...signingKey?.key.kid !== void 0 && {
|
|
359
|
+
kid: signingKey.key.kid
|
|
360
|
+
},
|
|
361
|
+
...signingKey?.key.x5c !== void 0 && {
|
|
362
|
+
x5c: signingKey.key.x5c
|
|
363
|
+
},
|
|
364
|
+
...type && {
|
|
365
|
+
typ: type
|
|
178
366
|
}
|
|
179
|
-
}
|
|
367
|
+
};
|
|
368
|
+
let credential;
|
|
369
|
+
if (isVcdm2) {
|
|
370
|
+
credential = await sdjwt.issue(
|
|
371
|
+
payload,
|
|
372
|
+
// @ts-ignore
|
|
373
|
+
args.disclosureFrame,
|
|
374
|
+
{
|
|
375
|
+
header
|
|
376
|
+
}
|
|
377
|
+
);
|
|
378
|
+
} else if (isSdJwtVc) {
|
|
379
|
+
credential = await sdjwt.issue(payload, args.disclosureFrame, {
|
|
380
|
+
header
|
|
381
|
+
});
|
|
382
|
+
} else {
|
|
383
|
+
return Promise.reject(new Error(`invalid_argument: credential '${type}' type is not supported`));
|
|
384
|
+
}
|
|
180
385
|
return {
|
|
386
|
+
type,
|
|
181
387
|
credential
|
|
182
388
|
};
|
|
183
389
|
}
|
|
@@ -303,6 +509,7 @@ var SDJwtPlugin = class {
|
|
|
303
509
|
* @returns A signed SD-JWT presentation.
|
|
304
510
|
*/
|
|
305
511
|
async createSdJwtPresentation(args, context) {
|
|
512
|
+
const type = args.type ?? "dc+sd-jwt";
|
|
306
513
|
const cred = await SDJwt.fromEncode(args.presentation, this.registeredImplementations.hasher);
|
|
307
514
|
const claims = await cred.getClaims(this.registeredImplementations.hasher);
|
|
308
515
|
let holder;
|
|
@@ -323,8 +530,9 @@ var SDJwtPlugin = class {
|
|
|
323
530
|
const { alg, signer } = await this.getSignerForIdentifier({
|
|
324
531
|
identifier: holder
|
|
325
532
|
}, context);
|
|
326
|
-
const sdjwt =
|
|
327
|
-
|
|
533
|
+
const sdjwt = SDJwtVcdmInstanceFactory.create(type, {
|
|
534
|
+
omitTyp: true,
|
|
535
|
+
hasher: this.registeredImplementations.hasher,
|
|
328
536
|
saltGenerator: this.registeredImplementations.saltGenerator,
|
|
329
537
|
kbSigner: signer,
|
|
330
538
|
kbSignAlg: alg ?? "ES256"
|
|
@@ -333,6 +541,7 @@ var SDJwtPlugin = class {
|
|
|
333
541
|
kb: args.kb
|
|
334
542
|
});
|
|
335
543
|
return {
|
|
544
|
+
type,
|
|
336
545
|
presentation
|
|
337
546
|
};
|
|
338
547
|
}
|
|
@@ -343,13 +552,18 @@ var SDJwtPlugin = class {
|
|
|
343
552
|
* @returns
|
|
344
553
|
*/
|
|
345
554
|
async verifySdJwtVc(args, context) {
|
|
346
|
-
const verifier = /* @__PURE__ */ __name(async (data, signature) => this.
|
|
347
|
-
const
|
|
555
|
+
const verifier = /* @__PURE__ */ __name(async (data, signature) => this.verifyCallbackImpl(sdjwt, context, data, signature), "verifier");
|
|
556
|
+
const cred = await SDJwt.fromEncode(args.credential, this.registeredImplementations.hasher);
|
|
557
|
+
const type = isVcdm2SdJwtPayload(cred.jwt?.payload) ? "vc+sd-jwt" : "dc+sd-jwt";
|
|
558
|
+
const sdjwt = SDJwtVcdmInstanceFactory.create(type, {
|
|
348
559
|
verifier,
|
|
349
560
|
hasher: this.registeredImplementations.hasher ?? defaultGenerateDigest
|
|
350
561
|
});
|
|
351
|
-
const { header = {}, payload, kb } = await sdjwt.verify(args.credential
|
|
562
|
+
const { header = {}, payload, kb } = await sdjwt.verify(args.credential, {
|
|
563
|
+
skewSeconds: 60 * 60 * 24 * 5
|
|
564
|
+
});
|
|
352
565
|
return {
|
|
566
|
+
type,
|
|
353
567
|
header,
|
|
354
568
|
payload,
|
|
355
569
|
kb
|
|
@@ -364,7 +578,7 @@ var SDJwtPlugin = class {
|
|
|
364
578
|
* @param payload - The payload of the SD-JWT
|
|
365
579
|
* @returns
|
|
366
580
|
*/
|
|
367
|
-
verifyKb(
|
|
581
|
+
verifyKb(context, data, signature, payload) {
|
|
368
582
|
if (!payload.cnf) {
|
|
369
583
|
throw Error("other method than cnf is not supported yet");
|
|
370
584
|
}
|
|
@@ -378,9 +592,10 @@ var SDJwtPlugin = class {
|
|
|
378
592
|
* @param signature - The signature
|
|
379
593
|
* @returns
|
|
380
594
|
*/
|
|
381
|
-
async
|
|
595
|
+
async verifyCallbackImpl(sdjwt, context, data, signature, opts) {
|
|
382
596
|
const decodedVC = await sdjwt.decode(`${data}.${signature}`);
|
|
383
|
-
const
|
|
597
|
+
const payload = decodedVC.jwt.payload;
|
|
598
|
+
const issuer = getIssuerFromSdJwt(payload);
|
|
384
599
|
const header = decodedVC.jwt.header;
|
|
385
600
|
const x5c = header?.x5c;
|
|
386
601
|
let jwk = header.jwk;
|
|
@@ -446,14 +661,18 @@ var SDJwtPlugin = class {
|
|
|
446
661
|
*/
|
|
447
662
|
async verifySdJwtPresentation(args, context) {
|
|
448
663
|
let sdjwt;
|
|
449
|
-
const verifier = /* @__PURE__ */ __name(async (data, signature) => this.
|
|
450
|
-
const verifierKb = /* @__PURE__ */ __name(async (data, signature, payload) => this.verifyKb(
|
|
451
|
-
sdjwt = new
|
|
664
|
+
const verifier = /* @__PURE__ */ __name(async (data, signature) => this.verifyCallbackImpl(sdjwt, context, data, signature), "verifier");
|
|
665
|
+
const verifierKb = /* @__PURE__ */ __name(async (data, signature, payload) => this.verifyKb(context, data, signature, payload), "verifierKb");
|
|
666
|
+
sdjwt = new SDJwtVcInstance2({
|
|
452
667
|
verifier,
|
|
453
668
|
hasher: this.registeredImplementations.hasher,
|
|
454
669
|
kbVerifier: verifierKb
|
|
455
670
|
});
|
|
456
|
-
|
|
671
|
+
const verifierOpts = {
|
|
672
|
+
requiredClaimKeys: args.requiredClaimKeys,
|
|
673
|
+
keyBindingNonce: args.keyBindingNonce
|
|
674
|
+
};
|
|
675
|
+
return sdjwt.verify(args.presentation, verifierOpts);
|
|
457
676
|
}
|
|
458
677
|
/**
|
|
459
678
|
* Fetch and validate Type Metadata.
|
|
@@ -524,7 +743,7 @@ var SDJwtPlugin = class {
|
|
|
524
743
|
return payload.cnf.jwk;
|
|
525
744
|
} else if (payload.cnf !== void 0 && "kid" in payload.cnf && typeof payload.cnf.kid === "string" && payload.cnf.kid.startsWith("did:jwk:")) {
|
|
526
745
|
const encoded = this.extractBase64FromDIDJwk(payload.cnf.kid);
|
|
527
|
-
const decoded =
|
|
746
|
+
const decoded = u8a.toString(u8a.fromString(encoded, "base64url"), "utf-8");
|
|
528
747
|
const jwt = JSON.parse(decoded);
|
|
529
748
|
return jwt;
|
|
530
749
|
}
|
|
@@ -538,26 +757,18 @@ var SDJwtPlugin = class {
|
|
|
538
757
|
return parts[2].split("#")[0];
|
|
539
758
|
}
|
|
540
759
|
};
|
|
541
|
-
|
|
542
|
-
// src/types.ts
|
|
543
|
-
import { contextHasPlugin } from "@sphereon/ssi-sdk.agent-config";
|
|
544
|
-
var sdJwtPluginContextMethods = [
|
|
545
|
-
"createSdJwtVc",
|
|
546
|
-
"createSdJwtPresentation",
|
|
547
|
-
"verifySdJwtVc",
|
|
548
|
-
"verifySdJwtPresentation"
|
|
549
|
-
];
|
|
550
|
-
function contextHasSDJwtPlugin(context) {
|
|
551
|
-
return contextHasPlugin(context, "verifySdJwtVc");
|
|
552
|
-
}
|
|
553
|
-
__name(contextHasSDJwtPlugin, "contextHasSDJwtPlugin");
|
|
554
760
|
export {
|
|
555
761
|
SDJwtPlugin,
|
|
556
762
|
assertValidTypeMetadata,
|
|
557
763
|
contextHasSDJwtPlugin,
|
|
558
764
|
createIntegrity,
|
|
765
|
+
defaultGenerateDigest,
|
|
559
766
|
extractHashFromIntegrity,
|
|
560
767
|
fetchUrlWithErrorHandling,
|
|
768
|
+
getIssuerFromSdJwt,
|
|
769
|
+
isSdjwtVcPayload,
|
|
770
|
+
isVcdm2SdJwt,
|
|
771
|
+
isVcdm2SdJwtPayload,
|
|
561
772
|
sdJwtPluginContextMethods,
|
|
562
773
|
validateIntegrity
|
|
563
774
|
};
|