@cooperation/vc-storage 1.0.0 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +90 -117
- package/dist/index.js +2 -1
- package/dist/models/CredentialEngine.js +161 -134
- package/dist/models/GoogleDriveStorage.js +188 -47
- package/dist/types/index.d.ts +2 -1
- package/dist/types/models/CredentialEngine.d.ts +44 -20
- package/dist/types/models/GoogleDriveStorage.d.ts +61 -3
- package/dist/types/utils/credential.d.ts +23 -0
- package/dist/types/utils/digitalbazaar.d.ts +1 -0
- package/dist/types/utils/google.d.ts +14 -0
- package/dist/types/utils/presentation.d.ts +10 -0
- package/dist/types/utils/saveToGoogle.d.ts +4 -4
- package/dist/utils/credential.js +172 -0
- package/dist/utils/digitalbazaar.js +37 -0
- package/dist/utils/google.js +79 -0
- package/dist/utils/presentation.js +48 -0
- package/dist/utils/saveToGoogle.js +12 -0
- package/package.json +5 -2
- package/dist/models/CredentialVerefier.js +0 -36
- package/dist/types/models/CredentialVerefier.d.ts +0 -9
package/README.md
CHANGED
@@ -1,136 +1,109 @@
|
|
1
|
-
#
|
1
|
+
# @cooperation/vc-storage
|
2
2
|
|
3
|
-
|
3
|
+
**Version**: 1.0.0
|
4
4
|
|
5
|
-
##
|
6
|
-
|
7
|
-
To install the Trust Storage library, you can use either npm or yarn. Run one of the following commands in your project directory:
|
8
|
-
|
9
|
-
```bash
|
10
|
-
npm install trust_storage
|
11
|
-
```
|
12
|
-
|
13
|
-
or
|
14
|
-
|
15
|
-
```bash
|
16
|
-
yarn add trust_storage
|
17
|
-
```
|
18
|
-
|
19
|
-
## Usage
|
20
|
-
|
21
|
-
To use the `GoogleDriveStorage` class in your application, you need to pass an access token that has appropriate permissions for Google Drive operations. You can generate an access token by following these steps:
|
22
|
-
|
23
|
-
1. Visit the [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/).
|
24
|
-
2. Enter the scope: `https://www.googleapis.com/auth/drive`.
|
25
|
-
3. Copy the accessToken and pass it to the `GoogleDriveStorage` class.
|
26
|
-
|
27
|
-
The `GoogleDriveStorage` class includes two methods:
|
28
|
-
|
29
|
-
- `createFolder()`: It is designed to create a new folder in Google Drive.
|
30
|
-
- `uploadFile()`: Ensure that the necessary folder has been created or identified where the file will be stored.
|
31
|
-
|
32
|
-
## Notes
|
33
|
-
|
34
|
-
- This library is a demonstration tool for uploading files to Google Drive.
|
35
|
-
|
36
|
-
### Your First Code Contribution
|
37
|
-
|
38
|
-
1. Clone the repository.
|
39
|
-
2. Run yarn or npm install to install dependencies.
|
40
|
-
3. Create a new branch for your feature or bugfix.
|
41
|
-
4. Make your changes.
|
42
|
-
5. Commit your changes and push your branch to your fork.
|
43
|
-
6. Open a pull request.
|
44
|
-
|
45
|
-
### Pull Requests
|
46
|
-
|
47
|
-
When you're ready to submit your pull request:
|
48
|
-
|
49
|
-
1. Ensure your work is aligned with the project's coding standards.
|
50
|
-
2. Fill out the pull request template.
|
51
|
-
3. Include a clear and detailed description of the changes.
|
52
|
-
4. Link any related issues.
|
53
|
-
5. Wait for review and address any feedback.
|
54
|
-
|
55
|
-
## Development Workflow
|
56
|
-
|
57
|
-
### Setup
|
5
|
+
## Overview
|
58
6
|
|
59
|
-
|
60
|
-
```bash
|
61
|
-
git clone https://github.com/yourusername/your-repo-name.git
|
62
|
-
```
|
63
|
-
2. Navigate to the project directory:
|
64
|
-
```bash
|
65
|
-
cd your-repo-name
|
66
|
-
```
|
67
|
-
3. Install dependencies:
|
68
|
-
```bash
|
69
|
-
npm install
|
70
|
-
```
|
7
|
+
`@cooperation/vc-storage` is a TypeScript library that allows you to sign and store Verifiable Credentials (VCs) in various storage strategies. This library provides flexibility and security by allowing you to choose where your VCs are stored, whether on cloud services like Google Drive, on your local device, or in your digital wallet. Support for Dropbox and wallet storage is currently under development.
|
71
8
|
|
72
|
-
|
9
|
+
## Features
|
73
10
|
|
74
|
-
|
75
|
-
|
11
|
+
- **Sign and Store VCs**: Securely sign your Verifiable Credentials and store them in your preferred storage medium.
|
12
|
+
- **Google Drive Integration**: Seamlessly store your VCs on Google Drive.
|
13
|
+
- **Local Device Storage**: Store your VCs directly on your device.
|
14
|
+
- **Future Integrations**:
|
15
|
+
- **Wallet Storage**: Integration for storing VCs directly in your digital wallet (under development).
|
16
|
+
- **Dropbox Storage**: Integration for storing VCs in Dropbox (under development).
|
76
17
|
|
77
|
-
|
78
|
-
|
79
|
-
### Request Access
|
80
|
-
|
81
|
-
Ask for access to publish the package in the Slack. Mention the version and any significant changes.
|
82
|
-
|
83
|
-
### Update Version
|
84
|
-
|
85
|
-
Ensure you update the version in `package.json` according to [Semantic Versioning](https://semver.org/). You can do this manually or using the npm command:
|
86
|
-
|
87
|
-
```bash
|
88
|
-
npm version [patch|minor|major]
|
89
|
-
```
|
90
|
-
````
|
91
|
-
|
92
|
-
### Ensure Tests Pass
|
93
|
-
|
94
|
-
Run all tests to make sure they are passing:
|
95
|
-
|
96
|
-
```bash
|
97
|
-
npm test
|
98
|
-
```
|
99
|
-
|
100
|
-
### Build the Project
|
18
|
+
## Installation
|
101
19
|
|
102
|
-
|
20
|
+
You can install this package via npm:
|
103
21
|
|
104
22
|
```bash
|
105
|
-
npm
|
23
|
+
npm install @cooperation/vc-storage
|
106
24
|
```
|
107
25
|
|
108
|
-
|
109
|
-
|
110
|
-
Commit and push your changes to the main branch:
|
26
|
+
## Usage
|
111
27
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
28
|
+
### Basic Example
|
29
|
+
|
30
|
+
Here’s how you can use the `@cooperation/vc-storage` library to sign and store your VCs:
|
31
|
+
|
32
|
+
```typescript
|
33
|
+
import { saveToGoogleDrive, CredentialEngine, GoogleDriveStorage } from '@cooperation/vc-storage';
|
34
|
+
|
35
|
+
const accessToken = 'your-google-drive-access-token';
|
36
|
+
const credentialEngine = new CredentialEngine();
|
37
|
+
const storage = new GoogleDriveStorage(accessToken);
|
38
|
+
|
39
|
+
async function main(useWallet = false, walletAddress = '') {
|
40
|
+
const formData = {
|
41
|
+
expirationDate: '2025-12-31T23:59:59Z',
|
42
|
+
fullName: 'John Doe',
|
43
|
+
duration: '1 year',
|
44
|
+
criteriaNarrative: 'This is a narrative',
|
45
|
+
achievementDescription: 'This is an achievement',
|
46
|
+
achievementName: 'Achievement Name',
|
47
|
+
portfolio: [
|
48
|
+
{ name: 'Portfolio 1', url: 'https://example.com/portfolio1' },
|
49
|
+
{ name: 'Portfolio 2', url: 'https://example.com/portfolio2' },
|
50
|
+
],
|
51
|
+
evidenceLink: 'https://example.com/evidence',
|
52
|
+
evidenceDescription: 'This is an evidence description',
|
53
|
+
credentialType: 'Credential Type',
|
54
|
+
};
|
55
|
+
|
56
|
+
let didDocument, keyPair;
|
57
|
+
|
58
|
+
// Step 1: Create DID based on the selected method
|
59
|
+
if (useWallet && walletAddress) {
|
60
|
+
({ didDocument, keyPair } = await credentialEngine.createWalletDID(walletAddress));
|
61
|
+
} else {
|
62
|
+
({ didDocument, keyPair } = await credentialEngine.createDID());
|
63
|
+
}
|
64
|
+
|
65
|
+
await saveToGoogleDrive(storage, { ...didDocument, keyPair }, 'DID');
|
66
|
+
|
67
|
+
const issuerDid = didDocument.id;
|
68
|
+
|
69
|
+
// Step 2: Create an Unsigned VC
|
70
|
+
const unsignedVC = await credentialEngine.createUnsignedVC(formData, issuerDid);
|
71
|
+
await saveToGoogleDrive(storage, unsignedVC, 'UnsignedVC');
|
72
|
+
console.log('Unsigned VC:', unsignedVC);
|
73
|
+
|
74
|
+
// Step 3: Sign the VC
|
75
|
+
try {
|
76
|
+
const signedVC = await credentialEngine.signVC(unsignedVC, keyPair);
|
77
|
+
await saveToGoogleDrive(storage, signedVC, 'VC');
|
78
|
+
console.log('Signed VC:', signedVC);
|
79
|
+
} catch (error) {
|
80
|
+
console.error('Error during VC signing:', error);
|
81
|
+
}
|
82
|
+
|
83
|
+
// Retrieve all stored claims
|
84
|
+
const claims = await storage.getAllClaims();
|
85
|
+
console.log('Stored Claims:', claims);
|
86
|
+
}
|
87
|
+
|
88
|
+
// Example usage:
|
89
|
+
// 1. For Google Drive storage with standard DID creation
|
90
|
+
main().catch(console.error);
|
91
|
+
|
92
|
+
// 2. For Google Drive storage with wallet-based DID creation
|
93
|
+
// main(true, 'your-wallet-address').catch(console.error);
|
116
94
|
```
|
117
95
|
|
118
|
-
###
|
96
|
+
### Available Storage Strategies
|
119
97
|
|
120
|
-
|
98
|
+
1. **Google Drive**: Store your VCs on Google Drive.
|
99
|
+
2. **Local Device**: Store your VCs on your local device.
|
100
|
+
3. **Wallet Storage**: (Under Development) Store your VCs directly in your digital wallet.
|
101
|
+
4. **Dropbox**: (Under Development) Store your VCs in Dropbox.
|
121
102
|
|
122
|
-
|
123
|
-
npm login
|
124
|
-
```
|
125
|
-
|
126
|
-
### Publish the Package
|
127
|
-
|
128
|
-
Once you have access and everything is set, publish the package:
|
103
|
+
## Contributing
|
129
104
|
|
130
|
-
|
131
|
-
npm publish
|
132
|
-
```
|
105
|
+
Contributions are welcome! Please feel free to submit a Pull Request or open an Issue for any bugs or feature requests.
|
133
106
|
|
134
|
-
|
107
|
+
## License
|
135
108
|
|
136
|
-
|
109
|
+
This project is licensed under the ISC License.
|
package/dist/index.js
CHANGED
@@ -1,62 +1,71 @@
|
|
1
1
|
import { Ed25519VerificationKey2020 } from '@digitalbazaar/ed25519-verification-key-2020';
|
2
2
|
import { Ed25519Signature2020 } from '@digitalbazaar/ed25519-signature-2020';
|
3
|
-
import
|
3
|
+
import * as vc from '@digitalbazaar/vc';
|
4
4
|
import { v4 as uuidv4 } from 'uuid';
|
5
|
-
import {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
5
|
+
import { extractKeyPairFromCredential, generateDIDSchema, generateUnsignedRecommendation, generateUnsignedVC, } from '../utils/credential.js';
|
6
|
+
import { customDocumentLoader } from '../utils/digitalbazaar.js';
|
7
|
+
import { saveToGoogleDrive } from '../utils/google.js';
|
8
|
+
import { GoogleDriveStorage } from './GoogleDriveStorage.js';
|
9
|
+
/**
|
10
|
+
* Class representing the Credential Engine.
|
11
|
+
* @class CredentialEngine
|
12
|
+
* @param {string} accessToken - The access token for the user.
|
13
|
+
* @classdesc Credential Engine class to create DIDs and VCs.
|
14
|
+
* @method createDID - Create a new DID with Digital Bazaar's Ed25519VerificationKey2020 key pair.
|
15
|
+
* @method createWalletDID - Create a new DID with user metamask address as controller.
|
16
|
+
* @method signVC - Sign a Verifiable Credential (VC).
|
17
|
+
* @method verifyCredential - Verify a Verifiable Credential (VC).
|
18
|
+
* @method createPresentation - Create a Verifiable Presentation (VP).
|
19
|
+
* @method signPresentation - Sign a Verifiable Presentation (VP).
|
20
|
+
*/
|
21
21
|
export class CredentialEngine {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
{
|
35
|
-
id: keyPair.id,
|
36
|
-
type: 'Ed25519VerificationKey2020',
|
37
|
-
controller: DID,
|
38
|
-
publicKeyMultibase: keyPair.publicKeyMultibase,
|
39
|
-
},
|
40
|
-
],
|
41
|
-
authentication: [keyPair.id],
|
42
|
-
assertionMethod: [keyPair.id],
|
43
|
-
capabilityDelegation: [keyPair.id],
|
44
|
-
capabilityInvocation: [keyPair.id],
|
45
|
-
keyAgreement: [
|
46
|
-
{
|
47
|
-
id: `${keyPair.id}-keyAgreement`,
|
48
|
-
type: 'X25519KeyAgreementKey2020',
|
49
|
-
controller: DID,
|
50
|
-
publicKeyMultibase: keyPair.publicKeyMultibase,
|
51
|
-
},
|
52
|
-
],
|
53
|
-
};
|
54
|
-
return didDocument;
|
22
|
+
uuid;
|
23
|
+
storage;
|
24
|
+
keyPair;
|
25
|
+
constructor(accessToken) {
|
26
|
+
this.uuid = uuidv4();
|
27
|
+
this.storage = new GoogleDriveStorage(accessToken);
|
28
|
+
}
|
29
|
+
async getKeyPair(vc) {
|
30
|
+
// Fetch all stored key pairs
|
31
|
+
const keyPairs = await this.storage.getAllFilesByType('KEYPAIRs');
|
32
|
+
if (!keyPairs || keyPairs.length === 0) {
|
33
|
+
throw new Error('No key pairs found in storage.');
|
55
34
|
}
|
56
|
-
|
57
|
-
|
58
|
-
|
35
|
+
// Extract UUID from VC ID
|
36
|
+
const vcIdParts = vc.id.split(':');
|
37
|
+
if (vcIdParts.length < 3) {
|
38
|
+
throw new Error('Invalid Verifiable Credential ID format.');
|
59
39
|
}
|
40
|
+
const uuidFromVC = vcIdParts[2];
|
41
|
+
// Match UUID with key pair files
|
42
|
+
const matchingKeyPairFile = keyPairs.find((key) => {
|
43
|
+
const [uuidPart] = key.name.split('_');
|
44
|
+
return uuidPart === uuidFromVC;
|
45
|
+
});
|
46
|
+
if (!matchingKeyPairFile) {
|
47
|
+
throw new Error('No matching key pair found for the Verifiable Credential ID.');
|
48
|
+
}
|
49
|
+
// Return the key pair content
|
50
|
+
const key = matchingKeyPairFile.content;
|
51
|
+
this.keyPair = key;
|
52
|
+
return key;
|
53
|
+
}
|
54
|
+
generateKeyPair = async (address) => {
|
55
|
+
const keyPair = await Ed25519VerificationKey2020.generate();
|
56
|
+
const a = address || keyPair.publicKeyMultibase;
|
57
|
+
keyPair.controller = `did:key:${a}`;
|
58
|
+
keyPair.id = `${keyPair.controller}#${a}`;
|
59
|
+
keyPair.revoked = false;
|
60
|
+
return keyPair;
|
61
|
+
};
|
62
|
+
async verifyCreds(creds) {
|
63
|
+
await Promise.all(creds.map((cred) => {
|
64
|
+
const res = this.verifyCredential(cred);
|
65
|
+
if (!res)
|
66
|
+
return false;
|
67
|
+
}));
|
68
|
+
return true;
|
60
69
|
}
|
61
70
|
/**
|
62
71
|
* Create a new DID with Digital Bazaar's Ed25519VerificationKey2020 key pair.
|
@@ -65,11 +74,10 @@ export class CredentialEngine {
|
|
65
74
|
*/
|
66
75
|
async createDID() {
|
67
76
|
try {
|
68
|
-
const keyPair = await
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
const didDocument = await this.generateDIDSchema(keyPair);
|
77
|
+
const keyPair = await this.generateKeyPair();
|
78
|
+
const keyFile = await saveToGoogleDrive(this.storage, keyPair, 'KEYPAIR', this.uuid);
|
79
|
+
console.log('🚀 ~ CredentialEngine ~ createDID ~ keyFile:', keyFile);
|
80
|
+
const didDocument = await generateDIDSchema(keyPair);
|
73
81
|
return { didDocument, keyPair };
|
74
82
|
}
|
75
83
|
catch (error) {
|
@@ -85,11 +93,10 @@ export class CredentialEngine {
|
|
85
93
|
*/
|
86
94
|
async createWalletDID(walletrAddress) {
|
87
95
|
try {
|
88
|
-
const keyPair = await
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
const didDocument = await this.generateDIDSchema(keyPair);
|
96
|
+
const keyPair = await this.generateKeyPair(walletrAddress);
|
97
|
+
const keyFile = await saveToGoogleDrive(this.storage, keyPair, 'KEYPAIR', this.uuid);
|
98
|
+
console.log('🚀 ~ CredentialEngine ~ createWalletDID ~ keyFile:', keyFile);
|
99
|
+
const didDocument = await generateDIDSchema(keyPair);
|
93
100
|
return { didDocument, keyPair };
|
94
101
|
}
|
95
102
|
catch (error) {
|
@@ -98,89 +105,109 @@ export class CredentialEngine {
|
|
98
105
|
}
|
99
106
|
}
|
100
107
|
/**
|
101
|
-
*
|
102
|
-
* @param {
|
103
|
-
* @param {string}
|
104
|
-
* @
|
105
|
-
* @
|
108
|
+
* Sign a Verifiable Credential (VC)
|
109
|
+
* @param {'VC' | 'RECOMMENDATION'} type - The signature type.
|
110
|
+
* @param {string} issuerId - The ID of the issuer [currently we put it as the did id]
|
111
|
+
* @param {KeyPair} keyPair - The key pair to use for signing.
|
112
|
+
* @returns {Promise<Credential>} The signed VC.
|
113
|
+
* @throws Will throw an error if VC signing fails.
|
106
114
|
*/
|
107
|
-
async
|
115
|
+
async signVC(formData, type, keyPair, issuerId) {
|
116
|
+
let credential;
|
117
|
+
if (type == 'VC') {
|
118
|
+
credential = generateUnsignedVC(formData, issuerId, this.uuid);
|
119
|
+
}
|
120
|
+
else if (type == 'RECOMMENDATION') {
|
121
|
+
credential = generateUnsignedRecommendation(formData, issuerId);
|
122
|
+
}
|
123
|
+
const suite = new Ed25519Signature2020({ key: keyPair, verificationMethod: keyPair.id });
|
108
124
|
try {
|
109
|
-
const
|
110
|
-
|
111
|
-
throw Error('issuanceDate cannot be after expirationDate');
|
112
|
-
const unsignedCredential = {
|
113
|
-
'@context': [
|
114
|
-
'https://www.w3.org/2018/credentials/v1',
|
115
|
-
'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json',
|
116
|
-
{
|
117
|
-
duration: 'https://schema.org/duration',
|
118
|
-
fullName: 'https://schema.org/name',
|
119
|
-
portfolio: 'https://schema.org/portfolio',
|
120
|
-
evidenceLink: 'https://schema.org/evidenceLink',
|
121
|
-
evidenceDescription: 'https://schema.org/evidenceDescription',
|
122
|
-
credentialType: 'https://schema.org/credentialType',
|
123
|
-
},
|
124
|
-
],
|
125
|
-
id: `urn:uuid:${uuidv4()}`, // Add the id property
|
126
|
-
type: ['VerifiableCredential', 'OpenBadgeCredential'],
|
127
|
-
issuer: {
|
128
|
-
id: issuerDid,
|
129
|
-
type: ['Profile'],
|
130
|
-
},
|
131
|
-
issuanceDate,
|
132
|
-
expirationDate: formData.expirationDate,
|
133
|
-
credentialSubject: {
|
134
|
-
type: ['AchievementSubject'],
|
135
|
-
name: formData.fullName,
|
136
|
-
portfolio: formData.portfolio,
|
137
|
-
evidenceLink: formData.evidenceLink,
|
138
|
-
evidenceDescription: formData.achievementDescription,
|
139
|
-
duration: formData.duration,
|
140
|
-
credentialType: formData.credentialType,
|
141
|
-
achievement: [
|
142
|
-
{
|
143
|
-
id: `urn:uuid:${uuidv4()}`,
|
144
|
-
type: ['Achievement'],
|
145
|
-
criteria: {
|
146
|
-
narrative: formData.criteriaNarrative,
|
147
|
-
},
|
148
|
-
description: formData.achievementDescription,
|
149
|
-
name: formData.achievementName,
|
150
|
-
image: formData.evidenceLink
|
151
|
-
? {
|
152
|
-
id: formData.evidenceLink,
|
153
|
-
type: 'Image',
|
154
|
-
}
|
155
|
-
: undefined,
|
156
|
-
},
|
157
|
-
],
|
158
|
-
},
|
159
|
-
};
|
160
|
-
console.log('Successfully created Unsigned Credentials', unsignedCredential);
|
161
|
-
return unsignedCredential;
|
125
|
+
const signedVC = await vc.issue({ credential, suite, documentLoader: customDocumentLoader });
|
126
|
+
return signedVC;
|
162
127
|
}
|
163
128
|
catch (error) {
|
164
|
-
console.error('Error
|
129
|
+
console.error('Error signing VC:', error);
|
165
130
|
throw error;
|
166
131
|
}
|
167
132
|
}
|
168
133
|
/**
|
169
|
-
*
|
170
|
-
* @param {object} credential - The
|
171
|
-
* @
|
172
|
-
* @
|
173
|
-
* @throws Will throw an error if VC signing fails.
|
134
|
+
* Verify a Verifiable Credential (VC)
|
135
|
+
* @param {object} credential - The Verifiable Credential to verify.
|
136
|
+
* @returns {Promise<boolean>} The verification result.
|
137
|
+
* @throws Will throw an error if VC verification fails.
|
174
138
|
*/
|
175
|
-
async
|
176
|
-
const suite = new Ed25519Signature2020({ key: keyPair, verificationMethod: keyPair.id });
|
139
|
+
async verifyCredential(credential) {
|
177
140
|
try {
|
178
|
-
const
|
179
|
-
|
180
|
-
|
141
|
+
const keyPair = await extractKeyPairFromCredential(credential);
|
142
|
+
const suite = new Ed25519Signature2020({
|
143
|
+
key: keyPair,
|
144
|
+
verificationMethod: keyPair.id,
|
145
|
+
});
|
146
|
+
const result = await vc.verifyCredential({
|
147
|
+
credential,
|
148
|
+
suite,
|
149
|
+
documentLoader: customDocumentLoader,
|
150
|
+
});
|
151
|
+
console.log(JSON.stringify(result));
|
152
|
+
return result;
|
181
153
|
}
|
182
154
|
catch (error) {
|
183
|
-
console.error('
|
155
|
+
console.error('Verification failed:', error);
|
156
|
+
throw error;
|
157
|
+
}
|
158
|
+
}
|
159
|
+
/**
|
160
|
+
* Create a Verifiable Presentation (VP)
|
161
|
+
* @param verifiableCredential
|
162
|
+
* @returns
|
163
|
+
*/
|
164
|
+
async createPresentation(verifiableCredential) {
|
165
|
+
try {
|
166
|
+
const res = await this.verifyCreds(verifiableCredential);
|
167
|
+
if (!res)
|
168
|
+
throw new Error('Some credentials failed verification');
|
169
|
+
const id = `urn:uuid:${uuidv4()}`;
|
170
|
+
const keyPair = await this.getKeyPair(verifiableCredential[0]);
|
171
|
+
console.log('🚀 ~ CredentialEngine ~ createPresentation ~ keyPair:', keyPair);
|
172
|
+
const VP = await vc.createPresentation({ verifiableCredential, id, holder: keyPair.controller });
|
173
|
+
return VP;
|
174
|
+
}
|
175
|
+
catch (error) {
|
176
|
+
console.error('Error creating presentation:', error);
|
177
|
+
throw error;
|
178
|
+
}
|
179
|
+
}
|
180
|
+
/**
|
181
|
+
* Sign a Verifiable Presentation (VP)
|
182
|
+
* @param presentation
|
183
|
+
* @returns
|
184
|
+
*/
|
185
|
+
async signPresentation(presentation) {
|
186
|
+
try {
|
187
|
+
// Wrap the keyPair into an Ed25519VerificationKey2020 that includes the signer method
|
188
|
+
const signingKey = new Ed25519VerificationKey2020({
|
189
|
+
id: this.keyPair.id,
|
190
|
+
controller: this.keyPair.controller,
|
191
|
+
type: this.keyPair.type,
|
192
|
+
publicKeyMultibase: this.keyPair.publicKeyMultibase,
|
193
|
+
privateKeyMultibase: this.keyPair.privateKeyMultibase,
|
194
|
+
});
|
195
|
+
// Create the Ed25519Signature2020 suite with the wrapped key that includes the signer
|
196
|
+
const suite = new Ed25519Signature2020({
|
197
|
+
key: signingKey,
|
198
|
+
verificationMethod: this.keyPair.id,
|
199
|
+
});
|
200
|
+
// Sign the presentation
|
201
|
+
const signedVP = await vc.signPresentation({
|
202
|
+
presentation,
|
203
|
+
suite,
|
204
|
+
documentLoader: customDocumentLoader,
|
205
|
+
challenge: '', // Provide the challenge if required
|
206
|
+
});
|
207
|
+
return signedVP;
|
208
|
+
}
|
209
|
+
catch (error) {
|
210
|
+
console.error('Error signing presentation:', error);
|
184
211
|
throw error;
|
185
212
|
}
|
186
213
|
}
|