Python SDK (embedded mode)
mintid-verifier-sdk: a frozen public surface, one decision entrypoint, five infrastructure ports — and a proof engine pinned inside the wheel.
The public surface
Package mintid-verifier-sdk, Python ≥ 3.12. The Rust proof engine ships compiled inside the wheel at a build-time pin — a supported installation cannot end up with a substituted or mismatched engine.
The public surface is small and frozen and test-enforced: a CI test imports exactly the published list and fails when it grows or drifts. Changes follow semver — surface or semantics change is a major version. The full import surface and reference documentation ship with the SDK; everything not on that list is internal and may change without notice.
The entrypoint
One function validates one presentation and returns one decision: accepted or rejected, with a machine-readable reason from the closed vocabulary, and — on acceptance — the verified predicate set. What you supply is infrastructure, never policy:
| You provide | Your freedom |
|---|---|
| proven chain reads | which nodes to read — never whether reads are proven |
| a durable nonce store | swap the bundled crash-durable backend if yours keeps atomic exactly-once consumption |
| the proof engine | none — the pinned engine rejects any proof not bound to the exact challenge |
| a decision sink | where decision records go — never what they contain |
| the clock | a skewed clock only makes you more rejecting |
There is no flag that skips a condition, no lite mode, and no parameter that widens the 10-second presentation lifetime — that number is a constant of the protocol, deliberately not a knob.
Issuing challenges
The SDK builds and shape-validates the signed challenge for you: a one-time nonce, your registered verifier identity and exact origin, the 10-second expiry, the finalized chain height, and your issuer and claim policy. The policy digest commits to the whole canonical body — tampering with any part of the challenge breaks the proof binding.
Chain access
The chain client splits trust into two ports on purpose:
- State queries — any RPC node, assumed malicious. Every answer carries a cryptographic proof and is verified before use.
- The trust anchor — an operator-designated node (your own node) that anchors what "proven" means. Backing this port with a full light client against untrusted peers is on the roadmap; never point the anchor at an arbitrary public RPC.
Absence is never trusted: if a node claims a record doesn't exist, the read fails closed and the decision reports unproven state.
Retention (what you keep, all of it)
Exactly one compact decision record per decision, accept or reject: a session identifier, the outcome, the reason code, a fixed-size digest of the bound context, and a timestamp. The record has fixed slots and serialization is test-enforced to emit exactly them — presentations, proof bytes and claim values structurally do not fit, and are never persisted. Treat any schema extension as a privacy review.