All posts
2026-06-01

Sending USDC privately on Solana

A USDC transfer on Solana is just as public as a SOL transfer — the dollar amount, both addresses, and the timestamp are written to a ledger anyone can read forever. Stablecoins feel like cash, but on-chain they behave like a bank statement stapled to your name. If the wallet you pay from has ever touched an exchange, a payroll deposit, or a public donation address, the recipient can read your USDC balance and your entire payment history the moment they receive funds from you.

This is the practical guide to moving USDC so the receiving side carries no trail back to the wallet you started from. It's a how-to. If you want the reasoning behind why the chain is this exposed, /blog/what-the-blockchain-reveals-about-you covers it.

Why a direct USDC transfer can't be hidden

There's no private mode on a standard SPL-token transfer. The transaction itself is the link between sender and recipient — sending USDC through two or three intermediate wallets first doesn't help, because every hop is public and the chain of custody stays fully reconstructable. To actually break the link you need a step where your funds become indistinguishable from many other people's: a shielded pool. You deposit USDC behind a cryptographic commitment, then later withdraw using a zero-knowledge proof that says "I own one of the deposits in here" without revealing which one. /learn/what-is-a-shielded-pool is the plain-English version.

SolMask runs a dedicated USDC pool, so you deposit USDC and the recipient receives USDC — no swap, no asset change, same dollar amount minus the withdraw fee.

The flow, step by step

1. Deposit USDC from your main wallet. Open /swap, connect your wallet, choose USDC and an amount, and deposit. Depositing is free — the full balance enters the pool, and the fee is charged later on withdrawal (/blog/fee-model-explained). Your browser generates the note locally and writes only its commitment — a hash — on-chain. Nobody watching can tell how much you'll withdraw or where.

2. Set a privacy delay and let it breathe. At deposit you pick an unlock delay (10 minutes minimum, up to a week). The longer your USDC sits while other deposits flow in around it, the larger the crowd you blend into. Withdrawing the second it unlocks throws most of that away — see /blog/the-privacy-delay-explained.

3. Get a fresh recipient address. The destination should have zero prior history: never funded by your main wallet, never used to trade or claim. This is where most people leak — withdraw cleanly to an address that already received a transfer from you last month and you've reconnected both ends yourself. /learn/choosing-a-recipient-address is the highest-leverage step after the deposit.

4. Withdraw USDC to the fresh address. Generate the proof in your browser and submit it through the relayer. The relayer broadcasts the transaction and pays the SOL network fee, so the fresh wallet needs no SOL to receive the USDC — which matters, because topping it up from your main wallet for gas would re-link them. The relayer sees the proof but never learns which deposit is yours (/glossary/relayer).

On-chain the result is a USDC deposit from your main wallet and, minutes or days later, an unrelated USDC withdraw to a fresh address. No edge connects them.

The mistakes that undo all of it

  • Funding the fresh wallet from your main wallet. A fresh USDC wallet often has no SOL for rent or future fees — but a "gas top-up" from a linked wallet reconnects them. The relayer covers the withdraw gas; fund the wallet later from another unlinked source if needed.
  • Withdrawing instantly after depositing. A deposit and a same-size withdraw clustered in a few minutes is correlatable by timing alone. Decorrelate in time.
  • Reusing a "fresh" address. One address, one use. Any prior activity on it defeats the purpose.
  • Round numbers and off-chain tells. Withdrawing the exact unusual amount you deposited, or paying a fresh wallet and then using it for something tied to your identity, leaks through inference. /learn/what-solmask-cannot-protect-you-from is the honest list of what's still on you.

What if you hold SOL, not USDC?

You can deposit SOL and have the recipient receive USDC instead — the withdraw routes through a swap so the destination gets the stablecoin while the link stays broken. That's a separate walkthrough: /blog/swapping-sol-to-usdc-privately.

For the one-page version of every rule above, see /blog/solana-wallet-privacy-checklist.

FAQ

Q. Does the recipient get the exact USDC amount I deposit? A. Almost — they receive the deposited amount minus the withdraw fee (a small percentage in USDC plus a flat SOL component covered from the withdrawal). Depositing itself is free. See /docs/fees.

Q. Can I send USDC to someone who has no SOL at all? A. Yes. The relayer pays the network fee and broadcasts for you, so a brand-new wallet with zero SOL can still receive the USDC.

Q. Is sending USDC through several wallets first just as good? A. No. Every hop is public, so the full path stays traceable. Only a shielded pool makes your funds indistinguishable from everyone else's.

Q. Will my main wallet still show that I deposited USDC? A. Yes — your wallet publicly shows a deposit into the pool. What's hidden is the link to where the USDC came out. Anyone can see you used the pool; nobody can see which withdraw was yours.

Q. How long should I wait between deposit and withdraw? A. Longer than the minimum. Ten minutes is the floor; for anything you care about, let hours or days pass with other pool activity in between. The cost is calendar time, not effort.

Sending USDC privately on Solana · SolMask