Skip to content

Commit

Permalink
Added Credential Manifest Types
Browse files Browse the repository at this point in the history
  • Loading branch information
nitro-neal committed Aug 7, 2023
1 parent 9cee9c9 commit c43748c
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 8 deletions.
131 changes: 124 additions & 7 deletions packages/credentials/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import type { ICredential, IIssuer, ICredentialSubject, ICredentialSchemaType } from '@sphereon/ssi-types';
import type { PresentationDefinitionV2 } from '@sphereon/pex-models';
import type { ICredential, IIssuer, ICredentialSubject, ICredentialSchemaType, ICredentialStatus} from '@sphereon/ssi-types';
import type { PresentationDefinitionV2, InputDescriptorV2 } from '@sphereon/pex-models';
import type { IPresentation, PresentationSubmission as PexPresentationSubmission, Descriptor, JwtDecodedVerifiableCredential as PexJwtDecodedVc, JwtDecodedVerifiablePresentation as PexJwtDecodedPres } from '@sphereon/ssi-types';
import type { PresentationResult as PexPR } from '@sphereon/pex/dist/main/lib/signing';

import { PEXv2, EvaluationResults as ER } from '@sphereon/pex';

const pex = new PEXv2();


/** Presentation Exchange */

/**
* A Verifiable Credential is a set of one or more claims made by the same entity.
*
* @see {@link https://www.w3.org/TR/vc-data-model/#credentials | VC data model}
* @see {@link https://www.w3.org/TR/vc-data-model/#credentials | VC Data Model}
*/
export type VerifiableCredential = ICredential;

Expand All @@ -22,14 +25,14 @@ export type JwtDecodedVerifiableCredential = PexJwtDecodedVc;
/**
* Credential Schema Types are useful when enforcing a specific structure on a given collection of data.
*
* @see {@link https://www.w3.org/TR/vc-data-model/#data-schemas | Data schemas}
* @see {@link https://www.w3.org/TR/vc-data-model/#data-schemas | Data Schemas}
*/
export type CredentialSchemaType = ICredentialSchemaType;

/**
* Issuer: The acting Entity issuing a Verifiable Credential.
* Issuer: The acting Entity issuing a Verifiable Credential. The value of the issuer property must be either a URI or an object containing an `id` property.
*
* @see {@link https://www.w3.org/TR/vc-data-model/#issuer | Issuer data model}
* @see {@link https://www.w3.org/TR/vc-data-model/#issuer | Issuer Data Model}
*/
export type Issuer = IIssuer;

Expand All @@ -40,6 +43,14 @@ export type Issuer = IIssuer;
*/
export type CredentialSubject = ICredentialSubject;

/**
* Used for the discovery of information about the current status of a verifiable credential, such as whether it is
* suspended or revoked.
*
* @see {@link https://www.w3.org/TR/vc-data-model/#status | Credential Status}
*/
export type CredentialStatus = ICredentialStatus;

/**
* Presentation Definition: Outlines the requirements Verifiers have for Proofs.
*
Expand Down Expand Up @@ -103,4 +114,110 @@ export const evaluatePresentation = (presentationDefinition: PresentationDefinit
*/
export const presentationFrom = (presentationDefinition: PresentationDefinitionV2, verifiableCredentials: string[]): PresentationResult => {
return pex.presentationFrom(presentationDefinition, verifiableCredentials);
};
};


/** Credential Manifest */

/**
* Input Descriptors are objects used to describe the information a Verifier requires of a Holder. All Input Descriptors MUST be satisfied, unless otherwise specified by a Feature.
*
* See {@link https://identity.foundation/presentation-exchange/#input-descriptor-object | Input Descriptor}
*/
export type InputDescriptor = InputDescriptorV2

/**
* See {@link https://identity.foundation/wallet-rendering/v0.0.1/#entity-styles | Entity Styles}
*/
export type EntityStyle = {
thumbnail?: Image
hero?: Image
background?: Colorable
text?: Colorable
}

export type Image = {
/** Valid URI string to an image resource */
uri: string;
/** String that describes the alternate text for the image */
alt?: string;
}

export type Colorable = {
/** HEX string color value */
color?: string
}

/**
* See {@link https://identity.foundation/credential-manifest/#output-descriptor | Output Descriptor}
*/
export type OutputDescriptor = {
/** String that does not conflict with the `id` of another OutputDescriptor in the same CredentialManifest */
id: string;
/** String specifying the schema of the credential to be issued */
schema: string;
/** Human-readable string that describes what the credential represents */
name?: string;
/** Human-readable string that descripbes what the credential is in greater detail */
description?: string;
/** Object or URI of the {@link https://identity.foundation/wallet-rendering/v0.0.1/#entity-styles | Entity Style} to render the OutputDescriptor */
styles?: EntityStyle | string;
/** Object or URI of the {@link https://identity.foundation/wallet-rendering/v0.0.1/#display-mapping-object | Display Mapping} used to pull data from the target Claim */
display?: DisplayMapping | string;
}

/** See {@link https://identity.foundation/wallet-rendering/v0.0.1/#display-mapping-object | Display Mapping Object} */
export type DisplayMapping = {
/** Array of JSONPath string expressions */
path: string[];
schema: {
/** Represents the type of data found with the `path` property */
type: 'string' | 'boolean' | 'number' | 'integer';
/** If the `type` property is "string", this property is used to format the string in any rendered UI */
format?: 'date-time' | 'time' | 'date' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' |
'ipv4' | 'ipv6' | 'uri' | 'uri-reference' | 'iri' | 'iri-reference';
}
/**
* String to be rendered into the UI if all the `path` property's item's value is
* undefined OR incorrectly processed
*/
fallback?: string;
}

/** See {@link https://identity.foundation/presentation-exchange/#presentation-definition | Presentation Definiton}'s `format` property */
export type Format = {
[key: string]: any;
}

/** See {@link https://identity.foundation/presentation-exchange/#input-descriptor-object | Input Descriptor}'s `constraints.fields.filter` property */
export type Filter = {
[key: string]: any;
}

/**
* Credential Manifests are a resource format that defines preconditional requirements, Issuer style preferences, and other facets User Agents
* utilize to help articulate and select the inputs necessary for processing and issuance of a specified credential.
*
* See {@link https://identity.foundation/credential-manifest/#credential-manifest | Credential Manifest}
*/
export type CredentialManifest = {
/** String providing a unique identifier for the desired context */
id: string;
/** String that acts as a summarizing title for the CredentialManifest */
name?: string;
/**
* String explaining what the CredentialManifest is generally offering for meeting
* its requirements
*/
description?: string;
spec_version?: string;
issuer: Issuer;
/** Output Descriptors are used by an Issuer to describe the credentials they are offering to a Holder. See Output Descriptor */
output_descriptors: OutputDescriptor[];
format?: Format
/**
* Presentation Exchange is a specification codifying a Presentation Definition data format Verifiers can use to articulate proof
* requirements in a Presentation Request, and a Presentation Submission data format Holders can use to describe proofs submitted in accordance with them.
*/
presentation_definition?: PresentationDefinition;
}
154 changes: 154 additions & 0 deletions packages/credentials/tests/credentialmanifest.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { expect } from 'chai';
import { Issuer, CredentialManifest, OutputDescriptor, InputDescriptor } from '../src/types.js';

describe('Credential Manifest Types', () => {
it('creates an Output Descriptor', () => {
const outputDescriptor: OutputDescriptor = {
id : 'example-id',
schema : 'example-schema',
name : 'Output Descriptor Name',
description : 'Output Descriptor Description',
styles : {
thumbnail: {
uri : 'https://example.com/image.png',
alt : 'image'
},
background: {
color: '#ffffff'
}
},
display: {
path : ['$.example'],
schema : {
type : 'string',
format : 'date-time'
},
fallback: 'N/A'
}
};

expect(outputDescriptor).to.have.property('id');
expect(outputDescriptor).to.have.property('schema');
expect(outputDescriptor).to.have.property('name');
expect(outputDescriptor).to.have.property('description');
expect(outputDescriptor).to.have.property('styles');
expect(outputDescriptor.styles).to.have.property('thumbnail');
expect(outputDescriptor.styles).to.have.property('background');
expect(outputDescriptor).to.have.property('display');
expect(outputDescriptor.display).to.have.property('path');
expect(outputDescriptor.display).to.have.property('schema');
expect(outputDescriptor.display).to.have.property('fallback');
});

it('creates a Credential Manifest', () => {
const issuer: Issuer = {
id: 'did:example:123456'
};

const inputDescriptor: InputDescriptor = {
id : 'input-example',
name : 'Input Name',
purpose : 'Input Purpose',
group : ['group1'],
};

const credentialManifest: CredentialManifest = {
id : 'manifest-id',
name : 'Credential Manifest Name',
description : 'Credential Manifest Description',
spec_version : '1.0.0',
issuer : issuer,
output_descriptors : [{
id : 'output-example',
schema : 'schema-example'
}],
format : { key: 'value' },
presentation_definition : {
id : 'pd-id',
input_descriptors : [
inputDescriptor
]
}
};

expect(credentialManifest).to.have.property('id');
expect(credentialManifest).to.have.property('name');
expect(credentialManifest).to.have.property('description');
expect(credentialManifest).to.have.property('spec_version');
expect(credentialManifest).to.have.property('issuer');
expect(credentialManifest).to.have.property('output_descriptors');
expect(credentialManifest.output_descriptors[0]).to.have.property('id');
expect(credentialManifest.output_descriptors[0]).to.have.property('schema');
expect(credentialManifest).to.have.property('format');
expect(credentialManifest.format).to.have.property('key');
expect(credentialManifest).to.have.property('presentation_definition');
expect(credentialManifest.presentation_definition).to.have.property('id');
expect(credentialManifest.presentation_definition).to.have.property('input_descriptors');
expect(credentialManifest.presentation_definition!.input_descriptors[0]).to.have.property('id');
});

it('creates a Credential Manifest with a single Input Descriptor', () => {
const outputDescriptor: OutputDescriptor = {
'id' : 'driver_license_output',
'schema' : 'https://schema.org/EducationalOccupationalCredential',
'name' : 'Washington State Driver License',
'description' : 'License to operate a vehicle with a gross combined weight rating (GCWR) of 26,001 or more pounds, as long as the GVWR of the vehicle(s) being towed is over 10,000 pounds.',
'styles' : {
'thumbnail': {
'uri' : 'https://dol.wa.com/logo.png',
'alt' : 'Washington State Seal'
},
'hero': {
'uri' : 'https://dol.wa.com/happy-people-driving.png',
'alt' : 'Happy people driving'
},
'background': {
'color': '#ff0000'
},
'text': {
'color': '#d4d400'
}
},
'display': {
'path' : ['$.name', '$.vc.name'],
'schema' : {
'type': 'string'
},
'fallback': 'Washington State Driver License'
}
};

const credentialManifest: CredentialManifest = {
'id' : 'WA-DL-CLASS-A',
'spec_version' : 'https://identity.foundation/credential-manifest/spec/v1.0.0/',
'issuer' : {
'id' : 'did:example:123?linked-domains=3',
'name' : 'Washington State Government',
'styles' : {
'thumbnail': {
'uri' : 'https://dol.wa.com/logo.png',
'alt' : 'Washington State Seal'
},
'hero': {
'uri' : 'https://dol.wa.com/people-working.png',
'alt' : 'People working on serious things'
},
'background': {
'color': '#ff0000'
},
'text': {
'color': '#d4d400'
}
}
},
'output_descriptors': [
outputDescriptor
]
};

expect(credentialManifest).to.have.property('id');
expect(credentialManifest).to.have.property('spec_version');
expect(credentialManifest).to.have.property('issuer');
expect(credentialManifest).to.have.property('output_descriptors');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if (!globalThis.crypto) globalThis.crypto = webcrypto;

let testAgent: TestAgent;

describe('PresentationExchange', () => {
describe('Presentation Exchange Types', () => {
before(async () => {
testAgent = await TestAgent.create();
});
Expand Down

0 comments on commit c43748c

Please sign in to comment.