Quickstart
Prerequisites
- Node.js 24 or newer
- A pnpm version compatible with the consumer workspace; repository contributors use pnpm 11.25.0
- Compact
0.31.1when consuming the Compact package
Install
Install only the boundaries the consumer needs. The current stable graph is 0.2.0:
# Metadata only
pnpm add -E @midnight-ntwrk/credential-model@0.2.0
# Metadata plus family-neutral Compact primitives
pnpm add -E \
@midnight-ntwrk/credential-model@0.2.0 \
@midnight-ntwrk/credential-compact@0.2.0
# Add only for did:midnight method binding
pnpm add -E @midnight-ntwrk/credential-did-midnight@0.2.0The packages do not provide a credential family, wallet flow, exchange protocol, DID resolver, status authority, or issuer trust policy. A consumer repository owns those choices.
For release-sensitive automation that needs the complete graph, use this guarded function. It verifies that every immutable package version exists and records the approved version exactly:
install_stable_graph() (
set -euo pipefail
EXPECTED_STABLE="${1:?usage: install_stable_graph VERSION}"
NPM_REGISTRY="${NPM_REGISTRY:-https://registry.npmjs.org/}"
for package in \
@midnight-ntwrk/credential-model \
@midnight-ntwrk/credential-compact \
@midnight-ntwrk/credential-did-midnight; do
if ! actual_version="$(npm view --registry "$NPM_REGISTRY" \
"${package}@${EXPECTED_STABLE}" version)"; then
printf 'could not resolve %s@%s\n' \
"$package" "$EXPECTED_STABLE" >&2
exit 1
fi
if [[ "$actual_version" != "$EXPECTED_STABLE" ]]; then
printf 'expected %s version=%s, got %s\n' \
"$package" "$EXPECTED_STABLE" "$actual_version" >&2
exit 1
fi
done
pnpm add --registry "$NPM_REGISTRY" -E \
"@midnight-ntwrk/credential-model@${EXPECTED_STABLE}" \
"@midnight-ntwrk/credential-compact@${EXPECTED_STABLE}" \
"@midnight-ntwrk/credential-did-midnight@${EXPECTED_STABLE}"
)
install_stable_graph 0.2.0Keep the package graph on one exact version for reproducible credential-family builds. The moving rc dist-tag may identify a prerelease older or newer than latest; inspect it before opting in:
NPM_REGISTRY="${NPM_REGISTRY:-https://registry.npmjs.org/}"
MODEL_RC="$(npm view --registry "$NPM_REGISTRY" @midnight-ntwrk/credential-model dist-tags.rc)"
COMPACT_RC="$(npm view --registry "$NPM_REGISTRY" @midnight-ntwrk/credential-compact dist-tags.rc)"
DID_RC="$(npm view --registry "$NPM_REGISTRY" @midnight-ntwrk/credential-did-midnight dist-tags.rc)"
printf 'model=%s compact=%s did=%s\n' "$MODEL_RC" "$COMPACT_RC" "$DID_RC"Only after confirming that all three rc tags identify the prerelease graph you intend to evaluate, record that exact version as EXPECTED_RC. The guarded install rechecks every moving tag against that approved version before using the immutable version:
install_rc_graph() (
set -euo pipefail
EXPECTED_RC="${1:?usage: install_rc_graph VERSION}"
NPM_REGISTRY="${NPM_REGISTRY:-https://registry.npmjs.org/}"
MODEL_RC="$(npm view --registry "$NPM_REGISTRY" @midnight-ntwrk/credential-model dist-tags.rc)"
COMPACT_RC="$(npm view --registry "$NPM_REGISTRY" @midnight-ntwrk/credential-compact dist-tags.rc)"
DID_RC="$(npm view --registry "$NPM_REGISTRY" @midnight-ntwrk/credential-did-midnight dist-tags.rc)"
if [[ "$MODEL_RC" != "$EXPECTED_RC" || \
"$COMPACT_RC" != "$EXPECTED_RC" || "$DID_RC" != "$EXPECTED_RC" ]]; then
printf 'refusing unapproved RC graph: expected=%s model=%s compact=%s did=%s\n' \
"$EXPECTED_RC" "$MODEL_RC" "$COMPACT_RC" "$DID_RC" >&2
exit 1
fi
pnpm add --registry "$NPM_REGISTRY" -E \
"@midnight-ntwrk/credential-model@${EXPECTED_RC}" \
"@midnight-ntwrk/credential-compact@${EXPECTED_RC}" \
"@midnight-ntwrk/credential-did-midnight@${EXPECTED_RC}"
)Use those install commands only when the reported rc versions are the exact prerelease graph you intend to evaluate. After recording that version, invoke the function explicitly, for example install_rc_graph 0.3.0-rc1. Prerelease adoption should not happen implicitly.
Define Metadata
credential-model validates protocol-neutral family and claim-schema metadata:
import { defineCredentialFamily } from "@midnight-ntwrk/credential-model";
export const membershipFamily = defineCredentialFamily({
id: "example.membership",
version: "0.1.0",
schema: {
id: "urn:example:membership",
version: "1.0.0",
credentialTypes: ["VerifiableCredential", "MembershipCredential"],
claims: [
{
id: "memberId",
path: ["memberId"],
disclosure: "selective",
required: true,
},
],
},
});Select a Compact Entrypoint
credential-compact publishes exactly two supported Compact roots:
| Entrypoint | Use |
|---|---|
./credentials.compact | Standalone use of the complete core surface |
./credentials/composable.compact | Include shared declarations once before family composition |
Use only package exports. Do not import repository src, generated managed, or dist internals.
For Midnight DID-aware contracts, include either the binding package's standalone ./did-midnight.compact root or include the core composable root once followed by ./did-midnight/composable.compact.
Verify the Repository
From a source checkout:
pnpm install --frozen-lockfile
./run.sh --light
./run.sh docs