---
title: Confidential Transfer
description:
  Learn about the Confidential Transfer extension and how to use it to add
  optional features to token mints and accounts.
---

## What are Confidential Transfers?

<Embed url="https://youtu.be/Bqs95tFcRIU" />

Confidential transfers enable you to transfer tokens between token accounts
without revealing the transfer amount. This is useful for privacy-preserving
transactions. Only the transfer amounts and token balances are private. The
token account addresses remain public.

- [Protocol Overview](https://www.solana-program.com/docs/confidential-balances/overview) -
  Details on the underlying cryptographic protocol
- [Quick Start Guide](https://www.solana-program.com/docs/confidential-balances#setup) -
  Setup and basic CLI commands
- [Confidential Balances Cookbook](https://github.com/solana-developers/Confidential-Balances-Sample) -
  Code snippets on how to use the Confidential Transfer extension

### How does it work?

The Confidential Transfer extension adds
[instructions](https://github.com/solana-program/token-2022/blob/efd0c957fefbd79882d77df5fb2dac88c001249c/program/src/extension/confidential_transfer/instruction.rs#L29)
to the Token Extension program that allows you to transfer tokens between
accounts without revealing the transfer amount.

```mermaid title="Confidential Transfer Basic Overview"
    sequenceDiagram

    participant A as Sender Wallet
    participant AA as Sender Token Account
    participant BB as Recipient Token Account
    participant B as Recipient Wallet

    A->>AA: Deposit
    A->>AA: Apply

    AA->>BB: Transfer
    B->>BB: Apply

    B->>BB: Withdraw

```

The basic flow of confidential token transfers is as follows:

1. Create a mint account with the confidential transfer extension.
2. Create token accounts with confidential transfer extension for the sender and
   recipient.
3. Mint tokens to the sender account.
4. **Deposit** sender's public balance to **confidential pending balance**.
5. **Apply** sender's pending balance to **confidential available balance**.
6. Confidentially **transfer** tokens from sender token account to recipient
   token account.
7. **Apply** recipient's pending balance to **confidential available balance**.
8. **Withdraw** recipient's confidential available balance to **public
   balance**.

For more details on the steps in the confidential transfer flow, see the
corresponding pages:

<Cards>
  <Card
    title="Create Mint Account"
    href="/docs/tokens/extensions/confidential-transfer/create-mint"
  >
    How to create a mint account with the Confidential Transfer extension
  </Card>
  <Card
    title="Create Token Account"
    href="/docs/tokens/extensions/confidential-transfer/create-token-account"
  >
    How to configure a token account with the Confidential Transfer extension
  </Card>
  <Card
    title="Deposit Tokens"
    href="/docs/tokens/extensions/confidential-transfer/deposit-tokens"
  >
    How to deposit tokens to confidential pending balance
  </Card>
  <Card
    title="Apply Pending Balance"
    href="/docs/tokens/extensions/confidential-transfer/apply-pending-balance"
  >
    How to apply pending balance to available confidential balance
  </Card>
  <Card
    title="Withdraw Tokens"
    href="/docs/tokens/extensions/confidential-transfer/withdraw-tokens"
  >
    How to withdraw tokens from confidential available balance
  </Card>
  <Card
    title="Transfer Tokens"
    href="/docs/tokens/extensions/confidential-transfer/transfer-tokens"
  >
    How to confidentially transfer tokens between token accounts
  </Card>
  <Card
    title="Integration Guide"
    href="/docs/tokens/extensions/confidential-transfer/integration-guide"
  >
    How wallets, explorers, and exchanges can support confidential transfer
    tokens
  </Card>
  <Card
    title="Issuer Guide"
    href="/docs/tokens/extensions/confidential-transfer/issuer-guide"
  >
    How to issue and operate a confidential transfer token (approve policy,
    auditors, fees, mint and burn)
  </Card>
</Cards>

The diagram below shows a detailed sequence of the basic flow for confidential
token transfers:

```mermaid title="Confidential Transfer Detailed Overview"
sequenceDiagram
    participant Sender as Sender Wallet
    participant SenderAccount as Sender Token Account
    participant Mint as Token Mint
    participant Token22 as Token Extensions Program
    participant ATAProgram as Associated Token Program
    participant ElGamal as ZK ElGamal Proof Program
    participant RecipientAccount as Recipient Token Account
    participant Recipient as Recipient Wallet

    rect rgba(120, 160, 235, 0.3)
    Note over Sender,Mint: 1. Initialize Mint

    activate Sender
    Sender->>Token22: create_mint (with Confidential Transfer Extension)
    activate Token22
    Token22-->>Mint: Initialize mint
    deactivate Token22
    deactivate Sender
    end

    rect rgba(130, 210, 170, 0.3)
    Note over Sender,SenderAccount: 2. Set Up Sender Account

    activate Sender
    Note right of Sender: Generate encryption keys
    Sender->>Sender: Generate ElGamal keypair
    Sender->>Sender: Generate AES key

    Sender->>ATAProgram: create_associated_token_account
    activate ATAProgram
    ATAProgram->>Token22: Create token account at deterministic address
    activate Token22
    Token22-->>SenderAccount: Initialize account
    deactivate Token22
    deactivate ATAProgram

    Sender->>Token22: reallocate & configure_account
    activate Token22
    Token22-->>SenderAccount: Configure for confidential transfers
    deactivate Token22
    deactivate Sender
    end

    rect rgba(130, 210, 170, 0.3)
    Note over Recipient,RecipientAccount: 3. Set Up Recipient Account

    activate Recipient
    Note right of Recipient: Generate encryption keys
    Recipient->>Recipient: Generate ElGamal keypair
    Recipient->>Recipient: Generate AES key

    Recipient->>ATAProgram: create_associated_token_account
    activate ATAProgram
    ATAProgram->>Token22: Create token account at deterministic address
    activate Token22
    Token22-->>RecipientAccount: Initialize account
    deactivate Token22
    deactivate ATAProgram

    Recipient->>Token22: reallocate & configure_account
    activate Token22
    Token22-->>RecipientAccount: Configure for confidential transfers
    deactivate Token22
    deactivate Recipient
    end

    rect rgba(235, 160, 80, 0.3)
    Note over Sender,SenderAccount: 4. Mint & Convert to Confidential Balance

    activate Sender
    Sender->>Token22: mint_tokens
    activate Token22
    Token22-->>SenderAccount: Increase token account public balance
    deactivate Token22

    Sender->>Token22: deposit_tokens
    activate Token22
    Token22-->>SenderAccount: Convert to confidential pending balance
    deactivate Token22

    Sender->>Sender: Use ElGamal keypair & AES key to decrypt
    Sender->>Token22: apply_pending_balance
    activate Token22
    Token22-->>SenderAccount: Convert pending balance to available balance
    deactivate Token22
    deactivate Sender
    end

    rect rgba(235, 120, 120, 0.3)
    Note over Sender,RecipientAccount: 5. Confidential Transfer

    activate Sender
    Note right of Sender: Create proofs
    Sender->>Sender: Generate proof data for transfer

    Sender->>ElGamal: Create equality proof context account
    activate ElGamal
    Sender->>ElGamal: Create ciphertext validity proof context account
    Sender->>ElGamal: Create range proof context account
    ElGamal-->>ElGamal: Verify proofs

    Sender->>Token22: transfer_tokens, providing proof context accounts
    activate Token22
    Token22-->>SenderAccount: Decrease encrypted available balance
    Token22-->>RecipientAccount: Increase encrypted pending balance
    deactivate Token22

    Sender->>ElGamal: Close proof context accounts
    deactivate ElGamal
    deactivate Sender
    end

    rect rgba(180, 150, 235, 0.3)
    Note over Recipient,RecipientAccount: 6. Apply & Withdraw

    activate Recipient
    Recipient->>Recipient: Use ElGamal keypair & AES key to decrypt
    Recipient->>Token22: apply_pending_balance
    activate Token22
    Token22-->>RecipientAccount: Convert pending balance to available balance
    deactivate Token22

    Note right of Recipient: Optional withdrawal
    Recipient->>Recipient: Generate proof data for withdraw

    Recipient->>ElGamal: Create equality proof context account
    activate ElGamal
    Recipient->>ElGamal: Create range proof context account
    ElGamal-->>ElGamal: Verify proofs

    Recipient->>Token22: withdraw_tokens, providing proof context accounts
    activate Token22
    Token22-->>RecipientAccount: Convert from available confidential balance to public balance
    deactivate Token22

    Recipient->>ElGamal: Close proof context accounts
    deactivate ElGamal
    deactivate Recipient
    end
```

## Confidential Transfer Instructions

The full list of Confidential Transfer extension
[instructions](https://github.com/solana-program/token-2022/blob/efd0c957fefbd79882d77df5fb2dac88c001249c/program/src/extension/confidential_transfer/instruction.rs#L29)
are as follows:

| Instruction                         | Description                                                                                                                                                       |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| _rs`InitializeMint`_                | Sets up mint account for confidential transfers. This instruction must be included in the same transaction as _rs`TokenInstruction::InitializeMint`_ instruction. |
| _rs`UpdateMint`_                    | Updates confidential transfer settings for a mint.                                                                                                                |
| _rs`ConfigureAccount`_              | Sets up a token account for confidential transfers.                                                                                                               |
| _rs`ApproveAccount`_                | Approves a token account for confidential transfers if the mint requires approval for new token accounts.                                                         |
| _rs`EmptyAccount`_                  | Empties the pending and available confidential balances to allow closing a token account.                                                                         |
| _rs`Deposit`_                       | Converts public token balance into pending confidential balance.                                                                                                  |
| _rs`Withdraw`_                      | Converts available confidential balance back to public balance.                                                                                                   |
| _rs`Transfer`_                      | Transfers tokens between token accounts confidentially.                                                                                                           |
| _rs`ApplyPendingBalance`_           | Converts pending balance into available balance after deposits or transfers.                                                                                      |
| _rs`EnableConfidentialCredits`_     | Allows a token account to receive confidential token transfers.                                                                                                   |
| _rs`DisableConfidentialCredits`_    | Blocks incoming confidential transfers while still allowing public transfers.                                                                                     |
| _rs`EnableNonConfidentialCredits`_  | Allows a token account to receive public token transfers.                                                                                                         |
| _rs`DisableNonConfidentialCredits`_ | Blocks regular transfers to make account receive only confidential transfers.                                                                                     |
| _rs`TransferWithFee`_               | Transfers tokens between token accounts confidentially with a fee.                                                                                                |
| _rs`ConfigureAccountWithRegistry`_  | Alternative way to configure token accounts for confidential transfers using an _rs`ElGamalRegistry`_ account instead of _rs`VerifyPubkeyValidity`_ proof.        |
