@sphereon/oid4vci-client 0.10.4-unstable.98 → 0.12.0

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.
Files changed (87) hide show
  1. package/README.md +7 -7
  2. package/dist/AccessTokenClient.d.ts.map +1 -1
  3. package/dist/AccessTokenClient.js +5 -6
  4. package/dist/AccessTokenClient.js.map +1 -1
  5. package/dist/AccessTokenClientV1_0_11.d.ts.map +1 -1
  6. package/dist/AccessTokenClientV1_0_11.js +3 -5
  7. package/dist/AccessTokenClientV1_0_11.js.map +1 -1
  8. package/dist/AuthorizationCodeClient.d.ts +4 -1
  9. package/dist/AuthorizationCodeClient.d.ts.map +1 -1
  10. package/dist/AuthorizationCodeClient.js +47 -8
  11. package/dist/AuthorizationCodeClient.js.map +1 -1
  12. package/dist/AuthorizationCodeClientV1_0_11.d.ts.map +1 -1
  13. package/dist/AuthorizationCodeClientV1_0_11.js +5 -3
  14. package/dist/AuthorizationCodeClientV1_0_11.js.map +1 -1
  15. package/dist/CredentialOfferClient.d.ts.map +1 -1
  16. package/dist/CredentialOfferClient.js +26 -12
  17. package/dist/CredentialOfferClient.js.map +1 -1
  18. package/dist/CredentialOfferClientV1_0_11.js +6 -7
  19. package/dist/CredentialOfferClientV1_0_11.js.map +1 -1
  20. package/dist/CredentialOfferClientV1_0_13.d.ts +10 -0
  21. package/dist/CredentialOfferClientV1_0_13.d.ts.map +1 -0
  22. package/dist/CredentialOfferClientV1_0_13.js +94 -0
  23. package/dist/CredentialOfferClientV1_0_13.js.map +1 -0
  24. package/dist/CredentialRequestClient.js +1 -1
  25. package/dist/CredentialRequestClient.js.map +1 -1
  26. package/dist/CredentialRequestClientBuilderV1_0_11.d.ts +3 -1
  27. package/dist/CredentialRequestClientBuilderV1_0_11.d.ts.map +1 -1
  28. package/dist/CredentialRequestClientBuilderV1_0_11.js +4 -0
  29. package/dist/CredentialRequestClientBuilderV1_0_11.js.map +1 -1
  30. package/dist/CredentialRequestClientV1_0_11.d.ts +9 -3
  31. package/dist/CredentialRequestClientV1_0_11.d.ts.map +1 -1
  32. package/dist/CredentialRequestClientV1_0_11.js +2 -1
  33. package/dist/CredentialRequestClientV1_0_11.js.map +1 -1
  34. package/dist/MetadataClient.d.ts +5 -5
  35. package/dist/MetadataClient.d.ts.map +1 -1
  36. package/dist/MetadataClient.js +30 -13
  37. package/dist/MetadataClient.js.map +1 -1
  38. package/dist/MetadataClientV1_0_13.d.ts +31 -0
  39. package/dist/MetadataClientV1_0_13.d.ts.map +1 -0
  40. package/dist/MetadataClientV1_0_13.js +181 -0
  41. package/dist/MetadataClientV1_0_13.js.map +1 -0
  42. package/dist/OpenID4VCIClient.d.ts +13 -24
  43. package/dist/OpenID4VCIClient.d.ts.map +1 -1
  44. package/dist/OpenID4VCIClient.js +126 -103
  45. package/dist/OpenID4VCIClient.js.map +1 -1
  46. package/dist/OpenID4VCIClientV1_0_11.d.ts +3 -2
  47. package/dist/OpenID4VCIClientV1_0_11.d.ts.map +1 -1
  48. package/dist/OpenID4VCIClientV1_0_11.js +5 -18
  49. package/dist/OpenID4VCIClientV1_0_11.js.map +1 -1
  50. package/dist/OpenID4VCIClientV1_0_13.d.ts +112 -0
  51. package/dist/OpenID4VCIClientV1_0_13.d.ts.map +1 -0
  52. package/dist/OpenID4VCIClientV1_0_13.js +478 -0
  53. package/dist/OpenID4VCIClientV1_0_13.js.map +1 -0
  54. package/dist/ProofOfPossessionBuilder.d.ts +14 -3
  55. package/dist/ProofOfPossessionBuilder.d.ts.map +1 -1
  56. package/dist/ProofOfPossessionBuilder.js +20 -20
  57. package/dist/ProofOfPossessionBuilder.js.map +1 -1
  58. package/dist/index.d.ts +5 -0
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +6 -0
  61. package/dist/index.js.map +1 -1
  62. package/lib/AccessTokenClient.ts +5 -11
  63. package/lib/AccessTokenClientV1_0_11.ts +3 -9
  64. package/lib/AuthorizationCodeClient.ts +47 -8
  65. package/lib/AuthorizationCodeClientV1_0_11.ts +8 -6
  66. package/lib/CredentialOfferClient.ts +31 -9
  67. package/lib/CredentialOfferClientV1_0_11.ts +6 -6
  68. package/lib/CredentialOfferClientV1_0_13.ts +103 -0
  69. package/lib/CredentialRequestClient.ts +1 -1
  70. package/lib/CredentialRequestClientBuilderV1_0_11.ts +7 -0
  71. package/lib/CredentialRequestClientV1_0_11.ts +9 -4
  72. package/lib/MetadataClient.ts +49 -14
  73. package/lib/MetadataClientV1_0_13.ts +188 -0
  74. package/lib/OpenID4VCIClient.ts +131 -115
  75. package/lib/OpenID4VCIClientV1_0_11.ts +9 -19
  76. package/lib/OpenID4VCIClientV1_0_13.ts +677 -0
  77. package/lib/ProofOfPossessionBuilder.ts +40 -9
  78. package/lib/__tests__/CredentialRequestClientV1_0_11.spec.ts +2 -2
  79. package/lib/__tests__/MetadataClient.spec.ts +3 -4
  80. package/lib/__tests__/MetadataMocks.ts +1 -0
  81. package/lib/__tests__/OpenID4VCIClient.spec.ts +42 -9
  82. package/lib/__tests__/OpenID4VCIClientV1_0_11.spec.ts +24 -0
  83. package/lib/__tests__/OpenID4VCIClientV1_0_13.spec.ts +204 -0
  84. package/lib/__tests__/SdJwt.spec.ts +2 -2
  85. package/lib/__tests__/SphereonE2E.spec.test.ts +4 -3
  86. package/lib/index.ts +8 -0
  87. package/package.json +4 -4
@@ -5,17 +5,23 @@ import {
5
5
  AuthorizationResponse,
6
6
  AuthzFlowType,
7
7
  CodeChallengeMethod,
8
+ CredentialConfigurationSupported,
8
9
  CredentialConfigurationSupportedV1_0_13,
9
- CredentialOfferPayloadV1_0_13,
10
+ CredentialOfferPayloadV1_0_08,
11
+ CredentialOfferPayloadV1_0_11,
10
12
  CredentialOfferRequestWithBaseUrl,
11
13
  CredentialResponse,
14
+ CredentialsSupportedLegacy,
12
15
  DefaultURISchemes,
16
+ determineVersionsFromIssuerMetadata,
17
+ EndpointMetadataResultV1_0_11,
13
18
  EndpointMetadataResultV1_0_13,
14
19
  ExperimentalSubjectIssuance,
15
20
  getClientIdFromCredentialOfferPayload,
16
21
  getIssuerFromCredentialOfferPayload,
17
22
  getSupportedCredentials,
18
23
  getTypesFromCredentialSupported,
24
+ getTypesFromObject,
19
25
  JWK,
20
26
  KID_JWK_X5C_ERROR,
21
27
  NotificationRequest,
@@ -30,32 +36,24 @@ import { CredentialFormat } from '@sphereon/ssi-types';
30
36
  import Debug from 'debug';
31
37
 
32
38
  import { AccessTokenClient } from './AccessTokenClient';
39
+ import { AccessTokenClientV1_0_11 } from './AccessTokenClientV1_0_11';
33
40
  import { createAuthorizationRequestUrl } from './AuthorizationCodeClient';
41
+ import { createAuthorizationRequestUrlV1_0_11 } from './AuthorizationCodeClientV1_0_11';
34
42
  import { CredentialOfferClient } from './CredentialOfferClient';
35
43
  import { CredentialRequestOpts } from './CredentialRequestClient';
36
44
  import { CredentialRequestClientBuilder } from './CredentialRequestClientBuilder';
45
+ import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11';
37
46
  import { MetadataClient } from './MetadataClient';
47
+ import { OpenID4VCIClientStateV1_0_11 } from './OpenID4VCIClientV1_0_11';
48
+ import { OpenID4VCIClientStateV1_0_13 } from './OpenID4VCIClientV1_0_13';
38
49
  import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder';
39
- import { generateMissingPKCEOpts } from './functions/AuthorizationUtil';
40
- import { sendNotification } from './functions/notifications';
50
+ import { generateMissingPKCEOpts, sendNotification } from './functions';
41
51
 
42
52
  const debug = Debug('sphereon:oid4vci');
43
53
 
44
- export interface OpenID4VCIClientState {
45
- credentialIssuer: string;
46
- credentialOffer?: CredentialOfferRequestWithBaseUrl;
47
- clientId?: string;
48
- kid?: string;
49
- jwk?: JWK;
50
- alg?: Alg | string;
51
- endpointMetadata?: EndpointMetadataResultV1_0_13;
52
- accessTokenResponse?: AccessTokenResponse;
53
- authorizationRequestOpts?: AuthorizationRequestOpts;
54
- authorizationCodeResponse?: AuthorizationResponse;
55
- pkce: PKCEOpts;
56
- accessToken?: string;
57
- authorizationURL?: string;
58
- }
54
+ export type OpenID4VCIClientState = OpenID4VCIClientStateV1_0_11 | OpenID4VCIClientStateV1_0_13;
55
+
56
+ export type EndpointMetadataResult = EndpointMetadataResultV1_0_11 | EndpointMetadataResultV1_0_13;
59
57
 
60
58
  export class OpenID4VCIClient {
61
59
  private readonly _state: OpenID4VCIClientState;
@@ -85,7 +83,7 @@ export class OpenID4VCIClient {
85
83
  authorizationRequest?: AuthorizationRequestOpts; // Can be provided here, or when manually calling createAuthorizationUrl
86
84
  jwk?: JWK;
87
85
  accessToken?: string;
88
- endpointMetadata?: EndpointMetadataResultV1_0_13;
86
+ endpointMetadata?: EndpointMetadataResult;
89
87
  accessTokenResponse?: AccessTokenResponse;
90
88
  authorizationRequestOpts?: AuthorizationRequestOpts;
91
89
  authorizationCodeResponse?: AuthorizationResponse;
@@ -105,12 +103,13 @@ export class OpenID4VCIClient {
105
103
  pkce: { disabled: false, codeChallengeMethod: CodeChallengeMethod.S256, ...pkce },
106
104
  authorizationRequestOpts,
107
105
  authorizationCodeResponse,
108
- accessToken,
109
106
  jwk,
110
- endpointMetadata,
107
+ endpointMetadata: endpointMetadata?.credentialIssuerMetadata?.authorization_server
108
+ ? (endpointMetadata as EndpointMetadataResultV1_0_11)
109
+ : (endpointMetadata as EndpointMetadataResultV1_0_13 | undefined),
111
110
  accessTokenResponse,
112
111
  authorizationURL,
113
- };
112
+ } as OpenID4VCIClientState;
114
113
  // Running syncAuthorizationRequestOpts later as it is using the state
115
114
  if (!this._state.authorizationRequestOpts) {
116
115
  this._state.authorizationRequestOpts = this.syncAuthorizationRequestOpts(authorizationRequest);
@@ -227,19 +226,28 @@ export class OpenID4VCIClient {
227
226
  ) {
228
227
  this._state.endpointMetadata.authorization_endpoint = this._state.endpointMetadata.credentialIssuerMetadata.authorization_endpoint as string;
229
228
  }
230
- this._state.authorizationURL = await createAuthorizationRequestUrl({
231
- pkce: this._state.pkce,
232
- endpointMetadata: this.endpointMetadata,
233
- authorizationRequest: this._state.authorizationRequestOpts,
234
- credentialOffer: this.credentialOffer,
235
- credentialConfigurationSupported: this.getCredentialsSupported(),
236
- version: this.version(),
237
- });
229
+ if (this.version() <= OpenId4VCIVersion.VER_1_0_11) {
230
+ this._state.authorizationURL = await createAuthorizationRequestUrlV1_0_11({
231
+ pkce: this._state.pkce,
232
+ endpointMetadata: this.endpointMetadata as EndpointMetadataResultV1_0_11,
233
+ authorizationRequest: this._state.authorizationRequestOpts,
234
+ credentialOffer: this.credentialOffer,
235
+ credentialsSupported: Object.values(this.getCredentialsSupported(true)) as CredentialsSupportedLegacy[],
236
+ });
237
+ } else {
238
+ this._state.authorizationURL = await createAuthorizationRequestUrl({
239
+ pkce: this._state.pkce,
240
+ endpointMetadata: this.endpointMetadata as EndpointMetadataResultV1_0_13,
241
+ authorizationRequest: this._state.authorizationRequestOpts,
242
+ credentialOffer: this.credentialOffer,
243
+ credentialConfigurationSupported: this.getCredentialsSupported(false) as Record<string, CredentialConfigurationSupportedV1_0_13>,
244
+ });
245
+ }
238
246
  }
239
247
  return this._state.authorizationURL;
240
248
  }
241
249
 
242
- public async retrieveServerMetadata(): Promise<EndpointMetadataResultV1_0_13> {
250
+ public async retrieveServerMetadata(): Promise<EndpointMetadataResult> {
243
251
  this.assertIssuerData();
244
252
  if (!this._state.endpointMetadata) {
245
253
  if (this.credentialOffer) {
@@ -284,7 +292,7 @@ export class OpenID4VCIClient {
284
292
  this._state.clientId = clientId;
285
293
  }
286
294
  if (!this._state.accessTokenResponse) {
287
- const accessTokenClient = new AccessTokenClient();
295
+ const accessTokenClient = this.version() <= OpenId4VCIVersion.VER_1_0_12 ? new AccessTokenClientV1_0_11() : new AccessTokenClient();
288
296
 
289
297
  if (redirectUri && redirectUri !== this._state.authorizationRequestOpts?.redirectUri) {
290
298
  console.log(
@@ -294,6 +302,7 @@ export class OpenID4VCIClient {
294
302
  if (this._state.authorizationRequestOpts?.redirectUri && !redirectUri) {
295
303
  redirectUri = this._state.authorizationRequestOpts.redirectUri;
296
304
  }
305
+
297
306
  const response = await accessTokenClient.acquireAccessToken({
298
307
  credentialOffer: this.credentialOffer,
299
308
  metadata: this.endpointMetadata,
@@ -328,7 +337,6 @@ export class OpenID4VCIClient {
328
337
  }
329
338
 
330
339
  public async acquireCredentials({
331
- credentialIdentifier,
332
340
  credentialTypes,
333
341
  context,
334
342
  proofCallbacks,
@@ -340,8 +348,7 @@ export class OpenID4VCIClient {
340
348
  deferredCredentialAwait,
341
349
  deferredCredentialIntervalInMS,
342
350
  }: {
343
- credentialIdentifier?: string;
344
- credentialTypes?: string | string[];
351
+ credentialTypes: string | string[];
345
352
  context?: string[];
346
353
  proofCallbacks: ProofOfPossessionCallbacks<any>;
347
354
  format?: CredentialFormat | OID4VCICredentialFormat;
@@ -361,38 +368,41 @@ export class OpenID4VCIClient {
361
368
  if (jwk) this._state.jwk = jwk;
362
369
  if (kid) this._state.kid = kid;
363
370
 
364
- const requestBuilder = this.credentialOffer
365
- ? CredentialRequestClientBuilder.fromCredentialOffer({
366
- credentialOffer: this.credentialOffer,
367
- metadata: this.endpointMetadata,
368
- })
369
- : CredentialRequestClientBuilder.fromCredentialIssuer({
370
- credentialIssuer: this.getIssuer(),
371
- credentialIdentifier: credentialIdentifier,
372
- metadata: this.endpointMetadata,
373
- version: this.version(),
374
- });
371
+ let requestBuilder: CredentialRequestClientBuilder | CredentialRequestClientBuilderV1_0_11;
372
+ if (this.version() < OpenId4VCIVersion.VER_1_0_13) {
373
+ requestBuilder = this.credentialOffer
374
+ ? CredentialRequestClientBuilderV1_0_11.fromCredentialOffer({
375
+ credentialOffer: this.credentialOffer,
376
+ metadata: this.endpointMetadata,
377
+ })
378
+ : CredentialRequestClientBuilderV1_0_11.fromCredentialIssuer({
379
+ credentialIssuer: this.getIssuer(),
380
+ credentialTypes,
381
+ metadata: this.endpointMetadata,
382
+ version: this.version(),
383
+ });
384
+ } else {
385
+ requestBuilder = this.credentialOffer
386
+ ? CredentialRequestClientBuilder.fromCredentialOffer({
387
+ credentialOffer: this.credentialOffer,
388
+ metadata: this.endpointMetadata,
389
+ })
390
+ : CredentialRequestClientBuilder.fromCredentialIssuer({
391
+ credentialIssuer: this.getIssuer(),
392
+ credentialTypes,
393
+ metadata: this.endpointMetadata,
394
+ version: this.version(),
395
+ });
396
+ }
375
397
 
376
398
  requestBuilder.withTokenFromResponse(this.accessTokenResponse);
377
399
  requestBuilder.withDeferredCredentialAwait(deferredCredentialAwait ?? false, deferredCredentialIntervalInMS);
378
400
  let subjectIssuance: ExperimentalSubjectIssuance | undefined;
379
401
  if (this.endpointMetadata?.credentialIssuerMetadata) {
380
402
  const metadata = this.endpointMetadata.credentialIssuerMetadata;
381
- const types = credentialTypes ? (Array.isArray(credentialTypes) ? credentialTypes : [credentialTypes]) : undefined;
403
+ const types = Array.isArray(credentialTypes) ? credentialTypes : [credentialTypes];
382
404
 
383
- if (credentialIdentifier) {
384
- if (typeof metadata.credential_configurations_supported !== 'object') {
385
- throw Error(
386
- `Credentials_supported should be an object, current ${typeof metadata.credential_configurations_supported} when credential_identifier is used`,
387
- );
388
- }
389
- const credentialsSupported = metadata.credential_configurations_supported;
390
- if (!metadata.credential_configurations_supported || !credentialsSupported[credentialIdentifier]) {
391
- throw new Error(`Credential type ${credentialIdentifier} is not supported by issuer ${this.getIssuer()}`);
392
- }
393
- } else if (!types) {
394
- throw Error(`If no credential_identifier is used, we expect types`);
395
- } else if (metadata.credentials_supported && Array.isArray(metadata.credentials_supported)) {
405
+ if (metadata.credentials_supported && Array.isArray(metadata.credentials_supported)) {
396
406
  let typeSupported = false;
397
407
 
398
408
  metadata.credentials_supported.forEach((supportedCredential) => {
@@ -412,9 +422,9 @@ export class OpenID4VCIClient {
412
422
  console.log(`Not all credential types ${JSON.stringify(credentialTypes)} are present in metadata for ${this.getIssuer()}`);
413
423
  // throw Error(`Not all credential types ${JSON.stringify(credentialTypes)} are supported by issuer ${this.getIssuer()}`);
414
424
  }
415
- } else if (metadata.credential_configurations_supported && !Array.isArray(metadata.credential_configurations_supported)) {
416
- const credentialsSupported = metadata.credential_configurations_supported;
417
- if (types.some((type) => !metadata.credential_configurations_supported || !credentialsSupported[type])) {
425
+ } else if (metadata.credentials_supported && !Array.isArray(metadata.credentials_supported)) {
426
+ const credentialsSupported = metadata.credentials_supported;
427
+ if (types.some((type) => !metadata.credentials_supported || !credentialsSupported[type])) {
418
428
  throw Error(`Not all credential types ${JSON.stringify(credentialTypes)} are supported by issuer ${this.getIssuer()}`);
419
429
  }
420
430
  }
@@ -448,7 +458,10 @@ export class OpenID4VCIClient {
448
458
  }
449
459
  const response = await credentialRequestClient.acquireCredentialsUsingProof({
450
460
  proofInput: proofBuilder,
451
- ...(credentialIdentifier ? { credentialIdentifier, subjectIssuance } : { format, context, credentialTypes, subjectIssuance }),
461
+ credentialTypes,
462
+ context,
463
+ format,
464
+ subjectIssuance,
452
465
  });
453
466
  if (response.errorBody) {
454
467
  debug(`Credential request error:\r\n${JSON.stringify(response.errorBody)}`);
@@ -473,13 +486,14 @@ export class OpenID4VCIClient {
473
486
  }
474
487
 
475
488
  getCredentialsSupported(
489
+ restrictToInitiationTypes?: boolean,
476
490
  format?: (OID4VCICredentialFormat | string) | (OID4VCICredentialFormat | string)[],
477
- ): Record<string, CredentialConfigurationSupportedV1_0_13> {
491
+ ): Record<string, CredentialConfigurationSupportedV1_0_13> | Array<CredentialConfigurationSupported> {
478
492
  return getSupportedCredentials({
479
493
  issuerMetadata: this.endpointMetadata.credentialIssuerMetadata,
480
494
  version: this.version(),
481
495
  format: format,
482
- types: undefined,
496
+ types: restrictToInitiationTypes ? this.getCredentialOfferTypes() : undefined,
483
497
  });
484
498
  }
485
499
 
@@ -491,34 +505,28 @@ export class OpenID4VCIClient {
491
505
  return sendNotification(credentialRequestOpts, request, accessToken ?? this._state.accessToken ?? this._state.accessTokenResponse?.access_token);
492
506
  }
493
507
 
494
- /* getCredentialOfferTypes(): string[][] {
508
+ getCredentialOfferTypes(): string[][] | undefined {
495
509
  if (!this.credentialOffer) {
496
510
  return [];
497
- } else if (this.credentialOffer.version < OpenId4VCIVersion.VER_1_0_11) {
511
+ } else if (this.version() < OpenId4VCIVersion.VER_1_0_11) {
498
512
  const orig = this.credentialOffer.original_credential_offer as CredentialOfferPayloadV1_0_08;
499
513
  const types: string[] = typeof orig.credential_type === 'string' ? [orig.credential_type] : orig.credential_type;
500
514
  const result: string[][] = [];
501
515
  result[0] = types;
502
516
  return result;
503
- } else {
504
- return this.credentialOffer.credential_offer.credentials.map((c) => {
505
- if (typeof c === 'string') {
506
- return [c];
507
- } else if ('types' in c) {
508
- return c.types;
509
- } else if ('vct' in c) {
510
- return [c.vct];
511
- } else {
512
- return c.credential_definition.types;
513
- }
514
- });
517
+ } else if (this.version() < OpenId4VCIVersion.VER_1_0_13) {
518
+ return (this.credentialOffer.credential_offer as CredentialOfferPayloadV1_0_11).credentials.map((c) => getTypesFromObject(c) ?? []);
515
519
  }
516
- }*/
520
+ // we don't have this for v13. v13 only has credential_configuration_ids which is not translatable to type
521
+ return undefined;
522
+ }
517
523
 
518
524
  issuerSupportedFlowTypes(): AuthzFlowType[] {
519
525
  return (
520
526
  this.credentialOffer?.supportedFlows ??
521
- (this._state.endpointMetadata?.credentialIssuerMetadata?.authorization_endpoint ? [AuthzFlowType.AUTHORIZATION_CODE_FLOW] : [])
527
+ (this._state.endpointMetadata?.credentialIssuerMetadata?.authorization_endpoint ?? this._state.endpointMetadata?.authorization_server
528
+ ? [AuthzFlowType.AUTHORIZATION_CODE_FLOW]
529
+ : [])
522
530
  );
523
531
  }
524
532
 
@@ -526,23 +534,33 @@ export class OpenID4VCIClient {
526
534
  return this.issuerSupportedFlowTypes().includes(flowType);
527
535
  }
528
536
 
529
- public hasAuthorizationURL(): boolean {
530
- return !!this.authorizationURL;
531
- }
532
-
533
537
  get authorizationURL(): string | undefined {
534
538
  return this._state.authorizationURL;
535
539
  }
536
540
 
541
+ public hasAuthorizationURL(): boolean {
542
+ return !!this.authorizationURL;
543
+ }
544
+
537
545
  get credentialOffer(): CredentialOfferRequestWithBaseUrl | undefined {
538
546
  return this._state.credentialOffer;
539
547
  }
540
548
 
541
549
  public version(): OpenId4VCIVersion {
542
- return this.credentialOffer?.version ?? OpenId4VCIVersion.VER_1_0_11;
550
+ if (this.credentialOffer?.version && this.credentialOffer.version !== OpenId4VCIVersion.VER_UNKNOWN) {
551
+ return this.credentialOffer.version;
552
+ }
553
+ const metadata = this._state.endpointMetadata;
554
+ if (metadata?.credentialIssuerMetadata) {
555
+ const versions = determineVersionsFromIssuerMetadata(metadata.credentialIssuerMetadata);
556
+ if (versions.length > 0 && !versions.includes(OpenId4VCIVersion.VER_UNKNOWN)) {
557
+ return versions[0];
558
+ }
559
+ }
560
+ return OpenId4VCIVersion.VER_1_0_13;
543
561
  }
544
562
 
545
- public get endpointMetadata(): EndpointMetadataResultV1_0_13 {
563
+ public get endpointMetadata(): EndpointMetadataResult {
546
564
  this.assertServerMetadata();
547
565
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
548
566
  return this._state.endpointMetadata!;
@@ -589,8 +607,11 @@ export class OpenID4VCIClient {
589
607
 
590
608
  public getAccessTokenEndpoint(): string {
591
609
  this.assertIssuerData();
592
- return this.endpointMetadata
593
- ? this.endpointMetadata.token_endpoint
610
+ if (this.endpointMetadata) {
611
+ return this.endpointMetadata.token_endpoint;
612
+ }
613
+ return this.version() <= OpenId4VCIVersion.VER_1_0_12
614
+ ? AccessTokenClientV1_0_11.determineTokenURL({ issuerOpts: { issuer: this.getIssuer() } })
594
615
  : AccessTokenClient.determineTokenURL({ issuerOpts: { issuer: this.getIssuer() } });
595
616
  }
596
617
 
@@ -611,33 +632,23 @@ export class OpenID4VCIClient {
611
632
  /**
612
633
  * Too bad we need a method like this, but EBSI is not exposing metadata
613
634
  */
614
- public isEBSI(): boolean {
615
- const credentialOffer = this.credentialOffer?.credential_offer as CredentialOfferPayloadV1_0_13;
616
-
617
- if (credentialOffer?.credential_configuration_ids) {
618
- const credentialConfigurations = this.endpointMetadata.credentialIssuerMetadata?.credential_configurations_supported;
619
-
620
- if (credentialConfigurations) {
621
- const isEBSITrustFramework = credentialOffer.credential_configuration_ids
622
- .map((id) => credentialConfigurations[id])
623
- .filter(
624
- (config): config is CredentialConfigurationSupportedV1_0_13 =>
625
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
626
- // @ts-ignore
627
- config !== undefined && 'trust_framework' in config && 'name' in config.trust_framework,
628
- )
635
+ public isEBSI() {
636
+ if (
637
+ this.credentialOffer &&
638
+ (this.credentialOffer?.credential_offer as CredentialOfferPayloadV1_0_11)?.credentials?.find(
639
+ (cred) =>
629
640
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
630
641
  // @ts-ignore
631
- .some((config) => config.trust_framework.name.includes('ebsi'));
632
-
633
- if (isEBSITrustFramework) {
634
- return true;
635
- }
636
- }
642
+ typeof cred !== 'string' && 'trust_framework' in cred && 'name' in cred.trust_framework && cred.trust_framework.name.includes('ebsi'),
643
+ )
644
+ ) {
645
+ return true;
637
646
  }
638
-
639
- this.assertIssuerData();
640
- return this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') ?? false;
647
+ // this.assertIssuerData();
648
+ return (
649
+ this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') ||
650
+ this.endpointMetadata.credentialIssuerMetadata?.authorization_server?.includes('ebsi.eu')
651
+ );
641
652
  }
642
653
 
643
654
  private assertIssuerData(): void {
@@ -661,7 +672,12 @@ export class OpenID4VCIClient {
661
672
  }
662
673
 
663
674
  private syncAuthorizationRequestOpts(opts?: AuthorizationRequestOpts): AuthorizationRequestOpts {
664
- let authorizationRequestOpts = { ...this._state?.authorizationRequestOpts, ...opts } as AuthorizationRequestOpts;
675
+ const requestObjectOpts = { ...this._state?.authorizationRequestOpts?.requestObjectOpts, ...opts?.requestObjectOpts };
676
+ let authorizationRequestOpts = {
677
+ ...this._state?.authorizationRequestOpts,
678
+ ...opts,
679
+ ...(requestObjectOpts && { requestObjectOpts }),
680
+ } as AuthorizationRequestOpts;
665
681
  if (!authorizationRequestOpts) {
666
682
  // We only set a redirectUri if no options are provided.
667
683
  // Note that this only works for mobile apps, that can handle a code query param on the default openid-credential-offer deeplink.
@@ -17,6 +17,7 @@ import {
17
17
  getIssuerFromCredentialOfferPayload,
18
18
  getSupportedCredentials,
19
19
  getTypesFromCredentialSupported,
20
+ getTypesFromObject,
20
21
  JWK,
21
22
  KID_JWK_X5C_ERROR,
22
23
  OID4VCICredentialFormat,
@@ -50,6 +51,7 @@ export interface OpenID4VCIClientStateV1_0_11 {
50
51
  authorizationRequestOpts?: AuthorizationRequestOpts;
51
52
  authorizationCodeResponse?: AuthorizationResponse;
52
53
  pkce: PKCEOpts;
54
+ accessToken?: string;
53
55
  authorizationURL?: string;
54
56
  }
55
57
 
@@ -212,7 +214,7 @@ export class OpenID4VCIClientV1_0_11 {
212
214
  throw Error(`No Authorization Request options present or provided in this call`);
213
215
  }
214
216
 
215
- // todo: Probably can go with current logic in MetadataClient who will always set the authorization_endpoint when found
217
+ // todo: Probably can go with current logic in MetadataClientV1_0_13 who will always set the authorization_endpoint when found
216
218
  // handling this because of the support for v1_0-08
217
219
  if (
218
220
  this._state.endpointMetadata?.credentialIssuerMetadata &&
@@ -459,15 +461,13 @@ export class OpenID4VCIClientV1_0_11 {
459
461
  }) as Record<string, CredentialConfigurationSupported>;
460
462
  }
461
463
 
462
- getCredentialsSupported(
463
- format?: (OID4VCICredentialFormat | string) | (OID4VCICredentialFormat | string)[],
464
- ): Record<string, CredentialConfigurationSupported> {
464
+ getCredentialsSupported(format?: (OID4VCICredentialFormat | string) | (OID4VCICredentialFormat | string)[]): CredentialConfigurationSupported[] {
465
465
  return getSupportedCredentials({
466
466
  issuerMetadata: this.endpointMetadata.credentialIssuerMetadata,
467
467
  version: this.version(),
468
468
  format: format,
469
469
  types: undefined,
470
- }) as Record<string, CredentialConfigurationSupported>;
470
+ }) as CredentialConfigurationSupported[];
471
471
  }
472
472
 
473
473
  getCredentialOfferTypes(): string[][] {
@@ -480,20 +480,10 @@ export class OpenID4VCIClientV1_0_11 {
480
480
  result[0] = types;
481
481
  return result;
482
482
  } else if (this.credentialOffer.version < OpenId4VCIVersion.VER_1_0_13) {
483
- return (this.credentialOffer.credential_offer as CredentialOfferPayloadV1_0_11).credentials.map((c) => {
484
- if (typeof c === 'string') {
485
- return [c];
486
- } else if ('types' in c) {
487
- return c.types;
488
- } else if ('vct' in c) {
489
- return [c.vct];
490
- } else {
491
- return c.credential_definition.types;
492
- }
493
- });
483
+ return (this.credentialOffer.credential_offer as CredentialOfferPayloadV1_0_11).credentials.map((c) => getTypesFromObject(c) ?? []);
494
484
  }
495
- // we don't have this for v13. v13 only has credential_configuration_ids which is not translatable to type
496
- return [];
485
+ // we don't support > V11
486
+ throw Error(`This class only supports version 11 and lower! Version: ${this.version()}`);
497
487
  }
498
488
 
499
489
  issuerSupportedFlowTypes(): AuthzFlowType[] {
@@ -605,7 +595,7 @@ export class OpenID4VCIClientV1_0_11 {
605
595
  return true;
606
596
  }
607
597
  this.assertIssuerData();
608
- return this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu');
598
+ return this.endpointMetadata.credentialIssuerMetadata?.authorization_endpoint?.includes('ebsi.eu') === true;
609
599
  }
610
600
 
611
601
  private assertIssuerData(): void {