Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Sample files for testing
fixtures

# Generated files from CLI commands
keypair.json
didKeyPairs.json
wellknown.json
credentialStatus.json
signed_vc.json

# Dependencies
node_modules/
Expand Down
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ A command-line interface tool for working with Decentralized Identifiers (DIDs),
- ✅ **Modern Cryptosuites**: Full support for ECDSA-SD-2023 and BBS-2023
- ✅ **Key Pair Generation**: Generate cryptographic key pairs with Multikey format
- ✅ **DID Management**: Create and manage did:web identifiers
- ✅ **Sign Verifiable Credentials**: Sign verifiable credentials
- ✅ **Token Registry**: Mint tokens to blockchain-based token registries
- ✅ **Credential Status**: Create and update W3C credential status lists
- ✅ **W3C Standards**: Compliant with latest W3C DID and Verifiable Credentials specifications
Expand All @@ -26,6 +27,7 @@ This CLI leverages the TrustVC package:
- [Commands](#commands)
- [`trustvc key-pair-generation`](#trustvc-key-pair-generation)
- [`trustvc did-web`](#trustvc-did-web)
- [`trustvc w3c-sign`](#trustvc-w3c-sign)
- [`trustvc credential-status-create`](#trustvc-credential-status-create)
- [`trustvc credential-status-update`](#trustvc-credential-status-update)
- [`trustvc mint`](#trustvc-mint)
Expand Down Expand Up @@ -56,6 +58,9 @@ trustvc key-pair-generation
# Create a DID from the key pair
trustvc did-web

# Sign a verifiable credential
trustvc w3c-sign

# Create a credential status list
trustvc credential-status-create

Expand All @@ -72,6 +77,8 @@ trustvc mint

- **Generating Well-Known DID**: The CLI uses the `issueDID` function from `@trustvc/trustvc` to generate a did:web identifier. This allows users to self-host their DID as a unique identifier in decentralized systems.

- **Sign Verifiable Credentials**: The CLI uses the `w3cSign` function from `@trustvc/trustvc` to sign verifiable credentials with the provided did:web identifier.

- **Credential Status Management**: The CLI provides commands to create and update W3C credential status lists for managing the revocation status of verifiable credentials.

- **Token Registry Minting**: The CLI uses the `mint` function from `@trustvc/trustvc` to mint document hashes to blockchain-based token registries, supporting multiple networks including Ethereum, Polygon, XDC, Stability, and Astron.
Expand Down Expand Up @@ -117,6 +124,23 @@ Generates a did:web identifier from an existing key pair. Supports modern Multik
trustvc did-web
```

### `trustvc w3c-sign`

Signs a verifiable credential using a did:web identifier.

**Interactive prompts:**
- Path to did:web key-pair JSON file
- Path to unsigned verifiable credential JSON file
- Select cryptosuite (ECDSA-SD-2023 or BBS-2023, must match the key pair)
- Output directory

**Output:** Creates a signed verifiable credential file: `signed_vc.json`.

**Example:**
```sh
trustvc w3c-sign
```

### `trustvc credential-status-create`

Creates a new W3C credential status list for managing the revocation status of verifiable credentials.
Expand Down Expand Up @@ -255,6 +279,7 @@ npm test
│ │ └── w3c/
│ │ ├── did.ts # DID generation command
│ │ ├── key-pair.ts # Key pair generation command
│ │ ├── sign.ts # Sign verifiable credential command
│ │ └── credentialStatus/
│ │ ├── create.ts # Create credential status
│ │ └── update.ts # Update credential status
Expand All @@ -272,6 +297,7 @@ npm test
│ │ └── w3c/
│ │ ├── did.test.ts
│ │ ├── key-pair.test.ts
│ │ ├── sign.test.ts
│ │ └── credentialStatus/
│ │ ├── create.test.ts
│ │ └── update.test.ts
Expand Down
1 change: 0 additions & 1 deletion package-lock.json

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

87 changes: 87 additions & 0 deletions src/commands/w3c/sign.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { input, select } from '@inquirer/prompts';
import { isDirectoryValid, readJsonFile, writeFile } from '../../utils';
import { issuer, RawVerifiableCredential, signW3C } from '@trustvc/trustvc';
import { SignInput } from '../../types';
import signale from 'signale';

export const command = 'w3c-sign';
export const describe = 'Sign a Verifiable Credential using a did key-pair file';

export const handler = async () => {
try {
const answers = await promptForInputs();
if (!answers) return;

await sign(answers);
} catch (err: unknown) {
signale.error(`${err instanceof Error ? err.message : String(err)}`);
}
};

export const promptForInputs = async (): Promise<SignInput> => {
const pathToCredentialFile = await input({
message: 'Please enter the path to your Verifiable Credential JSON file:',
required: true,
validate: (value: string) => {
if (!value || value.trim() === '') {
return 'Verifiable Credential JSON file path is required';
}
return true;
},
});
const credential: RawVerifiableCredential = readJsonFile(pathToCredentialFile, 'Verifiable Credential JSON');

const pathToKeypairFile = await input({
message: 'Please enter the path to your did key-pair JSON file:',
required: true,
default: './didKeyPairs.json',
validate: (value: string) => {
if (!value || value.trim() === '') {
return 'did key-pair JSON file path is required';
}
return true;
},
});
const keyPairData: typeof issuer.IssuedDIDOption = readJsonFile(pathToKeypairFile, 'key pair');

const encryptionAlgorithm = await select({
message: 'Select the encryption algorithm used to generate the key pair:',
choices: [
{ name: 'ECDSA-SD-2023', value: 'ecdsa-sd-2023', description: 'Sign credential using ECDSA-SD-2023 suite', },
{ name: 'BBS-2023', value: 'bbs-2023', description: 'Sign credential using BBS-2023 suite', },
],
default: 'ECDSA-SD-2023',
});

const pathToSignedVC = await input({
message: 'Enter a directory to save the signed Verifiable Credential (optional):',
required: false,
default: '.',
});

if (!isDirectoryValid(pathToSignedVC)) throw new Error('Output path is not valid');

return {
credential,
keyPairData,
encryptionAlgorithm,
pathToSignedVC,
};
};

export const sign = async ({
credential,
keyPairData,
encryptionAlgorithm,
pathToSignedVC,
}: SignInput): Promise<void> => {
const signedVC = await signW3C(credential, keyPairData, encryptionAlgorithm);
if (signedVC?.signed) {
signale.success('Verifiable Credential signed successfully');
const signedVCPath = `${pathToSignedVC}/signed_vc.json`;
writeFile(signedVCPath, signedVC.signed, true);
signale.success(`Signed verifiable credential saved to: ${signedVCPath}`);
} else {
signale.error(signedVC.error);
}
};
8 changes: 7 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { issuer, credentialStatus } from '@trustvc/trustvc';
import { credentialStatus, issuer, RawVerifiableCredential } from '@trustvc/trustvc';
import { GasOption, NetworkOption, RpcUrlOption, WalletOrSignerOption } from './utils';

export type SignInput = {
credential: RawVerifiableCredential;
keyPairData: typeof issuer.IssuedDIDOption;
encryptionAlgorithm: typeof credentialStatus.cryptoSuiteName;
pathToSignedVC: string;
}
export type DidInput = {
keyPairPath: string;
domainName: string;
Expand Down
Loading