SINAI STANDARD

Pattern: Confidential Transfers

Privacy-preserving compliant transfers with encrypted balances and auditor access

Overview

Confidential transfers encrypt token balances and transfer amounts on-chain using ElGamal encryption. Only the account owner and an optional auditor can decrypt the actual values. This enables privacy-preserving compliance — investors can transact without publicly exposing their holdings, while regulators retain audit access.

Uses Token-2022's native ConfidentialTransfer extension. No custom program deployment needed.

Use Cases

  • Privacy-preserving securities — hide investor positions from public view
  • Regulatory compliance — auditor key gives regulators full visibility
  • Institutional transfers — large block trades without front-running risk
  • Fund management — portfolio positions hidden from competitors

Implementation

1. Create Mint with Confidential Extension

import {
  ConfidentialTransferManager,
  generateElGamalKeypair,
  createAuditorKeypair,
} from "@sinai-standard/sdk";
import { Connection, Keypair } from "@solana/web3.js";
 
const connection = new Connection("https://api.devnet.solana.com");
const issuer = Keypair.generate();
const mintKeypair = Keypair.generate();
 
// Generate auditor keypair for regulatory compliance
const auditor = createAuditorKeypair();
// Store auditor.secretKey securely — it can decrypt ALL transfer amounts
 
const ctm = new ConfidentialTransferManager(
  connection,
  issuer,
  mintKeypair.publicKey
);
 
await ctm.initializeMintForConfidential(
  mintKeypair,
  6,                    // decimals
  issuer.publicKey,     // authority
  auditor.publicKey     // auditor can decrypt all transfers
);

2. Configure Accounts for Confidential Transfers

Each account that will participate in confidential transfers needs its own ElGamal keypair and must be configured with the extension.

// Generate ElGamal keys for each participant
const aliceKeys = generateElGamalKeypair();
const bobKeys = generateElGamalKeypair();
 
// Configure accounts
await ctm.configureAccount(alice, aliceTokenAccount, aliceKeys.publicKey);
await ctm.configureAccount(bob, bobTokenAccount, bobKeys.publicKey);

3. Deposit into Confidential Balance

Move tokens from the public balance into the encrypted confidential balance.

// Deposit 1M tokens into Alice's confidential balance
await ctm.deposit(alice, aliceTokenAccount, 1_000_000 * 10 ** 6, 6);
 
// Apply pending balance to make funds available
await ctm.applyPendingBalance(alice, aliceTokenAccount);

4. Confidential Transfer

Transfer encrypted amounts between accounts. The amount is hidden on-chain.

// Alice sends 100K tokens to Bob — amount is encrypted
await ctm.confidentialTransfer(
  alice,
  aliceTokenAccount,
  bobTokenAccount,
  100_000 * 10 ** 6,
  6
);
 
// Bob must apply pending balance before using received funds
await ctm.applyPendingBalance(bob, bobTokenAccount);

5. Withdraw to Public Balance

Move tokens back from confidential to public balance when needed.

// Bob withdraws 50K tokens back to public balance
await ctm.withdraw(bob, bobTokenAccount, 50_000 * 10 ** 6, 6);

Auditor Key Setup

The auditor ElGamal key is set at mint creation time. The entity holding the auditor secret key can decrypt all confidential transfer amounts for the mint.

const auditor = createAuditorKeypair();
 
// Set during mint initialization
await ctm.initializeMintForConfidential(
  mintKeypair,
  6,
  issuer.publicKey,
  auditor.publicKey  // All transfers are decryptable by auditor
);
 
// Store securely — this key provides full audit access
// auditor.secretKey → give to compliance team / regulator

Without an auditor key: balances are only visible to account owners. Set auditorElGamalPubkey to enable regulatory oversight.

Key Points

  • Balances are encrypted on-chain using ElGamal — only the owner (and auditor) can decrypt
  • Transfers use zero-knowledge proofs to validate correctness without revealing amounts
  • The public balance and confidential balance are separate — use deposit() and withdraw() to move between them
  • applyPendingBalance() must be called after receiving a deposit or transfer
  • No custom program needed — uses Token-2022's built-in ConfidentialTransfer extension
  • The auditor key is optional but recommended for regulatory compliance
  • Confidential transfers can be combined with other Sinai Standard hooks (allowlist, tax, hold period) via the Router Hook

On this page