npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@f0rest8/metamorphic-log

v0.5.0

Published

Tamper-evident, append-only transparency log + verification SDK for the Metamorphic platform: RFC 6962/9162 Merkle proofs, C2SP tlog-tiles substrate, witnessed checkpoints, hybrid post-quantum checkpoint signing, and CONIKS-style index privacy. Single sou

Readme

@f0rest8/metamorphic-log

Browser verification + monitor SDK for the metamorphic-log transparency log: RFC 6962 / RFC 9162 Merkle inclusion + consistency proofs, C2SP tlog-tiles checkpoints and signed-note co-signatures (classical Ed25519 and additive hybrid post-quantum), CONIKS-style index-privacy lookup/absence proofs, and signed per-namespace policy with declared == observed posture enforcement.

Built for Metamorphic and Mosslet — privacy-first apps by Moss Piglet Corporation — so the browser can monitor the log itself rather than trusting a server.

This package is a WebAssembly build of the metamorphic-log Rust crate. It is a thin personality over the audited Rust core: it performs no Merkle, signature, VRF, or policy logic of its own, so every verification and every byte it computes is identical to the native crate (locked by a cross-language byte-parity KAT). All cryptographic primitives come from metamorphic-crypto; there is no parallel crypto stack.

Verification, not bootstrap trust. A transparency log proves continuity, append-only consistency, and anti-equivocation — it cannot vouch for the first key you ever saw for a peer (a Trust-On-First-Use problem your app must solve out of band). Integrity, authentication, and commitments are post-quantum from day one; only CONIKS index-privacy defaults to a classical ECVRF. Nothing here is FIPS-validated and this package makes no such claim.

Install

npm install @f0rest8/metamorphic-log

Quick start

import init, {
  verifyInclusion,
  verifyConsistency,
  checkpointVerify,
} from "@f0rest8/metamorphic-log";

// Initialize the WASM module once before calling any function.
await init();

// All functions are synchronous after init(). Verification predicates return
// `true` on success and THROW on any failure (tamper, forgery, posture
// mismatch, malformed input).
const ok = verifyInclusion(index, size, leafHashB64, proofB64Array, rootB64);

Conventions

  • Binary values cross the boundary as standard base64 strings (padded, like btoa/atob). Merkle hashes are 32 bytes; SHA3-512 digests / CONIKS roots are 64 bytes.
  • Proof audit paths and trusted-key sets are arrays of base64 / text strings.
  • C2SP checkpoint / signed-note bodies and VerifierKeys cross as their canonical UTF-8 text form.

API overview

Inclusion + consistency (the monitor core)

import { verifyInclusion, verifyConsistency } from "@f0rest8/metamorphic-log";

// Throws unless the leaf at `index` is included under `root`.
verifyInclusion(index, size, leafHashB64, proofB64Array, rootB64);

// Anti-equivocation: throws unless the size2 tree is an append-only extension
// of the size1 tree.
verifyConsistency(size1, size2, proofB64Array, root1B64, root2B64);

Layer-0 leaf: key history

import {
  keyHistoryV1CanonicalBytes,
  keyHistoryV1Rfc6962LeafHash,
  keyHistoryEntryHashWithContext,
} from "@f0rest8/metamorphic-log";

// Pass an absent/empty prevEntryHash for the genesis entry.
const leafHash = keyHistoryV1Rfc6962LeafHash(
  seq, tsMs, encX25519B64, encPqB64, signingPubB64, prevEntryHashB64,
);
// Feed leafHash straight into verifyInclusion().

// Recommended: brand the intra-chain entry hash with your own namespace label
// so auditors can tell whose key history a chain belongs to. The canonical
// bytes and RFC 6962 leaf hash above are brand-independent; only this hash
// varies by label.
const entryHash = keyHistoryEntryHashWithContext(
  "acme/key-history/v1",
  seq, tsMs, encX25519B64, encPqB64, signingPubB64, prevEntryHashB64,
);

The frozen keyHistoryV1EntryHash(...) (the mosslet/key-history/v1 conformance value) is retained for backwards compatibility, but new applications should brand their leaves via keyHistoryEntryHashWithContext.

Checkpoints + signed notes (Ed25519 + hybrid PQ)

import {
  verifySignedNote,
  checkpointVerify,
  checkpointVerifyInclusion,
  checkpointVerifyConsistency,
} from "@f0rest8/metamorphic-log";

// Number of trusted signatures that verified (>= 1), or throws.
const n = verifySignedNote(noteText, [vkey1, vkey2]);

// Parse + verify a signed checkpoint note → { origin, size, rootB64, extensions }.
const head = checkpointVerify(noteText, [vkey1]);

// Verify a leaf against a verified checkpoint.
checkpointVerifyInclusion(noteText, [vkey1], leafIndex, leafHashB64, proofB64Array);

// Monitor: verify two checkpoints are a consistent, non-equivocating view.
checkpointVerifyConsistency(olderNote, newerNote, [vkey1], proofB64Array);

CONIKS index privacy

import {
  coniksVerifyLookup,
  coniksVerifyAbsence,
  verifyCommitment,
} from "@f0rest8/metamorphic-log";

// Returns the proven value (base64); throws if the proof/VRF/root is invalid.
const valueB64 = coniksVerifyLookup(namespace, vrfPublicB64, rootB64, identityB64, proofB64);

// Throws unless `identity` is provably absent under `root`.
coniksVerifyAbsence(namespace, vrfPublicB64, rootB64, identityB64, proofB64);

verifyCommitment(context, commitmentB64, valueB64, openingB64);

Namespace policy: declared == observed

import {
  signedPolicyVerify,
  policyEnforceCheckpointSigningKey,
  policyEnforceCheckpointSignature,
  policyEnforceVrfSuiteId,
  policyEnforceCommitmentHash,
} from "@f0rest8/metamorphic-log";

// Verify the signed policy → declared posture object.
const policy = signedPolicyVerify(signedPolicyB64);
// { namespace, policySchemaVersion, securityLevel, checkpointSuite,
//   commitmentHash, vrfMode, effectiveFrom, createdAt, policyHashB64,
//   rfc6962LeafHashB64 }

// Hard-reject any observed posture that disagrees with the declared one.
policyEnforceCheckpointSigningKey(signedPolicyB64, observedPublicKeyB64);
policyEnforceCheckpointSignature(signedPolicyB64, observedSignatureB64);
policyEnforceVrfSuiteId(signedPolicyB64, observedSuiteId);          // e.g. 0x03
policyEnforceCommitmentHash(signedPolicyB64, "sha3_256");           // or "sha3_512"

License

MIT OR Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.