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

@matanetwork/sign-verify

v0.1.0

Published

Node/Deno/Bun verifier for MATA signed statements — sign-arbitrary-content tokens (documents, IAMHUMAN posts). Runs the same four-step self-contained verification as Sovereign ID (genesis self-signature → roster chain → head VM → JWS signature) entirely l

Readme

@matanetwork/sign-verify

Verify MATA signed statements in Node, Deno, or Bun — sign-arbitrary-content tokens that prove a did:mata authored a document or a post.

A signed statement is the building block for:

  • Internal document signing — offer letters, NDAs, contracts signed by a company or person's sovereign identity.
  • IAMHUMAN — a PGP-equivalent for the open web: prove a verified human wrote a Reddit / X / forum post.

The token is self-contained — the signer's device roster and proof-of-control travel inside it — so you verify offline, with zero calls to MATA infrastructure. This is the JavaScript counterpart to the Rust mata-sign crate; the four cryptographic checks are identical to @matanetwork/sovereign-id-verify.

Install

npm install @matanetwork/sign-verify

Requires Node ≥ 18 (uses the Web Crypto API + node:crypto).

Usage

import { verifyStatement, matchesContent, VerifyError } from '@matanetwork/sign-verify';

// `token` is the signed-statement string; `document` is the bytes/text you hold.
try {
  const v = await verifyStatement(token, {
    nowUnixSecs: Math.floor(Date.now() / 1000),
    expectedContext: 'iamhuman', // optional: pin the use case
    // expectedNonce: '…',        // optional: anti-replay
    // maxIatSkewSecs: 120,        // optional, default 120
  });

  // The signature proved WHO signed (v.did). Now confirm WHAT they signed:
  if (!matchesContent(v, document)) {
    throw new Error('content does not match the signature');
  }

  console.log(`Signed by ${v.did} — verified human ✓`);
} catch (err) {
  if (err instanceof VerifyError) {
    console.error(`rejected: ${err.code} — ${err.message}`);
  }
}

Detached signatures — why two steps?

verifyStatement proves the token is authentic and tells you who signed and what hash they committed to. It does not receive the content — signing is detached (the token carries SHA-256(content), not the bytes, so signing a 2 GB PDF costs the same as signing a tweet). You call matchesContent with the bytes you already hold to bind who-signed to what-was-signed.

For short text (e.g. a forum post) the signer may inline a copy in v.preview — convenient for display, but matchesContent against the real content is still authoritative.

API

verifyStatement(token, opts) → Promise<VerifiedStatement>

| opts field | type | notes | | ------------------- | -------- | ------------------------------------------------------------ | | nowUnixSecs | number | required — verifier's wall clock (Unix seconds) | | maxIatSkewSecs | number? | allowed forward skew, default 120 | | expectedContext | string? | if set, the statement's context must equal it exactly | | expectedNonce | string? | if set, the statement's nonce must equal it exactly |

VerifiedStatement: { did, contentHash (hex), contentType, currentVersion, iat, exp, context, preview }.

matchesContent(verified, content) → boolean

Recompute SHA-256(content) and compare to the committed contentHash. content may be a string, Uint8Array, ArrayBuffer, or Buffer.

VerifyError

Thrown on any failure. .code is a stable snake_case string matching the Rust check that failed (genesis_signature_invalid, chain_signature_invalid, current_vm_not_in_head_roster, jwt_signature_invalid, expired, not_yet_valid, context_mismatch, nonce_mismatch, malformed_content_hash, invalid_jws_shape, …).

What gets checked

  1. Genesis self-signature — the genesis roster is signed by the key recoverable from the DID.
  2. Roster chain — each device-roster mutation is signed by a key in the prior roster; versions strictly increase.
  3. Current VM in head — the signing device is in the current roster (not revoked).
  4. JWS signature — ES256 over the token, against that device's key.
  5. Freshness + bindingexp / iat skew, optional context / nonce.

Then you call matchesContent to confirm the bytes.

Wire-format stability

This is a 0.x release. The wire format is shared with the Rust mata-sign crate and is kept in lockstep by a cross-implementation conformance test — the test suite verifies a real token produced by the Rust crate. The format is not yet frozen for 1.0; until then, treat it as subject to change.

License

MIT