Pred Orders API
Order placement, cancellation, and management endpoints. ## EIP-712 order signature All orders must be signed using EIP-712. Format: `0x` (132 hex characters), low-s normalized. **Domain (HAS version field):** `chainId` is ENV-specific. `verifyingContract` must come from market discovery for the specific parent market. ``` EIP712Domain type: "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" name: "Pred CTF Exchange" version: "1" chainId: verifyingContract: ``` **Order contract source (MANDATORY):** Use `parent_market_data.contract_address` from market discovery for the target parent market. Do not assume one static contract per environment; markets can have different order contract addresses. **Order type (FIELD ORDER IS CRITICAL):** ``` "Order(uint256 salt,address maker,address signer,address taker,uint256 price,uint256 quantity,uint256 expiration,uint256 nonce,bytes32 questionId,uint256 feeRateBps,uint8 intent,uint8 signatureType)" ``` **Field meanings:** - `salt`: `"02"` + 10-digit random number (e.g. `"020123456789"`); stringified integer - `maker`: proxy wallet address (from login `proxy_wallet_addr`) - `signer`: EOA wallet address - `taker`: `0x0000000000000000000000000000000000000000` (always zero) - `price`: wei-scaled = `(priceCents / 100) * 1e6` (e.g. 55 cents → 550000; not `55 * 1e6`) - `quantity`: wei-scaled = `quantity * 1e6` (e.g. 100 shares → 100000000) - `expiration`: Unix seconds; `0` = GTC - `nonce`: `0` (always) - `questionId`: market ID as bytes32; left-pad with zeros if hex < 64 chars - `feeRateBps`: `0` (default) - `intent`: LONG = `0`, SHORT = `1` (uint8) - `signatureType`: `2` (always; uint8) ## Cross-matching Cross-matching applies only **across child markets of the same parent market** (e.g. a parent with 3-outcome markets: Team A, Team B, Draw). It is enabled when the parent is configured for it. **When it applies:** A key validity condition — **Long orders summing to 100c across all markets of a cross-match–enabled parent form a valid match** (e.g. Long 25 in A + Long 25 in B + Long 50 in C = 100c). **How it works:** Orders match across child markets by combining liquidity from peer (sibling) markets into synthetic bid/ask levels. For a given child market, synthetic *Short* levels are derived from *Long* orders in peer child markets (e.g. Long 25 in B + Long 25 in C + Long 25 in D → synthetic Short at 75 for market A). An incoming Long order in A can match against these synthetic Short levels; execution is against the underlying peer Long orders. Similarly, synthetic *Long* levels can be built from *Short* orders in peer child markets; an incoming Short order can match against them. **Self-match:** Self-match is **allowed** when cross-matching is involved: the same user can match against their own liquidity **across different child markets within the same parent**. For example, your Long orders in two outcomes can provide synthetic liquidity that your Short order in the third outcome matches against. This is intentional and valid for cross-match–enabled parents. Self-match *within* the same market may be restricted; self-match *across* markets in the same parent is allowed. **Implications for API users:** - Orderbook responses may include synthetic levels; orderbook metadata can indicate `cross_matching_enabled` (e.g. in WebSocket orderbook payloads). - Placing Long orders in multiple child markets can create combined liquidity (e.g. summing to 100c Long across the parent's markets is a valid match). A Short order in another child market may match—including self-match—against that liquidity. - 422 / validation may still apply for other liquidity or validation reasons. **Example:** Long 25 in markets B, C, D → synthetic Short 75 for market A; or Long 25+25+50 across A, B, C = 100c valid match. ## Units - `price`: **cents** (e.g. 55.0 = $0.55) - `quantity`: **shares** - `amount`: **USD** - `fee_rate_bps`: **basis points** (default 0) - `timestamp`: **Unix seconds** (in place order payload; within 15s of server time)