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

@fairseal/verify

v0.1.1

Published

Independent verification for VEO-2 objects — structure, integrity, Ed25519 signatures, and on-chain Merkle anchors. Zero dependencies beyond @fairseal/core.

Readme

@fairseal/verify

Part of FairSeal — formerly OpenRNG.

Independent verification for VEO-2 (Verifiable Execution Object) records.

A VEO is only worth something if a third party can check it without trusting the party that issued it. This package is that checker. It has zero dependencies beyond @fairseal/core — an independent verifier shouldn't require you to install more than the thing it verifies.

npm install @fairseal/verify

Quick Start

import { verifyVEO } from '@fairseal/verify';

const result = verifyVEO(veo, { trustedKeys: [OUR_PUBLIC_KEY] });
if (!result.valid) console.error(result.errors);

Looking to verify a Committed Selection Receipt (CSReceipt)? That lives in @fairseal/commit — use its verifyReceipt(receipt), which returns status: 'VALID' | 'PARTIAL' | 'INVALID'. This package (@fairseal/verify) verifies VEO objects — structure, integrity, signature, and on-chain anchor.


Four separate questions

| Function | Question it answers | Network? | |---|---|---| | verifyStructure(veo) | Is this a well-formed VEO-2? | no | | verifyIntegrity(veo) | Has it been modified since it was signed? | no | | verifySignature(veo, trustedKeys?) | Was it signed by a key I trust? | no | | verifyAnchor(veo, rpcUrl?) | Is its Merkle root really on chain? | yes |

verifyVEO() runs the first three together and is what most callers want.


Quick start

import { verifyVEO } from '@fairseal/verify';

const result = verifyVEO(veo, { trustedKeys: [OUR_PUBLIC_KEY] });

if (result.valid) {
  console.log('verified');
} else {
  console.error(result.errors);
  console.error(result.checks); // per-check pass / fail / skipped
}

verifyVEO() is synchronous and never touches the network, so it is safe to run on untrusted input inside a request handler.


verifyVEO(veo, options?)

interface VerifyOptions {
  trustedKeys?: string[];      // PEM or raw 32-byte hex
  requireSignature?: boolean;  // default: true
}

interface VerificationResult {
  valid: boolean;
  checks: {
    structure: { status: 'pass' | 'fail' | 'skipped'; detail?: string };
    integrity: { status: 'pass' | 'fail' | 'skipped'; detail?: string };
    signature: { status: 'pass' | 'fail' | 'skipped'; detail?: string };
  };
  errors: string[];    // why it failed
  warnings: string[];  // what the result does *not* prove
}

Defaults are fail-closed. An unsigned object is not valid unless you pass { requireSignature: false }, and an empty trustedKeys array trusts nobody.

What a signature actually proves

This is the part most verifiers get wrong, so the API is explicit about it:

// Proves: not modified since signing.
// Does NOT prove: who signed it. Anyone can generate a keypair.
verifyVEO(veo);
// → valid: true, warnings: ['Signature was verified against the public key
//    embedded in the object…']

// Proves: signed by a key you decided to trust, and not modified since.
verifyVEO(veo, { trustedKeys: [OUR_PUBLIC_KEY] });
// → valid: true, warnings: []

If you are verifying someone else's VEO, always pass trustedKeys. A VEO that verifies against its own embedded key is self-consistent, not authentic.


verifyAnchor(veo, rpcUrl?)

Anchored VEOs (class VEO-2C) claim "this Merkle root was written to chain X in transaction Y". A signature over that claim only proves the issuer said so — confirming it means reading the chain back.

import { verifyAnchor } from '@fairseal/verify';

const result = await verifyAnchor(veo);                        // public RPC for the chain
const result = await verifyAnchor(veo, 'https://my-rpc.example'); // your own node
const result = await verifyAnchor(veo, { offline: true });     // local checks only

Three independent checks, strongest last:

  1. merkleProof — the object's leaf hashes up to anchor.merkle_root (local, no network).
  2. transaction — the anchor transaction succeeded and emitted a BatchAnchored event carrying that exact root, from the expected contract.
  3. contractStategetBatchRoot(anchor.batch_id) on the contract still returns that root. Skipped when batch_id is absent from the anchor record.
interface AnchorVerifyOptions {
  rpcUrl?: string;      // defaults to a public endpoint for anchor.chain
  offline?: boolean;    // skip all network calls
  timeoutMs?: number;   // per request, default 15000
  fetch?: FetchLike;    // inject a transport (tests, proxies)
  leafHash?: string;    // defaults to metadata._content_hash, then entropy_hash
}

verifyAnchor() never throws on network failure. An unreachable RPC yields valid: false with the check marked skipped, so you can tell "could not check" apart from "checked and wrong":

if (!result.valid && result.checks.transaction.status === 'skipped') {
  // RPC problem, not a bad anchor — retry later.
}

Supported chain

Anchoring currently runs on Polygon Amoy testnet against the MerkleAnchor contract at 0xA79E149C35Ad47Ed270Bf4b16B80170eBF7B88F8. Mainnet deployment is planned. See the root README for the full anchoring architecture.

Default RPC endpoints (DEFAULT_RPC_URLS) are provided for polygon-amoy and polygon-mainnet. For any other chain, pass rpcUrl explicitly.


Merkle helpers

Exported for building your own tooling:

import { verifyMerklePath, computeMerkleRoot } from '@fairseal/verify';

verifyMerklePath(leafHash, [{ hash: sibling, position: 'right' }], root);

Nodes are lowercase hex strings, and a parent is sha256(leftHex + rightHex) over the concatenated hex text — matching FairSeal's tree construction. position names the side the sibling sits on.


Verifying without this package

Everything here is deliberately reproducible from the spec. A verifier in another language needs: SHA-256, Ed25519, canonical JSON (sorted keys, undefined dropped), and an Ethereum JSON-RPC client. See docs/rfc/RFC-0002-VEO2.md and packages/core/veo-2.schema.json.


License

MIT