import {
CLOAK_PROGRAM_ID,
DEVNET_MOCK_USDC_MINT,
transact,
createUtxo,
createZeroUtxo,
generateUtxoKeypair,
getNkFromUtxoPrivateKey,
} from "@cloak.dev/sdk-devnet";
import { Connection, Keypair } from "@solana/web3.js";
import { getAssociatedTokenAddress, getAccount } from "@solana/spl-token";
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
// Amounts in 6-decimal mock-USDC base units. 5_000_000 = 5 mock USDC.
const DEPOSIT_AMOUNT = 5_000_000n;
const TRANSFER_AMOUNT = 2_000_000n;
const sender = Keypair.generate(); // pre-fund with mock USDC + a little SOL for fees
const senderUtxo = await generateUtxoKeypair();
const recipientUtxo = await generateUtxoKeypair();
const senderNk = getNkFromUtxoPrivateKey(senderUtxo.privateKey);
// (Optional) verify ATA balance before depositing.
const senderAta = await getAssociatedTokenAddress(DEVNET_MOCK_USDC_MINT, sender.publicKey);
const ataBefore = await getAccount(connection, senderAta);
console.log("Sender mock-USDC ATA:", ataBefore.amount);
// 1. Deposit mock USDC into the shield pool. createZeroUtxo(MINT) — circuit
// requires the padding zero UTXO to match the output mint.
const depositOutput = await createUtxo(DEPOSIT_AMOUNT, senderUtxo, DEVNET_MOCK_USDC_MINT);
const deposit = await transact(
{
inputUtxos: [await createZeroUtxo(DEVNET_MOCK_USDC_MINT)],
outputUtxos: [depositOutput],
externalAmount: DEPOSIT_AMOUNT,
depositor: sender.publicKey,
},
{
connection,
programId: CLOAK_PROGRAM_ID,
depositorKeypair: sender,
walletPublicKey: sender.publicKey,
chainNoteViewingKeyNk: senderNk,
},
);
const shielded = deposit.outputUtxos[0];
await new Promise((r) => setTimeout(r, 20_000));
// 2. Transfer 2 mock USDC to the recipient UTXO, keep 3 as change.
const recipientOut = await createUtxo(TRANSFER_AMOUNT, recipientUtxo, DEVNET_MOCK_USDC_MINT);
const changeOut = await createUtxo(
DEPOSIT_AMOUNT - TRANSFER_AMOUNT,
senderUtxo,
DEVNET_MOCK_USDC_MINT,
);
const transfer = await transact(
{
inputUtxos: [shielded],
outputUtxos: [recipientOut, changeOut],
externalAmount: 0n,
},
{
connection,
programId: CLOAK_PROGRAM_ID,
depositorKeypair: sender,
walletPublicKey: sender.publicKey,
chainNoteViewingKeyNk: senderNk,
cachedMerkleTree: deposit.merkleTree,
useUniqueNullifiers: true,
},
);
console.log("USDC transfer landed:", transfer.signature);
console.log("Recipient amount:", transfer.outputUtxos[0].amount); // 2_000_000
console.log("Change amount: ", transfer.outputUtxos[1].amount); // 3_000_000