API Reference
Full API reference for programatic integration with Fermi DEX
This document provides a detailed reference for integrating with the FermiHybrid Sequencer API, which enables interaction with a decentralized order book for Solana token markets.
Base URL
You can ping the following URLs (at the /healthendpoint), for figuring out which is your closest local sequencer for order placement/cancellation. Note that market related read ops can only be performed against the global sequencer.
Authentication
All endpoints that modify state (place/cancel orders) require cryptographic signatures to ensure the request originates from the owner of the key. See Signing Requirements section for details.
Market Operations
Create Market
Creates a new trading market for a pair of tokens.
Endpoint: POST /markets
Request Body:
{
"base_mint": "Base58EncodedPublicKey",
"quote_mint": "Base58EncodedPublicKey",
"name": "MARKET_NAME"
}Response:
{
"code": 201,
"message": "Market created successfully",
"data": {
"uuid": "market-uuid",
"base_mint": "Base58EncodedPublicKey",
"quote_mint": "Base58EncodedPublicKey",
"name": "MARKET_NAME",
"created_at": 1679489282
}
}List Markets
Retrieves all available markets.
Endpoint: GET /markets
Response:
{
"code": 200,
"message": "Markets retrieved successfully",
"data": [
{
"uuid": "market-uuid-1",
"base_mint": "Base58EncodedPublicKey",
"quote_mint": "Base58EncodedPublicKey",
"name": "SOL/USDC",
"created_at": 1679489282
},
{
"uuid": "market-uuid-2",
"base_mint": "Base58EncodedPublicKey",
"quote_mint": "Base58EncodedPublicKey",
"name": "BONK/USDC",
"created_at": 1679489282
}
]
}Get Orderbook
Retrieves the current orderbook for a specific market.
Endpoint: GET /markets/:market_id/orderbook
Parameters:
market_id(UUID) - The unique identifier of the market
Response:
{
"code": 200,
"message": "Orderbook retrieved successfully",
"data": {
"buys": [
{
"order_id": 123,
"owner": "Base58EncodedPublicKey",
"price": 50000000,
"quantity": 2000000000,
"side": "Buy",
"expiry": 1679489282,
"base_mint": "Base58EncodedPublicKey",
"quote_mint": "Base58EncodedPublicKey",
"market_id": "market-uuid"
}
],
"sells": [
{
"order_id": 124,
"owner": "Base58EncodedPublicKey",
"price": 51000000,
"quantity": 1000000000,
"side": "Sell",
"expiry": 1679489282,
"base_mint": "Base58EncodedPublicKey",
"quote_mint": "Base58EncodedPublicKey",
"market_id": "market-uuid"
}
]
}
}Get Trades
Retrieves recent trade history for a specific market.
Endpoint: GET /markets/:market_id/trades
Parameters:
market_id(UUID) - The unique identifier of the market
Response:
{
"code": 200,
"message": "Trade history retrieved successfully",
"data": [
{
"buyer_order_id": 123,
"seller_order_id": 456,
"buyer": "Base58EncodedPublicKey",
"seller": "Base58EncodedPublicKey",
"price": 50500000,
"quantity": 1000000000,
"timestamp": 1679489282
}
]
}Order Operations
Place Order
Places a new order in a market.
Endpoint: POST /orders
Request Body:
{
"intent": {
"order_id": 123,
"owner": "Base58EncodedPublicKey",
"side": "Buy",
"price": 50000000,
"quantity": 1000000000,
"expiry": 1679489282,
"market_id": "market-uuid"
},
"signature": [signature_bytes]
}The signature field must contain a valid ed25519 signature over the message derived from the order intent. See Order Placement Signingfor details.
Response:
{
"code": 200,
"message": "Order placed successfully",
"data": {
"order_id": 123,
"market_id": "market-uuid",
"status": "placed"
}
}Cancel Order
Cancels an existing order.
Endpoint: POST /orders/cancel
Request Body:
{
"order_id": 123,
"owner": "Base58EncodedPublicKey",
"market_id": "market-uuid",
"signature": "HexEncodedSignature"
}The signature field must contain a hex-encoded ed25519 signature over the message derived from the cancellation data. See Order Cancellation Signing for details.
Response:
{
"code": 200,
"message": "Order cancelled successfully",
"data": {
"order_id": 123,
"market_id": "market-uuid",
"status": "cancelled"
}
}Signing Requirements
Order Placement Signing
To place an order, you must create and sign a message using the following steps:
Create an
OrderIntentwith all order detailsSerialize the
OrderIntentusing Borsh serialization (not JSON)Create the signing message by:
Prepending the domain prefix
FRM_DEX_ORDER:Appending the Borsh-serialized order intent
Computing the SHA-256 hash of this combined data
Converting the hash to a hex string
Converting the hex string to UTF-8 bytes
Sign these UTF-8 bytes with an ed25519 private key
Include the signature in the request
Order Cancellation Signing
To cancel an order, you must create and sign a message using the following steps:
Create a
CancelOrderDatawith order ID, owner public key, and market IDSerialize using Borsh serialization
Create the signing message by:
Prepending the domain prefix
FRM_DEX_CANCEL:Appending the Borsh-serialized cancel data
Computing the SHA-256 hash of this combined data
Converting the hash to a hex string
Converting the hex string to UTF-8 bytes
Sign these UTF-8 bytes with an ed25519 private key
Convert the signature to a hex string
Include the hex-encoded signature in the request
Error Handling
All API responses follow a standard format:
{
"code": 400,
"message": "Error message",
"error": "Detailed error description"
}Common error codes:
400: Bad Request (invalid parameters, parsing errors)
401: Unauthorized (invalid signature)
404: Not Found (market or resource not found)
500: Internal Server Error
Receipt System
The sequencer provides cryptographic receipts for each processed order. These receipts can be used to verify that an order was received and processed by the sequencer.
OrderReceipt Structure
Copy
struct OrderReceipt {
order_id: u64,
owner: Pubkey,
timestamp_ms: u128,
sequencer_id: String,
merkle_root: [u8; 32],
sequencer_signature: [u8; 64],
}The receipt contains:
order_id: The unique identifier of the orderowner: The public key of the order ownertimestamp_ms: The precise millisecond timestamp when the order was processedsequencer_id: The identifier of the processing sequencermerkle_root: A cryptographic commitment to the state of the orderbook at the time of processingsequencer_signature: The sequencer's signature over the receipt data
Receipt Signing Format
The sequencer signs the receipt with the following message format:
Copy
ORDER_RECEIPT:{order_id}:{owner}:{timestamp_ms}:{sequencer_id}:{merkle_root_hex}Verifying a Receipt
To verify a receipt, reconstruct the signing message and verify the signature against the sequencer's public key:
Copy
use ed25519_dalek::{PublicKey, Signature, Verifier};
use hex;
// Reconstruct the message that was signed
let message = format!(
"ORDER_RECEIPT:{}:{}:{}:{}:{}",
receipt.order_id,
receipt.owner,
receipt.timestamp_ms,
receipt.sequencer_id,
hex::encode(receipt.merkle_root)
);
// Convert to bytes
let message_bytes = message.as_bytes();
// Parse the signature and sequencer's public key
let signature = Signature::from_bytes(&receipt.sequencer_signature).unwrap();
let sequencer_pubkey = PublicKey::from_bytes(&sequencer_public_bytes).unwrap();
// Verify the signature
let is_valid = sequencer_pubkey.verify(message_bytes, &signature).is_ok();Last updated