Skip to main content
  1. A deposit moves tokens from the user’s public Solana balance into their own or someone else’s private balance.
  2. Deposits are sent in a single Solana transaction to a Solana wallet address.

Deposit: What Is Private

The permissionless Ring is confidential with encrypted amount and asset. A custom Ring can be configured as confidential or anonymous (encrypted sender, recipient, asset, and amount).

How a Deposit Works

A deposit is a public Solana transfer with a resulting private balance.
  1. The user’s SOL or SPL balance is public onchain.
  2. The wallet sets amount and recipient, builds the deposit, and the owner signs. A deposit does not request a ZK proof.
  3. The Solana runtime verifies the signatures and invokes the Solana Privacy Program.
  4. The app tracks status via the Solana transaction hash.
  1. The user’s SOL or SPL balance is public onchain.
  2. The wallet reads public state, builds a transfer, and the owner signs.
  3. The Solana runtime verifies the signatures and invokes the System Program or Token Program, which updates the public balance.
  4. The app tracks status via the Solana transaction hash.
This is the high-level transaction flow for the permissionless confidential Ring. Compare to custom Rings in concepts.

Get Started

1

Prerequisites

The TypeScript examples require Node.js 24 or later, pnpm 11.18.0, and the Solana CLI.
Source: sdk-libs/ts
Add a Helius API key:
.env
The examples use the Solana CLI wallet as the payer by default. The payer must hold devnet SOL. See How to Get Devnet SOL.
2

Deposit to a Private Balance

  • The SDK returns instructions. The app signs and sends them.
  • sendAndConfirmFactory builds a Kit transaction, submits it, and returns the signature plus the landed slot.
  • senderAddress is the recipient’s . This example deposits to the sender. The recipient can be the sender or a third-party wallet.
  • senderViewTag is senderAddress.confidentialViewTag(), the sender’s Solana public key in confidential rings. The indexer uses it to return matching encrypted outputs.
  • client.tree is the state Merkle tree that receives the new output commitment.
  • depositor / senderSigner funds and signs the public-to-private deposit.
  • DepositAsset.sol() selects SOL. DepositAsset.spl takes the mint, source token account, and token program for SPL and Token 2022 assets.
  • recipientOwnerHash is senderAddress.ownerHash(). That hash of the recipient’s signing and nullifier public keys is the owner field committed in the new private token account.
  • randomBlinding() adds randomness to the private token account commitment.
  • DEPOSIT_AMOUNT uses lamports for SOL, or the token’s base units for SPL and Token 2022 assets.
  • sendAndConfirm signs and submits depositIx as a Solana transaction.
  • Confirmation yields the landed slot used to gate the indexer fetch.

Full Code Example

Clone and run the example:
The examples use a confidential Ring on local/devnet here.
deposit_transfer_withdraw.ts

Transfer

Withdraw

Read a Private Balance

Read Private History

Didn’t find what you were looking for?

Reach out! Telegram | E-Mail | Contact