Skip to main content
The platform is one capture-and-proof engine driven by data. Nothing about a bank, a gig platform or a payment lives in the engine.

Profile

A field is bound by its JSON "key":, so every key a policy reads must appear once in the reply. That is why a payment profile reads one transfer’s detail endpoint, never a list.

Policy

Values are typed: String, Integer, Decimal { units, scale }, Bool and Timestamp. Each has one canonical byte form, so a policy hashes the same way everywhere.

Context predicates

A payment proof must match one order, not a constant. Context predicates compare a field with a value from the session’s context instead of the policy:
  • Equals(field, ctx.key): the field equals a context value, such as the order’s exact amount.
  • HashEquals(field, ctx.key): SHA-256(canonical(field)) equals a context value. Used for payee and payer identities, so the identity never leaves the phone.
The verifier derives these public inputs from the context it was given by the relying party, never from the phone.

Bundles

Profiles and policies ship in a signed policy bundle. The SDK pins the bundle by digest and reads the login URL, cookie domains and request from it. A profile and policy pair compiles to one circuit ID, and the claim names the circuit ID and config hash it was proved under.

A second rail is a second pair of files

Adding a payment rail must not change the enclaves, the circuit compiler, the verifier, the SDK or any contract. If it would, the schema is wrong and the specification changes, not the core.