Bind a policy
Each gate pins a policy id and the attributes it requires: KYC, committed sanctions and revocation roots, age, investor type, jurisdiction, and corridor limits.
two gates, one primitive
One circuit and one credential root drive every gate. A gate is just a policy plus an on-chain action — add a new one without re-issuing a single credential. Two are live on testnet today.
shared primitive
Both gates use the same circuit and credential root. Each action produces its own proof, nullifier and action binding.
Each gate pins a policy id and the attributes it requires: KYC, committed sanctions and revocation roots, age, investor type, jurisdiction, and corridor limits.
The gate calls the shared verifier with the proof and public signals; the contract checks the frozen VK metadata, the credential root, root bindings, and the nullifier.
Only on a valid, unused proof does the gate move value: a SAC transfer for payments, or a one-time action-bound SEP-57 mint authorization for assets.
gate 01
Enforces travel-rule eligibility before value moves over a Stellar SAC — the sender proves they pass policy without revealing who they are.
Mechanism:
prove in-browser →
gate_payment.verify_and_pay verifies
the Groth16 proof on-chain → the nullifier registry rejects replays →
a real SAC transfer of 250 settles and emits
PaymentApproved.
gate 02
Authorizes a regulated OpenZeppelin SEP-57 mint only after the holder proves an issuer-asserted accredited-investor tier and jurisdiction. The amount, recipient, token and terms hash are bound into the one-time mint authorization.
Mechanism:
prove in-browser →
identity_verifier.attest_for_mint
verifies the proof on-chain and records a one-time authorization → the
compliance adapter consumes it during the OpenZeppelin SEP-57
mint → 100 units mint and emit
indexed approval events.
prove it yourself
Run the in-browser prover and watch the same public signals settle on-chain.