Two apps, one engine
Remittance
examples/remittance/ — a corridor policy (e.g. NG → UK) with an amount cap. A user proves corridor eligibility privately; the contract executes the exact transfer, once.RWA access
examples/rwa-access/ — an access-grant policy for a tokenized real-world asset. A user proves they’re on the approved list; the contract grants access, once.
Same engine, different policies, different
app_domain — and therefore different, unlinkable nullifiers.
Walkthrough — the remittance app
1
The app publishes a policy
policy_hash and registered on-chain (PolicyPublished).2
A user builds a request + proof
The user holds a
credential_secret whose commitment is in the corridor’s approved root. buildRequest derives the canonical public inputs; Noir + Barretenberg generate the proof.3
verify_and_execute — one call
action_type: "access_grant" and a different approved root — proving membership in an asset’s allowlist instead of a corridor.
Run the unlinkability proof
The load-bearing example. One credential, two apps, two unlinkable nullifiers:artifacts/demo-results.json):
The same
credentialCommitment produces two different nullifiers. There is no shared value an observer could use to link the remittance user to the RWA-access user — at the proof/nullifier layer. See Unlinkability for the scope of that claim.The evidence artifacts
The repo carries a full, reproducible evidence package:See the live evidence
Every claim as a real testnet transaction.
The SDK
The one-line
verifyAndExecute these apps call.