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.
Install
npm install @cloak.dev/sdk @solana/web3.js @solana/wallet-adapter-react
If your app standardizes on @solana/kit, add it as well and use the bridge pattern in Solana Kit Integration.
Add wallet UI packages as needed:
npm install @solana/wallet-adapter-react-ui @solana/wallet-adapter-wallets
Note-based integration (CloakSDK)
import { useMemo } from "react";
import { CloakSDK } from "@cloak.dev/sdk";
import { useWallet } from "@solana/wallet-adapter-react";
import { PublicKey } from "@solana/web3.js";
export function useCloak() {
const { publicKey, signTransaction, sendTransaction } = useWallet();
return useMemo(() => {
if (!publicKey || !sendTransaction) return null;
return new CloakSDK({
wallet: { publicKey, signTransaction, sendTransaction },
network: "mainnet",
programId: new PublicKey("zh1eLd6rSphLejbFfJEneUwzHRfMKxgzrgkfwA6qRkW"),
});
}, [publicKey, signTransaction, sendTransaction]);
}
UTXO integration with wallet signing
For UTXO transact deposits in browser apps, pass wallet signing fields in TransactOptions:
const result = await transact(params, {
connection,
programId,
relayUrl,
signTransaction, // wallet adapter signer
depositorPublicKey, // wallet public key
riskOracleQueue, // if required by deployment
riskQuoteUrl, // risk quote backend (if needed)
addressLookupTableAccounts,
});
Make sure your wallet supports signMessage so viewing-key registration can complete before transactions.
Full wallet-adapter SOL send flow (transact -> fullWithdraw)
import {
CLOAK_PROGRAM_ID,
NATIVE_SOL_MINT,
createUtxo,
createZeroUtxo,
fullWithdraw,
generateUtxoKeypair,
isRootNotFoundError,
transact,
} from "@cloak.dev/sdk";
import { Connection, PublicKey } from "@solana/web3.js";
const connection = new Connection(process.env.SOLANA_RPC_URL!, "confirmed");
const programId = CLOAK_PROGRAM_ID;
async function sendWithWalletAdapter({
walletPublicKey,
signTransaction,
signMessage,
recipientAddress,
amountLamports,
}: {
walletPublicKey: PublicKey;
signTransaction: (tx: any) => Promise<any>;
signMessage: (msg: Uint8Array) => Promise<Uint8Array>;
recipientAddress: string;
amountLamports: bigint;
}) {
const owner = await generateUtxoKeypair();
const output = await createUtxo(amountLamports, owner, NATIVE_SOL_MINT);
const deposited = await transact(
{
inputUtxos: [await createZeroUtxo(NATIVE_SOL_MINT)],
outputUtxos: [output],
externalAmount: amountLamports,
depositor: walletPublicKey,
},
{
connection,
programId,
signTransaction,
depositorPublicKey: walletPublicKey,
walletPublicKey,
onProgress: (status) => console.log("deposit", status),
onProofProgress: (percent) => console.log("deposit proof", percent),
},
);
const recipient = new PublicKey(recipientAddress);
let withdrawResult: Awaited<ReturnType<typeof fullWithdraw>> | undefined;
for (let attempt = 1; attempt <= 3; attempt += 1) {
try {
withdrawResult = await fullWithdraw(deposited.outputUtxos, recipient, {
connection,
programId,
walletPublicKey,
signMessage,
cachedMerkleTree: deposited.merkleTree,
onProgress: (status) => console.log("withdraw", status),
onProofProgress: (percent) => console.log("withdraw proof", percent),
});
break;
} catch (error) {
if (!isRootNotFoundError(error) || attempt === 3) throw error;
await new Promise((resolve) => setTimeout(resolve, 1_500));
}
}
if (!withdrawResult) throw new Error("withdraw did not produce a result");
return {
depositSignature: deposited.signature,
withdrawSignature: withdrawResult.signature,
};
}
Notes:
- Keep amount values as
bigint end-to-end.
- Use
cachedMerkleTree from deposit for the immediate withdraw call.
- Treat
isRootNotFoundError as retryable with bounded backoff.
UX requirements
- Show progress during proof generation (
onProgress, onProofProgress).
- Handle stale-root retries gracefully (
isRootNotFoundError).
- Keep circuit files accessible in browser deployments.
- Ensure viewing-key registration succeeds before transact/swap actions.
- For privacy history pages, expose explicit cache clear + rescan controls after swaps or failed scans.
Related pages