Native CLOB DEX on Solana, by Moonraise Labs.
Moonex is a fully on-chain central limit order book. Implemented as a Solana native program (no Anchor) — manual instruction dispatch, Borsh args, Pod (zero-copy) state, explicit account validation. Spot matching is live; perpetual extensions (funding, mark price, margin, liquidation) are planned.
Program ID (devnet): GawUJQ4vdnxeRzbnkwJsMAb1hVSh9qpXpeyvn9nXxZ72
moonex/
├── programs/moonex/ # on-chain native program (Rust)
│ ├── src/
│ │ ├── lib.rs # entrypoint
│ │ ├── instruction.rs # MoonexInstruction enum (Borsh)
│ │ ├── processor/ # one file per instruction
│ │ ├── state.rs # Pod state: Market, BookSide, OpenOrders, EventQueue
│ │ ├── math.rs # order id, lock math
│ │ ├── pda.rs # PDA seeds
│ │ ├── token.rs # SPL transfer wrappers
│ │ └── error.rs
│ └── tests/ # cargo test (unit + property tests)
├── app/ # Next.js 16 frontend + scripts
│ ├── src/
│ │ ├── app/ # routes
│ │ ├── components/ # Trade, Orderbook, PriceChart, …
│ │ └── lib/
│ │ ├── moonex/ # decoders + ix builders (mirrors program state)
│ │ ├── useMoonex.ts# polled subscription registry
│ │ └── tx.ts # sendAndConfirmRetry (raw send + status poll)
│ └── scripts/
│ ├── mm-bot.ts # synthetic market-maker
│ ├── crank.ts # event queue drain
│ ├── init-market.ts # bootstrap a new market
│ ├── fund-bots.ts / drain-bots.ts / mint-more.ts
│ └── deploy-program.sh
├── CONTRIBUTING.md
├── LICENSE # BUSL-1.1
└── README.md
- Rust +
solanaCLI 1.18+ (or compatible Agave) withcargo-build-sbf - Node.js 20+ and npm
- A Solana keypair at
~/.config/solana/id.json - Devnet RPC endpoint (Helius / QuickNode / public)
cargo build-sbf
cargo test # pure-Rust unit tests
bash app/scripts/deploy-program.sh # wraps `solana program deploy` with 429 backoffcd app
npm install
echo 'NEXT_PUBLIC_RPC_ENDPOINT=https://devnet.helius-rpc.com/?api-key=YOUR_KEY' > .env.local
npm run dev
# → http://localhost:3000cd app
npm run init-market # mints test base/quote, allocates market accounts, calls InitMarketcd app
npm run bot # 4 wallets, 700 ms cadence (defaults)
npm run bot -- --wallets=6 --interval=400 # tune at will
npm run bot:stopcd app
npm run crank- Instructions:
InitMarket,InitOpenOrders,PlaceOrder,CancelOrder,ConsumeEvents,SettleFunds. - Order types:
Limit,PostOnly,IOC,FOK. - State (all Pod, fixed-size):
Market(424 B) — params, vault refs, sub-account pubkeysBookSide(18,448 B) — sorted[OrderNode; 256]per sideOpenOrders(1,384 B, PDA) — 32 slots + free/locked accountingEventQueue(24,600 B) — ring buffer of 256FillEvents
- PDAs: vault signer (
["vault", market]), open orders (["open_orders", market, owner]). - Settlement: taker is paid inline by
PlaceOrder(≤3 SPL transfers per call). Makers are settled out-of-band viaConsumeEvents— anyone can crank. - Matching: O(N) shift-array book, capped at 8 fills per
PlaceOrdercall; self-trade prevention skips own makers.
Full architecture reference: docs/architecture.md (kept as a local
working doc — gitignored).
- All read paths use HTTP-polling via a shared subscription registry
(
src/lib/useMoonex.ts). NoaccountSubscribe— keeps the page well under RPC ws-subscription rate limits. - Transactions go through
src/lib/tx.tssendAndConfirmRetry: wallet signs once, raw bytes are sent + status-polled + auto-rebroadcast until confirmed or the blockhash expires. NosignatureSubscribe. - Orderbook layout: best bid / best ask hug the spread row; cumulative total column with hover-to-spread highlight + sweep readout.
See CONTRIBUTING.md for branch/commit conventions, build steps, and a checklist for changing on-chain layouts.
Business Source License 1.1 (BUSL-1.1). Non-production use permitted; production / commercial use reserved to Moonraise Labs. Converts to GPL v2.0-or-later on 2030-05-13. See LICENSE or contact Moonraise Labs for a commercial license.
- Moonraise Labs — https://moonraise.xyz