You write Solana programs every day. You know Anchor, you know SPL tokens, you know how to serialize account data into 10-kilobyte blobs and pray the rent math works out.
But every piece of state in your program is readable by anyone. Every balance, every order, every vote. The blockchain is a glass house.
The Aura SDK changes the default. This guide walks you through building your first application where program state is encrypted end-to-end, processed without decryption, and revealed only to the parties who should see it.
Prerequisites
Node.js 20+ or Bun 1.1+
Solana CLI tools installed
A Solana devnet wallet with some SOL (use
solana airdrop 2)Basic familiarity with TypeScript and Solana transactions
Step 1: Install the SDK
pnpm add @aura-fhe/sdk @solana/web3.jsOr if you prefer Rust:
cargo add aura-fhe-sdkThe TypeScript SDK wraps the core Rust FHE library via WASM, so encryption and decryption run client-side in the browser or Node.js. No plaintext ever leaves your machine.
Step 2: Initialize the Aura Client
import { AuraClient } from '@aura-fhe/sdk';
import { Connection, Keypair } from '@solana/web3.js';
const connection = new Connection('https://api.devnet.solana.com');
const wallet = Keypair.fromSecretKey(/* your devnet key */);
const aura = new AuraClient({
network: 'devnet',
connection,
wallet,
});
// Generate your FHE keypair (public key for encryption, secret key for decryption)
const fheKeys = await aura.generateKeys();
// Typical timing: < 100ms for key generationThe generateKeys() call creates a TFHE keypair locally. The public key is used to encrypt values that the Aura coprocessor can compute on. The secret key stays on your machine and is the only way to decrypt results.
Step 3: Encrypt a Value
// Encrypt a token amount
const encryptedAmount = await aura.encrypt(1000_000_000n, fheKeys.publicKey);
// encryptedAmount is a serialized FHE ciphertext (~4KB)
// You can also encrypt multiple values in a batch
const [encPrice, encQuantity] = await aura.encryptBatch(
[50_00n, 20n],
fheKeys.publicKey
);The encrypted value is a TFHE ciphertext. It looks like random bytes. The Aura coprocessor can perform addition, multiplication, and comparison on it — but cannot read the underlying number.
Step 4: Submit an Encrypted Transaction
// Build a private swap instruction
const swapIx = await aura.buildSwapInstruction({
inputMint: USDC_MINT,
outputMint: SOL_MINT,
encryptedAmount: encryptedAmount,
maxSlippageBps: 50,
fhePublicKey: fheKeys.publicKey,
});
// Sign and send — the transaction payload is encrypted
const signature = await aura.sendTransaction(swapIx);
// Wait for confirmation + threshold decryption of the result
const result = await aura.awaitResult(signature);Behind the scenes, the swap instruction is sent to the Aura coprocessor, which executes the AMM calculation homomorphically — on the encrypted input — and produces an encrypted output. The threshold decryption network (3-of-5 validators) then collaborates to produce a decryption share, which only your secret key can finalize.
Step 5: Decrypt the Result
// Only you can decrypt — requires your local FHE secret key
const outputAmount = await aura.decrypt(result.encryptedOutput, fheKeys.secretKey);
console.log(`Received: ${outputAmount} lamports of SOL`);Total wall-clock time from encryption to decrypted result: under 3 seconds on devnet.
What Just Happened
You encrypted a number locally. Nobody else can read it.
You submitted it to the Solana network as encrypted bytes.
The Aura coprocessor performed the swap calculation on the encrypted value — without decrypting it.
A threshold network of validators produced partial decryption shares.
Your local key combined those shares to reveal the output.
At no point did any validator, MEV bot, or RPC provider see your trade amount, price, or direction.
Beyond Swaps: Encrypted Program State
// Homomorphic operations on encrypted values
const encA = await aura.encrypt(100n, fheKeys.publicKey);
const encB = await aura.encrypt(200n, fheKeys.publicKey);
const encSum = await aura.add(encA, encB); // encrypted 300
const encProduct = await aura.multiply(encA, encB); // encrypted 20000
const encIsLess = await aura.lessThan(encA, encB); // encrypted boolean
const encMin = await aura.select(encIsLess, encA, encB); // encrypted minPerformance Benchmarks (Devnet, April 2026)
| Operation | Latency |
|---|---|
| FHE key generation | < 100ms |
| Encrypt (single uint64) | < 5ms |
| Homomorphic addition | < 1ms |
| Homomorphic multiplication | < 10ms |
| Encrypted comparison | < 5ms |
| Full encrypted swap (end-to-end) | < 3 seconds |
| Threshold decryption (3-of-5) | < 500ms |
Next Steps
Read the full API reference: docs.afhe.io/sdk
Clone the examples repo: github.com/aura-fhe/aura-examples
Join the Alpha (10 builder spots, April 24): Apply at afhe.io/builders
Ask questions in Discord: discord.gg/aurafhe — #builders-guild channel
April 7: SDK announcement + litepaper release
April 24: Alpha access for 10 selected builders
May 6-7: Public beta
