Skip to content

Commit

Permalink
Merge pull request #40 from verida/feature/31-use-verifiable-credenti…
Browse files Browse the repository at this point in the history
…al-lib

feat/used @verida/verifiable-credentials package  to create vcs
  • Loading branch information
nick-verida authored Apr 5, 2022
2 parents 85ec3e7 + 11873c4 commit 824b561
Show file tree
Hide file tree
Showing 7 changed files with 876 additions and 236 deletions.
2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@nestjs/platform-express": "^7.0.0",
"@typegoose/typegoose": "^7.2.0",
"@verida/account-node": "^1.1.8",
"@verida/client-ts": "^1.1.12",
"@verida/client-ts": "^1.1.13",
"bcrypt": "^5.0.0",
"class-transformer": "^0.2.3",
"class-validator": "^0.11.1",
Expand Down
86 changes: 0 additions & 86 deletions backend/src/helpers/CredentialHelper.js

This file was deleted.

172 changes: 35 additions & 137 deletions backend/src/helpers/VeridaHelper.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { BadRequestException } from '@nestjs/common';
import NodeCache from 'node-cache';

import Verida from '@verida/client-ts';
import EncryptionUtils from '@verida/encryption-utils';
import { Wallet } from 'ethers';
import BaseHelper from './BaseHelper';
import { Context, EnvironmentType, Network } from '@verida/client-ts';
import { AutoAccount } from '@verida/account-node';
import CredentialHelper from './CredentialHelper';

import { Credentials } from "@verida/verifiable-credentials";
import { CreateIssuerDto } from '../modules/issuer/dto';
import { IssuerDto } from '../modules/issuer/dto';
import { Issuer } from '../modules/issuer/interfaces/issuer.interface';
Expand All @@ -19,10 +13,8 @@ import { BLOCK_CHAIN, DURATION_TTL } from '../constants/constant.config';
const {
VERIDA_APP_NAME,
VERIDA_TESTNET_DEFAULT_SERVER,
CREDENTIAL_DOWNLOAD_URL,
} = process.env;

const VERIDA_ENVIRONMENT = EnvironmentType.TESTNET;

const CacheManager = new NodeCache();

Expand Down Expand Up @@ -59,65 +51,6 @@ export default class VeridaHelper {
return Wallet.createRandom();
}

static async validateCredential(cred: IssueCredentialDto) {
const schema = await new Verida.Client().getSchema(cred.data['schema']);
const valid = await schema.validate(cred.data);

if (!valid) {
throw new BadRequestException(schema.errors);
}
}

static async issueCredentialV1(issuer: Issuer, cred: IssueCredentialDto) {
// Convert the DOB to numeric only and fetch the mobile number
const dob = cred['dob'].replace(/\-/g, '');
const mobile = cred.data['did'];

// Generate an encryption key for the credential that combines a
// partial random key with the user's date of birth

// 6 digit alpha string + credential DOB
const randomKey = EncryptionUtils.randomKey(24);
const randomKeyHex = Buffer.from(randomKey).toString('hex');
const dobHex = Buffer.from(dob).toString('hex');
const encryptionKey = new Uint8Array(
Buffer.from(randomKeyHex + dobHex, 'hex'),
);

// Issue an encrypted credential
const result = await this._issueEncryptedCredential(
issuer,
cred,
encryptionKey,
);
const credentialId = result['result'].id;
const vid = result['vid'];

// Generate a URL that combines the issuer VID, credentialId and partial encryption key
// BASE64 encode values to save space
const uniqueId = BaseHelper.convertBase(
credentialId.replace(/\-/g, ''),
16,
64,
);
const keyShortened = BaseHelper.convertBase(randomKeyHex, 16, 64);
const vidShort = BaseHelper.convertBase(vid.replace(/0x/, ''), 16, 64);
const fetchUrl =
CREDENTIAL_DOWNLOAD_URL +
'?v=' +
vidShort +
'&c=' +
uniqueId +
'&k=' +
keyShortened;

return {
url: fetchUrl,
mobile: mobile,
credentialId: credentialId,
};
}

/**
*
* @param issuer
Expand All @@ -129,86 +62,48 @@ export default class VeridaHelper {

static async issueCredential(
issuer: Issuer,
cred: IssueCredentialDto,
credentialItem: IssueCredentialDto,
): Promise<any> {
const context = await VeridaHelper.connect(issuer.privateKey);

const credentials = new Credentials(context);
const credentialData = await credentials.createCredentialJWT(
credentialItem.did,
credentialItem.data
);

const data = await VeridaHelper.sendMessage(credentialData, context, credentialItem.did);

return data;
}

static async sendMessage(
data: any,
context: any,
did: string,
): Promise<SendMessageResponse> {
const type = 'inbox/type/dataSend';

const config = {
recipientContextName: 'Verida: Vault',
did
};
const title = cred.data['title'];
const context = await VeridaHelper.connect(issuer.privateKey);
const messaging = await context.getMessaging();

const did = cred.did;

const contextName = VERIDA_APP_NAME;

const jwtDID = await context
.getAccount()
.createDidJwt(contextName, cred.data);
const title = data['title'];
const messaging = await context.getMessaging();

const data = {
const messageData = {
data: [
{
...cred.data,
didJwtVc: jwtDID,
},
data
],
};

const response = await messaging.send(did, type, data, title, config);
const response = await messaging.send(did, type, messageData, title, config);

return response as SendMessageResponse;
}

// Verifiable Credential package not completely working at the moment

static async _issueEncryptedCredential(
issuer: Issuer,
cred: IssueCredentialDto,
encryptionKey: Uint8Array,
): Promise<object> {
// @todo: Locate issuer based on current logged in user
const app = await VeridaHelper.connect(issuer.privateKey);

// Issue a new public, encrypted verida credential
const now = new Date();
// const credIssuer = await Verida.Helpers.credentials.createIssuer(app);
const credential = {
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://www.w3.org/2018/credentials/examples/v1',
],
id: '',
type: ['VerifiableCredential'],
issuer: issuer.did,
issuanceDate: now.toISOString(),
credentialSubject: {
...cred.data,
},
credentialSchema: {
id: cred.data['schema'],
type: 'JsonSchemaValidator2018',
},
};

// const didJwtVc = await Verida.Helpers.credentials.createVerifiableCredential(
// credential,
// // credIssuer,
// );

const item = {
// didJwtVc: didJwtVc,
...cred.data,
};

const result = await CredentialHelper.issuePublicCredential(app, item, {
key: encryptionKey,
});

return result;
}

private static async connect(issuerPrivateKey: string): Promise<Context> {
const cachedContext = CacheManager.get(issuerPrivateKey);
Expand All @@ -226,13 +121,13 @@ export default class VeridaHelper {
*/

private static async init(issuerPrivateKey: string) {
const context = Network.connect({
context: {
name: VERIDA_APP_NAME,
},


const context = await Network.connect({
client: {
environment: VERIDA_ENVIRONMENT,
environment: EnvironmentType.TESTNET,
},
//@ts-ignore
account: new AutoAccount(
{
defaultDatabaseServer: {
Expand All @@ -246,9 +141,12 @@ export default class VeridaHelper {
},
{
privateKey: issuerPrivateKey,
environment: VERIDA_ENVIRONMENT,
environment: EnvironmentType.TESTNET,
},
),
context: {
name: VERIDA_APP_NAME,
},
});

CacheManager.set(issuerPrivateKey, context, DURATION_TTL);
Expand Down
2 changes: 1 addition & 1 deletion backend/src/modules/credential/credential.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class CredentialService {
constructor(
@InjectModel('Credential')
private readonly credentialModel: Model<Credential>,
) {}
) { }

async issue(issuer: Issuer, cred: IssueCredentialDto): Promise<object> {
const issuedCred = await VeridaHelper.issueCredential(issuer, cred);
Expand Down
Loading

0 comments on commit 824b561

Please sign in to comment.