@sphereon/oid4vci-client 0.8.2-next.6 → 0.8.2-unstable.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -8
- package/dist/AccessTokenClient.d.ts.map +1 -1
- package/dist/AccessTokenClient.js +8 -8
- package/dist/AccessTokenClient.js.map +1 -1
- package/dist/AuthorizationDetailsBuilder.d.ts.map +1 -1
- package/dist/CredentialRequestClient.d.ts.map +1 -1
- package/dist/CredentialRequestClient.js +38 -36
- package/dist/CredentialRequestClient.js.map +1 -1
- package/dist/CredentialRequestClientBuilder.d.ts +6 -0
- package/dist/CredentialRequestClientBuilder.d.ts.map +1 -1
- package/dist/CredentialRequestClientBuilder.js +10 -1
- package/dist/CredentialRequestClientBuilder.js.map +1 -1
- package/dist/OpenID4VCIClient.d.ts +11 -3
- package/dist/OpenID4VCIClient.d.ts.map +1 -1
- package/dist/OpenID4VCIClient.js +96 -34
- package/dist/OpenID4VCIClient.js.map +1 -1
- package/lib/AccessTokenClient.ts +10 -8
- package/lib/AuthorizationDetailsBuilder.ts +2 -2
- package/lib/CredentialRequestClient.ts +44 -38
- package/lib/CredentialRequestClientBuilder.ts +21 -1
- package/lib/OpenID4VCIClient.ts +121 -35
- package/lib/__tests__/CredentialRequestClient.spec.ts +13 -8
- package/lib/__tests__/EBSIE2E.spec.test.ts +136 -0
- package/lib/__tests__/OpenID4VCIClient.spec.ts +5 -0
- package/lib/__tests__/data/VciDataFixtures.ts +14 -13
- package/package.json +6 -4
package/lib/OpenID4VCIClient.ts
CHANGED
|
@@ -8,6 +8,9 @@ import {
|
|
|
8
8
|
CredentialResponse,
|
|
9
9
|
CredentialSupported,
|
|
10
10
|
EndpointMetadataResult,
|
|
11
|
+
getIssuerFromCredentialOfferPayload,
|
|
12
|
+
getSupportedCredentials,
|
|
13
|
+
getTypesFromCredentialSupported,
|
|
11
14
|
JsonURIMode,
|
|
12
15
|
OID4VCICredentialFormat,
|
|
13
16
|
OpenId4VCIVersion,
|
|
@@ -15,8 +18,6 @@ import {
|
|
|
15
18
|
PushedAuthorizationResponse,
|
|
16
19
|
ResponseType,
|
|
17
20
|
} from '@sphereon/oid4vci-common';
|
|
18
|
-
import { getSupportedCredentials } from '@sphereon/oid4vci-common/dist/functions/IssuerMetadataUtils';
|
|
19
|
-
import { CredentialSupportedTypeV1_0_08 } from '@sphereon/oid4vci-common/dist/types/v1_0_08.types';
|
|
20
21
|
import { CredentialFormat } from '@sphereon/ssi-types';
|
|
21
22
|
import Debug from 'debug';
|
|
22
23
|
|
|
@@ -39,27 +40,65 @@ interface AuthDetails {
|
|
|
39
40
|
|
|
40
41
|
interface AuthRequestOpts {
|
|
41
42
|
codeChallenge: string;
|
|
42
|
-
codeChallengeMethod
|
|
43
|
+
codeChallengeMethod?: CodeChallengeMethod;
|
|
43
44
|
authorizationDetails?: AuthDetails | AuthDetails[];
|
|
44
45
|
redirectUri: string;
|
|
45
46
|
scope?: string;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
export class OpenID4VCIClient {
|
|
49
|
-
private readonly _credentialOffer
|
|
50
|
+
private readonly _credentialOffer?: CredentialOfferRequestWithBaseUrl;
|
|
51
|
+
private _credentialIssuer: string;
|
|
50
52
|
private _clientId?: string;
|
|
51
53
|
private _kid: string | undefined;
|
|
52
54
|
private _alg: Alg | string | undefined;
|
|
53
55
|
private _endpointMetadata: EndpointMetadataResult | undefined;
|
|
54
56
|
private _accessTokenResponse: AccessTokenResponse | undefined;
|
|
55
57
|
|
|
56
|
-
private constructor(
|
|
58
|
+
private constructor({
|
|
59
|
+
credentialOffer,
|
|
60
|
+
clientId,
|
|
61
|
+
kid,
|
|
62
|
+
alg,
|
|
63
|
+
credentialIssuer,
|
|
64
|
+
}: {
|
|
65
|
+
credentialOffer?: CredentialOfferRequestWithBaseUrl;
|
|
66
|
+
kid?: string;
|
|
67
|
+
alg?: Alg | string;
|
|
68
|
+
clientId?: string;
|
|
69
|
+
credentialIssuer?: string;
|
|
70
|
+
}) {
|
|
57
71
|
this._credentialOffer = credentialOffer;
|
|
72
|
+
const issuer = credentialIssuer ?? (credentialOffer ? getIssuerFromCredentialOfferPayload(credentialOffer.credential_offer) : undefined);
|
|
73
|
+
if (!issuer) {
|
|
74
|
+
throw Error('No credential issuer supplied or deduced from offer');
|
|
75
|
+
}
|
|
76
|
+
this._credentialIssuer = issuer;
|
|
58
77
|
this._kid = kid;
|
|
59
78
|
this._alg = alg;
|
|
60
79
|
this._clientId = clientId;
|
|
61
80
|
}
|
|
62
81
|
|
|
82
|
+
public static async fromCredentialIssuer({
|
|
83
|
+
kid,
|
|
84
|
+
alg,
|
|
85
|
+
retrieveServerMetadata,
|
|
86
|
+
clientId,
|
|
87
|
+
credentialIssuer,
|
|
88
|
+
}: {
|
|
89
|
+
credentialIssuer: string;
|
|
90
|
+
kid?: string;
|
|
91
|
+
alg?: Alg | string;
|
|
92
|
+
retrieveServerMetadata?: boolean;
|
|
93
|
+
clientId?: string;
|
|
94
|
+
}) {
|
|
95
|
+
const client = new OpenID4VCIClient({ kid, alg, clientId, credentialIssuer });
|
|
96
|
+
if (retrieveServerMetadata === undefined || retrieveServerMetadata) {
|
|
97
|
+
await client.retrieveServerMetadata();
|
|
98
|
+
}
|
|
99
|
+
return client;
|
|
100
|
+
}
|
|
101
|
+
|
|
63
102
|
public static async fromURI({
|
|
64
103
|
uri,
|
|
65
104
|
kid,
|
|
@@ -75,7 +114,12 @@ export class OpenID4VCIClient {
|
|
|
75
114
|
resolveOfferUri?: boolean;
|
|
76
115
|
clientId?: string;
|
|
77
116
|
}): Promise<OpenID4VCIClient> {
|
|
78
|
-
const client = new OpenID4VCIClient(
|
|
117
|
+
const client = new OpenID4VCIClient({
|
|
118
|
+
credentialOffer: await CredentialOfferClient.fromURI(uri, { resolve: resolveOfferUri }),
|
|
119
|
+
kid,
|
|
120
|
+
alg,
|
|
121
|
+
clientId,
|
|
122
|
+
});
|
|
79
123
|
|
|
80
124
|
if (retrieveServerMetadata === undefined || retrieveServerMetadata) {
|
|
81
125
|
await client.retrieveServerMetadata();
|
|
@@ -86,16 +130,41 @@ export class OpenID4VCIClient {
|
|
|
86
130
|
public async retrieveServerMetadata(): Promise<EndpointMetadataResult> {
|
|
87
131
|
this.assertIssuerData();
|
|
88
132
|
if (!this._endpointMetadata) {
|
|
89
|
-
|
|
133
|
+
if (this.credentialOffer) {
|
|
134
|
+
this._endpointMetadata = await MetadataClient.retrieveAllMetadataFromCredentialOffer(this.credentialOffer);
|
|
135
|
+
} else if (this._credentialIssuer) {
|
|
136
|
+
this._endpointMetadata = await MetadataClient.retrieveAllMetadata(this._credentialIssuer);
|
|
137
|
+
} else {
|
|
138
|
+
throw Error(`Cannot retrieve issuer metadata without either a credential offer, or issuer value`);
|
|
139
|
+
}
|
|
90
140
|
}
|
|
91
141
|
return this.endpointMetadata;
|
|
92
142
|
}
|
|
93
143
|
|
|
144
|
+
// todo: Unify this method with the par method
|
|
145
|
+
|
|
94
146
|
public createAuthorizationRequestUrl({ codeChallengeMethod, codeChallenge, authorizationDetails, redirectUri, scope }: AuthRequestOpts): string {
|
|
95
147
|
// Scope and authorization_details can be used in the same authorization request
|
|
96
148
|
// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-rar-23#name-relationship-to-scope-param
|
|
97
149
|
if (!scope && !authorizationDetails) {
|
|
98
|
-
|
|
150
|
+
if (!this.credentialOffer) {
|
|
151
|
+
throw Error('Please provide a scope or authorization_details');
|
|
152
|
+
}
|
|
153
|
+
const creds = this.credentialOffer.credential_offer.credentials;
|
|
154
|
+
|
|
155
|
+
authorizationDetails = creds
|
|
156
|
+
.flatMap((cred) => (typeof cred === 'string' ? this.getCredentialsSupported(true) : (cred as CredentialSupported)))
|
|
157
|
+
.map((cred) => {
|
|
158
|
+
return {
|
|
159
|
+
...cred,
|
|
160
|
+
type: 'openid_credential',
|
|
161
|
+
locations: [this._credentialIssuer],
|
|
162
|
+
format: cred.format,
|
|
163
|
+
} satisfies AuthDetails;
|
|
164
|
+
});
|
|
165
|
+
if (authorizationDetails.length === 0) {
|
|
166
|
+
throw Error(`Could not create authorization details from credential offer. Please pass in explicit details`);
|
|
167
|
+
}
|
|
99
168
|
}
|
|
100
169
|
// todo: Probably can go with current logic in MetadataClient who will always set the authorization_endpoint when found
|
|
101
170
|
// handling this because of the support for v1_0-08
|
|
@@ -117,7 +186,7 @@ export class OpenID4VCIClient {
|
|
|
117
186
|
|
|
118
187
|
const queryObj: { [key: string]: string } = {
|
|
119
188
|
response_type: ResponseType.AUTH_CODE,
|
|
120
|
-
code_challenge_method: codeChallengeMethod,
|
|
189
|
+
code_challenge_method: codeChallengeMethod ?? CodeChallengeMethod.SHA256,
|
|
121
190
|
code_challenge: codeChallenge,
|
|
122
191
|
authorization_details: JSON.stringify(this.handleAuthorizationDetails(authorizationDetails)),
|
|
123
192
|
redirect_uri: redirectUri,
|
|
@@ -128,7 +197,7 @@ export class OpenID4VCIClient {
|
|
|
128
197
|
queryObj['client_id'] = this.clientId;
|
|
129
198
|
}
|
|
130
199
|
|
|
131
|
-
if (this.credentialOffer
|
|
200
|
+
if (this.credentialOffer?.issuerState) {
|
|
132
201
|
queryObj['issuer_state'] = this.credentialOffer.issuerState;
|
|
133
202
|
}
|
|
134
203
|
|
|
@@ -140,6 +209,7 @@ export class OpenID4VCIClient {
|
|
|
140
209
|
});
|
|
141
210
|
}
|
|
142
211
|
|
|
212
|
+
// todo: Unify this method with the create auth request url method
|
|
143
213
|
public async acquirePushedAuthorizationRequestURI({
|
|
144
214
|
codeChallengeMethod,
|
|
145
215
|
codeChallenge,
|
|
@@ -173,7 +243,7 @@ export class OpenID4VCIClient {
|
|
|
173
243
|
|
|
174
244
|
const queryObj: { [key: string]: string } = {
|
|
175
245
|
response_type: ResponseType.AUTH_CODE,
|
|
176
|
-
code_challenge_method: codeChallengeMethod,
|
|
246
|
+
code_challenge_method: codeChallengeMethod ?? CodeChallengeMethod.SHA256,
|
|
177
247
|
code_challenge: codeChallenge,
|
|
178
248
|
authorization_details: JSON.stringify(this.handleAuthorizationDetails(authorizationDetails)),
|
|
179
249
|
redirect_uri: redirectUri,
|
|
@@ -184,7 +254,7 @@ export class OpenID4VCIClient {
|
|
|
184
254
|
queryObj['client_id'] = this.clientId;
|
|
185
255
|
}
|
|
186
256
|
|
|
187
|
-
if (this.credentialOffer
|
|
257
|
+
if (this.credentialOffer?.issuerState) {
|
|
188
258
|
queryObj['issuer_state'] = this.credentialOffer.issuerState;
|
|
189
259
|
}
|
|
190
260
|
|
|
@@ -249,6 +319,7 @@ export class OpenID4VCIClient {
|
|
|
249
319
|
const response = await accessTokenClient.acquireAccessToken({
|
|
250
320
|
credentialOffer: this.credentialOffer,
|
|
251
321
|
metadata: this.endpointMetadata,
|
|
322
|
+
credentialIssuer: this.getIssuer(),
|
|
252
323
|
pin,
|
|
253
324
|
codeVerifier,
|
|
254
325
|
code,
|
|
@@ -298,36 +369,42 @@ export class OpenID4VCIClient {
|
|
|
298
369
|
this._kid = kid;
|
|
299
370
|
}
|
|
300
371
|
|
|
301
|
-
const requestBuilder =
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
372
|
+
const requestBuilder = this.credentialOffer
|
|
373
|
+
? CredentialRequestClientBuilder.fromCredentialOffer({
|
|
374
|
+
credentialOffer: this.credentialOffer,
|
|
375
|
+
metadata: this.endpointMetadata,
|
|
376
|
+
})
|
|
377
|
+
: CredentialRequestClientBuilder.fromCredentialIssuer({
|
|
378
|
+
credentialIssuer: this.getIssuer(),
|
|
379
|
+
credentialTypes,
|
|
380
|
+
metadata: this.endpointMetadata,
|
|
381
|
+
version: this.version(),
|
|
382
|
+
});
|
|
305
383
|
|
|
306
384
|
requestBuilder.withTokenFromResponse(this.accessTokenResponse);
|
|
307
385
|
if (this.endpointMetadata?.credentialIssuerMetadata) {
|
|
308
386
|
const metadata = this.endpointMetadata.credentialIssuerMetadata;
|
|
309
|
-
const types = Array.isArray(credentialTypes) ? credentialTypes.sort() : [credentialTypes];
|
|
387
|
+
const types = Array.isArray(credentialTypes) ? [...credentialTypes].sort() : [credentialTypes];
|
|
310
388
|
|
|
311
389
|
if (metadata.credentials_supported && Array.isArray(metadata.credentials_supported)) {
|
|
312
390
|
let typeSupported = false;
|
|
313
391
|
|
|
314
392
|
metadata.credentials_supported.forEach((supportedCredential) => {
|
|
315
|
-
|
|
316
|
-
throw Error('types is required in the credentials supported');
|
|
317
|
-
}
|
|
393
|
+
const subTypes = getTypesFromCredentialSupported(supportedCredential);
|
|
318
394
|
if (
|
|
319
|
-
|
|
320
|
-
(types.length === 1 && (types[0] === supportedCredential.id ||
|
|
395
|
+
subTypes.sort().every((t, i) => types[i] === t) ||
|
|
396
|
+
(types.length === 1 && (types[0] === supportedCredential.id || subTypes.includes(types[0])))
|
|
321
397
|
) {
|
|
322
398
|
typeSupported = true;
|
|
323
399
|
}
|
|
324
400
|
});
|
|
325
401
|
|
|
326
402
|
if (!typeSupported) {
|
|
327
|
-
|
|
403
|
+
console.log(`Not all credential types ${JSON.stringify(credentialTypes)} are present in metadata for ${this.getIssuer()}`);
|
|
404
|
+
// throw Error(`Not all credential types ${JSON.stringify(credentialTypes)} are supported by issuer ${this.getIssuer()}`);
|
|
328
405
|
}
|
|
329
406
|
} else if (metadata.credentials_supported && !Array.isArray(metadata.credentials_supported)) {
|
|
330
|
-
const credentialsSupported = metadata.credentials_supported
|
|
407
|
+
const credentialsSupported = metadata.credentials_supported;
|
|
331
408
|
if (types.some((type) => !metadata.credentials_supported || !credentialsSupported[type])) {
|
|
332
409
|
throw Error(`Not all credential types ${JSON.stringify(credentialTypes)} are supported by issuer ${this.getIssuer()}`);
|
|
333
410
|
}
|
|
@@ -356,7 +433,7 @@ export class OpenID4VCIClient {
|
|
|
356
433
|
format,
|
|
357
434
|
});
|
|
358
435
|
if (response.errorBody) {
|
|
359
|
-
debug(`Credential request error:\r\n${response.errorBody}`);
|
|
436
|
+
debug(`Credential request error:\r\n${JSON.stringify(response.errorBody)}`);
|
|
360
437
|
throw Error(
|
|
361
438
|
`Retrieving a credential from ${this._endpointMetadata?.credential_endpoint} for issuer ${this.getIssuer()} failed with status: ${
|
|
362
439
|
response.origResponse.status
|
|
@@ -389,7 +466,9 @@ export class OpenID4VCIClient {
|
|
|
389
466
|
}
|
|
390
467
|
|
|
391
468
|
getCredentialOfferTypes(): string[][] {
|
|
392
|
-
if (this.credentialOffer
|
|
469
|
+
if (!this.credentialOffer) {
|
|
470
|
+
return [];
|
|
471
|
+
} else if (this.credentialOffer.version < OpenId4VCIVersion.VER_1_0_11) {
|
|
393
472
|
const orig = this.credentialOffer.original_credential_offer as CredentialOfferPayloadV1_0_08;
|
|
394
473
|
const types: string[] = typeof orig.credential_type === 'string' ? [orig.credential_type] : orig.credential_type;
|
|
395
474
|
const result: string[][] = [];
|
|
@@ -397,21 +476,29 @@ export class OpenID4VCIClient {
|
|
|
397
476
|
return result;
|
|
398
477
|
} else {
|
|
399
478
|
return this.credentialOffer.credential_offer.credentials.map((c) => {
|
|
400
|
-
|
|
479
|
+
if (typeof c === 'string') {
|
|
480
|
+
return [c];
|
|
481
|
+
} else if ('types' in c) {
|
|
482
|
+
return c.types;
|
|
483
|
+
} else if ('vct' in c.credential_definition) {
|
|
484
|
+
return [c.credential_definition.vct];
|
|
485
|
+
} else {
|
|
486
|
+
return c.credential_definition.types;
|
|
487
|
+
}
|
|
401
488
|
});
|
|
402
489
|
}
|
|
403
490
|
}
|
|
404
491
|
|
|
405
492
|
issuerSupportedFlowTypes(): AuthzFlowType[] {
|
|
406
|
-
return this.credentialOffer.
|
|
493
|
+
return this.credentialOffer?.supportedFlows ?? [AuthzFlowType.AUTHORIZATION_CODE_FLOW];
|
|
407
494
|
}
|
|
408
495
|
|
|
409
|
-
get credentialOffer(): CredentialOfferRequestWithBaseUrl {
|
|
496
|
+
get credentialOffer(): CredentialOfferRequestWithBaseUrl | undefined {
|
|
410
497
|
return this._credentialOffer;
|
|
411
498
|
}
|
|
412
499
|
|
|
413
500
|
public version(): OpenId4VCIVersion {
|
|
414
|
-
return this.credentialOffer.
|
|
501
|
+
return this.credentialOffer?.version ?? OpenId4VCIVersion.VER_1_0_11;
|
|
415
502
|
}
|
|
416
503
|
|
|
417
504
|
public get endpointMetadata(): EndpointMetadataResult {
|
|
@@ -437,9 +524,6 @@ export class OpenID4VCIClient {
|
|
|
437
524
|
}
|
|
438
525
|
|
|
439
526
|
get clientId(): string | undefined {
|
|
440
|
-
/*if (!this._clientId) {
|
|
441
|
-
throw Error('No client id present');
|
|
442
|
-
}*/
|
|
443
527
|
return this._clientId;
|
|
444
528
|
}
|
|
445
529
|
|
|
@@ -451,7 +535,7 @@ export class OpenID4VCIClient {
|
|
|
451
535
|
|
|
452
536
|
public getIssuer(): string {
|
|
453
537
|
this.assertIssuerData();
|
|
454
|
-
return this.
|
|
538
|
+
return this._credentialIssuer!;
|
|
455
539
|
}
|
|
456
540
|
|
|
457
541
|
public getAccessTokenEndpoint(): string {
|
|
@@ -467,8 +551,10 @@ export class OpenID4VCIClient {
|
|
|
467
551
|
}
|
|
468
552
|
|
|
469
553
|
private assertIssuerData(): void {
|
|
470
|
-
if (!this._credentialOffer) {
|
|
554
|
+
if (!this._credentialOffer && this.issuerSupportedFlowTypes().includes(AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW)) {
|
|
471
555
|
throw Error(`No issuance initiation or credential offer present`);
|
|
556
|
+
} else if (!this._credentialIssuer) {
|
|
557
|
+
throw Error(`No credential issuer value present`);
|
|
472
558
|
}
|
|
473
559
|
}
|
|
474
560
|
|
|
@@ -3,6 +3,7 @@ import { KeyObject } from 'crypto';
|
|
|
3
3
|
import {
|
|
4
4
|
Alg,
|
|
5
5
|
EndpointMetadata,
|
|
6
|
+
getCredentialRequestForVersion,
|
|
6
7
|
getIssuerFromCredentialOfferPayload,
|
|
7
8
|
Jwt,
|
|
8
9
|
OpenId4VCIVersion,
|
|
@@ -127,7 +128,7 @@ describe('Credential Request Client ', () => {
|
|
|
127
128
|
version: OpenId4VCIVersion.VER_1_0_08,
|
|
128
129
|
});
|
|
129
130
|
expect(credentialRequest.proof?.jwt?.includes(partialJWT)).toBeTruthy();
|
|
130
|
-
expect(credentialRequest.format).toEqual('
|
|
131
|
+
expect(credentialRequest.format).toEqual('jwt_vc');
|
|
131
132
|
const result = await credReqClient.acquireCredentialsUsingRequest(credentialRequest);
|
|
132
133
|
expect(result?.successBody?.credential).toEqual(mockedVC);
|
|
133
134
|
});
|
|
@@ -149,9 +150,7 @@ describe('Credential Request Client ', () => {
|
|
|
149
150
|
.withKid(kid)
|
|
150
151
|
.withClientId('sphereon:wallet')
|
|
151
152
|
.build();
|
|
152
|
-
|
|
153
|
-
// @ts-ignore
|
|
154
|
-
await expect(credReqClient.acquireCredentialsUsingRequest({ format: 'jwt_vc_json-ld', types: ['random'], proof })).rejects.toThrow(
|
|
153
|
+
await expect(credReqClient.acquireCredentialsUsingRequest({ format: 'jwt_vc_json', types: ['random'], proof })).rejects.toThrow(
|
|
155
154
|
Error(URL_NOT_VALID),
|
|
156
155
|
);
|
|
157
156
|
});
|
|
@@ -194,10 +193,11 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
194
193
|
jwt: getMockData('spruce')?.credential.request.proof.jwt as string,
|
|
195
194
|
},
|
|
196
195
|
credentialTypes: ['OpenBadgeCredential'],
|
|
197
|
-
format: '
|
|
196
|
+
format: 'jwt_vc',
|
|
198
197
|
version: OpenId4VCIVersion.VER_1_0_08,
|
|
199
198
|
});
|
|
200
|
-
|
|
199
|
+
const draft8CredentialRequest = getCredentialRequestForVersion(credentialRequest, OpenId4VCIVersion.VER_1_0_08);
|
|
200
|
+
expect(draft8CredentialRequest).toEqual(getMockData('spruce')?.credential.request);
|
|
201
201
|
});
|
|
202
202
|
|
|
203
203
|
it('should create correct CredentialRequest for Walt', async () => {
|
|
@@ -264,7 +264,8 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
264
264
|
format: 'ldp_vc',
|
|
265
265
|
version: OpenId4VCIVersion.VER_1_0_08,
|
|
266
266
|
});
|
|
267
|
-
|
|
267
|
+
const credentialRequest = getCredentialRequestForVersion(credentialOffer, OpenId4VCIVersion.VER_1_0_08);
|
|
268
|
+
expect(credentialRequest).toEqual(getMockData('mattr')?.credential.request);
|
|
268
269
|
});
|
|
269
270
|
|
|
270
271
|
it('should create correct CredentialRequest for diwala', async () => {
|
|
@@ -286,6 +287,10 @@ describe('Credential Request Client with different issuers ', () => {
|
|
|
286
287
|
format: 'ldp_vc',
|
|
287
288
|
version: OpenId4VCIVersion.VER_1_0_08,
|
|
288
289
|
});
|
|
289
|
-
|
|
290
|
+
|
|
291
|
+
// createCredentialRequest returns uniform format in draft 11
|
|
292
|
+
const credentialRequest = getCredentialRequestForVersion(credentialOffer, OpenId4VCIVersion.VER_1_0_08);
|
|
293
|
+
|
|
294
|
+
expect(credentialRequest).toEqual(getMockData('diwala')?.credential.request);
|
|
290
295
|
});
|
|
291
296
|
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Alg, CodeChallengeMethod, Jwt } from '@sphereon/oid4vci-common';
|
|
2
|
+
import { toJwk } from '@sphereon/ssi-sdk-ext.key-utils';
|
|
3
|
+
import { CredentialMapper } from '@sphereon/ssi-types';
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
5
|
+
//@ts-ignore
|
|
6
|
+
import { from } from '@trust/keyto';
|
|
7
|
+
import { fetch } from 'cross-fetch';
|
|
8
|
+
import debug from 'debug';
|
|
9
|
+
import { base64url, importJWK, JWK, SignJWT } from 'jose';
|
|
10
|
+
import * as u8a from 'uint8arrays';
|
|
11
|
+
|
|
12
|
+
import { OpenID4VCIClient } from '..';
|
|
13
|
+
|
|
14
|
+
export const UNIT_TEST_TIMEOUT = 30000;
|
|
15
|
+
|
|
16
|
+
const ISSUER_URL = 'https://conformance-test.ebsi.eu/conformance/v3/issuer-mock';
|
|
17
|
+
const AUTH_URL = 'https://conformance-test.ebsi.eu/conformance/v3/auth-mock';
|
|
18
|
+
|
|
19
|
+
const jwk: JWK = {
|
|
20
|
+
alg: 'ES256',
|
|
21
|
+
use: 'sig',
|
|
22
|
+
kty: 'EC',
|
|
23
|
+
crv: 'P-256',
|
|
24
|
+
x: 'hUWYK06qFvdudydiqnEhVJhZ-73jcLtuzH8kIyNOSHE',
|
|
25
|
+
y: 'UZf7oUkJdo65SQekMD5ssiRclEimG2SmlsjXf3QwQJo',
|
|
26
|
+
d: 'zDeeo3K0Pk8dofeKcajvJYxMZ1vijx_cVDJQl1IpbAM',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
console.log(`JWK (private/orig): ${JSON.stringify(jwk, null, 2)}`);
|
|
30
|
+
|
|
31
|
+
const privateKey = from(jwk, 'jwk').toString('blk', 'private');
|
|
32
|
+
const publicKey = from(jwk, 'jwk').toString('blk', 'public');
|
|
33
|
+
console.log(`Private key: ${privateKey}`);
|
|
34
|
+
console.log(`Public key: ${publicKey}`);
|
|
35
|
+
console.log(`Private key (b64): ${base64url.encode(u8a.fromString(privateKey, 'base16'))}`);
|
|
36
|
+
console.log(`JWK (private 2) ${JSON.stringify(toJwk(privateKey, 'Secp256r1', { isPrivateKey: true }))}`);
|
|
37
|
+
console.log(`JWK (public 2) ${JSON.stringify(toJwk(publicKey, 'Secp256r1', { isPrivateKey: false }))}`);
|
|
38
|
+
|
|
39
|
+
// const DID_METHOD = 'did:key'
|
|
40
|
+
const DID =
|
|
41
|
+
'did:key:z2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9Kbrm54tL4pRrDDhR1QJ5RHPMXUq5MzYpZL2k35vya5eMiNxschNy9AJ74CC3MmcYiZJGZfyhWQ6qDgTVcDSHdquwPYvLDut383JbrgYdZYYSC2merTMgmQtUi3huYhaky1qE';
|
|
42
|
+
const DID_URL_ENCODED =
|
|
43
|
+
'did%3Akey%3Az2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9Kbrm54tL4pRrDDhR1QJ5RHPMXUq5MzYpZL2k35vya5eMiNxschNy9AJ74CC3MmcYiZJGZfyhWQ6qDgTVcDSHdquwPYvLDut383JbrgYdZYYSC2merTMgmQtUi3huYhaky1qE';
|
|
44
|
+
// const PRIVATE_KEY_HEX = '7dd923e40f4615ac496119f7e793cc2899e99b64b88ca8603db986700089532b'
|
|
45
|
+
|
|
46
|
+
// const PUBLIC_KEY_HEX =
|
|
47
|
+
// '04a23cb4c83901acc2eb0f852599610de0caeac260bf8ed05e7f902eaac0f9c8d74dd4841b94d13424d32af8ec0e9976db9abfa7e3a59e10d565c5d4d901b4be63'
|
|
48
|
+
|
|
49
|
+
// pub hex: 35e03477cb29f3ac518770dccd4e26e703cd21b9741c24b038170c377b0d99d9
|
|
50
|
+
// priv hex: 913466d1a38d1d8c0d3c0fb0fc3b633075085a31372bbd2a8022215a88d9d1e5
|
|
51
|
+
// const did = `did:key:z6Mki5ZwZKN1dBQprfJTikUvkDxrHijiiQngkWviMF5gw2Hv`;
|
|
52
|
+
const kid = `${DID}#z2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9Kbrm54tL4pRrDDhR1QJ5RHPMXUq5MzYpZL2k35vya5eMiNxschNy9AJ74CC3MmcYiZJGZfyhWQ6qDgTVcDSHdquwPYvLDut383JbrgYdZYYSC2merTMgmQtUi3huYhaky1qE`;
|
|
53
|
+
|
|
54
|
+
// const jw = jose.importKey()
|
|
55
|
+
describe('OID4VCI-Client using Sphereon issuer should', () => {
|
|
56
|
+
async function test(credentialType: 'CTWalletCrossPreAuthorised' | 'CTWalletCrossInTime') {
|
|
57
|
+
debug.enable('*');
|
|
58
|
+
const offer = await getCredentialOffer(credentialType);
|
|
59
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
60
|
+
uri: offer,
|
|
61
|
+
kid,
|
|
62
|
+
alg: Alg.ES256,
|
|
63
|
+
clientId: DID_URL_ENCODED,
|
|
64
|
+
});
|
|
65
|
+
expect(client.credentialOffer).toBeDefined();
|
|
66
|
+
expect(client.endpointMetadata).toBeDefined();
|
|
67
|
+
expect(client.getCredentialEndpoint()).toEqual(`${ISSUER_URL}/credential`);
|
|
68
|
+
expect(client.getAccessTokenEndpoint()).toEqual(`${AUTH_URL}/token`);
|
|
69
|
+
|
|
70
|
+
if (credentialType !== 'CTWalletCrossPreAuthorised') {
|
|
71
|
+
const url = client.createAuthorizationRequestUrl({
|
|
72
|
+
redirectUri: 'openid4vc%3A',
|
|
73
|
+
codeChallenge: 'mE2kPHmIprOqtkaYmESWj35yz-PB5vzdiSu0tAZ8sqs',
|
|
74
|
+
codeChallengeMethod: CodeChallengeMethod.SHA256,
|
|
75
|
+
});
|
|
76
|
+
const result = await fetch(url);
|
|
77
|
+
console.log(result.text());
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const accessToken = await client.acquireAccessToken({ pin: '0891' });
|
|
81
|
+
// console.log(accessToken);
|
|
82
|
+
expect(accessToken).toMatchObject({
|
|
83
|
+
expires_in: 86400,
|
|
84
|
+
// scope: 'GuestCredential',
|
|
85
|
+
token_type: 'Bearer',
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const format = 'jwt_vc';
|
|
89
|
+
const credentialResponse = await client.acquireCredentials({
|
|
90
|
+
credentialTypes: client.getCredentialOfferTypes()[0],
|
|
91
|
+
format,
|
|
92
|
+
proofCallbacks: {
|
|
93
|
+
signCallback: proofOfPossessionCallbackFunction,
|
|
94
|
+
},
|
|
95
|
+
kid,
|
|
96
|
+
});
|
|
97
|
+
console.log(JSON.stringify(credentialResponse, null, 2));
|
|
98
|
+
expect(credentialResponse.credential).toBeDefined();
|
|
99
|
+
const wrappedVC = CredentialMapper.toWrappedVerifiableCredential(credentialResponse.credential!);
|
|
100
|
+
expect(format.startsWith(wrappedVC.format)).toEqual(true);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
it(
|
|
104
|
+
'succeed in a full flow with the client using OpenID4VCI version 11 and jwt_vc_json',
|
|
105
|
+
async () => {
|
|
106
|
+
await test('CTWalletCrossPreAuthorised');
|
|
107
|
+
// await test('CTWalletCrossInTime');
|
|
108
|
+
},
|
|
109
|
+
UNIT_TEST_TIMEOUT,
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
async function getCredentialOffer(credentialType: 'CTWalletCrossPreAuthorised' | 'CTWalletCrossInTime'): Promise<string> {
|
|
114
|
+
const credentialOffer = await fetch(
|
|
115
|
+
`https://conformance-test.ebsi.eu/conformance/v3/issuer-mock/initiate-credential-offer?credential_type=${credentialType}&client_id=${DID_URL_ENCODED}&credential_offer_endpoint=openid-credential-offer%3A%2F%2F`,
|
|
116
|
+
{
|
|
117
|
+
method: 'GET',
|
|
118
|
+
headers: {
|
|
119
|
+
Accept: 'application/json',
|
|
120
|
+
'Content-Type': 'application/json',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return await credentialOffer.text();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function proofOfPossessionCallbackFunction(args: Jwt, kid?: string): Promise<string> {
|
|
129
|
+
const importedJwk = await importJWK(jwk);
|
|
130
|
+
return await new SignJWT({ ...args.payload })
|
|
131
|
+
.setProtectedHeader({ ...args.header, kid: kid! })
|
|
132
|
+
.setIssuer(DID)
|
|
133
|
+
.setIssuedAt()
|
|
134
|
+
.setExpirationTime('2m')
|
|
135
|
+
.sign(importedJwk);
|
|
136
|
+
}
|
|
@@ -68,6 +68,11 @@ describe('OpenID4VCIClient should', () => {
|
|
|
68
68
|
expect(scope?.[0]).toBe('openid');
|
|
69
69
|
});
|
|
70
70
|
it('throw an error if no scope and no authorization_details is provided', async () => {
|
|
71
|
+
nock(MOCK_URL).get(/.*/).reply(200, {});
|
|
72
|
+
nock(MOCK_URL).get(WellKnownEndpoints.OAUTH_AS).reply(404, {});
|
|
73
|
+
nock(MOCK_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404, {});
|
|
74
|
+
// Use a client with issuer only to trigger the error
|
|
75
|
+
client = await OpenID4VCIClient.fromCredentialIssuer({ credentialIssuer: 'https://server.example.com' });
|
|
71
76
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
72
77
|
// @ts-ignore
|
|
73
78
|
client._endpointMetadata?.credentialIssuerMetadata.authorization_endpoint = `${MOCK_URL}v1/auth/authorize`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CredentialSupportedFormatV1_0_08, IssuerCredentialSubjectDisplay, IssuerMetadataV1_0_08 } from '@sphereon/oid4vci-common';
|
|
2
2
|
import { ICredentialStatus, W3CVerifiableCredential } from '@sphereon/ssi-types';
|
|
3
3
|
|
|
4
4
|
export function getMockData(issuerName: string): IssuerMockData | null {
|
|
@@ -42,7 +42,8 @@ export interface IssuerMockData {
|
|
|
42
42
|
url: string;
|
|
43
43
|
deeplink: string;
|
|
44
44
|
request: {
|
|
45
|
-
types
|
|
45
|
+
types?: [string];
|
|
46
|
+
type?: string;
|
|
46
47
|
format: 'jwt_vc' | 'ldp_vc' | 'jwt_vc_json-ld' | string;
|
|
47
48
|
proof: {
|
|
48
49
|
proof_type: 'jwt' | string;
|
|
@@ -110,8 +111,8 @@ const mockData: VciMockDataStructure = {
|
|
|
110
111
|
deeplink:
|
|
111
112
|
'openid-initiate-issuance://?issuer=https%3A%2F%2Fngi%2Doidc4vci%2Dtest%2Espruceid%2Exyz&credential_type=OpenBadgeCredential&pre-authorized_code=eyJhbGciOiJFUzI1NiJ9.eyJjcmVkZW50aWFsX3R5cGUiOlsiT3BlbkJhZGdlQ3JlZGVudGlhbCJdLCJleHAiOiIyMDIzLTA0LTIwVDA5OjA0OjM2WiIsIm5vbmNlIjoibWFibmVpT0VSZVB3V3BuRFFweEt3UnRsVVRFRlhGUEwifQ.qOZRPN8sTv_knhp7WaWte2-aDULaPZX--2i9unF6QDQNUllqDhvxgIHMDCYHCV8O2_Gj-T2x1J84fDMajE3asg&user_pin_required=false',
|
|
112
113
|
request: {
|
|
113
|
-
|
|
114
|
-
format: '
|
|
114
|
+
type: 'OpenBadgeCredential',
|
|
115
|
+
format: 'jwt_vc',
|
|
115
116
|
proof: {
|
|
116
117
|
proof_type: 'jwt',
|
|
117
118
|
jwt: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlV6STFOa3NpTENKMWMyVWlPaUp6YVdjaUxDSnJkSGtpT2lKRlF5SXNJbU55ZGlJNkluTmxZM0F5TlRack1TSXNJbmdpT2lKclpuVmpTa0V0VEhKck9VWjBPRmx5TFVkMlQzSmpia3N3YjNkc2RqUlhNblUwU3pJeFNHZHZTVlIzSWl3aWVTSTZJalozY0ZCUE1rOUNRVXBTU0ZFMVRXdEtXVlJaV0dsQlJFUXdOMU5OTlV0amVXcDNYMkUzVUUxWmVGa2lmUSMwIn0.eyJhdWQiOiJodHRwczovL25naS1vaWRjNHZjaS10ZXN0LnNwcnVjZWlkLnh5eiIsImlhdCI6MTY4MTkxMTA2MC45NDIsImV4cCI6MTY4MTkxMTcyMC45NDIsImlzcyI6InNwaGVyZW9uOnNzaS13YWxsZXQiLCJqdGkiOiJhNjA4MzMxZi02ZmE0LTQ0ZjAtYWNkZWY5NmFjMjdmNmQ3MCJ9.NwF3_41gwnlIdd_6Uk9CczeQHzIQt6UcvTT5Cxv72j9S1vNwiY9annA2kLsjsTiR5-WMBdUhJCO7wYCtZ15mxw',
|
|
@@ -357,7 +358,7 @@ const mockData: VciMockDataStructure = {
|
|
|
357
358
|
url: 'https://jff.walt.id/issuer-api/default/oidc/credential',
|
|
358
359
|
request: {
|
|
359
360
|
types: ['OpenBadgeCredential'],
|
|
360
|
-
format: '
|
|
361
|
+
format: 'jwt_vc',
|
|
361
362
|
proof: {
|
|
362
363
|
proof_type: 'jwt',
|
|
363
364
|
jwt: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlV6STFOa3NpTENKMWMyVWlPaUp6YVdjaUxDSnJkSGtpT2lKRlF5SXNJbU55ZGlJNkluTmxZM0F5TlRack1TSXNJbmdpT2lKclpuVmpTa0V0VEhKck9VWjBPRmx5TFVkMlQzSmpia3N3YjNkc2RqUlhNblUwU3pJeFNHZHZTVlIzSWl3aWVTSTZJalozY0ZCUE1rOUNRVXBTU0ZFMVRXdEtXVlJaV0dsQlJFUXdOMU5OTlV0amVXcDNYMkUzVUUxWmVGa2lmUSMwIn0.eyJhdWQiOiJodHRwczovL2pmZi53YWx0LmlkL2lzc3Vlci1hcGkvZGVmYXVsdC9vaWRjLyIsImlhdCI6MTY4MTkxMTk0Mi4yMzgsImV4cCI6MTY4MTkxMjYwMi4yMzgsIm5vbmNlIjoiZjA2YTMxMDUtYTJlZC00NGZjLTk1NGItNGEyNTk3MDM0OTNiIiwiaXNzIjoic3BoZXJlb246c3NpLXdhbGxldCIsImp0aSI6IjA1OWM3ODA5LTlmOGYtNGE3ZS1hZDI4YTNhMTNhMGIzNmViIn0.RfiWyybxpe3nkx3b0yIsqDHQtvB1WwhDW4t0X-kijy2dsSfv2cYhSEmAzs1shg7OV4EW8fSzt_Te79xiVl6jCw',
|
|
@@ -514,7 +515,7 @@ const mockData: VciMockDataStructure = {
|
|
|
514
515
|
types: ['PermanentResidentCard'],
|
|
515
516
|
binding_methods_supported: ['did'],
|
|
516
517
|
cryptographic_suites_supported: ['Ed25519Signature2018'],
|
|
517
|
-
} as
|
|
518
|
+
} as CredentialSupportedFormatV1_0_08,
|
|
518
519
|
},
|
|
519
520
|
},
|
|
520
521
|
AcademicAward: {
|
|
@@ -525,7 +526,7 @@ const mockData: VciMockDataStructure = {
|
|
|
525
526
|
types: ['AcademicAward'],
|
|
526
527
|
binding_methods_supported: ['did'],
|
|
527
528
|
cryptographic_suites_supported: ['Ed25519Signature2018'],
|
|
528
|
-
} as
|
|
529
|
+
} as CredentialSupportedFormatV1_0_08,
|
|
529
530
|
},
|
|
530
531
|
},
|
|
531
532
|
LearnerProfile: {
|
|
@@ -536,7 +537,7 @@ const mockData: VciMockDataStructure = {
|
|
|
536
537
|
types: ['LearnerProfile'],
|
|
537
538
|
binding_methods_supported: ['did'],
|
|
538
539
|
cryptographic_suites_supported: ['Ed25519Signature2018'],
|
|
539
|
-
} as
|
|
540
|
+
} as CredentialSupportedFormatV1_0_08,
|
|
540
541
|
},
|
|
541
542
|
},
|
|
542
543
|
OpenBadgeCredential: {
|
|
@@ -547,7 +548,7 @@ const mockData: VciMockDataStructure = {
|
|
|
547
548
|
types: ['OpenBadgeCredential'],
|
|
548
549
|
binding_methods_supported: ['did'],
|
|
549
550
|
cryptographic_suites_supported: ['Ed25519Signature2018'],
|
|
550
|
-
} as
|
|
551
|
+
} as CredentialSupportedFormatV1_0_08,
|
|
551
552
|
},
|
|
552
553
|
},
|
|
553
554
|
},
|
|
@@ -573,8 +574,8 @@ const mockData: VciMockDataStructure = {
|
|
|
573
574
|
'openid-initiate-issuance://?issuer=https://launchpad.mattrlabs.com&credential_type=OpenBadgeCredential&pre-authorized_code=g0UCOj6RAN5AwHU6gczm_GzB4_lH6GW39Z0Dl2DOOiO',
|
|
574
575
|
url: 'https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/credential',
|
|
575
576
|
request: {
|
|
576
|
-
|
|
577
|
-
format: '
|
|
577
|
+
type: 'OpenBadgeCredential',
|
|
578
|
+
format: 'ldp_vc',
|
|
578
579
|
proof: {
|
|
579
580
|
proof_type: 'jwt',
|
|
580
581
|
jwt: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDprZXk6ejZNa3AxM3N6QUFMVFN0cDV1OGtMcnl5YW5vYWtrVWtFUGZXazdvOHY3dms0RW1KI3o2TWtwMTNzekFBTFRTdHA1dThrTHJ5eWFub2Fra1VrRVBmV2s3bzh2N3ZrNEVtSiJ9.eyJhdWQiOiJodHRwczovL2xhdW5jaHBhZC5tYXR0cmxhYnMuY29tIiwiaWF0IjoxNjgxOTE0NDgyLjUxOSwiZXhwIjoxNjgxOTE1MTQyLjUxOSwiaXNzIjoic3BoZXJlb246c3NpLXdhbGxldCIsImp0aSI6ImI5NDY1ZGE5LTY4OGYtNDdjNi04MjUwNDA0ZGNiOWI5Y2E5In0.uQ8ewOfIjy_1p_Gk6PjeEWccBJnjOca1pwbTWiCAFMQX9wlIsfeUdGtXUoHjH5_PQtpwytodx7WU456_CT9iBQ',
|
|
@@ -687,8 +688,8 @@ const mockData: VciMockDataStructure = {
|
|
|
687
688
|
'openid-initiate-issuance://?issuer=https://oidc4vc.diwala.io&credential_type=OpenBadgeCredential&pre-authorized_code=eyJhbGciOiJIUzI1NiJ9.eyJjcmVkZW50aWFsX3R5cGUiOiJPcGVuQmFkZ2VDcmVkZW50aWFsIiwiZXhwIjoxNjgxOTg0NDY3fQ.fEAHKz2nuWfiYHw406iNxr-81pWkNkbi31bWsYSf6Ng',
|
|
688
689
|
url: 'https://oidc4vc.diwala.io/credential',
|
|
689
690
|
request: {
|
|
690
|
-
|
|
691
|
-
format: '
|
|
691
|
+
type: 'OpenBadgeCredential',
|
|
692
|
+
format: 'ldp_vc',
|
|
692
693
|
proof: {
|
|
693
694
|
proof_type: 'jwt',
|
|
694
695
|
jwt: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDprZXk6ejZNa3AxM3N6QUFMVFN0cDV1OGtMcnl5YW5vYWtrVWtFUGZXazdvOHY3dms0RW1KI3o2TWtwMTNzekFBTFRTdHA1dThrTHJ5eWFub2Fra1VrRVBmV2s3bzh2N3ZrNEVtSiJ9.eyJhdWQiOiJodHRwczovL29pZGM0dmMuZGl3YWxhLmlvIiwiaWF0IjoxNjgxOTE1MDk1LjIwMiwiZXhwIjoxNjgxOTE1NzU1LjIwMiwiaXNzIjoic3BoZXJlb246c3NpLXdhbGxldCIsImp0aSI6IjYxN2MwM2EzLTM3MTUtNGJlMy1hYjkxNzM4MTlmYzYxNTYzIn0.KA-cHjecaYp9FSaWHkz5cqtNyhBIVT_0I7cJnpHn03T4UWFvdhjhn8Hpe-BU247enFyWOWJ6v3NQZyZgle7xBA',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/oid4vci-client",
|
|
3
|
-
"version": "0.8.2-
|
|
3
|
+
"version": "0.8.2-unstable.16+a504fb2",
|
|
4
4
|
"description": "OpenID for Verifiable Credential Issuance (OpenID4VCI) client",
|
|
5
5
|
"source": "lib/index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,13 +15,15 @@
|
|
|
15
15
|
"build": "tsc"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@sphereon/oid4vci-common": "0.8.2-
|
|
19
|
-
"@sphereon/ssi-types": "0.17.
|
|
18
|
+
"@sphereon/oid4vci-common": "0.8.2-unstable.16+a504fb2",
|
|
19
|
+
"@sphereon/ssi-types": "0.17.6-unstable.23",
|
|
20
20
|
"cross-fetch": "^3.1.8",
|
|
21
21
|
"debug": "^4.3.4"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
+
"@sphereon/ssi-sdk-ext.key-utils": "^0.15.1-next.7",
|
|
24
25
|
"@transmute/did-key.js": "^0.3.0-unstable.10",
|
|
26
|
+
"@trust/keyto": "^2.0.0-alpha1",
|
|
25
27
|
"@types/jest": "^29.5.3",
|
|
26
28
|
"@types/node": "^18.17.4",
|
|
27
29
|
"@types/uuid": "^9.0.6",
|
|
@@ -67,5 +69,5 @@
|
|
|
67
69
|
"OIDC4VCI",
|
|
68
70
|
"OID4VCI"
|
|
69
71
|
],
|
|
70
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "a504fb24a8d6127624e3e5497f1a6633e816253d"
|
|
71
73
|
}
|