> 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/builder-mode/split-merge-redeem.md).

# Split / Merge / Redeem

> Build, sign, and submit Safe transactions for on-chain token operations.

All four operations follow the same pattern: build the transaction, have the user sign it, then submit.

## Common Signing Pattern

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

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

// Build any Safe TX (split, merge, redeem, or withdraw)
const txResult = await builder.buildSplitTx(safeAddress, collateral, conditionId, amount);

// User signs the EIP-712 typed data
const user = new UserClient('0xUserPrivateKey...');
const signature = await user.signTypedData(txResult.eip712Data);

// Submit to backend for relay
const result = await builder.submitSafeTx(userAddress, txResult, signature);
```

## Split Position

Convert quote tokens (e.g., USDC) into Yes and No outcome tokens.

```typescript
const txResult = await builder.buildSplitTx(
  safeAddress,          // User's Safe wallet address
  collateralToken,      // Quote token address (e.g., USDC)
  conditionId,          // Market condition ID (from getMarket())
  1000000n,             // Amount in wei (e.g., 1 USDC = 1000000 with 6 decimals)
);
```

| Parameter         | Type      | Required | Description                                              |
| ----------------- | --------- | -------- | -------------------------------------------------------- |
| `safeAddress`     | string    | Yes      | User's Safe wallet address                               |
| `collateralToken` | string    | Yes      | Quote token contract address                             |
| `conditionId`     | string    | Yes      | Market condition ID                                      |
| `amount`          | bigint    | Yes      | Amount in wei                                            |
| `partition`       | number\[] | No       | Outcome partition (default: `[1, 2]` for binary markets) |

## Merge Position

Convert equal amounts of Yes and No tokens back into quote tokens.

```typescript
const txResult = await builder.buildMergeTx(
  safeAddress,
  collateralToken,
  conditionId,
  1000000n,
);
```

| Parameter         | Type      | Required | Description                           |
| ----------------- | --------- | -------- | ------------------------------------- |
| `safeAddress`     | string    | Yes      | User's Safe wallet address            |
| `collateralToken` | string    | Yes      | Quote token contract address          |
| `conditionId`     | string    | Yes      | Market condition ID                   |
| `amount`          | bigint    | Yes      | Amount in wei                         |
| `partition`       | number\[] | No       | Outcome partition (default: `[1, 2]`) |

## Redeem Position

Claim winnings from a resolved market. Converts winning outcome tokens back to quote tokens.

```typescript
const txResult = await builder.buildRedeemTx(
  safeAddress,
  collateralToken,
  conditionId,
);
```

| Parameter         | Type      | Required | Description                           |
| ----------------- | --------- | -------- | ------------------------------------- |
| `safeAddress`     | string    | Yes      | User's Safe wallet address            |
| `collateralToken` | string    | Yes      | Quote token contract address          |
| `conditionId`     | string    | Yes      | Market condition ID                   |
| `partition`       | number\[] | No       | Outcome partition (default: `[1, 2]`) |

## Withdraw Tokens

Transfer ERC20 tokens from the Safe wallet to any address.

```typescript
const txResult = await builder.buildWithdrawTx(
  safeAddress,          // From: user's Safe wallet
  tokenAddress,         // ERC20 token to withdraw
  1000000n,             // Amount in wei
  recipientAddress,     // To: destination address
);
```

| Parameter      | Type   | Required | Description                  |
| -------------- | ------ | -------- | ---------------------------- |
| `safeAddress`  | string | Yes      | User's Safe wallet address   |
| `tokenAddress` | string | Yes      | ERC20 token contract address |
| `amount`       | bigint | Yes      | Amount in wei                |
| `toAddress`    | string | Yes      | Recipient address            |

## Submit Safe Transaction

All build methods return a `SafeTxResult`. Submit it with a user signature:

```typescript
const result = await builder.submitSafeTx(userAddress, txResult, signature);
```

| Parameter       | Type         | Required | Description                            |
| --------------- | ------------ | -------- | -------------------------------------- |
| `walletAddress` | string       | Yes      | User's wallet address (Safe owner EOA) |
| `safeTxResult`  | SafeTxResult | Yes      | Result from any `build*Tx()` method    |
| `signature`     | string       | Yes      | User's signature on the EIP-712 data   |

## Test Helper

For testing, sign Safe transactions with a private key:

```typescript
const signature = await BuilderClient.signSafeTxWithPrivateKey(
  txResult.eip712Data,
  '0xPrivateKey...',
);
```

## Notes

* All Safe TX operations require `rpcUrl` in the BuilderClient config.
* Transactions are relayed by the backend -- no gas required from the user.
* Safe TX signing uses `user.signTypedData(eip712Data)`, not `signHash()`.
* For amount conversions, use `safeAmountToWei()` from the SDK:

  ```typescript
  import { safeAmountToWei } from '@opinion-labs/opinion-clob-sdk';
  const weiAmount = safeAmountToWei(5.0, 6); // 5 USDC -> 5000000n
  ```
* The `conditionId` for split, merge, and redeem is available from `getMarket()`.
* Redeem only works on resolved markets with winning outcome tokens.


---

# 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/builder-mode/split-merge-redeem.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.
