@trustvc/trustvc 1.6.0-alpha.6 → 1.6.0-alpha.7
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.
- package/README.md +35 -26
- package/dist/cjs/core/documentBuilder.js +38 -14
- package/dist/cjs/verify/fragments/document-integrity/ecdsaW3CSignatureIntegrity.js +3 -3
- package/dist/cjs/verify/fragments/document-integrity/w3cSignatureIntegrity.js +2 -2
- package/dist/esm/core/documentBuilder.js +39 -15
- package/dist/esm/verify/fragments/document-integrity/ecdsaW3CSignatureIntegrity.js +1 -1
- package/dist/esm/verify/fragments/document-integrity/w3cSignatureIntegrity.js +1 -1
- package/dist/types/core/documentBuilder.d.ts +14 -4
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -677,7 +677,7 @@ function rejectTransferOwners(bytes calldata _remark) external;
|
|
|
677
677
|
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)
|
|
678
678
|
|
|
679
679
|
### 8. **Document Builder**
|
|
680
|
-
> 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.
|
|
680
|
+
> 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.
|
|
681
681
|
|
|
682
682
|
#### Usage
|
|
683
683
|
|
|
@@ -690,7 +690,7 @@ To learn more about defining custom contexts, check out the [Credential Subject
|
|
|
690
690
|
// Adds a custom vocabulary used to define terms in the `credentialSubject`.
|
|
691
691
|
// Users can define their own context if they have domain-specific fields or custom data structures.
|
|
692
692
|
const builder = new DocumentBuilder({
|
|
693
|
-
'@context': 'https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-
|
|
693
|
+
'@context': 'https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld'
|
|
694
694
|
});
|
|
695
695
|
```
|
|
696
696
|
|
|
@@ -699,8 +699,8 @@ Set the subject of the Verifiable Credential, which typically contains informati
|
|
|
699
699
|
|
|
700
700
|
```ts
|
|
701
701
|
builder.credentialSubject({
|
|
702
|
-
|
|
703
|
-
|
|
702
|
+
type: ['Person'],
|
|
703
|
+
givenName: 'TrustVC',
|
|
704
704
|
});
|
|
705
705
|
```
|
|
706
706
|
|
|
@@ -736,7 +736,7 @@ builder.credentialStatus({
|
|
|
736
736
|
```
|
|
737
737
|
|
|
738
738
|
##### Set Expiration Date
|
|
739
|
-
You can set
|
|
739
|
+
You can set a valid until date (expiration) for the document.
|
|
740
740
|
|
|
741
741
|
```ts
|
|
742
742
|
builder.expirationDate('2026-01-01T00:00:00Z');
|
|
@@ -764,16 +764,17 @@ builder.qrCode({
|
|
|
764
764
|
```
|
|
765
765
|
|
|
766
766
|
##### Sign the Document
|
|
767
|
-
To sign the document, provide a `PrivateKeyPair` from `@trustvc/trustvc`.
|
|
767
|
+
To sign the document, provide a `PrivateKeyPair` from `@trustvc/trustvc`. The builder uses ECDSA key for signing by default.
|
|
768
768
|
|
|
769
769
|
```ts
|
|
770
770
|
const privateKey: PrivateKeyPair = {
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
771
|
+
'@context': 'https://w3id.org/security/multikey/v1',
|
|
772
|
+
id: 'did:web:example.com#multikey-1',
|
|
773
|
+
type: VerificationType.Multikey,
|
|
774
|
+
controller: 'did:web:example.com',
|
|
775
|
+
publicKeyMultibase: 'your-public-key-multibase',
|
|
776
|
+
secretKeyMultibase: 'your-secret-key-multibase',
|
|
777
|
+
}
|
|
777
778
|
|
|
778
779
|
const signedDocument = await builder.sign(privateKey);
|
|
779
780
|
console.log(signedDocument);
|
|
@@ -783,19 +784,18 @@ Example Output After Signing
|
|
|
783
784
|
```json
|
|
784
785
|
{
|
|
785
786
|
"@context": [
|
|
786
|
-
"https://www.w3.org/
|
|
787
|
-
"https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-
|
|
788
|
-
"https://
|
|
789
|
-
"https://trustvc.io/context/render-method-context.json",
|
|
787
|
+
"https://www.w3.org/ns/credentials/v2",
|
|
788
|
+
"https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld",
|
|
789
|
+
"https://trustvc.io/context/render-method-context-v2.json",
|
|
790
790
|
"https://trustvc.io/context/qrcode-context.json",
|
|
791
|
-
"https://w3id.org/security/
|
|
791
|
+
"https://w3id.org/security/data-integrity/v2"
|
|
792
792
|
],
|
|
793
793
|
"type": ["VerifiableCredential"],
|
|
794
794
|
"credentialSubject": {
|
|
795
|
-
"
|
|
796
|
-
"
|
|
795
|
+
"type": ["Person"],
|
|
796
|
+
"givenName": "TrustVC",
|
|
797
797
|
},
|
|
798
|
-
"
|
|
798
|
+
"validUntil": "2026-01-01T00:00:00Z",
|
|
799
799
|
"renderMethod": [
|
|
800
800
|
{
|
|
801
801
|
"id": "https://example.com/rendering-method",
|
|
@@ -814,21 +814,30 @@ Example Output After Signing
|
|
|
814
814
|
"statusListIndex": "<placeholder>",
|
|
815
815
|
"statusListCredential": "https://example.com/status-list"
|
|
816
816
|
},
|
|
817
|
-
"issuer": "did:example
|
|
818
|
-
"
|
|
817
|
+
"issuer": "did:web:example.com",
|
|
818
|
+
"validFrom": "2025-01-01T00:00:00Z",
|
|
819
819
|
"id": "urn:bnid:_:0195fec2-4ae1-7cca-9182-03fd7da5142b",
|
|
820
820
|
"proof": {
|
|
821
|
-
"type": "
|
|
821
|
+
"type": "DataIntegrityProof",
|
|
822
822
|
"created": "2025-01-01T00:00:01Z",
|
|
823
|
+
"verificationMethod": "did:web:example.com#multikey-1",
|
|
824
|
+
"cryptosuite": "ecdsa-sd-2023",
|
|
823
825
|
"proofPurpose": "assertionMethod",
|
|
824
|
-
"proofValue": "
|
|
825
|
-
"verificationMethod": "did:example:456#key1"
|
|
826
|
+
"proofValue": "u2V0AhVhAh1oLoiuV2AwmSa2ZspbmrG2gCDbpZW.......",
|
|
826
827
|
}
|
|
827
828
|
}
|
|
828
829
|
```
|
|
829
830
|
|
|
831
|
+
##### Deriving the Document
|
|
832
|
+
Provide the attributes to reveal to the `derive` method.
|
|
833
|
+
|
|
834
|
+
```ts
|
|
835
|
+
const derivedDocument = await builder.derive(['/credentialSubject/givenName']);
|
|
836
|
+
console.log(derivedDocument);
|
|
837
|
+
```
|
|
838
|
+
|
|
830
839
|
##### Verify the Document
|
|
831
|
-
To verify the signature of the signed document
|
|
840
|
+
To verify the signature of the signed document, ensure the document is derived first and then call the `verify` method.
|
|
832
841
|
|
|
833
842
|
```ts
|
|
834
843
|
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(
|
|
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: "
|
|
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.
|
|
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(
|
|
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(
|
|
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.
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var verify = require('../../../w3c/verify');
|
|
4
4
|
var w3cVc = require('@trustvc/w3c-vc');
|
|
5
5
|
|
|
6
6
|
var __defProp = Object.defineProperty;
|
|
@@ -42,11 +42,11 @@ const ecdsaW3CSignatureIntegrity = {
|
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
try {
|
|
45
|
-
let verificationResult = await
|
|
45
|
+
let verificationResult = await verify.verifyW3CSignature(document, verifierOptions);
|
|
46
46
|
let isDerived = true;
|
|
47
47
|
if (!verificationResult.verified && verificationResult.error?.includes(DERIVE_CREDENTIAL_ERROR)) {
|
|
48
48
|
const derivedCredential = await w3cVc.deriveCredential(document, []);
|
|
49
|
-
verificationResult = await
|
|
49
|
+
verificationResult = await verify.verifyW3CSignature(derivedCredential.derived, verifierOptions);
|
|
50
50
|
isDerived = false;
|
|
51
51
|
}
|
|
52
52
|
if (verificationResult.verified) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var verify = require('../../../w3c/verify');
|
|
4
4
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
@@ -23,7 +23,7 @@ const w3cSignatureIntegrity = {
|
|
|
23
23
|
}, "test"),
|
|
24
24
|
verify: /* @__PURE__ */ __name(async (document, verifierOptions) => {
|
|
25
25
|
const doc = document;
|
|
26
|
-
const verificationResult = await
|
|
26
|
+
const verificationResult = await verify.verifyW3CSignature(doc, verifierOptions);
|
|
27
27
|
if (verificationResult.verified) {
|
|
28
28
|
return {
|
|
29
29
|
type: "DOCUMENT_INTEGRITY",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CryptoSuite } from '@trustvc/w3c-issuer';
|
|
2
|
+
import { signW3C, deriveW3C, verifyW3CSignature } from '../w3c';
|
|
2
3
|
import { assertCredentialStatus, assertTransferableRecords } from '@trustvc/w3c-credential-status';
|
|
3
4
|
import { verifyCredentialStatus } from '@trustvc/w3c-vc';
|
|
4
5
|
import { ethers } from 'ethers';
|
|
@@ -7,6 +8,7 @@ import { constants as constants$1 } from '@tradetrust-tt/token-registry-v5';
|
|
|
7
8
|
import { v4Contracts } from '../token-registry-v4';
|
|
8
9
|
import { v5Contracts } from '../token-registry-v5';
|
|
9
10
|
import { SUPPORTED_CHAINS } from '../utils';
|
|
11
|
+
import { TR_CONTEXT_URL, RENDER_CONTEXT_V2_URL, QRCODE_CONTEXT_URL, DATA_INTEGRITY_V2_URL, BBS_V1_URL, VC_V1_URL, VC_V2_URL } from '@trustvc/w3c-context';
|
|
10
12
|
|
|
11
13
|
var __defProp = Object.defineProperty;
|
|
12
14
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
@@ -28,6 +30,8 @@ class DocumentBuilder {
|
|
|
28
30
|
// Required fields that must be present in the document.
|
|
29
31
|
isSigned = false;
|
|
30
32
|
// Tracks if a document is signed
|
|
33
|
+
isDerived = false;
|
|
34
|
+
// Tracks if a document is derived
|
|
31
35
|
/**
|
|
32
36
|
* Constructor to initialize the document builder.
|
|
33
37
|
* @param {Partial<VerifiableCredential>} input - The input document.
|
|
@@ -61,18 +65,17 @@ class DocumentBuilder {
|
|
|
61
65
|
tokenRegistry: config.tokenRegistry
|
|
62
66
|
};
|
|
63
67
|
this.rpcProviderUrl = config.rpcProviderUrl;
|
|
64
|
-
this.addContext(
|
|
68
|
+
this.addContext(TR_CONTEXT_URL);
|
|
65
69
|
} else if (isVerifiable) {
|
|
66
70
|
this.selectedStatusType = "verifiableDocument";
|
|
67
71
|
this.statusConfig = {
|
|
68
72
|
id: `${config.url}#${config.index}`,
|
|
69
|
-
type: "
|
|
73
|
+
type: "BitstringStatusListEntry",
|
|
70
74
|
statusPurpose: config.purpose || "revocation",
|
|
71
75
|
// Set status purpose to "revocation" by default.
|
|
72
76
|
statusListIndex: config.index,
|
|
73
77
|
statusListCredential: config.url
|
|
74
78
|
};
|
|
75
|
-
this.addContext("https://w3id.org/vc/status-list/2021/v1");
|
|
76
79
|
} else {
|
|
77
80
|
throw new Error("Configuration Error: Missing required fields for credential status.");
|
|
78
81
|
}
|
|
@@ -81,25 +84,25 @@ class DocumentBuilder {
|
|
|
81
84
|
// Sets the expiration date of the document.
|
|
82
85
|
expirationDate(date) {
|
|
83
86
|
if (this.isSigned) throw new Error("Configuration Error: Document is already signed.");
|
|
84
|
-
this.document.
|
|
87
|
+
this.document.validUntil = typeof date === "string" ? date : date.toISOString();
|
|
85
88
|
return this;
|
|
86
89
|
}
|
|
87
90
|
// Defines the rendering method for the document.
|
|
88
91
|
renderMethod(method) {
|
|
89
92
|
if (this.isSigned) throw new Error("Configuration Error: Document is already signed.");
|
|
90
93
|
this.document.renderMethod = [method];
|
|
91
|
-
this.addContext(
|
|
94
|
+
this.addContext(RENDER_CONTEXT_V2_URL);
|
|
92
95
|
return this;
|
|
93
96
|
}
|
|
94
97
|
// Defines the qrcode for the document.
|
|
95
98
|
qrCode(method) {
|
|
96
99
|
if (this.isSigned) throw new Error("Configuration Error: Document is already signed.");
|
|
97
100
|
this.document.qrCode = method;
|
|
98
|
-
this.addContext(
|
|
101
|
+
this.addContext(QRCODE_CONTEXT_URL);
|
|
99
102
|
return this;
|
|
100
103
|
}
|
|
101
104
|
// Sign the document using the provided private key and an optional cryptographic suite.
|
|
102
|
-
async sign(privateKey, cryptoSuite) {
|
|
105
|
+
async sign(privateKey, cryptoSuite, options) {
|
|
103
106
|
if (this.isSigned) throw new Error("Configuration Error: Document is already signed.");
|
|
104
107
|
if (this.selectedStatusType) {
|
|
105
108
|
this.document.credentialStatus = this.statusConfig;
|
|
@@ -117,16 +120,36 @@ class DocumentBuilder {
|
|
|
117
120
|
await this.verifyTokenRegistry();
|
|
118
121
|
}
|
|
119
122
|
this.document.issuer = privateKey.id.split("#")[0];
|
|
120
|
-
this.document.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
+
this.document.validFrom = this.document.validFrom || (/* @__PURE__ */ new Date()).toISOString();
|
|
124
|
+
if (!cryptoSuite || cryptoSuite === "ecdsa-sd-2023") {
|
|
125
|
+
this.addContext(DATA_INTEGRITY_V2_URL);
|
|
126
|
+
} else {
|
|
127
|
+
this.addContext(BBS_V1_URL);
|
|
128
|
+
}
|
|
129
|
+
const signedVC = await signW3C(this.document, privateKey, cryptoSuite, options);
|
|
123
130
|
if (signedVC.error) throw new Error(`Signing Error: ${signedVC.error}`);
|
|
124
131
|
this.isSigned = true;
|
|
125
132
|
return signedVC.signed;
|
|
126
133
|
}
|
|
134
|
+
async derive(revealedAttributes) {
|
|
135
|
+
if (!this.isSigned) throw new Error("Configuration Error: Document is not signed yet.");
|
|
136
|
+
if (this.isDerived) throw new Error("Configuration Error: Document is already derived.");
|
|
137
|
+
const derivedCredential = await deriveW3C(
|
|
138
|
+
this.document,
|
|
139
|
+
revealedAttributes
|
|
140
|
+
);
|
|
141
|
+
if (derivedCredential.error) throw new Error(`Derivation Error: ${derivedCredential.error}`);
|
|
142
|
+
this.document = derivedCredential.derived;
|
|
143
|
+
this.isDerived = true;
|
|
144
|
+
return derivedCredential.derived;
|
|
145
|
+
}
|
|
127
146
|
// Verify the document.
|
|
128
147
|
async verify() {
|
|
129
148
|
if (!this.isSigned) throw new Error("Verification Error: Document is not signed yet.");
|
|
149
|
+
const cryptosuite = this.document?.proof?.cryptosuite;
|
|
150
|
+
if (cryptosuite === CryptoSuite.EcdsaSd2023 && !this.isDerived) {
|
|
151
|
+
throw new Error("Verification Error: Document is not derived yet. Use derive() first.");
|
|
152
|
+
}
|
|
130
153
|
const verificationResult = await verifyW3CSignature(
|
|
131
154
|
this.document
|
|
132
155
|
);
|
|
@@ -165,10 +188,11 @@ class DocumentBuilder {
|
|
|
165
188
|
}
|
|
166
189
|
// Private helper method to build the context for the document, ensuring uniqueness and adding the default W3C context.
|
|
167
190
|
buildContext(context) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
191
|
+
const arrayContext = Array.isArray(context) ? context : context ? [context] : [];
|
|
192
|
+
if (arrayContext.includes(VC_V1_URL)) {
|
|
193
|
+
throw new Error("Document builder does not support data model v1.1.");
|
|
194
|
+
}
|
|
195
|
+
return [VC_V2_URL, ...arrayContext].filter((v, i, a) => a.indexOf(v) === i);
|
|
172
196
|
}
|
|
173
197
|
// Private helper method to add a new context to the document if it does not already exist.
|
|
174
198
|
addContext(context) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PrivateKeyPair } from '@trustvc/w3c-issuer';
|
|
2
|
-
import { VerifiableCredential, CryptoSuiteName, SignedVerifiableCredential } from '@trustvc/w3c-vc';
|
|
2
|
+
import { VerifiableCredential, CryptoSuiteName, SignedVerifiableCredential, ContextDocument } from '@trustvc/w3c-vc';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Configuration for a W3C Verifiable Document using a Bitstring Status List.
|
|
@@ -39,7 +39,7 @@ interface RenderMethod {
|
|
|
39
39
|
templateName: string;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
-
* Configuration for the
|
|
42
|
+
* Configuration for the qrcode used in a Verifiable Credential document.
|
|
43
43
|
* @property {string} uri - A unique identifier for the qrcode, typically a URL or URI.
|
|
44
44
|
* @property {string} type - The type of the qrcode method (e.g., 'TrustVCQRCode').
|
|
45
45
|
*/
|
|
@@ -47,8 +47,16 @@ interface qrCode {
|
|
|
47
47
|
uri: string;
|
|
48
48
|
type: string;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Options for signing a document.
|
|
52
|
+
* @property {string[]} mandatoryPointers - The mandatory pointers to be used for signing the document.
|
|
53
|
+
*/
|
|
54
|
+
interface SignOptions {
|
|
55
|
+
mandatoryPointers?: string[];
|
|
56
|
+
}
|
|
50
57
|
/**
|
|
51
58
|
* Main class responsible for building, configuring, and signing documents with credential statuses.
|
|
59
|
+
* This class implements the W3C Verifiable Credentials Data Model 2.0 specification.
|
|
52
60
|
*/
|
|
53
61
|
declare class DocumentBuilder {
|
|
54
62
|
private document;
|
|
@@ -58,6 +66,7 @@ declare class DocumentBuilder {
|
|
|
58
66
|
private rpcProviderUrl;
|
|
59
67
|
private requiredFields;
|
|
60
68
|
private isSigned;
|
|
69
|
+
private isDerived;
|
|
61
70
|
/**
|
|
62
71
|
* Constructor to initialize the document builder.
|
|
63
72
|
* @param {Partial<VerifiableCredential>} input - The input document.
|
|
@@ -69,7 +78,8 @@ declare class DocumentBuilder {
|
|
|
69
78
|
expirationDate(date: string | Date): this;
|
|
70
79
|
renderMethod(method: RenderMethod): this;
|
|
71
80
|
qrCode(method: qrCode): this;
|
|
72
|
-
sign(privateKey: PrivateKeyPair, cryptoSuite?: CryptoSuiteName): Promise<SignedVerifiableCredential>;
|
|
81
|
+
sign(privateKey: PrivateKeyPair, cryptoSuite?: CryptoSuiteName, options?: SignOptions): Promise<SignedVerifiableCredential>;
|
|
82
|
+
derive(revealedAttributes: ContextDocument | string[]): Promise<SignedVerifiableCredential>;
|
|
73
83
|
verify(): Promise<boolean>;
|
|
74
84
|
toString(): string;
|
|
75
85
|
private isTransferableRecordsConfig;
|
|
@@ -82,4 +92,4 @@ declare class DocumentBuilder {
|
|
|
82
92
|
private supportsInterface;
|
|
83
93
|
}
|
|
84
94
|
|
|
85
|
-
export { DocumentBuilder, type RenderMethod, type W3CTransferableRecordsConfig, type W3CVerifiableDocumentConfig, type qrCode };
|
|
95
|
+
export { DocumentBuilder, type RenderMethod, type SignOptions, type W3CTransferableRecordsConfig, type W3CVerifiableDocumentConfig, type qrCode };
|
|
@@ -7,7 +7,7 @@ export { fetchEventTime, mergeTransfersV4, mergeTransfersV5, sortLogChain } from
|
|
|
7
7
|
export { getEndorsementChain } from './endorsement-chain/retrieveEndorsementChain.js';
|
|
8
8
|
export { EndorsementChain, ParsedLog, TitleEscrowTransferEvent, TitleEscrowTransferEventType, TokenTransferEvent, TokenTransferEventType, TradeTrustTokenEventType, TransferBaseEvent, TransferEvent, TransferEventType, TypedEvent } from './endorsement-chain/types.js';
|
|
9
9
|
export { TitleEscrowInterface, checkSupportsInterface, fetchEndorsementChain, getDocumentOwner, getTitleEscrowAddress, isTitleEscrowVersion } from './endorsement-chain/useEndorsementChain.js';
|
|
10
|
-
export { DocumentBuilder, RenderMethod, W3CTransferableRecordsConfig, W3CVerifiableDocumentConfig, qrCode } from './documentBuilder.js';
|
|
10
|
+
export { DocumentBuilder, RenderMethod, SignOptions, W3CTransferableRecordsConfig, W3CVerifiableDocumentConfig, qrCode } from './documentBuilder.js';
|
|
11
11
|
import '@trustvc/w3c-vc';
|
|
12
12
|
import 'ethers';
|
|
13
13
|
import '@tradetrust-tt/tt-verify/dist/types/src/types/core';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export { fetchEventTime, mergeTransfersV4, mergeTransfersV5, sortLogChain } from
|
|
|
24
24
|
export { getEndorsementChain } from './core/endorsement-chain/retrieveEndorsementChain.js';
|
|
25
25
|
export { EndorsementChain, ParsedLog, TitleEscrowTransferEvent, TitleEscrowTransferEventType, TokenTransferEvent, TokenTransferEventType, TradeTrustTokenEventType, TransferBaseEvent, TransferEvent, TransferEventType, TypedEvent } from './core/endorsement-chain/types.js';
|
|
26
26
|
export { TitleEscrowInterface, checkSupportsInterface, fetchEndorsementChain, getDocumentOwner, getTitleEscrowAddress, isTitleEscrowVersion } from './core/endorsement-chain/useEndorsementChain.js';
|
|
27
|
-
export { DocumentBuilder, RenderMethod, W3CTransferableRecordsConfig, W3CVerifiableDocumentConfig, qrCode } from './core/documentBuilder.js';
|
|
27
|
+
export { DocumentBuilder, RenderMethod, SignOptions, W3CTransferableRecordsConfig, W3CVerifiableDocumentConfig, qrCode } from './core/documentBuilder.js';
|
|
28
28
|
export { signOA } from './open-attestation/sign.js';
|
|
29
29
|
export { KeyPair } from './open-attestation/types.js';
|
|
30
30
|
export { diagnose, getAssetId, getDocumentData, getIssuerAddress, getTemplateURL, isDocumentRevokable, isRawV2Document, isRawV3Document, isSignedWrappedV2Document, isSignedWrappedV3Document, isTransferableAsset, isWrappedV2Document, isWrappedV3Document } from './open-attestation/utils.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trustvc/trustvc",
|
|
3
|
-
"version": "1.6.0-alpha.
|
|
3
|
+
"version": "1.6.0-alpha.7",
|
|
4
4
|
"description": "TrustVC library",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -121,11 +121,11 @@
|
|
|
121
121
|
"@tradetrust-tt/tradetrust": "^6.10.2",
|
|
122
122
|
"@tradetrust-tt/tradetrust-utils": "^2.4.2",
|
|
123
123
|
"@tradetrust-tt/tt-verify": "^9.5.1",
|
|
124
|
-
"@trustvc/w3c": "^1.3.0-alpha.
|
|
125
|
-
"@trustvc/w3c-context": "^1.3.0-alpha.
|
|
126
|
-
"@trustvc/w3c-credential-status": "^1.3.0-alpha.
|
|
124
|
+
"@trustvc/w3c": "^1.3.0-alpha.7",
|
|
125
|
+
"@trustvc/w3c-context": "^1.3.0-alpha.7",
|
|
126
|
+
"@trustvc/w3c-credential-status": "^1.3.0-alpha.7",
|
|
127
127
|
"@trustvc/w3c-issuer": "^1.3.0-alpha.5",
|
|
128
|
-
"@trustvc/w3c-vc": "^1.3.0-alpha.
|
|
128
|
+
"@trustvc/w3c-vc": "^1.3.0-alpha.7",
|
|
129
129
|
"ethers": "^5.8.0",
|
|
130
130
|
"ethersV6": "npm:ethers@^6.14.4",
|
|
131
131
|
"js-sha3": "^0.9.3",
|