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

sellat-verify

v0.2.0

Published

Offline verifier for SELLAT proof-of-existence artifacts (sellat-proof/2). Zero dependencies.

Readme

sellat-verify

tests

Don't trust SELLAT. Verify.

sellat-verify is a standalone, zero-dependency verifier for SELLAT proof-of-existence artifacts (sellat-proof/2). Given a file and its proof.json, it proves — using only math and the public blockchain — that the exact bytes of that file existed no later than a specific moment in time.

No SELLAT server, database or goodwill is involved in verification. If sellat.app disappeared tomorrow, every proof it ever issued would still verify. That is the point.

Try it now — on a real proof

This repository ships a real example: a file whose proof was anchored on Polygon mainnet in transaction 0xdeb68fad….

$ git clone https://github.com/skanthemore/sellat-verify && cd sellat-verify
$ node bin/sellat-verify.mjs example/example.txt example/example.proof.json

 ✓ schema                 schema is "sellat-proof/2"
 ✓ content hash format    SHA-256 2ad295bdf52f661a…
 ✓ file matches proof     SHA-256 of the file equals content.hash
 ✓ leaf recomputation     leaf formula reproduces leaf.value
 ✓ merkle path            path folds to root 3c6e1005a0cb2699…
 ✓ has anchors            1 anchor(s)
 ✓ anchor[0] payload      payload commits to the root (Polygon Mainnet)

 ✓ anchor[0] on-chain     chain 137 confirms payload in block 91797318 (from 0x33167f8e…)

VERIFIED — this exact file existed no later than 2026-08-10T22:30:04.000Z.

Change a single byte of example.txt and verification fails.

Too much code? Verify it by hand

This example's batch has a single leaf, so you can check it with nothing but sha256sum and a block explorer:

# 1. Hash the file
$ sha256sum example/example.txt
2ad295bdf52f661acda66158a7b20fc7c982e190b2645117ea6a77583703e291

# 2. Compute the leaf (single-leaf batch ⇒ the leaf IS the Merkle root)
$ printf '%s' 'sellat-leaf:v2:d268831c-4c70-4226-97d9-bf1cd703d365:2ad295bdf52f661acda66158a7b20fc7c982e190b2645117ea6a77583703e291' | sha256sum
3c6e1005a0cb26993e3b445e5c755d75bc89ab60012cf8670cdd9c279b78b05c
  1. Open the transaction on Polygonscan, view its input data as UTF-8, and read:
sellat:v2:3c6e1005a0cb26993e3b445e5c755d75bc89ab60012cf8670cdd9c279b78b05c

That root sits in Polygon block 91797318, timestamped 2026-08-10 22:30:04 UTC. Nobody — including SELLAT — can rewrite that.

Usage

$ sellat-verify <file> <proof.json>              # offline checks + on-chain check
$ sellat-verify <file> <proof.json> --offline    # math only, no network, no date
$ sellat-verify <file> <proof.json> --rpc=<url>  # use your own JSON-RPC node

Exit code 0 means every check passed. Only the on-chain check proves a date, the block's time as the chain states it; --offline says so and states none. By default the on-chain check uses public RPC endpoints; pass --rpc= to use a node you control, so the verification trusts nothing chosen by anyone else.

As a library:

import { verifyProofOffline, checkAnchorOnChain } from 'sellat-verify';

The proven time is checkAnchorOnChain(...).blockTimestamp, read from the anchoring block. Never present the proof's own block_timestamp as proven: a proof.json is plain text, and since 0.2.0 a proof whose block_timestamp differs from the block's time fails the on-chain check. verifyProofOffline proves no date at all.

Verify in CI

This repository is also a composite GitHub Action, so a pipeline can prove its own artifacts verify before shipping them:

- uses: skanthemore/sellat-verify@main
  with:
    file: release/build.tar.gz
    proof: release/build.proof.json
    # offline: 'true'        # math only, skip the on-chain check
    # rpc: https://…         # or pin the check to a node you control

The job fails if the proof does not verify. Pair it with sellat-cli to stamp the artifact in the same pipeline.

How verification works

  1. SHA-256(file) must equal content.hash;
  2. the leaf is recomputed as SHA-256('sellat-leaf:v2:' + proof_id + ':' + content.hash);
  3. the Merkle path folds the leaf back to merkle.root;
  4. every anchor's payload must be exactly sellat:v2:<merkle.root>;
  5. the anchoring transaction is fetched from the chain and must carry that payload in its input data.

Steps 1–4 are pure computation. Step 5 works against any node or explorer. The full format is specified in SPEC.md and is frozen: issued proofs verify forever; format changes require a new schema version.

Trust layers

Artifacts can carry more than one independent layer over the same Merkle root: EVM anchors (anchors[], e.g. Polygon in minutes) and optional attestations[] — currently Bitcoin via OpenTimestamps, a standard .ots file you can verify with OTS tooling, at no cost. Layers verify separately; none depends on SELLAT or on each other. See SPEC.md §7.

What a proof does and does not claim

A sellat-proof/2 artifact proves existence and integrity at a point in time: these exact bytes existed no later than the anchor's block timestamp. It deliberately does not claim authorship, ownership, or that the content is true or authentic. In a world where anything can be fabricated now, the only unforgeable thing is the past — that is exactly what this verifies, and nothing more.

Getting a proof

Proofs come from the SELLAT API v2 (or the web app). From your own systems — only the SHA-256 leaves your machine:

$ curl https://sellat.app/api/v2/proofs \
    -H "Authorization: Bearer $SELLAT_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"hash\":\"$(sha256sum build.tar.gz | cut -d' ' -f1)\",\"name\":\"build.tar.gz\"}"

# once anchored (a few minutes), the portable proof is public — no key needed
$ curl -o build.proof.json https://sellat.app/api/v2/proof/<id>.json
$ sellat-verify build.tar.gz build.proof.json

About

Built by SELLAT — proof of existence for one file or a million, on the same engine. Every proof, created on the web or through the API, has its proof.json; this verifier and the format specification are the stable, public reference.

MIT licensed. Issues and PRs welcome.