Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ const signedWrappedDocument = await signOA(wrappedDocument, {

#### b) TrustVC W3C Signing (signW3C)

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.
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. It also supports **bbs-2023** for modern BBS signatures.

```ts
import { signW3C, VerificationType } from '@trustvc/trustvc';
Expand Down Expand Up @@ -195,7 +195,7 @@ const signingResult = await signW3C(rawDocument, {
secretKeyMultibase: '<secretKeyMultibase>'
});

// You can also specify mandatory pointers for selective disclosure with ecdsa-sd-2023
// You can also specify mandatory pointers for selective disclosure with ecdsa-sd-2023 / bbs-2023
const signingResultWithPointers = await signW3C(
rawDocument,
{
Expand All @@ -212,7 +212,22 @@ const signingResultWithPointers = await signW3C(
}
);

// Alternatively, specify a different crypto suite. Ensure the context is updated to include the crypto suite.
// Using BBS-2023 cryptosuite
const signingResultWithBbs2023 = await signW3C(
rawDocument,
{
'@context': 'https://w3id.org/security/multikey/v1',
id: 'did:web:trustvc.github.io:did:1#multikey-2',
type: VerificationType.Multikey,
controller: 'did:web:trustvc.github.io:did:1',
publicKeyMultibase: 'zUC75kRac7BdtjawFUxowfgD6mzqnRHFxAfMDaBynebdYgakviQkPS1KNJEw7uGWqj91H3hSE4pTERb3EZKLgKXjpqHWrN8dyE8SKyPBE3k7kUGjBNAqJoNGgUzqUW3DSaWrcNr',
secretKeyMultibase: '<secretKeyMultibase>',
},
'bbs-2023'
);

// ⚠️ DEPRECATED: BbsBlsSignature2020 is no longer supported
// Use 'ecdsa-sd-20203 or bbs-2023' cryptosuite instead as shown above
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
const signingResultWithBbs = await signW3C(
rawDocument,
{
Expand All @@ -222,7 +237,7 @@ const signingResultWithBbs = await signW3C(
publicKeyBase58: 'oRfEeWFresvhRtXCkihZbxyoi2JER7gHTJ5psXhHsdCoU1MttRMi3Yp9b9fpjmKh7bMgfWKLESiK2YovRd8KGzJsGuamoAXfqDDVhckxuc9nmsJ84skCSTijKeU4pfAcxeJ',
privateKeyBase58: '<privateKeyBase58>',
},
'BbsBlsSignature2020'
'BbsBlsSignature2020' // This will return an error
);

```
Expand All @@ -231,7 +246,7 @@ const signingResultWithBbs = await signW3C(

### 3. **Deriving (Selective Disclosure)**

> 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.
> When using ECDSA-SD-2023 or BBS-2023 crypto suites, 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.

```ts
import { deriveW3C } from '@trustvc/trustvc';
Expand Down Expand Up @@ -282,7 +297,7 @@ const derivationResult = await deriveW3C(signedDocument, {

### 4. **Verifying**

> 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.
> 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-SD-2023 and BBS-2023 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.

```ts
import { verifyDocument } from '@trustvc/trustvc';
Expand Down
73 changes: 45 additions & 28 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@
"@tradetrust-tt/tradetrust": "^6.10.2",
"@tradetrust-tt/tradetrust-utils": "^2.4.2",
"@tradetrust-tt/tt-verify": "^9.6.0",
"@trustvc/w3c": "^1.3.0-alpha.11",
"@trustvc/w3c-context": "^1.3.0-alpha.10",
"@trustvc/w3c-credential-status": "^1.3.0-alpha.10",
"@trustvc/w3c-issuer": "^1.3.0-alpha.8",
"@trustvc/w3c-vc": "^1.3.0-alpha.11",
"@trustvc/w3c": "^1.3.0-alpha.14",
"@trustvc/w3c-context": "^1.3.0-alpha.12",
"@trustvc/w3c-credential-status": "^1.3.0-alpha.12",
"@trustvc/w3c-issuer": "^1.3.0-alpha.10",
"@trustvc/w3c-vc": "^1.3.0-alpha.14",
"ethers": "^5.8.0",
"ethersV6": "npm:ethers@^6.14.4",
"js-sha3": "^0.9.3",
Expand Down
116 changes: 15 additions & 101 deletions src/__tests__/core/documentBuilder.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { DocumentBuilder } from '../../core/documentBuilder';
import { PrivateKeyPair, VerificationType } from '@trustvc/w3c-issuer';
import { ContextDocument } from '@trustvc/w3c-context';

const BBS2020testPrivateKey: PrivateKeyPair = {
id: 'did:web:trustvc.github.io:did:1#keys-1',
Expand All @@ -25,7 +24,9 @@ describe('DocumentBuilder data model 2.0 using ECDSA', () => {
let documentBuilder: DocumentBuilder;

beforeEach(() => {
documentBuilder = new DocumentBuilder({}).credentialSubject({});
documentBuilder = new DocumentBuilder({
'@context': 'https://trustvc.io/context/bill-of-lading.json',
}).credentialSubject({ type: ['BillOfLading'] });
});

describe('Initialization', () => {
Expand All @@ -35,6 +36,7 @@ describe('DocumentBuilder data model 2.0 using ECDSA', () => {
'@context': expect.arrayContaining([
'https://www.w3.org/ns/credentials/v2',
'https://w3id.org/security/data-integrity/v2',
'https://trustvc.io/context/bill-of-lading.json',
]),
type: expect.arrayContaining(['VerifiableCredential']),
});
Expand All @@ -45,9 +47,12 @@ describe('DocumentBuilder data model 2.0 using ECDSA', () => {
it('should return the current state of the document as a JSON string', () => {
const expectedJson = JSON.stringify(
{
'@context': ['https://www.w3.org/ns/credentials/v2'],
'@context': [
'https://www.w3.org/ns/credentials/v2',
'https://trustvc.io/context/bill-of-lading.json',
],
type: ['VerifiableCredential'],
credentialSubject: {},
credentialSubject: { type: ['BillOfLading'] },
},
null,
2,
Expand Down Expand Up @@ -275,102 +280,11 @@ describe('DocumentBuilder Data model 2.0 using BBS2020', () => {
documentBuilder = new DocumentBuilder({}).credentialSubject({});
});

describe('Initialization', () => {
it('should initialize with default context and type', async () => {
const signedDocument = await documentBuilder.sign(
BBS2020testPrivateKey,
'BbsBlsSignature2020',
);
expect(signedDocument).toMatchObject({
'@context': expect.arrayContaining([
'https://www.w3.org/ns/credentials/v2',
'https://w3id.org/security/bbs/v1',
]),
type: expect.arrayContaining(['VerifiableCredential']),
});
});
});

describe('Validation Errors', () => {
it('should throw an error when required fields are missing', async () => {
await expect(
new DocumentBuilder({}).sign(BBS2020testPrivateKey, 'BbsBlsSignature2020'),
).rejects.toThrow(
'Validation Error: Missing required field "credentialSubject" in the credential.',
);
});

it('should throw an error when document is already signed', async () => {
await documentBuilder.sign(BBS2020testPrivateKey, 'BbsBlsSignature2020');
expect(() =>
documentBuilder.credentialStatus({
chain: 'amoy',
chainId: 80002,
tokenRegistry: '0x71D28767662cB233F887aD2Bb65d048d760bA694',
rpcProviderUrl: 'https://rpc-amoy.polygon.technology',
}),
).toThrow('Configuration Error: Document is already signed.');
});
});

describe('Signing and Verification', () => {
it('should sign and verify the document successfully for transferableRecords', async () => {
documentBuilder.credentialStatus({
chain: 'amoy',
chainId: 80002,
tokenRegistry: '0x71D28767662cB233F887aD2Bb65d048d760bA694',
rpcProviderUrl: 'https://rpc-amoy.polygon.technology',
});
const signedDocument = await documentBuilder.sign(
BBS2020testPrivateKey,
'BbsBlsSignature2020',
);
expect(signedDocument).toBeDefined();
const verificationResult = await documentBuilder.verify();
expect(verificationResult).toBe(true);
});

it('should sign and verify the document successfully for verifiableDocument', async () => {
documentBuilder.credentialStatus({
url: 'https://trustvc.github.io/did/credentials/statuslist/1',
index: 10, // Not revoked
});
const signedDocument = await documentBuilder.sign(
BBS2020testPrivateKey,
'BbsBlsSignature2020',
);
expect(signedDocument).toBeDefined();
const verificationResult = await documentBuilder.verify();
expect(verificationResult).toBe(true);
});

it('should not verify the document if it is not signed yet', async () => {
await expect(documentBuilder.verify()).rejects.toThrow(
'Verification Error: Document is not signed yet.',
);
});

it('should be able to derive document and verify derived document', async () => {
const contextDocument: ContextDocument = {
'@context': [
'https://www.w3.org/ns/credentials/v2',
'https://w3id.org/security/bbs/v1',
'https://trustvc.io/context/transferable-records-context.json',
],
type: ['VerifiableCredential'],
};

documentBuilder.credentialStatus({
chain: 'amoy',
chainId: 80002,
tokenRegistry: '0x71D28767662cB233F887aD2Bb65d048d760bA694',
rpcProviderUrl: 'https://rpc-amoy.polygon.technology',
});
await documentBuilder.sign(BBS2020testPrivateKey, 'BbsBlsSignature2020');
const derivedDocument = await documentBuilder.derive(contextDocument);
expect(derivedDocument).toBeDefined();
const verificationResult = await documentBuilder.verify();
expect(verificationResult).toBe(true);
});
it('should throw error when trying to sign with BbsBlsSignature2020', async () => {
await expect(
documentBuilder.sign(BBS2020testPrivateKey, 'BbsBlsSignature2020'),
).rejects.toThrow(
'BbsBlsSignature2020 is no longer supported. Please use the latest cryptosuite versions instead',
);
});
});
Loading
Loading