Umbra Privacy SDK — Integration Test

Isolated test page for ETA shield/unshield flow before trading dashboard integration.

1. Wallet

Not connected

Setup Progress

Connect wallet
Initialize Umbra client
Check / register on-chain identity
Ready to shield USDC

2. SDK Initialization

Status: idle
Registration: unknown

3. Balances

Public USDC

Visible on-chain

Shielded USDC (ETA)

Encrypted on Arcium MPC

4a. Shield USDC

Move USDC from your public wallet into the encrypted ETA

4b. Unshield USDC

Withdraw USDC from your ETA back to your public wallet

5. Mixer — Full Anonymity (Phase 2)

Requires anonymous registration

Breaks the on-chain link between sender and recipient. The recipient wallet must be different from the sender wallet. Registration with anonymous: true is required for both wallets before using the mixer.

Step 0 (sender + recipient wallets): Enable mixer on your Umbra account

5a. Send (Sender Wallet)

Deposits USDC into the Umbra Merkle tree as a receiver-claimable UTXO. Funds leave your public wallet now. The recipient claims later from their wallet — no link between the two.

5b. Claim (Recipient Wallet)

Connect the recipient wallet, initialize the client, then scan and claim. The ZK proof proves knowledge of the UTXO secret without revealing which leaf it corresponds to.

Event Log

No events yet…

Test Checklist

  1. Connect your Solana wallet
  2. Click Initialize Umbra Client — wallet will sign once to derive master seed
  3. If not registered: click Register with Umbra (one-time setup)
  4. Click Refresh on Balances to confirm both public and shielded balances load
  5. Enter a small USDC amount and click Shield USDC — approve the transaction
  6. After Arcium MPC processes (up to a few minutes), click Refresh to see shielded balance increase
  7. Test Unshield USDC to verify the return flow works
  8. Check Event Log for any errors — all steps should show green on success

What is Umbra used for?

Every transaction on Solana is permanently public. Anyone with your wallet address can see your full balance history, which exchanges you use, how much you profited from a trade, and when you move funds. Umbra solves this for token balances.

Post-trade privacy

After closing a leveraged position on Orderly, your USDC payout lands in your public wallet and is immediately visible on-chain. Shielding it moves those funds into an Encrypted Token Account (ETA) where the balance is cryptographically hidden — no explorer, no third party, can read the amount.

Counterparty intelligence prevention

Market makers and sophisticated traders watch on-chain flows. If your wallet is known, large deposits or withdrawals telegraph your position-sizing intent before you even trade. Shielding between sessions breaks that signal.

Withdrawal destination privacy (Phase 2 — Mixer)

The full mixer flow (coming in Phase 2) goes further: USDC is deposited into a shared Merkle tree and claimed from a completely different wallet using a zero-knowledge proof. There is no on-chain link between the depositing wallet and the claiming wallet — even the amount is hidden.

Selective disclosure

Umbra supports viewing keys. You can share a read-only key with an auditor, accountant, or compliance officer so they can verify balances without giving them the ability to move funds. Privacy and auditability are not mutually exclusive.

How the technology works

Arcium Multi-Party Computation (MPC)

Your USDC balance is encrypted using Arcium's MPC network — a set of independent nodes that each hold a fragment of the decryption key. No single node can decrypt your balance. A withdrawal requires a quorum of nodes to jointly authorize the computation without any of them ever seeing the plaintext amount. This is the same category of cryptography used by institutional custody providers, applied to on-chain token accounts.

Encrypted Token Accounts (ETAs) — Shared mode

When you register with confidential: true, your ETA is created in Shared mode. The balance is encrypted under both Arcium's key and your own X25519 keypair (derived deterministically from your wallet). This means you can read your own shielded balance locally in the browser — no network round-trip to Arcium required. The Arcium key is still needed to authorize withdrawals, maintaining the security guarantee.

The dual-transaction pattern (handler + callback)

Every shielded operation splits across two on-chain transactions. TX 1 (the handler) is signed by your wallet — it validates inputs, deducts the tokens from your public ATA, and queues the computation with Arcium. TX 2 (the callback) is submitted automatically by the Arcium network after the off-chain MPC round completes — it posts the encrypted result on-chain and finalizes your ETA balance. You never sign TX 2; Arcium handles it. This is why there is a latency window between shielding and seeing your balance update.

Master seed derivation (one-time wallet signature)

When you initialize the Umbra client for the first time, your wallet signs a fixed message. The resulting Ed25519 signature is hashed with Keccak-512 to produce a 64-byte master seed. All Umbra cryptographic keys (your X25519 viewing keypair, Poseidon private keys, nullifiers) are deterministically derived from this seed. The seed is never stored — it is re-derived on demand from the same wallet signature. This means your keys are recoverable from any device just by connecting the same wallet.

Mixer / UTXO model and zero-knowledge proofs (Phase 2)

The mixer extends privacy further. When you deposit into the mixer, the SDK computes a Poseidon hash commitment of (amount, recipient X25519 key, random secret) and inserts it as a leaf in an on-chain indexed Merkle tree. The commitment reveals nothing about its contents. To claim, the recipient's wallet generates a Groth16 zero-knowledge proof that demonstrates knowledge of the secret behind a leaf — without revealing which leaf it is. The nullifier (a deterministic hash of the secret) is recorded on-chain to prevent double-claiming. Anonymity strength scales with tree occupancy: the more leaves, the harder it is to correlate any specific deposit with a claim.

Security best practices

Never reuse the same wallet for shielding and claiming

The entire point of the mixer is to break the link between sender and receiver. If you shield from wallet A and claim to wallet A, no privacy is gained. Always claim to a fresh wallet that has no prior on-chain history linked to wallet A.

Wait for anonymity set growth before claiming

If you are the only depositor in a Merkle tree when you claim, the claim is trivially linkable to your deposit. Wait until the tree has significant occupancy (many other deposits) before claiming. The UI will show the current tree leaf count.

Your master seed is as sensitive as your private key

The wallet signature used to derive the master seed controls all your Umbra keys. Never sign the Umbra initialization message in an untrusted environment. The SDK derives the seed deterministically — there is no backup phrase to protect, but losing access to your wallet means losing access to your shielded funds.

Do not deposit and withdraw the same round amount

On-chain observers use amount correlation to link deposits to withdrawals even without a direct address link. Use amounts that are common denominations (e.g. 100 USDC) rather than precise round-trip amounts that fingerprint the transaction.

Add time delay between shield and unshield

Timing correlation is a real attack vector. A deposit at 14:03 and a withdrawal at 14:07 narrows the suspect set significantly. Introducing hours or days between the two operations substantially increases privacy.

This feature is opt-in — never auto-route

Privacy features should never activate silently. Users must explicitly choose to shield funds. Auto-routing without consent creates compliance and UX risks. All integration points (trading dashboard) will surface this as an explicit user choice.