All examples use the current default program ID:Documentation Index
Fetch the complete documentation index at: https://docs.cloak.ag/llms.txt
Use this file to discover all available pages before exploring further.
zh1eLd6rSphLejbFfJEneUwzHRfMKxgzrgkfwA6qRkW
Shared setup
import {
CLOAK_PROGRAM_ID,
NATIVE_SOL_MINT,
createUtxo,
createZeroUtxo,
fullWithdraw,
generateUtxoKeypair,
getNkFromUtxoPrivateKey,
partialWithdraw,
swapWithChange,
transact,
scanTransactions,
toComplianceReport,
} from "@cloak.dev/sdk";
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
const USDC_MINT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const USDT_MINT = new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
const connection = new Connection(
"https://api.mainnet-beta.solana.com",
"confirmed",
);
const signer = Keypair.fromSecretKey(/* Uint8Array secret key */);
const scanKeypair = await generateUtxoKeypair();
const viewingKeyNk = getNkFromUtxoPrivateKey(scanKeypair.privateKey);
const baseOptions = {
connection,
programId: CLOAK_PROGRAM_ID,
depositorKeypair: signer,
walletPublicKey: signer.publicKey,
chainNoteViewingKeyNk: viewingKeyNk,
};
Send flow (SOL->SOL, USDC->USDC, USDT->USDT)
async function sendSameMint(args: {
mint: PublicKey;
amount: bigint;
recipientWallet: PublicKey;
partialWithdrawAmount?: bigint; // use for partial withdrawal example
}) {
const owner = await generateUtxoKeypair();
const output = await createUtxo(args.amount, owner, args.mint);
const deposited = await transact(
{
inputUtxos: [await createZeroUtxo(args.mint)],
outputUtxos: [output],
externalAmount: args.amount,
depositor: signer.publicKey,
},
baseOptions,
);
if (args.partialWithdrawAmount !== undefined) {
return partialWithdraw(
deposited.outputUtxos,
args.recipientWallet,
args.partialWithdrawAmount,
{
...baseOptions,
cachedMerkleTree: deposited.merkleTree,
},
);
}
return fullWithdraw(deposited.outputUtxos, args.recipientWallet, {
...baseOptions,
cachedMerkleTree: deposited.merkleTree,
});
}
// SOL -> SOL (full withdrawal send)
await sendSameMint({
mint: NATIVE_SOL_MINT,
amount: 1_000_000_000n,
recipientWallet: Keypair.generate().publicKey,
});
// USDC -> USDC (recipient wallet must have a USDC ATA)
await sendSameMint({
mint: USDC_MINT,
amount: 8_000_000n,
recipientWallet: Keypair.generate().publicKey,
});
// USDT -> USDT (recipient wallet must have a USDT ATA)
await sendSameMint({
mint: USDT_MINT,
amount: 8_000_000n,
recipientWallet: Keypair.generate().publicKey,
});
// Partial withdrawal example (withdraw part, keep private change)
await sendSameMint({
mint: NATIVE_SOL_MINT,
amount: 1_000_000_000n,
recipientWallet: Keypair.generate().publicKey,
partialWithdrawAmount: 250_000_000n,
});
SOL swap flow (SOL -> token)
const swapOwner = await generateUtxoKeypair();
const swapInput = await createUtxo(600_000_000n, swapOwner, NATIVE_SOL_MINT);
const swapDeposit = await transact(
{
inputUtxos: [await createZeroUtxo(NATIVE_SOL_MINT)],
outputUtxos: [swapInput],
externalAmount: 600_000_000n,
depositor: signer.publicKey,
},
baseOptions,
);
const recipientWallet = Keypair.generate().publicKey;
const recipientUsdcAta = getAssociatedTokenAddressSync(
USDC_MINT,
recipientWallet,
);
await swapWithChange(
[swapDeposit.outputUtxos[0]],
300_000_000n, // amount to swap
USDC_MINT,
recipientUsdcAta,
1n, // replace with quote-based min output
{
...baseOptions,
cachedMerkleTree: swapDeposit.merkleTree,
},
recipientWallet,
);
Payroll flow (multi-recipient private payouts)
const payroll = [
{ wallet: Keypair.generate().publicKey, amount: 250_000_000n },
{ wallet: Keypair.generate().publicKey, amount: 400_000_000n },
{ wallet: Keypair.generate().publicKey, amount: 350_000_000n },
];
for (const payment of payroll) {
await sendSameMint({
mint: NATIVE_SOL_MINT,
amount: payment.amount,
recipientWallet: payment.wallet,
});
}
History + compliance scan
// Reuse the same `viewingKeyNk` configured in your transaction options.
const scan = await scanTransactions({
connection,
programId: CLOAK_PROGRAM_ID,
viewingKeyNk,
limit: 250,
});
const report = toComplianceReport(scan);
console.log(report.summary);