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

logos-notary

v1.0.0

Published

Waterproof cryptographic proof-of-existence. SHA-256 + HMAC document notarization with Merkle tree batching, hash-chained audit logs, and multi-signature verification. Zero dependencies.

Readme

logos-notary

Waterproof cryptographic proof-of-existence for any content.
SHA-256 + HMAC document notarization with Merkle tree batching, hash-chained audit logs, and multi-signature verification.

npm version license zero dependencies Node.js 924 proofs in production

Built by Grace AI Technologies LLC — powering the LOGOS VPH-257 verification layer.
924 real proofs verified in production. This is not a demo.


Why

Every developer eventually needs to answer: "Can I prove this document existed, unmodified, at this exact moment?"

  • Law: Did the contract predate the dispute?
  • Finance: Was this transaction record altered after submission?
  • Healthcare: Has this patient record been tampered with?
  • IP: When did I create this design, before or after theirs?

logos-notary answers all of these with nothing but mathematics.
No blockchain fees. No third-party dependency. No trusted intermediary.
Just SHA-256, HMAC, and your own secret key.


Features

| Feature | Description | |---|---| | Proof creation | SHA-256 content hash + HMAC signature + nonce + timestamp | | Tamper detection | Timing-safe signature verification catches any modification | | Merkle batching | Batch thousands of proofs into one root hash — prove individual inclusion without exposing others | | Hash-chained audit log | Every event chained to the previous; any tampering breaks all subsequent entries | | Multi-signature | 3-signer system with derived keys from a master secret | | File hashing | Buffer support for PDFs, images, any binary format | | Zero dependencies | Uses only Node.js built-in crypto — nothing to audit, nothing to update | | Full TypeScript | Complete type definitions included |


Install

npm install logos-notary

Requires Node.js 18+.


Quick start

import { createProof, verifyProof, verifyContentAgainstProof } from 'logos-notary';

const SECRET = process.env.NOTARY_SECRET; // min 32 chars

// 1. Create a proof
const proof = createProof(
  { contract: 'MSA v1.2', signedBy: 'Alice', at: '2026-03-21' },
  { secret: SECRET, verificationBaseUrl: 'https://yourapp.com/verify' }
);

console.log(proof.proofId);       // PROOF-00001-AB3FC2
console.log(proof.contentHash);   // sha256 hex
console.log(proof.verificationUrl); // https://yourapp.com/verify/PROOF-00001-AB3FC2

// 2. Persist proof to your DB / file / S3 — your choice

// 3. Later: verify the stored proof is still valid
const check = verifyProof(storedProof, SECRET);
console.log(check.valid); // true

// 4. Verify the original content matches
const contentCheck = verifyContentAgainstProof(originalDocument, storedProof, SECRET);
console.log(contentCheck.valid);    // true  — content unchanged
console.log(contentCheck.message);  // "Proof is valid..."

API Reference

Core

hashContent(content: string | object | Buffer): string

Produces a SHA-256 hex digest. Accepts strings, JSON-serializable objects, or raw Buffers (for files).

createProof(content, options, sequenceNumber?): CreateProofResult

Creates a signed proof for any content.

const proof = createProof(document, {
  secret: 'your-32-char-secret',
  verificationBaseUrl: 'https://yourapp.com/verify', // optional
  proofIdPrefix: 'DOC',    // optional, default 'PROOF'
  includeQr: true,         // optional, default true
});
// Returns: { proofId, contentHash, signatureHash, serverNonce, timestampedAt, algorithm, verificationUrl, qrData }

verifyProof(proof: ProofRecord, secret: string): VerifyResult

Verifies the HMAC signature on a stored proof.

verifyContentAgainstProof(content, proof, secret): VerifyResult

Checks that content still matches the original hash AND the signature is valid.


Merkle tree

import { buildMerkleTree, getMerklePath, verifyMerklePath, getProofInclusion } from 'logos-notary';

// Build from an array of SHA-256 hashes
const { root, tree } = buildMerkleTree(hashes);

// Get proof-of-inclusion for one leaf
const path = getMerklePath(tree, leafIndex);

// Verify without rebuilding the tree
const valid = verifyMerklePath(leafHash, root, path);

// Convenience: build + path in one call
const inclusion = getProofInclusion(hashes, targetHash);
// Returns: { valid, root, index, path } or null if not found

Use case: Notarize 10,000 records → publish ONE Merkle root → any single record can prove membership with a O(log n) path.


Hash-chained audit log

import { AuditChain, verifyAuditChain } from 'logos-notary';

const chain = new AuditChain();

chain.append('document_uploaded', 'PROOF-001', contentHash, { filename: 'contract.pdf' });
chain.append('document_signed',   'PROOF-001', contentHash, { signedBy: '[email protected]' });
chain.append('document_shared',   'PROOF-001', contentHash, { sharedWith: '[email protected]' });

// Verify the entire chain
const result = chain.verify();
console.log(result.valid);   // true
console.log(result.entries); // 3

// Serialize → persist → restore → re-verify
const json = chain.toJSON();
const restored = AuditChain.fromJSON(json);
console.log(restored.verify().valid); // true

// Pass entries from your own database
const standaloneResult = verifyAuditChain(entriesFromDb);

Any modification to any entry invalidates all subsequent entries — provably, without a central server.


Multi-signature

import { createMultiSignatures, verifyMultiSignatures, buildDefaultSigners } from 'logos-notary';

// Build 3 signers derived from your master secret
const signers = buildDefaultSigners(masterSecret);

// Sign
const signatures = createMultiSignatures(contentHash, signers);

// Verify
const result = verifyMultiSignatures(contentHash, signatures, signers);
console.log(result.valid);  // true
console.log(result.passed); // 3

Storage

logos-notary is storage-agnostic. It creates and verifies proofs; you decide where to persist them.

// PostgreSQL example (Drizzle ORM)
await db.insert(proofs).values({
  proofId:       proof.proofId,
  contentHash:   proof.contentHash,
  signatureHash: proof.signatureHash,
  serverNonce:   proof.serverNonce,
  timestampedAt: proof.timestampedAt,
});

// Or just write to a file
import { writeFileSync } from 'fs';
writeFileSync(`proofs/${proof.proofId}.json`, JSON.stringify(proof));

Security notes

  • Secret key: Use at least 32 random characters. Store in environment variables, never in code.
  • Signature algorithm: SHA-256 HMAC with server nonce — resistant to length-extension attacks.
  • Timing-safe comparison: All signature comparisons use crypto.timingSafeEqual to prevent timing attacks.
  • Nonce: Every proof gets a fresh 16-byte random nonce — two identical documents produce different proofs.
  • No content stored: The proof only stores the hash — your actual content never leaves your system.

Examples

Three complete, runnable examples are in /examples:

| File | What it shows | |---|---| | basic-proof.mjs | Create, store, verify, and detect tampering on a document | | merkle-batch.mjs | Batch 10 documents, prove individual inclusion, detect forgery | | audit-chain.mjs | Build, serialize, restore, and tamper-test an audit chain |

# Build first
npm run build

# Then run any example
node examples/basic-proof.mjs
node examples/merkle-batch.mjs
node examples/audit-chain.mjs

Tests

npm run build
node --test test/core.test.mjs

Production proof

This library powers the LOGOS Notary — a live public verification system with 924 cryptographic proofs recorded in production as of March 2026.

Every prediction, token mint, and trade record in the LOGOS VPH-257 protocol is notarized using the exact algorithms in this library.


Who uses cryptographic notarization

  • Fintech — KYC/AML document integrity, loan application tamper-proofing
  • Legal tech — Contract existence proof before dispute dates
  • Healthcare — HIPAA-compliant audit trails for patient record changes
  • IP protection — Timestamp creative work before publication
  • Supply chain — Chain-of-custody provenance at each handoff
  • Compliance — SOX, GDPR, ISO 27001 audit trail requirements

License

MIT — Grace AI Technologies LLC


"Timing is worth more than trust. Proof is worth more than both."