Solana
Model Context Protocol server exposing the b402 Solana SDK as agent-callable tools (Claude Code, Cursor, any MCP runtime)
Ask AI about Solana
Powered by Claude Β· Grounded in docs
I know everything about Solana. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
b402-solana
Composable Confidential DeFi on Solana. Shield once, then swap, lend, LP, or trade perps from a private balance β without your wallet appearing on-chain as the executing party. Single-tx execution, composable with any Solana protocol via a registered adapter.
Implementation: Circom 2 circuits, Anchor BPF programs, Groth16 verification
through the alt_bn128_* syscalls (via Lightprotocol/groth16-solana),
Poseidon-bound UTXO commitments, nullifier non-membership in a sharded set,
and a viewing-key separation. The cryptographic primitives are standard
(chosen for auditability against existing literature); what's specific to
this repo is the on-Solana pool program and a proof-bound adapter ABI for
composing into Jupiter, Kamino, and other registered protocols atomically
from a private balance.
Use it on mainnet (one line, no env vars)
claude mcp add b402-solana -- npx -y @b402ai/solana-mcp@latest
Requires a Solana CLI keypair at ~/.config/solana/id.json plus the token
to shield (USDC or WSOL β the mints whitelisted on mainnet today). The
hosted relayer signs unshield and private_swap, so the depositor wallet
does not appear on those transactions.
Optional environment overrides:
B402_RPC_URLβ private RPC endpoint (Helius / Triton / QuickNode / Alchemy). Default isapi.mainnet-beta.solana.com.B402_CLUSTERβdevnetfor risk-free testing,localnetfor a local validator. Defaultmainnet.B402_KEYPAIR_PATHβ alternate keypair path. Default~/.config/solana/id.json.
Run it on devnet (~30 seconds)
git clone https://github.com/mmchougule/b402-solana && cd b402-solana
pnpm install
solana airdrop 1 --url devnet # if you don't have devnet SOL
RPC_URL=https://api.devnet.solana.com pnpm --filter=@b402ai/solana-examples e2e
Shield 100, unshield 100 to a fresh recipient. Sender and recipient share no on-chain edge.
Run private lending (mainnet, live)
Kamino V2 USDC lend + redeem are exposed as private_lend / private_redeem
through @b402ai/solana@0.0.20 and @b402ai/solana-mcp@0.0.27. Each viewing
key gets its own Kamino Obligation (PRD-33 per-user obligation, owner_pda
derived from outSpendingPub). Verified end-to-end on mainnet:
private_lend 4PVuzkJmFF2x...qoCR (Finalized), private_redeem
279hTmsJ2y...c457 (Finalized).
For mainnet-fork hacking against the same bytecode without spending real funds:
./ops/setup-kamino-fork.sh # clones state, boots validator
pnpm tsx examples/kamino-adapter-fork-deposit.ts # private 1 USDC deposit
Goes through b402_kamino_adapter::execute β 7 nested CPIs into Kamino
(init_user_metadata, init_obligation, init_obligation_farms_for_reserve,
refresh_reserve, refresh_obligation, deposit_v2, sweep). Obligation account
grows 0 β 3,344 B in a single tx, owned by the per-user owner_pda.
Kamino lending currently exposed for the main USDC reserve only at the SDK/MCP layer. The adapter itself is reserve-generic; multi-market discovery is the next task.
For the private swap variant (Jupiter v6 on mainnet-fork): Quickstart
step 8. Instruction layout for adapt_execute: docs/TX-WALKTHROUGH.md.
Numbers
Compute-unit cost per flow (litesvm probe against deployed bytecode, latest assurance run):
| Flow | CU consumed | Source |
|---|---|---|
| Shield | 233,495 | litesvm probe (assurance run) |
| Unshield | 223,413 | litesvm probe (assurance run) |
adapt_execute end-to-end (mock adapter, real Groth16) | 313,725 | litesvm probe (assurance run) |
verifier_adapt CPI alone | ~178k | sub-budget inside the adapt-execute probe |
Kamino deposit through b402_kamino_adapter (mainnet-fork, 7 nested CPIs into Kamino) | not yet pinned in the probe β assurance-roadmap item | mainnet-fork example |
Jupiter swap through b402_jupiter_adapter | ~660k observed in mainnet-fork execution | mainnet-fork example |
Solana per-tx limits and our headroom on the heaviest flow we ship today
(adapt_execute end-to-end, full Groth16 verify + adapter CPI + delta check):
| Limit | Solana cap | adapt_execute uses | Headroom |
|---|---|---|---|
| Compute units | 1,400,000 | 313,725 | ~77% free |
| Transaction size (serialized v0) | 1,232 B | fits β see ALT note below | ALT-relieved |
| CPI depth | 4 nested | 2 (pool β adapter β DeFi protocol) | 2 levels free |
| Account meta count (with one ALT) | ~256 | scales with adapter; expanded via ALT, not inline | extend the ALT |
| Per-instruction data | 10 KB | ~1.1 KB transact / ~1.4 KB adapt | ample |
| Signatures | wire-cost per sig | 1 (relayer) | minimal |
The 16-entry b402 Address Lookup Table is what makes adapt_execute a single
v0 transaction in practice. It compresses every common account
(pool program, both verifiers, USDC + wSOL mints, system + token programs,
b402 vaults) from 32-byte inline pubkeys to 1-byte ALT indexes. Adding a new
DeFi protocol = extend the ALT with that protocol's frequently-touched
accounts; the wire format doesn't grow proportionally.
The architectural claim: the whole shielded-swap or shielded-deposit flow is one instruction in one v0 transaction with one signature. CU has the most headroom; tx size is the tightest constraint and ALT is what makes it tractable.
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Client SDK shield β adapt β unshield builders β
β packages/sdk AdaptProver (23 public inputs) β
ββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ
β Pool program commitments tree, nullifier set, β
β programs/b402-pool adapter registry, post-CPI delta β
ββββββ¬ββββββββββββ¬ββββββββββ¬βββββββββββββββββββββββββββββββ
β β β
ββββββΌββββ ββββββΌβββββ βββΌβββββββββββββββββ
β Verif. β β Verif. β β Adapter (any β
β trans. β β adapt β β registered) β
β 18 PI β β 23 PI β β β Jupiter, Kaminoβ
ββββββββββ βββββββββββ β (perps + LP β
β on roadmap) β
βββββββββββ¬βββββββββ
β
βββββββββΌβββββββββ
β Solana DeFi β
β (Jupiter, β¦) β
ββββββββββββββββββ
Adding a new protocol = one Anchor crate (~200-300 LoC) implementing the
execute(action_payload) ABI + a registry entry. No circuit recut, no
ceremony, no pool change. Six adapter crates in repo today; PRDs cover the
v2 ABI extension that makes this strictly true going forward.
Adapter status
| Adapter | Status | What it enables |
|---|---|---|
| Jupiter v6 | mainnet (live) | private swap on any Jupiter route |
| Kamino lend | mainnet (live) β private_lend + private_redeem on USDC reserve, per-user obligation | private deposit + redeem; borrow / repay handlers are scaffolded but gated NotYetImplemented |
| Mock | live on devnet | adapter ABI invariant tests |
| Adrena perps | scaffold; discriminators verified vs Adrena IDL | private leveraged trading |
| Orca LP | scaffold | private whirlpool positions |
| Jupiter perps | scaffold | private perps via JLP (request-queue model β pending v2 ABI two-phase claim notes) |
| Drift perps | spec only | deferred pending Drift's post-hack reboot |
Mainnet deployment
| Program | ID |
|---|---|
| Pool | 42a3hsCXtQLWonyxWZosaaCJCweYYKMrvNd25p1Jrt2y (finalized slot 417871785, Path A slippage skip + Path B synthetic-mint input transfer skip + per_user_obligation) |
| Verifier (transact) | Afjbnv2Ekxa98jjRw33xPPhZabevek2uZxoE75kr6ZrK |
| Verifier (adapt) | 3Y2tyhNSaUiW5AcZcmFGRyTMdnroxHxc5GqFQPcMTZae |
| Jupiter adapter | 3RHRcbinCmcj8JPBfVxb9FW76oh4r8y21aSx4JFy3yx7 |
| Kamino adapter | 2enwFgcGKJDqruHpCtvmhtxe3DYcV3k72VTvoGcdt2rX (finalized slot 417870483, per_user_obligation + cpi-only features) |
| Mock adapter | 89kw33YDcbXfiayVNauz599LaDm51EuU8amWydpjYKgp |
| b402 ALT (16 entries) | 9FPYufa1KDkrn1VgfjkR7R667hbnTA7CNtmy38QcsuNj |
Hosted relayer: Cloud Run revision b402-solana-relayer-mainnet-00004-w5b,
exposes per-feature routes plus the generic /relay/pool-ix endpoint
(any pool ix; auth + rate-limit enforced; cfg.poolProgramId operator-fixed).
See ops/mainnet-deploy.sh.
Privacy model
The chain is public. b402 doesn't change that. What it cryptographically breaks is the link between your wallet and your shielded actions:
| Layer | What | Today |
|---|---|---|
| L1: wallet β action | After shielding, your wallet isn't visible as the spend authority on subsequent shielded actions | a public-chain observer cannot cryptographically link a post-shield spend to the original wallet from the shielded action path alone β Groth16 proof binds the spend without revealing which note was spent |
| L2: action β action | Two shielded actions can't be trivially linked | broken at the note layer; per-user adapter PDAs live on mainnet via per_user_obligation (Kamino adapter slot 417870483) |
| L3: pool-level clustering | Timing + amount correlation across the pool boundary | scales with anonymity set β small pool weak, large pool strong |
Defends against: wallet-watching bots scraping mempool to copy strategies, MEV searchers targeting public DEX flow, surveillance-grade indexers (Chainalysis, Nansen, Arkham) building wallet-level histories. Layer 1 unlinkability covers all of these.
Does NOT fully defend against: patient clustering analysts running timing-and-amount correlation across the pool boundary at small TVL. This is a fundamental property of UTXO-mixer constructions, not a b402-specific weakness. Mitigated by anonymity-set growth β every shield strengthens every other user's privacy. A soft TVL cap is enforced while the set grows.
For autonomous agents specifically β where the adversary is automated strategy-copying bots, not patient analysts β Layer 1 is sufficient.
What's implemented
Programs (programs/)
b402-poolβ init/shield/unshield/transact +adapt_execute(composable private execution with full ZK binding to adapter ID, action hash, expected mint and value) + admin (pause, set verifier, register adapter)b402-verifier-transactβ Groth16 verifier for the 18-input transact circuit, VK baked from ceremony at build timeb402-verifier-adaptβ Groth16 verifier for the 23-input adapt circuit (transact's bindings + adapter ID + action hash + expected out mint/value)b402-jupiter-adapterβ CPI adapter forwardingaction_payloadto Jupiter V6b402-mock-adapterβ test-only adapter for balance-delta invariant tests
Circuits (circuits/)
transact.circomβ 2-in / 2-out shielded transaction, 17,259 R1CS constraints, 18 public inputsadapt.circomβ adapt circuit, 17,582 R1CS constraints, 23 public inputs (transact's 18 + adapter binding fields)- Sub-circuits for commitment, nullifier, spending-key derivation, merkle path
- Tests: primitives, Rust β TS parity, witness generation, end-to-end snarkjs prove-verify (37 total)
SDK (packages/sdk/)
B402Solana β the recommended integration surface. Two-line shield + unshield:
import { B402Solana } from '@b402ai/solana';
const b402 = new B402Solana({
cluster: 'devnet',
keypair, // your Solana signer
proverArtifacts: {
wasmPath: 'circuits/build/transact_js/transact.wasm',
zkeyPath: 'circuits/build/ceremony/transact_final.zkey',
},
});
const shieldRes = await b402.shield({ mint: USDC, amount: 100_000_000n });
const unshieldRes = await b402.unshield({ to: recipientPubkey }); // spends the just-shielded note
End-to-end runnable example: examples/sdk-quick.ts. Wraps wallet build,
ATA derivation, tree fetch, and merkle-proof construction internally.
privateSwap, privateLend, privateRedeem are exposed on the same class
(shipped in @b402ai/solana@0.0.20).
Lower-level building blocks (use these for paths the class doesn't cover yet):
shield(params)/unshield(params)β standalone action functionsAdaptProver,swap-e2e.tsβ full adapt-execute flow (private swap)Scanner,ClientMerkleTree,buildWallet,NoteStoreβ client-side crypto primitives
Prover (packages/prover/)
TransactProverβ generates Groth16 proofs for transact (18 public inputs)AdaptProverβ generates Groth16 proofs for adapt (23 public inputs); composable swap demonstrated inexamples/swap-e2e.ts
Ops (ops/)
local-validator.shβ boots solana-test-validator with all 4 programs pre-deployedsmoke-validator.shβ verifies programs are live on the chosen RPCalt/create-alt.tsβ creates + extends the b402 Address Lookup Table (required foradapt_executeβ without it, Jupiter routes overflow Solana's 1,232 B tx cap)
Quickstart
# Toolchain
# Rust stable + Solana CLI 2.0+ + platform-tools v1.54
# Node 20+, pnpm workspace
pnpm install
# 1. Cryptographic stack β circuits + parity + prover (no chain)
cd circuits && pnpm install && RUN_PARITY=1 RUN_CIRCUIT_TESTS=1 pnpm vitest run
cd ../packages/prover && RUN_PROVER=1 RUN_VERIFIER=1 pnpm vitest run
cd ../crypto && cargo test
# 2. Build programs for BPF
cargo build-sbf --tools-version v1.54 --manifest-path programs/b402-verifier-transact/Cargo.toml
cargo build-sbf --tools-version v1.54 --manifest-path programs/b402-verifier-adapt/Cargo.toml
cargo build-sbf --tools-version v1.54 --manifest-path programs/b402-pool/Cargo.toml --features test-mock
cargo build-sbf --tools-version v1.54 --manifest-path programs/b402-jupiter-adapter/Cargo.toml
cargo build-sbf --tools-version v1.54 --manifest-path programs/b402-mock-adapter/Cargo.toml
# 3. On-chain tests (litesvm, in-process Solana VM)
cd tests/onchain && cargo test
# 4. SDK regression tests (tx-size, parity)
pnpm --filter=@b402ai/solana test
# 5. End-to-end against a local validator
./ops/local-validator.sh --reset # terminal 1
cd examples && pnpm e2e # terminal 2 β runs shield β unshield
# 6. Same e2e against devnet (uses CLI wallet + deployed programs)
RPC_URL=https://api.devnet.solana.com pnpm --filter=@b402ai/solana-examples e2e
# 6b. Same flow via the high-level SDK class (B402Solana β recommended integration path)
RPC_URL=https://api.devnet.solana.com pnpm --filter=@b402ai/solana-examples sdk-quick
# 7. Private swap on localnet (shield β adapt proof β mock adapter β unshield)
./ops/local-validator.sh --reset # terminal 1
cd examples && pnpm swap-e2e # terminal 2
# 7b. Same private swap, but on devnet against deployed programs.
# Funded CLI wallet pays rent for fresh nullifier shards (~0.07 SOL each).
RPC_URL=https://api.devnet.solana.com pnpm --filter=@b402ai/solana-examples swap-e2e
# 7a. Scanner auto-discovery: Alice privately sends to Bob, Bob's scanner
# discovers the note from public logs, Bob unshields to Charlie.
./ops/local-validator.sh --reset # terminal 1
cd examples && pnpm scanner-e2e # terminal 2
# 8. Private swap on a mainnet-forked validator (shield β Jupiter β unshield)
# Fetches a live Jupiter quote, boots a validator with Jupiter + AMM state
# cloned from mainnet, runs the flow against cloned bytecode.
cd examples && pnpm tsx ../ops/jup-quote.ts \
--in So11111111111111111111111111111111111111112 \
--out EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v \
--amount 100000000 \
--caller $(solana address -k ~/.config/solana/id.json) \
--out-file /tmp/jup-route.json
./ops/mainnet-fork-validator.sh --route /tmp/jup-route.json --reset # terminal 1
cd examples && pnpm swap-e2e-jupiter # terminal 2
Repo layout
b402-solana/
βββ docs/
β βββ prds/ sequenced PRDs 01β08 + 01-A amendment
β βββ TX-WALKTHROUGH.md anatomy of shield + unshield tx
β βββ SUBMISSION.md internal: submission strategy
βββ circuits/ Circom 2.2 source + scripts + tests
βββ programs/
β βββ b402-pool/ commitments tree, nullifier set, adapt_execute
β βββ b402-verifier-transact/ Groth16 verifier, 18 PI (transact circuit)
β βββ b402-verifier-adapt/ Groth16 verifier, 23 PI (adapt circuit)
β βββ b402-jupiter-adapter/ Jupiter v6 CPI wrapper
β βββ b402-kamino-adapter/ Kamino lend CPI wrapper (deposit + redeem live, per_user_obligation + cpi-only)
β βββ b402-mock-adapter/ test-only delta-invariant adapter
β βββ b402-adrena-adapter/ scaffold β perps, PRD-16
β βββ b402-orca-adapter/ scaffold β whirlpool LP
β βββ b402-jupiter-perps-adapter/ scaffold β JLP perps
βββ packages/
β βββ crypto/ Rust Fr / Poseidon / Merkle (parity-tested β TS)
β βββ shared/ @b402ai/solana-shared β constants, codecs
β βββ prover/ @b402ai/solana-prover β snarkjs wrapper
β βββ sdk/ @b402ai/solana β wallet, actions, scanner
βββ tests/onchain/ litesvm integration tests (15 tests)
βββ ops/
β βββ local-validator.sh boot a validator with all programs
β βββ smoke-validator.sh verify deploys
β βββ alt/ Address Lookup Table tooling
β βββ keypairs/ deploy authority keys (gitignored)
βββ examples/
β βββ e2e.ts shield β unshield demo
βββ Anchor.toml, Cargo.toml
βββ BUILD-STATE.md running internal state doc
βββ ENGINEER-REVIEW.md one-pager for reviewers
Design principles
- PRD-driven. Read
docs/prds/in numeric order. Each decision is justified before code. - TDD for circuits. Unit + property + Rust parity + negative tests before integration.
- Permissionless. No KYT, no allowlists. Optional opt-in viewing-key disclosure.
- 0% protocol fee. No fee field in the v1 program β adding one would require a circuit-level public input change (i.e. a new ceremony and a new pool deployment), not an admin instruction. Relayer fees are paid in-kind from the unshield amount.
- Audit-first. Designs written for auditor consumption. Cryptographic primitives and failure modes spelled out before implementation.
Status
Mainnet. Pool + verifiers + Jupiter adapter + Kamino adapter (per-user
obligation) live; private_swap, private_lend, private_redeem proven
end-to-end on mainnet with finalized signatures. Single-key admin today;
3-of-5 multisig migration is the next operational milestone. Throwaway
trusted-setup VK; multi-party ceremony pending. External audits scoped
with Veridise / Trail of Bits / Zellic β reports linked here when they
land. Soft TVL cap enforced; hard cap lands in PoolConfig before
community-promoted deposits. Stealth-address bech32 encoding is the
remaining SDK gap.
Read the full PRD set for the design rationale behind every
decision. Issues + PRs welcome β adapter additions are the easiest contribution.
See SECURITY.md for disclosure and CONTRIBUTING.md
for setup.
License
Apache-2.0. Use SECURITY.md for responsible disclosure and CONTRIBUTING.md for pull requests.
