Skip to content
ZKJEV

ZKJEV · Shielded pools on Robinhood Chain · decided by Jev

Shielded ZK swaps
decided by Jev

ZKJEV on Robinhood Chain: a shielded pool whose exit is a swap. Deposit a fixed note, prove it in your tab, leave as another token at an address that never touched your wallet. Every timing and routing call is made by Jev, a System One model that answers in probabilities, not prose.

$ZKJEVlaunching on pons · CA posted on X first
follow @zkjev for the launch ↗
jev · verdict · pool 0.1 ethreading…
withdraw_now · noul·
state: reading the pool…
crowd_risk·
wait·
venue → usdg·

Numbers, not prose. The state carries counts and ages, never an address or a note. Read the exact request in the Jev section below, or in the app before you withdraw.

ZKJEVreading the chain…
  • 3 fixed pools
  • ·poseidon tree · 20 levels
  • ·7 public signals
  • ·jev system one
  • ·relayed exits · v3 + v4

How it runs

One note, one proof, one transfer

A deposit puts a commitment in a Merkle tree. A withdrawal proves a note is in that tree and has not been spent, binds who receives what, and swaps on the way out. A relayer submits it and pays the gas, so the receiving address needs nothing and knows nothing.

zkjev · withdraw + swap
$ zkjev withdraw --note zkjev-eth-0.1-… --to USDG --recipient 0xfresh… jev withdraw_now noul 0.93 27 deposits · note 9 h · adequate crowd jev venue choice v3 (0.71) WETH/USDG 0.05 % · deepest of four tiers zk proof groth16 · 11,317 constraints · 2.8 s in this tab relay 0x744E51E225A7 → pool.withdraw(a, b, c, root, nullifierHash, recipient, relayer, fee, exit) chain settled · ≈ 410,000 gas with a swap · 265,000 as plain ETH out 246.12 USDG → 0xfresh… never funded by you, never funded by the relayer # the first cycle on chain, both hashes public deposit 0xeb47195a3c3dc7ffd6e7 block 60,299,118 · leaf 0 of the 0.01 pool withdraw 0x02d2ed6bc37ed6bc47d7 block 60,303,999 · as ETH to a fresh address

Pools

Three pools, read on every visit

Each row is a pool contract on Robinhood Chain holding one fixed denomination of ETH. Fixed sizes are what stop an amount from giving a swap away. Your browser reads the note count, the balance and the current root straight from the chain; this table has no database behind it.

PoolContractDepositsUnspentHeldRootJev · withdraw_now
0.01 ETH0xf8ade83edb7c···············
0.1 ETH0x23a7c84142c1···············
1 ETH0xb41c39262732···············

reading the chain…

A thin crowd is a thin disguise: with few deposits a withdrawal can be matched to one of few wallets. Jev scores that before you withdraw, and the MCP server refuses to send unless you force it.

Jev · System One

Ask Jev, get a verdict

Jev, from TypeSafe AI, does not generate text. You send it a state and typed questions; it returns one answer per question in about a hundred milliseconds: a probability, a pick from options you defined, or a place on a scale you defined. ZKJEV asks it whether a withdrawal should go now, through which venue, and how to spread a bundle.

POST /api/decide · request
{ "model": "jev-latest", "state": { "pool": { "denomination": "0.1", "deposits": 27, "unspent": 19 }, "note": { "ageHours": 9 }, "exit": { "token": "USDG", "venues": [{"id":"v3","liquidityUsd":412000,"fee":500}, {"id":"v4","liquidityUsd":118000,"fee":0,"hooked":true}] }, "relayer": { "enabled": true, "feeBps": 10 }, "bundle": null }, "questions": { "withdraw_now": { "type": "noul", "instructions": "A withdrawal sent right now would blend into the crowd…" }, "crowd_risk": { "type": "score", "criteria": ["negligible", "low", "moderate", "high"] }, "wait": { "type": "choice", "criteria": { "now": …, "one_hour": …, "six_hours": …, "a_day": … } }, "venue": { "type": "choice", "criteria": { "v4": …, "v3": …, "none": "deliver plain ETH" } } } } # no address, no note, no wallet: counts and ages only
response · 104 ms
{ "model": "jev-1.13.0", "answers": { "withdraw_now": { "type": "noul", "noul": 0.93 }, "crowd_risk": { "type": "score", "score": 1.1, "confidence": 0.88 }, "wait": { "type": "choice", "choice": "now", "probabilities": { "now": 0.81, … } }, "venue": { "type": "choice", "choice": "v3", "confidence": 0.71 } }, "usage": { "input_tokens": 210, "output_tokens": 0 } }
~100 msper call
$0.042per M input tokens
0 wordsanswers are numbers

Without a key this route answers the same questions locally, from the rules the app shipped with, and says source: "local". Nothing is labelled Jev that Jev did not answer. ZKJEV is a customer of TypeSafe’s API, not a partner, and nothing here is endorsed by TypeSafe AI.

The pool contract

A proof alone can’t pick the recipient

The seven public signals of the proof include the recipient, the relayer, the fee, the output token and the minimum out. Whoever relays it can submit it or drop it, but cannot change where the money goes or what it becomes. The contract checks, in order:

ZKJEVPOOL.WITHDRAW
  1. fee ≤ denominationelse FeeExceedsDenominationthe relayer cannot quote itself the whole note
  2. nullifier never seenelse AlreadySpentone note, one exit, forever
  3. root is one of the last 100else UnknownRootthe proof was made against a tree this pool had
  4. groth16 verifies on 7 public signalselse InvalidProofroot, nullifier, recipient, relayer, fee, tokenOut, minOut
  5. amountOut ≥ minOut after the swapelse TooLittleOuta sandwiched exit reverts instead of paying less
  6. venue is None, V4 or V3else BadVenuev4: unlock → swap → settle → take · v3: swap + guarded callback
  7. emits Withdrawal(recipient, nullifierHash, relayer, fee, tokenOut, amountOut)

The proof

One proof, then a withdrawal that links to nothing

A withdrawal carries a Groth16 proof made in your browser, against a 20-level Poseidon tree rebuilt from the chain. It shows a note exists and is unspent. It does not say which.

what the proof shows
  • a note is in this pool’s tree
  • its nullifier has not been used
  • recipient, relayer, fee, token and minimum out are the ones it was made for
what it hides
  • which deposit the note came from
  • who deposited it
  • the secret, and the nullifier’s preimage
  • which withdrawals belong together
≈ 3 sto make a proof in a browser tab
11,317constraints · 7 public signals
265kgas to check one on chain, 410k with a swap

The proving key comes from a public ceremony you can join from your browser; the circuit, the wasm and the verification key are published with their hashes in the docs. A forged proof would need the ceremony’s toxic waste from every contributor at once.

For agents · MCP

Let agents swap in private

ZKJEV is also an MCP server and a one-file skill. Seven tools over stdio: pools, quote, plan, decide, deposit, notes, withdraw. It runs on your machine, notes and proofs never leave it, and it asks Jev before it sends.

claude · mcp session
› agent calls tool tool withdraw({ note: "n_02", tokenOut: "USDG", recipient: "0xfresh…" }) jev withdraw_now 0.93 · crowd_risk low · venue v3 · wait now zk proving locally from ~/.zkjev · 2.8 s 200 relayed · tx 0x3a9f…c4d2 · 0 gas paid by you { hash: "0x3a9f…c4d2", out: "246.12 USDG", recipient: "0xfresh…", jev: { source: "jev", ms: 104 } } › with a thin crowd the tool stops: { warnings: ["only 3 deposits in this pool"], sent: false } · pass force: true to override

Live

Running on Robinhood Chain

What is on and what is not, read as you look at it. No status page can lie about a number it did not fetch.

deposits····relayer····decide····chainrobinhood chain 4663
ServiceWhat it doesWhereStatus
poolsThree fixed-denomination shielded pools, native ETH, v3 and v4 exitschain 4663live
proverGroth16 in the browser; wasm and zkey served from this originyour tablive
relayerSubmits withdrawals and pays gas; balance and fee floor on the stats page/api/relaysee stats
decideTyped questions to Jev; local answers until the key lands, and it says so/api/decidesee stats
ceremonyPublic contribution to the proving key, from the browser/ceremonyopen

Open a note on Robinhood Chain

Deposit a fixed note, let Jev call the moment and the venue, prove it in your tab, and leave as something else at an address that was never yours.