Ga naar hoofdinhoud

Trading API

The MonoHub Trading API is a REST + WebSocket API for order management, trade execution, and real-time market data. It uses JWT-based wallet authentication via EIP-191 signatures.

Base URL: https://api.monohub.xyz

Authentication

All authenticated endpoints require either a JWT token or an API key. The authentication flow uses EIP-191 wallet signatures to prove ownership of an Ethereum address.

Step 1: Request a Signing Message

POST /api/v1/auth/message

Returns a timestamped message for the wallet to sign. The message must be signed within 5 minutes.

Response:

{
"message": "MonoHub API Access: 1706140800000",
"timestamp": 1706140800000,
"expiresIn": 300000
}

Step 2: Exchange Signature for JWT

POST /api/v1/auth/token

Submit the signed message to receive a JWT token valid for 24 hours.

Request body:

{
"address": "0xYourWalletAddress",
"message": "MonoHub API Access: 1706140800000",
"signature": "0x...",
"chainId": 262146
}

Response:

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": "24h"
}

Step 3: Create an API Key (Optional)

POST /api/v1/auth/api-key

Requires authentication. Creates a long-lived API key for programmatic access. API keys carry specific permissions and do not expire, but can be revoked.

Headers: Authorization: Bearer <jwt_token>

Request body:

{
"permissions": ["read", "trade"]
}

Response:

{
"apiKey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"permissions": ["read", "trade"],
"warning": "Store this key securely. It will not be shown again."
}

Using Credentials

For JWT tokens, include the header:

Authorization: Bearer <token>

For API keys, include the header:

Authorization: ApiKey <api_key>

Get Current User

GET /api/v1/auth/me

Returns the authenticated user's address, chain, tier, and whether the request uses an API key.

Response:

{
"address": "0xabc...",
"chainId": 262146,
"tier": "free",
"isApiKey": false
}

Public Endpoints

These endpoints do not require authentication.

List Markets

GET /api/v1/markets?chain_id=262146

Returns all trading pairs for the specified chain. Defaults to Sprintnet (chain ID 262146) if omitted.

Response:

{
"markets": [
{
"pair": "0xPairAddress",
"baseToken": "0xToken0Address",
"quoteToken": "0xToken1Address",
"baseSymbol": "TOKEN",
"quoteSymbol": "WLYTH",
"lastPrice": "0.00123",
"volume24h": "45000",
"priceChange24h": "0.05",
"chainId": 262146
}
],
"chain": "Sprintnet"
}

Try It

Query live market data directly:

List Markets

Fetch all trading pairs on a chain.

Market Detail

GET /api/v1/markets/:pair?chain_id=262146

Returns detailed information for a specific market pair, including reserves, transaction count, and price data.

Response:

{
"pair": "0xPairAddress",
"baseToken": "0xToken0",
"quoteToken": "0xToken1",
"baseSymbol": "TOKEN",
"quoteSymbol": "WLYTH",
"reserve0": "1000000",
"reserve1": "500000",
"lastPrice": "0.5",
"volume24h": "45000",
"priceChange24h": "0.05",
"txCount24h": 120,
"chainId": 262146
}

Recent Trades

GET /api/v1/markets/:pair/trades?chain_id=262146&limit=50

Returns the most recent trades for a pair. The limit parameter accepts values up to 100 (default: 50).

Response:

{
"trades": [
{
"txHash": "0x...",
"timestamp": "2025-01-25T12:00:00Z",
"side": "buy",
"price": "0.00123",
"amount": "1000",
"quoteAmount": "1.23",
"maker": "0xSenderAddress"
}
]
}

OHLCV Candles

GET /api/v1/markets/:pair/candles?chain_id=262146&interval=1h&from=1706140800&to=1706227200

Returns OHLCV candlestick data for charting. The interval parameter accepts standard values such as 1m, 5m, 15m, 1h, 4h, 1d.

Response:

{
"candles": [
{
"timestamp": "2025-01-25T12:00:00Z",
"open": "0.00120",
"high": "0.00130",
"low": "0.00118",
"close": "0.00125",
"volume": "50000",
"quoteVolume": "62.5",
"trades": 45
}
]
}

Orderbook

GET /api/v1/markets/:pair/orderbook?chain_id=262146

Returns a simulated orderbook derived from the AMM constant-product bonding curve. The orderbook shows 10 levels of depth on each side at 0.5% price intervals.

Response:

{
"bids": [
["0.00124500", "500.000000"],
["0.00124000", "1000.000000"]
],
"asks": [
["0.00125500", "500.000000"],
["0.00126000", "1000.000000"]
],
"timestamp": 1706140800000
}

Authenticated Endpoints

All endpoints below require a valid JWT token or API key with read permission.

Account Overview

GET /api/v1/account

Returns the authenticated wallet's portfolio overview, including native token balance and tier.

Response:

{
"address": "0xYourAddress",
"chainId": 262146,
"chain": "Sprintnet",
"nativeBalance": "1.5",
"tier": "free"
}

Token Balances

GET /api/v1/account/balances?tokens=0xToken1,0xToken2

Returns ERC-20 token balances for the authenticated wallet. Pass a comma-separated list of token contract addresses.

Response:

{
"balances": [
{
"token": "0xToken1",
"symbol": "TOKEN",
"decimals": 18,
"balance": "1000000000000000000",
"formatted": "1.000000"
}
]
}

Trade History

GET /api/v1/account/history

Returns the authenticated wallet's trade history.

Response:

{
"trades": [],
"pagination": { "page": 1, "pageSize": 50, "total": 0 }
}

List API Keys

GET /api/v1/account/api-keys

Returns metadata for the authenticated wallet's API keys (key values are not included).

Revoke API Key

DELETE /api/v1/account/api-keys/:keyId

Revokes a specific API key by its ID.


Trading Endpoints

All trading endpoints require authentication with trade permission. JWT tokens have full access. API keys must include the trade permission.

Get Quote

POST /api/v1/orders/quote

Returns a price quote for a swap, including price impact and fee estimates. Quotes are valid for 30 seconds.

Request body:

{
"pair": "0xPairAddress",
"side": "buy",
"amount": "1000000000000000000"
}

Response:

{
"pair": "0xPairAddress",
"side": "buy",
"amountIn": "1000000000000000000",
"amountOut": "800000000000000000",
"price": "0.8",
"priceImpact": "0.05",
"fee": "0.003",
"route": ["0xPairAddress"],
"validFor": 30
}

Place Order

POST /api/v1/orders

Creates an order (swap). The API returns unsigned transaction data that the caller must sign and broadcast.

Request body:

{
"pair": "0xPairAddress",
"side": "buy",
"amount": "1000000000000000000",
"minReceived": "790000000000000000"
}

Response:

{
"orderId": "ord_1706140800000_abc12345",
"status": "pending_signature",
"pair": "0xPairAddress",
"side": "buy",
"amount": "1000000000000000000",
"minReceived": "790000000000000000",
"message": "Order created. Sign transaction in your wallet to execute.",
"tx": {
"to": "0xRouterAddress",
"data": "0x...",
"value": "1000000000000000000"
}
}

List Orders

GET /api/v1/orders

Returns pending orders for the authenticated wallet.

Get Order Status

GET /api/v1/orders/:orderId

Returns the status of a specific order.

Cancel Order

DELETE /api/v1/orders/:orderId

Cancels a pending order that has not yet been executed on-chain.


WebSocket API

The WebSocket endpoint provides real-time streaming data for trades, tickers, orderbook updates, and authenticated user events.

Connection

wss://api.monohub.xyz/api/v1/stream

On connection, the server sends a welcome message listing available channels:

{
"type": "welcome",
"message": "Connected to MonoHub WebSocket API",
"channels": ["trades", "orderbook", "candles", "ticker"],
"userChannels": ["orders", "fills", "positions"]
}

Authentication

To access user channels (orders, fills, positions), send an auth message after connecting:

{ "type": "auth", "token": "eyJhbGciOiJIUzI1NiI..." }

Or with an API key:

{ "type": "auth", "apiKey": "eyJhbGciOiJIUzI1NiI..." }

On success:

{ "type": "authenticated", "address": "0xYourAddress" }

Subscribing to Channels

Public channels (no auth required):

{ "type": "subscribe", "channel": "trades", "market": "0xPairAddress" }
{ "type": "subscribe", "channel": "orderbook", "market": "0xPairAddress" }
{ "type": "subscribe", "channel": "candles", "market": "0xPairAddress", "interval": "1h" }
{ "type": "subscribe", "channel": "ticker", "market": "0xPairAddress" }

User channels (auth required):

{ "type": "subscribe", "channel": "orders" }
{ "type": "subscribe", "channel": "fills" }
{ "type": "subscribe", "channel": "positions" }

Unsubscribing

{ "type": "unsubscribe", "channel": "trades", "market": "0xPairAddress" }

Heartbeat

Send periodic pings to keep the connection alive:

{ "type": "ping" }

Response:

{ "type": "pong", "timestamp": 1706140800000 }

Data Messages

All data arrives as messages with type: "data" and a channel field:

{
"type": "data",
"channel": "trades:0xPairAddress",
"trades": [
{
"txHash": "0x...",
"price": "0.00125",
"amount": "500",
"side": "buy",
"timestamp": "2025-01-25T12:00:00Z"
}
]
}
{
"type": "data",
"channel": "ticker:0xPairAddress",
"ticker": {
"pair": "0xPairAddress",
"lastPrice": "0.00125",
"volume24h": "45000",
"priceChange24h": "0.05"
}
}

Polling intervals: trades update every 2 seconds; tickers update every 5 seconds.


Rate Limits

Rate limits are applied per IP address on a 1-minute rolling window.

TierRequests per Minute
Free60
Basic300
Pro1,200

When the limit is exceeded, the API returns HTTP 429 with standard RateLimit-* headers.


Supported Chains

The API currently supports the following chains:

Chain IDNameStatus
262146SprintnetTestnet
43113Avalanche FujiTestnet
59141Linea SepoliaTestnet

Pass ?chain_id=<id> on any market endpoint to query a specific chain. Defaults to 262146 (Sprintnet).


Code Examples

JavaScript (fetch)

// Step 1: Get auth message
const msgRes = await fetch("https://api.monohub.xyz/api/v1/auth/message", {
method: "POST",
});
const { message } = await msgRes.json();

// Step 2: Sign with wallet (ethers.js example)
const signature = await signer.signMessage(message);

// Step 3: Get JWT
const authRes = await fetch("https://api.monohub.xyz/api/v1/auth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
address: await signer.getAddress(),
message,
signature,
chainId: 262146,
}),
});
const { token } = await authRes.json();

// Step 4: Use authenticated endpoints
const accountRes = await fetch("https://api.monohub.xyz/api/v1/account", {
headers: { Authorization: `Bearer ${token}` },
});
const account = await accountRes.json();

cURL

# Get auth message
curl -X POST https://api.monohub.xyz/api/v1/auth/message

# List markets on Sprintnet
curl https://api.monohub.xyz/api/v1/markets?chain_id=262146

# Get trades for a pair
curl "https://api.monohub.xyz/api/v1/markets/0xPairAddress/trades?limit=20&chain_id=262146"

# Authenticated request (replace YOUR_TOKEN)
curl -H "Authorization: Bearer YOUR_TOKEN" https://api.monohub.xyz/api/v1/account

# Get a quote (authenticated)
curl -X POST https://api.monohub.xyz/api/v1/orders/quote \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"pair":"0xPairAddress","side":"buy","amount":"1000000000000000000"}'

WebSocket (JavaScript)

const ws = new WebSocket("wss://api.monohub.xyz/api/v1/stream");

ws.onopen = () => {
// Authenticate (optional, for user channels)
ws.send(JSON.stringify({ type: "auth", token: "YOUR_TOKEN" }));

// Subscribe to trade feed
ws.send(JSON.stringify({
type: "subscribe",
channel: "trades",
market: "0xPairAddress",
}));
};

ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "data") {
console.log(`[${msg.channel}]`, msg);
}
};