ConfidentialTransferManager
Manage Token-2022 Confidential Transfers — privacy-preserving encrypted balances and transfers with auditor access
Overview
ConfidentialTransferManager wraps Token-2022's native Confidential Transfer extension. No custom on-chain program is needed — all operations use the standard Token-2022 program directly.
Balances are encrypted on-chain using ElGamal encryption. Only the account owner (and an optional auditor) can decrypt them. Transfers use zero-knowledge proofs to validate correctness without revealing amounts.
Import
Constructor
| Parameter | Type | Description |
|---|---|---|
connection | Connection | Solana RPC connection |
payer | Keypair | Fee payer for transactions |
mint | PublicKey | Token mint address |
Methods
initializeMintForConfidential(mintKeypair, decimals, authority?, auditorElGamalPubkey?)
Creates a new Token-2022 mint with the ConfidentialTransferMint extension enabled. Auto-approves new accounts by default.
| Parameter | Type | Description |
|---|---|---|
mintKeypair | Keypair | Keypair for the new mint account |
decimals | number | Token decimal places |
authority | PublicKey (optional) | Mint authority (defaults to payer) |
auditorElGamalPubkey | Uint8Array (optional) | Auditor's ElGamal public key for regulatory decryption |
configureAccount(owner, account, elGamalPubkey)
Enables confidential transfers on a token account by initializing the ConfidentialTransferAccount extension with the owner's ElGamal public key.
| Parameter | Type | Description |
|---|---|---|
owner | Keypair | Account owner |
account | PublicKey | Token account address |
elGamalPubkey | Uint8Array | Owner's ElGamal public key |
deposit(owner, account, amount, decimals)
Moves tokens from the public balance into the confidential (pending) balance. Call applyPendingBalance() afterward to make funds available for confidential transfers.
| Parameter | Type | Description |
|---|---|---|
owner | Keypair | Account owner |
account | PublicKey | Token account address |
amount | number | bigint | Amount to deposit |
decimals | number | Token decimal places |
withdraw(owner, account, amount, decimals, newDecryptableBalance?, proofInstructionOffset?)
Withdraws from the confidential balance back to the public balance. Requires a ZK range proof.
| Parameter | Type | Description |
|---|---|---|
owner | Keypair | Account owner |
account | PublicKey | Token account address |
amount | number | bigint | Amount to withdraw |
decimals | number | Token decimal places |
newDecryptableBalance | Uint8Array (optional) | Updated decryptable balance ciphertext |
proofInstructionOffset | number (optional) | Offset to ZK proof instruction |
confidentialTransfer(owner, sourceAccount, destAccount, amount, decimals, newSourceDecryptableBalance?, proofInstructionOffset?)
Performs an encrypted transfer between two confidential-enabled accounts. The transfer amount is hidden on-chain — only the sender, receiver, and auditor can see it.
| Parameter | Type | Description |
|---|---|---|
owner | Keypair | Source account owner |
sourceAccount | PublicKey | Source token account |
destAccount | PublicKey | Destination token account |
amount | number | bigint | Amount to transfer |
decimals | number | Token decimal places |
newSourceDecryptableBalance | Uint8Array (optional) | Updated source decryptable balance |
proofInstructionOffset | number (optional) | Offset to ZK proof instruction |
applyPendingBalance(owner, account, newDecryptableBalance?, expectedPendingCreditCounter?)
Applies pending incoming confidential balance to the available balance. Must be called after receiving a confidential transfer or deposit before funds can be used.
| Parameter | Type | Description |
|---|---|---|
owner | Keypair | Account owner |
account | PublicKey | Token account address |
newDecryptableBalance | Uint8Array (optional) | Updated decryptable balance |
expectedPendingCreditCounter | bigint (optional) | Expected pending credit counter |
getConfidentialBalance(account)
Reads the confidential balance state for a token account. Returns credit counters as balance activity indicators. Full decryption of encrypted balances requires the account owner's ElGamal secret key.
ElGamal Key Helpers
generateElGamalKeypair()
Generates an ElGamal keypair for use with confidential transfers. The 32-byte public key serves as the ElGamal public key for the Token-2022 extension.
createAuditorKeypair()
Creates an auditor ElGamal keypair. The auditor can decrypt all confidential transfers for compliance and regulatory purposes.
Balance Lifecycle
- Deposit — moves public tokens into pending confidential balance
- Apply — makes pending balance available for confidential transfers
- Transfer — sends encrypted amount to destination's pending balance
- Withdraw — moves confidential balance back to public balance