Money cannot reach a wallet that is not cleared
Settlement is gated on a Cleanverse Verified Identity read on chain, not on a flag the escrow could drop. This page reads cviStatus live on both Monad chains, draws the flow and shows the pass and the refuse as real transactions.
live CVI status, read on load
A server-side eth_call to each gate's cviStatus on every request. Nothing here is hardcoded, the page renders whatever the chain returns.
reproduce: curl -s https://kanmani.xyz/api/compliance/0xaA514cD6573f95DdD0df78ec1Fdcb8dA05E70936
check any wallet
The on-chain read for any address, on both chains. Pre-filled with the verified testnet worker so the happy path runs with one click.
cviStatus for 0xaA514cD6573f95DdD0df78ec1Fdcb8dA05E70936
how settlement is gated
Identity verification is structurally coupled to asset movement: the only payout path reads the CVI first, then the CVA re-checks it on its own transfer.
- 1buyer funds escrowopen()
open() escrows the hire through Aqueous with the gate as both buyer and agent, so only the gate can move the money.
- 2settle reads complianceVerify(gate, worker)cviStatus()
settle(), buyer only, reads cviStatus through the Compliance Validator before any money leaves escrow.
Verified: release and pay in the CVA
the escrow releases and the worker is paid in aUSDC, which re-checks the recipient CVI on its own transfer, so the payout is guarded twice.
Unverified: revert CviNotVerified
no money moves.
Unknown: revert CviUnknown
an unregistered pool or an unreadable validator fails closed, so money never moves on doubt.
the pass and the refuse, on chain
The end-to-end testnet run. A verified worker is paid, an unverified wallet is refused and no money moves. The escrowed asset is labelled on every row.
| step | asset | outcome | tx |
|---|---|---|---|
| register pool | tUSDC | is_register returns true | 0x1fde7e51…f2d64cce |
| set rule | tUSDC | any active CVI, tier 1 or higher | 0x87eb6dab…bdb333d9 |
| issue CVI | tUSDC | worker tier 20, status active | 0x6ae7f07b…48aef057 |
| verifiedpass: open | tUSDC | job opened for the verified worker | 0xb18196cb…e05047de |
| verifiedpass: settle | tUSDC | paid the worker 1,000,000 units | 0xea913ac3…6395174f |
| not clearedrefuse: open | tUSDC | job opened for a fresh wallet with no CVI | 0xbd1bd65f…2d585a35 |
| not clearedrefuse: settle | tUSDC | reverted, no money movedCviNotVerified() 0xbfeb29e5 | 0xd381c3e1…7a0539d0 |
The on-chain gate decides first, so a refusal reverts before any balance leaves escrow. The off-chain Verify-CVI API is documentation only here (it needs an api-id and an IP allowlist), and its code map is: 1 CVA not found (unknown), 2 user does not have a CVI (unverified), 3 CVI exists but cannot transfer (expired or frozen) (unverified), 4 success, valid CVI and transfer allowed (verified).
the use case: verified settlement
The bounty asks for identity structurally coupled to asset movement, not an optional layer.
An autonomous agent cannot be paid for work until its wallet carries a verified identity. A buyer hiring an agent has the same know-your-counterparty duty a bank has. The agent's wallet is the counterparty. Gating the payout on a CVI, inside a CVA, is that duty enforced by the settlement rail rather than by a policy document. Because the payout asset re-checks compliance at the source, a Travel Rule report can be pulled for the settlement itself.
Travel Rule export, built from the pass settle
originator (buyer) 0xDB6c6340342e71A63cD11Ebac2185204b7777777 beneficiary (worker) 0xaA514cD6573f95DdD0df78ec1Fdcb8dA05E70936 asset tUSDC on Monad testnet (chain 10143) amount 1,000,000 units settlement tx 0xea913ac399f270daec96bd6e1b374263a50803d84a4606a509dbc7176395174f identity gate CVI tier 20, issued 0x6ae7f07b…f148aef057
The on-chain leg is what this report is built from. The identity data stays with Cleanverse under the CVI, so Kanmani holds no PII. When plan 6.3 reruns the settle in aUSDC, the asset line reads aUSDC and the rest is unchanged.
mainnet status, stated plainly
No mock, no implied-live. What runs today and what waits on Cleanverse.
The mainnet gate is deployed at 0x4a21a5d8e24E683801ECC4CF19f178d7185e544A but it is not yet registered as a compliance pool, so the mainnet validator reverts PoolNotRegistered for it. Every mainnet cviStatus reads unknown and every settle fails closed by design, which is why the deployer row above shows unknown on mainnet and not cleared on testnet.
The live end-to-end flow runs on Monad testnet with a CVA today. Registration is an off-chain step that needs Cleanverse production credentials. When they land, the mainnet column turns real with no page change, because the page reads the chain live rather than a stored answer.