Skip to content

Instantly share code, notes, and snippets.

@MdSadiqMd
Last active April 6, 2026 15:07
Show Gist options
  • Select an option

  • Save MdSadiqMd/91b7ed287eb3d4862e959d116f87b8e6 to your computer and use it in GitHub Desktop.

Select an option

Save MdSadiqMd/91b7ed287eb3d4862e959d116f87b8e6 to your computer and use it in GitHub Desktop.

Incognitus — Frontend Specification

Project: Incognitus — On-Chain Central Limit Order Book (CLOB) Chain: Solana Scope: Frontend client — WASM + WebGPU + React Hackathon: Colosseum Frontier (April 6 – May 11, 2026)

incognitus-frontend-spec.md 27 KB Nomadic° — 8:08 PM lol yeah same. alright I am going to review your PR right now. 

Incognitus — Frontend Specification

Project: Incognitus — On-Chain Central Limit Order Book (CLOB) Chain: Solana Scope: Frontend client — WASM + WebGPU + React Hackathon: Colosseum Frontier (April 6 – May 11, 2026) Status: WIP — instruction accounts and details will be finalized as the on-chain program is built. This spec is the starting point for implementation. Expect iteration.


Table of Contents

  1. What Incognitus Is
  2. Frontend's Role
  3. System Architecture
  4. User Transaction Pipelines
  5. Instructions
  6. Accounts the Frontend Reads
  7. Client Architecture
  8. UI State
  9. Data Flow
  10. Glossary

1. What Incognitus Is

Incognitus is a fully on-chain Central Limit Order Book (CLOB) built on Solana. It enables spot trading between token pairs.

Two types of participants interact with the market:

  • Maker — places a limit order (a resting order at a specific price that sits in the book until matched)
  • Taker — places a market order (fills immediately against existing limit orders at the best available price)

Orders are stored on-chain. Matching happens on-chain. Settlement (the actual token transfer) happens on-chain.

The on-chain program never moves by itself. It only responds to transactions. The client is responsible for submitting each step of the pipeline in sequence.


2. Frontend's Role

The frontend is responsible for three things:

  1. Order placement — collect user input, compute required values, build and sign all pipeline transactions upfront, then dispatch them one by one as each prior step confirms
  2. Display — read on-chain account data and render the order book and balances
  3. History and candles — sourced from the indexer (not on-chain account reads)
graph LR
    User["Trader"] -->|"order input"| Frontend["Frontend Client"]
    Frontend -->|"signed transactions"| Solana["Solana Program"]
    Solana -->|"account state"| Frontend
    Frontend -->|"render order book + balances"| Display["UI"]
    Indexer -->|"trade history + candles"| Frontend
Loading

How to read this diagram: Each box is a component. Each arrow is data moving between them, labeled with what's being sent. The diagram shows: the trader gives input to the frontend, the frontend sends signed transactions to Solana and reads back account state, and the indexer provides history and candles separately.


3. System Architecture

graph TB
    subgraph BROWSER["Browser"]
        subgraph REACT["React / Vite UI"]
            OBDisplay["Order Book Ladder"]
            OrderForm["Order Form"]
            TradeHistory["Trade History"]
            Candles["Candles (TradingView)"]
            BalanceView["Balances / Account State"]
            PipelineStatus["Pipeline Status\n(in-flight tx progress)"]
        end

        subgraph WASM["WASM Client (Rust → WebAssembly)"]
            IB["Instruction Builders\nbuild all pipeline transactions"]
            AD["Account Decoders\nparse slab byte buffers"]
            PM["Pipeline Dispatcher\ndispatch pre-signed txs on events"]
            PC["Pre-computation\nquote = price × quantity"]
            VAL["Validation\ndivisibility checks"]
        end

        subgraph WALLET["Wallet (Phantom / Backpack)"]
            SIGN["Signs transactions\n(browser extension)"]
        end

        subgraph GPU["WebGPU"]
            CS["Compute Shaders\n(sort, aggregate)"]
            RS["Render Pipeline\n(depth chart, heatmap, ladder)"]
        end

        REACT -->|"user actions"| WASM
        WASM -->|"built transactions"| WALLET
        WALLET -->|"signed transactions"| WASM
        WASM -->|"decoded state"| REACT
        WASM -->|"raw price bytes"| GPU
        GPU -->|"sorted + aggregated data"| WASM
        GPU -->|"rendered frames → canvas"| REACT
    end

    subgraph SOLANA["Solana (On-Chain)"]
        Program["Solana Program"]
        OrderBook["Order Book\n(Slab Accounts)"]
        Ledger["Ledger\n(Slab Accounts)"]
        Transient["Transient Accounts\n(Queues, Aggregates, Events)"]
    end

    subgraph INDEXER["Indexer (post-MVP)"]
        CandleAPI["Candle History"]
        EventStream["Event Stream (WebSocket)"]
    end

    WASM -->|"RPC: submit txs"| Program
    WASM -->|"RPC: getMultipleAccounts"| OrderBook
    EventStream -->|"trade history + candles"| WASM
Loading

On-chain components the frontend interacts with:

Component What It Is How the Frontend Touches It
Solana Program Entry point — validates and routes all instructions Submit transactions via RPC
Order Book Slab accounts storing all resting limit orders Read for order book display
Ledger Slab accounts tracking trader identities and order status Read for user open orders
Transient Accounts Per-pipeline queues, aggregates, and event records Read and written during the pipeline

Note on account growth: When a slab account needs to grow in size, the client must include a resize transaction before the instruction that requires it. This is part of pipeline management — when account growth is needed, the client detects it and inserts the resize step automatically.


4. User Transaction Pipelines

Transaction Flow Pattern

All transactions in a pipeline are built and signed upfront before any are dispatched. Once signed, they are dispatched one by one — each dispatched only after the previous one confirms.

sequenceDiagram
    participant WASM as WASM Client
    participant Wallet as Wallet
    participant RPC as Solana RPC

    WASM->>WASM: Build all pipeline transactions
    WASM->>Wallet: Request signatures for all transactions
    Wallet-->>WASM: All transactions signed

    loop for each transaction in pipeline
        WASM->>RPC: Dispatch Tx[N]
        RPC-->>WASM: Confirmation event
    end
Loading

Why pre-build and pre-sign: The wallet signs everything at once. The user approves once. Then the pipeline runs automatically, dispatching each signed transaction as the prior one confirms.

On dispatch failures: If a transaction fails or times out, surface the error to the user. Whether to retry or abort is context-dependent and will be handled as issues arise during implementation.


4.1 Maker Pipeline (Limit Order) — 5 Transactions

sequenceDiagram
    actor Maker
    participant WASM as WASM Client
    participant Wallet as Wallet
    participant RPC as Solana RPC
    participant Program as Solana Program

    Maker->>WASM: Place limit order (side, action, price, quantity, quote)

    Note over WASM: Compute quote = price × quantity
    Note over WASM: Validate divisibility

    WASM->>WASM: Build all 5 transactions
    WASM->>Wallet: Request signatures
    Wallet-->>WASM: All signed

    WASM->>RPC: Dispatch PlaceLimitOrder
    RPC->>Program: PlaceLimitOrder
    Program-->>RPC: Confirmed
    RPC-->>WASM: Event

    Note over WASM: Dispatch all 3 aggregate txs simultaneously
    WASM->>RPC: Dispatch OrderAggregate + PriceAggregate + TrieAggregate (parallel)
    RPC->>Program: All 3 aggregate txs
    Program-->>RPC: All confirmed
    RPC-->>WASM: Event

    Note over WASM: Check write-lock before dispatching
    WASM->>RPC: Dispatch UpdateOrderBook
    RPC->>Program: UpdateOrderBook
    Program-->>RPC: Confirmed
    RPC-->>WASM: Event

    WASM-->>Maker: Limit order is live in the order book
Loading
Step Instruction(s) Dispatched What Happens
1 PlaceLimitOrder Alone Order validated and written into limit order queue
2 OrderAggregate + PriceAggregate + TrieAggregate All at once (parallel) Queue data grouped and prepared — one tx per aggregate type per side
3 UpdateOrderBook Alone (after write-lock check) Order written into the live order book

4.2 Taker Pipeline (Market Order) — 3 Transactions

Note: PlaceMarketOrder and CacheMarketOrder are out of scope for hackathon v1. The taker pipeline starts at matching.

sequenceDiagram
    actor Taker
    participant WASM as WASM Client
    participant Wallet as Wallet
    participant RPC as Solana RPC
    participant Program as Solana Program

    Taker->>WASM: Initiate market order

    WASM->>WASM: Build all 3 transactions
    WASM->>Wallet: Request signatures
    Wallet-->>WASM: All signed

    Note over WASM: Check write-lock before dispatching
    WASM->>RPC: Dispatch MatchOrders
    RPC->>Program: MatchOrders
    Program-->>RPC: Confirmed
    RPC-->>WASM: Event

    WASM->>RPC: Dispatch Settlement
    RPC->>Program: Settlement
    Program-->>RPC: Confirmed
    RPC-->>WASM: Event

    Note over WASM: Dispatch cleanup per side (parallel)
    WASM->>RPC: Dispatch Cleanup (bid) + Cleanup (ask)
    RPC->>Program: Both cleanup txs
    Program-->>RPC: Confirmed
    RPC-->>WASM: Event

    WASM-->>Taker: Order filled and settled
Loading
Step Instruction(s) Dispatched What Happens
1 MatchOrders Alone (after write-lock check) Matching engine runs — order fills against the book
2 Settlement Alone Ledger updated, balances credited and debited
3 Cleanup (bid + ask) Both at once (parallel) Matched entries removed from the order book

4.3 Write-Lock Check

Before dispatching UpdateOrderBook (maker step 3) and MatchOrders (taker step 1), the client must check the write-lock state on OrderBookConfig.

flowchart LR
    A["Ready to dispatch\nwrite-lock instruction"] --> B{"Write-lock\nactive?"}
    B -->|"No"| C["Dispatch immediately"]
    B -->|"Yes"| D{"More than 2 slots\nelapsed since lock?"}
    D -->|"Yes"| C
    D -->|"No"| E["Wait then re-check"]
    E --> B
Loading

5. Instructions

Note: Instruction names are working names. Exact names, discriminators, and remaining account details will be finalized with the program. Fields marked TBD will be updated. This spec is a starting point — expect changes as the program is built.


5.1 PlaceLimitOrder

Pipeline: Maker step 1 of 3

Purpose: Validate a new limit order or cancel request and write it into the limit order queue.

Client pre-computation (before building the transaction):

quote = price × quantity

Checks:
  quote % price    == 0
  quote % quantity == 0

If either check fails — reject locally, do not submit.

Inputs:

Field Type Description
side u8 0 = bid, 1 = ask
action u8 0 = open, 1 = cancel
price u64 Limit price — only if action = open
quantity u64 Base token amount — only if action = open
quote u64 Pre-computed: price × quantityonly if action = open
order_id TBD Order to cancel — only if action = cancel

Accounts:

Account Access Description
MarketConfig Read Market reference
AccountStatus Read User balance validation
LimitOrderQueue Write Destination queue
User wallet Signer Transaction authority

On-chain validation:

  • If ask + open: quantity <= AccountStatus.quantity_amount
  • If bid + open: quote <= AccountStatus.quote_amount
  • quote % price == 0
  • quote % quantity == 0

5.2 Aggregate Transactions (3 parallel transactions per side)

Pipeline: Maker step 2 of 3

Purpose: Process the limit order queue data into structured aggregates ready for order book insertion. Three separate aggregate transactions, each covering one type of data. Both sides (bid + ask) run in parallel. All can be dispatched simultaneously — they do not conflict.


5.2a OrderAggregate

Account Access Description
MarketConfig Read Market reference
LimitOrderQueue Read Source queue (per side)
OrderAggregate Write Aggregated order entry output
User wallet Signer

5.2b PriceAggregate

Account Access Description
MarketConfig Read Market reference
LimitOrderQueue Read Source queue (per side)
PriceAggregate Write Aggregated price level output
User wallet Signer

5.2c TrieAggregate

Account Access Description
MarketConfig Read Market reference
LimitOrderQueue Read Source queue (per side)
TrieAggregate Write Aggregated trie path output
User wallet Signer

5.3 UpdateOrderBook

Pipeline: Maker step 3 of 3

Purpose: Apply aggregated data to the live order book. Insert new TrieNodes, PriceNodes, and OrderBlocks into the slab accounts.

Write-lock: OrderBookConfig carries a write-lock. Before dispatching, check the lock. If locked, wait until released or until more than 2 slots have elapsed.

Inputs: None.

Accounts:

Account Access Description
MarketConfig Read Market reference
OrderBookConfig Write Write-lock state
Bid side
EntryAggregate Read Aggregated order entries for bid
PriceAggregate Read Aggregated price levels for bid
TrieAggregate Read Aggregated trie paths for bid
SlabTrieNode (bid) Write Trie node slab
SlabTrieLinkedNode (bid) Write Trie link node slab
SlabPriceNode (bid) Write Price node slab
SlabOrderBlockNode (bid) Write Order block slab
SlabOrderHeader (bid) Write Order header slab
Ask side
OrderAggregate Read Aggregated order entries for ask
PriceAggregate Read Aggregated price levels for ask
TrieAggregate Read Aggregated trie paths for ask
SlabTrieNode (ask) Write Trie node slab
SlabTrieLinkedNode (ask) Write Trie link node slab
SlabPriceNode (ask) Write Price node slab
SlabOrderBlockNode (ask) Write Order block slab
SlabOrderHeader (ask) Write Order header slab
User wallet Signer

5.4 PlaceMarketOrder

Out of scope for hackathon v1. Skip.


5.5 CacheMarketOrder

Out of scope for hackathon v1. Skip.


5.6 MatchOrders

Pipeline: Taker step 1 of 3

Purpose: The matching engine runs on-chain. The market order fills against resting limit orders in price-time priority. Fill records are written to the event queue.

Write-lock: Same check as UpdateOrderBook — check OrderBookConfig lock before dispatching.

Inputs: None.

Accounts:

Account Access Description
MarketConfig Read Market reference
OrderBookConfig Write Write-lock state
EventQueue Write Fill records output
Bid side
SlabTrieNode (bid) Write Trie traversal and delta updates
SlabTrieLinkedNode (bid) Write Child pointer chains
SlabPriceNode (bid) Write Price level cursor updates
SlabOrderBlockNode (bid) Write Entry consumption
SlabOrderHeader (bid) Write
Ask side
SlabTrieNode (ask) Write Trie traversal and delta updates
SlabTrieLinkedNode (ask) Write Child pointer chains
SlabPriceNode (ask) Write Price level cursor updates
SlabOrderBlockNode (ask) Write Entry consumption
SlabOrderHeader (ask) Write
User wallet Signer

5.7 Settlement

Pipeline: Taker step 2 of 3

Purpose: Apply fill results to the ledger. Credit and debit trader balances.

Write-lock: LedgerConfig carries a write-lock. Check before dispatching — same 2-slot rule applies. SlabOrderBlockNode is read-only here so it does not conflict with other writes.

Accounts:

Account Access Description
MarketConfig Read Market reference
LedgerConfig Write Write-lock state
EventQueue Read Fill records from MatchOrders
SlabOrderBlockNode Read Verify fill data
SlabAccountLedger Write Trader identity records
SlabOrderStatus Write Order status updates
SlabOrderEntry Write Order entry records
SlabOrderStatusLinkedNode Write Order status link nodes
SlabOrderEntryLinkedNode Write Order entry link nodes
User wallet Signer

5.8 Cleanup (one transaction per side)

Pipeline: Taker step 3 of 3

Purpose: Remove matched entries from the order book. Free slab memory.

Write-lock: Lock still applies — same check as UpdateOrderBook before dispatching.

Note: One transaction per side (bid + ask). Both can be dispatched at the same time.

Accounts (per side):

Account Access Description
MarketConfig Read Market reference
EventQueue Read Fill records to process
OrderBookConfig Write Write-lock
SlabTrieNode Write Remove empty trie nodes
SlabTrieLinkedNode Write Remove empty link nodes
SlabPriceNode Write Remove empty price levels
SlabOrderBlockNode Write Free matched entries
SlabOrderHeader Write
User wallet Signer

6. Accounts the Frontend Reads

6.1 Order Book Display

The client reads PriceNode slab accounts to build the order book display. Each account contains a sequence of PriceNode structs. The client reads through each node in the account, extracts the price and quantity, and builds the ladder.

Per PriceNode, extract:

Field Type Description
price u64 The price level
delta_quantity_total u64 Total resting quantity at this price
side derived Which slab you're reading — bid slab = bid, ask slab = ask

Account naming pattern:

SlabPriceNode [bid] [market] [0]   ← bid side
SlabPriceNode [ask] [market] [0]   ← ask side

PDA seeds TBD — finalized with program.

Display output: Sort by price, group into bid and ask ladder, compute cumulative depth for depth chart.


6.2 User State

Status: WIP — structure finalized with program.

Account Contents Use
AccountStatus User token balances Show available balance, validate order inputs
SlabOrderStatus Open orders and fill history Show active orders

6.3 Market State

Account Contents Use
MarketConfig Market parameters, token pair Validate orders reference correct market
OrderBookConfig Write-lock state Check before dispatching write-lock instructions

7. Client Architecture

7.1 Responsibilities by Layer

graph TB
    subgraph REACT["React Layer — UI"]
        R1["Order Form"]
        R2["Order Book Ladder"]
        R3["Trade History"]
        R4["Candles — TradingView widget"]
        R5["Balances + Open Orders"]
        R6["Pipeline Status — tx progress"]
    end

    subgraph WASM["WASM Layer — Rust → WebAssembly"]
        W1["Instruction Builders — build all pipeline txs"]
        W2["Account Decoders — parse slab byte buffers"]
        W3["Pipeline Dispatcher — dispatch pre-signed txs on events"]
        W4["Pre-computation — quote = price × quantity"]
        W5["Validation — divisibility checks"]
        W6["Write-lock checker — slot-aware dispatch logic"]
    end

    subgraph WALLET["Wallet — Phantom / Backpack"]
        WS["Signs transactions\nUser approves once per pipeline"]
    end

    subgraph GPU["WebGPU Layer"]
        G1["Radix Sort — sort price levels"]
        G2["Aggregation — parallel reduction by price"]
        G3["Depth Chart Renderer"]
        G4["Heatmap Renderer"]
        G5["Order Book Ladder Renderer"]
    end

    REACT -->|"user input"| WASM
    WASM -->|"decoded state"| REACT
    WASM -->|"built transactions"| WALLET
    WALLET -->|"signed transactions"| WASM
    WASM -->|"raw price bytes"| GPU
    GPU -->|"rendered frames → canvas"| REACT
Loading

7.2 Layer Responsibilities

WASM (Rust compiled to WebAssembly):

  • Build and serialize transactions
  • Decode on-chain account data (slab byte buffers)
  • Pre-compute quote = price × quantity
  • Run divisibility validation before submitting
  • Dispatch pre-signed transactions and listen for events
  • Write-lock check and slot-elapsed logic

Wallet (browser extension — Phantom / Backpack):

  • Sign transactions — this cannot happen in WASM in the browser, the wallet extension handles it
  • The WASM layer passes built transactions to the wallet adapter, the wallet signs them and returns them

WebGPU:

  • Sort price levels (radix sort — 10–30× faster than WASM for large sets)
  • Aggregate quantities by price (parallel reduction)
  • Render depth chart, heatmap, and order book ladder
  • For hackathon v1: start without WebGPU, add rendering and sort once core pipeline works

React:

  • All UI rendering and user interaction
  • Receives decoded state from WASM and rendered frames from WebGPU
  • Shows pipeline status (which tx in flight, confirmations)

7.3 When to Use WASM vs WebGPU

Workload Layer Reason
Build transactions WASM Sequential serialization
Sign transactions Wallet Browser extension only
Decode account data WASM Sequential struct parsing
Single order validation WASM Trivial, no GPU overhead worth it
Pipeline dispatch logic WASM State machine, event-driven
Write-lock check WASM Slot-aware branching logic
Sort price levels WebGPU GPU radix sort is 10–30× faster
Aggregate quantities by price WebGPU Parallel reduction
Render depth chart WebGPU Uniform pixel ops — stays on GPU
Render heatmap WebGPU Per-cell color mapping, ideal GPU work
Render order book ladder WebGPU Per-frame updates at 60fps

8. UI State

8.1 Market State

State Source Updated When
Order book bid levels SlabPriceNode (bid) Account change / per slot
Order book ask levels SlabPriceNode (ask) Account change / per slot
Trade history Indexer event stream Match event received
Candle data (OHLCV) Indexer on load, then live trade events Trade event → client updates current candle
Best bid / best ask Derived from order book Order book update

8.2 User State

State Source Updated When
Available balance AccountStatus After Settlement confirms
Active / open orders SlabOrderStatus After UpdateOrderBook confirms
Order history Indexer event stream Match event received

8.3 Pipeline State

Track each in-flight pipeline so the UI can show progress.

stateDiagram-v2
    direction LR

    [*] --> Idle

    Idle --> BuildSign : user submits limit order
    BuildSign --> Dispatching1 : wallet signs all txs
    Dispatching1 --> Dispatching2 : PlaceLimitOrder confirmed
    Dispatching2 --> Dispatching3 : all Aggregate txs confirmed
    Dispatching3 --> LiveInBook : UpdateOrderBook confirmed
    LiveInBook --> [*]

    Idle --> BuildSign2 : taker initiates match
    BuildSign2 --> TakerDispatching1 : wallet signs all txs
    TakerDispatching1 --> TakerDispatching2 : MatchOrders confirmed
    TakerDispatching2 --> TakerDispatching3 : Settlement confirmed
    TakerDispatching3 --> Filled : Cleanup confirmed
    Filled --> [*]
Loading

9. Data Flow

9.1 Transaction Pipeline (Build → Sign → Dispatch)

flowchart TD
    Input["User Input\nside, action, price, quantity"] --> Compute["WASM: Compute\nquote = price × quantity"]
    Compute --> Check{"Divisibility\nvalid?"}
    Check -->|"No"| Reject["Show error\ndo not proceed"]
    Check -->|"Yes"| Build["WASM: Build all pipeline transactions"]
    Build --> Sign["Wallet: Sign all transactions"]
    Sign --> Dispatch["WASM: Dispatch Tx[0]"]
    Dispatch --> Listen["Listen for confirmation event"]
    Listen --> Next["Dispatch Tx[N+1]\n(after write-lock check if applicable)"]
    Next --> Listen
Loading

9.2 Order Book Display

flowchart TD
    Trigger["Account change event\n(per slot)"] --> Fetch["RPC: getMultipleAccounts\nSlabPriceNode — bid + ask"]
    Fetch --> Decode["WASM: iterate each node\nextract price + quantity"]
    Decode --> Upload["Upload to GPU storage buffer"]
    Upload --> Compute["WebGPU Compute\n1. Radix sort by price\n2. Prefix sum for depth\n3. Color mapping"]
    Compute --> Render["WebGPU Render\nLadder + depth chart + heatmap"]
    Render --> Canvas["Canvas in React UI"]
Loading

9.3 History and Candles

flowchart TD
    Load["Page load"] --> Fetch["Indexer: fetch OHLCV history"]
    Fetch --> Feed["Feed into TradingView widget"]

    Stream["Live trade events\n(Indexer WebSocket)"] --> Update["WASM: update current candle\nopen, high, low, close, volume"]
    Update --> Feed
Loading

10. Glossary

Term Definition
Maker Trader who places a limit order — adds liquidity
Taker Trader who places a market order — removes liquidity
CLOB Central Limit Order Book — matches orders by price-time priority
Slab Allocator On-chain memory manager — fixed-size byte buffer managing node storage
TrieNode Node in the price trie — organizes limit orders by price digit
PriceNode Record for one specific price level — links to all order entries at that price
OrderBlock Batch of up to 16 order entries at a price level
OrderEntry Single resting limit order — the atomic unit
Pipeline The sequence of transactions required to complete one order lifecycle
Settlement On-chain step that credits and debits trader balances after a match
Write-lock Flag on OrderBookConfig or LedgerConfig signaling the resource is being written to
Event Queue On-chain account holding fill records produced by MatchOrders, consumed by Settlement and Cleanup
PDA Program Derived Address — deterministic on-chain account address
WASM WebAssembly — Rust compiled to run in the browser
WebGPU Browser GPU API — parallel computation and rendering
Slot ~400ms unit of time on Solana — one block
incognitus-frontend-spec.md
27 KB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment