WebSocket API
Your strategy communicates with the node over a WebSocket connection at ws://localhost:9090. The node sends events, the strategy sends actions.
Connection and auth
Connect to ws://localhost:9090 and immediately send an auth message:
{"action": "auth", "token": "your_strategy_auth_token"}The node responds with either:
{
"event": "auth_ok",
"data": {
"nft_id": 42,
"trustee_address": "0xabcd...1234",
"payout_address": "0xef56...7890",
"markets": ["EMM/KAY", "KAY/TEE", "TEE/EMM"],
"token_decimals": 5,
"price_decimals": 8,
"contract_address": "0x79b2...94a9"
}
}or:
{"event": "auth_failed", "data": {"reason": "invalid token"}}If auth fails, the connection is closed. Your strategy auth token is in your config.json.
Events (node → strategy)
batch_start
Sent at the beginning of each batch cycle. Your strategy should respond with a commit action.
{
"event": "batch_start",
"data": {
"batch_id": 500,
"pool_id": 2,
"escrow": {"EMM": "3300.00000", "KAY": "2855.00000", "TEE": "3102.50000"},
"escrow_confirmed": {"EMM": "3300.00000", "KAY": "2855.00000", "TEE": "3102.50000"},
"wallet": {"EMM": "0.00000", "KAY": "44.50000", "TEE": "19.75000"},
"gas_balance": "1.50000000",
"mint_state": {
"state": "OPEN",
"hold_duration_secs": 259200,
"period_end": 1772900000,
"block_end": 0,
"has_pending_mint": false,
"pending_claimable_at": 0
},
"circulating": {"EMM": "150000.00000", "KAY": "148000.00000", "TEE": "152000.00000"},
"vault_locks": [],
"batch_params": {
"blocks_per_batch": 20,
"commits_per_batch": 3,
"num_pools": 4
},
"pending_settlements": [],
"peers_in_pool": 7,
"min_trade_quantity": "100000000",
"last_batch": {"batch_id": 499, "matches": 3, "volume": "1500.00000"}
}
}reveal_start
Sent when the reveal phase begins. Your strategy can optionally respond with a reveal action specifying which commits to reveal (default: all).
{"event": "reveal_start", "data": {"batch_id": 500, "my_commits": ["0xabc...", "0xdef..."]}}match_result
Sent after matching completes. Shows your fills for this batch. Note: unlike order submission, price and quantity here are raw canonical units (price x 1e8, quantity x 1e5). The price is the settlement midpoint, not your submitted limit. This example is a fill of 1,000 EMM at 0.05 KAY per EMM.
{
"event": "match_result",
"data": {
"batch_id": 500,
"matches": [
{
"pair": "EMM/KAY",
"side": "buy",
"price": "5000000",
"quantity": "100000000",
"counterparty_nft_id": 99
}
]
}
}settlement
Sent when a matched trade settles on-chain. price is the on-chain clearing price and quantity is the base-token amount, both in raw canonical units (price x 1e8, quantity x 1e5).
{
"event": "settlement",
"data": {
"batch_id": 500,
"match_hash": "0xabcd...",
"status": "confirmed",
"pair": "EMM/KAY",
"side": "buy",
"price": "5000000",
"quantity": "100000000"
}
}token_action_result
Sent after a token action (mint, burn, lock, unlock) completes.
{"event": "token_action_result", "data": {"action": "mint", "success": true, "message": "gas=450"}}{"event": "token_action_result", "data": {"action": "burn", "success": false, "message": "E_INSUFFICIENT_BALANCE"}}Actions (strategy → node)
auth
Must be the first message. See above.
commit
Respond to batch_start with orders:
{
"action": "commit",
"orders": [
{"pair": "EMM/KAY", "side": "buy", "price": "0.04990000", "quantity": "1000.00000"},
{"pair": "KAY/TEE", "side": "sell", "price": "0.05100000", "quantity": "1000.00000"}
]
}reveal
Respond to reveal_start. Usually you reveal all commits (the node does this by default), but you can selectively reveal:
{"action": "reveal", "reveal_indices": [0, 1]}mint
Request a token mint. Amounts are in raw units (5 decimal places: 100000 = 1 token). Amounts don't have to be equal — you can skew up to roughly 40/30/30 to top up whichever token is lowest in your escrow. The total must be divisible by 1000000 (10 tokens).
{"action": "mint", "m": 3600000, "k": 3200000, "t": 3200000}This mints 36 EMM, 32 KAY, and 32 TEE (100 tokens total, weighted towards EMM).
claim_mint
Claim a pending mint after the hold period expires.
{"action": "claim_mint"}burn
Burn equal amounts of all three tokens, receiving SUPRA back to your trustee address (gas recovery). Also accepts "burn_from_escrow" as the action name.
{"action": "burn", "amount": 10000000}burn_for_profit
Same as burn, but SUPRA goes to your payout address (profit distribution). DMKT14: was burn_to_beneficiary.
{"action": "burn_for_profit", "amount": 10000000}lock
Lock tokens in the vault for a duration.
{"action": "lock", "symbol": "EMM", "amount": 50000000, "duration_secs": 86400}unlock
Unlock tokens after the lock period expires.
{"action": "unlock", "index": 2}donate_dust
Gift sub-minimum token amounts to another player's escrow. Amount must be less than the minimum trade quantity.
{"action": "donate_dust", "recipient_nft_id": 5, "symbol": "KAY", "amount": 50000}Timing
The node waits 3 seconds for your strategy to respond to batch_start with a commit. If no response arrives, the node skips this batch (no orders placed).
Token actions (mint, burn, lock, unlock) are processed asynchronously — you can send them anytime, not just during the commit window. Results arrive via token_action_result events.