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

@trustbench/verify-receipt

v0.1.2

Published

Standalone third-party verifier for TrustBench Ed25519-signed receipts. No TrustBench API calls in the verify path beyond fetching the published public key.

Readme

@trustbench/verify-receipt

Standalone third-party verifier for TrustBench Ed25519-signed receipts.

No TrustBench API calls in the verify path beyond fetching the published public key. Verifies offline once the public key is cached. Optional on-chain verification via viem peer dependency.

Install

npm install @trustbench/verify-receipt
# Optional, for on-chain verification:
npm install viem

Supported receipt prefixes

Two prefixes are accepted; both route to the same /receipts/:id endpoint:

| Prefix | Issued by | Envelope shape | |---|---|---| | rcpt_… | Phase 3 settlement receipts | receipt.settlement.{chain, tx_hash, block_number, payer_address, payee_address, amount_atomic, …} | | rrcpt_… | Phase 4 paywall routing receipts | receipt.paid.{chain, tx_hash, payer_address, payee_address, amount_atomic, …} (no block_number; verifier confirms the block via the tx_hash lookup) |

The verifier handles both shapes transparently. Code that already worked with rcpt_ requires no changes.

Usage (programmatic)

import { verifyReceipt } from '@trustbench/verify-receipt';

// By receipt id (Phase 3 or Phase 4)
const result = await verifyReceipt('rcpt_01KQY7C44GAPSXZPFQYRZ1D10C');
const result2 = await verifyReceipt('rrcpt_01KRN8HYPPRD1MS9JE7045S77Q');
console.log(result.signatureValid); // true | false
console.log(result.ok);              // signature valid + chain verified (if checkChain)

// From an already-fetched envelope
const result = await verifyReceipt(envelope);

// From a full URL
const result = await verifyReceipt('https://trustbench.io/receipts/rrcpt_...');

// With on-chain verification
const result = await verifyReceipt('rrcpt_...', { checkChain: true });
if (result.chain && result.chain.ok) {
  console.log('Block:', result.chain.block_number);
  console.log('Payer:', result.chain.payer);
  console.log('Amount:', result.chain.amount, '(atomic USDC)');
}

Usage (CLI)

# Signature-only verification
npx trustbench-verify-receipt rcpt_01KQY7C44GAPSXZPFQYRZ1D10C
npx trustbench-verify-receipt rrcpt_01KRN8HYPPRD1MS9JE7045S77Q

# Signature + on-chain (requires viem)
npx trustbench-verify-receipt rrcpt_01KRN8HYPPRD1MS9JE7045S77Q --check-chain

# From a local JSON file
npx trustbench-verify-receipt ./my-receipt.json

# Override the public key URL (useful for local-dev verification)
npx trustbench-verify-receipt ./my-receipt.json --pubkey-url http://localhost:3000/.well-known/trustbench-pubkey

Exit codes: 0 valid, 1 bad args, 2 signature invalid (tamper signal), 3 on-chain mismatch, 4 chain check error, 5 verification unavailable (couldn't fetch the receipt or public key — connectivity, not tampering).

What gets verified

The signature step:

  1. JCS-canonicalize the receipt object (RFC 8785-style: sorted keys at every depth, JSON.stringify for primitives, no whitespace).
  2. Encode to UTF-8 bytes.
  3. Verify the Ed25519 signature against those bytes using the public key fetched from signature.public_key_url.

The optional on-chain step (when --check-chain is used):

  1. Fetch the transaction by settlement.tx_hash from a Base RPC.
  2. Confirm tx.to is the USDC contract (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913).
  3. Decode the calldata as transferWithAuthorization(from, to, value, ...).
  4. Confirm from, to, and value match the receipt's payer_address, payee_address, and amount_atomic.
  5. Confirm the tx was mined successfully and (if present in the receipt) at the claimed block_number.

A signature alone tells you "TrustBench claims this happened with these parameters." --check-chain tells you "the chain agrees with TrustBench's claim." Both together is the strongest assurance an external party can get without trusting either side.

API

verifyReceipt(input, options?)

| Param | Type | | |---|---|---| | input | Object \| string | Receipt envelope, id (rcpt_...), full URL, or .json path | | options.baseUrl | string | Override base URL for id-based input. Default https://trustbench.io | | options.pubkeyUrl | string | Override the public_key_url from the envelope | | options.checkChain | boolean | Also verify on-chain settlement (requires viem) | | options.rpcUrl | string | RPC URL for chain check. Default https://mainnet.base.org |

Returns Promise<VerifyResult> — see index.d.ts for the full shape.

verifyOnChain(envelope, rpcUrl?)

Lower-level helper. Same chain check as verifyReceipt({ checkChain: true }) but skips the signature step. Returns { ok, reason?, chain?, tx_hash?, block_number?, payer?, payee?, amount? }.

jcsCanonicalize(obj)

The exact canonicalization function used internally. Useful for callers that want to reconstruct the bytes that were signed.

Compatibility

  • Node.js >= 18 (for built-in fetch).
  • viem >= 2.0.0 peer dependency, optional, only needed for --check-chain.
  • Mirrors the in-repo reference verifier (scripts/verify-receipt.js) byte-for-byte for the JCS + Ed25519 logic. If they disagree, that's a bug — please open an issue.

Changelog

0.1.2

  • Added verificationStatus: 'valid' | 'invalid' | 'unavailable' on the VerifyResult. Previously, a fetch failure for the receipt URL or the public key URL was indistinguishable from a tampered signature in the headline output. CLI now prints ⚠️ VERIFICATION UNAVAILABLE (exit code 5) when the verifier could not reach the URLs needed to do the math, vs. ❌ SIGNATURE INVALID (exit code 2) only when bytes were checked and do not match. CI policies that retry on flakiness but alert on tamper should branch on this distinction.
  • The signatureValid boolean and existing exit codes 0-4 are preserved. v0.1.0/v0.1.1 callers using result.signatureValid or result.ok continue working unchanged.
  • Refreshed example IDs in the README and CLI HELP block to point at the post-Strata-PR-24 reference receipt (rrcpt_01KRN8HYPPRD1MS9JE7045S77Q).
  • No change to the JCS canonicalization or Ed25519 verify logic. If v0.1.1 said VALID, v0.1.2 says VALID.

0.1.1

  • Recognize the rrcpt_ prefix in addition to rcpt_. Both route to the same /receipts/:id endpoint on the issuer host.
  • Verifier reads on-chain settlement data from either receipt.settlement (Phase 3) or receipt.paid (Phase 4 paywall routing receipts). When block_number is absent on the paywall envelope, the verifier still confirms the on-chain transaction via the tx_hash lookup and reports block_check: "block_number not in receipt" in the chain result.
  • No breaking changes. v0.1.0 callers continue working unchanged.

0.1.0

  • Initial release. Ed25519 signature verification over RFC 8785 JCS-canonical bytes, optional on-chain verification via viem.

License

MIT. See LICENSE.

Links