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

@lazyjackorg/bipcircle-verifier

v0.1.3

Published

Open-source verifier for BIPCircle stablecoin reserve attestations. Re-derives PASS/FAIL from primary sources (XRPL, bank-service JWKS, on-chain token supply) without trusting BIPCircle or Lazy-Jack infrastructure.

Readme

bipcircle-verifier

Open-source verifier for the BIPCircle public-reserve-verifier protocol v1. Anyone can prove a BIPCircle stablecoin reserve attestation PASSes or FAILs without trusting BIPCircle or any Lazy-Jack infrastructure.

The verifier reads primary sources (the XRPL ledger, the bank-service's published JWKS, the witness file in GCS, and the on-chain token contract) and re-derives the same checks BIPCircle's anchor side runs internally. The trust roots are pinned in the verifier source — not user input — so a wrong URL or social-engineered tx hash can't produce a false PASS.

Install

npm install -g @lazyjackorg/bipcircle-verifier

Requires Node.js 20+.

Use — pinned-tenant mode (preferred)

bipcircle-verify --xrpl-tx <hash> --tenant <tenantId>

The tenant id is looked up in the verifier's pinned src/tenants.json registry. Trust roots — bank-service URL, XRPL issuer account, KMS public-key fingerprint pattern, on-chain token contract — all come from the registry. Output:

VERDICT: PASS
  asOfDate: 2026-05-24
  tenantId: tvvin-prod
  sealCount: 24
  signatures: 24/24 OK
  merkle root: OK
  reserves: 100245700 | supply: 100245700 | match: ✓

The "match ✓" line is the on-chain supply comparison — reserves measured in bank-side minor units (pennies/cents) compared to the on-chain token totalSupply().

Use — unsafe-override (ad-hoc verification of an unregistered tenant)

bipcircle-verify \
    --xrpl-tx <hash> \
    --unsafe-bank-service-url https://bank-service-<tenant>.run.app \
    --unsafe-issuer rExampleIssuerAccount...

For tenants not yet in the verifier's pinned registry. Operator accepts the trust-anchor responsibility — both the URL and the issuer address need to come from a trusted out-of-band source (DPA, GFSC registry, etc.). On-chain supply check is skipped in this mode (no token-contract config available).

Exit codes: 0 PASS, 1 FAIL, 2 invocation error. --json for machine-readable output.

What the verifier actually checks

  1. Registry resolution — looks up the pinned trust roots for --tenant OR validates --unsafe-* overrides.
  2. XRPL transaction — fetches the tx by hash via public JSON-RPC. Validates tx.Account === pinned issuer (closes Pro F2 cross-account spoofing). Parses Memo 5 (reserve-verifier-v1).
  3. Memo kid binding — verifies the bankServicePublicKeyId in Memo 5 matches the tenant's pinned kidPattern (closes Pro F1 attacker-controlled URL).
  4. Witness file — HTTPS GET. Validates SHA-256 of the bytes against witnessSha256 in Memo 5. Schema check.
  5. Bank-service JWKS — fetches /.well-known/bank-service-keys from the pinned bankServiceUrl. Validates every advertised kid matches the tenant's kidPattern. Rejects duplicate kids; pins alg=ES256.
  6. Seal signatures — for every seal in the witness, decodes the canonical input and ECDSA-verifies the signature against the matching public key.
  7. Merkle root — re-builds the Merkle root from leaf digests; compares to Memo 5's anchored root.
  8. On-chain supply — fetches token totalSupply() from the chain in the tenant registry; compares to the sum of bank-side balances. Reports "match ✓" or "shortfall of N minor units."

Every stage produces a structured failure record on FAIL. --json gives the full diff.

Trust model

The verifier trusts only:

  • This verifier's pinned tenant registry (src/tenants.json, ships in the source release; operator-PR'd as tenants onboard)
  • The XRPL ledger (public, permissionless)
  • The bank-service public keys the operator publishes at the pinned /.well-known/bank-service-keys endpoint (HSM-backed ECDSA P-256, FIPS 140-2 Level 3)
  • The witness file's SHA-256 anchored on the immutable XRPL transaction
  • Node.js's built-in crypto (no external cryptographic dependencies)

The verifier does not trust BIPCircle, Lazy-Jack, the bank-service operator, the GCS witness host, or this binary's source (you can read it, build it, and check the npm + SLSA provenance on every release).

Protocol

https://github.com/Lazy-Jack-Ltd/bipcircle/blob/main/Documentation/architecture/public-reserve-verifier-protocol.md

Producer-side source-of-truth:

  • bank-service sealSigner.js (seal envelope + canonical input)
  • BIPCircle audit.js buildBankServiceSealCanonicalInput
  • BIPCircle sealMerkle.js (Merkle root + witness file shape)
  • BIPCircle publishTenantTreasuryAttestation.js (XRPL Memo 5 emit)

Releases + provenance

Every tagged release ships with:

  • npm package signed via npm provenance (build attested by GitHub Actions OIDC on a public runner)
  • SHA-256 checksums of the tarball on the GitHub release
  • Auto-generated release notes

To verify a downloaded release:

npm audit signatures @lazyjackorg/bipcircle-verifier
sha256sum lazy-jack-bipcircle-verifier-*.tgz

Adding a tenant

Tenants are pinned in source: every release embeds the registry available at release time. To onboard a new tenant:

  1. Open a PR to src/tenants.json adding the entry:

    {
      "tenantId": "your-tenant-id",
      "bankServiceUrl": "https://bank-service-your-tenant.run.app",
      "xrplIssuerAddress": "rYourTreasuryWalletAddress...",
      "kidPattern": "^projects/your-gcp-project/locations/europe-west2/keyRings/bank-service-signers/cryptoKeys/your-tenant-signer/cryptoKeyVersions/\\d+$",
      "token": {
        "chain": "ethereum",
        "contract": "0xYourErc20Address...",
        "decimals": 2,
        "currency": "GBP"
      }
    }
  2. Cut a new verifier release (bump the patch / minor). External verifiers upgrade when ready.

Until the new release lands, third parties can verify your tenant using --unsafe-bank-service-url + --unsafe-issuer overrides.

Building from source

git clone https://github.com/Lazy-Jack-Ltd/bipcircle-verifier
cd bipcircle-verifier
npm install
npm test
node bin/bipcircle-verify.js --help

No build step — pure JavaScript, runs directly on Node.

License

MIT — see LICENSE.

Audit history

  • v0.1.0 — initial release
  • v0.1.1 — self-audit pass: fetch timeouts on every external call (10s/15s/30s), CLI --key=value form, witness sealCount type check
  • v0.1.2 — Gemini Pro adversarial audit + external reviewer feedback:
    • F1 (CRITICAL) + F2 (CRITICAL) closed: pinned per-tenant registry binds bank-service URL + XRPL issuer + kid pattern in the verifier source (not user input). Closes both the user-supplied-URL trust gap AND the accept-any-XRPL-account spoofing path.
    • F4 (MEDIUM) closed: JWKS now rejects duplicate kids + pins alg=ES256 strictly.
    • 0.2.0 forward-port: on-chain totalSupply() comparison wired in via tenant registry's token config. Output now reports reserves = X | supply = Y | match ✓ or shortfall.
    • F7 (test coverage) closed: 21 tests (up from 14) including F1/F2/F4 regressions + signature-forgery + duplicate-kid + unknown-tenant + wrong-XRPL-account adversarial paths.
    • False positives documented in the commit message (nested-key canonicalisation, Merkle reorder, try/catch on crypto.verify — none were real issues; verifier doesn't re-canonicalise, witnessSha256 binds bytes, try/catch was already present).

Reproducible builds (bit-identical output) remain a 0.3.0 target.