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

@tmx-group/audit-verifier

v1.0.0

Published

Standalone, zero-dependency verifier for Thea API hash-chained audit receipts. Independently confirms an answer happened and has not been altered — no trust in the API required.

Readme

@tmx-group/audit-verifier

Standalone, zero-dependency verifier for Thea API hash-chained audit receipts.

Every answer the Thea API returns is recorded as a row in a tamper-evident hash chain. This package lets anyone — you, an auditor, a customer's own compliance team — independently confirm that an answer happened and has not been altered, without trusting TMX or the API. It runs offline, makes no network calls, and has no dependencies beyond Node's built-in crypto.

Install

npm install @tmx-group/audit-verifier

Requires Node.js >= 18.

What it checks

Given the rows of a workspace's audit chain, the verifier:

  • recomputes each row's hash from its payload, using the exact construction the gateway used — sha256(canonical(payload) + prev_hash);
  • confirms each row's prev_hash links to the previous row's hash;
  • confirms idx is contiguous and monotonic from 0 (no inserted, removed, or reordered rows);
  • rejects chains that mix more than one workspace_id;
  • reports the first break, with the offending idx and reason.

Usage

import { verifyChain, verifyReceipt } from '@tmx-group/audit-verifier';

// `rows` is the full audit chain for one workspace, each row shaped:
// { workspace_id, idx, prev_hash, query, route_summary,
//   atom_refs, tier, latency_ms, ts, hash }
const result = verifyChain(rows);

if (result.ok) {
  console.log(`verified ${result.rows_checked} rows; head = ${result.head_hash}`);
} else {
  console.error('chain broken:', result.breaks);
  // e.g. [{ idx: 2, reason: 'hash_mismatch', expected: '…', got: '…' }]
}

Verify a single sealed-response receipt against the full chain:

import { verifyReceipt } from '@tmx-group/audit-verifier';

// `receipt` is the { idx, hash, prev_hash, ts } anchor returned in a sealed
// response; `chainRows` is the workspace's audit chain.
const r = verifyReceipt(receipt, chainRows);
// { ok, receipt_in_chain, chain_ok, breaks }

API

verifyChain(rows, opts?)

Returns { ok, rows_checked, head_hash, breaks }. breaks is an array of { idx, reason, expected?, got? }; reason is one of hash_mismatch, broken_link, idx_discontinuity, or multiple_workspaces. Pass { stopOnFirstBreak: true } to stop walking at the first failure.

verifyReceipt(receipt, chainRows)

Returns { ok, receipt_in_chain, chain_ok, breaks }. ok is true only when the full chain verifies and the receipt is genuinely present in it.

recomputeHash(row)

Returns the hash the gateway would have stored for row. Exposed for advanced checks and testing.

Hash construction

The verifier mirrors the gateway exactly:

payload  = { workspace_id, idx, prev_hash, query, route_summary,
             atom_refs, tier, latency_ms, ts }
canonical = JSON.stringify(payload, TOP-LEVEL keys sorted)
hash      = sha256Hex( canonical + prev_hash )
genesis prev_hash = "(genesis)"

Only top-level keys are sorted — nested objects (e.g. route_summary) are serialised in their stored key order, because the gateway's canonical() does not deep-sort. This faithfulness is the whole point: deep-sorting here would make hashes diverge and defeat verification.

Tests

npm test

Covers valid chains, payload tampering, broken links, deleted rows, silent inserts, forged receipts, and mixed-/empty-workspace rejection.

License

Apache License 2.0 © The TMX Group ("TMX Group Ventures Pte Ltd"). See LICENSE and NOTICE.