> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chipipay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Private Balances (shield / unshield)

> Add confidential balances to your app: users shield USDC into the STRK20 privacy pool so only they can see what they keep. Self-custodial, gasless for the end user.

Production-proven engine (Chipi's consumer wallet "Modo privado", mainnet). Mental
model for your users: **checking/savings** — visible money is for spending,
private money is what they keep, invisible to everyone but them.

## The five rules

1. **Key handling**: privacy keys derive client-side from the user's anchor
   (passkey encryptKey / PRF) and are never stored server-side. Cache the
   companion **address**, never the keys. Note the proving trust model below —
   it bounds what "private" may honestly mean in your copy.
2. **One passkey gesture per shield/unshield** — that IS the security model.
   Set the expectation: *"You confirm with your fingerprint or Face ID — the
   same as when you send money."*
3. **Browsers need a gateway proxy** (`gatewaySubmitUrl`): the Starknet
   sequencer gateway has no CORS. Install the `private-balance-card` registry
   item to get the proxy route, or copy it from the example.
4. **Capture the StarkWare pool ToS** at the user's first shield.
5. **Fees**: fixed 4 STRK per op, fronted by Chipi's gas tank (metered per API
   key) — your user never holds STRK. Show it in USD via `getShieldFee`.

## The trust model, honestly

Keys derive client-side and are never stored server-side — but STRK20's
**delegated proving requires the pool spending key inside each proof
request**, so Chipi's proving service (a private prover Chipi operates; the
same model as StarkWare's hosted prover) sees it per operation and must be
trusted not to retain or use it. Privacy holds against the **public** —
chain observers, other users — not against the proving operator. Do not
tell your users "nobody, including Chipi, can see your balance." Local
proving is the roadmap item that removes this trust.

## What is the "companion"?

Each user gets a lightweight standard account (the **companion**) as their
pool identity, derived deterministically from their anchor and deployed
automatically on first shield. You only supply a standard SNIP-6 account
class hash (`classHash`, e.g. OpenZeppelin `0x061dac03…`); everything else is
handled. Why a companion instead of changing the account class: see
[our design write-up on the Starknet forum](https://community.starknet.io/t/adding-confidential-payments-to-an-advanced-smart-account-two-ways-to-use-the-starkware-privacy-pool-and-why-we-picked-the-companion/),
and the [Core SDK privacy page](/sdk/core/privacy) for the architecture.

## Quickstart

```tsx theme={null}
import { useShield, usePrivateBalance, derivePrivacyAccount } from "@chipi-stack/nextjs";

const keys = await derivePrivacyAccount({
  anchorSecret,                  // 32 bytes from your passkey rail
  seedDomainTag: wallet.address, // per-wallet domain separation
  classHash: COMPANION_CLASS_HASH,
});

const { shieldAsync } = useShield();
await shieldAsync({
  config: {
    apiPublicKey: process.env.NEXT_PUBLIC_CHIPI_API_KEY!,
    getBearerToken: () => getToken(),          // a FUNCTION: tokens die mid-flow
    gatewaySubmitUrl: "/api/starknet-gateway", // your CORS proxy
  },
  keys,
  token: USDC_ADDRESS,
  amount: 1_000_000n, // base units
  fundDeposit: (companion, amount) => transferGasless(companion, amount),
  onStep: setPhase,   // prepare | fund | deposit | prove | finish — drive a REAL loader
});

const { byToken } = usePrivateBalance({ mode: "ledger", events: recordedEvents });
```

Record every settled op in your own store — your ledger is the display source
of truth (the chain won't cleanly surface confidential moves). Failures never
strand money: a failed shield parks funds in the companion and the next
attempt sweeps them in; say "your money is safe" in error copy.

Full headless example (also the release smoke): `examples/private-balance` in
the SDK repo. Agent skill: `chipi-private-balances`.
