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/sovereign-id-verify

v0.1.0

Published

Node/Deno/Bun verifier for MATA Sovereign ID (mID) tokens. Runs the four-step verification (genesis self-signature → roster chain → head VM → JWS signature) entirely locally — zero runtime calls to MATA infrastructure.

Readme

@matanetwork/sovereign-id-verify

Node / Deno / Bun verifier for MATA Sovereign ID (mID) JWTs.

Runs the full four-step verification (genesis self-signature → roster chain → head VM check → JWS outer signature) entirely locally using Web Crypto API. Zero runtime HTTP calls to MATA infrastructure per ADR 0005.

Install

npm install @matanetwork/sovereign-id-verify

Pair with the page-side SDK:

npm install @matanetwork/sovereign-id

Quick start (Express)

import express from 'express';
import { verifyResponse, checkRollback, VerifyError } from '@matanetwork/sovereign-id-verify';

const app = express();
app.use(express.json());

app.post('/api/auth/mid', async (req, res) => {
  const { jwt } = req.body;
  if (typeof jwt !== 'string') {
    return res.status(400).json({ error: 'invalid_request' });
  }

  const sessionNonce = await pullNonceFromSession(req);

  try {
    const verified = await verifyResponse(jwt, {
      expectedAudience: 'https://acme.com',
      expectedNonce: sessionNonce,
      nowUnixSecs: Math.floor(Date.now() / 1000),
      maxIatSkewSecs: 120, // optional, default 120
    });

    // Optional rollback check — defend against stolen-device replay
    // of a pre-revocation roster envelope.
    const lastSeen = await db.lookupLastSeenVersion(verified.did);
    checkRollback(verified, lastSeen);

    // verified.did              — stable user identifier
    // verified.claims           — disclosed values
    // verified.currentVersion   — head roster version (cache as last_seen)
    // verified.genesisRosterHash — anchor on first sight

    await upsertUserAndIssueSession(req, res, verified);
    res.json({ ok: true });
  } catch (err) {
    if (err instanceof VerifyError) {
      return res.status(401).json({ error: err.code });
    }
    throw err;
  }
});

app.listen(3000);

API reference

verifyResponse(jwt, config)

Runs the full four-step verification.

config:

| Field | Type | Required | Notes | |---|---|---|---| | expectedAudience | string | yes | Must equal the JWT's aud claim. Your RP's bare origin. | | expectedNonce | string | yes | The single-use nonce you issued for this sign-in. | | nowUnixSecs | number | yes | Current wall-clock time. Math.floor(Date.now() / 1000). | | maxIatSkewSecs | number | no | Default 120. Tokens with iat > now + skew are rejected. |

Returns Promise<VerifiedSovereignId>:

interface VerifiedSovereignId {
  did: string;              // stable user ID
  genesisRosterHash: string; // hex sha256, anchor on first sight
  currentVersion: number;   // head roster version
  claims: Record<string, ClaimValue>;
  iat: number;
  exp: number;
  aud: string;
}

Throws VerifyError with .code matching the Rust mid-verify::VerifyError variants:

| Code | When | |---|---| | invalid_jws_shape | JWT didn't split into 3 dot-separated parts. | | base64_decode | A segment failed base64url decoding. | | invalid_jws_header | Header isn't {"alg":"ES256","typ":"JWT"}. | | payload_json | Payload bytes weren't valid JSON. | | audience_mismatch | audexpectedAudience. | | nonce_mismatch | nonceexpectedNonce. | | expired | now >= exp. | | not_yet_valid | iat > now + skew. | | malformed_did | DID didn't decode to a valid P-256 pubkey. | | malformed_vm_pubkey | VM publicKeyMultibase decode failed. | | signature_wrong_length | Signature wasn't 64 bytes. | | genesis_signature_invalid | Genesis self-signature didn't verify. | | chain_signer_not_in_prior_roster | Chain entry signed by unknown key. | | chain_signature_invalid | Chain entry signature didn't verify. | | chain_version_not_monotonic | Chain versions didn't strictly increase. | | current_vm_not_in_head_roster | Signing device has been revoked. | | jwt_signature_invalid | JWS outer signature didn't verify. |

checkRollback(verified, lastSeenVersion)

Optional rollback check. Pass the highest version your DB has seen for verified.did; the function throws VerifyError with code: 'rollback_detected' if the current is lower. No-op if lastSeenVersion is null / undefined (DID hasn't been seen before).

const lastSeen = await db.lookupLastSeenVersion(verified.did);
checkRollback(verified, lastSeen);
// proceed: upsert user with max(last_seen, current_version)

Anchoring on first sight

When you see a DID for the first time, record (did, genesisRosterHash, currentVersion). On subsequent sign-ins:

  1. The same DID MUST produce the same genesisRosterHash (different = attacker spoofing).
  2. currentVersion >= last_seen_version (lower = rollback).
CREATE TABLE users (
    did TEXT PRIMARY KEY,
    genesis_roster_hash TEXT NOT NULL,
    last_seen_roster_version BIGINT NOT NULL,
    ...
);

INSERT INTO users (did, genesis_roster_hash, last_seen_roster_version, ...)
VALUES ($1, $2, $3, ...)
ON CONFLICT (did) DO UPDATE
SET last_seen_roster_version = GREATEST(users.last_seen_roster_version, EXCLUDED.last_seen_roster_version),
    ...
WHERE users.genesis_roster_hash = EXCLUDED.genesis_roster_hash;

The WHERE predicate enforces "a DID's genesis state is immutable" — if anyone tries to upsert with a different genesis_roster_hash, the update is silently skipped (and you can alert on it).

Why this is a separate package from @matanetwork/sovereign-id

  • Bundle size. The frontend SDK has zero crypto dependencies; the verifier needs Web Crypto API + base58 + DER decoding. Splitting keeps the page-side bundle tiny.
  • Trust boundary. The verifier runs on YOUR backend — RPs review it carefully before integration. Auditors find one focused package, not a dual-use module.

License

MIT