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

@proofchain/verify-core

v0.1.1

Published

Trustless browser verification for ProofChain events and Score Receipts — Merkle proofs + on-chain root checks, zero dependencies

Readme

@proofchain/verify-core

Trustless, browser-friendly verification for ProofChain events and Score Receipts. Zero runtime dependencies — recomputes Merkle proofs and checks on-chain roots using nothing but fetch and the Web Crypto API, so it can run entirely client-side without trusting the ProofChain API.

Install

npm install @proofchain/verify-core

Requires Node 18+ (or any modern browser) for global fetch and crypto.subtle.

Usage

1. Verify a single event from the proof-bundle endpoint

import { verifyEvent } from '@proofchain/verify-core';

const bundle = await fetch(
  `https://api.proofchain.co.za/verify/event/${eventId}/proof-bundle`,
).then((r) => r.json());

const result = await verifyEvent(bundle);

console.log(result.level); // 'invalid' | 'merkle_valid' | 'chain_confirmed'

2. Verify a receipt fetched from /verify/receipt/{id}

import { verifyReceipt } from '@proofchain/verify-core';

const manifest = await fetch(
  `https://api.proofchain.co.za/verify/receipt/${receiptId}`,
).then((r) => r.json());

const result = await verifyReceipt(manifest);

console.log(result.level);           // overall verification level
console.log(result.events);          // { total, merkleValid, chainConfirmed, unresolved }
console.log(result.scoreCheck);      // advisory recomputed score sum

3. Override the RPC endpoint (or skip chain checks entirely)

import { verifyReceipt } from '@proofchain/verify-core';

// Use your own Polygon RPC provider instead of the public default.
const result = await verifyReceipt(manifest, {
  rpcUrl: 'https://polygon-mainnet.g.alchemy.com/v2/<key>',
  timeoutMs: 5_000,
});

// Or verify Merkle inclusion only, with no network calls at all.
const offlineResult = await verifyReceipt(manifest, { skipChainCheck: true });

Threat model

This package answers: "does this event/receipt data match what ProofChain committed on-chain?" It does not answer "is ProofChain trustworthy" or "is the API currently serving correct data" — it lets you check the API's claims independently.

Verified in v1:

  • The leaf hash is recomputed from the event's own public fields (certificate_id, document_hash, event_id) — the API cannot silently substitute a different document and still pass.
  • Merkle inclusion — the leaf really is included under the claimed root, via an independently-walked proof (OpenZeppelin sorted-pair convention).
  • On-chain confirmation — for a given tx_hash, the transaction succeeded, was sent to the expected contract address, and its attestBatch(...) calldata's merkleRoot argument equals the claimed root, via a direct Polygon RPC call the verifier controls.

NOT verified in v1 (explicitly deferred):

  • The attestBatch selector, batchId, and tenantId calldata arguments are not bound via keccak256 (that needs a vendored keccak implementation or an extra dependency); only the 256-bit merkleRoot equality is checked.
  • Block finality depth — a confirmed transaction could still be reorged on a very recent block; this package does not wait for or check confirmation depth.
  • Epoch Merkle inclusion — epochLeafValid recomputes and compares the epoch leaf hash, but does not walk a Merkle proof against an epoch tree root (the manifest carries only the leaf fields in v1, not an inclusion proof).

Score-recompute caveat

scoreCheck in verifyReceipt's result is advisory, not proof. It sums each event's contribution as a 4-decimal-place fixed-point BigInt (never floating point, so no drift) and compares it to totals.total_score. When the receipt is truncated, or any event is unresolved, the sum is reported as an upper bound with exact: false and an explanatory note. Even when exact is true, this is not a cryptographic guarantee: daily-cap-zeroed events are not flagged in the v1 manifest, so a capped event's true contribution to the score may differ from what's shown, and the recomputed sum can only ever be checked against the manifest's own totals — not against data the manifest doesn't carry.

API

See src/types.ts and src/receipt.ts for full type definitions, including EventProofBundle, ReceiptManifest, VerifyOptions, EventVerifyResult, and ReceiptVerifyResult.