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

@zdottedline/verify

v1.0.2

Published

Independent, vendor-neutral verification CLI for ZDottedLine signed documents. Verifies hash chain, Polygon anchor, and Bitcoin (OpenTimestamps) anchor without depending on ZDottedLine infrastructure.

Downloads

36

Readme

zdl-verify

Independent verification CLI for ZDottedLine signed documents. Confirms hash chain, Polygon anchor, and Bitcoin (OpenTimestamps) anchor. Open source. MIT-licensed. No dependency on ZDottedLine infrastructure.

If ZDottedLine, Inc. ceases to exist tomorrow, every signed document remains independently verifiable using this tool, the published spec, the signed PDF, and any public Bitcoin / Polygon node.

That's the whole point.

Spec v1.0 | Issues | npm


Install

npm install -g @zdottedline/verify

Or run without installing:

npx @zdottedline/verify verify <document-id>

Requires Node.js 20+. No other dependencies beyond commander for CLI parsing.

Quick start

$ zdl verify efca4f81-1ac4-4b40-a595-0dc51d0752c0

=== ZDL VERIFY === [VERIFIED]
  document: efca4f81-1ac4-4b40-a595-0dc51d0752c0
  endpoint: https://zdottedline.com

  [PASS] verify-endpoint    https://zdottedline.com/api/verify/efca4f81-...
  [PASS] hash-chain         4 events linked correctly
  [PASS] polygon-anchor     on-chain Merkle root matches (block 54221098)
  [PASS] bitcoin-anchor     confirmed at Bitcoin block 850123 — calendar: alice.btc

  Result: VERIFIED. The signed document's integrity is independently confirmed
  via public Polygon RPC + public Bitcoin block data. ZDottedLine does not
  need to be in the loop for this verification to be valid.

What this tool does

                              You
                               |
                               | (1) GET verify JSON
                               v
                    +-------------------+
                    | zdottedline.com   |  ← only this one server call to ZDL
                    +-------------------+
                               |
                  ┌────────────┼─────────────┐
                  | (2)         (3)          (4)
                  v            v             v
            (hash chain)  Polygon RPC     Bitcoin API
              [LOCAL]     [PUBLIC]         [PUBLIC]
                          polygon-rpc.com   blockstream.info
                          (or yours)        (or yours)
                  |            |             |
                  v            v             v
              VERIFIED     VERIFIED      VERIFIED

Step 1 retrieves the document's hash chain + on-chain anchor references. Steps 2-4 perform the cryptographic checks against public networks. ZDottedLine's server is involved in step 1 only, and only for read access to publicly-hashed data.

Commands

zdl verify <documentId>

Full verification: hash chain + Polygon anchor + Bitcoin anchor.

zdl verify efca4f81-1ac4-4b40-a595-0dc51d0752c0
zdl verify efca4f81-1ac4-4b40-a595-0dc51d0752c0 --json   # machine-readable
zdl verify efca4f81-1ac4-4b40-a595-0dc51d0752c0 --skip-bitcoin

Exit codes:

  • 0 — verified
  • 1 — failed
  • 2 — partial (some anchors verified, others pending)

zdl info <documentId>

Show the verify endpoint's JSON response without performing verification. Useful for debugging or for consuming the data in other tools.

zdl info efca4f81-1ac4-4b40-a595-0dc51d0752c0
zdl info efca4f81-1ac4-4b40-a595-0dc51d0752c0 --json

Self-sufficient verification (highest trust)

By default, zdl-verify uses public RPCs / APIs for Polygon and Bitcoin. For verification with no third-party dependencies at all, point at your own nodes:

zdl verify <id> \
  --polygon-rpc http://localhost:8545 \
  --btc-api http://localhost:3000/api

Or via environment variables:

export ZDL_POLYGON_RPC=http://localhost:8545
export ZDL_BITCOIN_API=http://localhost:3000/api
zdl verify <id>

For self-hosted ZDottedLine deployments, also override the verify endpoint:

zdl verify <id> --endpoint https://signing.your-company.com
# or: export ZDL_VERIFY_ENDPOINT=...

Programmatic use

import { verify } from "@zdottedline/verify";

const result = await verify({
  documentId: "efca4f81-1ac4-4b40-a595-0dc51d0752c0",
  endpoint: "https://zdottedline.com",
  polygonRpc: "https://polygon-rpc.com",
  bitcoinApi: "https://blockstream.info/api",
});

console.log(result.overall); // "verified" | "partial" | "failed" | "not_found"
console.log(result.checks);  // detailed per-anchor results

Lower-level building blocks (parseOtsProof, readAnchorOnChain, walkHashChain, computeMerkleRoot) are also exported for custom integrations.

How verification works

See SPEC.md for the full protocol specification (data formats, threat model, verification procedure).

The tl;dr:

  • Hash chain. Every document event (created, signed, completed) is SHA-256-hashed along with the prior event's hash, forming a tamper-evident linked list. The tool walks this chain locally; any break is reported with the exact event index.
  • Polygon anchor. The Merkle root of all events is committed to the ZdottedlineAnchor smart contract on Polygon. The tool reads this directly via eth_call against any public Polygon RPC and compares to the server-reported root.
  • Bitcoin anchor. The same Merkle root is timestamped to Bitcoin via OpenTimestamps. The tool downloads the .ots proof, walks its operations, fetches the referenced Bitcoin block from any public Bitcoin API, and confirms the proof commits to that block's Merkle root.

Each anchor independently proves the document's state at its block's timestamp. Compromising verification would require an attacker to produce a Bitcoin block AND modify a Polygon contract AND tamper with the local hash chain, which is roughly equivalent to "solve cryptographic primitives that secure ~$1T of value."

Why we built this

Most e-signature platforms tell you "we're tamper-proof" and ask you to trust their audit log. If the vendor goes away, gets breached, or simply changes their terms, the audit log goes with them.

We're trying to build the version where you don't have to trust us. The .ots proof file in your matter folder, plus this CLI, plus public Bitcoin and Polygon nodes, is sufficient to prove a document was signed at a specific moment — forever — with or without ZDottedLine, Inc. existing.

If you find a way to break that promise, please open an issue. We mean it.

Historical data disclosure

A defect in a prior version of the server-side recordDocumentEvent function caused hash-chain linkages to be miscomputed for events recorded before 2026-04-28 18:14:25 UTC. Documents signed before that time may report [FAIL] hash-chain when verified with this CLI — that is expected behavior given the historical defect. The Polygon and Bitcoin anchors over those documents remain independently valid; only the chain's internal linkage is affected. Scope of impact: 1 production document. Full disclosure including the rationale for not retroactively repairing the chain (immutability is the point) is in SPEC.md §8.

Audit trail / contributing

This is a small codebase by design. Read it. Audit it. Fork it. PR it.

src/
├── cli.ts              ~120 lines  CLI dispatch
├── index.ts            ~20 lines   programmatic API exports
└── lib/
    ├── api.ts          ~60 lines   public verify endpoint client
    ├── hash.ts         ~80 lines   SHA-256 + Merkle + chain walker
    ├── polygon.ts      ~110 lines  ZdottedlineAnchor contract reader
    ├── ots.ts          ~280 lines  OpenTimestamps proof walker
    ├── orchestrator.ts ~190 lines  end-to-end coordinator
    └── types.ts        ~50 lines   shared types

Total: ~900 lines of TypeScript. No transitive dependencies beyond commander (CLI parsing).

License

MIT © ZDottedLine, Inc.