API and SDK
Everything the app shows comes from a public HTTP API: the network, the vault, every book and its quote, epochs, incidents, parameters and wallet positions, plus a live stream and transaction building. No key is needed to read.
Base URL: https://api.openprop.trade
Conventions
- Responses are JSON of the form
{ "data": …, "meta": … }.metanames the cluster, the indexed slot (indexedSlot, finalized) and the chain slot (chainSlot, confirmed). - Integers that can exceed 2⁵³ — amounts, prices, slots, epochs — are decimal strings. Parse them with
BigIntor a decimal library, never as floats. - Units: SOL in lamports (10⁻⁹), USDC in micros (10⁻⁶), prices in USDC micros per SOL, vault shares with 6 decimals, scores ×10⁶, basis-point metrics as stated in each field.
- Errors return
{ "error": { "code", "message", "retryable", "programError"? } }. A program error carries its code and name, for example6004 QUOTE_STALE.
Reads
| Method | Path | Returns |
|---|---|---|
| GET | /v1/network |
Cluster, program address, wire and account versions, slots, index status |
| GET | /v1/pair |
SOL/USDC mints, reference price, confidence, breaker state |
| GET | /v1/vault |
Vault totals, NAV, share supply, share price, cap |
| GET | /v1/books |
Every registered book in registry order with its quote, allocation, excess and checks |
| GET | /v1/books/{address} |
One book in detail, with recent fills and checkpoints |
| GET | /v1/epochs |
Settled epochs |
| GET | /v1/epochs/{epoch} |
One settlement: per-book excess and the split |
| GET | /v1/incidents |
Limit trips and halts |
| GET | /v1/buybacks |
Every buy-and-burn of $OPENPROP: USDC spent, tokens burned, and the totals |
| GET | /v1/parameters |
The parameter catalog and the live Config values |
| GET | /v1/errors |
Every program and API error code |
| GET | /v1/wallets/{address}/position |
A wallet's vault shares, value and withdrawal tickets |
| GET | /v1/wallets/{address}/quoter |
A wallet's quoter seat, bond, tier, hot keys and unbond tickets |
| GET | /health |
ready, or waiting with the reason |
curl https://api.openprop.trade/v1/books
Live stream
GET /v1/live is a Server-Sent Events stream of update events. The first carries type: "snapshot" — network, vault, pair, books, quotes and recent fills — and each later one type: "tick" with the same shape as the chain advances. Replace your window with each event rather than merging it.
const live = new EventSource('https://api.openprop.trade/v1/live')
live.addEventListener('update', (e) => {
const event = JSON.parse(e.data) // { type, sequence, meta, data }
render(event.data)
})
Building transactions
The API builds unsigned transactions for every user action. It reads the current accounts, adds the compute budget, any missing token accounts and native-SOL wrapping, compiles a version-0 transaction against the deployment's lookup table, and simulates it.
POST /v1/tx/{action} with a JSON body of { "wallet": "<your address>", … }:
| Action | Body fields besides wallet |
|---|---|
deposit |
requestId, maxBaseLamports, maxQuoteMicros, minSharesAtomic |
request-withdraw |
epoch, sharesAtomic, optional minBaseLamports, minQuoteMicros |
claim |
epoch, optional minBaseLamports and minQuoteMicros together |
swap |
owner (the book's quoter), side (sell-base or buy-base), amountInAtomic, minAmountOutAtomic |
register |
requestId, amountMicros |
add-bond |
requestId, amountMicros |
request-unbond |
requestId, amountMicros |
claim-unbond |
requestId |
set-quote-authority |
authorities (up to 3 addresses), optional resetQuoteSequence |
pause, resume |
none |
requestId is any u64 you choose, unique per request; retrying the same request never applies twice.
The response:
{
"data": {
"transactionBase64": "…",
"blockhash": "…",
"lastValidBlockHeight": "…",
"requiredSigners": ["<wallet>"],
"simulation": { "unitsConsumed": 41234, "error": null }
}
}
If simulation.error is set, do not ask for a signature: the program would reject the transaction, and the error says why.
Signing and sending
Sign with the user's wallet. With a Wallet Standard wallet, prefer solana:signAndSendTransaction: the wallet sends through its own connection. Otherwise sign with solana:signTransaction and relay:
curl -X POST https://api.openprop.trade/v1/tx/relay \
-H 'content-type: application/json' \
-d '{"transactionBase64":"<signed transaction>"}'
The relay verifies every signature and accepts only transactions that call the OpenProp program, with nothing beyond the compute budget, System, Token, Associated Token, Ed25519 and Lighthouse programs. Then follow the signature:
curl https://api.openprop.trade/v1/tx/<signature>
which returns pending, confirmed, finalized or failed with the slot and any error.
Transactions whose requiredSigners list more than one key — adding a hot key — need every listed signature on the same message before relaying.
Transaction endpoints allow 60 requests per minute per client.
TypeScript client
@openprop/contract wraps every route with typed schemas: network(), vault(), pair(), books(), book(address), epochs(), epoch(n), incidents(), buybacks(), parameters(), position(wallet), quoter(wallet), subscribeLive({ onEvent }), the builders buildDeposit, buildSwapExactIn and the rest, relayTransaction and transactionStatus. It also exports the program's instruction builders, account decoders and error table.
import { createOpenPropClient } from '@openprop/contract'
const api = createOpenPropClient({ baseUrl: 'https://api.openprop.trade' })
const { data: books } = await api.books()
const prepared = await api.buildSwapExactIn({
wallet,
owner: books[0].owner,
side: 'sell-base',
amountInAtomic: '1000000000', // 1 SOL
minAmountOutAtomic: '0',
})
Quoter SDK
Quoters run openprop-quoter-sdk, a Rust crate: a reference quote engine with explicit parameters and a model hook, a hot-key signer that keeps the quote sequence in a local file, and a landing layer that sends each update down the paths you plug in — an adapter for BAM's Maker Priority Plugin, a Block Engine client or plain RPC; the reference quoter sends through RPC. See Quoting for the workflow.
Program
The program address, the pair's mints and the deployment's lookup table come from GET /v1/network and GET /v1/pair. Instruction layouts, account layouts, events and error codes are in the whitepaper's appendices.