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

@fts-tas/verify

v1.6.0

Published

Offline verifier for TAS composite ACDCs. Verifies issuer signatures, ACDC edge chaining, component integrity, signed status lists and on-chain anchor commitments without contacting TAS.

Readme

@fts-tas/verify

Offline verifier for TAS composite ACDCs. Verifies component integrity, issuer signature, issuer trust, and on-chain anchor commitment without contacting TAS.

This package exists so DIFO - and any other party consuming a TAS-assembled composite credential - can validate it independently. TAS can go dark and verification still works.

Install

npm i @fts-tas/verify

Usage

import { verifyComposite } from "@fts-tas/verify";

const result = await verifyComposite(bundle, {
  trustedIssuers: new Set(["EBfxc4dBtLk3a..."]),
  // Supply the issuer's KERI key event log and the verifier derives the
  // signing key itself - no key needs pinning out of band.
  resolveKel: async (aid) =>
    fetch(`https://your-watcher.example/oobi/${aid}`).then((r) => r.text()),
  readAnchor: async (proof) => {
    // Caller supplies their own on-chain reader - we never phone home.
    // TAS notarises to Polygon PoS. Any other chain a caller wishes to read
    // is the caller's own arrangement.
    if (proof.chain === "evm") return readEvmCommitment(proof.txId);
    return null;
  },
});

if (result.verdict === "valid") accept(bundle);

Identifiers and single credentials

import { verifyAid, verifyCredential } from "@fts-tas/verify";

// Replays the key event log from inception and binds it to the prefix.
const aidResult = await verifyAid({ aid, kel });

// Recomputes the credential SAID and checks the issuer signature.
const credResult = await verifyCredential({ acdc, raw, signature, issuerKel });

From the command line, with the bundle fetched for you:

npx @fts-tas/verify --aid E... --api https://api.trustanchorservice.com/v1
npx @fts-tas/verify --said E... --offline --api https://api-sandbox.trustanchorservice.com/v1
npx @fts-tas/verify bundle.json      # composite, identifier or credential

The offline bundle endpoint used by --aid and --offline is public. No key, account or relationship with TAS is needed to run these checks. --anon is still accepted for deployments that place the endpoint behind a gateway.

Checking the TAS root identifier yourself

This is the shortest independent check of the identifier that anchors the service. It contacts the public endpoint, replays the whole key event log and verifies the witness receipts on every event.

npx @fts-tas/verify \
  --aid EOSmZFUzeh813BgwYogwpdgfb0NthqWTPNcExx_bo0I2 \
  --api https://api.trustanchorservice.com/v1

The key event log can also be fetched straight from any of the four witnesses and checked with --kel, which removes the TAS API from the path entirely:

curl -s https://wit2.keri.trustanchorservice.com/oobi/EOSmZFUzeh813BgwYogwpdgfb0NthqWTPNcExx_bo0I2/witness > root.cesr
npx @fts-tas/verify --aid EOSmZFUzeh813BgwYogwpdgfb0NthqWTPNcExx_bo0I2 --kel root.cesr

Exit codes

| Code | Meaning | | --- | --- | | 0 | valid | | 1 | invalid | | 2 | unknown, including a bundle that could not be fetched | | 3 | usage or input error, including a local file that cannot be read or parsed |

A verdict is never 0 by accident. A missing argument, an unreadable file and an unreachable endpoint are all reported and all non-zero.

What gets checked

| Check | How | | --- | --- | | Component integrity | sha256 of each raw component equals the manifest hash | | Key event log | CESR stream replayed from inception: every SAID recomputed with a bundled BLAKE3, sequence numbers, prior digests and controller signatures | | Issuer signature | Ed25519 over the exact canonical payload, against the key state derived from the log (or a pinned key) | | Issuer trust | optional caller-supplied allow list | | Anchor | on-chain commitment equals the composite SAID, read by the caller's own node |

verdict is valid only when every applicable check passes, unknown when no key material was supplied at all, and invalid otherwise. There is no silent pass.

Dependencies

None. BLAKE3 is bundled; Ed25519 uses Web Crypto with a node:crypto fallback. Works in Deno, Node 20+, Bun and modern browsers.

Bundle shape

A composite bundle is the JSON returned by the TAS assemble-composite-acdc function plus the raw component credentials the verifier needs to recompute hashes:

{
  "acdc":       { "d": "...", "i": "...", "s": "...", "a": {}, "e": { "components": [...] } },
  "signature":  "<CESR signature>",
  "components": [ { "raw": "<original credential>", "entry": { ... } } ],
  "anchor":     { "chain": "cardano", "network": "mainnet", "txId": "...", "commitment": "..." }
}

Status

1.3.1. Component hashes, KEL replay, issuer signature, trust list and anchor checks are all implemented and produce the same verdict as the TAS kel-replay-verify service running server side.

Spec

See SPEC.md for the wire format and verification algorithm.

License

Apache-2.0.

What is checked offline, and what is not

Verifying an identifier bundle with no network reports four things separately, and the separation is deliberate.

| Check | What a pass means | | --- | --- | | key event log | Every event's digest recomputes, the log is linked and in sequence, each rotation honours its prior commitment, and the controller signatures meet the signing threshold in force. | | prefix binding | The log self-certifies the identifier the bundle claims. | | witness agreement | The witness receipts attached to each event verify against the witness list that event declares, and meet the witness threshold. | | trust list | The identifier is on the allow list the caller supplied. |

Witness receipts have been verified since 1.4.0. Earlier versions parsed past the receipt bytes without checking them, which meant a bundle with altered receipts and a bundle with sound receipts produced the same result. If you are pinned to 1.3.x, upgrade.

Witness agreement prints NOT ESTABLISHED rather than FAIL when a log simply carries no receipts, because that is an unmeasured condition and not evidence of a fault. A receipt that is present and does not verify does fail the verdict.

What this does not do

Verifying receipts shows that the named witnesses signed these exact event bytes. It does not show that no conflicting version of the log was served to someone else. Establishing that means comparing what different parties were served over time, which is a watcher function and is not part of this package. Nothing this package outputs is duplicity detection.

Revocation is also out of scope offline: the question answered is whether the record was validly issued, not whether it is still current.