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

# How to Trade Programmatically

> Trade Convallax options from your own code — discover markets, request a live quote, accept the best price, and settle the trade on-chain with a single transaction. Fully non-custodial.

This guide walks a trader through buying or selling a Convallax option **entirely from code** (e.g. a Node.js script with `ethers`). It's the same flow the website runs when you click **Trade** — just driven by you directly.

The mental model: trading is **two phases**.

1. **Price discovery (off-chain, HTTP).** You ask our backend for a price, market makers compete, and you accept the best quote. No wallet signing, no gas.
2. **Settlement (on-chain, one transaction).** You sign a single `fill()` transaction with your own wallet. This atomically pays the premium, locks any collateral, and mints your option tokens.

Your keys never leave your machine. The backend only coordinates pricing — it never holds your funds and never signs for you.

## What You Need

<Steps>
  <Step title="A funded wallet on Polygon Amoy">
    Any EVM wallet. You need **test USDC** for the premium (and collateral, if you sell) plus a little **POL** for gas. Get USDC from the faucet in the [dashboard](https://convallax.com/predict) or the [testnet guide](/guides/testnet).
  </Step>

  <Step title="No API key">
    Trading endpoints are **public** — no API key required. (API keys are only for market makers.) Your on-chain `fill()` transaction is your authorization.
  </Step>

  <Step title="One USDC approval">
    Before `fill()`, you grant a USDC allowance to the contract the backend tells you to:

    * **Buying (long):** approve the **Settlement** contract for the premium.
    * **Selling (short):** approve the **Core** contract for the collateral.

    The commit response returns the exact `spender` and `amount` in a `takerApproval` object — you don't have to compute it.
  </Step>
</Steps>

## The Four Steps

### 1. Discover what you can trade

Find the markets and series that exist on-chain. A trade can only settle against a registered series.

```bash theme={null}
# What markets are available?
curl https://api.convallax.com/v1/markets

# What series exist for a market? (filter by conditionId)
curl "https://api.convallax.com/v1/series?conditionId=0xa4ddc188...&optionType=call&settled=false"
```

From this you get the building blocks of a trade: the market's `conditionId` and `yesClobTokenId`, plus a `strikeBps`, `expiry`, and `optionType`. See [List Markets](/api-reference/series/markets) and [List Series](/api-reference/series/list).

### 2. Request a live quote

Open a quote request describing exactly what you want. The backend broadcasts it to all connected market makers.

```bash theme={null}
curl -X POST https://api.convallax.com/quote-requests \
  -H "Content-Type: application/json" \
  -d '{
    "wallet": "0xYourWallet...",
    "market": {
      "conditionId": "0xa4ddc188...",
      "yesTokenId": "51508280778...",
      "question": "Will there be a Hantavirus outbreak in 2026?"
    },
    "option": {
      "optionType": "call",
      "strikeBps": 50,
      "expiryMs": 1788220800000
    },
    "trade": { "side": "buy", "budgetUsd": 100 }
  }'
```

The `option` block fully identifies the contract (type, strike, expiry); makers price it using their own data and models.

<Note>
  **Sizing.** On a **buy** you submit a USDC budget (`trade.budgetUsd`). Makers quote a **per-option price**, and at commit you receive `floor(budgetUsd / price)` whole options (capped by the winning maker's quoted size), paying `contracts × price`. On a **sell** you submit a contract count instead: `"trade": { "side": "sell", "size": 100 }`.
</Note>

The response gives you a `requestId`:

```json theme={null}
{ "success": true, "requestId": "abc-123", "expiresAt": "...", "makersConnected": 2 }
```

<Info>
  No wallet signature is needed to open a quote request — your authorization happens later, at the on-chain `fill()`. See [Create Quote Request](/api-reference/trading/create-quote-request).
</Info>

### 3. Watch quotes, then accept the best

Quotes arrive within a second or two. Read the current best price, then commit when you're happy.

The recommended way to watch is the **SSE stream** (prices push to you live); polling also works.

```bash theme={null}
# Option A — stream live pricing (recommended)
curl -N https://api.convallax.com/quote-requests/abc-123/stream

# Option B — poll
curl https://api.convallax.com/quote-requests/abc-123/quotes
```

When you like the price, **commit**. You only send your wallet address — the backend selects the best valid quote and asks that maker to cryptographically sign the exact order:

```bash theme={null}
curl -X POST https://api.convallax.com/quote-requests/abc-123/commit \
  -H "Content-Type: application/json" \
  -d '{ "wallet": "0xYourWallet..." }'
```

The response hands you everything needed to settle on-chain, in the `onchain` object:

```json theme={null}
{
  "success": true,
  "message": "Order signed by maker — call fill() on-chain",
  "onchain": {
    "settlementAddress": "0x3E583BC4...",
    "coreAddress": "0x76c41a03...",
    "order": {
      "maker": "0xMarketMaker...",
      "seriesId": "...",
      "optionAmount": "100000000",
      "premiumAmount": "12000000",
      "makerSelling": true,
      "taker": "0xYourWallet...",
      "validUntil": 1750000000,
      "nonce": 12345
    },
    "makerSignature": "0x...",
    "takerApproval": { "spender": "0x3E583BC4...", "amount": "12000000", "reason": "premium" }
  }
}
```

You now hold the maker's **signature** authorizing this exact trade. Nothing has touched the chain yet. See [Commit](/api-reference/trading/commit).

### 4. Settle on-chain (`fill()`)

Two wallet actions — approve USDC, then call `fill()` with the order and the maker's signature. This single transaction atomically pulls the premium, locks the maker's collateral, and mints your option tokens.

```js theme={null}
import { ethers } from "ethers";

const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
const { settlementAddress, order, makerSignature, takerApproval } = res.onchain;

// 1. Approve USDC for the spender the backend specified
const usdc = new ethers.Contract(USDC_ADDRESS, [
  "function approve(address,uint256) returns (bool)",
  "function allowance(address,address) view returns (uint256)",
], wallet);

const current = await usdc.allowance(wallet.address, takerApproval.spender);
if (current < BigInt(takerApproval.amount)) {
  await (await usdc.approve(takerApproval.spender, takerApproval.amount)).wait();
}

// 2. Call fill() with the maker-signed order
const settlement = new ethers.Contract(settlementAddress, [
  "function fill((address maker,uint256 seriesId,uint256 optionAmount,uint256 premiumAmount,bool makerSelling,address taker,uint256 validUntil,uint256 nonce) order, bytes makerSignature)",
], wallet);

const tx = await settlement.fill(order, makerSignature);
await tx.wait();
console.log("Filled:", tx.hash);
```

That's it — you now hold the option tokens (an ERC-1155 balance keyed by `seriesId`).

<Warning>
  Commit and fill promptly. The signed order has a short `validUntil` window; if it expires before your `fill()` lands, re-commit to get a fresh signature.
</Warning>

## The Whole Flow

```js theme={null}
// 1. Discover
const { series } = await get("/v1/series?conditionId=0x...&optionType=call&settled=false");

// 2. Request a quote
const { requestId } = await post("/quote-requests", { wallet, market, option, trade });

// 3. Watch, then accept
await waitForGoodPrice(`/quote-requests/${requestId}/stream`);
const { onchain } = await post(`/quote-requests/${requestId}/commit`, { wallet });

// 4. Settle on-chain
await usdc.approve(onchain.takerApproval.spender, onchain.takerApproval.amount);
await settlement.fill(onchain.order, onchain.makerSignature);
```

Steps 1–3 are ordinary HTTP — no wallet, no gas. Only step 4 touches the chain.

## After the Trade

* **Check your position:** your option tokens are an ERC-1155 balance on `ConvallaxOptionToken`, keyed by `seriesId`. See [Verify Your Positions](/guides/testnet#verify-your-positions).
* **At expiry:** once the series is settled, holders claim their payout with [`claimHolderPayout`](/api-reference/contracts/claim-holder). See the [Settlement guide](/guides/settlement) for how resolution works.

## Why a Signature, Not a Custodial Order Book?

Convallax is **non-custodial**. The maker signs "I agree to these exact terms," and your `fill()` redeems that signature on-chain. Neither side can alter the terms, and the backend never touches anyone's funds or keys — it's purely a matchmaker for price discovery.
