/// Privacy enforced by a hook · built on Socket · Solana

A market where
every swap is private.
Enforced by the hook.

DARKHOOK — the programmable privacy hook layer for onchain markets. Put money in your private account, swap from it, take it out anywhere. The pool's hook refuses any swap that does not come from — and go back into — the private account.

Launch a market. Hook in privacy. Let it evolve privately.
/// What the hook controls

Privacy is not a wrapper.
It is a hook with rules.

DARKHOOK plugs into Socket, the hook-based AMM on Solana. Socket calls the hook before every swap on a DARKHOOK pool, and the hook decides who may trade: only the private account. The hook is open — anyone can plug it into a new pool.

01 / HIDDEN

What stays hidden

Who swaps. Every swap is made by a one-time wallet paid from the private account, with a zero-knowledge proof that never says which deposit it came from. Your balance inside the account is hidden too.

?
02 / REVEALED

What gets revealed

Only what you choose: putting money in, and taking it out to a wallet of your choice. Swap sizes on the pool are public — but not whose. Everything in between stays inside the private account.

◑
03 / EXECUTION

How markets execute

The hook reads the whole transaction and refuses any swap that is not funded from the private account and settled back into it. The rule is fixed when the pool is created — no website, admin or router can switch it off.

⌘
/// The lifecycle

Launch a market. Hook in privacy.
Let it evolve privately.

Five steps, one hook, zero changes to the AMM underneath.

Deposit

Your wallet puts SOL or USDC into the private account. You get a secret note.

PUBLIC · AMOUNT IN

Prove

Your browser proves you own a note — not which one — for the amount you want to swap.

Gate

At before swap the hook checks: paid from the private account, settled back into it. Otherwise: refused.

HOOK ENFORCED

Swap

A one-time wallet swaps on the Socket pool; a relayer pays the fees. Your wallet never signs.

Settle

The whole output goes back in as a new note. Withdraw any part, to any wallet, whenever you want.

YOUR CHOICE
/// Build on it

Two programs.
One SDK.

A small Rust hook guards every swap, a zero-knowledge private account holds the funds, and a TypeScript SDK builds deposits, proofs and private swaps for wallets, bots and apps.

// programs/gate-hook — the rule Socket runs before every swap
pub fn check_private(ixs: &[Ix], current: usize, pool: &Pubkey, shield: &Pubkey) -> Result<(), GateError> {
    let swap = &ixs[current];                      // must be a direct Socket swap on this pool
    if swap.program_id != SOCKET_PROGRAM_ID || &swap.accounts[1] != pool {
        return Err(NotADirectSwap);
    }
    let swapper = swap.accounts[0];

    // 1. the money comes out of the private account, earlier in this transaction
    let funded = ixs[..current].iter().any(|ix| ix.program_id == *shield
        && ix.tag == Some(WITHDRAW) && is_swapper_or_its_token_account(&ix.accounts[3]));
    if !funded { return Err(NotFundedFromVault); }

    // 2. everything the swap returns goes back in, later in this transaction
    let settled = ixs[current + 1..].iter().any(|ix| ix.program_id == *shield
        && ix.tag == Some(DEPOSIT_ALL) && ix.accounts[0] == swapper);
    if !settled { return Err(NotSettledToVault); }
    Ok(())
}
// sdk — swap a private note into the other asset, without your wallet
import {
  buildSpendWitness, formatProof, buildPrivateSwapMessage,
  privateSwapPayout, newNoteSecrets, noteInner,
} from "@darkhook/sdk";

const temp   = Keypair.generate();            // one-time wallet, holds funds only inside the tx
const payout = privateSwapPayout({ from: "SOL", temp: temp.publicKey, relayer, usdcMint });

// 1 — prove: one of the notes is mine; pay 1 SOL to the swap, keep the rest as change
const w = buildSpendWitness({ note, leaves, amount: 1_000_000_000n, fee, ...payout });
const { proof } = await snarkjs.groth16.fullProve(w.input, "/zk/spend.wasm", "/zk/spend.zkey");

// 2 — one transaction: withdraw → swap on the gated pool → deposit-all back
const out = newNoteSecrets();                 // the output note's secrets
const msg = buildPrivateSwapMessage({
  socketPool, usdcMint, relayer, temp: temp.publicKey, from: "SOL",
  proof: formatProof(proof), root: w.root, nullifierHash: w.nullifierHash,
  changeLeaf: w.changeLeaf, amount: 1_000_000_000n, fee,
  outputInner: noteInner(out), minOut,
}, blockhash, lookupTable);

// 3 — the one-time wallet signs, the relayer co-signs and pays: your wallet never appears
/// Use it

Three steps to a
private trade.

The DARKHOOK app talks straight to Solana mainnet: no account, no backend holding your keys. Connect Phantom only to put money in — the rest needs no signature.

01 / DEPOSIT

Into your private account

Any amount of SOL or USDC from your wallet. Your browser keeps a secret note for it — download a backup: the note is the key to the funds.

02 / SWAP PRIVATELY

Nothing to sign

Pick an amount and swap SOL ⇄ USDC. The app proves your note in the browser, a one-time wallet trades on the DARKHOOK pool and the whole result goes back into your account as a new note. Your wallet is not in the transaction.

03 / WITHDRAW

Anywhere, any part

Send any part to any wallet; the relayer pays the fees and the rest stays private. Rounder amounts and a little patience make you harder to match.

/// Roadmap

Today, private SOL/USDC markets.
Next, any token.

Phase A is live: the private account and an open hook anyone can plug into a SOL/USDC Socket pool. Next come private accounts for any token; then swap sizes disappear too.

PHASE A / LIVE

Private account + privacy hook

A zero-knowledge private account (Groth16, Poseidon Merkle tree, private amounts with change) and the DARKHOOK hook: every swap on a hooked pool is funded from the account and settled back into it. The hook is permissionless — anyone can launch a private SOL/USDC market today. Relayer included, launch caps while it is young.

PHASE A+ / NEXT

Any token, any market

Private accounts for any SPL token, so private markets can trade any pair. A "launch a private market" button and a list of hooked pools in the app; Socket allowlist for routing.

PHASE B / BUILDING

Hidden sizes, audit, compliance

Swaps settled in sealed batches inside the private account, so sizes are hidden too; a view key discloses on demand. External audit, multisig authority, higher caps, optional association sets to prove funds are clean without revealing which deposit is yours.