@learncard/credential-library
v1.0.13
Published
Comprehensive library of Verifiable Credential fixtures for testing, development, and regression prevention across the VC ecosystem
Downloads
1,086
Keywords
Readme
@learncard/credential-library
A comprehensive, queryable library of Verifiable Credential fixtures for testing, development, and regression prevention across the VC ecosystem.
Why?
The Verifiable Credential standard is infinitely customizable and always evolving. LearnCard adds enhanced support for specific schemas (OBv3, CLR v2, Boosts, etc.), and testing all flows (claiming, viewing, sharing, verifying) requires a diverse set of credential examples.
This package provides:
- Real and synthetic credential fixtures spanning VC v1, v2, OBv3, CLR v2, and LearnCard Boosts
- Rich metadata per fixture: spec, profile, features exercised, source, validity
- Queryable API to filter fixtures by any combination of metadata
- Fixture preparation for real issuance — patch in DIDs, timestamps, and fresh UUIDs
- Self-validating test suite that ensures every fixture passes its declared Zod validator
- Issuance integration tests that verify every valid fixture can be issued by a real LearnCard wallet
- Intentionally invalid fixtures for negative testing
- One-file-per-fixture pattern that makes it trivial to add new credentials
Quick Start
Querying Fixtures
import {
getAllFixtures,
getFixtures,
getFixture,
findFixture,
getValidFixtures,
getInvalidFixtures,
getUnsignedFixtures,
getSignedFixtures,
getStats,
} from '@learncard/credential-library';
// All fixtures
const all = getAllFixtures();
// Only OBv3 badges
const badges = getFixtures({ spec: 'obv3', profile: 'badge' });
// Fixtures with evidence AND alignment
const rich = getFixtures({ features: ['evidence', 'alignment'] });
// Fixtures with ANY of these features
const interesting = getFixtures({ featuresAny: ['skills', 'endorsement', 'nested-credentials'] });
// One specific fixture (throws if not found)
const jff = getFixture('obv3/plugfest-jff2');
// One specific fixture (returns undefined if not found)
const maybe = findFixture('obv3/does-not-exist');
// Only valid / only invalid
const valid = getValidFixtures();
const invalid = getInvalidFixtures();
// Stats breakdown
const stats = getStats();
// => { total, bySpec, byProfile, byValidity, signed, unsigned }Issuing Fixtures with a LearnCard Wallet
import { getFixture, prepareFixture, prepareFixtureById } from '@learncard/credential-library';
import { initLearnCard } from '@learncard/init';
const wallet = await initLearnCard({ seed: '...' });
const issuerDid = wallet.id.did();
// Option A: get fixture, then prepare
const fixture = getFixture('obv3/full-badge');
const unsigned = prepareFixture(fixture, {
issuerDid,
subjectDid: 'did:example:recipient',
});
// Option B: one-liner with prepareFixtureById
const unsigned2 = prepareFixtureById('boost/basic', { issuerDid });
// Issue the credential
const signed = await wallet.invoke.issueCredential(unsigned);prepareFixture deep-clones the fixture and patches:
- Issuer DID — replaces the placeholder issuer with your wallet's DID
- Subject DID — optionally replaces the subject DID
- Fresh UUIDs — regenerates all
urn:uuid:ids (disable withfreshIds: false) - Timestamps — sets
validFrom/issuanceDateto now (or a custom value)
Query API Reference
| Function | Description |
| ---------------------------------- | ----------------------------------------------------------------------------- |
| getAllFixtures() | Returns all registered fixtures |
| getFixture(id) | Returns a fixture by ID (throws if not found) |
| findFixture(id) | Returns a fixture by ID (returns undefined if not found) |
| getFixtures(filter) | Returns fixtures matching the filter |
| getValidFixtures(filter?) | Shorthand for getFixtures({ ...filter, validity: 'valid' }) |
| getInvalidFixtures(filter?) | Shorthand for getFixtures({ ...filter, validity: ['invalid', 'tampered'] }) |
| getUnsignedFixtures(filter?) | Returns only unsigned fixtures |
| getSignedFixtures(filter?) | Returns only signed fixtures |
| getStats() | Returns counts grouped by spec, profile, validity, and signed status |
| prepareFixture(fixture, options) | Clones a fixture and patches DIDs, UUIDs, and timestamps |
| prepareFixtureById(id, options) | Combines getFixture + prepareFixture |
FixtureFilter
All filter fields are optional. Array fields accept a single value or an array.
| Field | Type | Behavior |
| ------------- | ------------------------------------------ | ----------------------------------- |
| spec | CredentialSpec \| CredentialSpec[] | Match any of the given specs |
| profile | CredentialProfile \| CredentialProfile[] | Match any of the given profiles |
| features | CredentialFeature[] | Must have all of these features |
| featuresAny | CredentialFeature[] | Must have any of these features |
| signed | boolean | Filter by signed status |
| validity | FixtureValidity \| FixtureValidity[] | Match any of the given validities |
| source | FixtureSource \| FixtureSource[] | Match any of the given sources |
| tags | string[] | Must have all of these tags |
Adding a Fixture
Option 1: Create a file manually
- Create a file in
src/fixtures/<spec-dir>/my-fixture.ts:
import type { CredentialFixture } from '../../types';
export const myFixture: CredentialFixture = {
id: 'vc-v2/my-fixture',
name: 'My New Fixture',
description: 'What this fixture tests or demonstrates',
spec: 'vc-v2',
profile: 'generic',
features: [],
source: 'synthetic',
signed: false,
validity: 'valid',
credential: {
'@context': ['https://www.w3.org/ns/credentials/v2'],
type: ['VerifiableCredential'],
issuer: 'did:example:issuer',
validFrom: '2024-01-01T00:00:00Z',
credentialSubject: { id: 'did:example:subject' },
},
};Add the import and registration in
src/fixtures/index.tsRun
bun run test— both the self-validating and issuance suites will check your fixture automatically
Option 2: Use the Credential Viewer UI
The examples/credential-viewer app has a New Fixture button that provides a form with:
- JSON editor with metadata auto-inference
- JSON file upload
- Test Issue button (requires wallet connection)
- Saves the
.tsfile and updates the index automatically
See the Credential Viewer README for details.
Fixture Metadata
| Field | Type | Description |
| ------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | string | Unique identifier, e.g. obv3/minimal-badge |
| name | string | Human-readable name |
| description | string | What this fixture tests/demonstrates |
| spec | CredentialSpec | vc-v1, vc-v2, obv3, clr-v2, europass, custom |
| profile | CredentialProfile | badge, diploma, certificate, id, membership, license, micro-credential, course, degree, boost, boost-id, delegate, endorsement, learner-record, generic |
| features | CredentialFeature[] | Features exercised: evidence, alignment, endorsement, expiration, status, multiple-subjects, image, results, skills, display, associations, nested-credentials, etc. |
| source | FixtureSource | spec-example, plugfest, real-world, synthetic |
| signed | boolean | Whether the credential has a proof |
| validity | FixtureValidity | valid, invalid, or tampered |
| validator | z.ZodType? | Optional Zod validator from @learncard/types |
| tags | string[]? | Additional free-form tags for ad-hoc filtering |
Available Fixtures
VC v1 (3)
vc-v1/basic— Minimal VCDM v1 credentialvc-v1/with-status— With StatusList2021 credential statusvc-v1/alumni-credential— University alumni credential
VC v2 (8)
vc-v2/basic— Minimal VCDM v2 credentialvc-v2/with-evidence— With evidence arrayvc-v2/multiple-subjects— With multiple credential subjectsvc-v2/employment-credential— Employment verification credentialvc-v2/education-degree— University bachelor degree credentialvc-v2/digital-id— Government digital identity credentialvc-v2/membership-credential— Professional association membershipvc-v2/license-credential— Professional nursing license
Open Badges v3 (11)
obv3/minimal-badge— Minimal OBv3 achievement credentialobv3/full-badge— Full-featured badge with image, evidence, alignment, results, expirationobv3/with-alignment— With competency framework alignmentsobv3/with-endorsement— With embedded endorsement credentialobv3/plugfest-jff2— JFF PlugFest 2 interoperability badgeobv3/1edtech-full— 1EdTech complete OpenBadgeCredential (spec reference)obv3/professional-cert— AWS Solutions Architect professional certificationobv3/micro-credential— Data Science Fundamentals micro-credentialobv3/course-completion— Introduction to Machine Learning course completionobv3/k12-diploma— High school diplomaobv3/endorsement-credential— Program accreditation endorsement
CLR v2 (4)
clr/minimal— Minimal Comprehensive Learner Recordclr/multi-achievement— Multiple achievements with associationsclr/nd-student-transcript— North Dakota student transcript (nested VCs, real-world structure)clr/university-transcript— University academic transcript (6 nested course VCs)
LearnCard Boosts (5)
boost/basic— Basic BoostCredential with displayboost/boost-id— BoostID membership cardboost/with-skills— Boost with skills, evidence, and alignmentboost/community-award— Community leadership award boostboost/delegate— Organization delegate credential
Invalid / Negative Tests (3)
invalid/missing-context— No @contextinvalid/empty-type— Empty type arrayinvalid/missing-issuer— No issuer field
Tests
bun run testTwo test suites run automatically:
registry.test.ts— Validates every fixture against its Zod validator, checks metadata consistency, and tests the query/filter APIissuance.test.ts— Creates a real LearnCard wallet instance and callsissueCredential()on every valid fixture, verifying that each produces a signed VC with a proof
Bundle Size & Production Use
This package is designed for testing, development, and CI — not for inclusion in production application bundles. The fixture data is intentionally large and comprehensive.
- The package declares
"sideEffects": falseso bundlers can tree-shake unused fixtures - The credential-viewer (
examples/credential-viewer/) isprivate: trueand not published - If you only need a few fixtures in a test file, import them directly:
import { obv3MinimalBadge } from '@learncard/credential-library' - Avoid importing the full library in production application code paths
JSON-LD Context Notes
All valid fixtures use @context URLs that are either statically cached in DidKit or fetchable via allowRemoteContexts. If you add a fixture with custom terms, make sure they are defined in one of the included contexts. Common choices:
https://www.w3.org/2018/credentials/examples/v1— Example terms for VC v1 (degree,alumniOf, etc.)https://www.w3.org/ns/credentials/examples/v2— Example terms for VC v2 (degree,role, etc.)https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json— OBv3 terms (cached in DidKit)https://purl.imsglobal.org/spec/clr/v2p0/context.json— CLR v2 terms (cached in DidKit)
