> ## Documentation Index
> Fetch the complete documentation index at: https://docs.limitless.exchange/llms.txt
> Use this file to discover all available pages before exploring further.

# EIP-712 Order Signing

> How to sign orders using EIP-712 structured data

## Overview

All orders on Limitless are signed using **EIP-712 structured data**. The venue's exchange address is used as the `verifyingContract` in the signing domain.

<Tip>
  If you're using the [Programmatic API](/developers/programmatic-api) with delegated signing, the server handles EIP-712 signing for you via managed wallets. This page is for partners and traders who sign orders with their own private keys.
</Tip>

## EIP-712 domain

```json theme={null}
{
  "name": "Limitless CTF Exchange",
  "version": "1",
  "chainId": 8453,
  "verifyingContract": "<venue.exchange address>"
}
```

<Note>
  The `verifyingContract` must be fetched from the market's venue data via `GET /markets/:slug`. See [Venue System](/developers/venue-system).
</Note>

## Order type definition

```json theme={null}
{
  "Order": [
    { "name": "salt", "type": "uint256" },
    { "name": "maker", "type": "address" },
    { "name": "signer", "type": "address" },
    { "name": "taker", "type": "address" },
    { "name": "tokenId", "type": "uint256" },
    { "name": "makerAmount", "type": "uint256" },
    { "name": "takerAmount", "type": "uint256" },
    { "name": "expiration", "type": "uint256" },
    { "name": "nonce", "type": "uint256" },
    { "name": "feeRateBps", "type": "uint256" },
    { "name": "side", "type": "uint8" },
    { "name": "signatureType", "type": "uint8" }
  ]
}
```

## Field reference

| Field           | Type    | Description                                                                                                                                                                                                                                                                                                                                      |
| --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `salt`          | uint256 | Unique order identifier (typically timestamp-based)                                                                                                                                                                                                                                                                                              |
| `maker`         | address | Checksummed address of the order creator — must match your profile's trading wallet (see [Trading wallet mode](#trading-wallet-mode-whose-address-signs))                                                                                                                                                                                        |
| `signer`        | address | Same as maker in EOA trading mode (see [Trading wallet mode](#trading-wallet-mode-whose-address-signs))                                                                                                                                                                                                                                          |
| `taker`         | address | `0x000...000` for open orders (any taker)                                                                                                                                                                                                                                                                                                        |
| `tokenId`       | uint256 | Position ID — YES or NO token from market data                                                                                                                                                                                                                                                                                                   |
| `makerAmount`   | uint256 | Amount the maker offers, scaled by 1e6 (see [Amount calculation](#amount-calculation))                                                                                                                                                                                                                                                           |
| `takerAmount`   | uint256 | Amount the maker wants in return, scaled by 1e6 (always `1` for FOK orders)                                                                                                                                                                                                                                                                      |
| `expiration`    | uint256 | Must be `0`. Non-zero expiration is not currently supported and orders signed with a non-zero value are rejected.                                                                                                                                                                                                                                |
| `nonce`         | uint256 | Must be `0`. Non-zero nonce is not currently supported and orders signed with a non-zero value are rejected.                                                                                                                                                                                                                                     |
| `feeRateBps`    | uint256 | Fee rate in basis points. On fee-bearing markets (the market's `metadata.fee` flag is set) this must exactly equal your profile's `rank.feeRateBps` from [`GET /profiles/me`](/api-reference/portfolio/get-current-profile), or the order is rejected with `feeRateBps[...] is out of user's band`. Sign `0` only on markets without a fee flag. |
| `side`          | uint8   | `0` = BUY, `1` = SELL                                                                                                                                                                                                                                                                                                                            |
| `signatureType` | uint8   | `0` = EOA signature                                                                                                                                                                                                                                                                                                                              |

## Trading wallet mode: whose address signs

The backend validates `signer` and `maker` against your **profile's trading wallet mode** (`tradeWalletOption` on your profile), not against how you authenticate:

| Profile trading mode | Expected `maker`                | Expected `signer`                                              |
| -------------------- | ------------------------------- | -------------------------------------------------------------- |
| `eoa`                | your wallet address (`account`) | the same address                                               |
| `smartWallet`        | your smart-wallet address       | your embedded wallet address (a managed key you cannot export) |

An account connected with an external wallet can still be in `smartWallet` mode. Accepting the app's one-time "choose your trading wallet" prompt sets it, and the prompt does not reappear. In that state, every self-signed API order fails with:

```
400 — Signer does not match - you should use embedded address for smart wallet
```

Self-signed API orders need **`eoa` mode**. Switch it with an authenticated profile update (HMAC-signed like any other request):

```
PUT /profiles
{"tradeWalletOption": "eoa"}
```

The switch is immediate and reversible. Sending `{"tradeWalletOption": "smartWallet"}` restores the previous mode, since your profile keeps its stored smart-wallet association. One side effect: with `eoa` mode set, trading in the Limitless web app on this account runs through your raw wallet (a confirmation per action) instead of 1-click trading. For a dedicated bot or API account, that is usually the right end state.

<Note>
  The TypeScript SDK's `HttpClient` has no `put` helper. Send the request with any HMAC-signing HTTP client, or use the SDK's underlying axios instance (`client.http.client.put(...)`), which signs every verb.
</Note>

Two related errors from the same validation: `Signer does not match authenticated profile account` and `Maker does not match expected profile wallet` mean the respective field doesn't match the table above for your current mode.

## Order types

| Type                          | Description                                                                   |
| ----------------------------- | ----------------------------------------------------------------------------- |
| **GTC** (Good Till Cancelled) | Remains active until filled or cancelled                                      |
| **FAK** (Fill And Kill)       | Matches immediately available liquidity; any unmatched remainder is cancelled |
| **FOK** (Fill Or Kill)        | Must fill completely or be cancelled                                          |

## Amount calculation

USDC has **6 decimals** (1 USDC = 1,000,000 units). Shares are also scaled by **1e6**.

### GTC (limit orders)

| Side     | `makerAmount`                        | `takerAmount`                          |
| -------- | ------------------------------------ | -------------------------------------- |
| **BUY**  | `price * size * 1e6` (USDC to spend) | `size * 1e6` (shares to receive)       |
| **SELL** | `size * 1e6` (shares to sell)        | `price * size * 1e6` (USDC to receive) |

```
// BUY 10 shares at $0.50
makerAmount = 0.50 * 10 * 1e6 = 5,000,000
takerAmount = 10 * 1e6         = 10,000,000

// SELL 10 shares at $0.50
makerAmount = 10 * 1e6         = 10,000,000
takerAmount = 0.50 * 10 * 1e6  = 5,000,000
```

### FAK (fill-and-kill limit orders)

FAK orders build `makerAmount` and `takerAmount` with the same price/size formulas as GTC, but the matching engine treats the fields differently:

* `makerAmount` is the **hard spend cap** — the order tries to use the full amount (USDC to spend for BUY, shares to sell for SELL).
* `takerAmount` is a **protected minimum** — the minimum output implied by the signed price (shares to receive for BUY, USDC to receive for SELL), acting as slippage protection rather than a hard cap on matched size.
* Any portion not matched at or better than the signed price is cancelled; FAK never rests on the book.

`postOnly` is not supported for FAK.

### FOK (market orders)

| Side     | `makerAmount`        | `takerAmount`  |
| -------- | -------------------- | -------------- |
| **BUY**  | `usdcToSpend * 1e6`  | `1` (constant) |
| **SELL** | `sharesToSell * 1e6` | `1` (constant) |

FOK orders always set `takerAmount = 1` and omit `price`. The `makerAmount` represents the raw amount being offered.

<Note>
  The SDKs handle amount scaling automatically. You pass human-readable values (`price`, `size`, or `makerAmount`) and the builder calculates the scaled on-chain amounts.
</Note>
