@rankigi/verify
v1.0.1
Published
Standalone verifier for RANKIGI closure exports and hash chains
Readme
@rankigi/verify
Standalone verifier for RANKIGI closure exports and hash chains. No server required. Runs in browser and Node 20+.
Install
npm install @rankigi/verifySection 1: Verify a closure export (chain-hash check)
verifyChainHash aggregates event_hashes into a single SHA-256 over their canonical JSON representation and compares it to the chain_hash field in a closure export. This is the fast path. It proves the set of event hashes in the export was not altered.
import { verifyChainHash } from "@rankigi/verify";
const closure = JSON.parse(await fs.readFile("closure.json", "utf-8"));
const result = await verifyChainHash(
closure.event_hashes,
closure.chain_hash,
);
if (result.verified) {
console.log("Chain hash matches:", result.computed_chain_hash);
} else {
console.error("Chain hash mismatch");
console.error(" computed:", result.computed_chain_hash);
console.error(" provided:", result.provided_chain_hash);
}ChainHashResult shape:
{
verified: boolean;
first_broken_index: number | null;
computed_chain_hash: string;
provided_chain_hash: string;
}first_broken_index is always null for the aggregate verifier. For per-event localization use verifyChain.
Section 2: Verify individual event hashes
verifyChain walks every event in the export, recomputes its hash from the canonical field set, and verifies that each previous_event_hash matches the prior event's event_hash. If a chain is broken, the result includes a tamperedAt location.
import { verifyChain } from "@rankigi/verify";
const closure = JSON.parse(await fs.readFile("closure.json", "utf-8"));
const result = await verifyChain(
JSON.stringify(closure.events),
closure.chain_hash,
);
if (result.ok) {
console.log("Verified", result.eventsVerified, "events");
console.log("Head hash:", result.chainHeadHash);
console.log("Aggregate chain_hash verified:", result.chain_hash_verified);
} else {
console.error("Verification failed:", result.error);
if (result.tamperedAt) {
console.error(" at chain_index:", result.tamperedAt.chainIndex);
console.error(" event_id:", result.tamperedAt.eventId);
console.error(" expected:", result.tamperedAt.expectedHash);
console.error(" actual:", result.tamperedAt.actualHash);
}
}The second argument is optional. When provided, the result includes chain_hash_verified: boolean reflecting the aggregate check against event_hashes derived from the supplied events.
Note: for full offline verification, use a closure export at schema 1.3 or later which includes the events[] array.
Guarantees
- Pure functions. No DB. No network. No telemetry.
- Web Crypto only. Works in browsers and Node 20+.
- Canonical JSON matches the canonical Python reference at github.com/kya-standard/spec.
License
MIT
