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

trustbeat

v0.4.0

Published

TrustBeat SDK — qualified timestamping and Merkle anchoring

Readme

TrustBeat TypeScript / JavaScript SDK

Qualified electronic timestamps and Merkle anchoring — eIDAS-compliant, over a simple API.

Part of TrustBeat — digital trust infrastructure for the EU. All SDKs (Python, TypeScript, Java, C#, Go): trustbeat.eu/sdks.

Install

npm install trustbeat

Quickstart

import { TrustBeat } from "trustbeat";

const tb = new TrustBeat({ apiKey: "tb_live_..." });

// Anchor a file (SHA-256 computed locally, file never leaves your machine).
// anchorFileWait() blocks until the proof is ready (next batch, up to 11 min).
const proof = await tb.anchorFileWait("contract.pdf");
console.log(proof.id);          // tracking ID
console.log(proof.anchoredAt);  // ISO 8601 timestamp
console.log(proof.merkleRoot);  // Merkle root of the batch

// Verify locally — no network call
const valid = tb.verify(proof);

// Or anchor a raw SHA-256 hash without blocking, then wait for the proof.
const job = await tb.anchor("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
const waited = await tb.anchorWait(job.id);  // polls up to 11 min

Tamper-Evident Logs (NIS2)

Anchor a log hash together with canonical metadata for NIS2 Article 21 audit trails. The server seals the metadata into the Merkle leaf, so the proof covers both the log content and its context.

import { createHash } from "node:crypto";
import { readFileSync } from "node:fs";
import { TrustBeat } from "trustbeat";

const tb = new TrustBeat({ apiKey: "tb_live_..." });

// Hash the log yourself — content never leaves your machine.
const logHash = createHash("sha256").update(readFileSync("app.log")).digest("hex");

const job = await tb.anchorLog(logHash, {
  logSource: { uri: "/var/log/app.log", name: "Application log" },
  sourceIdentity: { hostname: "web-01", serviceName: "payments" },
  timeEnvelope: { startAt: "2026-04-15T00:00:00Z", endAt: "2026-04-15T23:59:59Z" },
}, { label: "incident-2026-05" });
console.log(job.id, job.combinedHash);

// Wait for the qualified anchor (next batch, up to 11 min).
const proof = await tb.anchorLogWait(job.id);
console.log(proof.verificationStatus); // "VERIFIED"

Webhooks

If your account has a webhook secret configured, every delivery is signed with an X-TrustBeat-Signature header. Verify it with the raw request body — before any JSON parsing:

import { verifyWebhookSignature } from "trustbeat";

// body must be the raw bytes/string as received (e.g. express.raw())
if (!verifyWebhookSignature(rawBody, signatureHeader, webhookSecret)) {
  throw new Error("Invalid webhook signature");
}

Also available as TrustBeat.verifyWebhookSignature(...). Rejects replays older than 5 minutes by default (toleranceSecs option to override).

Portable proof bundles for offline verification: exportAiDecision(id), exportVerification(id), exportLog(id) — each returns raw JSON bundle bytes.

Requirements

  • Node.js 18+ (uses native fetch and crypto)
  • Zero runtime dependencies (stdlib only)

Documentation

Full API reference and guides at api.trustbeat.eu/docs

License

MIT — see LICENSE

Merkle algorithm

Every proof declares how it must be folded, in proof.merkleAlgorithm:

| Value | Construction | |---|---| | trustbeat-legacy-sha256 | leaf = your hash, parent = SHA-256(left \|\| right) | | rfc6962-sha256 | leaf = SHA-256(0x00 \|\| hash), parent = SHA-256(0x01 \|\| left \|\| right) |

verifyProof() dispatches on it for you. A proof with no label was issued before the field existed and is legacy. An algorithm this SDK version does not implement throws UnsupportedAlgorithmError rather than returning false — "cannot check" is not "invalid".

Audit event proofs

verifyAuditEvent() folds an audit event proof the same way:

import { IncompleteProofError } from "@trustbeat/sdk";

const proof = await tb.getAuditEventProof(eventId);
try {
  console.log(await tb.verifyAuditEvent(proof));
} catch (e) {
  if (!(e instanceof IncompleteProofError)) throw e;
  // The server predates API 1.46 and sent no merkleRoot, so there is nothing to
  // fold against. The proof is not invalid — verify it server-side instead.
}

Treating that error as a failed proof would be wrong: it means "cannot check", not "tampered".