@openid4vc/openid4vci 0.3.0-alpha-20250224151429

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2130 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ AuthorizationFlow: () => AuthorizationFlow,
34
+ Openid4vciClient: () => Openid4vciClient,
35
+ Openid4vciDraftVersion: () => Openid4vciDraftVersion,
36
+ Openid4vciError: () => Openid4vciError,
37
+ Openid4vciIssuer: () => Openid4vciIssuer,
38
+ Openid4vciRetrieveCredentialsError: () => Openid4vciRetrieveCredentialsError,
39
+ Openid4vciSendNotificationError: () => Openid4vciSendNotificationError,
40
+ credentialsSupportedToCredentialConfigurationsSupported: () => credentialsSupportedToCredentialConfigurationsSupported,
41
+ extractScopesForCredentialConfigurationIds: () => extractScopesForCredentialConfigurationIds,
42
+ getCredentialConfigurationsMatchingRequestFormat: () => getCredentialConfigurationsMatchingRequestFormat,
43
+ getGlobalConfig: () => import_utils19.getGlobalConfig,
44
+ setGlobalConfig: () => import_utils19.setGlobalConfig
45
+ });
46
+ module.exports = __toCommonJS(src_exports);
47
+ var import_utils19 = require("@openid4vc/utils");
48
+
49
+ // src/credential-request/credential-request-configurations.ts
50
+ var import_utils4 = require("@openid4vc/utils");
51
+
52
+ // src/metadata/credential-issuer/credential-issuer-metadata.ts
53
+ var import_oauth23 = require("@openid4vc/oauth2");
54
+ var import_utils3 = require("@openid4vc/utils");
55
+
56
+ // src/metadata/credential-issuer/z-credential-issuer-metadata.ts
57
+ var import_oauth22 = require("@openid4vc/oauth2");
58
+ var import_utils2 = require("@openid4vc/utils");
59
+ var import_zod9 = __toESM(require("zod"));
60
+
61
+ // src/formats/credential/mso-mdoc/z-mso-mdoc.ts
62
+ var import_zod3 = __toESM(require("zod"));
63
+
64
+ // src/metadata/credential-issuer/z-credential-configuration-supported-common.ts
65
+ var import_zod2 = __toESM(require("zod"));
66
+
67
+ // src/key-attestation/z-key-attestation.ts
68
+ var import_oauth2 = require("@openid4vc/oauth2");
69
+ var import_utils = require("@openid4vc/utils");
70
+ var import_zod = __toESM(require("zod"));
71
+ var zKeyAttestationJwtHeader = import_zod.default.object({
72
+ ...import_oauth2.zJwtHeader.shape,
73
+ typ: import_zod.default.literal("keyattestation+jwt")
74
+ }).passthrough().refine(({ kid, jwk }) => jwk === void 0 || kid === void 0, {
75
+ message: `Both 'jwk' and 'kid' are defined. Only one is allowed`
76
+ }).refine(({ trust_chain, kid }) => !trust_chain || !kid, {
77
+ message: `When 'trust_chain' is provided, 'kid' is required`
78
+ });
79
+ var zIso18045 = import_zod.default.enum(["iso_18045_high", "iso_18045_moderate", "iso_18045_enhanced-basic", "iso_18045_basic"]);
80
+ var zIso18045OrStringArray = import_zod.default.array(import_zod.default.union([zIso18045, import_zod.default.string()]));
81
+ var zKeyAttestationJwtPayload = import_zod.default.object({
82
+ ...import_oauth2.zJwtPayload.shape,
83
+ iat: import_utils.zInteger,
84
+ attested_keys: import_zod.default.array(import_oauth2.zJwk),
85
+ key_storage: import_zod.default.optional(zIso18045OrStringArray),
86
+ user_authentication: import_zod.default.optional(zIso18045OrStringArray),
87
+ certification: import_zod.default.optional(import_zod.default.string())
88
+ }).passthrough();
89
+ var zKeyAttestationJwtPayloadForUse = (use) => import_zod.default.object({
90
+ ...zKeyAttestationJwtPayload.shape,
91
+ // REQUIRED when used as proof_type.attesation directly
92
+ nonce: use === "proof_type.attestation" ? import_zod.default.string({
93
+ message: `Nonce must be defined when key attestation is used as 'proof_type.attestation' directly`
94
+ }) : import_zod.default.optional(import_zod.default.string()),
95
+ // REQUIRED when used within header of proof_type.jwt
96
+ exp: use === "proof_type.jwt" ? import_utils.zInteger : import_zod.default.optional(import_utils.zInteger)
97
+ }).passthrough();
98
+
99
+ // src/metadata/credential-issuer/z-credential-configuration-supported-common.ts
100
+ var zCredentialConfigurationSupportedClaims = import_zod2.default.object({
101
+ mandatory: import_zod2.default.boolean().optional(),
102
+ value_type: import_zod2.default.string().optional(),
103
+ display: import_zod2.default.object({
104
+ name: import_zod2.default.string().optional(),
105
+ locale: import_zod2.default.string().optional()
106
+ }).passthrough().optional()
107
+ }).passthrough();
108
+ var zCredentialConfigurationSupportedCommon = import_zod2.default.object({
109
+ format: import_zod2.default.string(),
110
+ scope: import_zod2.default.string().optional(),
111
+ cryptographic_binding_methods_supported: import_zod2.default.array(import_zod2.default.string()).optional(),
112
+ credential_signing_alg_values_supported: import_zod2.default.array(import_zod2.default.string()).optional(),
113
+ proof_types_supported: import_zod2.default.record(
114
+ import_zod2.default.union([import_zod2.default.literal("jwt"), import_zod2.default.literal("attestation"), import_zod2.default.string()]),
115
+ import_zod2.default.object({
116
+ proof_signing_alg_values_supported: import_zod2.default.array(import_zod2.default.string()),
117
+ key_attestations_required: import_zod2.default.object({
118
+ key_storage: zIso18045OrStringArray.optional(),
119
+ user_authentication: zIso18045OrStringArray.optional()
120
+ }).passthrough().optional()
121
+ })
122
+ ).optional(),
123
+ display: import_zod2.default.array(
124
+ import_zod2.default.object({
125
+ name: import_zod2.default.string(),
126
+ locale: import_zod2.default.string().optional(),
127
+ logo: import_zod2.default.object({
128
+ // FIXME: make required again, but need to support draft 11 first
129
+ uri: import_zod2.default.string().optional(),
130
+ alt_text: import_zod2.default.string().optional()
131
+ }).passthrough().optional(),
132
+ description: import_zod2.default.string().optional(),
133
+ background_color: import_zod2.default.string().optional(),
134
+ background_image: import_zod2.default.object({
135
+ // TODO: should be required, but paradym's metadata is wrong here.
136
+ uri: import_zod2.default.string().optional()
137
+ }).passthrough().optional(),
138
+ text_color: import_zod2.default.string().optional()
139
+ }).passthrough()
140
+ ).optional()
141
+ }).passthrough();
142
+
143
+ // src/formats/credential/mso-mdoc/z-mso-mdoc.ts
144
+ var zMsoMdocFormatIdentifier = import_zod3.default.literal("mso_mdoc");
145
+ var zMsoMdocCredentialIssuerMetadata = import_zod3.default.object({
146
+ format: zMsoMdocFormatIdentifier,
147
+ doctype: import_zod3.default.string(),
148
+ claims: import_zod3.default.optional(zCredentialConfigurationSupportedClaims),
149
+ order: import_zod3.default.optional(import_zod3.default.array(import_zod3.default.string()))
150
+ });
151
+ var zMsoMdocCredentialRequestFormat = import_zod3.default.object({
152
+ format: zMsoMdocFormatIdentifier,
153
+ doctype: import_zod3.default.string(),
154
+ claims: import_zod3.default.optional(zCredentialConfigurationSupportedClaims)
155
+ });
156
+
157
+ // src/formats/credential/sd-jwt-vc/z-sd-jwt-vc.ts
158
+ var import_zod4 = __toESM(require("zod"));
159
+ var zSdJwtVcFormatIdentifier = import_zod4.default.literal("vc+sd-jwt");
160
+ var zSdJwtVcCredentialIssuerMetadata = import_zod4.default.object({
161
+ vct: import_zod4.default.string(),
162
+ format: zSdJwtVcFormatIdentifier,
163
+ claims: import_zod4.default.optional(zCredentialConfigurationSupportedClaims),
164
+ order: import_zod4.default.optional(import_zod4.default.array(import_zod4.default.string()))
165
+ });
166
+ var zSdJwtVcCredentialRequestFormat = import_zod4.default.object({
167
+ format: zSdJwtVcFormatIdentifier,
168
+ vct: import_zod4.default.string(),
169
+ claims: import_zod4.default.optional(zCredentialConfigurationSupportedClaims)
170
+ });
171
+
172
+ // src/formats/credential/w3c-vc/z-w3c-ldp-vc.ts
173
+ var import_zod6 = __toESM(require("zod"));
174
+
175
+ // src/formats/credential/w3c-vc/z-w3c-vc-common.ts
176
+ var import_zod5 = __toESM(require("zod"));
177
+ var zCredentialSubjectLeafType = import_zod5.default.object({
178
+ mandatory: import_zod5.default.boolean().optional(),
179
+ value_type: import_zod5.default.string().optional(),
180
+ display: import_zod5.default.array(
181
+ import_zod5.default.object({
182
+ name: import_zod5.default.string().optional(),
183
+ locale: import_zod5.default.string().optional()
184
+ }).passthrough()
185
+ ).optional()
186
+ }).passthrough();
187
+ var zClaimValueSchema = import_zod5.default.union([import_zod5.default.array(import_zod5.default.any()), import_zod5.default.record(import_zod5.default.string(), import_zod5.default.any()), zCredentialSubjectLeafType]);
188
+ var zW3cVcCredentialSubject = import_zod5.default.record(import_zod5.default.string(), zClaimValueSchema);
189
+ var zW3cVcJsonLdCredentialDefinition = import_zod5.default.object({
190
+ "@context": import_zod5.default.array(import_zod5.default.string()),
191
+ type: import_zod5.default.array(import_zod5.default.string()),
192
+ credentialSubject: zW3cVcCredentialSubject.optional()
193
+ }).passthrough();
194
+
195
+ // src/formats/credential/w3c-vc/z-w3c-ldp-vc.ts
196
+ var zLdpVcFormatIdentifier = import_zod6.default.literal("ldp_vc");
197
+ var zLdpVcCredentialIssuerMetadata = import_zod6.default.object({
198
+ format: zLdpVcFormatIdentifier,
199
+ credential_definition: zW3cVcJsonLdCredentialDefinition,
200
+ order: import_zod6.default.array(import_zod6.default.string()).optional()
201
+ });
202
+ var zLdpVcCredentialIssuerMetadataDraft11 = import_zod6.default.object({
203
+ order: import_zod6.default.array(import_zod6.default.string()).optional(),
204
+ format: zLdpVcFormatIdentifier,
205
+ // Credential definition was spread on top level instead of a separatey property in v11
206
+ // As well as using types instead of type
207
+ "@context": import_zod6.default.array(import_zod6.default.string()),
208
+ types: import_zod6.default.array(import_zod6.default.string()),
209
+ credentialSubject: zW3cVcCredentialSubject.optional()
210
+ }).passthrough();
211
+ var zLdpVcCredentialIssuerMetadataDraft11To14 = zLdpVcCredentialIssuerMetadataDraft11.transform(
212
+ ({ "@context": context, types, credentialSubject, ...rest }) => ({
213
+ ...rest,
214
+ credential_definition: {
215
+ "@context": context,
216
+ type: types,
217
+ // Prevent weird typing issue with optional vs undefined
218
+ ...credentialSubject ? { credentialSubject } : {}
219
+ }
220
+ })
221
+ );
222
+ var zLdpVcCredentialIssuerMetadataDraft14To11 = zLdpVcCredentialIssuerMetadata.passthrough().transform(({ credential_definition: { type, ...credentialDefinition }, ...rest }) => ({
223
+ ...rest,
224
+ ...credentialDefinition,
225
+ types: type
226
+ })).and(zLdpVcCredentialIssuerMetadataDraft11);
227
+ var zLdpVcCredentialRequestFormat = import_zod6.default.object({
228
+ format: zLdpVcFormatIdentifier,
229
+ credential_definition: zW3cVcJsonLdCredentialDefinition
230
+ });
231
+ var zLdpVcCredentialRequestDraft11 = import_zod6.default.object({
232
+ format: zLdpVcFormatIdentifier,
233
+ credential_definition: import_zod6.default.object({
234
+ "@context": import_zod6.default.array(import_zod6.default.string()),
235
+ // credential_definition was using types instead of type in v11
236
+ types: import_zod6.default.array(import_zod6.default.string()),
237
+ credentialSubject: zW3cVcCredentialSubject.optional()
238
+ })
239
+ }).passthrough();
240
+ var zLdpVcCredentialRequestDraft11To14 = zLdpVcCredentialRequestDraft11.transform(
241
+ ({ credential_definition: { types, ...restCredentialDefinition }, ...rest }) => ({
242
+ ...rest,
243
+ credential_definition: {
244
+ ...restCredentialDefinition,
245
+ type: types
246
+ }
247
+ })
248
+ );
249
+ var zLdpVcCredentialRequestDraft14To11 = zLdpVcCredentialRequestFormat.passthrough().transform(({ credential_definition: { type, ...restCredentialDefinition }, ...rest }) => ({
250
+ ...rest,
251
+ credential_definition: {
252
+ ...restCredentialDefinition,
253
+ types: type
254
+ }
255
+ })).and(zLdpVcCredentialRequestDraft11);
256
+
257
+ // src/formats/credential/w3c-vc/z-w3c-jwt-vc-json-ld.ts
258
+ var import_zod7 = __toESM(require("zod"));
259
+ var zJwtVcJsonLdFormatIdentifier = import_zod7.default.literal("jwt_vc_json-ld");
260
+ var zJwtVcJsonLdCredentialIssuerMetadata = import_zod7.default.object({
261
+ format: zJwtVcJsonLdFormatIdentifier,
262
+ credential_definition: zW3cVcJsonLdCredentialDefinition,
263
+ order: import_zod7.default.optional(import_zod7.default.array(import_zod7.default.string()))
264
+ });
265
+ var zJwtVcJsonLdCredentialIssuerMetadataDraft11 = import_zod7.default.object({
266
+ order: import_zod7.default.array(import_zod7.default.string()).optional(),
267
+ format: zJwtVcJsonLdFormatIdentifier,
268
+ // Credential definition was spread on top level instead of a separatey property in v11
269
+ // As well as using types instead of type
270
+ "@context": import_zod7.default.array(import_zod7.default.string()),
271
+ types: import_zod7.default.array(import_zod7.default.string()),
272
+ credentialSubject: zW3cVcCredentialSubject.optional()
273
+ }).passthrough();
274
+ var zJwtVcJsonLdCredentialIssuerMetadataDraft11To14 = zJwtVcJsonLdCredentialIssuerMetadataDraft11.transform(
275
+ ({ "@context": context, types, credentialSubject, ...rest }) => ({
276
+ ...rest,
277
+ credential_definition: {
278
+ "@context": context,
279
+ type: types,
280
+ // Prevent weird typing issue with optional vs undefined
281
+ ...credentialSubject ? { credentialSubject } : {}
282
+ }
283
+ })
284
+ );
285
+ var zJwtVcJsonLdCredentialIssuerMetadataDraft14To11 = zJwtVcJsonLdCredentialIssuerMetadata.passthrough().transform(({ credential_definition: { type, ...credentialDefinition }, ...rest }) => ({
286
+ ...rest,
287
+ ...credentialDefinition,
288
+ types: type
289
+ })).and(zJwtVcJsonLdCredentialIssuerMetadataDraft11);
290
+ var zJwtVcJsonLdCredentialRequestFormat = import_zod7.default.object({
291
+ format: zJwtVcJsonLdFormatIdentifier,
292
+ credential_definition: zW3cVcJsonLdCredentialDefinition
293
+ });
294
+ var zJwtVcJsonLdCredentialRequestDraft11 = import_zod7.default.object({
295
+ format: zJwtVcJsonLdFormatIdentifier,
296
+ credential_definition: import_zod7.default.object({
297
+ "@context": import_zod7.default.array(import_zod7.default.string()),
298
+ // credential_definition was using types instead of type in v11
299
+ types: import_zod7.default.array(import_zod7.default.string()),
300
+ credentialSubject: import_zod7.default.optional(zW3cVcCredentialSubject)
301
+ }).passthrough()
302
+ }).passthrough();
303
+ var zJwtVcJsonLdCredentialRequestDraft11To14 = zJwtVcJsonLdCredentialRequestDraft11.transform(
304
+ ({ credential_definition: { types, ...restCredentialDefinition }, ...rest }) => ({
305
+ ...rest,
306
+ credential_definition: {
307
+ ...restCredentialDefinition,
308
+ type: types
309
+ }
310
+ })
311
+ );
312
+ var zJwtVcJsonLdCredentialRequestDraft14To11 = zJwtVcJsonLdCredentialRequestFormat.passthrough().transform(({ credential_definition: { type, ...restCredentialDefinition }, ...rest }) => ({
313
+ ...rest,
314
+ credential_definition: {
315
+ ...restCredentialDefinition,
316
+ types: type
317
+ }
318
+ })).and(zJwtVcJsonLdCredentialRequestDraft11);
319
+
320
+ // src/formats/credential/w3c-vc/z-w3c-jwt-vc-json.ts
321
+ var import_zod8 = __toESM(require("zod"));
322
+ var zJwtVcJsonFormatIdentifier = import_zod8.default.literal("jwt_vc_json");
323
+ var zJwtVcJsonCredentialDefinition = import_zod8.default.object({
324
+ type: import_zod8.default.array(import_zod8.default.string()),
325
+ credentialSubject: zW3cVcCredentialSubject.optional()
326
+ }).passthrough();
327
+ var zJwtVcJsonCredentialIssuerMetadata = import_zod8.default.object({
328
+ format: zJwtVcJsonFormatIdentifier,
329
+ credential_definition: zJwtVcJsonCredentialDefinition,
330
+ order: import_zod8.default.array(import_zod8.default.string()).optional()
331
+ });
332
+ var zJwtVcJsonCredentialIssuerMetadataDraft11 = import_zod8.default.object({
333
+ format: zJwtVcJsonFormatIdentifier,
334
+ order: import_zod8.default.array(import_zod8.default.string()).optional(),
335
+ // Credential definition was spread on top level instead of a separatey property in v11
336
+ // As well as using types instead of type
337
+ types: import_zod8.default.array(import_zod8.default.string()),
338
+ credentialSubject: zW3cVcCredentialSubject.optional()
339
+ }).passthrough();
340
+ var zJwtVcJsonCredentialIssuerMetadataDraft11To14 = zJwtVcJsonCredentialIssuerMetadataDraft11.transform(
341
+ ({ types, credentialSubject, ...rest }) => ({
342
+ ...rest,
343
+ credential_definition: {
344
+ type: types,
345
+ // Prevent weird typing issue with optional vs undefined
346
+ ...credentialSubject ? { credentialSubject } : {}
347
+ }
348
+ })
349
+ );
350
+ var zJwtVcJsonCredentialIssuerMetadataDraft14To11 = zJwtVcJsonCredentialIssuerMetadata.passthrough().transform(({ credential_definition: { type, ...credentialDefinition }, ...rest }) => ({
351
+ ...rest,
352
+ types: type,
353
+ ...credentialDefinition
354
+ })).and(zJwtVcJsonCredentialIssuerMetadataDraft11);
355
+ var zJwtVcJsonCredentialRequestFormat = import_zod8.default.object({
356
+ format: zJwtVcJsonFormatIdentifier,
357
+ credential_definition: zJwtVcJsonCredentialDefinition
358
+ });
359
+ var zJwtVcJsonCredentialRequestDraft11 = import_zod8.default.object({
360
+ format: zJwtVcJsonFormatIdentifier,
361
+ // Credential definition was spread on top level instead of a separatey property in v11
362
+ // As well as using types instead of type
363
+ types: import_zod8.default.array(import_zod8.default.string()),
364
+ credentialSubject: import_zod8.default.optional(zW3cVcCredentialSubject)
365
+ }).passthrough();
366
+ var zJwtVcJsonCredentialRequestDraft11To14 = zJwtVcJsonCredentialRequestDraft11.transform(
367
+ ({ types, credentialSubject, ...rest }) => {
368
+ return {
369
+ ...rest,
370
+ credential_definition: {
371
+ type: types,
372
+ // Prevent weird typing issue with optional vs undefined
373
+ ...credentialSubject ? { credentialSubject } : {}
374
+ }
375
+ };
376
+ }
377
+ );
378
+ var zJwtVcJsonCredentialRequestDraft14To11 = zJwtVcJsonCredentialRequestFormat.passthrough().transform(({ credential_definition: { type, ...credentialDefinition }, ...rest }) => ({
379
+ ...rest,
380
+ types: type,
381
+ ...credentialDefinition
382
+ })).and(zJwtVcJsonCredentialRequestDraft11);
383
+
384
+ // src/version.ts
385
+ var Openid4vciDraftVersion = /* @__PURE__ */ ((Openid4vciDraftVersion2) => {
386
+ Openid4vciDraftVersion2["Draft14"] = "Draft14";
387
+ Openid4vciDraftVersion2["Draft11"] = "Draft11";
388
+ return Openid4vciDraftVersion2;
389
+ })(Openid4vciDraftVersion || {});
390
+
391
+ // src/metadata/credential-issuer/z-credential-issuer-metadata.ts
392
+ var allCredentialIssuerMetadataFormats = [
393
+ zSdJwtVcCredentialIssuerMetadata,
394
+ zMsoMdocCredentialIssuerMetadata,
395
+ zJwtVcJsonLdCredentialIssuerMetadata,
396
+ zLdpVcCredentialIssuerMetadata,
397
+ zJwtVcJsonCredentialIssuerMetadata
398
+ ];
399
+ var allCredentialIssuerMetadataFormatIdentifiers = allCredentialIssuerMetadataFormats.map(
400
+ (format) => format.shape.format.value
401
+ );
402
+ var zCredentialConfigurationSupportedWithFormats = zCredentialConfigurationSupportedCommon.transform(
403
+ (data, ctx) => {
404
+ if (!allCredentialIssuerMetadataFormatIdentifiers.includes(data.format)) return data;
405
+ const result = import_zod9.default.object({}).passthrough().and(import_zod9.default.discriminatedUnion("format", allCredentialIssuerMetadataFormats)).safeParse(data);
406
+ if (result.success) {
407
+ return result.data;
408
+ }
409
+ for (const issue of result.error.issues) {
410
+ ctx.addIssue(issue);
411
+ }
412
+ return import_zod9.default.NEVER;
413
+ }
414
+ );
415
+ var zCredentialIssuerMetadataDisplayEntry = import_zod9.default.object({
416
+ name: import_zod9.default.string().optional(),
417
+ locale: import_zod9.default.string().optional(),
418
+ logo: import_zod9.default.object({
419
+ // FIXME: make required again, but need to support draft 11 first
420
+ uri: import_zod9.default.string().optional(),
421
+ alt_text: import_zod9.default.string().optional()
422
+ }).passthrough().optional()
423
+ }).passthrough();
424
+ var zCredentialIssuerMetadataDraft14 = import_zod9.default.object({
425
+ credential_issuer: import_utils2.zHttpsUrl,
426
+ authorization_servers: import_zod9.default.array(import_utils2.zHttpsUrl).optional(),
427
+ credential_endpoint: import_utils2.zHttpsUrl,
428
+ deferred_credential_endpoint: import_utils2.zHttpsUrl.optional(),
429
+ notification_endpoint: import_utils2.zHttpsUrl.optional(),
430
+ // Added after draft 14, but needed for proper
431
+ nonce_endpoint: import_utils2.zHttpsUrl.optional(),
432
+ credential_response_encryption: import_zod9.default.object({
433
+ alg_values_supported: import_zod9.default.array(import_zod9.default.string()),
434
+ enc_values_supported: import_zod9.default.array(import_zod9.default.string()),
435
+ encryption_required: import_zod9.default.boolean()
436
+ }).passthrough().optional(),
437
+ batch_credential_issuance: import_zod9.default.object({
438
+ batch_size: import_zod9.default.number().positive()
439
+ }).passthrough().optional(),
440
+ signed_metadata: import_oauth22.zCompactJwt.optional(),
441
+ display: import_zod9.default.array(zCredentialIssuerMetadataDisplayEntry).optional(),
442
+ credential_configurations_supported: import_zod9.default.record(import_zod9.default.string(), zCredentialConfigurationSupportedWithFormats)
443
+ }).passthrough();
444
+ var zCredentialConfigurationSupportedDraft11To14 = import_zod9.default.object({
445
+ id: import_zod9.default.string().optional(),
446
+ format: import_zod9.default.string(),
447
+ cryptographic_suites_supported: import_zod9.default.array(import_zod9.default.string()).optional(),
448
+ display: import_zod9.default.array(
449
+ import_zod9.default.object({
450
+ logo: import_zod9.default.object({
451
+ url: import_zod9.default.string().url().optional()
452
+ }).passthrough().optional(),
453
+ background_image: import_zod9.default.object({
454
+ url: import_zod9.default.string().url().optional()
455
+ }).passthrough().optional()
456
+ }).passthrough()
457
+ ).optional()
458
+ }).passthrough().transform(({ cryptographic_suites_supported, display, id, ...rest }) => ({
459
+ ...rest,
460
+ ...cryptographic_suites_supported ? { credential_signing_alg_values_supported: cryptographic_suites_supported } : {},
461
+ ...display ? {
462
+ display: display.map(({ logo, background_image, ...displayRest }) => ({
463
+ ...displayRest,
464
+ // url became uri and also required
465
+ // so if there's no url in the logo, we remove the whole logo object
466
+ ...logo?.url ? {
467
+ // TODO: we should add the other params from logo as well
468
+ logo: {
469
+ uri: logo.url
470
+ }
471
+ } : {},
472
+ // TODO: we should add the other params from background_image as well
473
+ // url became uri and also required
474
+ // so if there's no url in the background_image, we remove the whole logo object
475
+ ...background_image?.url ? {
476
+ background_image: {
477
+ uri: background_image.url
478
+ }
479
+ } : {}
480
+ }))
481
+ } : {}
482
+ })).transform((data, ctx) => {
483
+ const formatSpecificTransformations = {
484
+ [zLdpVcFormatIdentifier.value]: zLdpVcCredentialIssuerMetadataDraft11To14,
485
+ [zJwtVcJsonFormatIdentifier.value]: zJwtVcJsonCredentialIssuerMetadataDraft11To14,
486
+ [zJwtVcJsonLdFormatIdentifier.value]: zJwtVcJsonLdCredentialIssuerMetadataDraft11To14
487
+ };
488
+ if (!Object.keys(formatSpecificTransformations).includes(data.format)) return data;
489
+ const schema = formatSpecificTransformations[data.format];
490
+ const result = schema.safeParse(data);
491
+ if (result.success) return result.data;
492
+ for (const issue of result.error.issues) {
493
+ ctx.addIssue(issue);
494
+ }
495
+ return import_zod9.default.NEVER;
496
+ }).pipe(zCredentialConfigurationSupportedWithFormats);
497
+ var zCredentialConfigurationSupportedDraft14To11 = zCredentialConfigurationSupportedWithFormats.and(
498
+ import_zod9.default.object({
499
+ id: import_zod9.default.string()
500
+ }).passthrough()
501
+ ).transform(({ id, credential_signing_alg_values_supported, display, proof_types_supported, scope, ...rest }) => ({
502
+ ...rest,
503
+ ...credential_signing_alg_values_supported ? { cryptographic_suites_supported: credential_signing_alg_values_supported } : {},
504
+ ...display ? {
505
+ display: display.map(({ logo, background_image, ...displayRest }) => {
506
+ const { uri: logoUri, ...logoRest } = logo ?? {};
507
+ const { uri: backgroundImageUri, ...backgroundImageRest } = background_image ?? {};
508
+ return {
509
+ ...displayRest,
510
+ // draft 11 uses url, draft 13/14 uses uri
511
+ ...logoUri ? { logo: { url: logoUri, ...logoRest } } : {},
512
+ // draft 11 uses url, draft 13/14 uses uri
513
+ ...backgroundImageUri ? { logo: { url: backgroundImageUri, ...backgroundImageRest } } : {}
514
+ };
515
+ })
516
+ } : {},
517
+ id
518
+ })).pipe(
519
+ import_zod9.default.union([
520
+ zLdpVcCredentialIssuerMetadataDraft14To11,
521
+ zJwtVcJsonCredentialIssuerMetadataDraft14To11,
522
+ zJwtVcJsonLdCredentialIssuerMetadataDraft14To11,
523
+ // To handle unrecognized formats and not error immediately we allow the common format as well
524
+ // but they can't use any of the foramt identifiers that have a specific transformation. This way if a format is
525
+ // has a transformation it NEEDS to use the format specific transformation, and otherwise we fall back to the common validation
526
+ import_zod9.default.object({
527
+ format: import_zod9.default.string().refine(
528
+ (input) => ![
529
+ zLdpVcFormatIdentifier.value,
530
+ zJwtVcJsonFormatIdentifier.value,
531
+ zJwtVcJsonLdFormatIdentifier.value
532
+ ].includes(input)
533
+ )
534
+ }).passthrough()
535
+ ])
536
+ );
537
+ var zCredentialIssuerMetadataDraft11To14 = import_zod9.default.object({
538
+ authorization_server: import_zod9.default.string().optional(),
539
+ credentials_supported: import_zod9.default.array(
540
+ import_zod9.default.object({
541
+ id: import_zod9.default.string().optional()
542
+ }).passthrough()
543
+ )
544
+ }).passthrough().transform(({ authorization_server, credentials_supported, ...rest }) => {
545
+ return {
546
+ ...rest,
547
+ ...authorization_server ? { authorization_servers: [authorization_server] } : {},
548
+ // Go from array to map but keep v11 structure
549
+ credential_configurations_supported: Object.fromEntries(
550
+ credentials_supported.map((supported) => supported.id ? [supported.id, supported] : void 0).filter((i) => i !== void 0)
551
+ )
552
+ };
553
+ }).pipe(
554
+ import_zod9.default.object({
555
+ // Update from v11 structrue to v14 structure
556
+ credential_configurations_supported: import_zod9.default.record(import_zod9.default.string(), zCredentialConfigurationSupportedDraft11To14)
557
+ }).passthrough()
558
+ ).pipe(zCredentialIssuerMetadataDraft14);
559
+ var zCredentialIssuerMetadataWithDraft11 = zCredentialIssuerMetadataDraft14.transform((issuerMetadata) => ({
560
+ ...issuerMetadata,
561
+ ...issuerMetadata.authorization_servers ? { authorization_server: issuerMetadata.authorization_servers[0] } : {},
562
+ credentials_supported: Object.entries(issuerMetadata.credential_configurations_supported).map(([id, value]) => ({
563
+ ...value,
564
+ id
565
+ }))
566
+ })).pipe(
567
+ zCredentialIssuerMetadataDraft14.extend({
568
+ credentials_supported: import_zod9.default.array(zCredentialConfigurationSupportedDraft14To11)
569
+ })
570
+ );
571
+ var zCredentialIssuerMetadata = import_zod9.default.union([
572
+ // First prioritize draft 14 (and 13)
573
+ zCredentialIssuerMetadataDraft14,
574
+ // Then try parsing draft 11 and transform into draft 14
575
+ zCredentialIssuerMetadataDraft11To14
576
+ ]);
577
+ var zCredentialIssuerMetadataWithDraftVersion = import_zod9.default.union([
578
+ // First prioritize draft 14 (and 13)
579
+ zCredentialIssuerMetadataDraft14.transform((credentialIssuerMetadata) => ({
580
+ credentialIssuerMetadata,
581
+ originalDraftVersion: "Draft14" /* Draft14 */
582
+ })),
583
+ // Then try parsing draft 11 and transform into draft 14
584
+ zCredentialIssuerMetadataDraft11To14.transform((credentialIssuerMetadata) => ({
585
+ credentialIssuerMetadata,
586
+ originalDraftVersion: "Draft11" /* Draft11 */
587
+ }))
588
+ ]);
589
+
590
+ // src/metadata/credential-issuer/credential-issuer-metadata.ts
591
+ var wellKnownCredentialIssuerSuffix = ".well-known/openid-credential-issuer";
592
+ async function fetchCredentialIssuerMetadata(credentialIssuer, fetch) {
593
+ const wellKnownMetadataUrl = (0, import_utils3.joinUriParts)(credentialIssuer, [wellKnownCredentialIssuerSuffix]);
594
+ const result = await (0, import_oauth23.fetchWellKnownMetadata)(wellKnownMetadataUrl, zCredentialIssuerMetadataWithDraftVersion, fetch);
595
+ if (result && result.credentialIssuerMetadata.credential_issuer !== credentialIssuer) {
596
+ throw new import_oauth23.Oauth2Error(
597
+ `The 'credential_issuer' parameter '${result.credentialIssuerMetadata.credential_issuer}' in the well known credential issuer metadata at '${wellKnownMetadataUrl}' does not match the provided credential issuer '${credentialIssuer}'.`
598
+ );
599
+ }
600
+ return result;
601
+ }
602
+ function extractKnownCredentialConfigurationSupportedFormats(credentialConfigurationsSupported) {
603
+ return Object.fromEntries(
604
+ Object.entries(credentialConfigurationsSupported).filter(
605
+ (entry) => allCredentialIssuerMetadataFormatIdentifiers.includes(entry[1].format)
606
+ )
607
+ );
608
+ }
609
+
610
+ // src/credential-request/credential-request-configurations.ts
611
+ function getCredentialConfigurationsMatchingRequestFormat({
612
+ requestFormat,
613
+ credentialConfigurations
614
+ }) {
615
+ const knownCredentialConfigurations = extractKnownCredentialConfigurationSupportedFormats(credentialConfigurations);
616
+ return Object.fromEntries(
617
+ Object.entries(knownCredentialConfigurations).filter(([, credentialConfiguration]) => {
618
+ if (credentialConfiguration.format !== requestFormat.format) return false;
619
+ const r = requestFormat;
620
+ const c = credentialConfiguration;
621
+ if ((c.format === "ldp_vc" || c.format === "jwt_vc_json-ld") && r.format === c.format) {
622
+ return (0, import_utils4.arrayEqualsIgnoreOrder)(r.credential_definition.type, c.credential_definition.type) && (0, import_utils4.arrayEqualsIgnoreOrder)(r.credential_definition["@context"], c.credential_definition["@context"]);
623
+ }
624
+ if (c.format === "jwt_vc_json" && r.format === c.format) {
625
+ return (0, import_utils4.arrayEqualsIgnoreOrder)(r.credential_definition.type, c.credential_definition.type);
626
+ }
627
+ if (c.format === "vc+sd-jwt" && r.format === c.format) {
628
+ return r.vct === c.vct;
629
+ }
630
+ if (c.format === "mso_mdoc" && r.format === c.format) {
631
+ return r.doctype === c.doctype;
632
+ }
633
+ return false;
634
+ })
635
+ );
636
+ }
637
+
638
+ // src/error/Openid4vciError.ts
639
+ var Openid4vciError = class extends Error {
640
+ constructor(message, options) {
641
+ const errorMessage = message ?? "Unknown error occured.";
642
+ const causeMessage = options?.cause instanceof Error ? ` ${options.cause.message}` : options?.cause ? ` ${options?.cause}` : "";
643
+ super(`${errorMessage}${causeMessage}`);
644
+ this.cause = options?.cause;
645
+ }
646
+ };
647
+
648
+ // src/error/Openid4vciRetrieveCredentialsError.ts
649
+ var Openid4vciRetrieveCredentialsError = class extends Openid4vciError {
650
+ constructor(message, response, responseText) {
651
+ super(
652
+ `${message}
653
+ ${JSON.stringify(response.credentialResponseResult?.data ?? response.credentialErrorResponseResult?.data ?? responseText, null, 2)}`
654
+ );
655
+ this.response = response;
656
+ }
657
+ };
658
+
659
+ // src/error/Openid4vciSendNotificationError.ts
660
+ var Openid4vciSendNotificationError = class extends Openid4vciError {
661
+ constructor(message, response) {
662
+ super(message);
663
+ this.response = response;
664
+ }
665
+ };
666
+
667
+ // src/metadata/credential-issuer/credential-configurations.ts
668
+ var import_oauth24 = require("@openid4vc/oauth2");
669
+ var import_utils5 = require("@openid4vc/utils");
670
+ function extractScopesForCredentialConfigurationIds(options) {
671
+ const scopes = /* @__PURE__ */ new Set();
672
+ for (const credentialConfigurationId of options.credentialConfigurationIds) {
673
+ const credentialConfiguration = options.issuerMetadata.credentialIssuer.credential_configurations_supported[credentialConfigurationId];
674
+ if (!credentialConfiguration) {
675
+ throw new import_oauth24.Oauth2Error(
676
+ `Credential configuration with id '${credentialConfigurationId}' not found in metadata from credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`
677
+ );
678
+ }
679
+ const scope = credentialConfiguration.scope;
680
+ if (scope) scopes.add(scope);
681
+ else if (!scope && options.throwOnConfigurationWithoutScope) {
682
+ throw new import_oauth24.Oauth2Error(
683
+ `Credential configuration with id '${credentialConfigurationId}' does not have a 'scope' configured, and 'throwOnConfigurationWithoutScope' was enabled.`
684
+ );
685
+ }
686
+ }
687
+ return scopes.size > 0 ? Array.from(scopes) : void 0;
688
+ }
689
+ function credentialsSupportedToCredentialConfigurationsSupported(credentialsSupported) {
690
+ const credentialConfigurationsSupported = {};
691
+ for (let index = 0; index < credentialsSupported.length; index++) {
692
+ const credentialSupported = credentialsSupported[index];
693
+ if (!credentialSupported.id) {
694
+ throw new Openid4vciError(
695
+ `Credential supported at index '${index}' does not have an 'id' property. Credential configuration requires the 'id' property as key`
696
+ );
697
+ }
698
+ const parseResult = zCredentialConfigurationSupportedDraft11To14.safeParse(credentialSupported);
699
+ if (!parseResult.success) {
700
+ throw new import_utils5.ValidationError(
701
+ `Error transforming credential supported with id '${credentialSupported.id}' to credential configuration supported format`,
702
+ parseResult.error
703
+ );
704
+ }
705
+ credentialConfigurationsSupported[credentialSupported.id] = parseResult.data;
706
+ }
707
+ return credentialConfigurationsSupported;
708
+ }
709
+
710
+ // src/Openid4vciClient.ts
711
+ var import_oauth218 = require("@openid4vc/oauth2");
712
+
713
+ // src/credential-offer/credential-offer.ts
714
+ var import_oauth26 = require("@openid4vc/oauth2");
715
+ var import_utils6 = require("@openid4vc/utils");
716
+
717
+ // src/credential-offer/z-credential-offer.ts
718
+ var import_oauth25 = require("@openid4vc/oauth2");
719
+ var import_zod11 = __toESM(require("zod"));
720
+
721
+ // ../utils/src/validation.ts
722
+ var import_zod10 = __toESM(require("zod"));
723
+
724
+ // ../utils/src/config.ts
725
+ var GLOBAL_CONFIG = {
726
+ allowInsecureUrls: false
727
+ };
728
+ function getGlobalConfig() {
729
+ return GLOBAL_CONFIG;
730
+ }
731
+
732
+ // ../utils/src/validation.ts
733
+ var zHttpsUrl2 = import_zod10.default.string().url().refine(
734
+ (url) => {
735
+ const { allowInsecureUrls } = getGlobalConfig();
736
+ return allowInsecureUrls ? url.startsWith("http://") || url.startsWith("https://") : url.startsWith("https://");
737
+ },
738
+ { message: "url must be an https:// url" }
739
+ );
740
+ var zInteger2 = import_zod10.default.number().int();
741
+ var zHttpMethod = import_zod10.default.enum(["GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "TRACE", "CONNECT", "PATCH"]);
742
+
743
+ // src/credential-offer/z-credential-offer.ts
744
+ var zTxCode = import_zod11.default.object({
745
+ input_mode: import_zod11.default.union([import_zod11.default.literal("numeric"), import_zod11.default.literal("text")]).optional(),
746
+ length: import_zod11.default.number().int().optional(),
747
+ description: import_zod11.default.string().max(300).optional()
748
+ }).passthrough();
749
+ var zCredentialOfferGrants = import_zod11.default.object({
750
+ authorization_code: import_zod11.default.object({
751
+ issuer_state: import_zod11.default.string().optional(),
752
+ authorization_server: zHttpsUrl2.optional()
753
+ }).passthrough().optional(),
754
+ [import_oauth25.preAuthorizedCodeGrantIdentifier]: import_zod11.default.object({
755
+ "pre-authorized_code": import_zod11.default.string(),
756
+ tx_code: zTxCode.optional(),
757
+ authorization_server: zHttpsUrl2.optional()
758
+ }).passthrough().optional()
759
+ }).passthrough();
760
+ var zCredentialOfferObjectDraft14 = import_zod11.default.object({
761
+ credential_issuer: zHttpsUrl2,
762
+ credential_configuration_ids: import_zod11.default.array(import_zod11.default.string()),
763
+ grants: import_zod11.default.optional(zCredentialOfferGrants)
764
+ }).passthrough();
765
+ var zCredentialOfferObjectDraft11To14 = import_zod11.default.object({
766
+ credential_issuer: zHttpsUrl2,
767
+ // We don't support the inline offer objects from draft 11
768
+ credentials: import_zod11.default.array(
769
+ import_zod11.default.string({ message: "Only string credential identifiers are supported for draft 11 credential offers" })
770
+ ),
771
+ grants: import_zod11.default.optional(
772
+ import_zod11.default.object({
773
+ // Has extra param in draft 14, but doesn't matter for transform purposes
774
+ authorization_code: zCredentialOfferGrants.shape.authorization_code,
775
+ [import_oauth25.preAuthorizedCodeGrantIdentifier]: import_zod11.default.object({
776
+ "pre-authorized_code": import_zod11.default.string(),
777
+ user_pin_required: import_zod11.default.optional(import_zod11.default.boolean())
778
+ }).passthrough().optional()
779
+ })
780
+ )
781
+ }).passthrough().transform(({ credentials, grants, ...rest }) => {
782
+ const v14 = {
783
+ ...rest,
784
+ credential_configuration_ids: credentials
785
+ };
786
+ if (grants) {
787
+ v14.grants = { ...grants };
788
+ if (grants[import_oauth25.preAuthorizedCodeGrantIdentifier]) {
789
+ const { user_pin_required, ...restGrants } = grants[import_oauth25.preAuthorizedCodeGrantIdentifier];
790
+ v14.grants[import_oauth25.preAuthorizedCodeGrantIdentifier] = {
791
+ ...restGrants
792
+ };
793
+ if (user_pin_required) {
794
+ v14.grants[import_oauth25.preAuthorizedCodeGrantIdentifier].tx_code = {
795
+ input_mode: "text"
796
+ };
797
+ }
798
+ }
799
+ }
800
+ return v14;
801
+ }).pipe(zCredentialOfferObjectDraft14);
802
+ var zCredentialOfferObject = import_zod11.default.union([
803
+ // First prioritize draft 14 (and 13)
804
+ zCredentialOfferObjectDraft14,
805
+ // Then try parsing draft 11 and transform into draft 14
806
+ zCredentialOfferObjectDraft11To14
807
+ ]);
808
+
809
+ // src/credential-offer/credential-offer.ts
810
+ async function resolveCredentialOffer(credentialOffer, options) {
811
+ const parsedQueryParams = (0, import_utils6.getQueryParams)(credentialOffer);
812
+ let credentialOfferParseResult;
813
+ if (parsedQueryParams.credential_offer_uri) {
814
+ const fetchWithZod = (0, import_utils6.createZodFetcher)(options?.fetch);
815
+ const { response, result } = await fetchWithZod(
816
+ zCredentialOfferObject,
817
+ import_utils6.ContentType.Json,
818
+ parsedQueryParams.credential_offer_uri
819
+ );
820
+ if (!response.ok || !result) {
821
+ throw new import_oauth26.InvalidFetchResponseError(
822
+ `Fetching credential offer from '${parsedQueryParams.credential_offer_uri}' resulted in an unsuccesfull response with status '${response.status}'`,
823
+ await response.clone().text(),
824
+ response
825
+ );
826
+ }
827
+ credentialOfferParseResult = result;
828
+ } else if (parsedQueryParams.credential_offer) {
829
+ let credentialOfferJson;
830
+ try {
831
+ credentialOfferJson = JSON.parse(decodeURIComponent(parsedQueryParams.credential_offer));
832
+ } catch (error) {
833
+ throw new import_oauth26.Oauth2Error(`Error parsing JSON from 'credential_offer' param in credential offer '${credentialOffer}'`);
834
+ }
835
+ credentialOfferParseResult = zCredentialOfferObject.safeParse(credentialOfferJson);
836
+ } else {
837
+ throw new import_oauth26.Oauth2Error(`Credential offer did not contain either 'credential_offer' or 'credential_offer_uri' param.`);
838
+ }
839
+ if (credentialOfferParseResult.error) {
840
+ throw new import_utils6.ValidationError(
841
+ `Error parsing credential offer in draft 11, 13 or 14 format extracted from credential offer '${credentialOffer}'`,
842
+ credentialOfferParseResult.error
843
+ );
844
+ }
845
+ return credentialOfferParseResult.data;
846
+ }
847
+ function determineAuthorizationServerForCredentialOffer(options) {
848
+ const authorizationServers = options.issuerMetadata.credentialIssuer.authorization_servers;
849
+ let authorizationServer;
850
+ if (options.grantAuthorizationServer) {
851
+ authorizationServer = options.grantAuthorizationServer;
852
+ if (!authorizationServers) {
853
+ throw new import_oauth26.Oauth2Error(
854
+ `Credential offer grant contains 'authorization_server' with value '${options.grantAuthorizationServer}' but credential issuer metadata does not have an 'authorization_servers' property to match the value against.`
855
+ );
856
+ }
857
+ if (!authorizationServers.includes(authorizationServer)) {
858
+ throw new import_oauth26.Oauth2Error(
859
+ `Credential offer grant contains 'authorization_server' with value '${options.grantAuthorizationServer}' but credential issuer metadata does not include this authorization server. Available 'authorization_server' values are ${authorizationServers.join(", ")}.`
860
+ );
861
+ }
862
+ } else if (!authorizationServers) {
863
+ authorizationServer = options.issuerMetadata.credentialIssuer.credential_issuer;
864
+ } else {
865
+ if (authorizationServers.length === 0) {
866
+ throw new import_oauth26.Oauth2Error(`Credential issuer metadata has 'authorization_servers' value with length of 0`);
867
+ }
868
+ if (authorizationServers.length > 1) {
869
+ throw new import_oauth26.Oauth2Error(
870
+ `Credential issuer metadata has 'authorization_server' with multiple entries, but the credential offer grant did not specify which authorization server to use.`
871
+ );
872
+ }
873
+ authorizationServer = authorizationServers[0];
874
+ }
875
+ return authorizationServer;
876
+ }
877
+ async function createCredentialOffer(options) {
878
+ const {
879
+ [import_oauth26.preAuthorizedCodeGrantIdentifier]: preAuthorizedCodeGrant,
880
+ [import_oauth26.authorizationCodeGrantIdentifier]: authorizationCodeGrant,
881
+ ...restGrants
882
+ } = options.grants;
883
+ const grants = { ...restGrants };
884
+ if (authorizationCodeGrant) {
885
+ determineAuthorizationServerForCredentialOffer({
886
+ issuerMetadata: options.issuerMetadata,
887
+ grantAuthorizationServer: authorizationCodeGrant.authorization_server
888
+ });
889
+ grants[import_oauth26.authorizationCodeGrantIdentifier] = authorizationCodeGrant;
890
+ }
891
+ if (preAuthorizedCodeGrant) {
892
+ determineAuthorizationServerForCredentialOffer({
893
+ issuerMetadata: options.issuerMetadata,
894
+ grantAuthorizationServer: preAuthorizedCodeGrant.authorization_server
895
+ });
896
+ grants[import_oauth26.preAuthorizedCodeGrantIdentifier] = {
897
+ ...preAuthorizedCodeGrant,
898
+ "pre-authorized_code": preAuthorizedCodeGrant["pre-authorized_code"] ?? (0, import_utils6.encodeToBase64Url)(await options.callbacks.generateRandom(32))
899
+ };
900
+ const txCode = grants[import_oauth26.preAuthorizedCodeGrantIdentifier].tx_code;
901
+ if (txCode && options.issuerMetadata.originalDraftVersion === "Draft11" /* Draft11 */) {
902
+ grants[import_oauth26.preAuthorizedCodeGrantIdentifier].user_pin_required = txCode !== void 0;
903
+ }
904
+ }
905
+ const idsNotInMetadata = options.credentialConfigurationIds.filter(
906
+ (id) => options.issuerMetadata.credentialIssuer.credential_configurations_supported[id] === void 0
907
+ );
908
+ if (idsNotInMetadata.length > 0) {
909
+ throw new import_oauth26.Oauth2Error(
910
+ `Credential configuration ids ${idsNotInMetadata} not found in the credential issuer metadata 'credential_configurations_supported'. Available ids are ${Object.keys(options.issuerMetadata.credentialIssuer.credential_configurations_supported).join(", ")}.`
911
+ );
912
+ }
913
+ const credentialOfferScheme = options.credentialOfferScheme ?? "openid-credential-offer://";
914
+ const credentialOfferObject = (0, import_utils6.parseWithErrorHandling)(zCredentialOfferObject, {
915
+ credential_issuer: options.issuerMetadata.credentialIssuer.credential_issuer,
916
+ credential_configuration_ids: options.credentialConfigurationIds,
917
+ grants,
918
+ ...options.additionalPayload
919
+ });
920
+ if (options.issuerMetadata.originalDraftVersion === "Draft11" /* Draft11 */) {
921
+ credentialOfferObject.credentials = credentialOfferObject.credential_configuration_ids;
922
+ }
923
+ const url = new import_utils6.URL(credentialOfferScheme);
924
+ url.search = `?${new import_utils6.URLSearchParams([
925
+ ...url.searchParams.entries(),
926
+ ...(0, import_utils6.objectToQueryParams)({
927
+ credential_offer_uri: options.credentialOfferUri,
928
+ // Only add credential_offer is uri is undefined
929
+ credential_offer: options.credentialOfferUri ? void 0 : credentialOfferObject
930
+ }).entries()
931
+ ]).toString()}`;
932
+ return {
933
+ credentialOffer: url.toString(),
934
+ credentialOfferObject
935
+ };
936
+ }
937
+
938
+ // src/credential-request/format-payload.ts
939
+ var import_utils7 = require("@openid4vc/utils");
940
+ function getCredentialRequestFormatPayloadForCredentialConfigurationId(options) {
941
+ const credentialConfiguration = options.issuerMetadata.credentialIssuer.credential_configurations_supported[options.credentialConfigurationId];
942
+ if (!credentialConfiguration) {
943
+ throw new Openid4vciError(
944
+ `Could not find credential configuration with id '${options.credentialConfigurationId}' in metadata of credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'.`
945
+ );
946
+ }
947
+ if ((0, import_utils7.zIs)(zSdJwtVcCredentialIssuerMetadata, credentialConfiguration)) {
948
+ return {
949
+ format: credentialConfiguration.format,
950
+ vct: credentialConfiguration.vct
951
+ };
952
+ }
953
+ if ((0, import_utils7.zIs)(zMsoMdocCredentialIssuerMetadata, credentialConfiguration)) {
954
+ return {
955
+ format: credentialConfiguration.format,
956
+ doctype: credentialConfiguration.doctype
957
+ };
958
+ }
959
+ if ((0, import_utils7.zIs)(zLdpVcCredentialIssuerMetadata, credentialConfiguration)) {
960
+ return {
961
+ format: credentialConfiguration.format,
962
+ credential_definition: {
963
+ "@context": credentialConfiguration.credential_definition["@context"],
964
+ type: credentialConfiguration.credential_definition.type
965
+ }
966
+ };
967
+ }
968
+ if ((0, import_utils7.zIs)(zJwtVcJsonLdCredentialIssuerMetadata, credentialConfiguration)) {
969
+ return {
970
+ format: credentialConfiguration.format,
971
+ credential_definition: {
972
+ "@context": credentialConfiguration.credential_definition["@context"],
973
+ type: credentialConfiguration.credential_definition.type
974
+ }
975
+ };
976
+ }
977
+ if ((0, import_utils7.zIs)(zJwtVcJsonCredentialIssuerMetadata, credentialConfiguration)) {
978
+ return {
979
+ format: credentialConfiguration.format,
980
+ credential_definition: {
981
+ type: credentialConfiguration.credential_definition.type
982
+ }
983
+ };
984
+ }
985
+ throw new Openid4vciError(
986
+ `Unknown format '${credentialConfiguration.format}' in credential configuration with id '${options.credentialConfigurationId}' for credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`
987
+ );
988
+ }
989
+
990
+ // src/credential-request/retrieve-credentials.ts
991
+ var import_oauth210 = require("@openid4vc/oauth2");
992
+ var import_utils9 = require("@openid4vc/utils");
993
+
994
+ // src/credential-request/z-credential-request.ts
995
+ var import_zod15 = __toESM(require("zod"));
996
+
997
+ // src/credential-request/z-credential-request-common.ts
998
+ var import_oauth29 = require("@openid4vc/oauth2");
999
+ var import_zod14 = __toESM(require("zod"));
1000
+
1001
+ // src/formats/proof-type/jwt/z-jwt-proof-type.ts
1002
+ var import_oauth27 = require("@openid4vc/oauth2");
1003
+ var import_utils8 = require("@openid4vc/utils");
1004
+ var import_zod12 = __toESM(require("zod"));
1005
+ var zJwtProofTypeIdentifier = import_zod12.default.literal("jwt");
1006
+ var jwtProofTypeIdentifier = zJwtProofTypeIdentifier.value;
1007
+ var zCredentialRequestProofJwt = import_zod12.default.object({
1008
+ proof_type: zJwtProofTypeIdentifier,
1009
+ jwt: import_oauth27.zCompactJwt
1010
+ });
1011
+ var zCredentialRequestJwtProofTypeHeader = import_oauth27.zJwtHeader.merge(
1012
+ import_zod12.default.object({
1013
+ key_attestation: import_zod12.default.optional(import_oauth27.zCompactJwt),
1014
+ typ: import_zod12.default.literal("openid4vci-proof+jwt")
1015
+ })
1016
+ ).passthrough().refine(({ kid, jwk }) => jwk === void 0 || kid === void 0, {
1017
+ message: `Both 'jwk' and 'kid' are defined. Only one is allowed`
1018
+ }).refine(({ trust_chain, kid }) => !trust_chain || !kid, {
1019
+ message: `When 'trust_chain' is provided, 'kid' is required`
1020
+ });
1021
+ var zCredentialRequestJwtProofTypePayload = import_zod12.default.object({
1022
+ ...import_oauth27.zJwtPayload.shape,
1023
+ aud: import_utils8.zHttpsUrl,
1024
+ iat: import_utils8.zInteger
1025
+ }).passthrough();
1026
+
1027
+ // src/formats/proof-type/attestation/z-attestation-proof-type.ts
1028
+ var import_oauth28 = require("@openid4vc/oauth2");
1029
+ var import_zod13 = __toESM(require("zod"));
1030
+ var zAttestationProofTypeIdentifier = import_zod13.default.literal("attestation");
1031
+ var attestationProofTypeIdentifier = zAttestationProofTypeIdentifier.value;
1032
+ var zCredentialRequestProofAttestation = import_zod13.default.object({
1033
+ proof_type: zAttestationProofTypeIdentifier,
1034
+ attestation: import_oauth28.zCompactJwt
1035
+ });
1036
+ var zCredentialRequestAttestationProofTypePayload = zKeyAttestationJwtPayloadForUse("proof_type.attestation");
1037
+
1038
+ // src/credential-request/z-credential-request-common.ts
1039
+ var zCredentialRequestProofCommon = import_zod14.default.object({
1040
+ proof_type: import_zod14.default.string()
1041
+ }).passthrough();
1042
+ var allCredentialRequestProofs = [zCredentialRequestProofJwt, zCredentialRequestProofAttestation];
1043
+ var zCredentialRequestProof = import_zod14.default.union([
1044
+ zCredentialRequestProofCommon,
1045
+ import_zod14.default.discriminatedUnion("proof_type", allCredentialRequestProofs)
1046
+ ]);
1047
+ var zCredentialRequestProofsCommon = import_zod14.default.record(import_zod14.default.string(), import_zod14.default.array(import_zod14.default.unknown()));
1048
+ var zCredentialRequestProofs = import_zod14.default.object({
1049
+ [zJwtProofTypeIdentifier.value]: import_zod14.default.optional(import_zod14.default.array(zCredentialRequestProofJwt.shape.jwt)),
1050
+ [zAttestationProofTypeIdentifier.value]: import_zod14.default.optional(import_zod14.default.array(zCredentialRequestProofAttestation.shape.attestation))
1051
+ });
1052
+ var zCredentialRequestCommon = import_zod14.default.object({
1053
+ proof: zCredentialRequestProof.optional(),
1054
+ proofs: import_zod14.default.optional(
1055
+ import_zod14.default.intersection(zCredentialRequestProofsCommon, zCredentialRequestProofs).refine((proofs) => Object.values(proofs).length === 1, {
1056
+ message: `The 'proofs' object in a credential request should contain exactly one attribute`
1057
+ })
1058
+ ),
1059
+ credential_response_encryption: import_zod14.default.object({
1060
+ jwk: import_oauth29.zJwk,
1061
+ alg: import_zod14.default.string(),
1062
+ enc: import_zod14.default.string()
1063
+ }).passthrough().optional()
1064
+ }).passthrough().refine(({ proof, proofs }) => !(proof !== void 0 && proofs !== void 0), {
1065
+ message: `Both 'proof' and 'proofs' are defined. Only one is allowed`
1066
+ });
1067
+
1068
+ // src/credential-request/z-credential-request.ts
1069
+ var allCredentialRequestFormats = [
1070
+ zSdJwtVcCredentialRequestFormat,
1071
+ zMsoMdocCredentialRequestFormat,
1072
+ zLdpVcCredentialRequestFormat,
1073
+ zJwtVcJsonLdCredentialRequestFormat,
1074
+ zJwtVcJsonCredentialRequestFormat
1075
+ ];
1076
+ var allCredentialRequestFormatIdentifiers = allCredentialRequestFormats.map(
1077
+ (format) => format.shape.format.value
1078
+ );
1079
+ var zAuthorizationDetailsCredentialRequest = import_zod15.default.object({
1080
+ credential_identifier: import_zod15.default.string(),
1081
+ // Cannot be present if credential identifier is present
1082
+ format: import_zod15.default.never({ message: "'format' cannot be defined when 'credential_identifier' is set." }).optional()
1083
+ });
1084
+ var zCredentialRequestFormatNoCredentialIdentifier = import_zod15.default.object({
1085
+ format: import_zod15.default.string(),
1086
+ credential_identifier: import_zod15.default.never({ message: "'credential_identifier' cannot be defined when 'format' is set." }).optional()
1087
+ }).passthrough();
1088
+ var zCredenialRequestDraft14WithFormat = zCredentialRequestCommon.and(zCredentialRequestFormatNoCredentialIdentifier).transform((data, ctx) => {
1089
+ if (!allCredentialRequestFormatIdentifiers.includes(data.format)) return data;
1090
+ const result = import_zod15.default.object({}).passthrough().and(import_zod15.default.discriminatedUnion("format", allCredentialRequestFormats)).safeParse(data);
1091
+ if (result.success) {
1092
+ return result.data;
1093
+ }
1094
+ for (const issue of result.error.issues) {
1095
+ ctx.addIssue(issue);
1096
+ }
1097
+ return import_zod15.default.NEVER;
1098
+ });
1099
+ var zCredentialRequestDraft14 = import_zod15.default.union([
1100
+ zCredenialRequestDraft14WithFormat,
1101
+ zCredentialRequestCommon.and(zAuthorizationDetailsCredentialRequest)
1102
+ ]);
1103
+ var zCredentialRequestDraft11To14 = zCredentialRequestCommon.and(zCredentialRequestFormatNoCredentialIdentifier).transform((data, ctx) => {
1104
+ const formatSpecificTransformations = {
1105
+ [zLdpVcFormatIdentifier.value]: zLdpVcCredentialRequestDraft11To14,
1106
+ [zJwtVcJsonFormatIdentifier.value]: zJwtVcJsonCredentialRequestDraft11To14,
1107
+ [zJwtVcJsonLdFormatIdentifier.value]: zJwtVcJsonLdCredentialRequestDraft11To14
1108
+ };
1109
+ if (!Object.keys(formatSpecificTransformations).includes(data.format)) return data;
1110
+ const schema = formatSpecificTransformations[data.format];
1111
+ const result = schema.safeParse(data);
1112
+ if (result.success) return result.data;
1113
+ for (const issue of result.error.issues) {
1114
+ ctx.addIssue(issue);
1115
+ }
1116
+ return import_zod15.default.NEVER;
1117
+ }).pipe(zCredentialRequestDraft14);
1118
+ var zCredentialRequestDraft14To11 = zCredentialRequestDraft14.refine(
1119
+ (data) => data.credential_identifier === void 0,
1120
+ `'credential_identifier' is not supported in OpenID4VCI draft 11`
1121
+ ).transform((data, ctx) => {
1122
+ const formatSpecificTransformations = {
1123
+ [zLdpVcFormatIdentifier.value]: zLdpVcCredentialRequestDraft14To11,
1124
+ [zJwtVcJsonFormatIdentifier.value]: zJwtVcJsonCredentialRequestDraft14To11,
1125
+ [zJwtVcJsonLdFormatIdentifier.value]: zJwtVcJsonLdCredentialRequestDraft14To11
1126
+ };
1127
+ if (!Object.keys(formatSpecificTransformations).includes(data.format)) return data;
1128
+ const schema = formatSpecificTransformations[data.format];
1129
+ const result = schema.safeParse(data);
1130
+ if (result.success) return result.data;
1131
+ for (const issue of result.error.issues) {
1132
+ ctx.addIssue(issue);
1133
+ }
1134
+ return import_zod15.default.NEVER;
1135
+ });
1136
+ var zCredentialRequest = import_zod15.default.union([zCredentialRequestDraft14, zCredentialRequestDraft11To14]);
1137
+
1138
+ // src/credential-request/z-credential-response.ts
1139
+ var import_zod17 = __toESM(require("zod"));
1140
+
1141
+ // ../oauth2/src/common/z-oauth2-error.ts
1142
+ var import_zod16 = __toESM(require("zod"));
1143
+ var Oauth2ErrorCodes = /* @__PURE__ */ ((Oauth2ErrorCodes4) => {
1144
+ Oauth2ErrorCodes4["ServerError"] = "server_error";
1145
+ Oauth2ErrorCodes4["InvalidTarget"] = "invalid_target";
1146
+ Oauth2ErrorCodes4["InvalidRequest"] = "invalid_request";
1147
+ Oauth2ErrorCodes4["InvalidToken"] = "invalid_token";
1148
+ Oauth2ErrorCodes4["InsufficientScope"] = "insufficient_scope";
1149
+ Oauth2ErrorCodes4["InvalidGrant"] = "invalid_grant";
1150
+ Oauth2ErrorCodes4["InvalidClient"] = "invalid_client";
1151
+ Oauth2ErrorCodes4["UnauthorizedClient"] = "unauthorized_client";
1152
+ Oauth2ErrorCodes4["UnsupportedGrantType"] = "unsupported_grant_type";
1153
+ Oauth2ErrorCodes4["InvalidScope"] = "invalid_scope";
1154
+ Oauth2ErrorCodes4["InvalidDpopProof"] = "invalid_dpop_proof";
1155
+ Oauth2ErrorCodes4["UseDpopNonce"] = "use_dpop_nonce";
1156
+ Oauth2ErrorCodes4["RedirectToWeb"] = "redirect_to_web";
1157
+ Oauth2ErrorCodes4["InvalidSession"] = "invalid_session";
1158
+ Oauth2ErrorCodes4["InsufficientAuthorization"] = "insufficient_authorization";
1159
+ Oauth2ErrorCodes4["InvalidCredentialRequest"] = "invalid_credential_request";
1160
+ Oauth2ErrorCodes4["CredentialRequestDenied"] = "credential_request_denied";
1161
+ Oauth2ErrorCodes4["UnsupportedCredentialType"] = "unsupported_credential_type";
1162
+ Oauth2ErrorCodes4["UnsupportedCredentialFormat"] = "unsupported_credential_format";
1163
+ Oauth2ErrorCodes4["InvalidProof"] = "invalid_proof";
1164
+ Oauth2ErrorCodes4["InvalidNonce"] = "invalid_nonce";
1165
+ Oauth2ErrorCodes4["InvalidEncryptionParameters"] = "invalid_encryption_parameters";
1166
+ Oauth2ErrorCodes4["InvalidRequestUri"] = "invalid_request_uri";
1167
+ Oauth2ErrorCodes4["InvalidRequestObject"] = "invalid_request_object";
1168
+ Oauth2ErrorCodes4["RequestNotSupported"] = "request_not_supported";
1169
+ Oauth2ErrorCodes4["RequestUriNotSupported"] = "request_uri_not_supported";
1170
+ Oauth2ErrorCodes4["VpFormatsNotSupported"] = "vp_formats_not_supported";
1171
+ Oauth2ErrorCodes4["AccessDenied"] = "access_denied";
1172
+ Oauth2ErrorCodes4["InvalidPresentationDefinitionUri"] = "invalid_presentation_definition_uri";
1173
+ Oauth2ErrorCodes4["InvalidPresentationDefinitionReference"] = "invalid_presentation_definition_reference";
1174
+ Oauth2ErrorCodes4["InvalidRequestUriMethod"] = "invalid_request_uri_method";
1175
+ Oauth2ErrorCodes4["InvalidTransactionData"] = "invalid_transaction_data";
1176
+ Oauth2ErrorCodes4["WalletUnavailable"] = "wallet_unavailable";
1177
+ return Oauth2ErrorCodes4;
1178
+ })(Oauth2ErrorCodes || {});
1179
+ var zOauth2ErrorResponse = import_zod16.default.object({
1180
+ error: import_zod16.default.union([import_zod16.default.nativeEnum(Oauth2ErrorCodes), import_zod16.default.string()]),
1181
+ error_description: import_zod16.default.string().optional(),
1182
+ error_uri: import_zod16.default.string().optional()
1183
+ }).passthrough();
1184
+
1185
+ // src/credential-request/z-credential-response.ts
1186
+ var zCredentialEncoding = import_zod17.default.union([import_zod17.default.string(), import_zod17.default.record(import_zod17.default.string(), import_zod17.default.any())]);
1187
+ var zCredentialResponse = import_zod17.default.object({
1188
+ credential: import_zod17.default.optional(zCredentialEncoding),
1189
+ credentials: import_zod17.default.optional(import_zod17.default.array(zCredentialEncoding)),
1190
+ transaction_id: import_zod17.default.string().optional(),
1191
+ c_nonce: import_zod17.default.string().optional(),
1192
+ c_nonce_expires_in: import_zod17.default.number().int().optional(),
1193
+ notification_id: import_zod17.default.string().optional()
1194
+ }).passthrough().refine(
1195
+ (value) => {
1196
+ const { credential, credentials, transaction_id } = value;
1197
+ return [credential, credentials, transaction_id].filter((i) => i !== void 0).length === 1;
1198
+ },
1199
+ {
1200
+ message: `Exactly one of 'credential', 'credentials', or 'transaction_id' MUST be defined.`
1201
+ }
1202
+ );
1203
+ var zCredentialErrorResponse = import_zod17.default.object({
1204
+ ...zOauth2ErrorResponse.shape,
1205
+ c_nonce: import_zod17.default.string().optional(),
1206
+ c_nonce_expires_in: import_zod17.default.number().int().optional()
1207
+ }).passthrough();
1208
+
1209
+ // src/credential-request/retrieve-credentials.ts
1210
+ async function retrieveCredentialsWithFormat(options) {
1211
+ const credentialRequest = {
1212
+ ...options.formatPayload,
1213
+ ...options.additionalRequestPayload,
1214
+ proof: options.proof,
1215
+ proofs: options.proofs
1216
+ };
1217
+ return retrieveCredentials({
1218
+ callbacks: options.callbacks,
1219
+ credentialRequest,
1220
+ issuerMetadata: options.issuerMetadata,
1221
+ accessToken: options.accessToken,
1222
+ dpop: options.dpop
1223
+ });
1224
+ }
1225
+ async function retrieveCredentials(options) {
1226
+ const credentialEndpoint = options.issuerMetadata.credentialIssuer.credential_endpoint;
1227
+ let credentialRequest = (0, import_utils9.parseWithErrorHandling)(
1228
+ zCredentialRequest,
1229
+ options.credentialRequest,
1230
+ "Error validating credential request"
1231
+ );
1232
+ if (credentialRequest.proofs) {
1233
+ const { batch_credential_issuance } = options.issuerMetadata.credentialIssuer;
1234
+ if (!batch_credential_issuance) {
1235
+ throw new import_oauth210.Oauth2Error(
1236
+ `Credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}' does not support batch credential issuance using the 'proofs' request property. Only 'proof' is supported.`
1237
+ );
1238
+ }
1239
+ const proofs = Object.values(credentialRequest.proofs)[0];
1240
+ if (proofs.length > batch_credential_issuance.batch_size) {
1241
+ throw new import_oauth210.Oauth2Error(
1242
+ `Credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}' supports batch issuance, but the max batch size is '${batch_credential_issuance.batch_size}'. A total of '${proofs.length}' proofs were provided.`
1243
+ );
1244
+ }
1245
+ }
1246
+ if (options.issuerMetadata.originalDraftVersion === "Draft11" /* Draft11 */) {
1247
+ credentialRequest = (0, import_utils9.parseWithErrorHandling)(
1248
+ zCredentialRequestDraft14To11,
1249
+ credentialRequest,
1250
+ `Error transforming credential request from ${"Draft14" /* Draft14 */} to ${"Draft11" /* Draft11 */}`
1251
+ );
1252
+ }
1253
+ const resourceResponse = await (0, import_oauth210.resourceRequest)({
1254
+ dpop: options.dpop,
1255
+ accessToken: options.accessToken,
1256
+ callbacks: options.callbacks,
1257
+ url: credentialEndpoint,
1258
+ requestOptions: {
1259
+ method: "POST",
1260
+ headers: {
1261
+ "Content-Type": import_utils9.ContentType.Json
1262
+ },
1263
+ body: JSON.stringify(credentialRequest)
1264
+ }
1265
+ });
1266
+ if (!resourceResponse.ok) {
1267
+ const credentialErrorResponseResult = (0, import_utils9.isResponseContentType)(import_utils9.ContentType.Json, resourceResponse.response) ? zCredentialErrorResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
1268
+ return {
1269
+ ...resourceResponse,
1270
+ credentialErrorResponseResult
1271
+ };
1272
+ }
1273
+ const credentialResponseResult = (0, import_utils9.isResponseContentType)(import_utils9.ContentType.Json, resourceResponse.response) ? zCredentialResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
1274
+ if (!credentialResponseResult?.success) {
1275
+ return {
1276
+ ...resourceResponse,
1277
+ ok: false,
1278
+ credentialResponseResult
1279
+ };
1280
+ }
1281
+ return {
1282
+ ...resourceResponse,
1283
+ credentialResponse: credentialResponseResult.data
1284
+ };
1285
+ }
1286
+
1287
+ // src/formats/proof-type/jwt/jwt-proof-type.ts
1288
+ var import_oauth213 = require("@openid4vc/oauth2");
1289
+ var import_oauth214 = require("@openid4vc/oauth2");
1290
+ var import_utils11 = require("@openid4vc/utils");
1291
+
1292
+ // src/key-attestation/key-attestation.ts
1293
+ var import_oauth211 = require("@openid4vc/oauth2");
1294
+ var import_oauth212 = require("@openid4vc/oauth2");
1295
+ var import_utils10 = require("@openid4vc/utils");
1296
+ async function verifyKeyAttestationJwt(options) {
1297
+ const { header, payload } = (0, import_oauth211.decodeJwt)({
1298
+ jwt: options.keyAttestationJwt,
1299
+ headerSchema: zKeyAttestationJwtHeader,
1300
+ payloadSchema: zKeyAttestationJwtPayloadForUse(options.use)
1301
+ });
1302
+ const now = options.now?.getTime() ?? Date.now();
1303
+ if (options.nonceExpiresAt && now > options.nonceExpiresAt.getTime()) {
1304
+ throw new Openid4vciError("Nonce used for key attestation jwt expired");
1305
+ }
1306
+ const { signer } = await (0, import_oauth212.verifyJwt)({
1307
+ compact: options.keyAttestationJwt,
1308
+ header,
1309
+ payload,
1310
+ signer: (0, import_oauth212.jwtSignerFromJwt)({ header, payload }),
1311
+ verifyJwtCallback: options.callbacks.verifyJwt,
1312
+ errorMessage: "Error verifiying key attestation jwt",
1313
+ expectedNonce: options.expectedNonce,
1314
+ now: options.now
1315
+ });
1316
+ return {
1317
+ header,
1318
+ payload,
1319
+ signer
1320
+ };
1321
+ }
1322
+
1323
+ // src/formats/proof-type/jwt/jwt-proof-type.ts
1324
+ async function createCredentialRequestJwtProof(options) {
1325
+ const header = (0, import_utils11.parseWithErrorHandling)(zCredentialRequestJwtProofTypeHeader, {
1326
+ ...(0, import_oauth213.jwtHeaderFromJwtSigner)(options.signer),
1327
+ key_attestation: options.keyAttestationJwt,
1328
+ typ: "openid4vci-proof+jwt"
1329
+ });
1330
+ const payload = (0, import_utils11.parseWithErrorHandling)(zCredentialRequestJwtProofTypePayload, {
1331
+ nonce: options.nonce,
1332
+ aud: options.credentialIssuer,
1333
+ iat: (0, import_utils11.dateToSeconds)(options.issuedAt),
1334
+ iss: options.clientId
1335
+ });
1336
+ const { jwt, signerJwk } = await options.callbacks.signJwt(options.signer, { header, payload });
1337
+ if (options.keyAttestationJwt) {
1338
+ const decodedKeyAttestation = (0, import_oauth213.decodeJwt)({
1339
+ jwt: options.keyAttestationJwt,
1340
+ headerSchema: zKeyAttestationJwtHeader,
1341
+ payloadSchema: zKeyAttestationJwtPayload
1342
+ });
1343
+ const isSigedWithAttestedKey = await (0, import_oauth213.isJwkInSet)({
1344
+ jwk: signerJwk,
1345
+ jwks: decodedKeyAttestation.payload.attested_keys,
1346
+ callbacks: options.callbacks
1347
+ });
1348
+ if (!isSigedWithAttestedKey) {
1349
+ throw new Openid4vciError(
1350
+ `Credential request jwt proof is not signed with a key in the 'key_attestation' jwt payload 'attested_keys'`
1351
+ );
1352
+ }
1353
+ }
1354
+ return jwt;
1355
+ }
1356
+ async function verifyCredentialRequestJwtProof(options) {
1357
+ const { header, payload } = (0, import_oauth213.decodeJwt)({
1358
+ jwt: options.jwt,
1359
+ headerSchema: zCredentialRequestJwtProofTypeHeader,
1360
+ payloadSchema: zCredentialRequestJwtProofTypePayload
1361
+ });
1362
+ const now = options.now?.getTime() ?? Date.now();
1363
+ if (options.nonceExpiresAt && now > options.nonceExpiresAt.getTime()) {
1364
+ throw new Openid4vciError("Nonce used for credential request proof expired");
1365
+ }
1366
+ const { signer } = await (0, import_oauth214.verifyJwt)({
1367
+ compact: options.jwt,
1368
+ header,
1369
+ payload,
1370
+ signer: (0, import_oauth214.jwtSignerFromJwt)({ header, payload }),
1371
+ verifyJwtCallback: options.callbacks.verifyJwt,
1372
+ errorMessage: "Error verifiying credential request proof jwt",
1373
+ expectedNonce: options.expectedNonce,
1374
+ expectedAudience: options.credentialIssuer,
1375
+ expectedIssuer: options.clientId,
1376
+ now: options.now
1377
+ });
1378
+ let keyAttestationResult = void 0;
1379
+ if (header.key_attestation) {
1380
+ keyAttestationResult = await verifyKeyAttestationJwt({
1381
+ callbacks: options.callbacks,
1382
+ keyAttestationJwt: header.key_attestation,
1383
+ use: "proof_type.jwt"
1384
+ });
1385
+ const isSigedWithAttestedKey = await (0, import_oauth213.isJwkInSet)({
1386
+ jwk: signer.publicJwk,
1387
+ jwks: keyAttestationResult.payload.attested_keys,
1388
+ callbacks: options.callbacks
1389
+ });
1390
+ if (!isSigedWithAttestedKey) {
1391
+ throw new Openid4vciError(
1392
+ `Credential request jwt proof is not signed with a key in the 'key_attestation' jwt payload 'attested_keys'`
1393
+ );
1394
+ }
1395
+ }
1396
+ return {
1397
+ header,
1398
+ payload,
1399
+ signer,
1400
+ keyAttestation: keyAttestationResult
1401
+ };
1402
+ }
1403
+
1404
+ // src/metadata/fetch-issuer-metadata.ts
1405
+ var import_oauth215 = require("@openid4vc/oauth2");
1406
+ var import_utils12 = require("@openid4vc/utils");
1407
+ async function resolveIssuerMetadata(credentialIssuer, options) {
1408
+ const allowAuthorizationMetadataFromCredentialIssuerMetadata = options?.allowAuthorizationMetadataFromCredentialIssuerMetadata ?? true;
1409
+ const credentialIssuerMetadataWithDraftVersion = await fetchCredentialIssuerMetadata(credentialIssuer, options?.fetch);
1410
+ if (!credentialIssuerMetadataWithDraftVersion) {
1411
+ throw new import_oauth215.Oauth2Error(`Well known credential issuer metadata for issuer '${credentialIssuer}' not found.`);
1412
+ }
1413
+ const { credentialIssuerMetadata, originalDraftVersion } = credentialIssuerMetadataWithDraftVersion;
1414
+ const authorizationServers = credentialIssuerMetadata.authorization_servers ?? [credentialIssuer];
1415
+ const authoriationServersMetadata = [];
1416
+ for (const authorizationServer of authorizationServers) {
1417
+ if (options?.restrictToAuthorizationServers && !options.restrictToAuthorizationServers.includes(authorizationServer)) {
1418
+ continue;
1419
+ }
1420
+ let authorizationServerMetadata = await (0, import_oauth215.fetchAuthorizationServerMetadata)(authorizationServer, options?.fetch);
1421
+ if (!authorizationServerMetadata && authorizationServer === credentialIssuer && allowAuthorizationMetadataFromCredentialIssuerMetadata) {
1422
+ authorizationServerMetadata = (0, import_utils12.parseWithErrorHandling)(
1423
+ import_oauth215.zAuthorizationServerMetadata,
1424
+ {
1425
+ token_endpoint: credentialIssuerMetadata.token_endpoint,
1426
+ issuer: credentialIssuer
1427
+ },
1428
+ `Well known authorization server metadata for authorization server '${authorizationServer}' not found, and could also not extract required values from the credential issuer metadata as a fallback.`
1429
+ );
1430
+ }
1431
+ if (!authorizationServerMetadata) {
1432
+ throw new import_oauth215.Oauth2Error(
1433
+ `Well known openid configuration or authorization server metadata for authorization server '${authorizationServer}' not found.`
1434
+ );
1435
+ }
1436
+ authoriationServersMetadata.push(authorizationServerMetadata);
1437
+ }
1438
+ return {
1439
+ originalDraftVersion,
1440
+ credentialIssuer: credentialIssuerMetadata,
1441
+ authorizationServers: authoriationServersMetadata
1442
+ };
1443
+ }
1444
+
1445
+ // src/nonce/nonce-request.ts
1446
+ var import_oauth216 = require("@openid4vc/oauth2");
1447
+ var import_utils14 = require("@openid4vc/utils");
1448
+
1449
+ // src/nonce/z-nonce.ts
1450
+ var import_utils13 = require("@openid4vc/utils");
1451
+ var import_zod18 = __toESM(require("zod"));
1452
+ var zNonceResponse = import_zod18.default.object({
1453
+ c_nonce: import_zod18.default.string(),
1454
+ c_nonce_expires_in: import_zod18.default.optional(import_utils13.zInteger)
1455
+ }).passthrough();
1456
+
1457
+ // src/nonce/nonce-request.ts
1458
+ async function requestNonce(options) {
1459
+ const fetchWithZod = (0, import_utils14.createZodFetcher)(options?.fetch);
1460
+ const nonceEndpoint = options.issuerMetadata.credentialIssuer.nonce_endpoint;
1461
+ if (!nonceEndpoint) {
1462
+ throw new Openid4vciError(
1463
+ `Credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}' does not have a nonce endpoint.`
1464
+ );
1465
+ }
1466
+ const { response, result } = await fetchWithZod(zNonceResponse, import_utils14.ContentType.Json, nonceEndpoint, {
1467
+ method: "POST"
1468
+ });
1469
+ if (!response.ok || !result) {
1470
+ throw new import_oauth216.InvalidFetchResponseError(
1471
+ `Requesting nonce from '${nonceEndpoint}' resulted in an unsuccesfull response with status '${response.status}'`,
1472
+ await response.clone().text(),
1473
+ response
1474
+ );
1475
+ }
1476
+ if (!result.success) {
1477
+ throw new import_utils14.ValidationError("Error parsing nonce response", result.error);
1478
+ }
1479
+ return result.data;
1480
+ }
1481
+ function createNonceResponse(options) {
1482
+ return (0, import_utils14.parseWithErrorHandling)(zNonceResponse, {
1483
+ c_nonce: options.cNonce,
1484
+ c_nonce_expires_in: options.cNonceExpiresIn,
1485
+ ...options.additionalPayload
1486
+ });
1487
+ }
1488
+
1489
+ // src/notification/notification.ts
1490
+ var import_oauth217 = require("@openid4vc/oauth2");
1491
+ var import_utils15 = require("@openid4vc/utils");
1492
+
1493
+ // src/notification/z-notification.ts
1494
+ var import_zod19 = __toESM(require("zod"));
1495
+ var zNotificationEvent = import_zod19.default.enum(["credential_accepted", "credential_failure", "credential_deleted"]);
1496
+ var zNotificationRequest = import_zod19.default.object({
1497
+ notification_id: import_zod19.default.string(),
1498
+ event: zNotificationEvent,
1499
+ event_description: import_zod19.default.optional(import_zod19.default.string())
1500
+ }).passthrough();
1501
+ var zNotificationErrorResponse = import_zod19.default.object({
1502
+ error: import_zod19.default.enum(["invalid_notification_id", "invalid_notification_request"])
1503
+ }).passthrough();
1504
+
1505
+ // src/notification/notification.ts
1506
+ async function sendNotifcation(options) {
1507
+ const notificationEndpoint = options.issuerMetadata.credentialIssuer.notification_endpoint;
1508
+ if (!notificationEndpoint) {
1509
+ throw new import_oauth217.Oauth2Error(
1510
+ `Credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}' does not have a notification endpiont configured.`
1511
+ );
1512
+ }
1513
+ const notificationRequest = (0, import_utils15.parseWithErrorHandling)(
1514
+ zNotificationRequest,
1515
+ {
1516
+ event: options.notification.event,
1517
+ notification_id: options.notification.notificationId,
1518
+ event_description: options.notification.eventDescription
1519
+ },
1520
+ "Error validating notification request"
1521
+ );
1522
+ const resourceResponse = await (0, import_oauth217.resourceRequest)({
1523
+ dpop: options.dpop,
1524
+ accessToken: options.accessToken,
1525
+ callbacks: options.callbacks,
1526
+ url: notificationEndpoint,
1527
+ requestOptions: {
1528
+ method: "POST",
1529
+ headers: {
1530
+ "Content-Type": import_utils15.ContentType.Json
1531
+ },
1532
+ body: JSON.stringify(notificationRequest)
1533
+ }
1534
+ });
1535
+ if (!resourceResponse.ok) {
1536
+ const notificationErrorResponseResult = (0, import_utils15.isResponseContentType)(import_utils15.ContentType.Json, resourceResponse.response) ? zNotificationErrorResponse.safeParse(await resourceResponse.response.clone().json()) : void 0;
1537
+ return {
1538
+ ...resourceResponse,
1539
+ notificationErrorResponseResult
1540
+ };
1541
+ }
1542
+ return resourceResponse;
1543
+ }
1544
+
1545
+ // src/Openid4vciClient.ts
1546
+ var AuthorizationFlow = /* @__PURE__ */ ((AuthorizationFlow2) => {
1547
+ AuthorizationFlow2["Oauth2Redirect"] = "Oauth2Redirect";
1548
+ AuthorizationFlow2["PresentationDuringIssuance"] = "PresentationDuringIssuance";
1549
+ return AuthorizationFlow2;
1550
+ })(AuthorizationFlow || {});
1551
+ var Openid4vciClient = class {
1552
+ constructor(options) {
1553
+ this.options = options;
1554
+ this.oauth2Client = new import_oauth218.Oauth2Client({
1555
+ callbacks: this.options.callbacks
1556
+ });
1557
+ }
1558
+ getKnownCredentialConfigurationsSupported(credentialIssuerMetadata) {
1559
+ return extractKnownCredentialConfigurationSupportedFormats(
1560
+ credentialIssuerMetadata.credential_configurations_supported
1561
+ );
1562
+ }
1563
+ /**
1564
+ * Resolve a credential offer into a credential offer object, handling both
1565
+ * 'credential_offer' and 'credential_offer_uri' params.
1566
+ */
1567
+ async resolveCredentialOffer(credentialOffer) {
1568
+ return resolveCredentialOffer(credentialOffer, {
1569
+ fetch: this.options.callbacks.fetch
1570
+ });
1571
+ }
1572
+ async resolveIssuerMetadata(credentialIssuer) {
1573
+ return resolveIssuerMetadata(credentialIssuer, {
1574
+ fetch: this.options.callbacks.fetch
1575
+ });
1576
+ }
1577
+ /**
1578
+ * Retrieve an authorization code for a presentation during issuance session
1579
+ *
1580
+ * This can only be called if an authorization challenge was performed before and returned a
1581
+ * `presentation` paramater along with an `auth_session`. If the presentation response included
1582
+ * an `presentation_during_issuance_session` parameter it MUST be included in this request as well.
1583
+ */
1584
+ async retrieveAuthorizationCodeUsingPresentation(options) {
1585
+ if (!options.credentialOffer.grants?.[import_oauth218.authorizationCodeGrantIdentifier]) {
1586
+ throw new import_oauth218.Oauth2Error(`Provided credential offer does not include the 'authorization_code' grant.`);
1587
+ }
1588
+ const authorizationCodeGrant = options.credentialOffer.grants[import_oauth218.authorizationCodeGrantIdentifier];
1589
+ const authorizationServer = determineAuthorizationServerForCredentialOffer({
1590
+ issuerMetadata: options.issuerMetadata,
1591
+ grantAuthorizationServer: authorizationCodeGrant.authorization_server
1592
+ });
1593
+ const authorizationServerMetadata = (0, import_oauth218.getAuthorizationServerMetadataFromList)(
1594
+ options.issuerMetadata.authorizationServers,
1595
+ authorizationServer
1596
+ );
1597
+ const oauth2Client = new import_oauth218.Oauth2Client({ callbacks: this.options.callbacks });
1598
+ const { authorizationChallengeResponse, dpop } = await oauth2Client.sendAuthorizationChallengeRequest({
1599
+ authorizationServerMetadata,
1600
+ authSession: options.authSession,
1601
+ presentationDuringIssuanceSession: options.presentationDuringIssuanceSession,
1602
+ dpop: options.dpop
1603
+ });
1604
+ return { authorizationChallengeResponse, dpop };
1605
+ }
1606
+ /**
1607
+ * Initiates authorization for credential issuance. It handles the following cases:
1608
+ * - Authorization Challenge
1609
+ * - Pushed Authorization Request
1610
+ * - Regular Authorization url
1611
+ *
1612
+ * In case the authorization challenge request returns an error with `insufficient_authorization`
1613
+ * with a `presentation` field it means the authorization server expects presentation of credentials
1614
+ * before issuance of crednetials. If this is the case, the value in `presentation` should be treated
1615
+ * as an openid4vp authorization request and submitted to the verifier. Once the presentation response
1616
+ * has been submitted, the RP will respnosd with a `presentation_during_issuance_session` parameter.
1617
+ * Together with the `auth_session` parameter returned in this call you can retrieve an `authorization_code`
1618
+ * using
1619
+ */
1620
+ async initiateAuthorization(options) {
1621
+ if (!options.credentialOffer.grants?.[import_oauth218.authorizationCodeGrantIdentifier]) {
1622
+ throw new import_oauth218.Oauth2Error(`Provided credential offer does not include the 'authorization_code' grant.`);
1623
+ }
1624
+ const authorizationCodeGrant = options.credentialOffer.grants[import_oauth218.authorizationCodeGrantIdentifier];
1625
+ const authorizationServer = determineAuthorizationServerForCredentialOffer({
1626
+ issuerMetadata: options.issuerMetadata,
1627
+ grantAuthorizationServer: authorizationCodeGrant.authorization_server
1628
+ });
1629
+ const authorizationServerMetadata = (0, import_oauth218.getAuthorizationServerMetadataFromList)(
1630
+ options.issuerMetadata.authorizationServers,
1631
+ authorizationServer
1632
+ );
1633
+ const oauth2Client = new import_oauth218.Oauth2Client({ callbacks: this.options.callbacks });
1634
+ try {
1635
+ const result = await oauth2Client.initiateAuthorization({
1636
+ clientId: options.clientId,
1637
+ pkceCodeVerifier: options.pkceCodeVerifier,
1638
+ redirectUri: options.redirectUri,
1639
+ scope: options.scope,
1640
+ additionalRequestPayload: {
1641
+ ...options.additionalRequestPayload,
1642
+ issuer_state: options.credentialOffer?.grants?.authorization_code?.issuer_state
1643
+ },
1644
+ dpop: options.dpop,
1645
+ clientAttestation: options.clientAttestation,
1646
+ resource: options.issuerMetadata.credentialIssuer.credential_issuer,
1647
+ authorizationServerMetadata
1648
+ });
1649
+ return {
1650
+ ...result,
1651
+ authorizationFlow: "Oauth2Redirect" /* Oauth2Redirect */,
1652
+ authorizationServer: authorizationServerMetadata.issuer
1653
+ };
1654
+ } catch (error) {
1655
+ if (error instanceof import_oauth218.Oauth2ClientAuthorizationChallengeError && error.errorResponse.error === import_oauth218.Oauth2ErrorCodes.InsufficientAuthorization && error.errorResponse.presentation) {
1656
+ if (!error.errorResponse.auth_session) {
1657
+ throw new Openid4vciError(
1658
+ `Expected 'auth_session' to be defined with authorization challenge response error '${error.errorResponse.error}' and 'presentation' parameter`
1659
+ );
1660
+ }
1661
+ return {
1662
+ authorizationFlow: "PresentationDuringIssuance" /* PresentationDuringIssuance */,
1663
+ openid4vpRequestUrl: error.errorResponse.presentation,
1664
+ authSession: error.errorResponse.auth_session,
1665
+ authorizationServer: authorizationServerMetadata.issuer
1666
+ };
1667
+ }
1668
+ throw error;
1669
+ }
1670
+ }
1671
+ /**
1672
+ * Convenience method around {@link Oauth2Client.createAuthorizationRequestUrl}
1673
+ * but specifically focused on a credential offer
1674
+ */
1675
+ async createAuthorizationRequestUrlFromOffer(options) {
1676
+ if (!options.credentialOffer.grants?.[import_oauth218.authorizationCodeGrantIdentifier]) {
1677
+ throw new import_oauth218.Oauth2Error(`Provided credential offer does not include the 'authorization_code' grant.`);
1678
+ }
1679
+ const authorizationCodeGrant = options.credentialOffer.grants[import_oauth218.authorizationCodeGrantIdentifier];
1680
+ const authorizationServer = determineAuthorizationServerForCredentialOffer({
1681
+ issuerMetadata: options.issuerMetadata,
1682
+ grantAuthorizationServer: authorizationCodeGrant.authorization_server
1683
+ });
1684
+ const authorizationServerMetadata = (0, import_oauth218.getAuthorizationServerMetadataFromList)(
1685
+ options.issuerMetadata.authorizationServers,
1686
+ authorizationServer
1687
+ );
1688
+ const { authorizationRequestUrl, pkce, dpop } = await this.oauth2Client.createAuthorizationRequestUrl({
1689
+ authorizationServerMetadata,
1690
+ clientId: options.clientId,
1691
+ additionalRequestPayload: {
1692
+ ...options.additionalRequestPayload,
1693
+ issuer_state: options.credentialOffer?.grants?.authorization_code?.issuer_state
1694
+ },
1695
+ resource: options.issuerMetadata.credentialIssuer.credential_issuer,
1696
+ redirectUri: options.redirectUri,
1697
+ scope: options.scope,
1698
+ pkceCodeVerifier: options.pkceCodeVerifier,
1699
+ clientAttestation: options.clientAttestation,
1700
+ dpop: options.dpop
1701
+ });
1702
+ return {
1703
+ authorizationRequestUrl,
1704
+ pkce,
1705
+ dpop,
1706
+ authorizationServer: authorizationServerMetadata.issuer
1707
+ };
1708
+ }
1709
+ /**
1710
+ * Convenience method around {@link Oauth2Client.retrievePreAuthorizedCodeAccessToken}
1711
+ * but specifically focused on a credential offer
1712
+ */
1713
+ async retrievePreAuthorizedCodeAccessTokenFromOffer({
1714
+ credentialOffer,
1715
+ issuerMetadata,
1716
+ additionalRequestPayload,
1717
+ txCode,
1718
+ dpop,
1719
+ clientAttestation
1720
+ }) {
1721
+ if (!credentialOffer.grants?.[import_oauth218.preAuthorizedCodeGrantIdentifier]) {
1722
+ throw new import_oauth218.Oauth2Error(`The credential offer does not contain the '${import_oauth218.preAuthorizedCodeGrantIdentifier}' grant.`);
1723
+ }
1724
+ if (credentialOffer.grants[import_oauth218.preAuthorizedCodeGrantIdentifier].tx_code && !txCode) {
1725
+ throw new import_oauth218.Oauth2Error(
1726
+ `Retrieving access token requires a 'tx_code' in the request, but the 'txCode' parameter was not provided.`
1727
+ );
1728
+ }
1729
+ const preAuthorizedCode = credentialOffer.grants[import_oauth218.preAuthorizedCodeGrantIdentifier]["pre-authorized_code"];
1730
+ const authorizationServer = determineAuthorizationServerForCredentialOffer({
1731
+ grantAuthorizationServer: credentialOffer.grants[import_oauth218.preAuthorizedCodeGrantIdentifier].authorization_server,
1732
+ issuerMetadata
1733
+ });
1734
+ const authorizationServerMetadata = (0, import_oauth218.getAuthorizationServerMetadataFromList)(
1735
+ issuerMetadata.authorizationServers,
1736
+ authorizationServer
1737
+ );
1738
+ const result = await this.oauth2Client.retrievePreAuthorizedCodeAccessToken({
1739
+ authorizationServerMetadata,
1740
+ preAuthorizedCode,
1741
+ txCode,
1742
+ resource: issuerMetadata.credentialIssuer.credential_issuer,
1743
+ additionalRequestPayload,
1744
+ dpop,
1745
+ clientAttestation
1746
+ });
1747
+ return {
1748
+ ...result,
1749
+ authorizationServer
1750
+ };
1751
+ }
1752
+ /**
1753
+ * Convenience method around {@link Oauth2Client.retrieveAuthorizationCodeAccessTokenFrom}
1754
+ * but specifically focused on a credential offer
1755
+ */
1756
+ async retrieveAuthorizationCodeAccessTokenFromOffer({
1757
+ issuerMetadata,
1758
+ additionalRequestPayload,
1759
+ credentialOffer,
1760
+ authorizationCode,
1761
+ pkceCodeVerifier,
1762
+ redirectUri,
1763
+ dpop,
1764
+ clientAttestation
1765
+ }) {
1766
+ if (!credentialOffer.grants?.[import_oauth218.authorizationCodeGrantIdentifier]) {
1767
+ throw new import_oauth218.Oauth2Error(`The credential offer does not contain the '${import_oauth218.authorizationCodeGrantIdentifier}' grant.`);
1768
+ }
1769
+ const authorizationServer = determineAuthorizationServerForCredentialOffer({
1770
+ grantAuthorizationServer: credentialOffer.grants[import_oauth218.authorizationCodeGrantIdentifier].authorization_server,
1771
+ issuerMetadata
1772
+ });
1773
+ const authorizationServerMetadata = (0, import_oauth218.getAuthorizationServerMetadataFromList)(
1774
+ issuerMetadata.authorizationServers,
1775
+ authorizationServer
1776
+ );
1777
+ const result = await this.oauth2Client.retrieveAuthorizationCodeAccessToken({
1778
+ authorizationServerMetadata,
1779
+ authorizationCode,
1780
+ pkceCodeVerifier,
1781
+ additionalRequestPayload,
1782
+ dpop,
1783
+ clientAttestation,
1784
+ redirectUri,
1785
+ resource: issuerMetadata.credentialIssuer.credential_issuer
1786
+ });
1787
+ return {
1788
+ ...result,
1789
+ authorizationServer
1790
+ };
1791
+ }
1792
+ /**
1793
+ * Request a nonce to be used in credential request proofs from the `nonce_endpoint`
1794
+ *
1795
+ * @throws Openid4vciError - if no `nonce_endpoint` is configured in the issuer metadata
1796
+ * @thrwos InvalidFetchResponseError - if the nonce endpoint did not return a succesfull response
1797
+ * @throws ValidationError - if validating the nonce response failed
1798
+ */
1799
+ async requestNonce(options) {
1800
+ return requestNonce(options);
1801
+ }
1802
+ /**
1803
+ * Creates the jwt proof payload and header to be included in a credential request.
1804
+ */
1805
+ async createCredentialRequestJwtProof(options) {
1806
+ const credentialConfiguration = options.issuerMetadata.credentialIssuer.credential_configurations_supported[options.credentialConfigurationId];
1807
+ if (!credentialConfiguration) {
1808
+ throw new Openid4vciError(
1809
+ `Credential configuration with '${options.credentialConfigurationId}' not found in 'credential_configurations_supported' from credential issuer '${options.issuerMetadata.credentialIssuer.credential_issuer}'`
1810
+ );
1811
+ }
1812
+ if (credentialConfiguration.proof_types_supported) {
1813
+ if (!credentialConfiguration.proof_types_supported.jwt) {
1814
+ throw new Openid4vciError(
1815
+ `Credential configuration with id '${options.credentialConfigurationId}' does not support the 'jwt' proof type.`
1816
+ );
1817
+ }
1818
+ if (!credentialConfiguration.proof_types_supported.jwt.proof_signing_alg_values_supported.includes(
1819
+ options.signer.alg
1820
+ )) {
1821
+ throw new Openid4vciError(
1822
+ `Credential configuration with id '${options.credentialConfigurationId}' does not support the '${options.signer.alg}' alg for 'jwt' proof type.`
1823
+ );
1824
+ }
1825
+ if (credentialConfiguration.proof_types_supported.jwt.key_attestations_required && !options.keyAttestationJwt) {
1826
+ throw new Openid4vciError(
1827
+ `Credential configuration with id '${options.credentialConfigurationId}' requires key attestations for 'jwt' proof type but no 'keyAttestationJwt' was provided`
1828
+ );
1829
+ }
1830
+ }
1831
+ const jwt = await createCredentialRequestJwtProof({
1832
+ credentialIssuer: options.issuerMetadata.credentialIssuer.credential_issuer,
1833
+ signer: options.signer,
1834
+ clientId: options.clientId,
1835
+ issuedAt: options.issuedAt,
1836
+ nonce: options.nonce,
1837
+ keyAttestationJwt: options.keyAttestationJwt,
1838
+ callbacks: this.options.callbacks
1839
+ });
1840
+ return {
1841
+ jwt
1842
+ };
1843
+ }
1844
+ /**
1845
+ * @throws Openid4vciRetrieveCredentialsError - if an unsuccesfull response or the respnose couldn't be parsed as credential response
1846
+ * @throws ValidationError - if validation of the credential request failed
1847
+ * @throws Openid4vciError - if the `credentialConfigurationId` couldn't be found, or if the the format specific request couldn't be constructed
1848
+ */
1849
+ async retrieveCredentials({
1850
+ issuerMetadata,
1851
+ proof,
1852
+ proofs,
1853
+ credentialConfigurationId,
1854
+ additionalRequestPayload,
1855
+ accessToken,
1856
+ dpop
1857
+ }) {
1858
+ const formatPayload = getCredentialRequestFormatPayloadForCredentialConfigurationId({
1859
+ credentialConfigurationId,
1860
+ issuerMetadata
1861
+ });
1862
+ const credentialResponse = await retrieveCredentialsWithFormat({
1863
+ accessToken,
1864
+ formatPayload,
1865
+ issuerMetadata,
1866
+ additionalRequestPayload,
1867
+ proof,
1868
+ proofs,
1869
+ callbacks: this.options.callbacks,
1870
+ dpop
1871
+ });
1872
+ if (!credentialResponse.ok) {
1873
+ throw new Openid4vciRetrieveCredentialsError(
1874
+ `Error retrieving credentials from '${issuerMetadata.credentialIssuer.credential_issuer}'`,
1875
+ credentialResponse,
1876
+ await credentialResponse.response.clone().text()
1877
+ );
1878
+ }
1879
+ return credentialResponse;
1880
+ }
1881
+ /**
1882
+ * @throws Openid4vciSendNotificationError - if an unsuccesfull response
1883
+ * @throws ValidationError - if validation of the notification request failed
1884
+ */
1885
+ async sendNotification({
1886
+ issuerMetadata,
1887
+ notification,
1888
+ additionalRequestPayload,
1889
+ accessToken,
1890
+ dpop
1891
+ }) {
1892
+ const notificationResponse = await sendNotifcation({
1893
+ accessToken,
1894
+ issuerMetadata,
1895
+ additionalRequestPayload,
1896
+ callbacks: this.options.callbacks,
1897
+ dpop,
1898
+ notification
1899
+ });
1900
+ if (!notificationResponse.ok) {
1901
+ throw new Openid4vciSendNotificationError(
1902
+ `Error sending notification to '${issuerMetadata.credentialIssuer.credential_issuer}'`,
1903
+ notificationResponse
1904
+ );
1905
+ }
1906
+ return notificationResponse;
1907
+ }
1908
+ };
1909
+
1910
+ // src/Openid4vciIssuer.ts
1911
+ var import_oauth219 = require("@openid4vc/oauth2");
1912
+ var import_utils18 = require("@openid4vc/utils");
1913
+
1914
+ // src/credential-request/credential-response.ts
1915
+ var import_utils16 = require("@openid4vc/utils");
1916
+ function createCredentialResponse(options) {
1917
+ const credentialResponse = (0, import_utils16.parseWithErrorHandling)(zCredentialResponse, {
1918
+ c_nonce: options.cNonce,
1919
+ c_nonce_expires_in: options.cNonceExpiresInSeconds,
1920
+ credential: options.credential,
1921
+ credentials: options.credentials,
1922
+ notification_id: options.notificationId,
1923
+ // NOTE `format` is removed in draft 13. For now if a format was requested
1924
+ // we just always return it in the response as well.
1925
+ format: options.credentialRequest.format?.format,
1926
+ ...options.additionalPayload
1927
+ });
1928
+ return credentialResponse;
1929
+ }
1930
+
1931
+ // src/credential-request/parse-credential-request.ts
1932
+ var import_utils17 = require("@openid4vc/utils");
1933
+ var import_zod20 = __toESM(require("zod"));
1934
+ function parseCredentialRequest(options) {
1935
+ const credentialRequest = (0, import_utils17.parseWithErrorHandling)(
1936
+ zCredentialRequest,
1937
+ options.credentialRequest,
1938
+ "Error validating credential request"
1939
+ );
1940
+ let proofs = void 0;
1941
+ const knownProofs = zCredentialRequestProofs.strict().safeParse(credentialRequest.proofs);
1942
+ if (knownProofs.success) {
1943
+ proofs = knownProofs.data;
1944
+ }
1945
+ const knownProof = import_zod20.default.union(allCredentialRequestProofs).safeParse(credentialRequest.proof);
1946
+ if (knownProof.success && knownProof.data.proof_type === jwtProofTypeIdentifier) {
1947
+ proofs = { [jwtProofTypeIdentifier]: [knownProof.data.jwt] };
1948
+ } else if (knownProof.success && knownProof.data.proof_type === attestationProofTypeIdentifier) {
1949
+ proofs = { [attestationProofTypeIdentifier]: [knownProof.data.attestation] };
1950
+ }
1951
+ if (credentialRequest.credential_identifier) {
1952
+ return {
1953
+ credentialIdentifier: credentialRequest.credential_identifier,
1954
+ credentialRequest,
1955
+ proofs
1956
+ };
1957
+ }
1958
+ if (credentialRequest.format && allCredentialRequestFormatIdentifiers.includes(credentialRequest.format)) {
1959
+ return {
1960
+ // Removes all claims that are not specific to this format
1961
+ format: (0, import_utils17.parseWithErrorHandling)(
1962
+ import_zod20.default.union(allCredentialRequestFormats),
1963
+ credentialRequest,
1964
+ "Unable to validate format specific properties from credential request"
1965
+ ),
1966
+ credentialRequest,
1967
+ proofs
1968
+ };
1969
+ }
1970
+ return {
1971
+ credentialRequest,
1972
+ proofs
1973
+ };
1974
+ }
1975
+
1976
+ // src/formats/proof-type/attestation/attestation-proof-type.ts
1977
+ async function verifyCredentialRequestAttestationProof(options) {
1978
+ const verificationResult = await verifyKeyAttestationJwt({
1979
+ ...options,
1980
+ use: "proof_type.attestation"
1981
+ });
1982
+ return verificationResult;
1983
+ }
1984
+
1985
+ // src/Openid4vciIssuer.ts
1986
+ var Openid4vciIssuer = class {
1987
+ constructor(options) {
1988
+ this.options = options;
1989
+ }
1990
+ getCredentialIssuerMetadataDraft11(credentialIssuerMetadata) {
1991
+ return (0, import_utils18.parseWithErrorHandling)(zCredentialIssuerMetadataWithDraft11, credentialIssuerMetadata);
1992
+ }
1993
+ getKnownCredentialConfigurationsSupported(credentialIssuerMetadata) {
1994
+ return extractKnownCredentialConfigurationSupportedFormats(
1995
+ credentialIssuerMetadata.credential_configurations_supported
1996
+ );
1997
+ }
1998
+ /**
1999
+ * Create issuer metadata and validates the structure is correct
2000
+ */
2001
+ createCredentialIssuerMetadata(credentialIssuerMetadata) {
2002
+ return (0, import_utils18.parseWithErrorHandling)(
2003
+ zCredentialIssuerMetadata,
2004
+ credentialIssuerMetadata,
2005
+ "Error validating credential issuer metadata"
2006
+ );
2007
+ }
2008
+ async createCredentialOffer(options) {
2009
+ return createCredentialOffer({
2010
+ callbacks: this.options.callbacks,
2011
+ credentialConfigurationIds: options.credentialConfigurationIds,
2012
+ grants: options.grants,
2013
+ issuerMetadata: options.issuerMetadata,
2014
+ additionalPayload: options.additionalPayload,
2015
+ credentialOfferScheme: options.credentialOfferScheme,
2016
+ credentialOfferUri: options.credentialOfferUri
2017
+ });
2018
+ }
2019
+ /**
2020
+ * @throws Oauth2ServerErrorResponseError - if verification of the jwt failed. You can extract
2021
+ * the credential error response from this.
2022
+ */
2023
+ async verifyCredentialRequestJwtProof(options) {
2024
+ try {
2025
+ return await verifyCredentialRequestJwtProof({
2026
+ callbacks: this.options.callbacks,
2027
+ credentialIssuer: options.issuerMetadata.credentialIssuer.credential_issuer,
2028
+ expectedNonce: options.expectedNonce,
2029
+ nonceExpiresAt: options.nonceExpiresAt,
2030
+ jwt: options.jwt,
2031
+ clientId: options.clientId,
2032
+ now: options.now
2033
+ });
2034
+ } catch (error) {
2035
+ throw new import_oauth219.Oauth2ServerErrorResponseError(
2036
+ {
2037
+ error: import_oauth219.Oauth2ErrorCodes.InvalidProof,
2038
+ error_description: (
2039
+ // TOOD: error should have a internalErrorMessage and a publicErrorMessage
2040
+ error instanceof import_oauth219.Oauth2JwtVerificationError || error instanceof Openid4vciError ? error.message : "Invalid proof"
2041
+ )
2042
+ },
2043
+ {
2044
+ internalMessage: "Error verifying credential request proof jwt",
2045
+ cause: error
2046
+ }
2047
+ );
2048
+ }
2049
+ }
2050
+ /**
2051
+ * @throws Oauth2ServerErrorResponseError - if verification of the key attestation failed. You can extract
2052
+ * the credential error response from this.
2053
+ */
2054
+ async verifyCredentialRequestAttestationProof(options) {
2055
+ try {
2056
+ return await verifyCredentialRequestAttestationProof({
2057
+ callbacks: this.options.callbacks,
2058
+ expectedNonce: options.expectedNonce,
2059
+ keyAttestationJwt: options.keyAttestationJwt,
2060
+ nonceExpiresAt: options.nonceExpiresAt,
2061
+ now: options.now
2062
+ });
2063
+ } catch (error) {
2064
+ throw new import_oauth219.Oauth2ServerErrorResponseError(
2065
+ {
2066
+ error: import_oauth219.Oauth2ErrorCodes.InvalidProof,
2067
+ error_description: (
2068
+ // TOOD: error should have a internalErrorMessage and a publicErrorMessage
2069
+ error instanceof import_oauth219.Oauth2JwtVerificationError || error instanceof Openid4vciError ? error.message : "Invalid proof"
2070
+ )
2071
+ },
2072
+ {
2073
+ internalMessage: "Error verifying credential request proof attestation",
2074
+ cause: error
2075
+ }
2076
+ );
2077
+ }
2078
+ }
2079
+ /**
2080
+ * @throws Oauth2ServerErrorResponseError - when validation of the credential request fails
2081
+ * You can extract the credential error response from this.
2082
+ */
2083
+ parseCredentialRequest(options) {
2084
+ try {
2085
+ return parseCredentialRequest(options);
2086
+ } catch (error) {
2087
+ throw new import_oauth219.Oauth2ServerErrorResponseError(
2088
+ {
2089
+ error: import_oauth219.Oauth2ErrorCodes.InvalidCredentialRequest,
2090
+ error_description: (
2091
+ // TODO: error should have a internalErrorMessage and a publicErrorMessage
2092
+ error instanceof import_utils18.ValidationError ? error.message : "Invalid request"
2093
+ )
2094
+ },
2095
+ {
2096
+ internalMessage: "Error verifying credential request proof jwt",
2097
+ cause: error
2098
+ }
2099
+ );
2100
+ }
2101
+ }
2102
+ /**
2103
+ * @throws ValidationError - when validation of the credential response fails
2104
+ */
2105
+ createCredentialResponse(options) {
2106
+ return createCredentialResponse(options);
2107
+ }
2108
+ /**
2109
+ * @throws ValidationError - when validation of the nonce response fails
2110
+ */
2111
+ createNonceResponse(options) {
2112
+ return createNonceResponse(options);
2113
+ }
2114
+ };
2115
+ // Annotate the CommonJS export names for ESM import in node:
2116
+ 0 && (module.exports = {
2117
+ AuthorizationFlow,
2118
+ Openid4vciClient,
2119
+ Openid4vciDraftVersion,
2120
+ Openid4vciError,
2121
+ Openid4vciIssuer,
2122
+ Openid4vciRetrieveCredentialsError,
2123
+ Openid4vciSendNotificationError,
2124
+ credentialsSupportedToCredentialConfigurationsSupported,
2125
+ extractScopesForCredentialConfigurationIds,
2126
+ getCredentialConfigurationsMatchingRequestFormat,
2127
+ getGlobalConfig,
2128
+ setGlobalConfig
2129
+ });
2130
+ //# sourceMappingURL=index.js.map