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

mememage-js

v0.1.0

Published

The JavaScript SDK for mememage-core — the JS implementation of the Mememage protocol (decode, verify, encode, encrypt/unlock), on parity with the Python reference.

Downloads

172

Readme

mememage-js

The JavaScript SDK for the Mememage protocol — the JS implementation of mememage-core, so JavaScript developers can work with Mememage (decode, verify, and — as this is built out — encode) natively, without a Python dependency. It's the counterpart to the Python mememage package: two language bindings of one protocol.

Python is the reference. This SDK never becomes a second source of truth — every operation mirrors a Python function and is validated against Python's own output by a parity gate. Maintenance means fixing the Python core; the gate tells us if the JS side needs to follow. So there's nothing here to chase down independently.

Status — complete at core parity

The SDK now covers the whole raw-core protocol, each op gated against Python:

  • decodeBar — read the bar → { identifier, contentHash }.
  • verifyWitnessed / isSupportedHashVersion — integrity (the open model).
  • encode — stamp a bar + build the record, byte-identical to mememage.encode.
  • encryptField / decryptField / encode(…, {password, private}) / unlock / isEncrypted — field encryption (AES-256-GCM / PBKDF2), envelope byte-compatible with Python: a record encrypted in either language opens in the other.

The open hash model (schema-agnostic)

The SDK is schema-agnostic: it implements the open hash model — the content hash covers every field a record holds (what the raw API and ComfyUI produce). So it verifies any adopter's record no matter what they store, without knowing any particular chain's schema.

Curated integer hash versions (the canonical chain's hash_version: 1, with its fixed field list) are a reference-implementation concern. A record on one of those reads as UNSUPPORTED here — not tampered, exactly the verdict ComfyUI's verifier and the core CLI give. Call isSupportedHashVersion(record) before verifyWitnessed to tell UNSUPPORTED apart from ALTERED.

Deliberately not here — reference-implementation features, out of raw-core scope: signing / AUTHENTICATED (the raw core's verify() is integrity-only), EMBODIED (dHash + luma grid), and the distributed watermark. These are the canonical chain's specific tamper-evidence technique — they need a record carrying a thumbnail and a luma_grid, and another adopter might use a different technique or none. They belong to the reference implementation, not the core. For now they live only in the decoder site (docs/js); if they're ever ported to JS they'll be a separate surface with its own parity anchor (the reference impl).

Use

import {
  decodeBar, isSupportedHashVersion, verifyWitnessed,
} from "mememage-js";

// 1. decode the bar from image pixels (canvas getImageData().data, flat RGBA)
const bar = decodeBar(pixels, width, height);
if (!bar) { /* NO BAR */ }
// -> { identifier: "mememage-…", contentHash: "…" }

// 2. fetch the record for bar.identifier from wherever it lives (yours to resolve),
//    then produce a verdict — by math alone, no server needed:
if (!isSupportedHashVersion(record)) {
  // UNSUPPORTED — a hash model this layer doesn't implement (e.g. a canonical-chain
  // record). NOT tampered; verify it in that app's own decoder.
} else if (await verifyWitnessed(record, bar.contentHash)) {
  // WITNESSED — intact and matched to the image (integrity)
} else {
  // ALTERED — the record does not match the image
}

Raw core exports (extractBarScaleAware, decodePayload, packPayload, extractIdentifier, normalizeIdentifier, computeContentHash, encode, contentIdentifier) are available for lower-level use.

Parity

Codec/verify bodies are verbatim from the parity-locked decoder in docs/js (the frozen decoder site), wrapped as ES modules. npm test validates the core layer against the Python core directly: decode-parity decodes bars the core produced (gen-vectors.py), verify-parity recomputes hashes the core stamped (gen-hash-vectors.py, using compute_content_hash), and checks encode output — across sequential + even-fill layouts, custom prefixes, the real V1 example soul, open- version records, and a tamper negative. Regenerate vectors from the repo root with python3 test/gen-vectors.py and python3 test/gen-hash-vectors.py.

MIT.