Skip to main content
A private balance is stored in UTXOs (unspent transaction outputs). You can think of UTXOs as private SPL token accounts, with two core differences:
  1. A UTXO is not a Solana account, so it needs no rent-exemption.
  2. Its balance is encrypted onchain.
The UTXO data layout is similar to SPL token accounts:
  • Owner – Solana keypair, PDA, or P-256 key.
  • Asset – the mint (SOL, SPL or Token-2022).
  • Amount – the number of units of asset, in its smallest unit.
  • Data – a UTXO can store arbitrary data, for example the owner of escrowed tokens.
  • Program and policy data – optional configured Ring compliance.
A Private Solana Token Account. The Solana Privacy Program owns a Private Token Account, which expands into its UTXO fields: owner, asset, amount, data, policy data, and policy program id.
Solana token account.

Private Balance

The private balance is the sum of all UTXOs of one asset owned by a private wallet. The wallet displays one balance, regardless of whether a private balance consists of one, or multiple UTXOs. A private transfer can spend several UTXOs at once. A Private Wallet connected by dashed lines to several UTXOs, each holding one amount of one asset. The wallet balance is the sum of the UTXOs.

Private Transfer

Private transfers with UTXOs work differently from public transfers with SPL token accounts:
  • A transfer from an SPL token account updates the amount.
  • A private transfer with UTXOs does not update the amount of a UTXO. Instead, private transfers spend existing UTXOs and create new UTXOs for the recipient and for the sender’s remaining balance.
Still for the user, public transfer with Solana token accounts and private transfers with UTXOs feel similar. For example, Alice has 50 USDC and sends Bob 35 USDC.
  • With SPL token accounts, Alice’s amount decreases from 50 to 15, and Bob’s increases by 35.
  • With UTXOs, Alice holds one UTXO for 50 USDC. The transaction spends the existing UTXO and creates two new UTXOs: one with 35 USDC for Bob and one with 15 USDC for Alice.
Spend one UTXO

UTXO Selection

For private transfers, the SDK selects unspent UTXOs that cover the amount you want to transfer. The UTXO selection algorithm spends as few UTXOs as possible per transfer:
  1. The SDK filters your UTXOs by the asset being sent and sorts them by amount.
  2. The SDK selects as many UTXOs as necessary to cover the transfer amount. It selects the largest UTXOs first until the transfer amount is covered.
For example, Alice sends Bob 80 USDC. Her three largest UTXOs are enough to cover the transfer: Alice sends 80 USDC. Her UTXOs are sorted largest first: 40, 25, 20, 10, and 5 USDC. The SDK selects 40, 25, and 20 USDC, which cover 80 USDC, and leaves 10 and 5 USDC unselected. Fewer UTXOs keep the transaction small. Each spent UTXO adds 66 bytes for a nullifier account, which marks the UTXO as spent. The account prevents the UTXO . Example private transfers without additional data, or other instructions:

Transaction Variants

Every private transfer uses a transaction variant: a fixed number of slots for UTXOs to spend and new UTXOs to create. Variants range from 1 to 36 spent UTXOs, and each variant has its own ZK circuit. The circuit proves that the spent UTXOs are valid and that the new UTXOs hold the same total amount. If a transfer needs more than 36 UTXOs, merge them first. The SDK picks a variant that fits the transfer and fills unused slots with dummy UTXOs. Dummy UTXOs hold no value and look like real UTXOs onchain.
Alice sends Bob 30 USDC. Her largest UTXO covers the transfer.Alice's 40 USDC UTXO is spent, and her 25, 20, 10, and 5 USDC UTXOs stay unspent. The transaction creates 30 USDC for Bob and 10 USDC for Alice.
View source code: Spec · Supported variants

Merging UTXOs

Receiving many transfers without spending can fragment the private balance across many UTXOs. If a transfer needs more than 36 UTXOs, merge them first so the user can spend the entire balance in one transfer. Most users will rarely encounter a fragmented balance since one transfer can spend up to 36 UTXOs.
  • A merge combines UTXOs of the same owner and asset into one UTXO with the same total value.
  • A merge cannot spend funds or change the owner.
  • Merging can be done under the hood without impacting UX for end users.
A merge spends five of Alice's UTXOs of 1 USDC each and creates one new UTXO of 5 USDC for Alice. The number of merges needed to spend the whole balance in one transfer depends on how many UTXOs hold it: Each merge is one Solana transaction with a ZK proof and turns up to 36 UTXOs into one. Because the merge outcome is deterministic, the merge proofs and the transfer proof are generated in parallel.

Example Merge Instruction Usage

Your application can merge at two points:
  • When syncing the private balance: on wallet unlock, private wallet open, app resume, network reconnect, stream gap, or wallet restore.
  • Before a transfer: when the transfer needs more than 36 UTXOs.
Merges run without a user signature. Custom Rings set their own merge permissions. When using the embedded private wallet, merge is done for you under the hood.
For example, a private wallet holds 1,296 USDC in 1,296 UTXOs after receiving 1,296 private transfers of 1 USDC. A transfer spends at most 36 UTXOs, so the wallet spends the balance in two stages:
  1. 36 merge transactions run in parallel and create 36 UTXOs of 36 USDC each.
  2. One 36-input transfer spends the entire 1,296 USDC balance.

UTXO Concurrency

Users can spend private balances as soon as transactions are final. A private balance can be spent concurrently when it is split across several UTXOs. Each UTXO can be spent in a separate transaction at the same time. For example, a balance of three UTXOs of 100 USDC each can fund three transfers of up to 100 USDC at once. The wallet selects which UTXOs to spend. Alice's three UTXOs of 100 USDC each fund three transfers at the same time, one UTXO per transfer. A single UTXO can only be spent once. For the protocol’s throughput limits, see State Merkle Tree and Forester.

Learn More

Overview

Rings, privacy guarantees, and transaction flow.

Architecture

How wallets, RPC services, and Solana programs interact.

Encryption and Privacy Guarantees

How assets are encrypted and the role of the shielded keypair.

Custom Enterprise Rings

Learn how to configure a custom Ring.

Didn’t find what you were looking for?

Reach out! Telegram | E-Mail | Contact