@injistack/react-inji-verify-sdk 0.18.0-beta.28 → 0.18.0-beta.29

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
@@ -2,6 +2,32 @@
2
2
 
3
3
  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
4
 
5
+ ## Pre-requisites
6
+
7
+ ### What You Need:
8
+
9
+ 1. **A React project** (TypeScript recommended)
10
+ 2. **A verification backend** - You need a server that can verify credentials
11
+ 3. **Camera permissions** - For QR scanning features
12
+
13
+ ### Backend Requirements:
14
+
15
+ Your backend must support the OpenID4VP protocol. You can either:
16
+
17
+ - Use the official `inji-verify-service`
18
+ - Build your own following [this specification](https://openid.net/specs/openid-4-verifiable-presentations-1_0-ID3.html)
19
+
20
+ **Important:** Your backend URL should look like:
21
+
22
+ ```
23
+ https://your-backend.com/v1/verify
24
+ ```
25
+
26
+ > **Note**
27
+ >
28
+ > - The SDK uses a session-based verification flow internally.
29
+ > - Session handling, redirects, and result fetching are managed by the SDK.
30
+ > - No manual handling of `transactionId` or browser storage is required.
5
31
  ## Usage Guide
6
32
 
7
33
  ### Step 1: Install the Package
@@ -10,7 +36,7 @@ Inji Verify SDK provides ready-to-use **React components** to integrate [OpenID4
10
36
  npm i @injistack/react-inji-verify-sdk
11
37
  ```
12
38
 
13
- ### Step 2: Import and Use
39
+ ### Step 2: Import & Usage
14
40
 
15
41
  ```javascript
16
42
  import {
@@ -19,7 +45,7 @@ import {
19
45
  } from "@injistack/react-inji-verify-sdk";
20
46
  ```
21
47
 
22
- ### Step 3: Choose Your Verification Method
48
+ ### Step 3: Choose Verification Method
23
49
 
24
50
  **Option A: QR Code Verification (Scan & Upload)**
25
51
 
@@ -27,7 +53,109 @@ import {
27
53
  function MyApp() {
28
54
  return (
29
55
  <QRCodeVerification
30
- verifyServiceUrl="https://your-backend.com/verify"
56
+ triggerElement={triggerElement} //UI element used to start verification.
57
+ verifyServiceUrl="https://your-backend.com/v1/verify"
58
+ isEnableScan={false}
59
+ onVCProcessed={(result) => {
60
+ console.log("Verification complete:", result);
61
+ // Handle the verification result here
62
+ }}
63
+ onError={(error) => {
64
+ console.log("Something went wrong:", error);
65
+ }}
66
+ clientId="did:example:123456789" // DID example
67
+ />
68
+ );
69
+ }
70
+ ```
71
+
72
+ **Option B: OpenID4VP Verification**
73
+
74
+ ```javascript
75
+ function MyApp() {
76
+ return (
77
+ <OpenID4VPVerification
78
+ triggerElement={<button>Show QR for Wallet Scan</button>}
79
+ verifyServiceUrl="https://your-backend.com/v1/verify"
80
+ clientId="did:example:123456789" // DID example
81
+ presentationDefinitionId="your-definition-id"
82
+ isSameDeviceFlowEnabled={false} // QR code flow
83
+ onVPProcessed={(result) => {
84
+ console.log("VP processed:", result);
85
+ }}
86
+ onQrCodeExpired={() => {
87
+ console.log(" QR code expired - ask user to retry");
88
+ }}
89
+ onError={(error) => {
90
+ console.error("Verification error:", error);
91
+ }}
92
+ />
93
+ );
94
+ }
95
+ ```
96
+
97
+ ## Verification Response
98
+
99
+ Once verification is complete, the response depends on the `summariseResults` attribute (default = true)
100
+
101
+ If `summariseResults = true`, the response will be:
102
+
103
+ #### For QRCodeVerification (Upload / Scan):
104
+
105
+
106
+ ```javascript
107
+ {
108
+ "verificationStatus":"STATUS"
109
+ }
110
+ ```
111
+ #### For OpenID4VPVerification:
112
+ ```javascript
113
+ {
114
+ "vcResults": [
115
+ {
116
+ "vc": { /* Your verified credential data */ },
117
+ "vcStatus": "SUCCESS" // or "INVALID", "EXPIRED"
118
+ }
119
+ ],
120
+ "vpResultStatus": "SUCCESS" // Overall verification status
121
+ }
122
+ ```
123
+
124
+ > **Security Recommendation**
125
+ >
126
+ > Avoid consuming results directly from VPProcessed or VCProcessed.
127
+ > Instead, use VPReceived or VCReceived events to capture the transactionId, then retrieve the verification results securely from your backend's verification service endpoint.
128
+ > This ensures data integrity and prevents reliance on client-side verification data for final decisions.
129
+
130
+ ## Detailed Component Guide
131
+ The following sections provide advanced usage and detailed configuration for each component.
132
+ > The package should already be installed as described in the Usage Guide.
133
+
134
+ ### Option A: QR Code Verification (Scan & Upload)
135
+
136
+ The QRCodeVerification component enables end-to-end Verifiable Credential (VC) verification using QR codes in Inji-Verify. It supports both camera-based scanning and file upload for QR code verification.
137
+
138
+ **Perfect for:** Scanning QR codes from documents, or uploading QR codes (PNG, JPEG, JPG, PDF) within the supported size range of 10 KB to 5 MB.
139
+
140
+ Follow these steps to integrate:
141
+
142
+ #### Import & Usage
143
+
144
+ ```javascript
145
+ import {QRCodeVerification} from "@injistack/react-inji-verify-sdk";
146
+ ```
147
+
148
+ #### 1. Uploading a Verifiable Credential (VC) for verification
149
+
150
+ a. Client-side handling (onVCProcessed)
151
+
152
+ ```javascript
153
+ function MyApp() {
154
+ return (
155
+ <QRCodeVerification
156
+ triggerElement={triggerElement} //UI element used to start verification.
157
+ verifyServiceUrl="https://your-backend.com/v1/verify"
158
+ isEnableScan={false}
31
159
  onVCProcessed={(result) => {
32
160
  console.log("Verification complete:", result);
33
161
  // Handle the verification result here
@@ -35,206 +163,509 @@ function MyApp() {
35
163
  onError={(error) => {
36
164
  console.log("Something went wrong:", error);
37
165
  }}
38
- triggerElement={<button>📷 Scan ID Document</button>}
39
- clientId="CLIENT_ID"
166
+ clientId="did:example:123456789" // DID example
167
+ />
168
+ );
169
+ }
170
+ ```
171
+ b. Server-to-server handling (onVCReceived)
172
+ ```javascript
173
+ function MyApp() {
174
+ return (
175
+ <QRCodeVerification
176
+ triggerElement={triggerElement}
177
+ verifyServiceUrl="https://your-backend.com/v1/verify"
178
+ isEnableScan={false}
179
+ onVCReceived={(transactionId) => {
180
+ //using the transactionId, one can securely fetch the result from service
181
+ console.log("VC received transactionId:", transactionId);
182
+ }}
183
+ onError={(error) => {
184
+ console.log("Something went wrong:", error);
185
+ }}
186
+ clientId="client-12345" // non-DID example
40
187
  />
41
188
  );
42
189
  }
43
190
  ```
44
191
 
45
- **Option B: OpenID4VP Verification**
192
+ > 🔁 **Verification Handling Modes**
193
+ >
194
+ > **Client-side Handling (`onVCProcessed` / `onVPProcessed`)**
195
+ > - SDK returns verification result directly to frontend
196
+ > - Faster and simple
197
+ >
198
+ > **Server-to-server Handling (`onVCReceived` / `onVPReceived`)**
199
+ > - SDK returns only `transactionId`
200
+ > - Backend fetches result securely
201
+
202
+ #### 2. Scanning a Verifiable Credential (VC) Using Device Camera
203
+
204
+ a. Client-side handling (onVCProcessed)
46
205
 
47
206
  ```javascript
48
207
  function MyApp() {
49
208
  return (
50
- <OpenID4VPVerification
209
+ <QRCodeVerification
210
+ scannerActive={scannerActive}
51
211
  verifyServiceUrl="https://your-backend.com/v1/verify"
52
- presentationDefinitionId="your-definition-id"
53
- onVpProcessed={(result) => {
54
- console.log("Wallet verification complete:", result);
212
+ isEnableUpload={false}
213
+ onClose={onClose} // invoked when scanner is closed
214
+ onVCProcessed={(result) => {
215
+ console.log("Verification complete:", result);
55
216
  // Handle the verification result here
56
217
  }}
57
- onQrCodeExpired={() => alert("QR code expired, please try again")}
58
- onError={(error) => console.log("Error:", error)}
59
- triggerElement={<button>📱 Verify with Digital Wallet</button>}
60
- clientId="CLIENT_ID"
218
+ onError={(error) => {
219
+ console.log("Something went wrong:", error);
220
+ }}
221
+ clientId="did:example:123456789" // DID example
61
222
  />
62
223
  );
63
224
  }
64
225
  ```
226
+ b. Server-to-server handling (onVCReceived)
65
227
 
66
- ## Response Received
228
+ ```javascript
229
+ function MyApp() {
230
+ return (
231
+ <QRCodeVerification
232
+ scannerActive={scannerActive}
233
+ verifyServiceUrl="https://your-backend.com/v1/verify"
234
+ isEnableUpload={false}
235
+ onClose={onClose} // invoked when scanner is closed
236
+ onVCReceived={(transactionId) => {
237
+ //using the transactionId, one can securely fetch the result from service
238
+ console.log("VC received transactionId:", transactionId);
239
+ }}
240
+ onError={(error) => {
241
+ console.log("Something went wrong:", error);
242
+ }}
243
+ clientId="did:example:123456789" // DID example
244
+ />
245
+ );
246
+ }
247
+ ```
67
248
 
68
- When verification is completed, the response received is based on summariseResults attribute which will decide the format of the response from SDK.
249
+ ### Verification Response
69
250
 
70
- ### QRCodeVerification
251
+ Once VC Verification is complete, the response depends on the `summariseResults` attribute (default = true)
252
+
253
+ If `summariseResults = true`, the response will be:
71
254
 
72
- If summariseResults=true, then response should be
73
255
  ```javascript
74
256
  {
75
257
  "verificationStatus":"STATUS"
76
258
  }
77
259
  ```
78
- If summariseResults=false, then response should be
260
+
261
+ If `summariseResults = false`, the response will be:
262
+
79
263
  ```javascript
80
264
  {
81
- "allChecksSuccessful": true,
82
- "schemaAndSignatureCheck": { "valid": true, "error": null },
265
+ "allChecksSuccessful": true,
266
+ "schemaAndSignatureCheck": { "valid": true, "error": null },
83
267
  "expiryCheck": { "valid": true },
84
268
  "statusChecks": [
85
- { "purpose": "revocation", "valid": true, "error": null },
86
- { "purpose": "suspension", "valid": true, "error": null }
87
- ],
88
- "claims": {...}
269
+ { "purpose": "revocation", "valid": true, "error": null }
270
+ ],
271
+ "claims": {...}
89
272
  }
90
273
  ```
91
- ### OpenID4VPVerification
92
- If summariseResults=true, then response should be
274
+
275
+ #### Response Fields Summary
276
+
277
+ | Property | Type | Description |
278
+ |---------------------------|---------|-----------------------------------------------------------|
279
+ | `allChecksSuccessful` | boolean | Final aggregated validation flag |
280
+ | `schemaAndSignatureCheck` | object | Validates schema and signature check |
281
+ | `expiryCheck` | object | If false, the credential is EXPIRED |
282
+ | `statusChecks` | array | Contains revocation and other status validations |
283
+ | `statusChecks.error` | object | If present, throws an error instead of returning a status |
284
+ | `statusChecks.purpose` | string | Identifies purpose (e.g., "revocation") |
285
+ | `statusChecks.valid` | boolean | If false for revocation → credential is revoked |
286
+ | `claims` | object | Includes all claims from credentialSubject |
287
+
288
+ ### Option B: OpenID4VP Verification
289
+ OpenID4VPVerification Component verifies Verifiable Presentations securely using OpenID4VP standards for both cross-device and same-device flows.
290
+
291
+ **Perfect for:** Integrating with digital wallets (like mobile ID apps)
292
+
293
+ Follow these steps to integrate:
294
+
295
+ #### Import & Usage
296
+
93
297
  ```javascript
94
- {
95
- vcResults: [
96
- {
97
- vc: { /* Your verified credential data */ },
98
- vcStatus: "SUCCESS" // or "INVALID", "EXPIRED"
99
- }
100
- ],
101
- vpResultStatus: "SUCCESS" // Overall verification status
102
- }
298
+ import {OpenID4VPVerification} from "@injistack/react-inji-verify-sdk";
103
299
  ```
104
- If summariseResults=false, then response should be
300
+
301
+ #### 1. Cross-device flow (QR code scan from another device)
105
302
  ```javascript
106
- {
107
- "transactionId": "txn_11",
108
- "allChecksSuccessful": true,
109
- "credentialResults": [
110
- {
111
- "verifiableCredential": "{...}",
112
- "allChecksSuccessful": true,
113
- "holderProofCheck": { "valid": true, "error": null },
114
- "schemaAndSignatureCheck": { "valid": true, "error": null },
115
- "expiryCheck": { "valid": true },
116
- "statusChecks": [
117
- { "purpose": "revocation", "valid": true, "error": null },
118
- { "purpose": "suspension", "valid": true, "error": null },
119
- ],
120
- "claims": {..}
121
- }
122
- ]
123
- }
303
+ import { OpenID4VPVerification } from "@injistack/react-inji-verify-sdk";
304
+ export default function VerifyCrossDevice() {
305
+ return (
306
+ <OpenID4VPVerification
307
+ triggerElement={<button>Show QR for Wallet Scan</button>}
308
+ verifyServiceUrl="https://your-backend.com/v1/verify"
309
+ clientId="did:example:123456789" // DID example
310
+ presentationDefinition={{
311
+ id: "custom-verification",
312
+ purpose: "We need to verify your identity",
313
+ format: {
314
+ ldp_vc: {
315
+ proof_type: ["Ed25519Signature2020"],
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
+ ],
334
+ }}
335
+ isSameDeviceFlowEnabled={false} // QR code flow
336
+ onVPProcessed={(result) => {
337
+ console.log("VP processed:", result);
338
+ }}
339
+ onQrCodeExpired={() => {
340
+ console.log(" QR code expired - ask user to retry");
341
+ }}
342
+ onError={(error) => {
343
+ console.error("Verification error:", error);
344
+ }}
345
+
346
+ />
347
+ );
348
+ }
124
349
  ```
125
- > **Security Recommendation**
126
- >
127
- > Avoid consuming results directly from VPProcessed or VCProcessed.
128
- > Instead, use VPReceived or VCReceived events to capture the txnId, then retrieve the verification results securely from your backend's verification service endpoint.
129
- > This ensures data integrity and prevents reliance on client-side verification data for final decisions.
350
+ ```mermaid
351
+ sequenceDiagram
352
+ autonumber
353
+ participant UserBrowser as User Browser
354
+ participant VerifierBackend as Verifier Backend
355
+ participant MobileWallet as Wallet (Mobile)
130
356
 
131
- ## Pre-requisites
357
+ UserBrowser->>VerifierBackend: Start verification(/vp-session-request,response_code_validation_required=false)
132
358
 
133
- ### What You Need:
359
+ VerifierBackend->>VerifierBackend: Generate transaction_id and request_id
360
+ VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (txn_id)
361
+ VerifierBackend-->>UserBrowser: Return OpenID4VP request + QR code
134
362
 
135
- 1. **A React project** (TypeScript recommended)
136
- 2. **A verification backend** - You need a server that can verify credentials
137
- 3. **Camera permissions** - For QR scanning features
363
+ UserBrowser->>MobileWallet: User scans QR code
138
364
 
139
- ### Backend Requirements:
365
+ MobileWallet->>VerifierBackend: Submit vp_token + presentation_submission
140
366
 
141
- Your backend must support the OpenID4VP protocol. You can either:
367
+ loop Long Polling
368
+ UserBrowser->>VerifierBackend: GET /vp-request/{requestId}/status
369
+ VerifierBackend-->>UserBrowser: Pending
370
+ end
142
371
 
143
- - Use the official `inji-verify-service`
144
- - Build your own following [this specification](https://openid.net/specs/openid-4-verifiable-presentations-1_0-ID3.html)
372
+ VerifierBackend-->>UserBrowser: Completed
145
373
 
146
- **Important:** Your backend URL should look like:
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
147
378
 
379
+ VerifierBackend-->>UserBrowser: Verification result
148
380
  ```
149
- https://your-backend.com
381
+
382
+ #### 2. Same Device Flow with Mobile Wallet
383
+ Used when a native mobile wallet app is triggered via deep link.
384
+
385
+ ```javascript
386
+ import { OpenID4VPVerification } from "@injistack/react-inji-verify-sdk";
387
+ export default function VerifySameDevice() {
388
+ return (
389
+ <OpenID4VPVerification
390
+ triggerElement={<button>Verify with Wallet</button>}
391
+ verifyServiceUrl="https://your-backend.com/v1/verify"
392
+ clientId="client-12345" // non-DID example
393
+ presentationDefinition={{
394
+ id: "custom-verification",
395
+ purpose: "We need to verify your identity",
396
+ format: {
397
+ ldp_vc: {
398
+ proof_type: ["Ed25519Signature2020"],
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
+ ],
417
+ }}
418
+ isSameDeviceFlowEnabled={true} //default value
419
+ // No webWalletBaseUrl → triggers mobile wallet via deep link
420
+ onVPProcessed={(result) => {
421
+ console.log("VP processed:", result);
422
+ }}
423
+ onError={(error) => {
424
+ console.error("Verification error:", error);
425
+ }}
426
+ />
427
+ );
428
+ }
150
429
  ```
151
430
 
152
- ## 📖 Detailed Component Guide
431
+ ```mermaid
432
+ sequenceDiagram
433
+ autonumber
434
+ participant UserBrowser as User Browser (Verifier App)
435
+ participant VerifierBackend as Verifier Backend
436
+ participant MobileWallet as Mobile Wallet App
153
437
 
154
- ### QRCodeVerification Component
438
+ UserBrowser->>VerifierBackend: Start verification(/vp-session-request,response_code_validation_required=false)
155
439
 
156
- **Perfect for:** Scanning QR codes from documents or uploading QR codes (PNG, JPEG, JPG, PDF)
440
+ VerifierBackend->>VerifierBackend: Generate transaction_id and request_id
441
+ VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (txn_id)
442
+ VerifierBackend-->>UserBrowser: Return OpenID4VP authorization request
157
443
 
158
- #### Basic Setup:
444
+ UserBrowser->>MobileWallet: Open mobile wallet via deep link
159
445
 
160
- ```javascript
161
- <QRCodeVerification
162
- verifyServiceUrl="https://your-backend.com"
163
- onVCProcessed={(result) => handleResult(result)}
164
- onError={(error) => handleError(error)}
165
- triggerElement={<button>Start Verification</button>}
166
- clientId="CLIENT_ID"
167
- />
446
+ MobileWallet->>VerifierBackend: Submit vp_token + presentation_submission
447
+
448
+ Note right of MobileWallet: User manually switches back to browser
449
+
450
+ loop Long Polling
451
+ UserBrowser->>VerifierBackend: GET /vp-request/{requestId}/status
452
+ VerifierBackend-->>UserBrowser: Pending
453
+ end
454
+
455
+ VerifierBackend-->>UserBrowser: Completed
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
+
462
+ VerifierBackend-->>UserBrowser: Verification result
463
+ VerifierBackend-->>UserBrowser: Clear cookie (txn_id)
168
464
  ```
169
465
 
170
- #### All Available Options:
466
+ #### 3. Same Device Flow with Web Wallet
467
+ Used when verification happens in a web-based wallet on the same device.
171
468
 
172
469
  ```javascript
173
- <QRCodeVerification
174
- // Required
175
- verifyServiceUrl="https://your-backend.com"
176
- onVCProcessed={(result) => console.log(result)} // OR use onVCReceived
177
- onError={(error) => console.log(error)}
178
- clientId="CLIENT_ID"
179
- // Optional
180
- triggerElement={<button>Custom Trigger</button>}
181
- transactionId="your-tracking-id" //Optional
182
- uploadButtonId="my-upload-btn"
183
- uploadButtonStyle={{ backgroundColor: "blue" }}
184
- isEnableUpload={true} // Allow file uploads
185
- isEnableScan={true} // Allow camera scanning
186
- isEnableZoom={true} // Allow camera zoom
187
- isVPSubmissionSupported={false} // This attribute indicates whether VP submission is supported in Inji OVP VC sharing flow. By default, it is false which means that VP token will be directly sent in response. If set to true, then VP token will be submitted to the VP_SUBMISSION_ URL.
188
- acceptVPWithoutHolderProof={false} // This attribute controls whether unsigned Verifiable Presentations (VPs without proof) are allowed in the Inji OVP VC sharing flow. By default, it is set to false, meaning unsigned VP tokens are not supported and an error is thrown if an unsigned VP is received. If set to true, VP tokens without a signature (proof) are allowed and can be verified. For data-share it is set to true by default.
189
- summariseResults={true} // This attribute will decide the format of the response from SDK
190
- />
470
+ import { OpenID4VPVerification } from "@injistack/react-inji-verify-sdk";
471
+ export default function VerifySameDevice() {
472
+ return (
473
+ <OpenID4VPVerification
474
+ triggerElement={<button>Verify with Wallet</button>}
475
+ verifyServiceUrl="https://your-backend.com/v1/verify"
476
+ clientId="did:example:123456789" // DID example
477
+ presentationDefinition={{
478
+ id: "custom-verification",
479
+ purpose: "We need to verify your identity",
480
+ format: {
481
+ ldp_vc: {
482
+ proof_type: ["Ed25519Signature2020"],
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
+ ],
501
+ }}
502
+ isSameDeviceFlowEnabled={true} //default value
503
+ webWalletBaseUrl="https://wallet.example.com" // required to support web-wallets
504
+ onVPProcessed={(result) => {
505
+ console.log("VP processed:", result);
506
+ }}
507
+ onError={(error) => {
508
+ console.error("Verification error:", error);
509
+ }}
510
+ />
511
+ );
512
+ }
191
513
  ```
192
514
 
193
- **Choose One Callback:**
515
+ ```mermaid
516
+ sequenceDiagram
517
+ autonumber
518
+ participant UserBrowser as User Browser
519
+ participant VerifierBackend as Verifier Backend
520
+ participant WebWallet as Web Wallet
194
521
 
195
- - `onVCProcessed`: Get full verification results immediately
196
- - `onVCReceived`: Get just a transaction ID (your backend handles the rest)
522
+ UserBrowser->>VerifierBackend: Start verification\n(/vp-session-request,\nresponse_code_validation_required=true)
197
523
 
198
- ### OpenID4VPVerification Component
524
+ VerifierBackend->>VerifierBackend: Generate transaction_id\nand request_id
525
+ VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (txn_id)
526
+ VerifierBackend-->>UserBrowser: Return OpenID4VP authorization request
199
527
 
200
- **Perfect for:** Integrating with digital wallets (like mobile ID apps)
528
+ UserBrowser->>WebWallet: Open Web Wallet
529
+
530
+ WebWallet->>VerifierBackend: Submit vp_token + presentation_submission
531
+ VerifierBackend-->>WebWallet: Return response_code
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)
201
538
 
202
- #### Basic Setup:
539
+ VerifierBackend->>VerifierBackend: Validate response_code + txn_id
540
+ VerifierBackend->>VerifierBackend: Fetch transaction state
203
541
 
542
+ VerifierBackend-->>UserBrowser: Verification result
543
+ VerifierBackend-->>UserBrowser: Clear cookie (txn_id)
544
+ ```
545
+
546
+ > **NOTE**
547
+ >
548
+ > When webWalletBaseUrl is configured, we use web-wallets to support verification flow.
549
+ >In the absence of webWalletBaseUrl, the SDK falls back to a deep link mechanism to launch the native wallet application if any supported mobile wallet is installed.
550
+
551
+
552
+ #### 4. Server-to-server callback (onVPReceived)
204
553
  ```javascript
205
- <OpenID4VPVerification
206
- verifyServiceUrl="https://your-backend.com"
207
- presentationDefinitionId="what-you-want-to-verify"
208
- onVpProcessed={(result) => handleResult(result)}
209
- onQrCodeExpired={() => alert("Please try again")}
210
- onError={(error) => handleError(error)}
211
- clientId="CLIENT_ID"
212
- />
554
+ import { OpenID4VPVerification } from "@injistack/react-inji-verify-sdk";
555
+
556
+ export default function VerifyServerToServer() {
557
+ return (
558
+ <OpenID4VPVerification
559
+ triggerElement={<button>Start Verification</button>}
560
+ verifyServiceUrl="https://your-backend.com/v1/verify"
561
+ clientId="did:example:123456789" // DID example
562
+ presentationDefinition={{
563
+ id: "custom-verification",
564
+ purpose: "We need to verify your identity",
565
+ format: {
566
+ ldp_vc: {
567
+ proof_type: ["Ed25519Signature2020"],
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
+ }}
587
+ isSameDeviceFlowEnabled={false}
588
+ onVPReceived={(transactionId) => {
589
+ //using the transactionId one can securely fetch the result from service
590
+ console.log("VP received transactionId:", transactionId);
591
+ }}
592
+ onQrCodeExpired={() => {
593
+ console.log("QR code expired");
594
+ }}
595
+ onError={(error) => {
596
+ console.error("Verification error:", error);
597
+ }}
598
+ />
599
+ );
600
+ }
213
601
  ```
214
602
 
215
- #### With Presentation Definition:
603
+ ### Verification Response
604
+
605
+ Once VP Verification is complete, the response depends on the `summariseResults` attribute (default = true)
606
+
607
+ If `summariseResults = true`, the response will be:
216
608
 
217
609
  ```javascript
218
- <OpenID4VPVerification
219
- verifyServiceUrl="https://your-backend.com"
220
- presentationDefinition={"Refer Option 2 below"}
221
- onVpProcessed={(result) => console.log(result)}
222
- onQrCodeExpired={() => alert("QR expired")}
223
- onError={(error) => console.error(error)}
224
- triggerElement={<button>🔐 Verify Credentials</button>}
225
- clientId="CLIENT_ID"
226
- />
610
+ {
611
+ "vcResults": [
612
+ {
613
+ "vc": { /* verified credential data */ },
614
+ "vcStatus": "SUCCESS" // or "INVALID", "EXPIRED","REVOKED"
615
+ }
616
+ ],
617
+ "vpResultStatus": "SUCCESS" // or "INVALID" Overall verification status
618
+ }
619
+ ```
620
+
621
+ If `summariseResults = false`, the response will be:
622
+
623
+ ```javascript
624
+ {
625
+ "transactionId": "txn_11",
626
+ "allChecksSuccessful": true,
627
+ "credentialResults": [
628
+ {
629
+ "verifiableCredential": "{...}",
630
+ "allChecksSuccessful": true,
631
+ "holderProofCheck": { "valid": true, "error": null },
632
+ "schemaAndSignatureCheck": { "valid": true, "error": null },
633
+ "expiryCheck": { "valid": true },
634
+ "statusChecks": [
635
+ { "purpose": "revocation", "valid": true, "error": null }
636
+ ],
637
+ "claims": {..}
638
+ }
639
+ ]
640
+ }
227
641
  ```
228
642
 
643
+ #### Response Fields Summary
644
+
645
+ | Property | Type | Description |
646
+ |---------------------------|---------|-----------------------------------------------------------|
647
+ | `allChecksSuccessful` | boolean | Final aggregated validation flag |
648
+ | `verifiableCredential` | string | The VC which needs to be verified |
649
+ | `holderProofCheck` | object | Validates if presenter owns the credential |
650
+ | `schemaAndSignatureCheck` | object | Validates schema and signature check |
651
+ | `expiryCheck` | object | If false, the credential is EXPIRED |
652
+ | `statusChecks` | array | Contains revocation and other status validations |
653
+ | `statusChecks.error` | object | If present, throws an error instead of returning a status |
654
+ | `statusChecks.purpose` | string | Identifies purpose (e.g., "revocation") |
655
+ | `statusChecks.valid` | boolean | If false for revocation → credential is revoked |
656
+ | `claims` | object | Includes all claims from credentialSubject |
657
+
658
+ ### Presentation Definition:
659
+
229
660
  #### Define What to Verify:
230
661
 
231
- **Option 1: Use a predefined template**
662
+ **Option 1: Use a predefined template ID**
232
663
 
233
664
  ```javascript
234
665
  presentationDefinitionId = "drivers-license-check";
235
666
  ```
236
667
 
237
- **Option 2: Define exactly what you want**
668
+ **Option 2: Define Presentation Definition**
238
669
 
239
670
  ```javascript
240
671
  presentationDefinition={{
@@ -263,6 +694,12 @@ presentationDefinition={{
263
694
  ],
264
695
  }}
265
696
  ```
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.
266
703
 
267
704
  ## 🎛️ Component Options Reference
268
705
 
@@ -274,34 +711,36 @@ presentationDefinition={{
274
711
  | `onError` | function | ✅ | Callback invoked when an error occurs |
275
712
  | `triggerElement` | React element | ❌ | Custom button/element to start verification |
276
713
  | `transactionId` | string | ❌ | Optional client-side tracking ID |
277
- | `clientId` | string | ✅ | Client identifier |
714
+ | `clientId` | string | ✅ | Client identifier (DID or Non-DID) |
278
715
  | `acceptVPWithoutHolderProof` | boolean | ❌ | Allow unsigned Verifiable Presentations |
279
716
  | `summariseResults` | boolean | ❌ | Decides format of SDK Response |
280
717
 
281
718
  ### QRCodeVerification Specific
282
719
 
283
- | Property | Type | Default | Description |
284
- | ------------------------- | -------- | ------- | ---------------------------- |
285
- | `onVCProcessed` | function | - | Get full results immediately |
286
- | `onVCReceived` | function | - | Get transaction ID only |
287
- | `isEnableUpload` | boolean | true | Allow file uploads |
288
- | `isEnableScan` | boolean | true | Allow camera scanning |
289
- | `isEnableZoom` | boolean | true | Allow camera zoom |
290
- | `uploadButtonStyle` | object | - | Custom upload button styling |
291
- | `isVPSubmissionSupported` | Boolean | false | Toggle VP submission support |
720
+ | Property | Type | Default | Description |
721
+ |---------------------------|----------|---------|--------------------------------------------|
722
+ | `onVCProcessed` | function | - | Get full results immediately |
723
+ | `onVCReceived` | function | - | Get transaction ID only |
724
+ | `isEnableUpload` | boolean | true | Allow file uploads |
725
+ | `isEnableScan` | boolean | true | Allow camera scanning |
726
+ | `isEnableZoom` | boolean | true | Allow camera zoom (for mobile and tablets) |
727
+ | `uploadButtonStyle` | string | - | Custom upload button styling |
728
+ | `isVPSubmissionSupported` | boolean | false | Toggle VP submission support |
729
+ | `vcVerificationV2Request` | object | - | contains request body for VC Verification |
292
730
 
293
731
  ### OpenID4VPVerification Specific
294
732
 
295
- | Property | Type | Default | Description |
296
- | -------------------------- | -------- | -------------- | ---------------------------------- |
297
- | `protocol` | string | "openid4vp://" | Protocol for QR codes (optional) |
298
- | `presentationDefinitionId` | string | - | Predefined verification template |
299
- | `presentationDefinition` | object | - | Custom verification rules |
300
- | `onVpProcessed` | function | - | Get full results immediately |
301
- | `onVpReceived` | function | - | Get transaction ID only |
302
- | `onQrCodeExpired` | function | - | Handle QR code expiration |
303
- | `isSameDeviceFlowEnabled` | boolean | true | Enable same-device flow (optional) |
304
- | `qrCodeStyles` | object | - | Customize QR code appearance |
733
+ | Property | Type | Default | Description |
734
+ |--------------------------| -------- |----------------|-------------------------------------------|
735
+ | `protocol` | string | "openid4vp://" | Protocol for QR codes (optional) |
736
+ | `presentationDefinitionId` | string | - | Predefined verification template |
737
+ | `presentationDefinition` | object | - | Custom verification rules |
738
+ | `onVPProcessed` | function | - | Get full results immediately |
739
+ | `onVPReceived` | function | - | Get transaction ID only |
740
+ | `onQrCodeExpired` | function | - | Handle QR code expiration |
741
+ | `isSameDeviceFlowEnabled` | boolean | true | Enable same-device flow (optional) |
742
+ | `qrCodeStyles` | object | - | Customize QR code appearance |
743
+ | `vpVerificationRequest` | object | - | contains request body for VP Verification |
305
744
 
306
745
  ## ⚠️ Important Limitations
307
746