Wallet-authenticated API · v1
Ignite Authenticated Trading API
Connect an EVM wallet, create a short-lived Ignite session, read the wallet's account state, and place or cancel orders. Standard wallets use EIP-712; Thanos Wallet uses its published SIWE personal_sign flow. Authentication proves wallet control; Ignite never requests a private key or seed phrase.
https://api.ignite.tradeAuthentication flow
Send the wallet address. The challenge is valid for five minutes and replaces any earlier challenge for that address.
Sign the returned typedData object as EIP-712 data. Do not sign the human-readable challenge hint.
Send the address and signature. A valid, unused challenge returns an eight-hour bearer session.
Send Authorization: Bearer <token>. Responses are always scoped to the authenticated wallet.
Request a wallet challenge
POST /v1/auth/challengeThe EIP-712 domain intentionally has no chain ID, so the login is not tied to the wallet's currently selected network.
curl -X POST https://api.ignite.trade/v1/auth/challenge \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_WALLET"}'
{
"typedData": {
"domain": { "name": "Ignite DEX", "version": "1" },
"types": { "Login": [
{ "name": "address", "type": "address" },
{ "name": "nonce", "type": "string" },
{ "name": "issuedAt", "type": "string" }
]},
"primaryType": "Login",
"message": {
"address": "0xYOUR_WALLET",
"nonce": "single-use-random-value",
"issuedAt": "2026-07-27T12:00:00.000Z"
}
},
"expiresIn": "5m"
}Verify and create a session
POST /v1/auth/verify// viem example
const challenge = await fetch('https://api.ignite.trade/v1/auth/challenge', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ address: account.address })
}).then((response) => response.json());
const signature = await walletClient.signTypedData({
account,
...challenge.typedData
});
const session = await fetch('https://api.ignite.trade/v1/auth/verify', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ address: account.address, signature })
}).then((response) => response.json());
// { "verified": true, "token": "<session JWT>" }Thanos Wallet SIWE compatibility
GET + POST /api/auth/nonce · /api/auth/verifyThanos Wallet signs an EIP-4361 SIWE message with personal_sign. Request a nonce for the wallet, build the SIWE message with the current Ignite domain and URI, sign that exact message, then verify it. The returned sessionToken is the same eight-hour bearer credential used by all protected routes.
const nonce = await fetch(
'https://api.ignite.trade/api/auth/nonce?address=' + account.address
).then((response) => response.text());
// Use thanos-connect's buildSiweMessage() so the signed bytes match.
const message = buildSiweMessage({
domain: window.location.host,
address: account.address,
uri: window.location.origin,
statement: 'Sign in to Ignite DEX with your Thanos Wallet.',
chainId,
nonce,
expirationTime: new Date(Date.now() + 5 * 60_000).toISOString()
});
const signature = await walletClient.signMessage({ account, message });
const { sessionToken } = await fetch('https://api.ignite.trade/api/auth/verify', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ address: account.address, message, signature })
}).then((response) => response.json());Authoritative market rules
Read GET /v1/markets before submitting an order. Each market record is authoritative for symbol, type, status, tradingEnabled, feeBps, tickSize, minOrderSize, maxOrderSize, token symbols, and network ID.
Balances and positions
GET /v1/portfolio/{address}Returns equity, free collateral, balances and positions for the authenticated wallet only. The path address must match the bearer-token subject; another wallet is rejected.
curl https://api.ignite.trade/v1/portfolio/0xYOUR_WALLET \
-H "Authorization: Bearer $IGNITE_TOKEN"Place an order
POST /v1/orderscurl -X POST https://api.ignite.trade/v1/orders \
-H "Authorization: Bearer $IGNITE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"market": "LITHO/USDT",
"side": "buy",
"type": "limit",
"price": 8.70,
"size": 1,
"clientOrderId": "strategy-a-000001",
"timeInForce": "GTC",
"postOnly": false,
"reduceOnly": false
}'| Field | Accepted values | Rule |
|---|---|---|
| market | Published market symbol | Required; must be active and trading-enabled. |
| side | buy | sell | Required. Market-specific restrictions still apply. |
| type | limit | market | Required. Limit orders should include price. |
| price | Positive number | Must align to tickSize when the market publishes one. |
| size | Positive number | Required except quote-denominated market buys; min/max rules apply. |
| quoteAmount | Positive number | Only for market buys; cannot be combined with size. |
| clientOrderId | 1–128 characters | Recommended account-scoped idempotency key. A retry returns the original result. |
| timeInForce | GTC | IOC | FOK | Defaults to GTC. Market orders terminate any unfilled remainder. |
| postOnly | boolean | Rejects an order that would immediately take liquidity. |
| reduceOnly | boolean | Relevant only to supported position markets; cannot increase or flip a position. |
| account | Wallet address | Optional; if supplied it must equal the authenticated wallet. |
List wallet orders
GET /v1/ordersReturns only orders belonging to the authenticated wallet, including open and terminal states.
curl https://api.ignite.trade/v1/orders \
-H "Authorization: Bearer $IGNITE_TOKEN"Cancel an order
DELETE /v1/orders/{orderId}Only the authenticated owner can cancel a live order. Filled, rejected, expired, failed, or already-cancelled orders cannot be cancelled.
curl -X DELETE https://api.ignite.trade/v1/orders/ORDER_ID \
-H "Authorization: Bearer $IGNITE_TOKEN"Wallet fills
GET /v1/trades?market={symbol}&limit=100Returns fills where the authenticated wallet was maker or taker. The optional limit is clamped to 1–500 and the optional market filter uses the published market symbol.
Responses and integration safety
Malformed input, invalid signature, market rule failure, insufficient balance, or an order that cannot be accepted.
Missing, invalid, or expired bearer token. Request a new challenge and session; do not retry with the same expired token.
The requested account or object does not belong to the authenticated wallet.
Unknown market or resource. Refresh the market list before retrying.
Account state requires a current action, such as accepting a new terms version.
Honor RateLimit headers and retry only after the published reset time with exponential backoff.
Admin, custody-operator, RPC credentials, internal service routes, and automation-signer details are intentionally outside this public integration contract.

