> ## 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.

# useShield / useUnshield / usePrivateBalance

> Privacy hooks over the mainnet-proven STRK20 engine in @chipi-stack/core.

<Warning>
  **`useShield` (deposits) is temporarily paused.** After StarkWare's July 2026
  STRK20 pool **v2.0** upgrade, shielding into the shared privacy pool requires
  a screener attestation issued by StarkWare's hosted proving service — Chipi is
  finalizing that access. **`useUnshield` and `usePrivateBalance` work today;
  shields will revert until access lands.** Don't ship a shield flow to
  production yet — we'll announce on X ([@hichipipay](https://x.com/hichipipay))
  when shielding is back on.
</Warning>

Signatures below are stated from the package types (`@chipi-stack/chipi-react`)
— if a snippet here doesn't compile against the installed package, that's a
docs bug; report it.

## 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.

## useShield()

Moves money INTO the private balance. Returns `{ shield, shieldAsync, data,
isLoading, isError, error, isSuccess, reset }`.

`shieldAsync(input: ShieldHookInput)` where:

```ts theme={null}
interface ShieldHookInput {
  config: PrivacyConfig;
  keys: PrivacyKeys;          // from derivePrivacyAccount — client-side only
  token: string;              // token contract address
  amount: bigint;             // base units
  fundDeposit?: (companionAddress: string, amount: bigint) => Promise<void>;
  onStep?: (step: PrivacyStep) => void; // "prepare"|"fund"|"deposit"|"prove"|"finish"
}
```

Orchestration (all retried/hardened): gas-tank funding → your `fundDeposit`
transfer → funding-arrival wait → companion deploy + approvals → prove →
gateway submit → **receipt + pool-event assertion** (no phantom successes) →
background STRK sweep. Resolves with `{ transactionHash, via, receipt, feeStrk }`.

## useUnshield()

Same spine, plus **`deliverTo: string`** (required): withdrawals land in the
companion and are delivered onward to the user's wallet (awaited).

## Multiple tokens

Both hooks are **per-token by design** (`token: string, amount: bigint`).

* **Batch shield** (N tokens, one proof, one 4-STRK fee) lives in the core
  engine: [`execShieldMany`](/sdk/core/privacy#multi-token-operations). Call
  it directly for multi-token shields; a single-item batch is exactly the
  hook's path.
* **Sequential unshields** need spacing: proving runs against `head − 12`,
  so a second withdrawal within \~13 blocks (\~5–6 min) of the first fails
  with the prover's `state_too_fresh` hint. Catch it, tell the user what
  already came back, and retry the rest a few minutes later — the full
  pattern is on the [Core SDK privacy page](/sdk/core/privacy#unshielding-several-tokens).

## usePrivateBalance(input)

Read-only — the difference from the actions: no gesture after setup, no gas,
no writes.

* `{ mode: "ledger", events: PrivacyLedgerEvent[] }` — instant netting of
  your recorded events, clamped at zero. Use for passive display.
* `{ mode: "onchain", config, keys, tokens? }` — authoritative pool note scan
  with the viewing key. Use for an explicit "verify on-chain" action.

Returns `{ byToken: Record<string, bigint>, isLoading, isError, error, refetch }`.

## derivePrivacyAccount(p)

`{ anchorSecret: Uint8Array; seedDomainTag: string; classHash: string } →
Promise<PrivacyKeys>` — deterministic, client-side. Cache the address, never
the keys.
