@sd-jwt/core 0.3.2-next.94 → 0.3.2-next.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,7 +32,8 @@ Ensure you have Node.js installed as a prerequisite.
32
32
 
33
33
  ### Usage
34
34
 
35
- This library can not be used on it's own, it is a dependency for other implementations like `@sd-jwt/sd-jwt-vc`.
35
+ The library can be used to create sd-jwt based credentials. To be compliant with the `sd-jwt-vc` standard, you can use the `@sd-jwt/sd-jwt-vc` that is implementing this spec.
36
+ If you want to use the pure sd-jwt class or implement your own sd-jwt credential approach, you can use this library.
36
37
 
37
38
  ### Dependencies
38
39
 
package/dist/index.d.mts CHANGED
@@ -67,8 +67,8 @@ declare const pack: <T extends Record<string, unknown>>(claims: T, disclosureFra
67
67
  declare const createDecoy: (hash: HasherAndAlg, saltGenerator: SaltGenerator) => Promise<string>;
68
68
 
69
69
  type SdJwtPayload = Record<string, unknown>;
70
- declare abstract class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
71
- protected abstract type: string;
70
+ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
71
+ protected type?: string;
72
72
  static DEFAULT_hashAlg: string;
73
73
  private userConfig;
74
74
  constructor(userConfig?: SDJWTConfig);
@@ -78,7 +78,12 @@ declare abstract class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
78
78
  issue<Payload extends ExtendedPayload>(payload: Payload, disclosureFrame?: DisclosureFrame<Payload>, options?: {
79
79
  header?: object;
80
80
  }): Promise<SDJWTCompact>;
81
- protected abstract validateReservedFields<T extends ExtendedPayload>(disclosureFrame: DisclosureFrame<T>): void;
81
+ /**
82
+ * Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
83
+ * @param disclosureFrame
84
+ * @returns
85
+ */
86
+ protected validateReservedFields<T extends ExtendedPayload>(disclosureFrame: DisclosureFrame<T>): void;
82
87
  present(encodedSDJwt: string, presentationKeys?: string[], options?: {
83
88
  kb?: KBOptions;
84
89
  }): Promise<SDJWTCompact>;
package/dist/index.d.ts CHANGED
@@ -67,8 +67,8 @@ declare const pack: <T extends Record<string, unknown>>(claims: T, disclosureFra
67
67
  declare const createDecoy: (hash: HasherAndAlg, saltGenerator: SaltGenerator) => Promise<string>;
68
68
 
69
69
  type SdJwtPayload = Record<string, unknown>;
70
- declare abstract class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
71
- protected abstract type: string;
70
+ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
71
+ protected type?: string;
72
72
  static DEFAULT_hashAlg: string;
73
73
  private userConfig;
74
74
  constructor(userConfig?: SDJWTConfig);
@@ -78,7 +78,12 @@ declare abstract class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
78
78
  issue<Payload extends ExtendedPayload>(payload: Payload, disclosureFrame?: DisclosureFrame<Payload>, options?: {
79
79
  header?: object;
80
80
  }): Promise<SDJWTCompact>;
81
- protected abstract validateReservedFields<T extends ExtendedPayload>(disclosureFrame: DisclosureFrame<T>): void;
81
+ /**
82
+ * Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
83
+ * @param disclosureFrame
84
+ * @returns
85
+ */
86
+ protected validateReservedFields<T extends ExtendedPayload>(disclosureFrame: DisclosureFrame<T>): void;
82
87
  present(encodedSDJwt: string, presentationKeys?: string[], options?: {
83
88
  kb?: KBOptions;
84
89
  }): Promise<SDJWTCompact>;
package/dist/index.js CHANGED
@@ -489,6 +489,14 @@ var _SDJwtInstance = class _SDJwtInstance {
489
489
  return sdJwt.encodeSDJwt();
490
490
  });
491
491
  }
492
+ /**
493
+ * Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
494
+ * @param disclosureFrame
495
+ * @returns
496
+ */
497
+ validateReservedFields(disclosureFrame) {
498
+ return;
499
+ }
492
500
  present(encodedSDJwt, presentationKeys, options) {
493
501
  return __async(this, null, function* () {
494
502
  var _a;
package/dist/index.mjs CHANGED
@@ -469,6 +469,14 @@ var _SDJwtInstance = class _SDJwtInstance {
469
469
  return sdJwt.encodeSDJwt();
470
470
  });
471
471
  }
472
+ /**
473
+ * Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
474
+ * @param disclosureFrame
475
+ * @returns
476
+ */
477
+ validateReservedFields(disclosureFrame) {
478
+ return;
479
+ }
472
480
  present(encodedSDJwt, presentationKeys, options) {
473
481
  return __async(this, null, function* () {
474
482
  var _a;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sd-jwt/core",
3
- "version": "0.3.2-next.94+32af6cf",
3
+ "version": "0.3.2-next.95+a2daee4",
4
4
  "description": "sd-jwt draft 7 implementation in typescript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -14,10 +14,9 @@
14
14
  "scripts": {
15
15
  "build": "rm -rf **/dist && tsup",
16
16
  "lint": "biome lint ./src",
17
- "test": "pnpm run test:node && pnpm run test:browser && pnpm run test:e2e && pnpm run test:cov",
18
- "test:node": "vitest run ./src/test/*.spec.ts && vitest run ./src/test/*.spec.ts --environment jsdom",
17
+ "test": "pnpm run test:node && pnpm run test:browser && pnpm run test:cov",
18
+ "test:node": "vitest run ./src/test/*.spec.ts",
19
19
  "test:browser": "vitest run ./src/test/*.spec.ts --environment jsdom",
20
- "test:e2e": "vitest run ./test/*e2e.spec.ts --environment node",
21
20
  "test:cov": "vitest run --coverage"
22
21
  },
23
22
  "keywords": [
@@ -39,12 +38,12 @@
39
38
  },
40
39
  "license": "Apache-2.0",
41
40
  "devDependencies": {
42
- "@sd-jwt/crypto-nodejs": "0.3.2-next.94+32af6cf"
41
+ "@sd-jwt/crypto-nodejs": "0.3.2-next.95+a2daee4"
43
42
  },
44
43
  "dependencies": {
45
- "@sd-jwt/decode": "0.3.2-next.94+32af6cf",
46
- "@sd-jwt/types": "0.3.2-next.94+32af6cf",
47
- "@sd-jwt/utils": "0.3.2-next.94+32af6cf"
44
+ "@sd-jwt/decode": "0.3.2-next.95+a2daee4",
45
+ "@sd-jwt/types": "0.3.2-next.95+a2daee4",
46
+ "@sd-jwt/utils": "0.3.2-next.95+a2daee4"
48
47
  },
49
48
  "publishConfig": {
50
49
  "access": "public"
@@ -62,5 +61,5 @@
62
61
  "esm"
63
62
  ]
64
63
  },
65
- "gitHead": "32af6cfa150fceb440fc9225bcaf2791a6aeee90"
64
+ "gitHead": "a2daee4acc8def8b4d5871b36f740f0f5d50479d"
66
65
  }
package/src/index.ts CHANGED
@@ -19,9 +19,9 @@ export * from './decoy';
19
19
 
20
20
  export type SdJwtPayload = Record<string, unknown>;
21
21
 
22
- export abstract class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
22
+ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
23
23
  //header type
24
- protected abstract type: string;
24
+ protected type?: string;
25
25
 
26
26
  public static DEFAULT_hashAlg = 'sha-256';
27
27
 
@@ -127,9 +127,16 @@ export abstract class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
127
127
  return sdJwt.encodeSDJwt();
128
128
  }
129
129
 
130
- protected abstract validateReservedFields<T extends ExtendedPayload>(
130
+ /**
131
+ * Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
132
+ * @param disclosureFrame
133
+ * @returns
134
+ */
135
+ protected validateReservedFields<T extends ExtendedPayload>(
131
136
  disclosureFrame: DisclosureFrame<T>,
132
- ): void;
137
+ ) {
138
+ return;
139
+ }
133
140
 
134
141
  public async present(
135
142
  encodedSDJwt: string,
@@ -1,19 +1,9 @@
1
1
  import { SDJwtInstance, SdJwtPayload } from '../index';
2
- import { DisclosureFrame, Signer, Verifier } from '@sd-jwt/types';
2
+ import { Signer, Verifier } from '@sd-jwt/types';
3
3
  import Crypto from 'node:crypto';
4
4
  import { describe, expect, test } from 'vitest';
5
5
  import { digest, generateSalt } from '@sd-jwt/crypto-nodejs';
6
6
 
7
- export class TestInstance extends SDJwtInstance<SdJwtPayload> {
8
- protected type = 'sd-jwt';
9
-
10
- protected validateReservedFields(
11
- disclosureFrame: DisclosureFrame<SdJwtPayload>,
12
- ): void {
13
- return;
14
- }
15
- }
16
-
17
7
  export const createSignerVerifier = () => {
18
8
  const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
19
9
  const signer: Signer = async (data: string) => {
@@ -33,13 +23,13 @@ export const createSignerVerifier = () => {
33
23
 
34
24
  describe('index', () => {
35
25
  test('create', async () => {
36
- const sdjwt = new TestInstance();
26
+ const sdjwt = new SDJwtInstance<SdJwtPayload>();
37
27
  expect(sdjwt).toBeDefined();
38
28
  });
39
29
 
40
30
  test('kbJwt', async () => {
41
31
  const { signer, verifier } = createSignerVerifier();
42
- const sdjwt = new TestInstance({
32
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
43
33
  signer,
44
34
  signAlg: 'EdDSA',
45
35
  verifier,
@@ -77,7 +67,7 @@ describe('index', () => {
77
67
 
78
68
  test('issue', async () => {
79
69
  const { signer, verifier } = createSignerVerifier();
80
- const sdjwt = new TestInstance({
70
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
81
71
  signer,
82
72
  signAlg: 'EdDSA',
83
73
  verifier,
@@ -111,7 +101,7 @@ describe('index', () => {
111
101
  );
112
102
  };
113
103
 
114
- const sdjwt = new TestInstance({
104
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
115
105
  signer,
116
106
  signAlg: 'EdDSA',
117
107
  verifier: failedverifier,
@@ -149,7 +139,7 @@ describe('index', () => {
149
139
  Buffer.from(sig, 'base64url'),
150
140
  );
151
141
  };
152
- const sdjwt = new TestInstance({
142
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
153
143
  signer,
154
144
  signAlg: 'EdDSA',
155
145
  verifier,
@@ -191,7 +181,7 @@ describe('index', () => {
191
181
 
192
182
  test('verify with kbJwt', async () => {
193
183
  const { signer, verifier } = createSignerVerifier();
194
- const sdjwt = new TestInstance({
184
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
195
185
  signer,
196
186
  signAlg: 'EdDSA',
197
187
  verifier,
@@ -229,7 +219,7 @@ describe('index', () => {
229
219
  });
230
220
 
231
221
  test('Hasher not found', async () => {
232
- const sdjwt = new TestInstance({});
222
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({});
233
223
  try {
234
224
  const credential = await sdjwt.issue(
235
225
  {
@@ -250,7 +240,7 @@ describe('index', () => {
250
240
  });
251
241
 
252
242
  test('SaltGenerator not found', async () => {
253
- const sdjwt = new TestInstance({
243
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
254
244
  hasher: digest,
255
245
  });
256
246
  try {
@@ -273,7 +263,7 @@ describe('index', () => {
273
263
  });
274
264
 
275
265
  test('Signer not found', async () => {
276
- const sdjwt = new TestInstance({
266
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
277
267
  hasher: digest,
278
268
  saltGenerator: generateSalt,
279
269
  });
@@ -298,7 +288,7 @@ describe('index', () => {
298
288
 
299
289
  test('Verifier not found', async () => {
300
290
  const { signer, verifier } = createSignerVerifier();
301
- const sdjwt = new TestInstance({
291
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
302
292
  signer,
303
293
  hasher: digest,
304
294
  saltGenerator: generateSalt,
@@ -338,7 +328,7 @@ describe('index', () => {
338
328
 
339
329
  test('kbSigner not found', async () => {
340
330
  const { signer, verifier } = createSignerVerifier();
341
- const sdjwt = new TestInstance({
331
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
342
332
  signer,
343
333
  verifier,
344
334
  hasher: digest,
@@ -376,7 +366,7 @@ describe('index', () => {
376
366
 
377
367
  test('kbVerifier not found', async () => {
378
368
  const { signer, verifier } = createSignerVerifier();
379
- const sdjwt = new TestInstance({
369
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
380
370
  signer,
381
371
  verifier,
382
372
  hasher: digest,
@@ -416,7 +406,7 @@ describe('index', () => {
416
406
 
417
407
  test('kbSignAlg not found', async () => {
418
408
  const { signer, verifier } = createSignerVerifier();
419
- const sdjwt = new TestInstance({
409
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
420
410
  signer,
421
411
  verifier,
422
412
  hasher: digest,
@@ -440,7 +430,6 @@ describe('index', () => {
440
430
  const presentation = sdjwt.present(credential, ['foo'], {
441
431
  kb: {
442
432
  payload: {
443
- sd_hash: 'sha-256',
444
433
  aud: '1',
445
434
  iat: 1,
446
435
  nonce: '342',
@@ -452,8 +441,56 @@ describe('index', () => {
452
441
  );
453
442
  });
454
443
 
455
- test('hasher is not found', () => {
456
- const sdjwt = new TestInstance({});
444
+ test('hasher is not found', async () => {
445
+ const { signer } = createSignerVerifier();
446
+ const sdjwt_create = new SDJwtInstance<SdJwtPayload>({
447
+ signer,
448
+ hasher: digest,
449
+ saltGenerator: generateSalt,
450
+ signAlg: 'EdDSA',
451
+ });
452
+ const credential = await sdjwt_create.issue(
453
+ {
454
+ foo: 'bar',
455
+ iss: 'Issuer',
456
+ iat: new Date().getTime(),
457
+ vct: '',
458
+ },
459
+ {
460
+ _sd: ['foo'],
461
+ },
462
+ );
463
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({});
457
464
  expect(sdjwt.keys('')).rejects.toThrow('Hasher not found');
465
+ expect(sdjwt.presentableKeys('')).rejects.toThrow('Hasher not found');
466
+ expect(sdjwt.getClaims('')).rejects.toThrow('Hasher not found');
467
+ expect(() => sdjwt.decode('')).toThrowError('Hasher not found');
468
+ expect(sdjwt.present(credential, ['foo'])).rejects.toThrow(
469
+ 'Hasher not found',
470
+ );
471
+ });
472
+
473
+ test('presentableKeys', async () => {
474
+ const { signer } = createSignerVerifier();
475
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
476
+ signer,
477
+ hasher: digest,
478
+ saltGenerator: generateSalt,
479
+ signAlg: 'EdDSA',
480
+ });
481
+ const credential = await sdjwt.issue(
482
+ {
483
+ foo: 'bar',
484
+ iss: 'Issuer',
485
+ iat: new Date().getTime(),
486
+ vct: '',
487
+ },
488
+ {
489
+ _sd: ['foo'],
490
+ },
491
+ );
492
+ const keys = await sdjwt.presentableKeys(credential);
493
+ expect(keys).toBeDefined();
494
+ expect(keys).toEqual(['foo']);
458
495
  });
459
496
  });
@@ -1,11 +1,10 @@
1
1
  import Crypto from 'node:crypto';
2
- import { SdJwtPayload } from '../src';
3
- import { DisclosureFrame, SD, Signer, Verifier } from '@sd-jwt/types';
2
+ import { SDJwtInstance, SdJwtPayload } from '../src';
3
+ import { DisclosureFrame, Signer, Verifier } from '@sd-jwt/types';
4
4
  import fs from 'fs';
5
5
  import path from 'path';
6
6
  import { describe, expect, test } from 'vitest';
7
7
  import { digest, generateSalt } from '@sd-jwt/crypto-nodejs';
8
- import { TestInstance } from '../src/test/index.spec';
9
8
 
10
9
  export const createSignerVerifier = () => {
11
10
  const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
@@ -27,7 +26,7 @@ export const createSignerVerifier = () => {
27
26
  describe('App', () => {
28
27
  test('Example', async () => {
29
28
  const { signer, verifier } = createSignerVerifier();
30
- const sdjwt = new TestInstance({
29
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
31
30
  signer,
32
31
  signAlg: 'EdDSA',
33
32
  verifier,
@@ -193,7 +192,7 @@ describe('App', () => {
193
192
  async function JSONtest(filename: string) {
194
193
  const test = loadTestJsonFile(filename);
195
194
  const { signer, verifier } = createSignerVerifier();
196
- const sdjwt = new TestInstance({
195
+ const sdjwt = new SDJwtInstance<SdJwtPayload>({
197
196
  signer,
198
197
  signAlg: 'EdDSA',
199
198
  verifier,
@@ -210,7 +209,7 @@ async function JSONtest(filename: string) {
210
209
 
211
210
  expect(validated).toBeDefined();
212
211
  expect(validated).toStrictEqual({
213
- header: { alg: 'EdDSA', typ: 'sd-jwt' },
212
+ header: { alg: 'EdDSA' },
214
213
  payload: test.claims,
215
214
  });
216
215
 
@@ -229,7 +228,7 @@ async function JSONtest(filename: string) {
229
228
 
230
229
  expect(verified).toBeDefined();
231
230
  expect(verified).toStrictEqual({
232
- header: { alg: 'EdDSA', typ: 'sd-jwt' },
231
+ header: { alg: 'EdDSA' },
233
232
  payload: test.claims,
234
233
  });
235
234
  }