@mattrglobal/verifier-sdk-web 2.0.0-preview-digital-credential-api.3 → 2.0.0-preview-digital-credential-api.5

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
@@ -35,7 +35,7 @@ Request or download the
35
35
 
36
36
  ## Overview
37
37
 
38
- The Verifier Web SDK is a powerful tool for integrating online credential verification capabilities into your web applications. It enables secure and efficient verification of [mDocs](https://learn.mattr.global/docs/formats/mdocs), supporting both [same-device](https://learn.mattr.global/docs/formats/mdocs/verification-workflows/online#same-device-verification-workflow) and [cross-device](https://learn.mattr.global/docs/formats/mdocs/verification-workflows/online#cross-device-verification-workflow) verification workflows. The SDK leverages the MATTR VII platform to handle credential presentation and verification processes.
38
+ The Verifier Web SDK is a powerful tool for integrating online credential verification capabilities into your web applications. It enables secure and efficient verification of [mDocs](https://learn.mattr.global/docs/mdocs), supporting both [same-device](https://learn.mattr.global/docs/verification/online/mdocs/overview#same-device-verification-workflow) and [cross-device](https://learn.mattr.global/docs/verification/online/mdocs/overview#cross-device-verification-workflow) verification workflows. The SDK leverages the MATTR VII platform to handle credential presentation and verification processes.
39
39
 
40
40
  ## Features
41
41
 
@@ -50,7 +50,7 @@ The Verifier Web SDK is a powerful tool for integrating online credential verifi
50
50
 
51
51
  ## How to get access to the MATTR Pi Verifier Web SDK
52
52
 
53
- Refer to our [SDK Docs landing page](https://learn.mattr.global/sdk-docs) for step-by-step instructions to gain access
53
+ Refer to our [SDK Docs landing page](https://learn.mattr.global/references#mattr-pi-sdk-docs) for step-by-step instructions to gain access
54
54
  to any of our SDKs.
55
55
 
56
56
  > Please [reach out](mailto:dev-support@mattr.global) if you need any assistance.
@@ -84,9 +84,9 @@ MATTRVerifierSDK.initialise(...);
84
84
  2. Access SDK functions via global `MATTRVerifierSDK` object.
85
85
 
86
86
  ```javascript
87
- <script>
87
+ <script>
88
88
  MATTRVerifierSDK.initialise(...);
89
- </script>
89
+ </script>
90
90
  ```
91
91
 
92
92
  # Usage
@@ -104,45 +104,53 @@ The SDK can make a request to create a presentation session with a configured MA
104
104
  This SDK supports the experimental Web Platform Digital Credential API and will automatically attempt to use the Digital Credential API (ahead of executing the request based on OpenID4VP as per ISO 18013-7) when the following conditions are met:
105
105
  - The SDK detects the Digital Credential API is available in the current web browser.
106
106
  - The feature has been enabled when the SDK was [initialised]((#initialise-the-sdk).
107
-
107
+
108
108
  ## Initialise the SDK
109
109
 
110
- You must initialise the SDK before you can use any of its functions and methods.
110
+ You must initialise the SDK before you can use any of its functions and methods:
111
111
 
112
112
  ```javascript
113
113
  MATTRVerifierSDK.initialise({
114
- apiBaseUrl: "{tenant_url}", // provide the URL of the MATTR VII verifier tenant.
115
- /**
116
- * Configurations when Digital Credential Api is available
114
+ apiBaseUrl: "{tenant_url}",
115
+ applicationId: "{applicationId}",
116
+ /**
117
+ * Configurations when Digital Credential Api is available
117
118
  **/
118
- enableDigitalCredentialsApiSameDeviceFlow: true, // indicates whether the SDK will use the Digital Credential API in same-device flows.
119
- enableDigitalCredentialsApiCrossDeviceFlow: false, // indicates whether the SDK will use the Digital Credential API in cross-device flows.
119
+ enableDigitalCredentialsApiSameDeviceFlow: true, // indicate if SDK will request credential via Digital Credential Api in a same device flow
120
+ enableDigitalCredentialsApiCrossDeviceFlow: false, // indicate if SDK request credential via Digital Credential Api in a cross device flow
120
121
  });
121
122
  ```
122
123
 
124
+ - `apiBaseUrl` (required): URL of the MATTR VII verifier tenant.
125
+ - `applicationId` (optional): Unique identifier of the verifier application. This must match the [`name`](https://learn.mattr.global/api-reference/latest/tag/mDocs-verification#operation/postVerifierApplication!path=name&t=request) parameter defined as part of a Verifier application created on the MATTR VII verifier tenant.
126
+
123
127
  ## Prepare a credential query
124
128
 
125
- The following example credential query will request the `birthdate` and `portrait` claims from a `mobile` credential `profile` with `org.iso.18013.5.1.mDL` as a `docType`:
129
+ The following example credential query will request the `birthdate` and `portrait` claims from a `mobile` credential `profile` with `org.iso.18013.5.1.mDL` as a `docType`:
126
130
 
127
131
  ```javascript
128
- const credentialQuery = {
129
- "profile": "mobile",
130
- "docType": "org.iso.18013.5.1.mDL",
131
- "nameSpaces": {
132
- "org.iso.18013.5.1": {
133
- "birthdate": {
134
- "intentToRetain": false
132
+ const credentialQuery = [
133
+ {
134
+ "profile": "mobile",
135
+ "docType": "org.iso.18013.5.1.mDL",
136
+ "nameSpaces": {
137
+ "org.iso.18013.5.1": {
138
+ "birthdate": {
139
+ "intentToRetain": false
140
+ },
141
+ "portrait": {
142
+ "intentToRetain": false
143
+ },
144
+ "resident_postal_code": {
145
+ "intentToRetain": false
146
+ }
135
147
  },
136
- "portrait": {},
137
- "resident_postal_code": {
138
- "intentToRetain": false
139
- }
140
- },
148
+ }
141
149
  }
142
- };
150
+ ];
143
151
  ```
144
152
 
145
- > The API supports multiple queries in one request. For simplicity, this example only includes a single query.
153
+ > The API supports including multiple query objects in the `credentialQuery` array in a single request. For simplicity, this example only includes a single query object.
146
154
 
147
155
  ## Generate challenge
148
156
 
@@ -156,7 +164,7 @@ When the challenge is generated by your backend, you should use it to validate t
156
164
 
157
165
  The **same-device flow** involves the user completing all steps on a single device, such as their smartphone. They initiate the credential request on the verifier's web app, are redirected to their wallet app to consent and present credentials, and then return to the verifier's web app with the results.
158
166
 
159
- In contrast, the **cross-device flow** starts on one device, like a laptop. When the user initiates the request, the web app responds by displaying a QR code. The user then scans this QR code with their smartphone, use their wallet app to present matching credentials, and the results are sent back to the verifier's web app.
167
+ In contrast, the **cross-device flow** starts on one device, like a laptop. When the user initiates the request, the web app responds by displaying a QR code. The user then scans this QR code with their smartphone, use their wallet app to present matching credentials, and the results are sent back to the verifier's web app.
160
168
 
161
169
  The main difference is that the same-device flow uses only one device for the entire process, while the cross-device flow uses two devices for added flexibility.
162
170
 
@@ -184,8 +192,8 @@ When using the same-device presentation flow with OpenID4VP (ISO 18013-7) e.g in
184
192
  ## Request credentials with automatic flow selection
185
193
 
186
194
  ```javascript
187
- MATTRVerifierSDK.initialise({ apiBaseUrl }); // Initialise the SDK
188
- const requestCredentialsResult = await MATTRVerifierSDK.requestCredentials({
195
+ MATTRVerifierSDK.initialise({ apiBaseUrl, applicationId }); // Initialise the SDK
196
+ const result = await MATTRVerifierSDK.requestCredentials({
189
197
  credentialQuery: [credentialQuery], // Define what credential query to use
190
198
  challenge: MATTRVerifierSDK.utils.generateChallenge(), // Pass a unique challenge
191
199
  walletProviderId, // Define the wallet identifier
@@ -201,7 +209,7 @@ const requestCredentialsResult = await MATTRVerifierSDK.requestCredentials({
201
209
  });
202
210
 
203
211
  // Check result when it's available in the return value
204
- if (requestCredentialsResult.isOk() && "result" in requestCredentialsResult.value) {
212
+ if (requestCredentialsResult.isOk() && "result" in requestCredentialsResult.value) {
205
213
  console.info("<<< MATTRVerifierSDK.requestCredentials result",result.value.result);
206
214
  }
207
215
 
@@ -222,7 +230,7 @@ window.addEventListener("load", async () => {
222
230
  ## Request credentials with explicit same-device flow
223
231
 
224
232
  ```javascript
225
- MATTRVerifierSDK.initialise({ apiBaseUrl });
233
+ MATTRVerifierSDK.initialise({ apiBaseUrl, applicationId });
226
234
  const requestCredentialsResult = await MATTRVerifierSDK.requestCredentials({
227
235
  credentialQuery: [credentialQuery],
228
236
  challenge: MATTRVerifierSDK.utils.generateChallenge(),
@@ -232,13 +240,13 @@ const requestCredentialsResult = await MATTRVerifierSDK.requestCredentials({
232
240
  });
233
241
 
234
242
  // Check result when it's available in the return value
235
- if (requestCredentialsResult.isOk() && "result" in requestCredentialsResult.value) {
243
+ if (requestCredentialsResult.isOk() && "result" in requestCredentialsResult.value) {
236
244
  console.info("<<< MATTRVerifierSDK.requestCredentials result",result.value.result);
237
245
  }
238
246
 
239
247
  // Check result also in your page of redirect_uri
240
248
  window.addEventListener("load", async () => {
241
- MATTRVerifierSDK.initialise({ apiBaseUrl });
249
+ MATTRVerifierSDK.initialise({ apiBaseUrl, applicationId });
242
250
  const result = await MATTRVerifierSDK.handleRedirectCallback();
243
251
  });
244
252
  ```
@@ -250,7 +258,7 @@ window.addEventListener("load", async () => {
250
258
  ## Request credentials with explicit cross-device flow
251
259
 
252
260
  ```javascript
253
- MATTRVerifierSDK.initialise({ apiBaseUrl });
261
+ MATTRVerifierSDK.initialise({ apiBaseUrl, applicationId });
254
262
  const requestCredentialsResult = await MATTRVerifierSDK.requestCredentials({
255
263
  credentialQuery: [credentialQuery],
256
264
  challenge: MATTRVerifierSDK.utils.generateChallenge(),
@@ -267,7 +275,7 @@ const requestCredentialsResult = await MATTRVerifierSDK.requestCredentials({
267
275
  });
268
276
 
269
277
  // Check result when it's available in the return value
270
- if (requestCredentialsResult.isOk() && "result" in requestCredentialsResult.value) {
278
+ if (requestCredentialsResult.isOk() && "result" in requestCredentialsResult.value) {
271
279
  console.info("<<< MATTRVerifierSDK.requestCredentials result",result.value.result);
272
280
  }
273
281
  ```
@@ -7,8 +7,8 @@
7
7
  * Do Not Translate or Localize
8
8
  *
9
9
  * Bundle of @mattrglobal/verifier-sdk-web
10
- * Generated: 2025-02-18
11
- * Version: 2.0.0-preview-digital-credential-api.3
10
+ * Generated: 2025-04-28
11
+ * Version: 2.0.0-preview-digital-credential-api.5
12
12
  * Dependencies:
13
13
  */
14
14
 
@@ -127,6 +127,9 @@ exports.MobileCredentialVerificationReasonType = void 0;
127
127
  (function(MobileCredentialVerificationReasonType) {
128
128
  MobileCredentialVerificationReasonType["Expired"] = "expired";
129
129
  MobileCredentialVerificationReasonType["Inactive"] = "inactive";
130
+ MobileCredentialVerificationReasonType["StatusRevoked"] = "invalid";
131
+ MobileCredentialVerificationReasonType["StatusSuspended"] = "suspended";
132
+ MobileCredentialVerificationReasonType["StatusUnknown"] = "unknown";
130
133
  })(exports.MobileCredentialVerificationReasonType || (exports.MobileCredentialVerificationReasonType = {}));
131
134
 
132
135
  exports.ClaimType = void 0;
@@ -169,6 +172,22 @@ const CredentialQueryValidator = v__namespace.object({
169
172
  })))
170
173
  });
171
174
 
175
+ const DcqlCredentialQueryValidator = v__namespace.object({
176
+ credentials: v__namespace.array(v__namespace.object({
177
+ id: v__namespace.string(),
178
+ format: v__namespace.string(),
179
+ meta: v__namespace.optional(v__namespace.unknown()),
180
+ claims: v__namespace.array(v__namespace.object({
181
+ path: v__namespace.array(v__namespace.string())
182
+ }))
183
+ })),
184
+ credential_sets: v__namespace.optional(v__namespace.array(v__namespace.object({
185
+ options: v__namespace.array(v__namespace.array(v__namespace.string())),
186
+ required: v__namespace.optional(v__namespace.boolean()),
187
+ purpose: v__namespace.optional(v__namespace.unknown())
188
+ })))
189
+ });
190
+
172
191
  var PresentationErrorType;
173
192
 
174
193
  (function(PresentationErrorType) {
@@ -189,7 +208,7 @@ const PresentationResultRelaxValidator = v__namespace.object({
189
208
  });
190
209
 
191
210
  v__namespace.object({
192
- credentialQuery: v__namespace.array(CredentialQueryValidator),
211
+ credentialQuery: v__namespace.union([ v__namespace.array(CredentialQueryValidator), DcqlCredentialQueryValidator ]),
193
212
  challenge: v__namespace.string(),
194
213
  redirectUri: v__namespace.optional(v__namespace.string()),
195
214
  walletProviderId: v__namespace.optional(v__namespace.string())
@@ -228,7 +247,7 @@ var MessageEventDataType;
228
247
  })(MessageEventDataType || (MessageEventDataType = {}));
229
248
 
230
249
  const RequestCredentialsSameDeviceOptionsValidator = v__namespace.object({
231
- credentialQuery: v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()),
250
+ credentialQuery: v__namespace.union([ v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()), DcqlCredentialQueryValidator ]),
232
251
  redirectUri: v__namespace.string(),
233
252
  challenge: v__namespace.optional(v__namespace.string()),
234
253
  walletProviderId: v__namespace.optional(v__namespace.string()),
@@ -236,7 +255,7 @@ const RequestCredentialsSameDeviceOptionsValidator = v__namespace.object({
236
255
  });
237
256
 
238
257
  const RequestCredentialsCrossDeviceOptionsValidator = v__namespace.object({
239
- credentialQuery: v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()),
258
+ credentialQuery: v__namespace.union([ v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()), DcqlCredentialQueryValidator ]),
240
259
  crossDeviceCallback: v__namespace.object({
241
260
  onComplete: v__namespace.function(),
242
261
  onFailure: v__namespace.function()
@@ -247,7 +266,7 @@ const RequestCredentialsCrossDeviceOptionsValidator = v__namespace.object({
247
266
  });
248
267
 
249
268
  const RequestCredentialsAutoDetectDeviceOptionsValidator = v__namespace.object({
250
- credentialQuery: v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()),
269
+ credentialQuery: v__namespace.union([ v__namespace.pipe(v__namespace.array(CredentialQueryValidator), v__namespace.nonEmpty()), DcqlCredentialQueryValidator ]),
251
270
  crossDeviceCallback: v__namespace.object({
252
271
  onComplete: v__namespace.function(),
253
272
  onFailure: v__namespace.function()
@@ -268,6 +287,7 @@ exports.RequestCredentialsErrorType = void 0;
268
287
 
269
288
  const InitialiseOptionsValidator = v__namespace.object({
270
289
  apiBaseUrl: v__namespace.string(),
290
+ applicationId: v__namespace.optional(v__namespace.string()),
271
291
  enableDigitalCredentialsApiSameDeviceFlow: v__namespace.optional(v__namespace.boolean()),
272
292
  enableDigitalCredentialsApiCrossDeviceFlow: v__namespace.optional(v__namespace.boolean())
273
293
  });
@@ -319,12 +339,14 @@ const getHashParamValue = (hash, param) => {
319
339
  return urlParams.get(param);
320
340
  };
321
341
 
322
- const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl, walletProviderId: walletProviderId}) => {
323
- const postData = Object.assign(Object.assign({
342
+ const createSession = async ({credentialQuery: credentialQuery, challenge: challenge, redirectUri: redirectUri, apiBaseUrl: apiBaseUrl, applicationId: applicationId, walletProviderId: walletProviderId}) => {
343
+ const postData = Object.assign(Object.assign(Object.assign({
324
344
  credentialQuery: credentialQuery,
325
345
  challenge: challenge
326
346
  }, redirectUri ? {
327
347
  redirectUri: redirectUri
348
+ } : {}), applicationId ? {
349
+ applicationId: applicationId
328
350
  } : {}), walletProviderId ? {
329
351
  walletProviderId: walletProviderId
330
352
  } : {});
@@ -401,7 +423,7 @@ const createDigitalCredentialsApiSession = async ({credentialQuery: credentialQu
401
423
  }, protocol && {
402
424
  protocol: protocol
403
425
  });
404
- const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/browserApi/request`, {
426
+ const responseResult = await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/web/request`, {
405
427
  method: "POST",
406
428
  headers: {
407
429
  "Content-Type": "application/json"
@@ -421,13 +443,14 @@ const createDigitalCredentialsApiSession = async ({credentialQuery: credentialQu
421
443
  return neverthrow.ok(data);
422
444
  };
423
445
 
424
- const getDigitalCredentialsApiSessionResult = async ({challenge: challenge, sessionId: sessionId, response: response, apiBaseUrl: apiBaseUrl}) => {
446
+ const getDigitalCredentialsApiSessionResult = async ({challenge: challenge, sessionId: sessionId, response: response, apiBaseUrl: apiBaseUrl, protocol: protocol}) => {
425
447
  const postData = {
426
448
  challenge: challenge,
427
449
  sessionId: sessionId,
428
- response: response
450
+ response: response,
451
+ protocol: protocol
429
452
  };
430
- const fetchResultFn = async () => await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/browserApi/response`, {
453
+ const fetchResultFn = async () => await safeFetch(`${apiBaseUrl}/v2/presentations/sessions/web/response`, {
431
454
  method: "POST",
432
455
  headers: {
433
456
  "Content-Type": "application/json"
@@ -548,17 +571,19 @@ const openCrossDeviceModal = options => {
548
571
  modalContainer.appendChild(style);
549
572
  modalContainer.appendChild(iframe);
550
573
  document.body.appendChild(modalContainer);
551
- modalContainer.setAttribute("style", "background: rgba(0, 0, 0, 0.5) !important; position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important;");
574
+ modalContainer.setAttribute("style", "background: rgba(0, 0, 0, 0.5) !important; position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; z-index: 999;");
575
+ modalContainer.setAttribute("class", "mattr-verifier-modal-container");
552
576
  return modalContainer;
553
577
  };
554
578
 
555
579
  const requestCredentialsCrossDevice = async options => {
556
580
  const {challenge: challenge, walletProviderId: walletProviderId, credentialQuery: credentialQuery, crossDeviceCallback: crossDeviceCallback, initialiseOptions: initialiseOptions} = options;
557
- const {apiBaseUrl: apiBaseUrl} = initialiseOptions;
581
+ const {apiBaseUrl: apiBaseUrl, applicationId: applicationId} = initialiseOptions;
558
582
  const createSessionResult = await createSession({
559
583
  credentialQuery: credentialQuery,
560
584
  challenge: challenge,
561
585
  apiBaseUrl: apiBaseUrl,
586
+ applicationId: applicationId,
562
587
  walletProviderId: walletProviderId
563
588
  });
564
589
  if (createSessionResult.isErr()) {
@@ -595,7 +620,7 @@ var SameDeviceRequestCredentialsErrorMessage$1;
595
620
 
596
621
  const requestCredentialsSameDevice = async options => {
597
622
  const {challenge: challenge, credentialQuery: credentialQuery, redirectUri: redirectUri, walletProviderId: walletProviderId, initialiseOptions: initialiseOptions} = options;
598
- const {apiBaseUrl: apiBaseUrl} = initialiseOptions;
623
+ const {apiBaseUrl: apiBaseUrl, applicationId: applicationId} = initialiseOptions;
599
624
  window.localStorage.setItem(LocalStorageKey.challenge, challenge);
600
625
  const storedChallenge = window.localStorage.getItem(LocalStorageKey.challenge);
601
626
  if (!storedChallenge) {
@@ -609,6 +634,7 @@ const requestCredentialsSameDevice = async options => {
609
634
  challenge: storedChallenge,
610
635
  redirectUri: redirectUri,
611
636
  apiBaseUrl: apiBaseUrl,
637
+ applicationId: applicationId,
612
638
  walletProviderId: walletProviderId
613
639
  });
614
640
  if (createSessionResult.isErr()) {
@@ -678,7 +704,8 @@ const requestCredentialsDigitalCredentialsApi = async options => {
678
704
  challenge: challenge,
679
705
  sessionId: sessionId,
680
706
  response: response,
681
- apiBaseUrl: apiBaseUrl
707
+ apiBaseUrl: apiBaseUrl,
708
+ protocol: digitalCredentialsApiProtocol !== null && digitalCredentialsApiProtocol !== void 0 ? digitalCredentialsApiProtocol : "preview"
682
709
  });
683
710
  if (result.isOk()) {
684
711
  return neverthrow.ok({