Build with PRAXIS
Resolve an identity. Verify it yourself.
The reference implementation is an operational TypeScript SDK with a lean, audited dependency surface. It resolves an Agentic Identity Document, recomputes every commitment from the bytes, verifies the real BLS signature, walks the version chain, and fails closed on any mismatch — from public artifacts alone, with no dependency on the issuer's cooperation.
@praxis/agent-id
2 audited deps · 0 vulns
68 tests
TypeScript
MIT
Quickstart
Install, resolve, verify.
Three moves from an empty project to a verified determination you can trust.
shell# 1 · add the package
npm install @praxis/agent-id
# 2 · clone and reproduce every figure from source
git clone https://github.com/quantum-field/praxis-agent-id
npm ci && npm run ci # typecheck · build · validate · test · drift gate
✓ 68 passing (25 aid + 22 crypto + 17 KG + 4 resolver e2e) · exit 0
The core call
One function resolves and proves.
Resolution is a mechanical pipeline: read the on-chain anchor, fetch the document, re-hash and bind, walk the chain, verify the signature, gate on policy. Any failed check stops it — the system fails closed.
typescriptimport { resolveAid, verifyChain, validateAid } from "@praxis/agent-id";
// resolve: fetch, re-hash against the on-chain commitment, walk to genesis
const result = await resolveAid("did:tz:mainnet:tz4…");
if (result.status === "trusted") {
console.log(result.aid.controller); // the accountable principal
console.log(result.aid.contentHash); // c2349d4a…e976b332
console.log(result.aid.genesisHash); // 1fe73207…ce70394f
}
// a tampered document hashes to a different value → rejected at the bind step
// resolveAid never trusts the gateway; it recomputes.
The binding rule
The token could point anywhere, so the resolver re-hashes the fetched document against the on-chain commitment. The document could claim any predecessor, so the chain is walked link by link back to a constant genesis. Verification never trusts an indexer — it recomputes.
The primitives
A small, sharp surface.
Every primitive is pure and deterministic — no hidden network calls behind a hash check, no ambient trust.
resolveAid(did)
The full pipeline: fetch, re-hash and bind against the anchor, walk the chain, verify, gate on policy. Returns a trusted determination or a fail-closed rejection.
validateAid(doc)
Structural + semantic validation, including the anti-"unaccountable void" rule: the delegation chain must terminate in a depth-0 accountable root, or it is rejected.
verifyChain(versions)
Walks each version to its predecessor by content hash back to a constant genesis, confirming an unbroken, append-only history.
canonicalize(doc)
The frozen encoding praxis-canonical-json/1 — recursive key sorting, no floats, fixed unicode — the precondition that makes two implementations agree byte-for-byte.
verifyProof(doc)
Real signature verification behind a CryptoProvider boundary — BLS12-381 tz4 min-sig, Ed25519, P-256, secp256k1. Proofs are content-bound; a v1 proof is rejected on v2.
AidResolver / service
The deployable resolver: chain → Arweave → re-hash → signature → status, returning an auditable proofChain. Holds no keys, cannot mutate state; ships with a Dockerfile.
Conformance
Prove a second implementation, in any language.
A published suite of golden byte-equality vectors fixes { input, canonical, sha256 } across the tricky cases, plus rejection vectors an encoder must refuse.
01
Load the vectors
Read fixtures/canonical-vectors.json — nine acceptance, three rejection.
02
Reproduce each
Canonicalize and hash every input; require byte-equality with the fixed output.
03
Refuse the rejections
Every rejection vector must fail your encoder — proving parity without reading the reference code.
Why this matters
A Python indexer or a Rust verifier reproduces every acceptance vector and rejects every rejection vector, proving byte-for-byte hash compatibility without reading a line of the reference TypeScript. Determinism becomes externally testable — the precondition for a real standard rather than a single-vendor format.
Honest boundaries
What's shipped, and what's behind a fail-closed seam.
The SDK, schemas, knowledge graph, golden vectors, CI substrate, real signature verification, the live Arweave client, and the deployable resolver are shipped and verified — each fails closed rather than returning a fake result. The one boundary still held closed is mainnet contract origination, gated on an external audit by policy, not capability. A mock is never presented as real.
statusSHIPPED SDK · schemas · canonicalizer · KG · golden vectors · CI drift gate
SHIPPED real signature verify (BLS12-381 + Ed25519/P-256/secp256k1) · content-bound
SHIPPED live Arweave client (multi-gateway, untrusted) · deployable resolver service
GATED mainnet contract origination — audit policy, not capability (Ghostnet after audit)
Read the source. Then verify it.