@trustvc/trustvc 1.8.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +165 -70
  2. package/dist/cjs/core/documentBuilder.js +38 -14
  3. package/dist/cjs/open-attestation/utils.js +0 -2
  4. package/dist/cjs/utils/documents/index.js +27 -0
  5. package/dist/cjs/verify/fragments/document-integrity/ecdsaW3CSignatureIntegrity.js +87 -0
  6. package/dist/cjs/verify/fragments/document-integrity/w3cSignatureIntegrity.js +2 -2
  7. package/dist/cjs/verify/fragments/index.js +5 -0
  8. package/dist/cjs/verify/verify.js +2 -0
  9. package/dist/cjs/w3c/derive.js +11 -0
  10. package/dist/cjs/w3c/index.js +7 -0
  11. package/dist/cjs/w3c/sign.js +2 -2
  12. package/dist/esm/core/documentBuilder.js +39 -15
  13. package/dist/esm/open-attestation/utils.js +1 -2
  14. package/dist/esm/utils/documents/index.js +26 -1
  15. package/dist/esm/verify/fragments/document-integrity/ecdsaW3CSignatureIntegrity.js +85 -0
  16. package/dist/esm/verify/fragments/document-integrity/w3cSignatureIntegrity.js +1 -1
  17. package/dist/esm/verify/fragments/index.js +1 -0
  18. package/dist/esm/verify/verify.js +2 -0
  19. package/dist/esm/w3c/derive.js +9 -0
  20. package/dist/esm/w3c/index.js +1 -0
  21. package/dist/esm/w3c/sign.js +2 -2
  22. package/dist/types/core/documentBuilder.d.ts +14 -4
  23. package/dist/types/core/index.d.ts +1 -1
  24. package/dist/types/{index-Bc5NlE8f.d.ts → index-1ws_BWZW.d.ts} +2 -2
  25. package/dist/types/{index-CRVFHzes.d.ts → index-LpXMEhhr.d.ts} +3 -1
  26. package/dist/types/index.d.ts +7 -5
  27. package/dist/types/open-attestation/index.d.ts +1 -2
  28. package/dist/types/open-attestation/utils.d.ts +1 -3
  29. package/dist/types/utils/documents/index.d.ts +4 -2
  30. package/dist/types/utils/index.d.ts +2 -2
  31. package/dist/types/verify/fragments/document-integrity/ecdsaW3CSignatureIntegrity.d.ts +5 -0
  32. package/dist/types/verify/fragments/index.d.ts +1 -0
  33. package/dist/types/verify/index.d.ts +2 -1
  34. package/dist/types/w3c/derive.d.ts +11 -0
  35. package/dist/types/w3c/index.d.ts +2 -1
  36. package/dist/types/w3c/sign.d.ts +7 -3
  37. package/package.json +6 -5
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## About
4
4
 
5
- TrustVC is a comprehensive wrapper library designed to simplify the signing and verification processes for TrustVC W3C [Verifiable Credentials (VC)](https://github.com/TrustVC/w3c) and OpenAttestation Verifiable Documents (VD), adhering to the W3C [VC](https://www.w3.org/TR/vc-data-model/) Data Model v1.1 (W3C Standard). It ensures compatibility and interoperability for Verifiable Credentials while supporting OpenAttestation [Verifiable Documents (VD)](https://github.com/Open-Attestation/open-attestation) v6.9.5. TrustVC seamlessly integrates functionalities for handling W3C Verifiable Credentials and OpenAttestation Verifiable Documents, leveraging existing TradeTrust libraries and smart contracts for [Token Registry](https://github.com/TradeTrust/token-registry) (V4 and V5). Additionally, it includes essential utility functions for strings, networks, and chains, making it a versatile tool for developers working with decentralized identity and verifiable data solutions.
5
+ TrustVC is a comprehensive wrapper library designed to simplify the signing and verification processes for TrustVC W3C [Verifiable Credentials (VC)](https://github.com/TrustVC/w3c) and OpenAttestation Verifiable Documents (VD), adhering to the W3C [VC](https://www.w3.org/TR/vc-data-model/) Data Model v2.0 (W3C Standard). It ensures compatibility and interoperability for Verifiable Credentials while supporting OpenAttestation [Verifiable Documents (VD)](https://github.com/Open-Attestation/open-attestation) v6.9.5. TrustVC seamlessly integrates functionalities for handling W3C Verifiable Credentials and OpenAttestation Verifiable Documents, leveraging existing TradeTrust libraries and smart contracts for [Token Registry](https://github.com/TradeTrust/token-registry) (V4 and V5). Additionally, it includes essential utility functions for strings, networks, and chains, making it a versatile tool for developers working with decentralized identity and verifiable data solutions.
6
6
 
7
7
  ## Table of Contents
8
8
 
@@ -16,15 +16,16 @@ TrustVC is a comprehensive wrapper library designed to simplify the signing and
16
16
  - [2. **Signing**](#2-signing)
17
17
  - [a) OpenAttestation Signing (signOA) v2 v3](#a-openattestation-signing-signoa-v2-v3)
18
18
  - [b) TrustVC W3C Signing (signW3C)](#b-trustvc-w3c-signing-signw3c)
19
- - [3. **Verifying**](#3-verifying)
20
- - [4. **Encryption**](#4-encryption)
21
- - [5. **Decryption**](#5-decryption)
22
- - [6. **TradeTrust Token Registry**](#6-tradetrust-token-registry)
19
+ - [3. **Deriving (Selective Disclosure)**](#3-deriving-selective-disclosure)
20
+ - [4. **Verifying**](#4-verifying)
21
+ - [5. **Encryption**](#5-encryption)
22
+ - [6. **Decryption**](#6-decryption)
23
+ - [7. **TradeTrust Token Registry**](#7-tradetrust-token-registry)
23
24
  - [Usage](#usage-2)
24
25
  - [TradeTrustToken](#tradetrusttoken)
25
26
  - [a) Token Registry v4](#a-token-registry-v4)
26
27
  - [b) Token Registry V5](#b-token-registry-v5)
27
- - [7. **Document Builder**](#7-document-builder)
28
+ - [8. **Document Builder**](#8-document-builder)
28
29
 
29
30
  ## Installation
30
31
 
@@ -113,7 +114,7 @@ console.log(wrappedDocuments);
113
114
 
114
115
  ### 2. **Signing**
115
116
 
116
- > The TrustVC Signing feature simplifies the signing process for OA documents and W3C-compliant verifiable credentials using BBS+ signatures. This feature allows you to easily sign W3C Verifiable Credentials (VCs) and ensure they comply with the latest standards.
117
+ > The TrustVC Signing feature simplifies the signing process for OA documents and W3C-compliant verifiable credentials using ECDSA signature. This feature allows you to easily sign W3C Verifiable Credentials (VCs) and ensure they comply with the latest standards.
117
118
 
118
119
  The signing functionality is split into two methods:
119
120
 
@@ -154,84 +155,169 @@ const signedWrappedDocument = await signOA(wrappedDocument, {
154
155
 
155
156
  #### b) TrustVC W3C Signing (signW3C)
156
157
 
158
+ The `signW3C` function signs W3C Verifiable Credentials using the provided cryptographic suite and key pair. By default, it uses the **ecdsa-sd-2023** crypto suite unless otherwise specified.
159
+
157
160
  ```ts
158
161
  import { signW3C, VerificationType } from '@trustvc/trustvc';
159
162
 
160
163
  const rawDocument = {
161
164
  '@context': [
162
- 'https://www.w3.org/2018/credentials/v1',
163
- 'https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v1.jsonld',
164
- 'https://w3id.org/security/bbs/v1',
165
+ 'https://www.w3.org/ns/credentials/v2',
166
+ 'https://w3id.org/security/data-integrity/v2',
165
167
  'https://w3id.org/vc/status-list/2021/v1',
168
+ 'https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld',
166
169
  ],
167
170
  credentialStatus: {
168
171
  id: 'https://trustvc.github.io/did/credentials/statuslist/1#1',
169
- type: 'StatusList2021Entry',
172
+ type: 'BitstringStatusListEntry',
170
173
  statusPurpose: 'revocation',
171
174
  statusListIndex: '10',
172
175
  statusListCredential: 'https://trustvc.github.io/did/credentials/statuslist/1',
173
176
  },
174
177
  credentialSubject: {
175
- name: 'TrustVC',
178
+ type: ['Person']
179
+ givenName: 'TrustVC',
176
180
  birthDate: '2024-04-01T12:19:52Z',
177
- type: ['PermanentResident', 'Person'],
178
181
  },
179
- expirationDate: '2029-12-03T12:19:52Z',
180
182
  issuer: 'did:web:trustvc.github.io:did:1',
181
183
  type: ['VerifiableCredential'],
182
- issuanceDate: '2024-04-01T12:19:52Z',
184
+ validFrom: '2024-04-01T12:19:52Z',
185
+ validUntil: '2029-12-03T12:19:52Z'
183
186
  };
184
187
 
188
+ // Using default ecdsa-sd-2023 crypto suite
185
189
  const signingResult = await signW3C(rawDocument, {
186
- id: 'did:web:trustvc.github.io:did:1#keys-1',
190
+ '@context': 'https://w3id.org/security/multikey/v1',
191
+ id: 'did:web:trustvc.github.io:did:1#multikey-1',
192
+ type: VerificationType.Multikey,
187
193
  controller: 'did:web:trustvc.github.io:did:1',
188
- type: VerificationType.Bls12381G2Key2020,
189
- publicKeyBase58:
190
- 'oRfEeWFresvhRtXCkihZbxyoi2JER7gHTJ5psXhHsdCoU1MttRMi3Yp9b9fpjmKh7bMgfWKLESiK2YovRd8KGzJsGuamoAXfqDDVhckxuc9nmsJ84skCSTijKeU4pfAcxeJ',
191
- privateKeyBase58: '<privateKeyBase58>',
194
+ publicKeyMultibase: 'zDnaemDNwi4G5eTzGfRooFFu5Kns3be6yfyVNtiaMhWkZbwtc',
195
+ secretKeyMultibase: '<secretKeyMultibase>'
192
196
  });
197
+
198
+ // You can also specify mandatory pointers for selective disclosure with ecdsa-sd-2023
199
+ const signingResultWithPointers = await signW3C(
200
+ rawDocument,
201
+ {
202
+ '@context': 'https://w3id.org/security/multikey/v1',
203
+ id: 'did:web:trustvc.github.io:did:1#multikey-1',
204
+ type: VerificationType.Multikey,
205
+ controller: 'did:web:trustvc.github.io:did:1',
206
+ publicKeyMultibase: 'zDnaemDNwi4G5eTzGfRooFFu5Kns3be6yfyVNtiaMhWkZbwtc',
207
+ secretKeyMultibase: '<secretKeyMultibase>'
208
+ },
209
+ 'ecdsa-sd-2023',
210
+ {
211
+ mandatoryPointers: ['/credentialStatus']
212
+ }
213
+ );
214
+
215
+ // Alternatively, specify a different crypto suite. Ensure the context is updated to include the crypto suite.
216
+ const signingResultWithBbs = await signW3C(
217
+ rawDocument,
218
+ {
219
+ id: 'did:web:trustvc.github.io:did:1#keys-1',
220
+ controller: 'did:web:trustvc.github.io:did:1',
221
+ type: VerificationType.Bls12381G2Key2020,
222
+ publicKeyBase58: 'oRfEeWFresvhRtXCkihZbxyoi2JER7gHTJ5psXhHsdCoU1MttRMi3Yp9b9fpjmKh7bMgfWKLESiK2YovRd8KGzJsGuamoAXfqDDVhckxuc9nmsJ84skCSTijKeU4pfAcxeJ',
223
+ privateKeyBase58: '<privateKeyBase58>',
224
+ },
225
+ 'BbsBlsSignature2020'
226
+ );
227
+
193
228
  ```
194
229
 
195
230
  ---
196
231
 
197
- ### 3. **Verifying**
232
+ ### 3. **Deriving (Selective Disclosure)**
198
233
 
199
- > TrustVC simplifies the verification process with a single function that supports both W3C Verifiable Credentials (VCs) and OpenAttestation Verifiable Documents (VDs). Whether you're working with W3C standards or OpenAttestation standards, TrustVC handles the verification seamlessly.
234
+ > When using ECDSA-SD-2023 crypto suite, we can derive a new credential with selective disclosure. This means you can choose which parts of the credential to reveal while keeping others hidden.
200
235
 
201
236
  ```ts
202
- import { verifyDocument } from '@trustvc/trustvc';
237
+ import { deriveW3C } from '@trustvc/trustvc';
203
238
 
239
+ // This is a signed document using ecdsa-sd-2023
204
240
  const signedDocument = {
205
241
  '@context': [
206
- 'https://www.w3.org/2018/credentials/v1',
207
- 'https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v1.jsonld',
208
- 'https://w3id.org/security/bbs/v1',
209
- 'https://w3id.org/vc/status-list/2021/v1',
242
+ 'https://www.w3.org/ns/credentials/v2',
243
+ 'https://w3id.org/security/data-integrity/v2',
244
+ 'https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld'
210
245
  ],
211
246
  credentialStatus: {
212
247
  id: 'https://trustvc.github.io/did/credentials/statuslist/1#1',
213
- type: 'StatusList2021Entry',
248
+ type: 'BitstringStatusListEntry',
214
249
  statusPurpose: 'revocation',
215
250
  statusListIndex: '10',
216
- statusListCredential: 'https://trustvc.github.io/did/credentials/statuslist/1',
251
+ statusListCredential: 'https://trustvc.github.io/did/credentials/statuslist/1'
217
252
  },
218
253
  credentialSubject: {
219
- name: 'TrustVC',
220
- birthDate: '2024-04-01T12:19:52Z',
221
- type: ['PermanentResident', 'Person'],
254
+ type: ['Person'],
255
+ givenName: 'TrustVC',
256
+ birthDate: '2024-04-01T12:19:52Z'
222
257
  },
223
- expirationDate: '2029-12-03T12:19:52Z',
224
258
  issuer: 'did:web:trustvc.github.io:did:1',
225
259
  type: ['VerifiableCredential'],
226
- issuanceDate: '2024-04-01T12:19:52Z',
260
+ validFrom: '2024-04-01T12:19:52Z',
261
+ validUntil: '2029-12-03T12:19:52Z',
262
+ id: 'urn:uuid:0198e4a3-b601-7117-9d02-8c9a9a54ab5d',
227
263
  proof: {
228
- type: 'BbsBlsSignature2020',
229
- created: '2024-10-14T04:11:49Z',
264
+ type: 'DataIntegrityProof',
265
+ created: '2025-08-18T14:38:51Z',
266
+ verificationMethod: 'did:web:trustvc.github.io:did:1#multikey-1',
267
+ cryptosuite: 'ecdsa-sd-2023',
230
268
  proofPurpose: 'assertionMethod',
231
- proofValue:
232
- 'l79dlFQMowalep+WCFqgCvpVBcCAr0GDEFUV6S7gRVY/TQ+sp/wcwaT61PaD19rJYUHlKfzccE4m7waZyoLEkBLFiK2g54Q2i+CdtYBgDdkUDsoULSBMcH1MwGHwdjfXpldFNFrHFx/IAvLVniyeMQ==',
233
- verificationMethod: 'did:web:trustvc.github.io:did:1#keys-1',
269
+ proofValue: 'u2V0AhVhAWvyp4W7vt4DBhJy2JjKdbDjNSjh3mFsIfPv68Xk2uc4PSFf1iiAeq19rvnHou1LW_Ff0MrRxzcmuTsBO54q3vVgjgCQDz9CT1s28B8Wsk-i8hgzexvcOZgInRbK9VpG6pMwSfbNYIA0xoaqSwjMxAISQ2l2uRmBFlIdL3XFduNUlo93wj5EMilhA24fPUQHaYlpN2hezHkI2QbUpUzVdIoRFA9KdzA1JNWM9GuCKWF0A62W91QmN82237JIiF1d2aLq3lnCpgR_Y-VhAdhqKN1MXPH5BNYAmM1rSZLHGF92dYt2k3XLb84UsgBYNx0f5VKOKFKNY-ZNho59RdsSTRNbsUzU-zzH1CLkc-lhAKgI6LHZPLePwB-Vsad2jOO-_PGHoHas5-uNJDDSp-xTO2auFGmpI6OGx-U_xwcKYX3su3qwtYCJ3nf2-l-t5SFhAfNLg1QbwjJBStUFCcVZWzu1wDh1d9owiox2nNm9EDun4DU40ThWLoWJEEGtqJYE0XFeMxCNkGJGvBQkXJxKZYlhAXBhzKu4D8oXuUHymh5rXvp-a4cUHI0Mh0H0eEifx41FqPc_hNNhCEZKAl_lB6mxIAA-5rqDkUH8zj-gH0TDgq1hA8GZCjLF6wE5feS14DscTe_oVIAfe_2YYTdDLwtklycGXiIGjMs3XmX002URnASJU2RcX1hROupc2tpXFGOQZmlhAPwgkCD6aSL2gusl56goodXi7lg5GDJyh3iYSSA2qL0HkBs7q3FsbijIvscH3-bIEWZHUX127ZC3f1UL85WPR01hAQi-48VLrcfPC1aFuwuUQm_UEwkZ4LZsEvvPrPtrC1WjtGq7-NDAfNkz6cO9MgsUwjAncXliJW-tTNX3ujDfEA1hAARmh7uujgnsv7CoQt4suDhtVJKZA5UdKahJkUvqXZKRFfhRmJHPwJKnM04IV_AcQd8RH--v2ZUzD6IUGYXCUIVhABjkqmiaLL9PY20li9JBOd0VR7udnu0eM8JMGnnHm_gEIKM3eHWPqyfJyw9AfFymBwm0fgBqRxf0LIo9uDkLlwYJnL2lzc3VlcmovdmFsaWRGcm9t'
270
+ }
271
+ };
272
+
273
+ // Derive a new credential with only specific fields disclosed
274
+ const derivationResult = await deriveW3C(signedDocument, {
275
+ // Only reveal the credential type and givenName, hide birthDate
276
+ selectivePointers: ['/type', '/credentialSubject/givenName']
277
+ });
278
+
279
+ ```
280
+
281
+ ---
282
+
283
+ ### 4. **Verifying**
284
+
285
+ > TrustVC simplifies the verification process with a single function that supports both W3C Verifiable Credentials (VCs) and OpenAttestation Verifiable Documents (VDs). Whether you're working with W3C standards or OpenAttestation standards, TrustVC handles the verification seamlessly. For ECDSA-signed documents, which normally require derivation before verification, TrustVC automatically handles this process internally - if a document is not derived, the `verifyDocument` function will automatically derive and verify the document in a single step.
286
+
287
+ ```ts
288
+ import { verifyDocument } from '@trustvc/trustvc';
289
+
290
+ const signedDocument = {
291
+ '@context': [
292
+ 'https://www.w3.org/ns/credentials/v2',
293
+ 'https://w3id.org/security/data-integrity/v2',
294
+ 'https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld'
295
+ ],
296
+ credentialStatus: {
297
+ id: 'https://trustvc.github.io/did/credentials/statuslist/1#1',
298
+ type: 'BitstringStatusListEntry',
299
+ statusPurpose: 'revocation',
300
+ statusListIndex: '10',
301
+ statusListCredential: 'https://trustvc.github.io/did/credentials/statuslist/1'
234
302
  },
303
+ credentialSubject: {
304
+ type: ['Person'],
305
+ givenName: 'TrustVC',
306
+ birthDate: '2024-04-01T12:19:52Z'
307
+ },
308
+ issuer: 'did:web:trustvc.github.io:did:1',
309
+ type: ['VerifiableCredential'],
310
+ validFrom: '2024-04-01T12:19:52Z',
311
+ validUntil: '2029-12-03T12:19:52Z',
312
+ id: 'urn:uuid:0198e4a3-b601-7117-9d02-8c9a9a54ab5d',
313
+ proof: {
314
+ type: 'DataIntegrityProof',
315
+ created: '2025-08-18T14:38:51Z',
316
+ verificationMethod: 'did:web:trustvc.github.io:did:1#multikey-1',
317
+ cryptosuite: 'ecdsa-sd-2023',
318
+ proofPurpose: 'assertionMethod',
319
+ proofValue: 'u2V0AhVhAWvyp4W7vt4DBhJy2JjKdbDjNSjh3mFsIfPv68Xk2uc4PSFf1iiAeq19rvnHou1LW_Ff0MrRxzcmuTsBO54q3vVgjgCQDz9CT1s28B8Wsk-i8hgzexvcOZgInRbK9VpG6pMwSfbNYIA0xoaqSwjMxAISQ2l2uRmBFlIdL3XFduNUlo93wj5EMilhA24fPUQHaYlpN2hezHkI2QbUpUzVdIoRFA9KdzA1JNWM9GuCKWF0A62W91QmN82237JIiF1d2aLq3lnCpgR_Y-VhAdhqKN1MXPH5BNYAmM1rSZLHGF92dYt2k3XLb84UsgBYNx0f5VKOKFKNY-ZNho59RdsSTRNbsUzU-zzH1CLkc-lhAKgI6LHZPLePwB-Vsad2jOO-_PGHoHas5-uNJDDSp-xTO2auFGmpI6OGx-U_xwcKYX3su3qwtYCJ3nf2-l-t5SFhAfNLg1QbwjJBStUFCcVZWzu1wDh1d9owiox2nNm9EDun4DU40ThWLoWJEEGtqJYE0XFeMxCNkGJGvBQkXJxKZYlhAXBhzKu4D8oXuUHymh5rXvp-a4cUHI0Mh0H0eEifx41FqPc_hNNhCEZKAl_lB6mxIAA-5rqDkUH8zj-gH0TDgq1hA8GZCjLF6wE5feS14DscTe_oVIAfe_2YYTdDLwtklycGXiIGjMs3XmX002URnASJU2RcX1hROupc2tpXFGOQZmlhAPwgkCD6aSL2gusl56goodXi7lg5GDJyh3iYSSA2qL0HkBs7q3FsbijIvscH3-bIEWZHUX127ZC3f1UL85WPR01hAQi-48VLrcfPC1aFuwuUQm_UEwkZ4LZsEvvPrPtrC1WjtGq7-NDAfNkz6cO9MgsUwjAncXliJW-tTNX3ujDfEA1hAARmh7uujgnsv7CoQt4suDhtVJKZA5UdKahJkUvqXZKRFfhRmJHPwJKnM04IV_AcQd8RH--v2ZUzD6IUGYXCUIVhABjkqmiaLL9PY20li9JBOd0VR7udnu0eM8JMGnnHm_gEIKM3eHWPqyfJyw9AfFymBwm0fgBqRxf0LIo9uDkLlwYJnL2lzc3VlcmovdmFsaWRGcm9t'
320
+ }
235
321
  };
236
322
 
237
323
  const resultFragments = await verifyDocument(signedDocument);
@@ -239,7 +325,7 @@ const resultFragments = await verifyDocument(signedDocument);
239
325
 
240
326
  ---
241
327
 
242
- ### 4. **Encryption**
328
+ ### 5. **Encryption**
243
329
 
244
330
  > The `encrypt` function encrypts plaintext messages using the **ChaCha20** encryption algorithm, ensuring the security and integrity of the input data. It supports custom keys and nonces, returning the encrypted message in hexadecimal format.
245
331
 
@@ -316,7 +402,7 @@ It also relies on the `ts-chacha20` library for encryption operations.
316
402
 
317
403
  ---
318
404
 
319
- ### 5. **Decryption**
405
+ ### 6. **Decryption**
320
406
 
321
407
  > The `decrypt` function decrypts messages encrypted with the **ChaCha20** algorithm. It converts the input from a hexadecimal format back into plaintext using the provided key and nonce.
322
408
 
@@ -399,7 +485,7 @@ It also relies on the `ts-chacha20` library for decryption operations.
399
485
 
400
486
  ---
401
487
 
402
- ### 6. **TradeTrust Token Registry**
488
+ ### 7. **TradeTrust Token Registry**
403
489
 
404
490
  > The Electronic Bill of Lading (eBL) is a digital document that can be used to prove the ownership of goods. It is a standardized document that is accepted by all major shipping lines and customs authorities. The [Token Registry](https://github.com/TradeTrust/token-registry) repository contains both the smart contract (v4 and v5) code for token registry (in `/contracts`) as well as the node package for using this library (in `/src`).
405
491
  > The TrustVC library not only simplifies signing and verification but also imports and integrates existing TradeTrust libraries and smart contracts for token registry (V4 and V5), making it a versatile tool for decentralized identity and trust solutions.
@@ -589,8 +675,8 @@ function rejectTransferOwners(bytes calldata _remark) external;
589
675
 
590
676
  For more information on Token Registry and Title Escrow contracts **version v5**, please visit the readme of [TradeTrust Token Registry V5](https://github.com/TradeTrust/token-registry/blob/master/README.md)
591
677
 
592
- ### 7. **Document Builder**
593
- > The `DocumentBuilder` class helps build and manage W3C Verifiable Credentials (VCs) with credential status features. It supports creating documents with two types of credential statuses: `transferableRecords` and `verifiableDocument`. It can sign the document using a private key, verify its signature, and serialize the document to a JSON format. Additionally, it allows for configuration of document rendering methods and expiration dates.
678
+ ### 8. **Document Builder**
679
+ > The `DocumentBuilder` class helps build and manage W3C Verifiable Credentials (VCs) with credential status features, implementing the **W3C VC Data Model 2.0** specification. It supports creating documents with two types of credential statuses: `transferableRecords` and `verifiableDocument`. It can sign the document using a private key, verify its signature, and serialize the document to a JSON format. Additionally, it allows for configuration of document rendering methods and expiration dates.
594
680
 
595
681
  #### Usage
596
682
 
@@ -603,7 +689,7 @@ To learn more about defining custom contexts, check out the [Credential Subject
603
689
  // Adds a custom vocabulary used to define terms in the `credentialSubject`.
604
690
  // Users can define their own context if they have domain-specific fields or custom data structures.
605
691
  const builder = new DocumentBuilder({
606
- '@context': 'https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v1.jsonld'
692
+ '@context': 'https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld'
607
693
  });
608
694
  ```
609
695
 
@@ -612,8 +698,8 @@ Set the subject of the Verifiable Credential, which typically contains informati
612
698
 
613
699
  ```ts
614
700
  builder.credentialSubject({
615
- id: 'did:example:123',
616
- name: 'John Doe',
701
+ type: ['Person'],
702
+ givenName: 'TrustVC',
617
703
  });
618
704
  ```
619
705
 
@@ -649,7 +735,7 @@ builder.credentialStatus({
649
735
  ```
650
736
 
651
737
  ##### Set Expiration Date
652
- You can set an expiration date for the document.
738
+ You can set a valid until date (expiration) for the document.
653
739
 
654
740
  ```ts
655
741
  builder.expirationDate('2026-01-01T00:00:00Z');
@@ -677,16 +763,17 @@ builder.qrCode({
677
763
  ```
678
764
 
679
765
  ##### Sign the Document
680
- To sign the document, provide a `PrivateKeyPair` from `@trustvc/trustvc`.
766
+ To sign the document, provide a `PrivateKeyPair` from `@trustvc/trustvc`. The builder uses ECDSA key for signing by default.
681
767
 
682
768
  ```ts
683
769
  const privateKey: PrivateKeyPair = {
684
- id: 'did:example:456#key1',
685
- controller: 'did:example:456',
686
- type: VerificationType.Bls12381G2Key2020,
687
- publicKeyBase58: 'your-public-key-base58',
688
- privateKeyBase58: 'your-private-key-base58',
689
- };
770
+ '@context': 'https://w3id.org/security/multikey/v1',
771
+ id: 'did:web:example.com#multikey-1',
772
+ type: VerificationType.Multikey,
773
+ controller: 'did:web:example.com',
774
+ publicKeyMultibase: 'your-public-key-multibase',
775
+ secretKeyMultibase: 'your-secret-key-multibase',
776
+ }
690
777
 
691
778
  const signedDocument = await builder.sign(privateKey);
692
779
  console.log(signedDocument);
@@ -696,19 +783,18 @@ Example Output After Signing
696
783
  ```json
697
784
  {
698
785
  "@context": [
699
- "https://www.w3.org/2018/credentials/v1",
700
- "https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v1.jsonld",
701
- "https://w3id.org/vc/status-list/2021/v1",
702
- "https://trustvc.io/context/render-method-context.json",
786
+ "https://www.w3.org/ns/credentials/v2",
787
+ "https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld",
788
+ "https://trustvc.io/context/render-method-context-v2.json",
703
789
  "https://trustvc.io/context/qrcode-context.json",
704
- "https://w3id.org/security/bbs/v1"
790
+ "https://w3id.org/security/data-integrity/v2"
705
791
  ],
706
792
  "type": ["VerifiableCredential"],
707
793
  "credentialSubject": {
708
- "id": "did:example:123",
709
- "name": "John Doe"
794
+ "type": ["Person"],
795
+ "givenName": "TrustVC",
710
796
  },
711
- "expirationDate": "2026-01-01T00:00:00Z",
797
+ "validUntil": "2026-01-01T00:00:00Z",
712
798
  "renderMethod": [
713
799
  {
714
800
  "id": "https://example.com/rendering-method",
@@ -722,26 +808,35 @@ Example Output After Signing
722
808
  },
723
809
  "credentialStatus": {
724
810
  "id": "https://example.com/status-list#<placeholder>",
725
- "type": "StatusList2021Entry",
811
+ "type": "BitstringStatusListEntry",
726
812
  "statusPurpose": "revocation",
727
813
  "statusListIndex": "<placeholder>",
728
814
  "statusListCredential": "https://example.com/status-list"
729
815
  },
730
- "issuer": "did:example:456",
731
- "issuanceDate": "2025-01-01T00:00:00Z",
816
+ "issuer": "did:web:example.com",
817
+ "validFrom": "2025-01-01T00:00:00Z",
732
818
  "id": "urn:bnid:_:0195fec2-4ae1-7cca-9182-03fd7da5142b",
733
819
  "proof": {
734
- "type": "BbsBlsSignature2020",
820
+ "type": "DataIntegrityProof",
735
821
  "created": "2025-01-01T00:00:01Z",
822
+ "verificationMethod": "did:web:example.com#multikey-1",
823
+ "cryptosuite": "ecdsa-sd-2023",
736
824
  "proofPurpose": "assertionMethod",
737
- "proofValue": "rV56L+QYozATRy3GOVLomzUo99sXtw2x0Cy9dEkHJ15wi4cS12cQJRIwzONVi3YscdhaSKoqD1jWmwb5A/khLZnDq5eo3QzDgTVClYuV86opL3HJyoS4+t2rRt3wl+chnATy2jqr5zMEvcVJ3gdXpQ==",
738
- "verificationMethod": "did:example:456#key1"
825
+ "proofValue": "u2V0AhVhAh1oLoiuV2AwmSa2ZspbmrG2gCDbpZW.......",
739
826
  }
740
827
  }
741
828
  ```
742
829
 
830
+ ##### Deriving the Document
831
+ Provide the attributes to reveal to the `derive` method.
832
+
833
+ ```ts
834
+ const derivedDocument = await builder.derive(['/credentialSubject/givenName']);
835
+ console.log(derivedDocument);
836
+ ```
837
+
743
838
  ##### Verify the Document
744
- To verify the signature of the signed document:
839
+ To verify the signature of the signed document, ensure the document is derived first and then call the `verify` method.
745
840
 
746
841
  ```ts
747
842
  const isVerified = await builder.verify();
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var w3cIssuer = require('@trustvc/w3c-issuer');
3
4
  var w3c = require('../w3c');
4
5
  var w3cCredentialStatus = require('@trustvc/w3c-credential-status');
5
6
  var w3cVc = require('@trustvc/w3c-vc');
@@ -9,6 +10,7 @@ var tokenRegistryV5$1 = require('@tradetrust-tt/token-registry-v5');
9
10
  var tokenRegistryV4 = require('../token-registry-v4');
10
11
  var tokenRegistryV5 = require('../token-registry-v5');
11
12
  var utils = require('../utils');
13
+ var w3cContext = require('@trustvc/w3c-context');
12
14
 
13
15
  var __defProp = Object.defineProperty;
14
16
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -30,6 +32,8 @@ class DocumentBuilder {
30
32
  // Required fields that must be present in the document.
31
33
  isSigned = false;
32
34
  // Tracks if a document is signed
35
+ isDerived = false;
36
+ // Tracks if a document is derived
33
37
  /**
34
38
  * Constructor to initialize the document builder.
35
39
  * @param {Partial<VerifiableCredential>} input - The input document.
@@ -63,18 +67,17 @@ class DocumentBuilder {
63
67
  tokenRegistry: config.tokenRegistry
64
68
  };
65
69
  this.rpcProviderUrl = config.rpcProviderUrl;
66
- this.addContext("https://trustvc.io/context/transferable-records-context.json");
70
+ this.addContext(w3cContext.TR_CONTEXT_URL);
67
71
  } else if (isVerifiable) {
68
72
  this.selectedStatusType = "verifiableDocument";
69
73
  this.statusConfig = {
70
74
  id: `${config.url}#${config.index}`,
71
- type: "StatusList2021Entry",
75
+ type: "BitstringStatusListEntry",
72
76
  statusPurpose: config.purpose || "revocation",
73
77
  // Set status purpose to "revocation" by default.
74
78
  statusListIndex: config.index,
75
79
  statusListCredential: config.url
76
80
  };
77
- this.addContext("https://w3id.org/vc/status-list/2021/v1");
78
81
  } else {
79
82
  throw new Error("Configuration Error: Missing required fields for credential status.");
80
83
  }
@@ -83,25 +86,25 @@ class DocumentBuilder {
83
86
  // Sets the expiration date of the document.
84
87
  expirationDate(date) {
85
88
  if (this.isSigned) throw new Error("Configuration Error: Document is already signed.");
86
- this.document.expirationDate = typeof date === "string" ? date : date.toISOString();
89
+ this.document.validUntil = typeof date === "string" ? date : date.toISOString();
87
90
  return this;
88
91
  }
89
92
  // Defines the rendering method for the document.
90
93
  renderMethod(method) {
91
94
  if (this.isSigned) throw new Error("Configuration Error: Document is already signed.");
92
95
  this.document.renderMethod = [method];
93
- this.addContext("https://trustvc.io/context/render-method-context.json");
96
+ this.addContext(w3cContext.RENDER_CONTEXT_V2_URL);
94
97
  return this;
95
98
  }
96
99
  // Defines the qrcode for the document.
97
100
  qrCode(method) {
98
101
  if (this.isSigned) throw new Error("Configuration Error: Document is already signed.");
99
102
  this.document.qrCode = method;
100
- this.addContext("https://trustvc.io/context/qrcode-context.json");
103
+ this.addContext(w3cContext.QRCODE_CONTEXT_URL);
101
104
  return this;
102
105
  }
103
106
  // Sign the document using the provided private key and an optional cryptographic suite.
104
- async sign(privateKey, cryptoSuite) {
107
+ async sign(privateKey, cryptoSuite, options) {
105
108
  if (this.isSigned) throw new Error("Configuration Error: Document is already signed.");
106
109
  if (this.selectedStatusType) {
107
110
  this.document.credentialStatus = this.statusConfig;
@@ -119,16 +122,36 @@ class DocumentBuilder {
119
122
  await this.verifyTokenRegistry();
120
123
  }
121
124
  this.document.issuer = privateKey.id.split("#")[0];
122
- this.document.issuanceDate = this.document.issuanceDate || (/* @__PURE__ */ new Date()).toISOString();
123
- this.addContext("https://w3id.org/security/bbs/v1");
124
- const signedVC = await w3c.signW3C(this.document, privateKey, cryptoSuite);
125
+ this.document.validFrom = this.document.validFrom || (/* @__PURE__ */ new Date()).toISOString();
126
+ if (!cryptoSuite || cryptoSuite === "ecdsa-sd-2023") {
127
+ this.addContext(w3cContext.DATA_INTEGRITY_V2_URL);
128
+ } else {
129
+ this.addContext(w3cContext.BBS_V1_URL);
130
+ }
131
+ const signedVC = await w3c.signW3C(this.document, privateKey, cryptoSuite, options);
125
132
  if (signedVC.error) throw new Error(`Signing Error: ${signedVC.error}`);
126
133
  this.isSigned = true;
127
134
  return signedVC.signed;
128
135
  }
136
+ async derive(revealedAttributes) {
137
+ if (!this.isSigned) throw new Error("Configuration Error: Document is not signed yet.");
138
+ if (this.isDerived) throw new Error("Configuration Error: Document is already derived.");
139
+ const derivedCredential = await w3c.deriveW3C(
140
+ this.document,
141
+ revealedAttributes
142
+ );
143
+ if (derivedCredential.error) throw new Error(`Derivation Error: ${derivedCredential.error}`);
144
+ this.document = derivedCredential.derived;
145
+ this.isDerived = true;
146
+ return derivedCredential.derived;
147
+ }
129
148
  // Verify the document.
130
149
  async verify() {
131
150
  if (!this.isSigned) throw new Error("Verification Error: Document is not signed yet.");
151
+ const cryptosuite = this.document?.proof?.cryptosuite;
152
+ if (cryptosuite === w3cIssuer.CryptoSuite.EcdsaSd2023 && !this.isDerived) {
153
+ throw new Error("Verification Error: Document is not derived yet. Use derive() first.");
154
+ }
132
155
  const verificationResult = await w3c.verifyW3CSignature(
133
156
  this.document
134
157
  );
@@ -167,10 +190,11 @@ class DocumentBuilder {
167
190
  }
168
191
  // Private helper method to build the context for the document, ensuring uniqueness and adding the default W3C context.
169
192
  buildContext(context) {
170
- return [
171
- "https://www.w3.org/2018/credentials/v1",
172
- ...Array.isArray(context) ? context : context ? [context] : []
173
- ].filter((v, i, a) => a.indexOf(v) === i);
193
+ const arrayContext = Array.isArray(context) ? context : context ? [context] : [];
194
+ if (arrayContext.includes(w3cContext.VC_V1_URL)) {
195
+ throw new Error("Document builder does not support data model v1.1.");
196
+ }
197
+ return [w3cContext.VC_V2_URL, ...arrayContext].filter((v, i, a) => a.indexOf(v) === i);
174
198
  }
175
199
  // Private helper method to add a new context to the document if it does not already exist.
176
200
  addContext(context) {
@@ -12,7 +12,6 @@ const {
12
12
  isSignedWrappedV3Document,
13
13
  isRawV2Document,
14
14
  isRawV3Document,
15
- isObfuscated,
16
15
  getDocumentData,
17
16
  getIssuerAddress,
18
17
  diagnose,
@@ -49,7 +48,6 @@ exports.getDocumentData = getDocumentData;
49
48
  exports.getIssuerAddress = getIssuerAddress;
50
49
  exports.getTemplateURL = getTemplateURL;
51
50
  exports.isDocumentRevokable = isDocumentRevokable;
52
- exports.isObfuscated = isObfuscated;
53
51
  exports.isRawV2Document = isRawV2Document;
54
52
  exports.isRawV3Document = isRawV3Document;
55
53
  exports.isSignedWrappedV2Document = isSignedWrappedV2Document;
@@ -73,9 +73,36 @@ const getChainId = /* @__PURE__ */ __name((document) => {
73
73
  return void 0;
74
74
  }
75
75
  }, "getChainId");
76
+ const isObfuscated = /* @__PURE__ */ __name((document) => {
77
+ if (openAttestation.isWrappedV3Document(document)) {
78
+ return !!document.proof.privacy?.obfuscated?.length;
79
+ }
80
+ if (openAttestation.isWrappedV2Document(document)) {
81
+ return !!document.privacy?.obfuscatedData?.length;
82
+ }
83
+ if (vc.isSignedDocument(document)) {
84
+ return document.proof?.type === "BbsBlsSignatureProof2020";
85
+ }
86
+ throw new Error(
87
+ "Unsupported document type: Can only check if there are obfuscated data from wrapped OpenAttestation v2, v3 documents and signed verifiable credentials."
88
+ );
89
+ }, "isObfuscated");
90
+ const getObfuscatedData = /* @__PURE__ */ __name((document) => {
91
+ if (openAttestation.isWrappedV3Document(document)) {
92
+ return document.proof.privacy?.obfuscated;
93
+ }
94
+ if (openAttestation.isWrappedV2Document(document)) {
95
+ return document.privacy?.obfuscatedData || [];
96
+ }
97
+ throw new Error(
98
+ "Unsupported document type: Can only retrieve obfuscated data from wrapped OpenAttestation v2 & v3 documents."
99
+ );
100
+ }, "getObfuscatedData");
76
101
 
77
102
  exports.getChainId = getChainId;
103
+ exports.getObfuscatedData = getObfuscatedData;
78
104
  exports.getTokenId = getTokenId;
79
105
  exports.getTokenRegistryAddress = getTokenRegistryAddress;
80
106
  exports.getTransferableRecordsCredentialStatus = getTransferableRecordsCredentialStatus;
107
+ exports.isObfuscated = isObfuscated;
81
108
  exports.isTransferableRecord = isTransferableRecord;