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

# Testnet & Mainnet

> How to develop on SX Bet testnet and switch to mainnet when you're ready.

## Overview

SX Bet runs a full testnet environment (called **Toronto**) that mirrors mainnet. Use testnet to develop and test your integration without risking real funds, then switch to mainnet by updating a few configuration values.

## Testnet setup

### 1. Create a testnet account

Sign up at [toronto.sx.bet](https://toronto.sx.bet) and export your private key from the assets page, the same way you would on mainnet.

### 2. Get testnet funds

Open a support chat on [sx.bet](https://sx.bet) to receive testnet USDC.

### 3. Enable betting on testnet

Approve the `TokenTransferProxy` on the testnet chain. The simplest way is to place a test bet through the [toronto.sx.bet](https://toronto.sx.bet) UI. To do it programmatically, use [POST /orders/approve](/api-reference/post-approve) with the testnet RPC URL and contract addresses below.

## Configuration reference

Everything that differs between testnet and mainnet:

| Setting          | Testnet (Toronto)                              | Mainnet                                      |
| ---------------- | ---------------------------------------------- | -------------------------------------------- |
| **API Base URL** | `https://api.toronto.sx.bet`                   | `https://api.sx.bet`                         |
| **App URL**      | `https://toronto.sx.bet`                       | `https://sx.bet`                             |
| **Chain ID**     | `79479957`                                     | `4162`                                       |
| **RPC URL**      | `https://rpc-rollup.toronto.sx.technology`     | `https://rpc-rollup.sx.technology`           |
| **Explorer API** | `https://explorerl2.toronto.sx.technology/api` | `https://explorerl2.sx.technology/api`       |
| **USDC Address** | `0x1BC6326EA6aF2aB8E4b6Bc83418044B1923b2956`   | `0x6629Ce1Cf35Cc1329ebB4F63202F3f197b3F050B` |
| **Metadata**     | `https://api.toronto.sx.bet/metadata`          | `https://api.sx.bet/metadata`                |

<Warning>The `executor`, `EIP712FillHasher`, and `TokenTransferProxy` addresses are also different between environments. You can fetch them from the `/metadata` endpoint.</Warning>

## Structuring your code for easy switching

The cleanest approach is to store all environment-specific values in a config object and swap based on an environment variable:

<CodeGroup>
  ```python Python theme={null}
  import os

  ENV = os.environ.get("SX_ENV", "testnet")

  CONFIG = {
      "testnet": {
          "api_url": "https://api.toronto.sx.bet",
          "chain_id": 79479957,
          "rpc_url": "https://rpc-rollup.toronto.sx.technology",
          "usdc_address": "0x1BC6326EA6aF2aB8E4b6Bc83418044B1923b2956",
          "wsx_address": "0x5c02932f8422D943647682E95c87ea0333191e08",
          "explorer_api": "https://explorerl2.toronto.sx.technology/api",
      },
      "mainnet": {
          "api_url": "https://api.sx.bet",
          "chain_id": 4162,
          "rpc_url": "https://rpc-rollup.sx.technology",
          "usdc_address": "0x6629Ce1Cf35Cc1329ebB4F63202F3f197b3F050B",
          "wsx_address": "0x3E96B0a25d51e3Cc89C557f152797c33B839968f",
          "explorer_api": "https://explorerl2.sx.technology/api",
      },
  }

  cfg = CONFIG[ENV]

  # Fetch executor and TokenTransferProxy from metadata — these differ per network
  import requests
  metadata = requests.get(f"{cfg['api_url']}/metadata").json()["data"]
  cfg["executor"] = metadata["executorAddress"]
  cfg["token_transfer_proxy"] = metadata["TokenTransferProxy"]
  cfg["domain_version"] = metadata["domainVersion"]
  cfg["eip712_fill_hasher"] = metadata["EIP712FillHasher"]
  ```

  ```javascript JavaScript theme={null}
  const ENV = process.env.SX_ENV || "testnet";

  const CONFIG = {
    testnet: {
      apiUrl: "https://api.toronto.sx.bet",
      chainId: 79479957,
      rpcUrl: "https://rpc-rollup.toronto.sx.technology",
      usdcAddress: "0x1BC6326EA6aF2aB8E4b6Bc83418044B1923b2956",
      wsxAddress: "0x5c02932f8422D943647682E95c87ea0333191e08",
      explorerApi: "https://explorerl2.toronto.sx.technology/api",
    },
    mainnet: {
      apiUrl: "https://api.sx.bet",
      chainId: 4162,
      rpcUrl: "https://rpc-rollup.sx.technology",
      usdcAddress: "0x6629Ce1Cf35Cc1329ebB4F63202F3f197b3F050B",
      wsxAddress: "0x3E96B0a25d51e3Cc89C557f152797c33B839968f",
      explorerApi: "https://explorerl2.sx.technology/api",
    },
  };

  const cfg = CONFIG[ENV];

  // Fetch executor and TokenTransferProxy from metadata — these differ per network
  const metadata = await fetch(`${cfg.apiUrl}/metadata`).then((r) => r.json()).then((r) => r.data);
  cfg.executor = metadata.executorAddress;
  cfg.tokenTransferProxy = metadata.TokenTransferProxy;
  cfg.domainVersion = metadata.domainVersion;
  cfg.eip712FillHasher = metadata.EIP712FillHasher;
  ```
</CodeGroup>

Then reference `cfg` everywhere instead of hardcoding values:

<CodeGroup>
  ```python Python theme={null}
  # API calls use cfg["api_url"]
  markets = requests.get(f"{cfg['api_url']}/markets/active").json()

  # Fill signing domain uses cfg["chain_id"] and values from metadata
  DOMAIN = {
      "name": "SX Bet",
      "version": cfg["domain_version"],
      "chainId": cfg["chain_id"],
      "verifyingContract": cfg["eip712_fill_hasher"],
  }

  # Token addresses use cfg
  base_token = cfg["usdc_address"]
  ```

  ```javascript JavaScript theme={null}
  // API calls use cfg.apiUrl
  const markets = await fetch(`${cfg.apiUrl}/markets/active`).then((r) => r.json());

  // Fill signing domain uses cfg.chainId and values from metadata
  const DOMAIN = {
    name: "SX Bet",
    version: cfg.domainVersion,
    chainId: cfg.chainId,
    verifyingContract: cfg.eip712FillHasher,
  };

  // Token addresses use cfg
  const baseToken = cfg.usdcAddress;
  ```
</CodeGroup>

To switch to mainnet, change one environment variable:

```bash theme={null}
# Testnet (default)
SX_ENV=testnet node your-bot.js

# Mainnet
SX_ENV=mainnet node your-bot.js
```

## Switching to mainnet checklist

When you're ready to go live:

* [ ] Set `SX_ENV=mainnet` (or update your config to use mainnet values)
* [ ] Use your **mainnet** private key and API key (testnet keys won't work on mainnet)
* [ ] Fund your mainnet wallet with USDC
* [ ] Approve the `TokenTransferProxy` on mainnet — either through [sx.bet](https://sx.bet) or [programmatically](/api-reference/post-approve)
* [ ] Confirm your fill signing domain uses chain ID `4162` and `EIP712FillHasher` from `/metadata` as `verifyingContract`
* [ ] Test with a small order before scaling up

## Common pitfalls

### Wrong chain ID in signatures

If you see `TAKER_SIGNATURE_MISMATCH` or orders being rejected, check that your signing domain's `chainId` matches the network you're targeting. Testnet is `79479957`, mainnet is `4162`.

### Wrong token addresses

USDC has different contract addresses on each network. Using a testnet token address on mainnet (or vice versa) will result in `BAD_BASE_TOKEN` errors.

### Hardcoded executor or TokenTransferProxy

These addresses differ between networks. You can fetch them from [`GET /metadata`](/api-reference/get-metadata) at startup and cache them in your config.

### Testnet API key on mainnet

API keys are network-specific. Generate a separate key for each environment.

## Related

<CardGroup cols={2}>
  <Card title="References →" icon="link" href="/api-reference/references">
    Full list of addresses, URLs, and chain IDs.
  </Card>

  <Card title="Approve Token Spending →" icon="toggle-on" href="/api-reference/post-approve">
    Approve the TokenTransferProxy for trading.
  </Card>

  <Card title="Querying Balances →" icon="wallet" href="/developers/querying-balances">
    Check your balance on either network.
  </Card>

  <Card title="Quickstart →" icon="rocket" href="/developers/quickstart">
    End-to-end guide from setup to first fill.
  </Card>
</CardGroup>
