@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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
209
|
+
<QRCodeVerification
|
|
210
|
+
scannerActive={scannerActive}
|
|
51
211
|
verifyServiceUrl="https://your-backend.com/v1/verify"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
clientId="
|
|
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
|
-
|
|
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
|
-
|
|
249
|
+
### Verification Response
|
|
69
250
|
|
|
70
|
-
|
|
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
|
-
|
|
260
|
+
|
|
261
|
+
If `summariseResults = false`, the response will be:
|
|
262
|
+
|
|
79
263
|
```javascript
|
|
80
264
|
{
|
|
81
|
-
"allChecksSuccessful": true,
|
|
82
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
"claims": {...}
|
|
269
|
+
{ "purpose": "revocation", "valid": true, "error": null }
|
|
270
|
+
],
|
|
271
|
+
"claims": {...}
|
|
89
272
|
}
|
|
90
273
|
```
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
300
|
+
|
|
301
|
+
#### 1. Cross-device flow (QR code scan from another device)
|
|
105
302
|
```javascript
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
357
|
+
UserBrowser->>VerifierBackend: Start verification(/vp-session-request,response_code_validation_required=false)
|
|
132
358
|
|
|
133
|
-
|
|
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
|
-
|
|
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
|
-
|
|
365
|
+
MobileWallet->>VerifierBackend: Submit vp_token + presentation_submission
|
|
140
366
|
|
|
141
|
-
|
|
367
|
+
loop Long Polling
|
|
368
|
+
UserBrowser->>VerifierBackend: GET /vp-request/{requestId}/status
|
|
369
|
+
VerifierBackend-->>UserBrowser: Pending
|
|
370
|
+
end
|
|
142
371
|
|
|
143
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
438
|
+
UserBrowser->>VerifierBackend: Start verification(/vp-session-request,response_code_validation_required=false)
|
|
155
439
|
|
|
156
|
-
|
|
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
|
-
|
|
444
|
+
UserBrowser->>MobileWallet: Open mobile wallet via deep link
|
|
159
445
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
####
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
|
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` |
|
|
291
|
-
| `isVPSubmissionSupported` |
|
|
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
|
|
296
|
-
|
|
297
|
-
| `protocol`
|
|
298
|
-
| `presentationDefinitionId` | string | - | Predefined verification template
|
|
299
|
-
| `presentationDefinition`
|
|
300
|
-
| `
|
|
301
|
-
| `
|
|
302
|
-
| `onQrCodeExpired`
|
|
303
|
-
| `isSameDeviceFlowEnabled`
|
|
304
|
-
| `qrCodeStyles`
|
|
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
|
|