Privacy

How Mixoor keeps your Solana wallet actions separate

Mixoor runs Poseidon hash commitments, Merkle trees, and strict nullifier checks on Solana to break wallet linkage and credibly block double-spends. Here’s how it actually works when you move coins.

By Jorge Rodriguez · 7 min read read · 2026-07-01T11:00:00-03:00

How commitments and nullifiers break on-chain wallet linkage

Solana’s fully public ledger means everyone sees every move. You spin up a fresh wallet and fund it? Game over. Source is obvious. Mixoor solves this: move SOL or USDC between wallets, no clean on-chain trail. The core tech? Commitments and nullifiers.

Let’s get into the weeds: Mixoor’s design uses Poseidon commitments and one-time nullifiers on top of a Merkle tree, all with Groth16 ZK proofs. Result? You get privacy and double-spend defense, no LARP, enforced entirely on Solana.

Why generic token transfers leak wallet relationships

You know the deal: Solana txs are fast and cheap, but it’s all see-through. Every transfer, every recipient, every asset is on display. Feet in wet concrete. On-chain explorers and wallet clustering tools can reconstruct it all in seconds.

TechniqueExposesCan be linked by...
Direct SOL/USDC transferSource wallet, recipient wallet, time, amountAnyone (Solana Explorer)
Obfuscation via multi-hop manual transferFunding patterns, relays, likely linkageAnalysts, bubble maps
Mixoor transferDeposit and withdrawal, but with no direct linkRequires attacking ZK proof or deanonymizing with external data

If you’re building or auditing, you need to get how Mixoor severs linkage. The whole thing hangs on trustless, on-chain cryptography, not magic, just solid math.

Commitments: How deposits become unlinked claims

User drops a deposit to Mixoor, client-side spins a secret note and hashes it up with deposit data via Poseidon. That hash? Commitment. Gets parked as a Merkle leaf, nothing about your wallet address goes in.

Deposit receipt is the note itself. Lose it, funds stuck forever. Dev view: these commitments are bare hashes (no wallet key), one-time and unlinkable without outside clues.

Nullifiers: Catching double-spends and rejecting duplicates

A commitment proves a deposit, but without guardrails, you could try to double-spend. Nullifier fixes this. It’s another hash from the note. For each spend, client generates a ZK proof and a new nullifierhash.

Mixoor smart contract checks if that nullifierhash is already on-chain. If yes, tx fails. Only one withdraw per note, regardless of which wallet tries.

Inside the Mixoor protocol: Walkthrough for devs

Here’s the system, start to finish: privacy checks, proof, and enforcement all native to Solana.

1
Deposit: Poseidon commitment

You (the user) spin a random note client-side. That and your deposit info get Poseidon-hashed, commitment goes onto the on-chain Merkle tree, then you fund the deposit.

2
Merkle path logged

Merkle root bumps with each new leaf. No addresses or transaction paths get logged in the tree.

3
Withdrawal: Zero-knowledge proof and nullifier

Withdrawal wallet shows a ZK proof that it knows a real commitment path to the root and tosses in a fresh nullifierhash.

4
On-chain checks

Smart contract checks the Groth16 proof, confirms the nullifierhash hasn't shown up before, and sends funds to the withdrawal wallet.

5
Double-spend rejected

Try to reuse a note (thus a nullifier)? Smart contract bricks the tx. Nullifiers only live once.

How commitments and nullifiers reduce wallet linkage (and what they can't do)

So, deposit wallet and withdrawal wallet don’t have to overlap. On-chain, there’s no binding between the two. Explorers see a deposit, then a withdrawal, but can’t match them up unless you screw up with side info.

But don’t kid yourself, nothing’s bulletproof. Timing, amounts, or sloppy wallet habits can leak connects. Mixoor just cranks up the difficulty for linkage. You still have to operate smart.

lockProof-enforced privacy

Groth16 proofs protect the link between deposit and withdrawal.

shieldNo address stored in pool

Only cryptographic commitments, never wallet addresses, are in the pool.

eyePrevents double-spends

Nullifierhash ensures one withdrawal per note, trustless and automatic.

wrenchDev-auditable logic

All checks are contract-enforced and source-verifiable on Solana.

Checklists for audits and integration

Auditing or integrating Mixoor? Here’s what actually matters under the hood.

What exactly is a commitment in Mixoor?

Commitment is a Poseidon hash of your note and deposit. Gets saved as a Merkle leaf. Nothing about your wallet, just the hash.

How does the nullifier prevent double-spending?

Each withdrawal burns a nullifierhash from your original note. Smart contract looks for duplicates. If found already, withdrawal fails.

Can someone trace my Mixoor deposit to my withdrawal?

No on-chain trail if you avoid wallet reuse and obvious patterns. Forensic matching is harder, not impossible.

What happens if I lose my note?

Note is your only claim to the coins. Lose it and funds are stuck, no recourse. Back these up or kiss it goodbye.

Ready to build with Mixoor’s privacy core?

Check out the live protocol and audit the contracts to see how commitments and nullifiers actually run.

Try Mixoor on Solana →