Skip to content

Commit

Permalink
fix: make sdjwt instance non abstract (#122)
Browse files Browse the repository at this point in the history
Signed-off-by: Mirko Mollik <[email protected]>
  • Loading branch information
cre8 committed Mar 8, 2024
1 parent 3415550 commit e85aae8
Show file tree
Hide file tree
Showing 23 changed files with 727 additions and 64 deletions.
36 changes: 36 additions & 0 deletions examples/sd-jwt-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SD JWT Core Examples

This directory contains example of basic usage(issue, validate, present, verify) of SD JWT

## Run the example

```bash
pnpm run {example_file_name}

# example
pnpm run all
```

### Example lists

- basic: Example of basic usage(issue, validate, present, verify) of SD JWT
- all: Example of issue, present and verify the comprehensive data.
- custom: Example of using custom hasher and salt generator for SD JWT
- custom_header: Example of using custom header for SD JWT
- sdjwtobject: Example of using SD JWT Object
- decoy: Example of adding decoy digest in SD JWT
- kb: key binding example in SD JWT
- decode: Decoding example of a SD JWT sample

### Variables In Examples

- claims: the user's information
- disclosureFrame: specify which claims should be disclosed
- credential: Issued Encoded SD JWT.
- validated: result of SD JWT validation
- presentationFrame: specify which claims should be presented
- presentation: Presented Encoded SD JWT.
- requiredClaims: specify which claims should be verified
- verified: result of verification
- sdJwtToken: SD JWT Token Object
- SDJwtInstance: SD JWT Instance
105 changes: 105 additions & 0 deletions examples/sd-jwt-example/all.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { SDJwtInstance } from '@sd-jwt/core';
import { DisclosureFrame } from '@sd-jwt/types';
import { createSignerVerifier, digest, generateSalt } from './utils';

(async () => {
const { signer, verifier } = await createSignerVerifier();

// Create SDJwt instance for use
const sdjwt = new SDJwtInstance({
signer,
verifier,
signAlg: 'EdDSA',
hasher: digest,
hashAlg: 'SHA-256',
saltGenerator: generateSalt,
});

// Issuer Define the claims object with the user's information
const claims = {
firstname: 'John',
lastname: 'Doe',
ssn: '123-45-6789',
id: '1234',
data: {
firstname: 'John',
lastname: 'Doe',
ssn: '123-45-6789',
list: [{ r: '1' }, 'b', 'c'],
},
data2: {
hi: 'bye',
},
};

// Issuer Define the disclosure frame to specify which claims can be disclosed
const disclosureFrame: DisclosureFrame<typeof claims> = {
_sd: ['firstname', 'id', 'data2'],
data: {
_sd: ['list'],
_sd_decoy: 2,
list: {
_sd: [0, 2],
_sd_decoy: 1,
0: {
_sd: ['r'],
},
},
},
data2: {
_sd: ['hi'],
},
};

// Issue a signed JWT credential with the specified claims and disclosures
// Return a Encoded SD JWT. Issuer send the credential to the holder
const credential = await sdjwt.issue(claims, disclosureFrame);
console.log('encodedJwt:', credential);

// Holder Receive the credential from the issuer and validate it
// Return a boolean result
const validated = await sdjwt.validate(credential);
console.log('validated:', validated);

// You can decode the SD JWT to get the payload and the disclosures
const sdJwtToken = await sdjwt.decode(credential);

// You can get the keys of the claims from the decoded SD JWT
const keys = await sdJwtToken.keys(digest);
console.log({ keys });

// You can get the claims from the decoded SD JWT
const payloads = await sdJwtToken.getClaims(digest);

// You can get the presentable keys from the decoded SD JWT
const presentableKeys = await sdJwtToken.presentableKeys(digest);

console.log({
payloads: JSON.stringify(payloads, null, 2),
disclosures: JSON.stringify(sdJwtToken.disclosures, null, 2),
claim: JSON.stringify(sdJwtToken.jwt?.payload, null, 2),
presentableKeys,
});

console.log(
'================================================================',
);

// Holder Define the presentation frame to specify which claims should be presented
// The list of presented claims must be a subset of the disclosed claims
// the presentation frame is determined by the verifier or the protocol that was agreed upon between the holder and the verifier
const presentationFrame = ['firstname', 'id'];

// Create a presentation using the issued credential and the presentation frame
// return a Encoded SD JWT. Holder send the presentation to the verifier
const presentation = await sdjwt.present(credential, presentationFrame);
console.log('presentedSDJwt:', presentation);

// Verifier Define the required claims that need to be verified in the presentation
const requiredClaims = ['firstname', 'id', 'data.ssn'];

// Verify the presentation using the public key and the required claims
// return a boolean result
const verified = await sdjwt.verify(credential, requiredClaims);
console.log('verified:', verified);
})();
55 changes: 55 additions & 0 deletions examples/sd-jwt-example/basic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { SDJwtInstance } from '@sd-jwt/core';
import { DisclosureFrame } from '@sd-jwt/types';
import { createSignerVerifier, digest, generateSalt } from './utils';

(async () => {
const { signer, verifier } = await createSignerVerifier();

// Create SDJwt instance for use
const sdjwt = new SDJwtInstance({
signer,
verifier,
signAlg: 'EdDSA',
hasher: digest,
hashAlg: 'SHA-256',
saltGenerator: generateSalt,
});

// Issuer Define the claims object with the user's information
const claims = {
firstname: 'John',
lastname: 'Doe',
ssn: '123-45-6789',
id: '1234',
};

// Issuer Define the disclosure frame to specify which claims can be disclosed
const disclosureFrame: DisclosureFrame<typeof claims> = {
_sd: ['firstname', 'lastname', 'ssn'],
};

// Issue a signed JWT credential with the specified claims and disclosures
// Return a Encoded SD JWT. Issuer send the credential to the holder
const credential = await sdjwt.issue(claims, disclosureFrame);

// Holder Receive the credential from the issuer and validate it
// Return a boolean result
const valid = await sdjwt.validate(credential);

// Holder Define the presentation frame to specify which claims should be presented
// The list of presented claims must be a subset of the disclosed claims
// the presentation frame is determined by the verifier or the protocol that was agreed upon between the holder and the verifier
const presentationFrame = ['firstname', 'ssn'];

// Create a presentation using the issued credential and the presentation frame
// return a Encoded SD JWT. Holder send the presentation to the verifier
const presentation = await sdjwt.present(credential, presentationFrame);

// Verifier Define the required claims that need to be verified in the presentation
const requiredClaims = ['firstname', 'ssn', 'id'];

// Verify the presentation using the public key and the required claims
// return a boolean result
const verified = await sdjwt.verify(presentation, requiredClaims);
console.log(verified);
})();
82 changes: 82 additions & 0 deletions examples/sd-jwt-example/custom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { SDJwtInstance } from '@sd-jwt/core';
import { DisclosureFrame } from '@sd-jwt/types';
import { createSignerVerifier, digest, generateSalt } from './utils';

(async () => {
const { signer, verifier } = await createSignerVerifier();

// Create SDJwt instance for use
const sdjwt = new SDJwtInstance({
signer,
verifier,
signAlg: 'EdDSA',
hasher: digest,
hashAlg: 'SHA-256',
saltGenerator: generateSalt,
});

// Issuer Define the claims object with the user's information
const claims = {
firstname: 'John',
lastname: 'Doe',
ssn: '123-45-6789',
id: '1234',
};

// Issuer Define the disclosure frame to specify which claims can be disclosed
const disclosureFrame: DisclosureFrame<typeof claims> = {
_sd: ['firstname', 'id'],
};

// Issue a signed JWT credential with the specified claims and disclosures
// Return a Encoded SD JWT. Issuer send the credential to the holder
const credential = await sdjwt.issue(claims, disclosureFrame);
console.log('encodedJwt:', credential);

// Holder Receive the credential from the issuer and validate it
// Return a boolean result
const validated = await sdjwt.validate(credential);
console.log('validated:', validated);

// You can decode the SD JWT to get the payload and the disclosures
const sdJwtToken = await sdjwt.decode(credential);

// You can get the keys of the claims from the decoded SD JWT
const keys = await sdJwtToken.keys(digest);
console.log({ keys });

// You can get the claims from the decoded SD JWT
const payloads = await sdJwtToken.getClaims(digest);

// You can get the presentable keys from the decoded SD JWT
const presentableKeys = await sdJwtToken.presentableKeys(digest);

console.log({
payloads: JSON.stringify(payloads, null, 2),
disclosures: JSON.stringify(sdJwtToken.disclosures, null, 2),
claim: JSON.stringify(sdJwtToken.jwt?.payload, null, 2),
presentableKeys,
});

console.log(
'================================================================',
);

// Holder Define the presentation frame to specify which claims should be presented
// The list of presented claims must be a subset of the disclosed claims
// the presentation frame is determined by the verifier or the protocol that was agreed upon between the holder and the verifier
const presentationFrame = ['firstname', 'id'];

// Create a presentation using the issued credential and the presentation frame
// return a Encoded SD JWT. Holder send the presentation to the verifier
const presentation = await sdjwt.present(credential, presentationFrame);
console.log('presentedSDJwt:', presentation);

// Verifier Define the required claims that need to be verified in the presentation
const requiredClaims = ['firstname', 'id'];

// Verify the presentation using the public key and the required claims
// return a boolean result
const verified = await sdjwt.verify(presentation, requiredClaims);
console.log('verified:', verified);
})();
41 changes: 41 additions & 0 deletions examples/sd-jwt-example/custom_header.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { SDJwtInstance } from '@sd-jwt/core';
import { DisclosureFrame } from '@sd-jwt/types';
import { createSignerVerifier, digest, generateSalt } from './utils';

(async () => {
const { signer, verifier } = await createSignerVerifier();

// Create SDJwt instance for use
const sdjwt = new SDJwtInstance({
signer,
verifier,
signAlg: 'EdDSA',
hasher: digest,
hashAlg: 'SHA-256',
saltGenerator: generateSalt,
});

// Issuer Define the claims object with the user's information
const claims = {
firstname: 'John',
lastname: 'Doe',
ssn: '123-45-6789',
id: '1234',
};

// Issuer Define the disclosure frame to specify which claims can be disclosed
const disclosureFrame: DisclosureFrame<typeof claims> = {
_sd: ['firstname', 'id'],
};

// Issue a signed JWT credential with the specified claims and disclosures
// Return a Encoded SD JWT. Issuer send the credential to the holder
const credential = await sdjwt.issue(claims, disclosureFrame, {
header: { typ: 'vc+sd-jwt', custom: 'data' }, // You can add custom header data to the SD JWT
});
console.log('encodedSdjwt:', credential);

// You can check the custom header data by decoding the SD JWT
const sdJwtToken = await sdjwt.decode(credential);
console.log(sdJwtToken);
})();
27 changes: 27 additions & 0 deletions examples/sd-jwt-example/decode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { SDJwtInstance } from '@sd-jwt/core';
import { createSignerVerifier, digest, generateSalt } from './utils';

(async () => {
const { signer, verifier } = await createSignerVerifier();

// Create SDJwt instance for use
const sdjwt = new SDJwtInstance({
signer,
signAlg: 'EdDSA',
verifier,
hasher: digest,
saltGenerator: generateSalt,
kbSigner: signer,
kbSignAlg: 'EdDSA',
kbVerifier: verifier,
});

// this is an example of SD JWT
const data =
'eyJhbGciOiAiRVMyNTYiLCAia2lkIjogImRvYy1zaWduZXItMDUtMjUtMjAyMiIsICJ0eXAiOiAidmMrc2Qtand0In0.eyJfc2QiOiBbIjA5dktySk1PbHlUV00wc2pwdV9wZE9CVkJRMk0xeTNLaHBINTE1blhrcFkiLCAiMnJzakdiYUMwa3k4bVQwcEpyUGlvV1RxMF9kYXcxc1g3NnBvVWxnQ3diSSIsICJFa084ZGhXMGRIRUpidlVIbEVfVkNldUM5dVJFTE9pZUxaaGg3WGJVVHRBIiwgIklsRHpJS2VpWmREd3BxcEs2WmZieXBoRnZ6NUZnbldhLXNONndxUVhDaXciLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiamRyVEU4WWNiWTRFaWZ1Z2loaUFlX0JQZWt4SlFaSUNlaVVRd1k5UXF4SSIsICJqc3U5eVZ1bHdRUWxoRmxNXzNKbHpNYVNGemdsaFFHMERwZmF5UXdMVUs0Il0sICJpc3MiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9pc3N1ZXIiLCAiaWF0IjogMTY4MzAwMDAwMCwgImV4cCI6IDE4ODMwMDAwMDAsICJkY3QiOiAiaHR0cHM6Ly9jcmVkZW50aWFscy5leGFtcGxlLmNvbS9pZGVudGl0eV9jcmVkZW50aWFsIiwgIl9zZF9hbGciOiAic2hhLTI1NiIsICJjbmYiOiB7Imp3ayI6IHsia3R5IjogIkVDIiwgImNydiI6ICJQLTI1NiIsICJ4IjogIlRDQUVSMTladnUzT0hGNGo0VzR2ZlNWb0hJUDFJTGlsRGxzN3ZDZUdlbWMiLCAieSI6ICJaeGppV1diWk1RR0hWV0tWUTRoYlNJaXJzVmZ1ZWNDRTZ0NGpUOUYySFpRIn19fQ.b036DutqQ72WszrCq0GuqZnbws3MApQyzA41I5DSJmenUfsADtqW8FbI_N04FP1wZDF_JtV6a6Ke3Z7apkoTLA~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgInBob25lX251bWJlciIsICIrMS0yMDItNTU1LTAxMDEiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyJBSngtMDk1VlBycFR0TjRRTU9xUk9BIiwgImJpcnRoZGF0ZSIsICIxOTQwLTAxLTAxIl0~WyJQYzMzSk0yTGNoY1VfbEhnZ3ZfdWZRIiwgImlzX292ZXJfMTgiLCB0cnVlXQ~WyJHMDJOU3JRZmpGWFE3SW8wOXN5YWpBIiwgImlzX292ZXJfMjEiLCB0cnVlXQ~WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgImlzX292ZXJfNjUiLCB0cnVlXQ~';
const decodedObject = await sdjwt.decode(data);
console.log(decodedObject);

const claims = await sdjwt.getClaims(data);
console.log(claims);
})();
35 changes: 35 additions & 0 deletions examples/sd-jwt-example/decoy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { SDJwtInstance } from '@sd-jwt/core';
import { DisclosureFrame } from '@sd-jwt/types';
import { createSignerVerifier, digest, generateSalt } from './utils';

(async () => {
const { signer, verifier } = await createSignerVerifier();

// Create SDJwt instance for use
const sdjwt = new SDJwtInstance({
signer,
verifier,
signAlg: 'EdDSA',
hasher: digest,
hashAlg: 'SHA-256',
saltGenerator: generateSalt,
});
// Issuer Define the claims object with the user's information
const claims = {
lastname: 'Doe',
ssn: '123-45-6789',
id: '1234',
};

// Issuer Define the disclosure frame to specify which claims can be disclosed
const disclosureFrame: DisclosureFrame<typeof claims> = {
_sd: ['id'],
_sd_decoy: 1, // 1 decoy digest will be added in SD JWT
};
const credential = await sdjwt.issue(claims, disclosureFrame);
console.log('encodedSdjwt:', credential);

// You can check the decoy digest in the SD JWT by decoding it
const sdJwtToken = await sdjwt.decode(credential);
console.log(sdJwtToken);
})();
Loading

0 comments on commit e85aae8

Please sign in to comment.