https://api.devnet.solana.com with the published IDLs (idl/mint_redeem.json and idl/clp.json in the docs repo).
What lives where
The price is
Market.user_twap_price. Despite the name, it holds the keeper’s latest spot price, scaled to 1e6 and adjusted for corporate actions. The oracle program’s OracleConfig accounts are not updated on devnet, so don’t read prices from them.
Clp.oi_cap is the market’s exposure cap in cUSDC atoms, 0 meaning uncapped. It sits at byte offset 48 of the account (after the discriminator, market_id and total_fees_collected). Clp.current_oi is not maintained and reads 0 on every market.
To see how much room a capped market has, compute traders’ net position E from the Market account and four token balances:
poolLongVault and poolShortVault are the synth vaults of the two Pool accounts. clpLong and clpShort are the associated token accounts of the Clp PDA for the long and short mints. A token account that was never created counts as 0. l_nav and s_nav are the legs’ NAVs (see NAV). E and the cap are both in cUSDC atoms. Traders can still go net long by cap − E, and net short by cap + E, where a negative result means 0 room.
Fetch one market
totalCollateral is this market’s own collateral ledger, the figure the solvency checks read. Each market has its own vault, and on 11 Oct 2026 every vault’s token balance equaled its ledger. A plain token transfer into a vault raises its balance without changing the ledger, so use market.totalCollateral for solvency.
committedOrders reads swap_guards from the Clp account. It is true for every live market since 11 Oct 2026. A committed order still needs a fresh price push to settle. The bin books are the reverse: they fill only while riskState isn’t "normal" and priceAgeSec is over 300, and pool_swap fails with PoolClosedWhileLive otherwise.
NAV
NAV is derived, not stored:P is user_twap_price, and getNav above computes both legs with the program’s integer rounding. A price of 0 means the market has no price yet. Mint and redeem revert then, and the app leaves the market out. Don’t fall back to the initial_l_price field.
Mint and redeem don’t fill at NAV. They quote each leg against the user by the confidence band; see Mint and Redeem.
Price freshness and risk
twapUpdatedAt holds the publish time of the price the keeper pushed, or the push’s block time if the keeper gave none. Mint and redeem revert with TwapNotAvailable when that is more than 300 s ago or the price is 0, and Stress blocks both. The priceAgeSec and mintRedeemOpen fields in the sample check exactly these conditions. While the underlying market is closed the keeper normally withholds pushes, which is why the output above shows a closed market on a Saturday.
oracleConfidence is the keeper’s confidence band in price units (1e6), from a GJR-GARCH volatility model. The program widens mint and redeem quotes by the band times the risk-state multiplier (1.5× in ProxyMode) on every market with worst-case quoting on. Before a push, the keeper checks each price against Hyperliquid and holds the push if they disagree.
Batch-fetch all 13 markets
OnegetMultipleAccountsInfo call returns every live market:
Bin books
Each market has two books, one per leg. Derive their addresses from the market PDA:basePrice1E6 is the book’s centre; Anchor turns base_price_1e6 into basePrice1E6, with a capital E. Asks are tokens of the leg and bids are cUSDC. The keeper sets the centre from NAV, shifted by the CLP’s inventory, and off-hours it posts a demand-sized free-float book (see Book management). Compare the centre with NAV to see how far a book sits from it. To price a trade, walk the bins as in Quote and swap.
User position value
Pending committed orders
There’s no index of open orders, and some RPC providers, Helius among them, disablegetProgramAccounts. Track your orders yourself. When you commit, store the order PDA or the nonce; the PDA’s seeds are the user, the market and the nonce, so those three find it again.
OrderSettled, OrderRefunded or OrderCancelled. If you lost the nonce, the OrderCommitted event in your commit transaction carries the order address. Where getProgramAccounts works, you can filter Order accounts by user at byte offset 8 and market at offset 40.
Subscribing to live updates
Pool accounts; each book is one account.
Common pitfalls
- After a mint, redeem or swap, fetch again once the transaction is confirmed. Values read before it are stale.
getMultipleAccountsInforeturns null for a book that doesn’t exist. All 28 books of the 14 markets then listed existed on 10 Oct 2026; with MSTR closed, 26 books belong to live markets. Take addresses from Addresses or derive them as above.- Amounts in account state are base units with 6 decimals, for cUSDC and for every L and S token. Divide by
10 ** 6to display them.
See also
Mint flow
What
mint_paired does on chain.SDK setup
Setting up a project to make these reads.

