Deposit Tokens

How to deposit tokens to confidential pending balance

Before tokens can be transferred confidentially, the public token balance must be converted to a confidential balance. This conversion happens in two stages:

  1. Confidential Pending Balance: Initially, tokens are "deposited" from public balance to a "pending" confidential balance.
  2. Confidential Available Balance: The pending balance is then "applied" to the available balance, making the tokens available for confidential transfers.

This section explains the first stage: depositing public token balance to the confidential pending balance.

The following diagram shows the steps involved in depositing tokens from the public balance to the confidential pending balance:

Deposit Tokens

Required Instruction

To convert a public balance to a confidential pending balance, invoke the ConfidentialTransferInstruction::Deposit instruction. The maximum amount per deposit instruction is limited to 2^48.

The spl_token_client crate provides a confidential_transfer_deposit method that builds and sends a transaction with the Deposit instruction, as demonstrated in the example below.

Example Code

The following example demonstrates how to deposit public token balance to confidential pending balance.

Confidential transfers depend on the ZK ElGamal Proof program, which is enabled on mainnet and devnet. A stock solana-test-validator does not enable it, but a mainnet-forking local validator such as Surfpool does. Run the example against one of those (the code uses devnet) with a funded payer, and replace the placeholder mint and account addresses with your own.

Rust

const ZK_PROOF_PROGRAM_ID: Pubkey =
solana_pubkey::pubkey!("ZkE1Gama1Proof11111111111111111111111111111");
fn main() -> Result<()> {
let rpc_client = RpcClient::new_with_commitment(
String::from("https://api.devnet.solana.com"),
CommitmentConfig::confirmed(),
);
// Owner = fee payer = token account owner. The setup below configures the
// account for confidential transfers (see "Create a Token Account").
let owner = load_keypair()?;
let amount: u64 = 100;
let decimals: u8 = 2;
// Setup: create a confidential token account with public tokens.
let (mint, token_account) = setup_deposit_account(&rpc_client, &owner, amount, decimals)?;
// Deposit moves tokens from the public balance into the pending confidential
// balance. No proof is required. The tokens land in the pending balance and
// must be applied (see "Apply Pending Balance") before they can be spent.
let deposit_ix = deposit(
&spl_token_2022::id(),
&token_account,
&mint,
amount,
decimals,
&owner.pubkey(),
&[&owner.pubkey()],
)?;
let blockhash = rpc_client.get_latest_blockhash()?;
let transaction =
Transaction::new_signed_with_payer(&[deposit_ix], Some(&owner.pubkey()), &[&owner], blockhash);
let signature = rpc_client.send_and_confirm_transaction(&transaction)?;
println!("Deposited {amount} tokens to the pending confidential balance: {signature}");
Ok(())
}

Typescript

const client = await createClient()
.use(signerFromFile(join(homedir(), ".config/solana/id.json")))
.use(
solanaRpc({
rpcUrl: "https://api.devnet.solana.com"
})
);
// The Solana CLI default keypair, used as fee payer, mint authority, and
// token account owner.
const owner = client.payer;
const amount = 100n;
const decimals = 2;
// Setup: create a confidential mint and token account with public tokens.
const mint = await createConfidentialMint(client, owner, decimals);
const token = await createConfidentialTokenAccount(client, owner, mint);
await mintPublicTokens(client, owner, mint, token, amount);
// Deposit moves public tokens into the pending confidential balance. No proof
// is required; the tokens must then be applied before they can be spent.
const depositInstruction = getConfidentialDepositInstruction({
token,
mint,
authority: owner,
amount,
decimals
});
const result = await client.sendTransaction([depositInstruction]);
console.log(
`Deposited ${amount} tokens to the pending confidential balance: ${result.context.signature}`
);

Is this page helpful?

Table of Contents

Edit Page
© 2026 Solana Foundation. All rights reserved.