### Install SDK with pnpm, npm, or yarn Source: https://developer.probable.markets/api/typescript-sdk/installation Choose the command corresponding to your package manager to install the SDK. ```bash # pnpm pnpm add @prob/clob # npm npm install @prob/clob # yarn yarn add @prob/clob ``` -------------------------------- ### Install Dependencies Source: https://developer.probable.markets/api/orderbook-api/token-approvals Install Viem and Safe Protocol Kit using npm. ```bash npm install viem @safe-global/protocol-kit ``` -------------------------------- ### Complete JavaScript Example for Probable Markets API Source: https://developer.probable.markets/api/orderbook-api/getting-started This example demonstrates the entire process of interacting with the Probable Markets API. It includes steps for obtaining a nonce, signing messages, logging in, generating API keys, and placing an order. Ensure you have the necessary libraries like 'axios' and 'ethers.js' installed, and replace placeholder values with your actual credentials and addresses. ```javascript import crypto from 'crypto'; import axios from 'axios'; const BASE_URL = 'https://api.probable.markets'; const eoaAddress = '0x...'; // Your EOA address const proxyWalletAddress = await getOrCreateProxyWallet(eoaAddress); // Get or create proxy wallet const chainId = 56; // Step 1: Get nonce const { data: nonceData } = await axios.get(`${BASE_URL}/public/api/v1/auth/nonce`); const nonce = nonceData.nonce; // Step 2: Sign with wallet (using ethers.js) const signature = await signer._signTypedData(domain, types, message); // Step 3: Login (use EOA address for authentication) await axios.post(`${BASE_URL}/public/api/v1/auth/login`, { identity: { account: eoaAddress, namespace: 'default', chainId: '56', address: eoaAddress }, message: 'Sign in to Prob...', signature, nonce, issuedAt: new Date().toISOString(), domain: 'prob.vbgf.cc' }); // Step 4: Generate API key (with L1 headers) const timestamp = Math.floor(Date.now() / 1000).toString(); const { data: apiKeyData } = await axios.post( `${BASE_URL}/public/api/v1/auth/api-key/${chainId}`, {}, { headers: { prob_address: eoaAddress, // Use EOA address for authentication prob_signature: signature, prob_timestamp: timestamp, prob_nonce: nonce } } ); const { apiKey, secret, passphrase } = apiKeyData; // Step 5: Create L2 signature function function createL2Signature(timestamp, method, path, body, secret, passphrase) { const message = `${timestamp}${method}${path}${body ? JSON.stringify(body) : ''}`; return crypto.createHmac('sha256', secret).update(message).digest('hex'); } // Step 6: Place order (with L2 headers) const orderData = { deferExec: false, order: { /* order details */ maker: proxyWalletAddress, // Use proxy wallet address signer: eoaAddress, // Use EOA address (signs the order) // ... other order fields }, owner: proxyWalletAddress, // Use proxy wallet address orderType: 'GTC' }; const orderTimestamp = Math.floor(Date.now() / 1000).toString(); const orderPath = `/public/api/v1/order/${chainId}`; const orderSignature = createL2Signature( orderTimestamp, 'POST', orderPath, orderData, secret, passphrase ); const { data: orderResponse } = await axios.post( `${BASE_URL}${orderPath}`, orderData, { headers: { 'Content-Type': 'application/json', prob_address: eoaAddress, // Use EOA address for authentication prob_signature: orderSignature, prob_timestamp: orderTimestamp, prob_api_key: apiKey, prob_passphrase: passphrase } } ); console.log('Order placed:', orderResponse); ``` -------------------------------- ### Get Open Orders Response Example Source: https://developer.probable.markets/api/orderbook-api/orders Example JSON response structure for retrieving open orders, including order details and pagination information. ```json { "orders": [ { "orderId": 12345, "symbol": "BTC-USD", "side": "BUY", "status": "NEW", "...": "..." } ], "pagination": { "page": 1, "limit": 20, "total": 50 } } ``` -------------------------------- ### Get Order Example Request Source: https://developer.probable.markets/api/orderbook-api/orders Example cURL command to retrieve order details. This request requires the chain ID, order ID, and a token ID, along with L2 authentication headers. ```bash curl "https://api.probable.markets/public/api/v1/orders/56/12345?tokenId=0xabc123..." \ -H "prob_address: 0xEOA_ADDRESS..." \ -H "prob_signature: 0xabc123..." \ -H "prob_timestamp: 1705312200" \ -H "prob_api_key: pk_live_abc123xyz" \ -H "prob_passphrase: my-passphrase" ``` -------------------------------- ### Install Viem Dependency Source: https://developer.probable.markets/api/orderbook-api/proxy-wallet Install the Viem library, which is required for interacting with the blockchain. ```bash npm install viem ``` -------------------------------- ### Place Order Example Request Source: https://developer.probable.markets/api/orderbook-api/orders Example cURL command for placing an order. This includes all necessary headers for L2 authentication and the order details in the request body. ```bash curl -X POST "https://api.probable.markets/public/api/v1/order/56" \ -H "Content-Type: application/json" \ -H "prob_address: 0xEOA_ADDRESS..." \ -H "prob_signature: 0xabc123..." \ -H "prob_timestamp: 1705312200" \ -H "prob_api_key: pk_live_abc123xyz" \ -H "prob_passphrase: my-passphrase" \ -d '{ "deferExec": true, "order": { "salt": "1234567890", "maker": "0xPROXY_WALLET...", "signer": "0xEOA_ADDRESS...", "taker": "0x0000...", "tokenId": "0xabc123...", "makerAmount": "1000000000000000000", "takerAmount": "500000000000000000", "side": "BUY", "expiration": "1735689600", "nonce": "0", "feeRateBps": "175", "signatureType": 0, "signature": "0xdef456..." }, "owner": "0xPROXY_WALLET...", "orderType": "GTC" }' ``` -------------------------------- ### Get Current Price Response Source: https://developer.probable.markets/api/orderbook-api/orderbook Example response structure for a single token price query. ```json { "price": "0.65" } ``` -------------------------------- ### Place Order Example Response Source: https://developer.probable.markets/api/orderbook-api/orders Example response received after successfully placing an order. It includes details about the created order such as its ID, status, and quantities. ```json { "orderId": 12345, "clientOrderId": "my-order-123", "symbol": "BTC-USD", "side": "BUY", "type": "LIMIT", "timeInForce": "GTC", "price": "0.5", "origQty": "1.0", "executedQty": "0.0", "cumQuote": "0.0", "status": "NEW", "time": 1705312200000, "updateTime": 1705312200000, "avgPrice": "0.0", "origType": "LIMIT", "tokenId": "0xabc123...", "ctfTokenId": "0xabc123...", "stopPrice": "0.0", "orderListId": -1, "cumQty": "0.0" } ``` -------------------------------- ### Get Midpoint Price Response Source: https://developer.probable.markets/api/orderbook-api/orderbook Example response for the midpoint price query, showing the calculated midpoint value. ```json { "mid": "0.625" } ``` -------------------------------- ### Setup Viem Clients Source: https://developer.probable.markets/api/orderbook-api/token-approvals Set up Viem clients for BSC mainnet, including wallet and public clients, and an account. ```typescript import { createWalletClient, createPublicClient, http, custom } from 'viem'; import { bsc } from 'viem/chains'; import { privateKeyToAccount } from 'viem/accounts'; import Safe, { MetaTransactionData, OperationType } from '@safe-global/protocol-kit'; // Setup account and clients const account = privateKeyToAccount('0x...' as `0x${string}`); const eoaAddress = account.address; const publicClient = createPublicClient({ chain: bsc, transport: http(), }); const walletClient = createWalletClient({ account, chain: bsc, transport: http(), }); // Get proxy wallet address (from previous step) const proxyWalletAddress = await computeProxyAddress(eoaAddress); ``` -------------------------------- ### Standard Search Response Example Source: https://developer.probable.markets/api/market-public/search An example of a typical response from the search API, including event details, associated tags, and pagination information. Markets are nested within events. ```json { "events": [ { "id": 123, "slug": "btc-usd-2025-11", "title": "Bitcoin Price Prediction", "markets": [ { "id": 456, "question": "Will BTC exceed $100k?", "market_slug": "btc-100k" } ] } ], "tags": [ { "id": 1, "label": "Crypto", "slug": "crypto" } ], "pagination": { "hasMore": true, "totalResults": 50, "page": 1, "limit": 20, "totalPages": 3, "hasPrevPage": false } } ``` -------------------------------- ### Setup Viem Wallet Client (Node.js) Source: https://developer.probable.markets/api/orderbook-api/proxy-wallet Create a Viem wallet client for Node.js environments using a private key to sign transactions. ```typescript import { privateKeyToAccount } from 'viem/accounts'; const account = privateKeyToAccount('0x...' as `0x${string}`); const walletClient = createWalletClient({ account, chain: bsc, transport: http(), }); ``` -------------------------------- ### Setup Viem Public Client Source: https://developer.probable.markets/api/orderbook-api/proxy-wallet Initialize a Viem public client to interact with the blockchain for read-only operations, connected to the BSC chain. ```typescript import { createPublicClient } from 'viem'; const publicClient = createPublicClient({ chain: bsc, transport: http(), }); ``` -------------------------------- ### Optimized Search Response Example Source: https://developer.probable.markets/api/market-public/search An example of a response when the 'optimized=true' parameter is used. This response omits the nested 'markets' array for events, providing a more lightweight payload. ```json { "events": [ { "id": 123, "slug": "btc-usd-2025-11", "title": "Bitcoin Price Prediction" // markets array is empty } ], "tags": [...], "pagination": {...} } ``` -------------------------------- ### Logout Response Source: https://developer.probable.markets/api/orderbook-api/authentication Example response indicating a successful logout. ```json { "success": true } ``` -------------------------------- ### Example Tags Response Source: https://developer.probable.markets/api/market-public/tags Shows the structure of a successful response when listing tags, including tag details and pagination information. ```json { "tags": [ { "id": 1, "label": "Sports", "slug": "sports" }, { "id": 2, "label": "Crypto", "slug": "crypto" }, { "id": 3, "label": "Politics", "slug": "politics" } ], "pagination": { "page": 1, "limit": 20, "totalResults": 150, "totalPages": 8, "hasMore": true, "hasPrevPage": false } } ``` -------------------------------- ### Verify L1 Headers Response Source: https://developer.probable.markets/api/orderbook-api/authentication Example response after verifying L1 authentication headers, indicating validity and returning user details. ```json { "valid": true, "address": "0x1234...", "chainId": 56, "message": "Verification successful" } ``` -------------------------------- ### Get Price Source: https://developer.probable.markets/api/orderbook-api/orderbook Retrieves the current price for a specific token, either for buying or selling. ```APIDOC ## GET /public/api/v1/price ### Description Get the current price for a specific token. ### Method GET ### Endpoint /public/api/v1/price ### Parameters #### Query Parameters - **token_id** (string) - Required - CTF token ID - **side** (string) - Required - "BUY" or "SELL" ### Request Example ```bash curl "https://api.probable.markets/public/api/v1/price?token_id=0xabc123...&side=BUY" ``` ### Response #### Success Response (200) - **price** (string) - The current price of the token. #### Response Example ```json { "price": "0.65" } ``` ``` -------------------------------- ### Get Order Book for a Token (cURL) Source: https://developer.probable.markets/api/orderbook-api/orderbook Fetch the complete order book, including both bids and asks, for a specified token ID. ```bash curl "https://api.probable.markets/public/api/v1/book?token_id=0xabc123..." ``` -------------------------------- ### Get Event by Slug Source: https://developer.probable.markets/api/market-public/events Retrieve a specific event and its associated markets using the event's URL-friendly slug. Caching is applied for 2 minutes. ```bash curl "https://market-api.probable.markets/public/api/v1/events/slug/btc-usd-2025-11" ``` -------------------------------- ### Get Prices Response Source: https://developer.probable.markets/api/orderbook-api/orderbook The response contains prices for each requested token, organized by token ID and side. ```json { "0xabc123...": { "BUY": "0.65", "SELL": "0.60" }, "0xdef456...": { "BUY": "0.45", "SELL": "0.40" } } ``` -------------------------------- ### Setup Viem Wallet Client (Browser) Source: https://developer.probable.markets/api/orderbook-api/proxy-wallet Create a Viem wallet client connected to the BSC chain for browser environments, utilizing MetaMask or similar injected providers. ```typescript import { createWalletClient, http, custom } from 'viem'; import { bsc } from 'viem/chains'; // For browser environments (MetaMask, etc.) const walletClient = createWalletClient({ chain: bsc, transport: custom(window.ethereum), }); ``` -------------------------------- ### GET /public/api/v1/trades Source: https://developer.probable.markets/api/orderbook-api/trades Get public trade history. No authentication required. ```APIDOC ## GET /public/api/v1/trades ### Description Get public trade history (no authentication required). ### Method GET ### Endpoint `/public/api/v1/trades` ### Parameters #### Query Parameters - **user** (string) - Optional - User Profile Address (0x-prefixed, 40 hex chars) - **limit** (number) - Optional - Maximum number of trades to return (default: 100) - **offset** (number) - Optional - Offset for pagination (default: 0) - **takerOnly** (boolean) - Optional - Filter to taker trades only (default: true) - **filterType** (string) - Optional - Filter type: "CASH" or "TOKENS" (must be provided with filterAmount) - **filterAmount** (number) - Optional - Filter amount (must be provided with filterType) - **market** (string or array) - Optional - Comma-separated list of condition IDs. Mutually exclusive with eventId - **eventId** (string or array) - Optional - Comma-separated list of event IDs. Mutually exclusive with market - **side** (string) - Optional - Trade side: "BUY" or "SELL" ### Request Example ```curl https://api.probable.markets/public/api/v1/trades?user=0x1234...&limit=50&side=BUY ``` ### Response #### Success Response (200) - **(array)** - List of public trades - **proxyWallet** (string) - Proxy wallet address - **side** (string) - Trade side (BUY or SELL) - **asset** (string) - Asset traded - **conditionId** (string) - Condition ID - **size** (number) - Trade size - **price** (number) - Trade price - **timestamp** (number) - Timestamp of the trade - **title** (string) - Title of the event - **slug** (string) - Slug of the event - **icon** (string) - Icon URL for the event - **eventSlug** (string) - Slug of the event - **outcome** (string) - Outcome of the event - **outcomeIndex** (number) - Index of the outcome - **name** (string) - Name of the trader - **pseudonym** (string) - Pseudonym of the trader - **bio** (string) - Bio of the trader - **profileImage** (string) - Profile image URL - **profileImageOptimized** (string) - Optimized profile image URL - **transactionHash** (string) - Transaction hash #### Response Example ```json [ { "proxyWallet": "0x1234...", "side": "BUY", "asset": "USDC", "conditionId": "0xabc123...", "size": 1.0, "price": 0.65, "timestamp": 1705312200000, "title": "Will BTC exceed $100k?", "slug": "btc-100k", "icon": "https://...", "eventSlug": "btc-usd-2025-11", "outcome": "Yes", "outcomeIndex": 0, "name": "John Doe", "pseudonym": "trader123", "bio": "Crypto trader", "profileImage": "https://...", "profileImageOptimized": "https://...", "transactionHash": "0xdef456..." } ] ``` ``` -------------------------------- ### GET /public/api/v1/trade/{chainId} Source: https://developer.probable.markets/api/orderbook-api/trades Get trade history with cursor-based pagination. Requires L2 Authentication. ```APIDOC ## GET /public/api/v1/trade/{chainId} ### Description Get trade history with cursor-based pagination. ### Method GET ### Endpoint `/public/api/v1/trade/{chainId}` ### Parameters #### Path Parameters - **chainId** (number) - Required - Chain ID #### Query Parameters - **tokenId** (string) - Required - CTF token ID (symbol) - **before** (string) - Optional - Encoded cursor for time filtering (get trades before this time) - **after** (string) - Optional - Encoded cursor for time filtering (get trades after this time) - **next_cursor** (string) - Optional - Encoded cursor for pagination (next page) - **limit** (number) - Optional - Maximum number of trades to return (default: 10) #### Headers (L2 Authentication Required) - **prob_address** (string) - EOA address (signed by EOA) - **prob_signature** (string) - HMAC signature - **prob_timestamp** (string) - Unix timestamp - **prob_api_key** (string) - API key - **prob_passphrase** (string) - API passphrase ### Request Example ```curl https://api.probable.markets/public/api/v1/trade/56?tokenId=0xabc123...&limit=20 \ -H "prob_address: 0x1234..." \ -H "prob_signature: 0xabc123..." \ -H "prob_timestamp: 1705312200" \ -H "prob_api_key: pk_live_abc123xyz" \ -H "prob_passphrase: my-passphrase" ``` ### Response #### Success Response (200) - **trades** (array) - List of trades - **id** (number) - Trade ID - **orderId** (number) - Order ID - **symbol** (string) - Trade symbol - **price** (string) - Trade price - **qty** (string) - Trade quantity - **quoteQty** (string) - Quote quantity - **commission** (string) - Commission amount - **commissionAsset** (string) - Commission asset - **time** (number) - Timestamp of the trade - **buyer** (boolean) - True if the trade was a buy - **maker** (boolean) - True if the trade was a maker order - **counterpartyId** (number) - Counterparty ID - **next_cursor** (string) - Encoded cursor for the next page of results #### Response Example ```json { "trades": [ { "id": 12345, "orderId": 67890, "symbol": "BTC-USD", "price": "0.65", "qty": "1.0", "quoteQty": "0.65", "commission": "0.001", "commissionAsset": "USDC", "time": 1705312200000, "buyer": true, "maker": false, "counterpartyId": 11111 } ], "next_cursor": "eyJ0aW1lIjoxNzA1MzEyMjAwMDAwfQ==" } ``` ### Pagination Use the `next_cursor` from the response to fetch the next page: ```curl https://api.probable.markets/public/api/v1/trade/56?tokenId=0xabc123...&next_cursor=eyJ0aW1lIjoxNzA1MzEyMjAwMDAwfQ== ``` ``` -------------------------------- ### Get Prices Request Body Source: https://developer.probable.markets/api/orderbook-api/orderbook The request body for the Get Prices endpoint should be a JSON array, where each object specifies a token ID and the desired side. ```json [ { "token_id": "0xabc123...", "side": "BUY" }, { "token_id": "0xdef456...", "side": "SELL" } ] ``` -------------------------------- ### Create Proxy Wallet with Viem Source: https://developer.probable.markets/api/orderbook-api/proxy-wallet Creates a proxy wallet by first computing its address, checking for existence, generating the necessary signature, and then submitting the creation transaction via the factory contract. Includes optional payment parameters. ```typescript async function createProxyWallet( eoaAddress: `0x${string}`, paymentToken: `0x${string}` = '0x0000000000000000000000000000000000000000', // Zero address for no payment payment: bigint = 0n, paymentReceiver: `0x${string}` = '0x0000000000000000000000000000000000000000' // Zero address for no payment ): Promise<`0x${string}`> { // Compute the proxy address first const proxyAddress = await computeProxyAddress(eoaAddress); // Check if already exists if (await proxyWalletExists(proxyAddress)) { console.log('Proxy wallet already exists'); return proxyAddress; } // Create signature const createSig = await createProxySignature(eoaAddress, paymentToken, payment, paymentReceiver); // Create the proxy const hash = await walletClient.writeContract({ address: PROXY_WALLET_FACTORY_ADDRESS, abi: PROXY_WALLET_FACTORY_ABI, functionName: 'createProxy', args: [paymentToken, payment, paymentReceiver, createSig], }); // Wait for transaction confirmation const receipt = await publicClient.waitForTransactionReceipt({ hash }); console.log('Transaction confirmed:', receipt.transactionHash); // Verify the wallet was created const exists = await proxyWalletExists(proxyAddress); if (!exists) { throw new Error('Failed to create proxy wallet'); } return proxyAddress; } // Create proxy wallet (no payment required) const proxyWalletAddress = await createProxyWallet(eoaAddress); console.log('Proxy wallet created:', proxyWalletAddress); ``` -------------------------------- ### Initialize Safe Protocol Kit Source: https://developer.probable.markets/api/orderbook-api/token-approvals Initialize Safe Protocol Kit using Viem's transport and the provided signer and Safe address. ```typescript // Initialize Safe Protocol Kit with viem transport const safeProtocolKit = await Safe.init({ provider: walletClient.transport, // Use viem's transport signer: eoaAddress, safeAddress: proxyWalletAddress, }); ``` -------------------------------- ### Create Wallet and CLOB Clients Source: https://developer.probable.markets/api/typescript-sdk/quickstart Instantiate a wallet client and a CLOB client. For authenticated methods, generate an API key once per client. Ensure the account private key is securely handled. ```typescript import { createWalletClient, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { bscTestnet } from "viem/chains"; import { createClobClient } from "@prob/clob"; const account = privateKeyToAccount("0x..." as `0x${string}`); const wallet = createWalletClient({ chain: bscTestnet, transport: http(), account, }); const client = createClobClient({ baseUrl: "https://api.probable.markets/public/api/v1", chainId: bscTestnet.id, wallet, }); await client.generateApiKey(); ``` -------------------------------- ### Place Order from EOA Example Source: https://developer.probable.markets/api/orderbook-complete-guide Use this function to place an order by interacting with a user's Externally Owned Account (EOA) via a WalletClient. It handles proxy wallet creation, token approvals, API key generation, order signing, and submission. ```typescript async function placeOrderFromEOA( walletClient: WalletClient, tokenId: string, price: number, size: number, side: 0 | 1 ) { const eoaAddress = walletClient.account.address; // Step 1: Create or get proxy wallet const { exists, address: proxyAddress } = await checkProxyExists(eoaAddress); if (!exists) { await createProxyWallet(eoaAddress, walletClient); } // Step 2: Approve tokens const approvals = await checkApprovals(proxyAddress); if (approvals.needsUSDTForCTFToken || approvals.needsUSDTForExchange || approvals.needsCTFTokenForExchange) { await approveTokens(proxyAddress, privateKey); } // Step 3: Ensure USDT balance (user should deposit manually) // Check balance and prompt user if needed // Step 4: Create API key const apiKey = await createApiKey(walletClient); // Step 5: Create and sign order const userOrder: UserOrder = { tokenID: tokenId, price, size, side, feeRateBps: 175, nonce: 0, }; const orderData = buildOrderData(userOrder, eoaAddress, proxyAddress, '0.01'); const salt = `${Math.round(Math.random() * Date.now())}`; const signature = await signOrder(orderData, walletClient, salt); const signedOrder = { ...orderData, salt, taker: '0x0000000000000000000000000000000000000000', signature, }; // Step 6: Submit order const result = await submitOrder( signedOrder, apiKey.key, apiKey.secret, apiKey.passphrase, eoaAddress ); console.log('Order placed:', result); return result; } ``` -------------------------------- ### Generate Nonce Source: https://developer.probable.markets/api/orderbook-api/authentication Get a nonce for L1 authentication. ```APIDOC ## GET /public/api/v1/auth/nonce ### Description Get a nonce for L1 authentication. ### Method GET ### Endpoint /public/api/v1/auth/nonce ### Response #### Success Response (200) - **nonce** (string) - The generated nonce. - **issuedAt** (string) - The timestamp when the nonce was issued (ISO 8601 format). ### Response Example ```json { "nonce": "abc123xyz", "issuedAt": "2025-01-15T10:30:00Z" } ``` ``` -------------------------------- ### Get Prices Source: https://developer.probable.markets/api/orderbook-api/orderbook Fetches prices for multiple tokens simultaneously in a single request. ```APIDOC ## POST /public/api/v1/prices ### Description Get prices for multiple tokens in a single request. ### Method POST ### Endpoint /public/api/v1/prices ### Parameters #### Request Body - **token_id** (string) - Required - CTF token ID - **side** (string) - Required - "BUY" or "SELL" ### Request Example ```bash curl -X POST "https://api.probable.markets/public/api/v1/prices" \ -H "Content-Type: application/json" \ -d \ '[ { "token_id": "0xabc123...", "side": "BUY" }, { "token_id": "0xdef456...", "side": "SELL" } ]' ``` ### Response #### Success Response (200) - **token_id** (object) - An object where keys are token IDs. - **side** (string) - The price for the specified side (BUY or SELL). #### Response Example ```json { "0xabc123...": { "BUY": "0.65", "SELL": "0.60" }, "0xdef456...": { "BUY": "0.45", "SELL": "0.40" } } ``` ``` -------------------------------- ### Login User with Wallet Signature Request (L1) Source: https://developer.probable.markets/api/orderbook-api/authentication Example cURL request for the login endpoint, demonstrating how to send the user's identity, message, signature, nonce, issuedAt, and domain. ```bash curl -X POST "https://api.probable.markets/public/api/v1/auth/login" \ -H "Content-Type: application/json" \ -d '{ "identity": { "account": "0x1234...", "namespace": "default", "chainId": "56", "address": "0x1234..." }, "message": "Sign in to Prob...", "signature": "0xabc123...", "nonce": "abc123xyz", "issuedAt": "2025-01-15T10:30:00Z", "domain": "prob.vbgf.cc" }' ``` -------------------------------- ### Get Event Tags Source: https://developer.probable.markets/api/market-public/overview Retrieves a list of tags associated with a specific event. ```APIDOC ## GET /events/{id}/tags ### Description Get tags for an event. ### Method GET ### Endpoint /events/{id}/tags ### Path Parameters - **id** (integer) - Required - The unique numeric identifier of the event. ### Response #### Success Response (200) - **tags** (array) - List of tags associated with the event. ``` -------------------------------- ### Create and Submit Limit Order Source: https://developer.probable.markets/api/typescript-sdk/orders Use this to create and submit a limit order. Ensure you have the necessary imports. The `feeRateBps` can be optionally overridden. ```typescript import { LimitTimeInForce, OrderSide } from "@prob/clob"; const order = await client.createLimitOrder({ tokenId: "...", price: 0.6, size: 100, side: OrderSide.Buy, timeInForce: LimitTimeInForce.GTC, }); // Optional: override feeRateBps (max taker fee), in basis points. // Must be between 175 and 1000 (inclusive). The SDK uses bigint here. order.feeRateBps = 175n; const { orderId } = await client.postOrder(order); ``` -------------------------------- ### Get Midpoint Source: https://developer.probable.markets/api/orderbook-api/orderbook Calculates and returns the midpoint price between the bid and ask for a given token. ```APIDOC ## GET /public/api/v1/midpoint ### Description Get the midpoint price between bid and ask for a token. ### Method GET ### Endpoint /public/api/v1/midpoint ### Parameters #### Query Parameters - **token_id** (string) - Required - CTF token ID ### Request Example ```bash curl "https://api.probable.markets/public/api/v1/midpoint?token_id=0xabc123..." ``` ### Response #### Success Response (200) - **mid** (string) - The midpoint price between bid and ask. #### Response Example ```json { "mid": "0.625" } ``` ``` -------------------------------- ### Import createClobClient Source: https://developer.probable.markets/api/typescript-sdk/installation Import the necessary client function for interacting with the CLOB API. ```javascript import { createClobClient } from "@prob/clob"; ``` -------------------------------- ### List All Markets Source: https://developer.probable.markets/api/market-public/markets Get a paginated list of prediction markets with comprehensive filtering options. ```APIDOC ## GET /public/api/v1/markets/ ### Description Get a paginated list of prediction markets with comprehensive filtering options. ### Method GET ### Endpoint /public/api/v1/markets/ ### Parameters #### Query Parameters All parameters are optional. ##### Pagination - **page** (integer, default: 1) - Page number using 1-based indexing - **limit** (integer, default: 20, max: 100) - Results per page - **offset** (integer) - Results to skip (0-based). Use instead of page for offset-based pagination ##### Filtering - **status** (string) - Filter by market status (e.g., "new", "processing", "completed") - **active** (boolean) - Only active markets if true - **closed** (boolean) - Only closed markets if true - **event_id** (integer) - Filter by event ID ### Request Example ```curl https://market-api.probable.markets/public/api/v1/markets/?page=1&limit=20&active=true ``` ### Response #### Success Response (200) - **markets** (array) - List of market objects - **pagination** (object) - Pagination details #### Response Example ```json { "markets": [ { "id": 456, "condition_id": "0x123...", "question": "Will BTC exceed $100k?", "market_slug": "btc-100k", "outcomes": ["Yes", "No"], "clobTokenIds": ["0xabc...", "0xdef..."], "active": true, "closed": false } ], "pagination": { "hasMore": true, "totalResults": 500, "page": 1, "limit": 20, "totalPages": 25, "hasPrevPage": false } } ``` ### Market Fields - **id** (integer) - Market identifier - **condition_id** (string) - CTF Conditional Token ID - **question** (string) - Market question/title - **market_slug** (string) - URL-friendly market identifier - **outcomes** (array) - Array of outcome names - **clobTokenIds** (array) - CTF token IDs for trading - **active** (boolean) - Boolean market status - **closed** (boolean) - Boolean closed status ### Caching Results are cached for 3 minutes. ``` -------------------------------- ### Get Event by Slug Source: https://developer.probable.markets/api/market-public/overview Retrieves detailed information about a specific event using its slug. ```APIDOC ## GET /events/slug/{slug} ### Description Get event details by slug. ### Method GET ### Endpoint /events/slug/{slug} ### Path Parameters - **slug** (string) - Required - The unique slug identifier of the event. ### Response #### Success Response (200) - **event** (object) - Detailed information about the event. ``` -------------------------------- ### Get or Create Proxy Wallet Source: https://developer.probable.markets/api/orderbook-api/proxy-wallet Use this function to compute a proxy wallet address, check if it exists on-chain, and create it if it doesn't. Requires setting up viem clients and handling signature generation for creation. ```typescript import { createWalletClient, createPublicClient, http, custom, encodeAbiParameters, keccak256, toBytes, } from 'viem'; import { bsc } from 'viem/chains'; import { privateKeyToAccount } from 'viem/accounts'; const PROXY_WALLET_FACTORY_ADDRESS = '0xB99159aBF0bF59a512970586F38292f8b9029924' as const; const PROXY_WALLET_FACTORY_ABI = [ { inputs: [{ internalType: 'address', name: 'user', type: 'address' }], name: 'computeProxyAddress', outputs: [{ internalType: 'address', name: '', type: 'address' }], stateMutability: 'view', type: 'function', }, { inputs: [ { internalType: 'address', name: 'paymentToken', type: 'address' }, { internalType: 'uint256', name: 'payment', type: 'uint256' }, { internalType: 'address payable', name: 'paymentReceiver', type: 'address' }, { components: [ { internalType: 'uint8', name: 'v', type: 'uint8' }, { internalType: 'bytes32', name: 'r', type: 'bytes32' }, { internalType: 'bytes32', name: 's', type: 'bytes32' }, ], internalType: 'struct SafeProxyFactory.Sig', name: 'createSig', type: 'tuple', }, ], name: 'createProxy', outputs: [], stateMutability: 'nonpayable', type: 'function', }, { inputs: [], name: 'domainSeparator', outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], stateMutability: 'view', type: 'function', }, { inputs: [], name: 'CREATE_PROXY_TYPEHASH', outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], stateMutability: 'view', type: 'function', }, ] as const; async function getOrCreateProxyWallet(eoaAddress: `0x${string}`) { // Setup clients const publicClient = createPublicClient({ chain: bsc, transport: http(), }); // For browser: use custom(window.ethereum) // For Node.js: use privateKeyToAccount const account = privateKeyToAccount('0x...' as `0x${string}`); const walletClient = createWalletClient({ account, chain: bsc, transport: http(), }); // Compute proxy address const proxyAddress = await publicClient.readContract({ address: PROXY_WALLET_FACTORY_ADDRESS, abi: PROXY_WALLET_FACTORY_ABI, functionName: 'computeProxyAddress', args: [eoaAddress], }); // Check if wallet already exists const code = await publicClient.getBytecode({ address: proxyAddress }); if (code && code !== '0x' && code.length > 2) { console.log('Using existing proxy wallet:', proxyAddress); return proxyAddress; } // Create new proxy wallet console.log('Creating new proxy wallet...'); // Get domain separator and typehash const [domainSeparator, createProxyTypehash] = await Promise.all([ publicClient.readContract({ address: PROXY_WALLET_FACTORY_ADDRESS, abi: PROXY_WALLET_FACTORY_ABI, functionName: 'domainSeparator', }), publicClient.readContract({ address: PROXY_WALLET_FACTORY_ADDRESS, abi: PROXY_WALLET_FACTORY_ABI, functionName: 'CREATE_PROXY_TYPEHASH', }), ]); // Prepare payment parameters (zero for no payment) const paymentToken = '0x0000000000000000000000000000000000000000' as `0x${string}`; const payment = 0n; const paymentReceiver = '0x0000000000000000000000000000000000000000' as `0x${string}`; // Create struct hash const structHash = keccak256( encodeAbiParameters( [ { type: 'bytes32' }, { type: 'address' }, { type: 'address' }, { type: 'uint256' }, { type: 'address' }, ], [createProxyTypehash, eoaAddress, paymentToken, payment, paymentReceiver] ) ); // Create message hash const message = keccak256( encodeAbiParameters( [{ type: 'bytes32' }, { type: 'bytes32' }, { type: 'bytes32' }], ['0x1901' as `0x${string}`, domainSeparator, structHash] ) ); // Sign message const signature = await walletClient.signMessage({ message: { raw: toBytes(message) }, }); // Split signature const r = `0x${signature.slice(2, 66)}` as `0x${string}`; const s = `0x${signature.slice(66, 130)}` as `0x${string}`; const v = parseInt(signature.slice(130, 132), 16); // Create proxy const hash = await walletClient.writeContract({ address: PROXY_WALLET_FACTORY_ADDRESS, abi: PROXY_WALLET_FACTORY_ABI, functionName: 'createProxy', args: [paymentToken, payment, paymentReceiver, { v, r, s }], }); // Wait for confirmation const receipt = await publicClient.waitForTransactionReceipt({ hash }); console.log('Proxy wallet created in transaction:', receipt.transactionHash); // Verify creation const newCode = await publicClient.getBytecode({ address: proxyAddress }); if (newCode && newCode !== '0x' && newCode.length > 2) { console.log('Proxy wallet created successfully:', proxyAddress); return proxyAddress; } throw new Error('Proxy wallet creation failed'); } ``` -------------------------------- ### Get Open Orders API Source: https://developer.probable.markets/api/orderbook-api/orders Retrieve all open orders for a user by specifying the chain ID. ```APIDOC ## GET /public/api/v1/orders/{chainId}/open ### Description Retrieve all open orders for a user. ### Method GET ### Endpoint `/public/api/v1/orders/{chainId}/open` ### Parameters #### Path Parameters - **chainId** (number) - Required - Chain ID #### Query Parameters - **eventId** (string) - Optional - Filter by event ID - **token_ids** (array) - Optional - Filter by token IDs - **page** (number) - Optional - Page number - **limit** (number) - Optional - Results per page #### Headers (L2 Authentication Required) - **prob_address** (string) - EOA address (signed by EOA) - **prob_signature** (string) - HMAC signature - **prob_timestamp** (string) - Unix timestamp - **prob_api_key** (string) - API key - **prob_passphrase** (string) - API passphrase ### Request Example ```curl curl "https://api.probable.markets/public/api/v1/orders/56/open?page=1&limit=20" \ -H "prob_address: 0xEOA_ADDRESS..." \ -H "prob_signature: 0xabc123..." \ -H "prob_timestamp: 1705312200" \ -H "prob_api_key: pk_live_abc123xyz" \ -H "prob_passphrase: my-passphrase" ``` ### Response #### Success Response (200) - **orders** (array) - List of open orders. - **orderId** (number) - The ID of the order. - **symbol** (string) - The trading symbol for the order. - **side** (string) - The side of the order (e.g., BUY, SELL). - **status** (string) - The current status of the order. - **pagination** (object) - Pagination details for the results. - **page** (number) - The current page number. - **limit** (number) - The number of results per page. - **total** (number) - The total number of results available. #### Response Example ```json { "orders": [ { "orderId": 12345, "symbol": "BTC-USD", "side": "BUY", "status": "NEW", "...": "..." } ], "pagination": { "page": 1, "limit": 20, "total": 50 } } ``` ``` -------------------------------- ### Create and Submit Market Order Source: https://developer.probable.markets/api/typescript-sdk/orders Use this to create and submit a market order. The `feeRateBps` can be optionally overridden. Note that `calculateFee` is a helper function not shown here. ```typescript const marketOrder = await client.createMarketOrder({ tokenId: "...", size: 100, side: OrderSide.Buy, }); // Optional: override feeRateBps (max taker fee), in basis points. // Must be between 175 and 1000 (inclusive). The SDK uses bigint here. marketOrder.feeRateBps = 175n; const feeAmount = calculateFee(marketOrder) await client.postOrder(marketOrder); ```