
ShieldRamp
Trustless P2P crypto ↔ INR off-ramp world mini app for India using UPI + Pluto TEE Web Proofs.
Demo
About
# ShieldRamp **A P2P on/off-ramp for Indian users on WorldChain, powered by UPI + Pluto TEE-based Web Proofs.** ## Overview ShieldRamp enables verified humans on WorldChain to seamlessly off-ramp crypto into INR via UPI. The system leverages **World ID verification** to ensure one-human-one-account and **Pluto TEE-based Web Proofs** to securely prove off-chain UPI payments on-chain. ## Flow ### Sellers (INR Off-Ramp Providers) 1. Open the **ShieldRamp Mini App**. 2. Deposit **Worldcoin (WLD)** into the on-chain escrow contract. 3. Register their **UPI ID** (for receiving INR payments). 4. Earn yield from transaction fees (1.5–2%) + spread buffer (~0.5%) on each off-ramp. ### Users (Off-Ramp) 1. Must be a **verified human via World ID Orb**. 2. Signal intent to off-ramp (max **$500 equivalent per verified human**). 3. Matched with a Seller from the pool. 4. Send INR payment via **UPI → Seller’s UPI ID**. 5. Generate a **TEE-based Web Proof via Pluto** confirming the payment. 6. Submit proof to the escrow contract. 7. Escrow releases crypto funds from Seller → User. ## Key Features * ✅ **One-Human-One-Account**: Enforced via World ID. * ✅ **Trustless Settlement**: Users submit proof to escrow to unlock funds automatically. * ✅ **Privacy-Preserving Proofs**: Powered by Pluto’s TEE mode. * ✅ **Fair Limits**: Max $500 per user to reduce risk. ## Tech Stack * **WorldChain** for contracts. * **Pluto TEE-based Web Proofs** for off-chain → on-chain verification. * **UPI** for INR transfers. * **Mini App UI** (React/Next.js). ## Why ShieldRamp? * Solves the **India-specific on/off-ramp gap**. * Uses **verifiable payments** without needing custodians. * LPs earn yield while users get easy fiat exits.
How it's made
### Client (`client/`) - **Next.js 15 + React 19** Mini App using `@worldcoin/minikit-js` and `@worldcoin/minikit-react` to run inside World App. - On-device flows: - Wallet auth via SIWE: `GET /api/nonce` issues a cookie-stored nonce, `POST /api/complete-siwe` verifies with `verifySiweMessage`. - World ID verification via `MiniKit.commandsAsync.verify(...)` with Orb level, then used to call on-chain registrar. - Transactions sent via `MiniKit.commandsAsync.sendTransaction(...)` directly to WorldChain using ABIs from `client/utils/constants.js`. - Contract reads/writes done with `viem` against `worldchain` RPC; event history hydrated via `getLogs` and `parseAbiItem`. - Pluto TEE integration with `@plutoxyz/frame-js` embeds a TEE browser session that automates Amazon Pay history, extracts receipt fields, and produces a signed Web Proof. The proof JSON is fed to the contract through `claimFunds`. ### Smart Contracts (`contracts/`) - `escrowV1.sol` implements the core flow: - Sellers deposit WLD using **Permit2** (`ISignatureTransfer`) via `depositFunds(permit, details, sig)`; funds tracked per `depositId`. - Buyers `signalIntent(depositId, amount)` with 24h expiry and single active intent constraint. - `claimFunds(input, signature)` verifies Pluto attestation on-chain using `PlutoAttestationVerifier` and transfers WLD to buyer, marking the UPI tx as claimed to prevent replay. Emits rich events for UI history. - Sellers can `withdrawRemainingFunds` for unused liquidity. - `plutoVerifier.sol` contains: - `Verifier` which gates trusted notary addresses and verifies ECDSA signatures over a digest computed from session+script hashes; prevents duplicate proof reuse per-digest mapping. - `PlutoAttestationVerifier` that reconstructs `scriptHash`, `sessionHash`, and `digest`, checks signer, and returns boolean to `escrowV1`. - `L2RegistrarWIthWorld.sol` (demo): World ID proof gating for username-style registrations; shows how the same MiniKit World ID payload maps to on-chain `register(...)`. ### APIs (`client/app/api/`) - `nonce/route.js`: secure nonce cookie for SIWE. - `complete-siwe/route.js`: verifies SIWE with `@worldcoin/minikit-js`. - `verify/route.js`: optional server-side World ID cloud verification via `verifyCloudProof` for off-chain checks. ### Notable hacks and learnings - Used MiniKit’s built-in Permit2 support by passing `permit2: [...]` in the transaction call while still supplying a placeholder signature arg to match the escrow ABI, simplifying WLD approvals inside World App. - Robust World ID field extraction in the client tolerates multiple SDK payload shapes and hex-encoded proof packing to ensure compatibility across SDK versions. - Pluto automation script handles Amazon Pay 2FA via interactive prompts inside the TEE session, scrapes a JSON blob from a `data` attribute, and proves only the minimal fields required on-chain: `paymentStatusTitle`, `paymentTotalAmount`, `receiverUpiId`, `upi_transaction_id`. - Escrow enforces one-active-intent-per-buyer and 24h expiry to mitigate griefing; UPI transaction IDs are tracked on-chain to prevent double-claims. - Event-driven UI: the app incrementally reconstructs history with `viem.getLogs` across a moving block window to stay responsive inside a mobile mini app.