# Earn private yield with Zama

Hold and grow USDC without revealing balances or amounts on-chain. This recipe shields USDC into [Zama](https://zama.org)'s confidential token (**cUSDC**) and deposits it into the live **Steakhouse Confidential** Morpho vault, so your position earns ~4% yield while balances, deposits and yield stay **encrypted**. The wallet is an Openfort embedded **EOA** with **passkey** recovery, EIP-7702-delegated so an Openfort **paymaster** sponsors every transaction.

With Openfort and Zama together, your app can:

* Auto-create a self-custodial **EOA** wallet on login (passkey recovery — no seed phrase, no backend)
* **Shield / unshield**: wrap public USDC into encrypted cUSDC and back
* **Earn yield privately**: deposit cUSDC into a confidential vault and hold an encrypted, appreciating position
* **Decrypt-to-view**: reveal your own balances with a single cached EIP-712 permit, signed by the embedded wallet

:::note
Zama runs **client-side** — there is no Zama account or backend to stand up. The browser encrypts amounts and decrypts your own balances through Zama's public relayer; the Openfort embedded EOA is the single signer for both transactions and the decryption permit. The whole app is frontend-only.
:::

<HoverCardLink
  title="View Sample Code"
  subtitle="GitHub Repository"
  description="Complete source for the confidential-yield recipe: Openfort embedded EOA + passkey + paymaster, the @zama-fhe/sdk confidential flow, and an iPhone-style UI — on Ethereum Sepolia."
  href="https://github.com/openfort-xyz/recipes-hub/tree/main/zama-confidential-yield"
  img={{
  src: "/img/icons/github-icon.svg",
  alt: "GitHub Icon",
  className: "rounded-none",
}}
  color="#333"
  external
/>

## How it works

The embedded wallet is created as an **EOA** so its plain ECDSA key can sign Zama's user-decrypt permit (a smart-account signature is not accepted there). That same EOA is EIP-7702-**delegated** to a smart account, which lets an Openfort fee-sponsorship policy pay gas. Shielding wraps USDC into cUSDC (the entry amount is visible; everything after is private). Depositing is a **confidential transfer to a batcher** — the batcher aggregates deposits, and once a batch settles you `claim` confidential vault shares that appreciate as the vault earns.

```text
Openfort embedded EOA (passkey, EIP-7702 → paymaster-sponsored, Ethereum Sepolia)
        │  shield: wrap USDC → cUSDC          ← amount visible once; balances encrypted
        ▼
   cUSDC (confidential ERC-7984)
        │  deposit: confidentialTransferAndCall → deposit batcher
        ▼
   Deposit batcher ──(batch settles off-chain)──▶ claim → confidential vault shares
        │                                                    │  ~4% yield, encrypted
        ▼                                                    ▼
   Steakhouse Confidential vault (Morpho)        reveal: userDecrypt → value in cUSDC
```

| Step | What happens | Where |
| ------- | ----------------------------------------------------------- | ----------------------- |
| Sign in | Email OTP, then create a passkey EOA (7702-delegated for gasless) | `@openfort/react` |
| Get USDC | Mint test USDC (the Sepolia faucet token has a public `mint`) | `USDCMock.mint` |
| Shield | Wrap USDC → encrypted cUSDC | `cUSDC.wrap` |
| Earn | Deposit cUSDC into the batch, then `claim` once it settles | `confidentialTransferAndCall` → `claim` |
| Reveal | Decrypt your cUSDC + vault value, shown in cUSDC | `@zama-fhe/sdk` `decryptValues` |
| Unshield | Burn cUSDC, public-decrypt the amount, finalize → USDC | `unwrap` → `finalizeUnwrap` |

:::note
Deposits and redeems are **batched**: your encrypted amount joins the current batch, an operator settles it off-chain (`Open → Dispatched → Finalized`), then you `claim`. Vault shares only land in your wallet after the claim — the recipe surfaces each batch's status so you can claim when it's ready.
:::

## Getting started

:::note

* Node 22+ and `pnpm`
* An [Openfort account](https://dashboard.openfort.io) with **Ethereum Sepolia** enabled, the **Delegated (EIP-7702)** account type, and a **gas sponsorship policy** for Sepolia
* A Sepolia RPC URL (a dedicated Alchemy/Infura endpoint — the public relayer is flaky on shared RPCs)
* No Zama account is required — the confidential SDK uses Zama's public testnet relayer
  :::

::::steps

### Set up your project

Clone the recipe and install dependencies:

```bash
pnpx gitpick openfort-xyz/recipes-hub/tree/main/zama-confidential-yield openfort-zama-yield
cd openfort-zama-yield
pnpm install
```

The recipe is a single Vite + React app (no backend): the Openfort provider, the `@zama-fhe/sdk` confidential layer, and the UI.

### Configure your Openfort credentials

In the [Openfort Dashboard](https://dashboard.openfort.io):

1. Create an account or sign in
2. Get your **Publishable Key** (`pk_test_...`) from **Developers → API Keys** and your **Shield Publishable Key** from the **Shield** section
3. Enable **Ethereum Sepolia** and make sure the **Delegated** account type is available
4. Create a **gas sponsorship policy** for Sepolia and copy its id (`pol_...`) — this is what makes transactions gasless

### Configure your environment

Create `.env`:

```bash
VITE_NETWORK=sepolia
VITE_OPENFORT_PUBLISHABLE_KEY=pk_test_...
VITE_OPENFORT_SHIELD_KEY=...
VITE_OPENFORT_FEE_SPONSORSHIP_ID=pol_...   # Sepolia policy → sponsored (gasless) txs
VITE_RPC_URL=https://ethereum-sepolia-rpc.publicnode.com
```

### Run it

```bash
pnpm dev
```

Open [http://localhost:5182](http://localhost:5182). Sign in with email and create a passkey wallet, tap **Get test USDC** to mint, **Shield** it into cUSDC, then **Deposit** into the vault. Tap the pending batch to watch it settle and **claim** your shares, and hit **Reveal** to decrypt your balances — shown in cUSDC, growing with yield. **Unshield** converts cUSDC back to USDC.

::::
