Skip to content

Recipes

Issue an employee badge

import { generateDidKey, issueCredential, verifyCredentialJwt } from 'simple-vc';

const company = generateDidKey();
const employee = generateDidKey();

const badge = await issueCredential({
  issuer: company,
  subject: employee.did,
  type: ['EmployeeBadge'],
  claims: { name: 'Ana Silva', role: 'Engineer', department: 'Platform' },
  expiresIn: 60 * 60 * 24 * 365,
});

const check = await verifyCredentialJwt(badge);
console.log(check.verifiableCredential.credentialSubject.role); // "Engineer"

Persist and reload an issuer identity

import { writeFileSync, readFileSync } from 'node:fs';
import { generateDidKey } from 'simple-vc';

// once: create and store the 32-byte seed securely (KMS/secret in real life)
const issuer = generateDidKey();
writeFileSync('issuer.key', Buffer.from(issuer.privateKey));

// later: same DID every time
const seed = new Uint8Array(readFileSync('issuer.key'));
const sameIssuer = generateDidKey(seed);

Verify with graceful failure

import { verifyCredentialJwt } from 'simple-vc';

async function safeVerify(jwt: string) {
  try {
    const { verifiableCredential, issuer } = await verifyCredentialJwt(jwt);
    return { valid: true, issuer, claims: verifiableCredential.credentialSubject };
  } catch (err) {
    return { valid: false, reason: (err as Error).message };
  }
}

Share a credential as a URL / QR

import QRCode from 'qrcode';
const url = `https://verify.example.com/#${badge}`; // the JWT is the fragment
await QRCode.toFile('badge.png', url);

Trust only known issuers

const trusted = new Set([company.did]);
const { issuer } = await verifyCredentialJwt(badge);
if (!trusted.has(issuer)) throw new Error('Untrusted issuer');