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.

Source on GitHub Run the live verifier Read the docs