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

# Polymarket

> Build gasless prediction market applications with Magic and Polymarket's Builder Program

## Overview

Polymarket's Builders Program enables developers to integrate prediction markets into their applications with gasless trading and builder order attribution. This guide demonstrates how to use Magic's passwordless authentication with Polymarket's CLOB Client and Builder Relayer Client.

This guide covers the Safe Wallet implementation using Magic authentication for gasless prediction market trading.

<Card title="Magic Safe Builder Example" icon="github" href="https://github.com/Polymarket/magic-safe-builder-example">
  Complete Next.js application showing Magic authentication with Safe wallet deployment for Polymarket trading.
</Card>

***

## Prerequisites

Before starting, ensure you have:

1. A Magic **Publishable** API Key from your [Magic Dashboard](https://dashboard.magic.link)
2. Polymarket Builder credentials (Builder ID and signing key)
3. A Polygon RPC endpoint

### Safe Wallet Architecture

The Safe Wallet flow uses Magic SDK for authentication and the Builder Relayer Client to deploy Gnosis Safe wallets:

1. User authenticates with Magic (Email OTP or Social Login)
2. Magic SDK creates an EOA signer for the user
3. Builder Relayer Client deploys a Gnosis Safe wallet
4. Token approvals are set via the Relayer
5. User API credentials are generated by initializing a temporary ClobClient with the Magic signer and calling `deriveApiKey()` or `createApiKey()`.
6. Authenticated ClobClient is initialized for trading

<Warning>
  Store Builder credentials server-side only. Never expose signing keys in client code.
</Warning>

For the complete implementation with step-by-step code, see the [magic-safe-builder-example](https://github.com/Polymarket/magic-safe-builder-example) repository.

***

## Placing Orders

With the authenticated ClobClient, you can place market and limit orders.

<Tabs>
  <Tab title="Market Orders">
    ```typescript TypeScript icon="square-js" theme={null}
    import { Side, OrderType } from "@polymarket/clob-client";

    async function submitMarketOrder(
      clobClient: ClobClient,
      tokenId: string,
      size: number,
      side: "BUY" | "SELL",
      negRisk: boolean = false
    ) {
      // Get current price from orderbook
      const oppositeSide = side === "BUY" ? Side.SELL : Side.BUY;
      const priceResponse = await clobClient.getPrice(tokenId, oppositeSide);
      const marketPrice = parseFloat(priceResponse.price);

      // Apply aggressive pricing for immediate fills
      let aggressivePrice: number;
      if (side === "BUY") {
        aggressivePrice = Math.min(0.99, marketPrice * 1.05); // +5% above market
      } else {
        aggressivePrice = Math.max(0.01, marketPrice * 0.95); // -5% below market
      }

      const order = {
        tokenID: tokenId,
        price: aggressivePrice,
        size: size,
        side: side === "BUY" ? Side.BUY : Side.SELL,
        feeRateBps: 0,
        expiration: 0,
        taker: "0x0000000000000000000000000000000000000000",
      };

      const response = await clobClient.createAndPostOrder(
        order,
        { negRisk },
        OrderType.GTC
      );

      return response.orderID;
    }
    ```

    <Info>
      Polymarket's CLOB doesn't have true "market orders". Market orders are simulated using limit orders with aggressive pricing that fills immediately.
    </Info>
  </Tab>

  <Tab title="Limit Orders">
    ```typescript TypeScript icon="square-js" theme={null}
    import { Side, OrderType } from "@polymarket/clob-client";

    async function submitLimitOrder(
      clobClient: ClobClient,
      tokenId: string,
      price: number,
      size: number,
      side: "BUY" | "SELL",
      negRisk: boolean = false
    ) {
      const order = {
        tokenID: tokenId,
        price: price,         // User-specified (0.01 to 0.99)
        size: size,
        side: side === "BUY" ? Side.BUY : Side.SELL,
        feeRateBps: 0,
        expiration: 0,        // 0 = Good-til-Cancel
        taker: "0x0000000000000000000000000000000000000000",
      };

      const response = await clobClient.createAndPostOrder(
        order,
        { negRisk },
        OrderType.GTC
      );

      return response.orderID;
    }
    ```
  </Tab>
</Tabs>

**Order Execution:**

* Orders are signed by the user's EOA (Magic wallet)
* Executed from the Safe wallet address
* **Gasless execution** - no gas fees for users
* Prompts user signature for each order

***

## Position & Order Management

### Fetch User Positions

```typescript TypeScript icon="square-js" theme={null}
// Fetch from Polymarket Data API
const response = await fetch(
  `https://data-api.polymarket.com/positions?user=${safeAddress}&sizeThreshold=0.01&limit=500`
);
const positions = await response.json();
```

### Fetch Active Orders

```typescript TypeScript icon="square-js" theme={null}
// Fetch from CLOB client
const allOrders = await clobClient.getOpenOrders();
const userOrders = allOrders.filter(
  (order) =>
    order.maker_address.toLowerCase() === safeAddress.toLowerCase() &&
    order.status === "LIVE"
);
```

### Cancel Order

```typescript TypeScript icon="square-js" theme={null}
await clobClient.cancelOrder({ orderID: orderId });
```

***

## Token Addresses

Important contract addresses on Polygon:

```typescript TypeScript icon="square-js" theme={null}
// USDC.e (Bridged USDC) - The trading currency
export const USDC_E_ADDRESS = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
export const USDC_E_DECIMALS = 6;

// Conditional Token Framework
export const CTF_ADDRESS = "0x4d97dcd97ec945f40cf65f87097ace5ea0476045";

// Exchanges
export const CTF_EXCHANGE = "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E";
export const NEG_RISK_CTF_EXCHANGE = "0xC5d563A36AE78145C45a50134d48A1215220f80a";
export const NEG_RISK_ADAPTER = "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296";
```

***

## Key Dependencies

| Package                                                                                      | Version | Purpose                               |
| -------------------------------------------------------------------------------------------- | ------- | ------------------------------------- |
| [`@polymarket/clob-client`](https://github.com/Polymarket/clob-client)                       | ^4.22.8 | Order placement, User API credentials |
| [`@polymarket/builder-relayer-client`](https://github.com/Polymarket/builder-relayer-client) | ^0.0.8  | Safe deployment, token approvals      |
| [`@polymarket/builder-signing-sdk`](https://github.com/Polymarket/builder-signing-sdk)       | ^0.0.8  | Builder configuration                 |
| [`magic-sdk`](https://www.npmjs.com/package/magic-sdk)                                       | latest  | Magic authentication                  |
| [`ethers`](https://docs.ethers.org/v5/)                                                      | ^5.8.0  | Wallet creation, signing              |
| [`viem`](https://viem.sh/)                                                                   | ^2.39.2 | Ethereum interactions                 |

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Safe deployment fails">
    **Symptoms:** Cannot deploy Safe wallet

    **Solutions:**

    * Ensure Builder credentials are valid
    * Check that the Relayer service is accessible
    * Verify the Magic user is authenticated
    * Check server-side logs for signing errors
  </Accordion>

  <Accordion title="CLOB client not initialized">
    **Symptoms:** Cannot place orders, trading session incomplete

    **Solutions:**

    * Click "Initialize Trading Session" button
    * Ensure Magic authentication is valid
    * Check browser console for authentication errors
    * Verify User API Credentials were obtained successfully
  </Accordion>

  <Accordion title="Balance shows $0.00">
    **Symptoms:** USDC.e balance appears as zero

    **Solutions:**

    * Fund the **Safe Wallet**, not the EOA
    * Check [Polygonscan](https://polygonscan.com) for confirmation
    * Verify RPC endpoint is working in `.env.local`
    * The wallet address is shown in the header UI
  </Accordion>

  <Accordion title="Orders not appearing">
    **Symptoms:** Orders submitted but not visible

    **Solutions:**

    * Wait 2-3 seconds for CLOB sync
    * Check USDC.e balance (need funds to trade)
    * Verify order was submitted successfully in browser console
    * Ensure the wallet is properly funded
  </Accordion>
</AccordionGroup>

***

## Resources

<CardGroup cols={2}>
  <Card title="Safe Wallet Demo" icon="github" href="https://github.com/Polymarket/magic-safe-builder-example">
    Complete implementation with Magic authentication
  </Card>

  <Card title="CLOB Client Docs" icon="book" href="https://docs.polymarket.com/developers/CLOB/clients">
    Official Polymarket CLOB client documentation
  </Card>

  <Card title="Authentication Guide" icon="key" href="https://docs.polymarket.com/developers/CLOB/authentication">
    Learn about Polymarket's authentication flow
  </Card>

  <Card title="Order Placement" icon="shopping-cart" href="https://docs.polymarket.com/quickstart/orders/first-order">
    Guide to placing your first order
  </Card>
</CardGroup>

***
