# E2 — Full recovery claim on Preview (funds recovered to a real wallet) A custody balance was locked at the full `RedemptionValidator`, a real client-side ZK proof of the 3,450,403-constraint Recovery circuit was generated, and the live Cardano Preview node ran the **entire** validator — proof verification + entitlement + destination + no-self-pay — and released exactly 5 tADA to a fresh real wallet. Date 2026-06-27. Network Preview (testnet-magic 2). Branch `feat/vending-machine`. ## Difference from E1 (verify-gate) E1 proved the node verifies the proof (a gate). E2 runs the **full RedemptionValidator**: it also reconstructs `pub` from authenticated context, re-encodes the paid Value to the 553-byte canonical entitlement and compares it to `cdEntitlement`, checks the payout goes to the bound destination `D`, and forbids self-pay — then releases the custody to a real wallet. ## Validator changes the full claim required - `groth16Verify` → **`groth16VerifyCommitted`** (the real proof carries the gnark BSB22 commitment). - `addrBytes = serialiseData(Address)` → **`encodeAddr`**: the raw canonical address bytes the circuit binds — testnet base keyhash/keyhash = `0x00 ‖ payment_keyhash(28) ‖ stake_keyhash(28)` (script `0x70`, enterprise keyhash `0x60`). - `soleNonChangePayout` → **`findPayout`**: locate the output whose `encodeAddr == crDestination`, allowing a fee-change output back to the claimant. ## Parameters | Item | Value | |------|-------| | Claimant credential `C` | `19e07fbcc7577359d6c51f1e49cf1b0bf4c943b48ba4e4905a8702e4` | | Entitlement | 5 tADA, ADA-only (`encodeEntitlement` = `404b4c00…` : 5,000,000 LE ‖ count 0 ‖ zeros) | | Snapshot root R | `4a87ca7f53f5467c06086021b956b1548916668c67da698e52e9b913eb98a0e5` | | Destination `D` (57 B) | `00483df46f0e8772d5ac6799f33f4f94685db069d93245644ea8aedbe587fd0b53ef4ecdfca456f16a542fe784010317e5fbdbec4f29671641` | | Destination address | `addr_test1qpyrmar0p6rh94dvv7vlx060j359mvrfmyey2ezw4zhdhev8l5948m6weh72g4h3df2zleuyqyp30e0mm0ky72t8zeqsm0yae5` | | Full validator | Plutus V3, 5960 bytes (inline), addr `addr_test1wq3xw4rlsavkfkrwmn5rgkds6uethg6q3naf65jefcp4d5qm46s4w` | | Funded wallet | `addr_test1vpw0dhd0k6rq0qrpeul0km0xtl5tguqk8f9q8v5p5rzghdq05nhzv` | ## Off-chain gate (CEK) before going live The full `compiledValidator` on a synthetic V3 ScriptContext with the real proof **ACCEPTs**; ExBudget **3,914,957,868 CPU / 2,826,629 mem** (fits 10e9 / 16.5e6). Negatives reject: tampered proof (`bls12_381_G1_uncompress` fails), wrong value (entitlement mismatch), wrong `D` (payout not found). `encodeAddr(destAddr)==D` and `encodeEntitlement(5 tADA)==cdEntitlement` both True. ## Transactions | # | Tx hash | Action | Fee | Confirmations | |---|---------|--------|-----|---------------| | 1 | `09664cd27de2d64f30db788ff9457b27b6ebd82dc9e7c4acb767a4c79ae9314e` | Lock 5 tADA in custody (inline `CustodyDatum(C, ent)`) | 1.0 tADA | confirmed | | 2 | `ababcda39b11f37ca490fa80a02a09b69225a2d7dfa2bd170f90c8cb34856d16` | Claim — full validator runs, 5 tADA recovered to `D` | 2.0 tADA | 2+ | (First claim attempt was rejected at phase-1 with `BabbageOutputTooSmallUTxO` — a too-small return-collateral output; fixed by using the large funded UTxO as collateral. Not a contract failure.) Explorer: - Lock: https://preview.cexplorer.io/tx/09664cd27de2d64f30db788ff9457b27b6ebd82dc9e7c4acb767a4c79ae9314e - Claim: https://preview.cexplorer.io/tx/ababcda39b11f37ca490fa80a02a09b69225a2d7dfa2bd170f90c8cb34856d16 ## Fund flow ``` funded wallet addr_test1vpw0dhd… │ 9,994 tADA in │== TX1 lock (fee 1.0 tADA) ===========================================+ │ ▼ │ RedemptionValidator addr_test1wq3xw4rl…qm46s4w │ custody UTxO: 5 tADA + CustodyDatum(C, ent) │ 9,976 change │ │ │ TX2 claim — redeemer = real 336-byte proof │ │ node runs FULL validator: │ │ groth16VerifyCommitted ✓ │ │ encodeEntitlement(payout)==cdEntitlement ✓ │ │ encodeAddr(payAddr)==D ✓ , no-self-pay ✓ │ +3.836 fee-input ▼ (fee 2.0 tADA) │ 5 tADA ──> destination addr_test1qpyrmar… (CONFIRMED balance 5 tADA) └───────────────── 1.836 change back to funded ``` ## Result The destination wallet `addr_test1qpyrmar…` holds **5,000,000 lovelace (5 tADA)** in a UTxO from the claim tx `ababcda3…` (confirmed). A real client ZK proof recovered the custody balance to a fresh wallet through the live node running the complete RedemptionValidator. Claim declared ex-units `(6,000,000,000, 4,000,000)`; the off-chain CEK measured `3,914,957,868 / 2,826,629` — both within the per-tx budget.