{"_id":"@opinion-labs/opinion-clob-sdk","_rev":"5-251c70a268286079da236c4d07212c5c","name":"@opinion-labs/opinion-clob-sdk","dist-tags":{"latest":"0.6.1"},"versions":{"0.5.2":{"name":"@opinion-labs/opinion-clob-sdk","version":"0.5.2","keywords":["opinion","prediction-market","clob","sdk","viem","ethereum","bnb-chain"],"author":{"name":"Opinion Labs"},"license":"MIT","_id":"@opinion-labs/opinion-clob-sdk@0.5.2","maintainers":[{"name":"jeff_opinion","email":"jeff@opinionlabs.xyz"},{"name":"tedop4","email":"ted@opinionlabs.xyz"}],"dist":{"shasum":"4d7ffaaeaad6815ab210281fe2e845b06edd2262","tarball":"https://registry.npmjs.org/@opinion-labs/opinion-clob-sdk/-/opinion-clob-sdk-0.5.2.tgz","fileCount":146,"integrity":"sha512-D/ZHqz+4ckwM2xw/G9+HZxtrSc5wA0Wd+uEDIGvaIJbSPPVgKCZOtYobZxkXWmHWar72CticesU22u8gSi5VWw==","signatures":[{"sig":"MEYCIQCVBiFAnNT4Ux6e3BrdKhqp2Yd1oUlQuhsdIz5Bm0PyYwIhAP7Pi4dWZST8qQhMcRbKgL/ESa980LudEj7nKpUkbBXp","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":632850},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"3369f028fc4663b103983f28946f344718c04821","scripts":{"lint":"eslint src --ext .ts","test":"vitest run --exclude \"tests/test_{integration,websocket}.ts\"","build":"tsc","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","lint:fix":"eslint src --ext .ts --fix","test:unit":"vitest run --exclude \"tests/test_{integration,websocket}.ts\"","typecheck":"tsc --noEmit","test:watch":"vitest --exclude \"tests/test_{integration,websocket}.ts\"","format:check":"prettier --check \"src/**/*.ts\"","test:coverage":"vitest run --coverage","prepublishOnly":"npm run clean && npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"tedop4","email":"ted@opinionlabs.xyz"},"_npmVersion":"11.6.2","description":"TypeScript SDK for Opinion Labs Prediction Market CLOB operations","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.19.0","viem":"^2.21.0","undici":"^6.0.0","https-proxy-agent":"^7.0.6","@opinion-labs/opinion-api":"^0.2.1"},"_hasShrinkwrap":false,"devDependencies":{"dotenv":"^16.3.1","eslint":"^8.57.0","vitest":"^3.2.4","prettier":"^3.2.0","@types/ws":"^8.18.1","typescript":"^5.3.0","@types/node":"^20.10.0","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^9.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/opinion-clob-sdk_0.5.2_1771053756972_0.722762403127841","host":"s3://npm-registry-packages-npm-production"}},"0.5.3":{"name":"@opinion-labs/opinion-clob-sdk","version":"0.5.3","keywords":["opinion","prediction-market","clob","sdk","viem","ethereum","bnb-chain"],"author":{"name":"Opinion Labs"},"license":"MIT","_id":"@opinion-labs/opinion-clob-sdk@0.5.3","maintainers":[{"name":"jeff_opinion","email":"jeff@opinionlabs.xyz"},{"name":"tedop4","email":"ted@opinionlabs.xyz"}],"dist":{"shasum":"390aa6908251ee8727e1de13b2eb384d1738ddd3","tarball":"https://registry.npmjs.org/@opinion-labs/opinion-clob-sdk/-/opinion-clob-sdk-0.5.3.tgz","fileCount":147,"integrity":"sha512-2qlFILS7x+nfjZUdjJqQQCb+wiNzEPd1V4G0rXrOg6BwVC7wFDsRHJcdMuVGdrgvnCaIcAvEXPDgBkackPnhPQ==","signatures":[{"sig":"MEUCIQCoK+XF/fmDv8yYb26fh7WeBQNQZWHBA2dRVUbPzEmepQIgMyTFXgn8pvogOm1w7u7pdHHzHoHtRRw/EBt/Yqokx5k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":641235},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"1ec33e42f75471da7f3f537f4c8b8b3e8a48d9bb","scripts":{"lint":"eslint src --ext .ts","test":"vitest run --exclude \"tests/test_{integration,websocket}.ts\"","build":"tsc","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","lint:fix":"eslint src --ext .ts --fix","test:unit":"vitest run --exclude \"tests/test_{integration,websocket}.ts\"","typecheck":"tsc --noEmit","test:watch":"vitest --exclude \"tests/test_{integration,websocket}.ts\"","format:check":"prettier --check \"src/**/*.ts\"","test:coverage":"vitest run --coverage","prepublishOnly":"npm run clean && npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1b015439-54c6-419f-a79e-caa8b0db205e"}},"_npmVersion":"11.6.2","description":"TypeScript SDK for Opinion Labs Prediction Market CLOB operations","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.19.0","viem":"^2.21.0","undici":"^6.0.0","https-proxy-agent":"^7.0.6","@opinion-labs/opinion-api":"^0.2.2"},"_hasShrinkwrap":false,"devDependencies":{"dotenv":"^16.3.1","eslint":"^8.57.0","vitest":"^3.2.4","prettier":"^3.2.0","@types/ws":"^8.18.1","typescript":"^5.3.0","@types/node":"^20.10.0","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^9.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/opinion-clob-sdk_0.5.3_1771055656505_0.211217325016833","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@opinion-labs/opinion-clob-sdk","version":"0.6.0","keywords":["opinion","prediction-market","clob","sdk","viem","ethereum","bnb-chain"],"author":{"name":"Opinion Labs"},"license":"MIT","_id":"@opinion-labs/opinion-clob-sdk@0.6.0","maintainers":[{"name":"jeff_opinion","email":"jeff@opinionlabs.xyz"},{"name":"tedop4","email":"ted@opinionlabs.xyz"},{"name":"nik_opinionlabs","email":"nik@opinionlabs.xyz"}],"dist":{"shasum":"f773007a506b73e628c627ad80068a864123a55f","tarball":"https://registry.npmjs.org/@opinion-labs/opinion-clob-sdk/-/opinion-clob-sdk-0.6.0.tgz","fileCount":147,"integrity":"sha512-gcMdKis1HbTSJ7Ff9Si4HR42KgKU7hmb4CgCAPKEamLHbBRPLr6pE+bMnI3ZVtwg8Ur/r1Hhg1T0dSVBixRgsw==","signatures":[{"sig":"MEUCIGX1wwtlMH4Q7aTm6cUsbv5BaLiLBLntQcr9QcBrxyHNAiEA4dA4bbTcep1WpkzfSwSGHYN8Ul8ExtRpT+r+Mr8IwBQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":645605},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"72992ff0af91ddabc04d6a2f1c7def6e2693fba9","scripts":{"lint":"eslint src --ext .ts","test":"vitest run --exclude \"tests/test_{integration,websocket}.ts\"","build":"tsc","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","lint:fix":"eslint src --ext .ts --fix","test:unit":"vitest run --exclude \"tests/test_{integration,websocket}.ts\"","typecheck":"tsc --noEmit","test:watch":"vitest --exclude \"tests/test_{integration,websocket}.ts\"","format:check":"prettier --check \"src/**/*.ts\"","test:coverage":"vitest run --coverage","prepublishOnly":"npm run clean && npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1b015439-54c6-419f-a79e-caa8b0db205e"}},"_npmVersion":"11.9.0","description":"TypeScript SDK for Opinion Labs Prediction Market CLOB operations","directories":{},"_nodeVersion":"24.14.0","dependencies":{"ws":"^8.19.0","viem":"^2.21.0","undici":"^6.0.0","https-proxy-agent":"^7.0.6","@opinion-labs/opinion-api":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{"dotenv":"^16.3.1","eslint":"^8.57.0","vitest":"^3.2.4","prettier":"^3.2.0","@types/ws":"^8.18.1","typescript":"^5.3.0","@types/node":"^20.10.0","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^9.1.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/opinion-clob-sdk_0.6.0_1773149361873_0.1390896648704527","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@opinion-labs/opinion-clob-sdk","version":"0.6.1","description":"TypeScript SDK for Opinion Labs Prediction Market CLOB operations","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"tsc","clean":"rm -rf dist","test":"vitest run --exclude \"tests/test_{integration,websocket}.ts\"","test:watch":"vitest --exclude \"tests/test_{integration,websocket}.ts\"","test:unit":"vitest run --exclude \"tests/test_{integration,websocket}.ts\"","test:integration":"vitest run --config vitest.integration.config.ts","test:coverage":"vitest run --coverage","lint":"eslint src --ext .ts","lint:fix":"eslint src --ext .ts --fix","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","typecheck":"tsc --noEmit","prepublishOnly":"npm run clean && npm run build"},"keywords":["opinion","prediction-market","clob","sdk","viem","ethereum","bnb-chain"],"author":{"name":"Opinion Labs"},"license":"MIT","dependencies":{"@opinion-labs/opinion-api":"^0.3.1","https-proxy-agent":"^7.0.6","undici":"^6.0.0","viem":"^2.21.0","ws":"^8.19.0"},"devDependencies":{"@types/node":"^20.10.0","@types/ws":"^8.18.1","@typescript-eslint/eslint-plugin":"^7.0.0","@typescript-eslint/parser":"^7.0.0","@vitest/coverage-v8":"^3.2.4","dotenv":"^16.3.1","eslint":"^8.57.0","eslint-config-prettier":"^9.1.0","prettier":"^3.2.0","typescript":"^5.3.0","vitest":"^3.2.4"},"gitHead":"aacd2b179d558e8354f5f7426ece429f97af3b5f","_id":"@opinion-labs/opinion-clob-sdk@0.6.1","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-q/ZPQ4hGUExqDCgOKa07RbrSS5yoXCK+ZWjFrmUsCi8/qPyLDxEbk5PXqDNzXTX33Ycjy9b6OWBESrZJfks/Fg==","shasum":"bc91d5ec187ea32e46418c62949ca270888ab99c","tarball":"https://registry.npmjs.org/@opinion-labs/opinion-clob-sdk/-/opinion-clob-sdk-0.6.1.tgz","fileCount":147,"unpackedSize":651257,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC8vbHb7aCXhtN+RHkGU4WX9t72pWC356WVk3uJAXtflAiBi+DukWn0ENp3lFGpNDgG4kX06HSZtatVB1bl1Xj3YuQ=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1b015439-54c6-419f-a79e-caa8b0db205e"}},"directories":{},"maintainers":[{"name":"jeff_opinion","email":"jeff@opinionlabs.xyz"},{"name":"tedop4","email":"ted@opinionlabs.xyz"},{"name":"nik_opinionlabs","email":"nik@opinionlabs.xyz"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/opinion-clob-sdk_0.6.1_1784275256132_0.13489750952576207"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-14T07:22:36.876Z","modified":"2026-07-17T08:00:56.430Z","0.5.2":"2026-02-14T07:22:37.127Z","0.5.3":"2026-02-14T07:54:16.707Z","0.6.0":"2026-03-10T13:29:22.028Z","0.6.1":"2026-07-17T08:00:56.266Z"},"author":{"name":"Opinion Labs"},"license":"MIT","keywords":["opinion","prediction-market","clob","sdk","viem","ethereum","bnb-chain"],"description":"TypeScript SDK for Opinion Labs Prediction Market CLOB operations","maintainers":[{"name":"jeff_opinion","email":"jeff@opinionlabs.xyz"},{"name":"tedop4","email":"ted@opinionlabs.xyz"},{"name":"nik_opinionlabs","email":"nik@opinionlabs.xyz"}],"readme":"# @opinion-labs/opinion-clob-sdk\n\nTypeScript SDK for [Opinion Labs](https://opinion.trade) Prediction Market. Trade on blockchain-based prediction markets with EIP-712 signed orders, Gnosis Safe multi-sig support, and real-time WebSocket updates.\n\n## Installation\n\n```bash\nnpm install @opinion-labs/opinion-clob-sdk\n```\n\n## Quick Start\n\n```typescript\nimport { Client, CHAIN_ID_BNB_MAINNET, DEFAULT_API_HOST, OrderSide, OrderType } from '@opinion-labs/opinion-clob-sdk';\n\nconst client = new Client({\n  host: DEFAULT_API_HOST,\n  apiKey: 'your_api_key',\n  chainId: CHAIN_ID_BNB_MAINNET,\n  rpcUrl: 'https://bsc-dataseed.binance.org',\n  privateKey: '0x...',\n  multiSigAddress: '0x...',\n});\n\n// Get markets\nconst markets = await client.getMarkets({ limit: 10 });\nconsole.log(markets.result.list);\n\n// Place a limit buy order\nawait client.placeOrder({\n  marketId: 1234,\n  tokenId: '0x...',\n  side: OrderSide.BUY,\n  orderType: OrderType.LIMIT_ORDER,\n  price: '0.5',\n  makerAmountInQuoteToken: '10',\n});\n```\n\n## Prerequisites\n\n| Requirement | Description |\n|-------------|-------------|\n| **API Key** | Obtained from the Opinion Labs team |\n| **Private Key** | EOA wallet private key for signing orders |\n| **Multi-sig Address** | Your Gnosis Safe wallet address (visible in \"My Portfolio\") |\n| **RPC URL** | BNB Chain RPC endpoint |\n\n> **Note:** The signer (private key) and multi-sig address may be different wallets. The signer is an owner of the Safe that authorizes trades.\n\n## Configuration\n\n```typescript\nconst client = new Client({\n  // Required\n  host: 'https://openapi.opinion.trade/openapi',\n  apiKey: 'your_api_key',\n  chainId: 56,                    // BNB Chain (only supported chain)\n  rpcUrl: 'https://bsc-dataseed.binance.org',\n  privateKey: '0x...',\n  multiSigAddress: '0x...',\n\n  // Optional\n  proxyUrl: 'http://127.0.0.1:7890',  // HTTP proxy\n  quoteTokensCacheTtl: 3600,           // Cache TTL in seconds (default: 3600)\n  marketCacheTtl: 300,                 // Cache TTL in seconds (default: 300)\n});\n```\n\n## API Reference\n\n### Market Data\n\n```typescript\n// Discover available labels (categories)\nconst labels = await client.getLabels();\nlabels.result.list.forEach(l => console.log(l.labelId, l.labelName));\n\n// Filter markets by labelId (use 0 or omit to get all)\nconst markets = await client.getMarkets({\n  topicType: TopicType.BINARY,             // BINARY, CATEGORICAL, or ALL\n  status: TopicStatusFilter.ACTIVATED,      // ACTIVATED, RESOLVED, or ALL\n  sortBy: TopicSortType.BY_VOLUME_DESC,    // Sort order\n  page: 1,\n  limit: 20,\n  labelId: 3,                              // Optional — filter by label\n});\n\n// Each market also includes labels (names) and labelIds aligned by index\nmarkets.result.list.forEach(m =>\n  console.log(m.marketId, m.labels, m.labelIds)\n);\n\n// Also supports simple usage:\nconst all = await client.getMarkets({ limit: 10 });\n\n// Get market details\nconst market = await client.getMarket(marketId);\n\n// Get categorical market details\nconst catMarket = await client.getCategoricalMarket(marketId);\n\n// Get orderbook\nconst orderbook = await client.getOrderbook(tokenId);\n\n// Get latest price\nconst price = await client.getLatestPrice(tokenId);\n\n// Get price history\nconst history = await client.getPriceHistory(tokenId, {\n  interval: '1h',   // '1m' | '1h' | '1d' | '1w' | 'max'\n  startAt: 1700000000,\n  endAt: 1700100000,\n});\n\n// Get quote tokens\nconst tokens = await client.getQuoteTokens();\n\n// Get on-chain fee rates\nconst fees = await client.getFeeRates(tokenId);\n```\n\n### Trading\n\nAll order operations are **gas-free** (signed off-chain, submitted via API).\n\n```typescript\n// Enable trading (one-time approval, requires gas)\nawait client.enableTrading();\n\n// Place a limit buy order\nawait client.placeOrder({\n  marketId: 1234,\n  tokenId: '0x...',\n  side: OrderSide.BUY,\n  orderType: OrderType.LIMIT_ORDER,\n  price: '0.5',\n  makerAmountInQuoteToken: '10',  // 10 USDC\n});\n\n// Place a limit sell order\nawait client.placeOrder({\n  marketId: 1234,\n  tokenId: '0x...',\n  side: OrderSide.SELL,\n  orderType: OrderType.LIMIT_ORDER,\n  price: '0.6',\n  makerAmountInBaseToken: '10',   // 10 outcome tokens\n});\n\n// Place a market buy order\nawait client.placeOrder({\n  marketId: 1234,\n  tokenId: '0x...',\n  side: OrderSide.BUY,\n  orderType: OrderType.MARKET_ORDER,\n  price: '0',\n  makerAmountInQuoteToken: '10',\n});\n\n// Cancel an order\nawait client.cancelOrder(orderId);\n\n// Batch operations\nawait client.placeOrdersBatch([order1, order2, order3]);\nawait client.cancelOrdersBatch([id1, id2, id3]);\n\n// Cancel all open orders (with optional filters)\nawait client.cancelAllOrders({ marketId: 1234, side: OrderSide.BUY });\n```\n\n### User Data\n\n```typescript\nconst positions = await client.getMyPositions({ marketId: 1234 });\nconst trades = await client.getMyTrades({ page: 1, limit: 20 });\nconst orders = await client.getMyOrders({ status: '1' });  // 1 = open\nconst order = await client.getOrderById(orderId);\nconst balances = await client.getMyBalances();\nconst auth = await client.getUserAuth();\n```\n\n### Token Operations\n\nThese operations interact directly with the blockchain and **require gas** (BNB).\n\n```typescript\n// Split: convert collateral (USDC) into Yes + No tokens\nawait client.split(marketId, 10000000n);  // amount in wei\n\n// Merge: convert Yes + No tokens back to collateral\nawait client.merge(marketId, 10000000n);\n\n// Redeem: claim winnings from a resolved market\nawait client.redeem(marketId);\n```\n\n### WebSocket\n\nSubscribe to real-time market updates.\n\n```typescript\nconst ws = client.createWebSocketClient({\n  heartbeatInterval: 30,\n  onOpen: () => console.log('Connected'),\n  onClose: () => console.log('Disconnected'),\n  onError: (err) => console.error(err),\n});\n\nawait ws.connect();\n\n// Subscribe to orderbook depth updates\nws.subscribeMarketDepthDiff(marketId, (msg) => {\n  console.log(`Depth: ${msg.side} ${msg.price} @ ${msg.size}`);\n});\n\n// Subscribe to price updates\nws.subscribeMarketLastPrice(marketId, (msg) => {\n  console.log(`Price: ${msg.price}`);\n});\n\n// Subscribe to trade updates\nws.subscribeMarketLastTrade(marketId, (msg) => {\n  console.log(`Trade: ${msg.price} x ${msg.size}`);\n});\n\n// Subscribe to your order status updates\nws.subscribeTradeOrderUpdate((msg) => {\n  console.log(`Order ${msg.orderId}: ${msg.status}`);\n});\n\n// Subscribe to your new trade records\nws.subscribeTradeRecordNew((msg) => {\n  console.log(`New trade: ${msg.tradeId}`);\n});\n\n// Disconnect when done\nawait ws.disconnect();\n```\n\n## Builder Mode\n\nFor platforms that place orders **on behalf of users** without holding their private keys.\n\n```typescript\nimport { BuilderClient, UserClient } from '@opinion-labs/opinion-clob-sdk';\n\nconst builder = new BuilderClient({\n  host: 'https://openapi.opinion.trade/openapi',\n  builderApiKey: 'your_builder_api_key',\n  chainId: 56,\n  rpcUrl: 'https://bsc-dataseed.binance.org',\n});\n\n// Create a sub-account for a user\nconst userInfo = await builder.createUser('0xUserWallet...');\n// IMPORTANT: userInfo.apikey is returned only once — store it securely\n\n// Build an order for the user to sign\nconst orderResult = await builder.buildOrderForSigning({\n  marketId: 1234,\n  tokenId: '0x...',\n  userWalletAddress: '0xUserSafeWallet...',\n  side: OrderSide.BUY,\n  orderType: OrderType.LIMIT_ORDER,\n  amount: 10,\n  price: '0.5',\n});\n\n// User signs the order (client-side)\nconst user = new UserClient('0xUserPrivateKey...');\nconst signature = await user.signTypedData(orderResult.typedData);\n\n// Submit the signed order\nawait builder.placeOrderForUser({\n  ...orderResult,\n  signature,\n  userWalletAddress: '0xUserSafeWallet...',\n});\n```\n\n## Error Handling\n\n```typescript\nimport {\n  SdkError,\n  InvalidParamError,\n  OpenApiError,\n  BalanceNotEnough,\n  InsufficientGasBalance,\n} from '@opinion-labs/opinion-clob-sdk';\n\ntry {\n  await client.placeOrder(orderData);\n} catch (err) {\n  if (err instanceof InvalidParamError) {\n    // Invalid order parameters\n  } else if (err instanceof BalanceNotEnough) {\n    // Insufficient token balance\n  } else if (err instanceof InsufficientGasBalance) {\n    // Not enough BNB for gas\n  } else if (err instanceof OpenApiError) {\n    // API call failed\n  }\n}\n```\n\n## Response Format\n\nAll API methods return:\n\n```typescript\n{\n  errno: number;    // 0 = success\n  errmsg: string;   // Error message (empty on success)\n  result: T;        // Response payload\n}\n```\n\n## Workflow\n\n```\n1. enableTrading()     One-time approval (requires gas)\n                           |\n2. split() (optional)  Convert USDC -> Yes/No tokens (requires gas)\n                           |\n3. placeOrder()        Place limit/market orders (gas-free)\n                           |\n4. cancelOrder()       Cancel open orders (gas-free)\n                           |\n5. merge() / redeem()  Convert back or claim winnings (requires gas)\n```\n\n## Builder Demo (Recommended for Partners)\n\n### `examples/builder_demo/` — Scenario-based examples for Builder mode integration\n\nBuilder mode lets you build your own trading terminal on top of Opinion's\nprediction market, with 2,000 free gasless transactions per day.\n\n```bash\ncd examples/builder_demo\ncp config.example.json config.json\n# Edit config.json with your credentials\n\nnpx tsx 01_user_onboarding.ts      # Create user + Safe wallet\nnpx tsx 02_market_discovery.ts     # Browse markets (read-only)\nnpx tsx 03_enable_trading.ts       # One-time trading setup\nnpx tsx 04_place_limit_order.ts    # Place a limit order\nnpx tsx 05_place_market_order.ts   # Place a market order\nnpx tsx 06_manage_orders.ts        # Query + cancel orders\nnpx tsx 07_split_and_merge.ts      # Split/merge outcome tokens\nnpx tsx 08_redeem_and_withdraw.ts  # Redeem winnings + withdraw\nnpx tsx 10_full_trading_flow.ts    # End-to-end combined flow\n```\n\nSee [`examples/builder_demo/README.md`](examples/builder_demo/README.md) for the full guide,\narchitecture overview, and production integration tips.\n\n## Requirements\n\n- Node.js >= 18\n- TypeScript >= 5.3\n\n## License\n\nMIT\n","readmeFilename":"README.md"}