> For the complete documentation index, see [llms.txt](https://docs.opinion.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opinion.trade/developer-guide/opinion-clob-typescript-sdk/support/faq.md).

# FAQ

Frequently asked questions about the TypeScript SDK (`@opinion-labs/opinion-clob-sdk` v0.5.2).

***

## Installation and Setup

<details>

<summary>How do I install the SDK?</summary>

```bash
npm install @opinion-labs/opinion-clob-sdk
```

The package is published on npm as `@opinion-labs/opinion-clob-sdk`.

</details>

<details>

<summary>What are the minimum requirements?</summary>

* **Node.js**: 18 or later
* **TypeScript**: 5.3 or later (if using TypeScript)
* The SDK is an ESM package and requires an ESM-compatible project setup.

</details>

<details>

<summary>How do I use the SDK in a CommonJS project?</summary>

The SDK is published as ESM. If your project uses CommonJS (`require`), use dynamic `import()`:

```javascript
async function main() {
  const { Client, CHAIN_ID_BNB_MAINNET, DEFAULT_API_HOST } = await import(
    '@opinion-labs/opinion-clob-sdk'
  );

  const client = new Client({
    host: DEFAULT_API_HOST,
    apiKey: 'YOUR_API_KEY',
    chainId: CHAIN_ID_BNB_MAINNET,
    rpcUrl: 'YOUR_RPC_URL',
    privateKey: '0xYOUR_PRIVATE_KEY',
    multiSigAddress: '0xYOUR_MULTI_SIG_ADDRESS',
  });
}

main();
```

Alternatively, add `"type": "module"` to your `package.json` to enable ESM.

</details>

<details>

<summary>What imports do I need?</summary>

```typescript
// Main client
import { Client, CHAIN_ID_BNB_MAINNET, DEFAULT_API_HOST } from '@opinion-labs/opinion-clob-sdk';

// Enums
import {
  TopicType,
  TopicStatus,
  TopicStatusFilter,
  TopicSortType,
  OrderSide,
  OrderType,
} from '@opinion-labs/opinion-clob-sdk';

// Types
import type { PlaceOrderDataInput } from '@opinion-labs/opinion-clob-sdk';

// Error classes
import {
  InvalidParamError,
  OpenApiError,
  BalanceNotEnough,
  NoPositionsToRedeem,
  InsufficientGasBalance,
  ValidationException,
} from '@opinion-labs/opinion-clob-sdk';

// Builder mode (optional)
import { BuilderClient, UserClient } from '@opinion-labs/opinion-clob-sdk';
```

</details>

***

## Configuration

<details>

<summary>Which chain IDs are supported?</summary>

Currently only **BNB Chain mainnet (chain ID 56)** is supported. Use the constant `CHAIN_ID_BNB_MAINNET`:

```typescript
import { CHAIN_ID_BNB_MAINNET } from '@opinion-labs/opinion-clob-sdk';

const client = new Client({
  chainId: CHAIN_ID_BNB_MAINNET, // 56
  // ...
});
```

</details>

<details>

<summary>What is the difference between the private key and the multi-sig address?</summary>

* **Private Key (`privateKey`)**: The key of your **login wallet** (EOA). Used for signing orders and transactions. This wallet needs BNB for gas fees on blockchain operations.
* **Multi-Sig Address (`multiSigAddress`)**: Your **asset wallet** (Gnosis Safe). This is where your trading funds are held. It is the address shown in "My Portfolio" on the platform.

The signer (login wallet) authorizes trades on behalf of the multi-sig (asset wallet).

</details>

<details>

<summary>How do I get an API key?</summary>

Contact the Opinion Labs team to obtain your API key for SDK access. The API key is passed in the `apikey` HTTP header for all API requests.

</details>

<details>

<summary>How do I find my asset wallet (multi-sig) address?</summary>

1. Log in at [app.olab.xyz](https://app.olab.xyz/).
2. Click the **Add Fund** button on the navigation bar.
3. Click **Create Your Asset Wallet** if you do not have one.
4. Wait a few minutes and reopen the popup.
5. Copy the address displayed.

</details>

<details>

<summary>How do I configure a proxy?</summary>

Pass the `proxyUrl` option during client initialization:

```typescript
const client = new Client({
  // ...
  proxyUrl: 'http://127.0.0.1:7890',
});
```

The proxy applies to both HTTP API calls and WebSocket connections.

</details>

<details>

<summary>Can I override the default contract addresses?</summary>

Yes, but only do so if instructed by the Opinion Labs team:

```typescript
const client = new Client({
  // ...
  conditionalTokensAddress: '0x...',
  multiSendAddress: '0x...',
  feeManagerAddress: '0x...',
  ctfExchangeAddress: '0x...',
});
```

</details>

***

## Trading

<details>

<summary>What is the difference between market orders and limit orders?</summary>

* **Market order** (`OrderType.MARKET_ORDER`): Executes immediately at the best available price. You specify how much to spend (buy) or how many shares to sell. Price is ignored.
* **Limit order** (`OrderType.LIMIT_ORDER`): Executes at your specified price or better. If the market price does not reach your limit, the order remains open until filled, canceled, or expired.

</details>

<details>

<summary>How do I specify order amounts?</summary>

There are two ways:

* **By quote token** (`makerAmountInQuoteToken`): Specify how much USDC to spend. Example: `"100"` means 100 USDC.
* **By shares** (`makerAmountInBaseToken`): Specify how many outcome tokens (shares). Example: `"50"` means 50 Yes tokens.

Rules:

| Order Type | Side | Allowed Amount Field           |
| ---------- | ---- | ------------------------------ |
| Market     | Buy  | `makerAmountInQuoteToken` only |
| Market     | Sell | `makerAmountInBaseToken` only  |
| Limit      | Buy  | Either                         |
| Limit      | Sell | Either                         |

</details>

<details>

<summary>Do I need to call enableTrading() before every order?</summary>

No. You only need to call `enableTrading()` once per trading account. After that, your orders can be filled on-chain.

Alternatively, pass `checkApproval: true` to `placeOrder()`, which will check and enable trading if needed. However, for performance, it is better to call `enableTrading()` once at startup.

</details>

<details>

<summary>How do I cancel orders?</summary>

```typescript
// Cancel a single order
await client.cancelOrder('order_id');

// Cancel multiple orders
await client.cancelOrdersBatch(['id_1', 'id_2', 'id_3']);

// Cancel all open orders
await client.cancelAllOrders();

// Cancel all BUY orders for a specific market
await client.cancelAllOrders({ marketId: 57, side: OrderSide.BUY });
```

</details>

<details>

<summary>What are the order status codes?</summary>

| Status | Meaning         |
| ------ | --------------- |
| 1      | Pending (open)  |
| 2      | Filled          |
| 3      | Canceled        |
| 4      | Expired         |
| 5      | Failed          |
| 6      | On-chain failed |

</details>

***

## Smart Contracts

<details>

<summary>Which operations require gas (BNB)?</summary>

| Operation          | Gas Required | Description                               |
| ------------------ | ------------ | ----------------------------------------- |
| `enableTrading()`  | Yes          | Approve token spending on-chain           |
| `split()`          | Yes          | Convert collateral to outcome tokens      |
| `merge()`          | Yes          | Convert outcome tokens back to collateral |
| `redeem()`         | Yes          | Claim winnings from resolved markets      |
| `placeOrder()`     | No           | Off-chain signed order                    |
| `cancelOrder()`    | No           | Off-chain cancellation                    |
| `getMarkets()`     | No           | API call                                  |
| All `get*` methods | No           | API calls                                 |

</details>

<details>

<summary>What is the split/merge/redeem workflow?</summary>

1. **Split**: Deposit USDC into a market to receive equal amounts of Yes and No tokens.
2. **Trade**: Buy or sell outcome tokens on the order book.
3. **Merge**: Convert equal amounts of Yes and No tokens back to USDC (useful to exit both sides).
4. **Redeem**: After market resolution, exchange winning tokens for USDC.

</details>

<details>

<summary>What market statuses allow split and merge?</summary>

Both `split()` and `merge()` require the market to be in one of these statuses:

* `ACTIVATED` (2)
* `RESOLVING` (3)
* `RESOLVED` (4)

</details>

<details>

<summary>What market status is required for redeem?</summary>

Only `RESOLVED` (4). The market must have a final outcome before you can redeem.

</details>

***

## Errors

<details>

<summary>Why do I get "Invalid parameter" errors?</summary>

Common causes:

* `page` is less than 1.
* `limit` is less than 1 or greater than 20.
* `marketId` is 0 or negative.
* `tokenId` is an empty string.
* `orderId` is an empty string.
* Using `makerAmountInBaseToken` for a market buy order (not allowed).
* Using `makerAmountInQuoteToken` for a market sell order (not allowed).
* Amount is less than 1 (minimum order size).

</details>

<details>

<summary>What does "Cannot split/merge/redeem on different chain" mean?</summary>

The market you are trying to interact with belongs to a different blockchain than your client is configured for. Ensure `chainId` is set to 56 and the market is on BNB Chain.

</details>

<details>

<summary>What does "Cannot redeem on non-resolved market" mean?</summary>

You can only redeem from markets that have been resolved (status = 4). Check the market status first:

```typescript
const market = await client.getMarket(marketId);
console.log(market.result.data.status);     // Should be 4 (RESOLVED)
console.log(market.result.data.statusEnum); // Should be "resolved"
```

</details>

<details>

<summary>How do I handle network errors?</summary>

Wrap your calls in try/catch and check for `OpenApiError`:

```typescript
import { OpenApiError } from '@opinion-labs/opinion-clob-sdk';

try {
  const result = await client.getMarkets();
} catch (error) {
  if (error instanceof OpenApiError) {
    console.error('API error:', error.message);
    // Retry logic here
  }
}
```

</details>

***

## Data and Precision

<details>

<summary>How are prices represented?</summary>

Prices are strings representing a value between 0 and 1. For example, `"0.55"` means 55 cents per outcome token. A price of `"1"` means the outcome is considered certain.

</details>

<details>

<summary>How are amounts represented?</summary>

* **API responses**: Amounts are returned as strings with full decimal precision (e.g., `"887306.479964285714285714"`).
* **placeOrder input**: Use human-readable strings (e.g., `"100"` for 100 USDC).
* **split/merge input**: Use `bigint` in wei (e.g., `BigInt(100 * 10**6)` for 100 USDC with 6 decimals).

</details>

<details>

<summary>What decimal precision should I use for split/merge amounts?</summary>

It depends on the collateral token's decimals. Check with `getQuoteTokens()`:

```typescript
const tokens = await client.getQuoteTokens();
const decimal = tokens.result.list[0].decimal;  // e.g., 6 for USDC, 18 for others

// For USDC (6 decimals): 100 USDC = 100 * 10^6
const amount = BigInt(100 * 10 ** decimal);
await client.split(marketId, amount);
```

</details>

<details>

<summary>Why are there floating-point precision differences in prices?</summary>

The SDK uses string-based arithmetic internally to minimize floating-point issues. Prices and amounts in API responses are always strings. When performing your own calculations, avoid native floating-point math; use a library like `decimal.js` for precise calculations.

</details>

***

## Support

<details>

<summary>Where can I find more documentation?</summary>

* SDK Documentation: [https://docs.opinion.trade](https://docs.opinion.trade/)
* API Reference: [https://openapi.opinion.trade](https://openapi.opinion.trade/)

</details>

<details>

<summary>How do I report a bug?</summary>

* Email: <support@opinion.trade>
* GitHub Issues: Open an issue on the SDK repository with:
  * SDK version (`npm list @opinion-labs/opinion-clob-sdk`)
  * Node.js version (`node --version`)
  * Full error message and stack trace
  * Minimal code to reproduce the issue

</details>

<details>

<summary>Is there a Python SDK available?</summary>

Yes. The Python SDK (`opinion_clob_sdk`) provides equivalent functionality. See the [Python SDK documentation](broken://pages/aaef683222d9e73b8acd42b7944a31af122b2ed6) for details.

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.opinion.trade/developer-guide/opinion-clob-typescript-sdk/support/faq.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
