
Research
/Security News
TensorLake npm SDK Compromised in ChainDrop Shai-Hulud Credential-Stealing Attack
Tensorlake npm SDK version 0.5.144 was compromised in a ChainDrop / Shai-Hulud attack, delivering credential-stealing malware.
@fairseal/verify
Advanced tools
Independent verification for VEO-2 objects — structure, integrity, Ed25519 signatures, and on-chain Merkle anchors. Zero dependencies beyond @fairseal/core.
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 @openrng/core — an independent verifier shouldn't require you to
install more than the thing it verifies.
npm install @openrng/verify
| 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.
import { verifyVEO } from '@openrng/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.
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 '@openrng/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:
merkleProof — the object's leaf hashes up to anchor.merkle_root
(local, no network).transaction — the anchor transaction succeeded and emitted a
BatchAnchored event carrying that exact root, from the expected contract.contractState — getBatchRoot(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.
}
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.
Exported for building your own tooling:
import { verifyMerklePath, computeMerkleRoot } from '@openrng/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 OpenRNG's tree construction.
position names the side the sibling sits on.
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.
MIT
FAQs
Independent verification for FairSeal anchor receipts and VEO-2 objects — structure, integrity, Ed25519 signatures, and on-chain Merkle anchors. ESM + CJS, Node >= 18.
The npm package @fairseal/verify receives a total of 20 weekly downloads. As such, @fairseal/verify popularity was classified as not popular.
We found that @fairseal/verify demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Research
/Security News
Tensorlake npm SDK version 0.5.144 was compromised in a ChainDrop / Shai-Hulud attack, delivering credential-stealing malware.

Research
/Security News
Socket found 16 malicious Firefox extensions designed to steal crypto wallet recovery phrases and private keys using cloned Rabby and OKX interfaces.

Product
Socket now scans VS Code extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.