1. Conduid
  2. Blockchain
  3. Solana
MCP server · Blockchain

Solana

Model Context Protocol server exposing the b402 Solana SDK as agent-callable tools (Claude Code, Cursor, any MCP runtime)

37Low

Scored 5 months ago · breakdown

About Solana

Solana is an MCP server in the Blockchain category: model Context Protocol server exposing the b402 Solana SDK as agent-callable tools (Claude Code, Cursor, any MCP runtime).

Install

Claude Code
claude mcp add solana -- npx -y @b402ai/solana-mcp
npx
npx -y @b402ai/solana-mcp

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Solana

Powered by Claude · Grounded in docs

I know everything about Solana. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

  • ✓README presentThe repository ships documentation.

5 checks have not been run yet.

README

b402-solana

ci license

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 is api.mainnet-beta.solana.com.
  • B402_CLUSTER — devnet for risk-free testing, localnet for a local validator. Default mainnet.
  • 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 time
  • b402-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 forwarding action_payload to Jupiter V6
  • b402-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 inputs
  • adapt.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 functions
  • AdaptProver, 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 in examples/swap-e2e.ts

Ops (ops/)

  • local-validator.sh — boots solana-test-validator with all 4 programs pre-deployed
  • smoke-validator.sh — verifies programs are live on the chosen RPC
  • alt/create-alt.ts — creates + extends the b402 Address Lookup Table (required for adapt_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.

README copy captured when this server was indexed; it may lag the repository. The original is authoritative.

Questions

About Solana

How do I install Solana?

Run claude mcp add solana -- npx -y @b402ai/solana-mcp, then add the server to your MCP client's configuration.

Is Solana safe to use with an AI agent?

Its trust score is 37 out of 100 (low). It passes 1 of the 1 static security checks run so far. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Solana still maintained?

Conduid hasn't recorded a commit date for this repository yet. Check the repository directly for recent activity.