Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ node_modules
.env*
testVc.js
testresume.js
/dist
/dist
/.yalc*
yalc*
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@digitalcredentials/ed25519-signature-2020": "^5.0.0",
"@digitalcredentials/ed25519-verification-key-2020": "^5.0.0-beta.2",
"@digitalcredentials/ezcap": "^5.1.0",
"@digitalcredentials/ssi": "^5.1.0",
"@wallet.storage/fetch-client": "^1.2.0",
"add": "^2.0.6",
"bnid": "^3.0.0",
Expand Down
34 changes: 17 additions & 17 deletions src/utils/credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import {
RecommendationCredential,
Credential,
RecommendationFormDataI,
VerifiableCredential,
EmploymentFormDataI,
VolunteeringFormDataI,
PerformanceReviewFormDataI,
} from '../../types';
import { IVerifiableCredential } from '@digitalcredentials/ssi';
import { v4 as uuidv4 } from 'uuid';
import CryptoJS from 'crypto-js';
import { employmentCredentialContext, volunteeringCredentialContext, performanceReviewCredentialContext } from './context.js';
Expand Down Expand Up @@ -74,10 +74,10 @@ export const generateDIDSchema = async (keyPair: KeyPair): Promise<DidDocument>
* @param {FormDataI} params
* @param {string} params.FormData - The form dta to include in the VC.
* @param {string} params.issuerDid - The DID of the issuer.
* @returns {Credential} The created unsigned VC.
* @returns {IVerifiableCredential} The created unsigned VC.
* @throws Will throw an error if the VC creation fails or if issuance date exceeds expiration date.
*/
export function generateUnsignedVC({ formData, issuerDid }: { formData: FormDataI; issuerDid: string }): Credential {
export function generateUnsignedVC({ formData, issuerDid }: { formData: FormDataI; issuerDid: string }): IVerifiableCredential {
const issuanceDate = new Date().toISOString();
if (issuanceDate > formData.expirationDate) throw new Error('issuanceDate cannot be after expirationDate');

Expand All @@ -94,7 +94,7 @@ export function generateUnsignedVC({ formData, issuerDid }: { formData: FormData
credentialType: 'https://schema.org/credentialType',
},
],
id: '', // Will be set after hashing
id: '', // Will be set after hashing
type: ['VerifiableCredential', 'OpenBadgeCredential'],
issuer: {
id: issuerDid,
Expand Down Expand Up @@ -137,16 +137,16 @@ export function generateUnsignedVC({ formData, issuerDid }: { formData: FormData
// Generate the hashed ID
unsignedCredential.id = 'urn:' + generateHashedId(unsignedCredential);

return unsignedCredential;
return unsignedCredential as IVerifiableCredential;
}
/**
* Generate an unsigned Recommendation Credential.
* Uses the hash of the VC to set the `id` for consistency.
* @param {object} params
* @param {VerifiableCredential} params.vc - The Verifiable Credential to base the recommendation on.
* @param {IVerifiableCredential} params.vc - The Verifiable Credential to base the recommendation on.
* @param {RecommendationFormDataI} params.recommendation - The recommendation form data.
* @param {string} params.issuerDid - The DID of the issuer.
* @returns {RecommendationCredential} The created unsigned Recommendation Credential.
* @returns {IVerifiableCredential} The created unsigned Recommendation Credential.
* @throws Will throw an error if the recommendation creation fails or if issuance date exceeds expiration date.
*/
export function generateUnsignedRecommendation({
Expand All @@ -157,7 +157,7 @@ export function generateUnsignedRecommendation({
vcId: string;
recommendation: RecommendationFormDataI;
issuerDid: string;
}): RecommendationCredential {
}): IVerifiableCredential {
const issuanceDate = new Date().toISOString();
if (issuanceDate > recommendation.expirationDate) throw new Error('issuanceDate cannot be after expirationDate');

Expand Down Expand Up @@ -194,13 +194,13 @@ export function generateUnsignedRecommendation({
},
};

return unsignedRecommendation;
return unsignedRecommendation as IVerifiableCredential;
}

/**
* Generate an unsigned Employment Credential.
*/
export function generateUnsignedEmployment({ formData, issuerDid }: { formData: EmploymentFormDataI; issuerDid: string }) {
export function generateUnsignedEmployment({ formData, issuerDid }: { formData: EmploymentFormDataI; issuerDid: string }): IVerifiableCredential {
const issuanceDate = new Date().toISOString();
const unsignedCredential = {
'@context': ['https://www.w3.org/2018/credentials/v1', employmentCredentialContext['@context']],
Expand All @@ -223,13 +223,13 @@ export function generateUnsignedEmployment({ formData, issuerDid }: { formData:
},
};
unsignedCredential.id = 'urn:' + generateHashedId(unsignedCredential);
return unsignedCredential;
return unsignedCredential as IVerifiableCredential;
}

/**
* Generate an unsigned Volunteering Credential.
*/
export function generateUnsignedVolunteering({ formData, issuerDid }: { formData: VolunteeringFormDataI; issuerDid: string }) {
export function generateUnsignedVolunteering({ formData, issuerDid }: { formData: VolunteeringFormDataI; issuerDid: string }): IVerifiableCredential {
const issuanceDate = new Date().toISOString();
const unsignedCredential = {
'@context': ['https://www.w3.org/2018/credentials/v1', volunteeringCredentialContext['@context']],
Expand All @@ -253,13 +253,13 @@ export function generateUnsignedVolunteering({ formData, issuerDid }: { formData
},
};
unsignedCredential.id = 'urn:' + generateHashedId(unsignedCredential);
return unsignedCredential;
return unsignedCredential as IVerifiableCredential;
}

/**
* Generate an unsigned Performance Review Credential.
*/
export function generateUnsignedPerformanceReview({ formData, issuerDid }: { formData: PerformanceReviewFormDataI; issuerDid: string }) {
export function generateUnsignedPerformanceReview({ formData, issuerDid }: { formData: PerformanceReviewFormDataI; issuerDid: string }): IVerifiableCredential {
const issuanceDate = new Date().toISOString();
const unsignedCredential = {
'@context': ['https://www.w3.org/2018/credentials/v1', performanceReviewCredentialContext['@context']],
Expand Down Expand Up @@ -291,17 +291,17 @@ export function generateUnsignedPerformanceReview({ formData, issuerDid }: { for
},
};
unsignedCredential.id = 'urn:' + generateHashedId(unsignedCredential);
return unsignedCredential;
return unsignedCredential as IVerifiableCredential;
}

/**
* Extracts the keypair from a Verifiable Credential
* @param {Object} credential - The signed Verifiable Credential
* @returns {Ed25519VerificationKey2020} keyPair - The generated keypair object
*/
export async function extractKeyPairFromCredential(credential: VerifiableCredential): Promise<KeyPair> {
export async function extractKeyPairFromCredential(credential: IVerifiableCredential): Promise<KeyPair> {
const verificationMethod: string = credential.proof.verificationMethod;
const issuer: string = credential.issuer.id;
const issuer: string = typeof credential.issuer === 'string' ? credential.issuer : credential.issuer.id;

// Example of extracting the public key from the DID fragment (verification method)
const publicKeyMultibase: string = verificationMethod.split('#')[1];
Expand Down
30 changes: 4 additions & 26 deletions types/Credential.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,10 @@ interface PortfolioItem {
url: string;
}

interface Achievement {
id: string;
type: string[];
criteria: {
narrative: string;
};
description: string;
name: string;
image?: {
id: string;
type: string;
};
}
import type { IAchievement, IOpenBadgeSubject } from '@digitalcredentials/ssi';

export type Achievement = IAchievement;
export type OpenBadgeSubject = IOpenBadgeSubject;

export interface KeyPair {
id: string;
Expand Down Expand Up @@ -119,19 +110,6 @@ export interface Proof {
proofValue: string;
}

// Define the structure of the Verifiable Credential (partial based on what was provided)
export interface VerifiableCredential {
'@context': string[];
id: string;
type: string[];
issuer: { id: string; type: string[] };
issuanceDate: string;
expirationDate: string;
credentialSubject: { [key: string]: any };
proof: Proof;
}


/**
* Employment form data
*/
Expand Down
7 changes: 5 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@
"@noble/ed25519" "^1.7.5"
base-x "^4.0.1"

"@digitalcredentials/ezcap@^7.1.0":
"@digitalcredentials/ezcap@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@digitalcredentials/ezcap/-/ezcap-5.1.0.tgz#18f9cf9904d0d88693dc21f3c4189f5a2fada457"
integrity sha512-maF5y2MNC9c6q0Y5fjadHIEo9xthJc5ARnr4V85wNRbTdCB/G3ZWLcugIHNBWFcbYW6Rgf52e06BED7+ODZgKw==
Expand Down Expand Up @@ -535,6 +535,9 @@
resolved "https://registry.yarnpkg.com/@digitalcredentials/ssi/-/ssi-3.0.5.tgz#a214fe4544b786bf85860851c635fc65575d108c"
integrity sha512-V8Xuz3yWS2+EOwsfuJkpai+rIEs7Nvvl4r7FPcJYbmumB8DWefTCvATqRTMbF2CrT4It0Izs843qHdjWuPQIkg==

"@digitalcredentials/ssi@file:.yalc/@digitalcredentials/ssi":
version "5.0.0"

"@esbuild/[email protected]":
version "0.24.2"
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz#38848d3e25afe842a7943643cbcd387cc6e13461"
Expand Down Expand Up @@ -3573,7 +3576,7 @@ ts-node@^10.9.2:

tsc@^2.0.4:
version "2.0.4"
resolved "https://registry.npmjs.org/tsc/-/tsc-2.0.4.tgz"
resolved "https://registry.yarnpkg.com/tsc/-/tsc-2.0.4.tgz#5f6499146abea5dca4420b451fa4f2f9345238f5"
integrity sha512-fzoSieZI5KKJVBYGvwbVZs/J5za84f2lSTLPYf6AGiIf43tZ3GNrI1QzTLcjtyDDP4aLxd46RTZq1nQxe7+k5Q==

[email protected]:
Expand Down