Skip to main content

Overview

Starkzap supports confidential (privacy-preserving) transfers through the Tongo protocol. Using the Tongo SDK, users can perform confidential transfers (amount is obfuscated) on Starknet. Tongo hides amounts. It keeps one encrypted balance per account, proves locally, and returns plain calls that you batch and send from your own account.
Tongo is one of two independent privacy protocols in Starkzap. It is not interchangeable with the STRK20 privacy pool — the two share no interface, so you pick one per integration. If you are still deciding, start with Choosing a privacy protocol.
What users can do with confidential:
  • 🔐 Transfer confidentially - Send to another confidential account by recipient public key; amounts are hidden on-chain
  • 📋 Compliance and auditing - Tongo provides flexible auditing mechanisms that enable compliance without sacrificing user privacy. Through viewing keys and ex-post proving, regulators can verify transaction details while preserving confidentiality for all other parties.
  • Ragequit — Exit full balance and rollover (activate pending balance)
The Tongo private key is separate from the Starknet wallet key. Your app must create and hold a TongoConfidential instance with the user’s Tongo key and the correct Tongo contract address for the chain.

Configuration

Create a TongoConfidential instance with the Tongo contract for your chain, the user’s Tongo private key, and an RPC provider (typically the wallet’s provider).
create is async because @fatsolutions/tongo-sdk is an optional peer dependency loaded on first use — if it is not installed, this rejects with an install hint instead of breaking the starkzap import. Use the Tongo protocol documentation or deployment list for the correct contractAddress per chain. There is no wallet-level “register confidential”; you pass the TongoConfidential into the tx builder methods.
Tongo and the STRK20 privacy pool are separate integrations with no shared interface. Tongo keeps an encrypted balance per account and proves locally; the pool spends notes and needs a remote prover whose output rides on the transaction rather than inside a call. Pick the one you are integrating — there is nothing to code against generically.

TongoConfidential: address and state

Tongo address (for display or sharing): The address is a single base58-encoded public key — the recommended value to share with others so they can send you confidential transfers:
Recipient identity (for receiving confidential transfers): recipientId is the same public key expressed as on-chain { x, y } coordinates. Pass it (or a decoded shared address, see below) as to in a confidential transfer:
Decode a shared address into a recipient: When a sender has someone’s shareable address (the single base58 public key), recipientFromAddress converts it into the { x, y } recipient expected by confidentialTransfer — so users can exchange one public key instead of raw coordinates:
Decrypted state (balance, pending, nonce):

ConfidentialState shape

Unit conversion (optional)

Convert between public ERC20 amounts and confidential (Tongo) units when you need to display or validate amounts:

Funding a confidential account

Convert public ERC20 into confidential balance. The tx builder calls the provider’s fund() method, which returns the approve call (if needed) and the fund call.
Optional: pay a fee to the sender (e.g. for relayed transactions):

Confidential transfer

Send from this confidential account to another confidential account. The recipient is identified by their public key — either their recipientId ({ x, y }) or a shared address decoded with recipientFromAddress.
The transfer generates ZK proofs locally and submits the call on-chain; amounts are not visible on the public ledger.

Withdrawing to a public address

Convert confidential balance back to ERC20 and send to a Starknet address.

Tongo-specific: ragequit and rollover

Ragequit — Exit the entire confidential balance to a public address in one call. Use when the user wants to close the confidential account or move everything on-chain.
Rollover — Move pending balance (from received confidential transfers) into the active balance so it can be spent.

Batching with the transaction builder

You can combine confidential operations with transfers, approvals, or other builder methods:
Use at most one confidential operation per transaction for a given account. Each one is proved against the balance and nonce read when it was built. Once the first applies, the second is stale, and the whole transaction reverts. One confidential operation plus ordinary calls, as above, is fine. Send two confidential operations one after another.
Builder methods for confidential: Ragequit and rollover are not on the builder; use confidential.ragequit(...) / confidential.rollover(...) and add the returned calls with .add(...calls).

Reaching the rest of the Tongo SDK

TongoConfidential wraps the operations that produce calls, plus balance reads and unit conversion. Tongo’s own Account does more than that: transaction history and per-event reads, audit and ex-post proofs, raw encrypted state, and manual decryption. For any of those, construct the SDK’s Account yourself with the same values you passed to create:
You already hold all three arguments, and the SDK is already installed. A second Account instance is safe. It holds no chain state and reads its nonce and balance fresh on every call, so it cannot disagree with the one inside TongoConfidential.

Best practices

  1. Keep the Tongo key separate from the Starknet wallet key; treat it as sensitive user data and protect it accordingly.
  2. Use the same Tongo contract address as the rest of your app (same chain) so all operations are consistent.
  3. Check state before withdraw — ensure state.balance (and pending if needed) is sufficient; use toPublicUnits / toConfidentialUnits if you need to show human-readable amounts.

Troubleshooting

Wrong contract or chain

Ensure contractAddress matches the Tongo deployment for the wallet’s chain. A mismatch can lead to failed transactions or wrong state.

Fund fails or “approve” errors

The provider includes the approve call in fund(); if the token or spender is non-standard, you may need to approve manually before calling the builder. Verify the token is the one supported by the Tongo contract.

Recipient format for confidential transfer

to must be a ConfidentialRecipient — the object { x, y }. Get it from the recipient’s confidential.recipientId, or decode their shared base58 Tongo address with confidential.recipientFromAddress(address). Do not pass a Starknet address; use the recipient’s Tongo public key.

Next steps