Skip to main content
Nullis ships two example apps that share a single contract and a single circuit. They aren’t toys glued on top — they’re the proof of the hardest claim in the system: the same credential authorizes actions in both apps, yet is unlinkable between them.

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

Hashed to 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

The RWA access app is the same shape with 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:
Sample output (captured in 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.