@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:
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, plusdeliverTo: 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. 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’sstate_too_freshhint. 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.
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.
{ 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.