# Builder Mode

> Build your own trading terminal on top of Opinion's prediction market with non-custodial user management and 2,000 free gasless transactions per day.
>
> To request Builder access, Please kindly fill out this [short application form ](https://forms.gle/tqL84A5mMXjZ1xT86).&#x20;

## Overview

Builder mode lets platforms manage user sub-accounts and place orders on behalf of users. Users retain control of their funds through Gnosis Safe wallets and sign all operations with their own keys.

## Architecture

```
┌──────────────┐     ┌──────────────────┐     ┌────────────┐
│  Your App    │     │  Opinion Backend  │     │  BNB Chain  │
│  (Builder)   │────>│  (API + Relayer)  │────>│  (On-chain) │
│              │     │                   │     │             │
│  BuilderClient     │  - Order matching │     │  - Safe     │
│  + UserClient│<────│  - TX relay       │<────│  - CTF      │
│              │     │  - Safe creation  │     │  - ERC20    │
└──────────────┘     └──────────────────┘     └────────────┘
```

**Three wallets involved:**

| Wallet                  | What                               | Who Controls             |
| ----------------------- | ---------------------------------- | ------------------------ |
| **EOA** (signer)        | Signs orders and Safe transactions | User (private key)       |
| **Safe** (asset wallet) | Holds funds, executes trades       | Multi-sig (EOA is owner) |
| **Builder API key**     | Authenticates builder API calls    | Builder (your server)    |

## Quick Start

```typescript
import {
  BuilderClient,
  UserClient,
  OrderSide,
  OrderType,
} from '@opinion-labs/opinion-clob-sdk';

// 1. Initialize builder client
const builder = new BuilderClient({
  host: 'https://openapi.opinion.trade/openapi',
  builderApiKey: 'YOUR_BUILDER_KEY',
  chainId: 56,
  rpcUrl: 'https://bsc-dataseed.binance.org',
});

// 2. Create a user and save the API key
const userInfo = await builder.createUser('0xUserEOA...');
const userApiKey = userInfo.apikey; // SAVE THIS - only returned once!

// 3. Build and sign an order
const orderData = await builder.buildOrderForSigning({
  marketId: 123,
  tokenId: 'token_id',
  userWalletAddress: userInfo.multiSigWallet,
  side: OrderSide.BUY,
  orderType: OrderType.LIMIT_ORDER,
  amount: 10,
  price: '0.5',
  signerAddress: '0xUserEOA...',
});

// 4. User signs the order hash (in production, use MetaMask/WalletConnect)
const user = new UserClient('0xUserPrivateKey...');
const signature = await user.signHash(orderData.structHash);

// 5. Place order
const result = await builder.placeOrderForUserFromBuildResult(
  orderData, signature, userInfo.multiSigWallet
);
```

## Configuration

```typescript
const builder = new BuilderClient({
  host: 'https://openapi.opinion.trade/openapi',
  builderApiKey: 'YOUR_BUILDER_KEY',
  chainId: 56,
  rpcUrl: 'https://bsc-dataseed.binance.org',  // Required for Safe operations
  proxyUrl: 'http://127.0.0.1:7890',           // Optional HTTP proxy
  quoteTokensCacheTtl: 3600,                    // Cache TTL in seconds (default: 3600)
  marketCacheTtl: 300,                          // Cache TTL in seconds (default: 300)
});
```

| Parameter             | Type    | Required | Description                                           |
| --------------------- | ------- | -------- | ----------------------------------------------------- |
| `host`                | string  | Yes      | API host URL                                          |
| `builderApiKey`       | string  | Yes      | Builder API key (uses `builder-apikey` header)        |
| `chainId`             | number  | Yes      | Blockchain chain ID (56 for BNB Chain)                |
| `rpcUrl`              | string  | No       | RPC endpoint URL (required for Safe operations)       |
| `proxyUrl`            | string  | No       | HTTP proxy URL for API requests                       |
| `useBeta`             | boolean | No       | Use beta/testnet addresses (default: false)           |
| `contractAddresses`   | object  | No       | Override specific contract addresses                  |
| `quoteTokensCacheTtl` | number  | No       | Cache TTL for quote tokens in seconds (default: 3600) |
| `marketCacheTtl`      | number  | No       | Cache TTL for market data in seconds (default: 300)   |

## API Reference

### User Management

* [Create User](/developer-guide/opinion-clob-typescript-sdk/builder-mode/create-user.md) -- register a sub-account and get an API key
* [Get User / Regenerate API Key](/developer-guide/opinion-clob-typescript-sdk/builder-mode/get-user.md) -- query user info or regenerate credentials

### Market Data

* [Get Quote Tokens](/developer-guide/opinion-clob-typescript-sdk/builder-mode/get-quote-tokens.md) -- list supported currencies
* [Get Market / Orderbook](/developer-guide/opinion-clob-typescript-sdk/builder-mode/get-market.md) -- query market details and orderbook depth

### Trading

* [Build Order](/developer-guide/opinion-clob-typescript-sdk/builder-mode/build-order.md) -- build an EIP-712 order structure for signing
* [Place Order](/developer-guide/opinion-clob-typescript-sdk/builder-mode/place-order.md) -- submit a signed order on behalf of a user
* [Cancel / Manage Orders](/developer-guide/opinion-clob-typescript-sdk/builder-mode/cancel-order.md) -- cancel orders and query order history

### On-chain Operations

* [Enable Trading](/developer-guide/opinion-clob-typescript-sdk/builder-mode/enable-trading.md) -- one-time approval setup via Safe transaction
* [Split / Merge / Redeem / Withdraw](/developer-guide/opinion-clob-typescript-sdk/builder-mode/split-merge-redeem.md) -- token operations via Safe transactions

### Testing

* [UserClient](/developer-guide/opinion-clob-typescript-sdk/builder-mode/userclient.md) -- test wallet helper for signing

## Error Handling

```typescript
import {
  BuilderError,
  BuilderInvalidParamError,
  BuilderApiError,
} from '@opinion-labs/opinion-clob-sdk';

try {
  await builder.createUser(address);
} catch (e) {
  if (e instanceof BuilderInvalidParamError) {
    // Bad input: invalid address format, missing required field
    console.error('Invalid parameter:', e.message);
  } else if (e instanceof BuilderApiError) {
    // Backend error: user already exists, rate limit, server error
    console.error('API error:', e.message);
  } else if (e instanceof BuilderError) {
    // General builder error (base class)
    console.error('Builder error:', e.message);
  }
}
```

## Signature Types

| Type               | Value | Description                             |
| ------------------ | ----- | --------------------------------------- |
| EOA                | 0     | Direct EOA signature (maker == signer)  |
| POLY\_GNOSIS\_SAFE | 2     | Gnosis Safe signature (maker != signer) |

The signature type is automatically determined based on whether `signerAddress` differs from `userWalletAddress` in `buildOrderForSigning()`.


---

# Agent Instructions: 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/builder-mode.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.
