@injistack/react-inji-verify-sdk 0.19.0-beta.11 → 0.19.0-beta.13
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/README.md
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
# INJI VERIFY SDK
|
|
2
2
|
|
|
3
|
+
**Repository:** [github.com/mosip/inji-verify](https://github.com/mosip/inji-verify)
|
|
4
|
+
|
|
3
5
|
Inji Verify SDK provides ready-to-use **React components** to integrate [OpenID4VP](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html)-based **Verifiable Credential (VC) and Verifiable Presentation (VP) verification** into any React TypeScript web application.
|
|
4
6
|
|
|
7
|
+
## Index
|
|
8
|
+
|
|
9
|
+
1. [Pre-requisites](#pre-requisites)
|
|
10
|
+
2. [Usage Guide](#usage-guide)
|
|
11
|
+
- [Install](#step-1-install-the-package)
|
|
12
|
+
- [Choose Verification Method](#step-3-choose-verification-method)
|
|
13
|
+
- [Verification Response](#verification-response)
|
|
14
|
+
3. [Detailed Component Guide](#detailed-component-guide)
|
|
15
|
+
- [Option A: QR Code Verification](#option-a-qr-code-verification-scan--upload)
|
|
16
|
+
- [Verification Response](#verification-response-1)
|
|
17
|
+
- [Option B: OpenID4VP Verification](#option-b-openid4vp-verification)
|
|
18
|
+
- [Verification Response](#verification-response-2)
|
|
19
|
+
- [DCQL Query](#dcql-query)
|
|
20
|
+
- [`require_cryptographic_holder_binding`](#require_cryptographic_holder_binding)
|
|
21
|
+
4. [Component Options Reference](#️-component-options-reference)
|
|
22
|
+
5. [Important Limitations](#️-important-limitations)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
5
26
|
## Pre-requisites
|
|
6
27
|
|
|
7
28
|
### What You Need:
|
|
@@ -15,7 +36,7 @@ Inji Verify SDK provides ready-to-use **React components** to integrate [OpenID4
|
|
|
15
36
|
Your backend must support the OpenID4VP protocol. You can either:
|
|
16
37
|
|
|
17
38
|
- Use the official `inji-verify-service`
|
|
18
|
-
- Build your own following [this specification](https://openid.net/specs/openid-4-verifiable-presentations-1_0
|
|
39
|
+
- Build your own following [this specification](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html)
|
|
19
40
|
|
|
20
41
|
**Important:** Your backend URL should look like:
|
|
21
42
|
|
|
@@ -78,13 +99,15 @@ function MyApp() {
|
|
|
78
99
|
triggerElement={<button>Show QR for Wallet Scan</button>}
|
|
79
100
|
verifyServiceUrl="https://your-backend.com/v1/verify"
|
|
80
101
|
clientId="did:example:123456789" // DID example
|
|
81
|
-
|
|
102
|
+
dcqlQuery={{
|
|
103
|
+
credentials: [{ id: "id_card", format: "ldp_vc", meta: {} }]
|
|
104
|
+
}}
|
|
82
105
|
isSameDeviceFlowEnabled={false} // QR code flow
|
|
83
106
|
onVPProcessed={(result) => {
|
|
84
107
|
console.log("VP processed:", result);
|
|
85
108
|
}}
|
|
86
109
|
onQrCodeExpired={() => {
|
|
87
|
-
console.log("
|
|
110
|
+
console.log("QR code expired - ask user to retry");
|
|
88
111
|
}}
|
|
89
112
|
onError={(error) => {
|
|
90
113
|
console.error("Verification error:", error);
|
|
@@ -114,7 +137,7 @@ If `summariseResults = true`, the response will be:
|
|
|
114
137
|
"vcResults": [
|
|
115
138
|
{
|
|
116
139
|
"vc": { /* Your verified credential data */ },
|
|
117
|
-
"vcStatus": "SUCCESS" // or
|
|
140
|
+
"vcStatus": "SUCCESS" // or "INVALID", "EXPIRED", "REVOKED"
|
|
118
141
|
}
|
|
119
142
|
],
|
|
120
143
|
"vpResultStatus": "SUCCESS" // Overall verification status
|
|
@@ -265,7 +288,7 @@ If `summariseResults = false`, the response will be:
|
|
|
265
288
|
"allChecksSuccessful": true,
|
|
266
289
|
"schemaAndSignatureCheck": { "valid": true, "error": null },
|
|
267
290
|
"expiryCheck": { "valid": true },
|
|
268
|
-
"
|
|
291
|
+
"statusCheck": [
|
|
269
292
|
{ "purpose": "revocation", "valid": true, "error": null }
|
|
270
293
|
],
|
|
271
294
|
"claims": {...}
|
|
@@ -276,14 +299,18 @@ If `summariseResults = false`, the response will be:
|
|
|
276
299
|
|
|
277
300
|
| Property | Type | Description |
|
|
278
301
|
|---------------------------|---------|-----------------------------------------------------------|
|
|
279
|
-
| `
|
|
280
|
-
| `
|
|
281
|
-
| `
|
|
282
|
-
| `
|
|
283
|
-
| `
|
|
284
|
-
| `
|
|
285
|
-
| `
|
|
286
|
-
| `
|
|
302
|
+
| `vc` | object | The VC that has been verified |
|
|
303
|
+
| `allChecksSuccessful` | boolean | Final aggregated validation flag |
|
|
304
|
+
| `schemaAndSignatureCheck` | object | Schema and signature validation result |
|
|
305
|
+
| `schemaAndSignatureCheck.valid`| boolean | If false, credential signature or schema is invalid |
|
|
306
|
+
| `schemaAndSignatureCheck.error`| object | Non-null if the check could not be performed |
|
|
307
|
+
| `expiryCheck` | object | Expiry validation result |
|
|
308
|
+
| `expiryCheck.valid` | boolean | If false, the credential is EXPIRED |
|
|
309
|
+
| `statusCheck` | array | Contains revocation and other status validations |
|
|
310
|
+
| `statusCheck[].purpose` | string | Identifies purpose (e.g., "revocation") |
|
|
311
|
+
| `statusCheck[].valid` | boolean | If false for revocation and `error` is null → credential is revoked |
|
|
312
|
+
| `statusCheck[].error` | object | Non-null if the status check could not be performed (e.g. status list unreachable) |
|
|
313
|
+
| `claims` | object | Includes all claims from credentialSubject |
|
|
287
314
|
|
|
288
315
|
### Option B: OpenID4VP Verification
|
|
289
316
|
OpenID4VPVerification Component verifies Verifiable Presentations securely using OpenID4VP standards for both cross-device and same-device flows.
|
|
@@ -307,42 +334,24 @@ export default function VerifyCrossDevice() {
|
|
|
307
334
|
triggerElement={<button>Show QR for Wallet Scan</button>}
|
|
308
335
|
verifyServiceUrl="https://your-backend.com/v1/verify"
|
|
309
336
|
clientId="did:example:123456789" // DID example
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
},
|
|
318
|
-
input_descriptors: [
|
|
319
|
-
{
|
|
320
|
-
id: "id-card-check",
|
|
321
|
-
constraints: {
|
|
322
|
-
fields: [
|
|
323
|
-
{
|
|
324
|
-
path: ["$.type"],
|
|
325
|
-
filter: {
|
|
326
|
-
type: "object",
|
|
327
|
-
pattern: "DriverLicenseCredential",
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
|
-
],
|
|
331
|
-
},
|
|
332
|
-
},
|
|
333
|
-
],
|
|
337
|
+
dcqlQuery={{
|
|
338
|
+
credentials: [{
|
|
339
|
+
id: "id_card",
|
|
340
|
+
format: "ldp_vc",
|
|
341
|
+
meta: { type_values: [["DriverLicenseCredential"]] },
|
|
342
|
+
claims: [{ path: ["name"] }]
|
|
343
|
+
}]
|
|
334
344
|
}}
|
|
335
345
|
isSameDeviceFlowEnabled={false} // QR code flow
|
|
336
346
|
onVPProcessed={(result) => {
|
|
337
347
|
console.log("VP processed:", result);
|
|
338
348
|
}}
|
|
339
349
|
onQrCodeExpired={() => {
|
|
340
|
-
console.log("
|
|
350
|
+
console.log("QR code expired - ask user to retry");
|
|
341
351
|
}}
|
|
342
352
|
onError={(error) => {
|
|
343
353
|
console.error("Verification error:", error);
|
|
344
354
|
}}
|
|
345
|
-
|
|
346
355
|
/>
|
|
347
356
|
);
|
|
348
357
|
}
|
|
@@ -354,28 +363,17 @@ sequenceDiagram
|
|
|
354
363
|
participant VerifierBackend as Verifier Backend
|
|
355
364
|
participant MobileWallet as Wallet (Mobile)
|
|
356
365
|
|
|
357
|
-
UserBrowser->>VerifierBackend:
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (txn_id)
|
|
361
|
-
VerifierBackend-->>UserBrowser: Return OpenID4VP request + QR code
|
|
362
|
-
|
|
366
|
+
UserBrowser->>VerifierBackend: POST /v2/vp-session-request
|
|
367
|
+
VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (transaction_id) + authorization request
|
|
368
|
+
UserBrowser->>UserBrowser: SDK generates QR code from authorization request
|
|
363
369
|
UserBrowser->>MobileWallet: User scans QR code
|
|
364
|
-
|
|
365
|
-
MobileWallet->>VerifierBackend: Submit vp_token + presentation_submission
|
|
366
|
-
|
|
370
|
+
MobileWallet->>VerifierBackend: POST /v2/vp-submission/direct-post (vp_token)
|
|
367
371
|
loop Long Polling
|
|
368
372
|
UserBrowser->>VerifierBackend: GET /vp-request/{requestId}/status
|
|
369
|
-
VerifierBackend-->>UserBrowser:
|
|
373
|
+
VerifierBackend-->>UserBrowser: ACTIVE
|
|
370
374
|
end
|
|
371
|
-
|
|
372
|
-
VerifierBackend
|
|
373
|
-
|
|
374
|
-
UserBrowser->>VerifierBackend: GET /vp-session-results (Cookie txn_id automatically sent)
|
|
375
|
-
|
|
376
|
-
VerifierBackend->>VerifierBackend: Resolve txn_id from cookie
|
|
377
|
-
VerifierBackend->>VerifierBackend: Fetch transaction state
|
|
378
|
-
|
|
375
|
+
VerifierBackend-->>UserBrowser: VP_SUBMITTED
|
|
376
|
+
UserBrowser->>VerifierBackend: POST /vp-session-results (Cookie auto-sent)
|
|
379
377
|
VerifierBackend-->>UserBrowser: Verification result
|
|
380
378
|
```
|
|
381
379
|
|
|
@@ -390,30 +388,12 @@ export default function VerifySameDevice() {
|
|
|
390
388
|
triggerElement={<button>Verify with Wallet</button>}
|
|
391
389
|
verifyServiceUrl="https://your-backend.com/v1/verify"
|
|
392
390
|
clientId="client-12345" // non-DID example
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
},
|
|
400
|
-
},
|
|
401
|
-
input_descriptors: [
|
|
402
|
-
{
|
|
403
|
-
id: "id-card-check",
|
|
404
|
-
constraints: {
|
|
405
|
-
fields: [
|
|
406
|
-
{
|
|
407
|
-
path: ["$.type"],
|
|
408
|
-
filter: {
|
|
409
|
-
type: "object",
|
|
410
|
-
pattern: "DriverLicenseCredential",
|
|
411
|
-
},
|
|
412
|
-
},
|
|
413
|
-
],
|
|
414
|
-
},
|
|
415
|
-
},
|
|
416
|
-
],
|
|
391
|
+
dcqlQuery={{
|
|
392
|
+
credentials: [{
|
|
393
|
+
id: "id_card",
|
|
394
|
+
format: "ldp_vc",
|
|
395
|
+
meta: { type_values: [["DriverLicenseCredential"]] }
|
|
396
|
+
}]
|
|
417
397
|
}}
|
|
418
398
|
isSameDeviceFlowEnabled={true} //default value
|
|
419
399
|
// No webWalletBaseUrl → triggers mobile wallet via deep link
|
|
@@ -431,36 +411,22 @@ export default function VerifySameDevice() {
|
|
|
431
411
|
```mermaid
|
|
432
412
|
sequenceDiagram
|
|
433
413
|
autonumber
|
|
434
|
-
participant UserBrowser as User Browser
|
|
414
|
+
participant UserBrowser as User Browser
|
|
435
415
|
participant VerifierBackend as Verifier Backend
|
|
436
416
|
participant MobileWallet as Mobile Wallet App
|
|
437
417
|
|
|
438
|
-
UserBrowser->>VerifierBackend:
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
VerifierBackend
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
UserBrowser->>MobileWallet: Open mobile wallet via deep link
|
|
445
|
-
|
|
446
|
-
MobileWallet->>VerifierBackend: Submit vp_token + presentation_submission
|
|
447
|
-
|
|
448
|
-
Note right of MobileWallet: User manually switches back to browser
|
|
449
|
-
|
|
418
|
+
UserBrowser->>VerifierBackend: POST /v2/vp-session-request
|
|
419
|
+
VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (transaction_id) + authorization request
|
|
420
|
+
UserBrowser->>MobileWallet: Open via deep link
|
|
421
|
+
MobileWallet->>VerifierBackend: POST /v2/vp-submission/direct-post (vp_token)
|
|
422
|
+
Note right of MobileWallet: User switches back to browser
|
|
450
423
|
loop Long Polling
|
|
451
424
|
UserBrowser->>VerifierBackend: GET /vp-request/{requestId}/status
|
|
452
|
-
VerifierBackend-->>UserBrowser:
|
|
425
|
+
VerifierBackend-->>UserBrowser: ACTIVE
|
|
453
426
|
end
|
|
454
|
-
|
|
455
|
-
VerifierBackend
|
|
456
|
-
|
|
457
|
-
UserBrowser->>VerifierBackend: GET /vp-session-results (Cookie txn_id automatically sent)
|
|
458
|
-
|
|
459
|
-
VerifierBackend->>VerifierBackend: Resolve txn_id from cookie
|
|
460
|
-
VerifierBackend->>VerifierBackend: Fetch transaction state
|
|
461
|
-
|
|
427
|
+
VerifierBackend-->>UserBrowser: VP_SUBMITTED
|
|
428
|
+
UserBrowser->>VerifierBackend: POST /vp-session-results (Cookie auto-sent)
|
|
462
429
|
VerifierBackend-->>UserBrowser: Verification result
|
|
463
|
-
VerifierBackend-->>UserBrowser: Clear cookie (txn_id)
|
|
464
430
|
```
|
|
465
431
|
|
|
466
432
|
#### 3. Same Device Flow with Web Wallet
|
|
@@ -474,30 +440,12 @@ export default function VerifySameDevice() {
|
|
|
474
440
|
triggerElement={<button>Verify with Wallet</button>}
|
|
475
441
|
verifyServiceUrl="https://your-backend.com/v1/verify"
|
|
476
442
|
clientId="did:example:123456789" // DID example
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
},
|
|
484
|
-
},
|
|
485
|
-
input_descriptors: [
|
|
486
|
-
{
|
|
487
|
-
id: "id-card-check",
|
|
488
|
-
constraints: {
|
|
489
|
-
fields: [
|
|
490
|
-
{
|
|
491
|
-
path: ["$.type"],
|
|
492
|
-
filter: {
|
|
493
|
-
type: "object",
|
|
494
|
-
pattern: "DriverLicenseCredential",
|
|
495
|
-
},
|
|
496
|
-
},
|
|
497
|
-
],
|
|
498
|
-
},
|
|
499
|
-
},
|
|
500
|
-
],
|
|
443
|
+
dcqlQuery={{
|
|
444
|
+
credentials: [{
|
|
445
|
+
id: "id_card",
|
|
446
|
+
format: "ldp_vc",
|
|
447
|
+
meta: { type_values: [["DriverLicenseCredential"]] }
|
|
448
|
+
}]
|
|
501
449
|
}}
|
|
502
450
|
isSameDeviceFlowEnabled={true} //default value
|
|
503
451
|
webWalletBaseUrl="https://wallet.example.com" // required to support web-wallets
|
|
@@ -519,28 +467,14 @@ sequenceDiagram
|
|
|
519
467
|
participant VerifierBackend as Verifier Backend
|
|
520
468
|
participant WebWallet as Web Wallet
|
|
521
469
|
|
|
522
|
-
UserBrowser->>VerifierBackend:
|
|
523
|
-
|
|
524
|
-
VerifierBackend->>VerifierBackend: Generate transaction_id\nand request_id
|
|
525
|
-
VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (txn_id)
|
|
526
|
-
VerifierBackend-->>UserBrowser: Return OpenID4VP authorization request
|
|
527
|
-
|
|
470
|
+
UserBrowser->>VerifierBackend: POST /v2/vp-session-request (responseCodeValidationRequired=true)
|
|
471
|
+
VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (transaction_id) + authorization request
|
|
528
472
|
UserBrowser->>WebWallet: Open Web Wallet
|
|
529
|
-
|
|
530
|
-
WebWallet
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
WebWallet-->>UserBrowser: Redirect to redirect_uri
|
|
534
|
-
|
|
535
|
-
UserBrowser->>UserBrowser: Extract response_code
|
|
536
|
-
|
|
537
|
-
UserBrowser->>VerifierBackend: GET /vp-session-results?response_code=xyz\n(Cookie txn_id automatically sent)
|
|
538
|
-
|
|
539
|
-
VerifierBackend->>VerifierBackend: Validate response_code + txn_id
|
|
540
|
-
VerifierBackend->>VerifierBackend: Fetch transaction state
|
|
541
|
-
|
|
473
|
+
WebWallet->>VerifierBackend: POST /v2/vp-submission/direct-post (vp_token)
|
|
474
|
+
VerifierBackend-->>WebWallet: response_code
|
|
475
|
+
WebWallet-->>UserBrowser: Redirect with response_code
|
|
476
|
+
UserBrowser->>VerifierBackend: POST /vp-session-results?response_code=... (Cookie auto-sent)
|
|
542
477
|
VerifierBackend-->>UserBrowser: Verification result
|
|
543
|
-
VerifierBackend-->>UserBrowser: Clear cookie (txn_id)
|
|
544
478
|
```
|
|
545
479
|
|
|
546
480
|
> **NOTE**
|
|
@@ -559,31 +493,13 @@ export default function VerifyServerToServer() {
|
|
|
559
493
|
triggerElement={<button>Start Verification</button>}
|
|
560
494
|
verifyServiceUrl="https://your-backend.com/v1/verify"
|
|
561
495
|
clientId="did:example:123456789" // DID example
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
},
|
|
570
|
-
input_descriptors: [
|
|
571
|
-
{
|
|
572
|
-
id: "id-card-check",
|
|
573
|
-
constraints: {
|
|
574
|
-
fields: [
|
|
575
|
-
{
|
|
576
|
-
path: ["$.type"],
|
|
577
|
-
filter: {
|
|
578
|
-
type: "object",
|
|
579
|
-
pattern: "DriverLicenseCredential",
|
|
580
|
-
},
|
|
581
|
-
},
|
|
582
|
-
],
|
|
583
|
-
},
|
|
584
|
-
},
|
|
585
|
-
],
|
|
586
|
-
}}
|
|
496
|
+
dcqlQuery={{
|
|
497
|
+
credentials: [{
|
|
498
|
+
id: "id_card",
|
|
499
|
+
format: "ldp_vc",
|
|
500
|
+
meta: { type_values: [["DriverLicenseCredential"]] }
|
|
501
|
+
}]
|
|
502
|
+
}}
|
|
587
503
|
isSameDeviceFlowEnabled={false}
|
|
588
504
|
onVPReceived={(transactionId) => {
|
|
589
505
|
//using the transactionId one can securely fetch the result from service
|
|
@@ -604,18 +520,31 @@ export default function VerifyServerToServer() {
|
|
|
604
520
|
|
|
605
521
|
Once VP Verification is complete, the response depends on the `summariseResults` attribute (default = true)
|
|
606
522
|
|
|
607
|
-
If `summariseResults = true`, the response will be
|
|
523
|
+
If `summariseResults = true`, the response will be an array with one element per credential. Each element's `verificationResponse` contains the full `vcResults` list and the overall `vpResultStatus`:
|
|
608
524
|
|
|
609
525
|
```javascript
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
526
|
+
[
|
|
527
|
+
{
|
|
528
|
+
"vc": { /* credential-1 data */ },
|
|
529
|
+
"verificationResponse": {
|
|
530
|
+
"vcResults": [
|
|
531
|
+
{ "vc": { /* credential-1 data */ }, "vcStatus": "SUCCESS" }, // or "INVALID", "EXPIRED", "REVOKED"
|
|
532
|
+
{ "vc": { /* credential-2 data */ }, "vcStatus": "SUCCESS" }
|
|
533
|
+
],
|
|
534
|
+
"vpResultStatus": "SUCCESS" // or "INVALID" — overall verification status
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
"vc": { /* credential-2 data */ },
|
|
539
|
+
"verificationResponse": {
|
|
540
|
+
"vcResults": [
|
|
541
|
+
{ "vc": { /* credential-1 data */ }, "vcStatus": "SUCCESS" },
|
|
542
|
+
{ "vc": { /* credential-2 data */ }, "vcStatus": "SUCCESS" }
|
|
543
|
+
],
|
|
544
|
+
"vpResultStatus": "SUCCESS"
|
|
618
545
|
}
|
|
546
|
+
}
|
|
547
|
+
]
|
|
619
548
|
```
|
|
620
549
|
|
|
621
550
|
If `summariseResults = false`, the response will be:
|
|
@@ -623,83 +552,114 @@ If `summariseResults = false`, the response will be:
|
|
|
623
552
|
```javascript
|
|
624
553
|
{
|
|
625
554
|
"transactionId": "txn_11",
|
|
626
|
-
|
|
627
|
-
|
|
555
|
+
"allChecksSuccessful": true,
|
|
556
|
+
"credentialResults": [
|
|
628
557
|
{
|
|
629
558
|
"verifiableCredential": "{...}",
|
|
630
559
|
"allChecksSuccessful": true,
|
|
631
560
|
"holderProofCheck": { "valid": true, "error": null },
|
|
632
561
|
"schemaAndSignatureCheck": { "valid": true, "error": null },
|
|
633
562
|
"expiryCheck": { "valid": true },
|
|
634
|
-
"
|
|
563
|
+
"statusCheck": [
|
|
635
564
|
{ "purpose": "revocation", "valid": true, "error": null }
|
|
636
565
|
],
|
|
637
|
-
"claims": {
|
|
566
|
+
"claims": {...}
|
|
638
567
|
}
|
|
639
568
|
]
|
|
640
|
-
}
|
|
569
|
+
}
|
|
641
570
|
```
|
|
642
571
|
|
|
643
572
|
#### Response Fields Summary
|
|
644
573
|
|
|
645
574
|
| Property | Type | Description |
|
|
646
575
|
|---------------------------|---------|-----------------------------------------------------------|
|
|
647
|
-
| `allChecksSuccessful`
|
|
648
|
-
| `verifiableCredential`
|
|
649
|
-
| `holderProofCheck`
|
|
650
|
-
| `
|
|
651
|
-
| `
|
|
652
|
-
| `
|
|
653
|
-
| `
|
|
654
|
-
| `
|
|
655
|
-
| `
|
|
656
|
-
| `
|
|
657
|
-
|
|
658
|
-
|
|
576
|
+
| `allChecksSuccessful` | boolean | Final aggregated validation flag |
|
|
577
|
+
| `verifiableCredential` | string | The VC that has been verified |
|
|
578
|
+
| `holderProofCheck` | object | Holder binding result. `null` when `require_cryptographic_holder_binding=false` |
|
|
579
|
+
| `holderProofCheck.valid` | boolean | If false, presenter does not own the credential |
|
|
580
|
+
| `holderProofCheck.error` | object | Non-null if the check could not be performed |
|
|
581
|
+
| `schemaAndSignatureCheck` | object | Schema and signature validation result |
|
|
582
|
+
| `schemaAndSignatureCheck.valid`| boolean | If false, credential signature or schema is invalid |
|
|
583
|
+
| `schemaAndSignatureCheck.error`| object | Non-null if the check could not be performed |
|
|
584
|
+
| `expiryCheck` | object | Expiry validation result |
|
|
585
|
+
| `expiryCheck.valid` | boolean | If false, the credential is EXPIRED |
|
|
586
|
+
| `statusCheck` | array | Contains revocation and other status validations |
|
|
587
|
+
| `statusCheck[].purpose` | string | Identifies purpose (e.g., "revocation") |
|
|
588
|
+
| `statusCheck[].valid` | boolean | If false for revocation and `error` is null → credential is revoked |
|
|
589
|
+
| `statusCheck[].error` | object | Non-null if the status check could not be performed (e.g. status list unreachable) |
|
|
590
|
+
| `claims` | object | Includes all claims from credentialSubject |
|
|
591
|
+
|
|
592
|
+
### DCQL Query:
|
|
593
|
+
|
|
594
|
+
The `dcqlQuery` prop describes which credentials to request from the wallet, following the [DCQL (Digital Credentials Query Language)](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html) format.
|
|
595
|
+
|
|
596
|
+
> **Unsupported:** `trusted_authorities` is not currently supported. DCQL queries containing `trusted_authorities` will be rejected with `UNKNOWN_FIELD`.
|
|
597
|
+
|
|
598
|
+
**Minimal example — request a single ldp_vc:**
|
|
659
599
|
|
|
660
|
-
|
|
600
|
+
```javascript
|
|
601
|
+
dcqlQuery={{
|
|
602
|
+
credentials: [{
|
|
603
|
+
id: "id_card",
|
|
604
|
+
format: "ldp_vc",
|
|
605
|
+
meta: { type_values: [["DriverLicenseCredential"]] }
|
|
606
|
+
}]
|
|
607
|
+
}}
|
|
608
|
+
```
|
|
661
609
|
|
|
662
|
-
**
|
|
610
|
+
**Request specific claims:**
|
|
663
611
|
|
|
664
612
|
```javascript
|
|
665
|
-
|
|
613
|
+
dcqlQuery={{
|
|
614
|
+
credentials: [{
|
|
615
|
+
id: "id_card",
|
|
616
|
+
format: "dc+sd-jwt",
|
|
617
|
+
meta: { vct_values: ["DriverLicenseCredential"] },
|
|
618
|
+
claims: [
|
|
619
|
+
{ path: ["given_name"] },
|
|
620
|
+
{ path: ["birth_date"] }
|
|
621
|
+
]
|
|
622
|
+
}]
|
|
623
|
+
}}
|
|
666
624
|
```
|
|
667
625
|
|
|
668
|
-
**
|
|
626
|
+
**Request multiple credential types (OR logic via credential_sets):**
|
|
669
627
|
|
|
670
628
|
```javascript
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
ldp_vc: {
|
|
676
|
-
proof_type: ["Ed25519Signature2020"],
|
|
677
|
-
},
|
|
678
|
-
},
|
|
679
|
-
input_descriptors: [
|
|
680
|
-
{
|
|
681
|
-
id: "id-card-check",
|
|
682
|
-
constraints: {
|
|
683
|
-
fields: [
|
|
684
|
-
{
|
|
685
|
-
path: ["$.type"],
|
|
686
|
-
filter: {
|
|
687
|
-
type: "object",
|
|
688
|
-
pattern: "DriverLicenseCredential",
|
|
689
|
-
},
|
|
690
|
-
},
|
|
691
|
-
],
|
|
692
|
-
},
|
|
693
|
-
},
|
|
629
|
+
dcqlQuery={{
|
|
630
|
+
credentials: [
|
|
631
|
+
{ id: "mdl", format: "dc+sd-jwt", meta: { vct_values: ["DriverLicense"] } },
|
|
632
|
+
{ id: "pid", format: "ldp_vc", meta: { type_values: [["PersonalID"]] } }
|
|
694
633
|
],
|
|
634
|
+
credential_sets: [
|
|
635
|
+
{ options: [["mdl"], ["pid"]] } // wallet can satisfy with either
|
|
636
|
+
]
|
|
637
|
+
}}
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
**`require_cryptographic_holder_binding` — holder binding control:**
|
|
641
|
+
|
|
642
|
+
Each credential entry in `dcqlQuery` supports a `require_cryptographic_holder_binding` flag (default `true`) that controls whether the wallet must prove it cryptographically owns the credential:
|
|
643
|
+
|
|
644
|
+
| Value | Behavior | `holderProofCheck` in result |
|
|
645
|
+
|---|---|---|
|
|
646
|
+
| `true` (default) | Wallet must wrap the VC in a signed VP. The verifier checks that the presenter owns the credential. | Populated — `valid: true` if holder proof passes |
|
|
647
|
+
| `false` | Wallet may submit the VC without a VP wrapper (bare VC). No holder binding check is performed. | `null` |
|
|
648
|
+
|
|
649
|
+
Format-specific behavior:
|
|
650
|
+
- **`ldp_vc`**: when `true`, wallet submits a JSON-LD VP with a `proof` field; when `false`, bare VC is accepted.
|
|
651
|
+
- **`dc+sd-jwt` / `vc+sd-jwt`**: when `true`, a KB-JWT (Key Binding JWT) is required, containing `aud`, `nonce`, `iat`, and `sd_hash`; when `false`, KB-JWT is skipped.
|
|
652
|
+
|
|
653
|
+
```javascript
|
|
654
|
+
dcqlQuery={{
|
|
655
|
+
credentials: [{
|
|
656
|
+
id: "id_card",
|
|
657
|
+
format: "ldp_vc",
|
|
658
|
+
meta: { type_values: [["DriverLicenseCredential"]] },
|
|
659
|
+
require_cryptographic_holder_binding: false // accept bare VC, skip holder check
|
|
660
|
+
}]
|
|
695
661
|
}}
|
|
696
662
|
```
|
|
697
|
-
> **NOTE**
|
|
698
|
-
>
|
|
699
|
-
> Only one of presentationDefinitionId or presentationDefinition should be provided at a time.
|
|
700
|
-
> It is recommended to use:
|
|
701
|
-
>- presentationDefinitionId when leveraging predefined templates.
|
|
702
|
-
>- presentationDefinition when custom verification requirements are needed.
|
|
703
663
|
|
|
704
664
|
## 🎛️ Component Options Reference
|
|
705
665
|
|
|
@@ -712,7 +672,6 @@ presentationDefinition={{
|
|
|
712
672
|
| `triggerElement` | React element | ❌ | Custom button/element to start verification |
|
|
713
673
|
| `transactionId` | string | ❌ | Optional client-side tracking ID |
|
|
714
674
|
| `clientId` | string | ✅ | Client identifier (DID or Non-DID) |
|
|
715
|
-
| `acceptVPWithoutHolderProof` | boolean | ❌ | Allow unsigned Verifiable Presentations |
|
|
716
675
|
| `summariseResults` | boolean | ❌ | Decides format of SDK Response |
|
|
717
676
|
|
|
718
677
|
### QRCodeVerification Specific
|
|
@@ -730,17 +689,16 @@ presentationDefinition={{
|
|
|
730
689
|
|
|
731
690
|
### OpenID4VPVerification Specific
|
|
732
691
|
|
|
733
|
-
| Property
|
|
734
|
-
|
|
735
|
-
| `
|
|
736
|
-
| `
|
|
737
|
-
| `
|
|
738
|
-
| `
|
|
739
|
-
| `
|
|
740
|
-
| `onQrCodeExpired` | function | - | Handle QR code expiration |
|
|
692
|
+
| Property | Type | Default | Description |
|
|
693
|
+
|---------------------------| -------- |----------------|-------------------------------------------|
|
|
694
|
+
| `dcqlQuery` | object | - | DCQL query describing requested credentials (required) |
|
|
695
|
+
| `protocol` | string | "openid4vp://" | Protocol for QR codes (optional) |
|
|
696
|
+
| `onVPProcessed` | function | - | Get full results immediately |
|
|
697
|
+
| `onVPReceived` | function | - | Get transaction ID only |
|
|
698
|
+
| `onQrCodeExpired` | function | - | Handle QR code expiration |
|
|
741
699
|
| `isSameDeviceFlowEnabled` | boolean | true | Enable same-device flow (optional) |
|
|
742
|
-
| `qrCodeStyles`
|
|
743
|
-
| `vpVerificationRequest`
|
|
700
|
+
| `qrCodeStyles` | object | - | Customize QR code appearance |
|
|
701
|
+
| `vpVerificationRequest` | object | - | contains request body for VP Verification |
|
|
744
702
|
|
|
745
703
|
## ⚠️ Important Limitations
|
|
746
704
|
|