Add scraped Polymarket documentation (117 files)

This commit is contained in:
Etherdrake
2026-02-14 12:59:26 +01:00
parent 26c6b35691
commit 9263557be6
119 changed files with 27955 additions and 0 deletions
@@ -0,0 +1,70 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Blockchain Data Resources
> Access Polymarket on-chain activity for data & analytics
Polymarket data that lands on the blockchain, such as trades, balances, positions, and redeems, is available through various on-chain analytics platforms and blockchain data providers. Polymarket also provides its own APIs and WebSockets. See the [API Endpoints reference](/quickstart/reference/endpoints) for more information.
The purpose of this page is to serve as a public good for Polymarket builders, researches, and analysts alike.
***
## Data
### Goldsky
[Goldsky](https://docs.goldsky.com/chains/polymarket) provides real-time streaming pipelines for Polymarket on-chain activity (i.e. trades, balances, positions, etc...) into your own database/data warehouse.
Goldsky also partnered with [ClickHouse](https://clickhouse.com) to create [CryptoHouse](https://crypto.clickhouse.com), where you can query Polymarket on-chain data using SQL.
### Dune
[Dune](https://dune.com) is a blockchain analytics platform that has Polymarket on-chain activity (i.e. trades, balances, positions, etc...). Query Polymarket data using SQL, create custom dashboards, and more.
Here are a few simple queries to get started:
| Query | Description | Link |
| ------------- | --------------------------------------------- | --------------------------------------------------- |
| Volume | Notional Volume and Maker & Taker USDC Volume | [View Dune Query](https://dune.com/queries/6545441) |
| TVL | USDC locked in Polymarket smart contracts | [View Dune Query](https://dune.com/queries/6588784) |
| Open Interest | Estimated market open interest, and over time | [View Dune Query](https://dune.com/queries/6555478) |
### Allium
[Allium](https://docs.allium.so/historical-data/predictions) is a blockchain analytics platform that has Polymarket on-chain activity (i.e. trades, balances, positions, etc...). Query Polymarket data using SQL, create custom dashboards, and more.
\--
## Dashboards
Third-party blockchain analytics platforms that aggregate and visualize Polymarket data:
<CardGroup cols={4}>
<Card title="Blockworks" img="https://pbs.twimg.com/profile_images/1651677302634483712/7s2FxV2K_400x400.jpg" href="https://blockworks.com/analytics/polymarket" />
<Card title="Artemis" img="https://pbs.twimg.com/profile_images/1896982195723546624/2XeO9mPb_400x400.png" href="https://app.artemisanalytics.com/asset/polymarket?from=assets" />
<Card title="Dune" img="https://pbs.twimg.com/profile_images/1986458079248986112/qq80s3hx_400x400.jpg" href="https://dune.com/discover/content/popular?q=polymarket&resource-type=dashboards" />
<Card title="DeFiLlama" img="https://pbs.twimg.com/profile_images/1915756547705036800/rAeLzZqs_400x400.jpg" href="https://defillama.com/protocol/polymarket" />
<Card title="The Block" img="https://pbs.twimg.com/profile_images/1944749695525425152/9babG7Df_400x400.jpg" href="https://www.theblock.co/data/decentralized-finance/prediction-markets-and-betting" />
<Card title="Token Terminal" img="https://pbs.twimg.com/profile_images/1594678659222306817/SMum_RcQ_400x400.jpg" href="https://tokenterminal.com/explorer/projects/polymarket" />
<Card title="Allium" img="https://pbs.twimg.com/profile_images/1778926940407132160/UEwR3lHt_400x400.jpg" href="https://predictions.allium.so" />
</CardGroup>
### Community Dashboards
Community-created Dune dashboards of Polymarket on-chain analytics:
| Dashboard | Created By | Link |
| ------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------- |
| Polymarket Overview | [@datadashboards](https://x.com/datadashboards) | [View Dashboard](https://dune.com/datadashboards/polymarket-overview) |
| Polymarket Volume, OI, Markets, Addresses and TVL | [@hildobby](https://x.com/hildobby) | [View Dashboard](https://dune.com/hildobby/polymarket) |
| Polymarket Historical Accuracy | [@alexmccullaaa](https://x.com/alexmccullaaa) | [View Dashboard](https://dune.com/alexmccullough/how-accurate-is-polymarket) |
| Polymarket Builders Dashboard | [@defioasis](https://x.com/defioasis) | [View Dashboard](https://dune.com/gateresearch/pmbuilders) |
+102
View File
@@ -0,0 +1,102 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Builder Program Introduction
> Learn about Polymarket's Builder Program and how to integrate
## What is a Builder?
A "builder" is a person, group, or organization that routes orders from their users to Polymarket.
If you've created a platform that allows users to trade on Polymarket via your system, this program is for you.
***
## Program Benefits
<CardGroup cols={3}>
<Card title="Relayer Access" icon="gas-pump">
All onchain operations are gasless through our relayer
</Card>
<Card title="Order Attribution" icon="tag">
Get credited for orders and compete for weekly rewards on the Builder Leaderboard
</Card>
<Card title="Fee Share" icon="percent">
Earn a share of fees on routed orders
</Card>
</CardGroup>
### Relayer Access
We expose our relayer to builders, providing gasless transactions for users with
Polymarket's Proxy Wallets deployed via [Relayer Client](/developers/builders/relayer-client).
When transactions are routed through proxy wallets, Polymarket pays all gas fees for:
* Deploying Gnosis Safe Wallets or Custom Proxy (Magic Link users) Wallets
* Token approvals (USDC, outcome tokens)
* CTF operations (split, merge, redeem)
* Order execution (via [CLOB API](/developers/CLOB/introduction))
<Warning>
EOA wallets do not have relayer access. Users trading directly from an EOA pay their own gas fees.
</Warning>
### Trading Attribution
Attach custom headers to orders to identify your builder account:
* Orders attributed to your builder account
* Compete on the [Builder Leaderboard](https://builders.polymarket.com/) for weekly rewards
* Track performance via the Data API
* [Leaderboard API](/api-reference/builders/get-aggregated-builder-leaderboard): Get aggregated builder rankings for a time period
* [Volume API](/api-reference/builders/get-daily-builder-volume-time-series): Get daily time-series volume data for trend analysis
***
## Getting Started
1. **Get Builder Credentials**: Generate API keys from your [Builder Profile](/developers/builders/builder-profile)
2. **Configure Order Attribution**: Set up CLOB client to credit trades to your account ([guide](/developers/builders/order-attribution))
3. **Enable Gasless Transactions**: Use the Relayer for gas-free wallet deployment and trading ([guide](/developers/builders/relayer-client))
<Tip>
See [Example Apps](/developers/builders/examples) for complete Next.js reference implementations.
</Tip>
***
## SDKs & Libraries
<CardGroup cols={3}>
<Card title="CLOB Client (TypeScript)" icon="github" href="https://github.com/Polymarket/clob-client">
Place orders with builder attribution
</Card>
<Card title="CLOB Client (Python)" icon="github" href="https://github.com/Polymarket/py-clob-client">
Place orders with builder attribution
</Card>
<Card title="CLOB Client (Rust)" icon="github" href="https://github.com/Polymarket/rs-clob-client">
Place orders with builder attribution
</Card>
<Card title="Relayer Client (TypeScript)" icon="github" href="https://github.com/Polymarket/builder-relayer-client">
Gasless onchain transactions for your users
</Card>
<Card title="Relayer Client (Python)" icon="github" href="https://github.com/Polymarket/py-builder-relayer-client">
Gasless onchain transactions for your users
</Card>
<Card title="Signing SDK (TypeScript)" icon="github" href="https://github.com/Polymarket/builder-signing-sdk">
Sign builder authentication headers
</Card>
<Card title="Signing SDK (Python)" icon="github" href="https://github.com/Polymarket/py-builder-signing-sdk">
Sign builder authentication headers
</Card>
</CardGroup>
@@ -0,0 +1,76 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Builder Profile & Keys
> Learn how to access your builder profile and obtain API credentials
## Accessing Your Builder Profile
<CardGroup cols={2}>
<Card title="Direct Link" icon="link">
Go to [polymarket.com/settings?tab=builder](https://polymarket.com/settings?tab=builder)
</Card>
<Card title="From Profile Menu" icon="user">
Click your profile image and Select "Builders"
</Card>
</CardGroup>
***
## Builder Profile Settings
<img src="https://mintcdn.com/polymarket-292d1b1b/Quu9lXyXHL-5rjVX/images/builder-profile-image.png?fit=max&auto=format&n=Quu9lXyXHL-5rjVX&q=85&s=67176050b411016e3bfea47bc6fd8fbb" alt="Builder Settings Page" data-og-width="1854" width="1854" data-og-height="1056" height="1056" data-path="images/builder-profile-image.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/polymarket-292d1b1b/Quu9lXyXHL-5rjVX/images/builder-profile-image.png?w=280&fit=max&auto=format&n=Quu9lXyXHL-5rjVX&q=85&s=539b92c0a46959d583d603849459e8df 280w, https://mintcdn.com/polymarket-292d1b1b/Quu9lXyXHL-5rjVX/images/builder-profile-image.png?w=560&fit=max&auto=format&n=Quu9lXyXHL-5rjVX&q=85&s=e7141165754009d3942946b53817feb8 560w, https://mintcdn.com/polymarket-292d1b1b/Quu9lXyXHL-5rjVX/images/builder-profile-image.png?w=840&fit=max&auto=format&n=Quu9lXyXHL-5rjVX&q=85&s=1ec3abc842204033dc99acc2a1fdd9bf 840w, https://mintcdn.com/polymarket-292d1b1b/Quu9lXyXHL-5rjVX/images/builder-profile-image.png?w=1100&fit=max&auto=format&n=Quu9lXyXHL-5rjVX&q=85&s=33d5ca2e18a9267289c1075a0b6d2413 1100w, https://mintcdn.com/polymarket-292d1b1b/Quu9lXyXHL-5rjVX/images/builder-profile-image.png?w=1650&fit=max&auto=format&n=Quu9lXyXHL-5rjVX&q=85&s=5ee84537ae2c108a23f01a19581f2783 1650w, https://mintcdn.com/polymarket-292d1b1b/Quu9lXyXHL-5rjVX/images/builder-profile-image.png?w=2500&fit=max&auto=format&n=Quu9lXyXHL-5rjVX&q=85&s=ed471a4141f2e55fba0f16ad0b70aa38 2500w" />
### Customize Your Builder Identity
* **Profile Picture**: Upload a custom image for the [Builder Leaderboard](https://builders.polymarket.com/)
* **Builder Name**: Set the name displayed publicly on the leaderboard
### View Your Builder Information
* **Builder Address**: Your unique builder address for identification
* **Creation Date**: When your builder account was created
* **Current Tier**: Your rate limit tier (Unverified or Verified)
***
## Builder API Keys
Builder API keys are required to access the relayer and for CLOB order attribution.
### Creating API Keys
In the **Builder Keys** section of your profile's **Builder Settings**:
1. View existing API keys with their creation dates and status
2. Click **"+ Create New"** to generate a new API key
Each API key includes:
| Credential | Description |
| ------------ | ------------------------------------ |
| `apiKey` | Your builder API key identifier |
| `secret` | Secret key for signing requests |
| `passphrase` | Additional authentication passphrase |
### Managing API Keys
* **Multiple Keys**: Create separate keys for different environments
* **Active Status**: Keys show "ACTIVE" when operational
***
## Next Steps
<CardGroup cols={2}>
<Card title="Order Attribution" icon="tag" href="/developers/builders/order-attribution">
Start attributing customer orders to your account
</Card>
<Card title="Builder Leaderboard" icon="trophy" href="https://builders.polymarket.com/">
View your public profile and stats
</Card>
</CardGroup>
+151
View File
@@ -0,0 +1,151 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Builder Tiers
> Permissionless integration with tiered rate limits, rewards, and revenue generating opportunities as you scale
## Overview
Polymarket Builders lets anyone integrate without approval.
Tiers exist to manage rate limits while rewarding high performing integrations with weekly rewards and revenue sharing opportunities. Higher tiers also unlock engineering support, marketing promotion, and priority access.
## Feature Definitions
| Feature | Description |
| --------------------------- | -------------------------------------------------------------------------- |
| **Daily Relayer Txn Limit** | Maximum Relayer transactions per day for Safe/Proxy wallet operations |
| **API Rate Limits** | Rate limits for non-relayer endpoints (CLOB, Gamma, etc.) |
| **Subsidized Transactions** | Gas fees subsidized for Relayer and CLOB operations via Safe/Proxy wallets |
| **Order Attribution** | Orders tracked and attributed to your Builder profile |
| **RevShare Protocol** | Infrastructure allowing Builders to charge fees |
| **Leaderboard Visibility** | Visibility on the [Builder leaderboard](https://builders.polymarket.com/) |
| **Weekly Rewards** | Weekly USDC rewards program for visible builders based on volume |
| **Telegram Channel** | Private Builders channel for announcements and support |
| **Badge** | Verified Builder affiliate badge on your Builder profile |
| **Engineering Support** | Direct access to engineering team |
| **Marketing Support** | Promotion via official Polymarket social accounts |
| **Weekly Rewards Boost** | Multiplier on the weekly USDC rewards program for visible builders |
| **Priority Access** | Early access to new features and products |
## Tier Comparison
| Feature | Unverified | Verified | Partner |
| --------------------------- | :--------: | :-------: | :-------: |
| **Daily Relayer Txn Limit** | 100/day | 3,000/day | Unlimited |
| **API Rate Limits** | Standard | Standard | Highest |
| **Subsidized Transactions** | ✅ | ✅ | ✅ |
| **Order Attribution** | ✅ | ✅ | ✅ |
| **RevShare Protocol** | ❌ | ✅ | ✅ |
| **Leaderboard Visibility** | ❌ | ✅ | ✅ |
| **Weekly Rewards** | ❌ | ✅ | ✅ |
| **Telegram Channel** | ❌ | ✅ | ✅ |
| **Badge** | ❌ | ✅ | ✅ |
| **Engineering Support** | ❌ | Standard | Elevated |
| **Marketing Support** | ❌ | Standard | Elevated |
| **Weekly Reward Boosts** | ❌ | ❌ | ✅ |
| **Priority Access** | ❌ | ❌ | ✅ |
***
### Unverified
<Card title="100 transactions/day" icon="seedling">
The default tier for all new builders. Create Builder API keys instantly from your Polymarket profile.
</Card>
**How to get started:**
1. Go to [polymarket.com/settings?tab=builder](https://polymarket.com/settings?tab=builder)
2. Create a builder profile and click **"+ Create New"** to generate builder API keys
3. Implement [builder signing](/developers/builders/order-attribution); required for Relayer access and CLOB order attribution
**Included:**
* Gasless trading on all CLOB orders through Safe/Proxy wallets
* Gas subsidized on all Relayer transactions through Safe/Proxy wallets up to daily limit
* Order attribution credit to your Builder profile
* Access to all client libraries and documentation
***
### Verified
<Card title="3,000 transactions/day" icon="badge-check">
For builders who need higher throughput. Requires manual approval by Polymarket.
</Card>
**How to upgrade:**
Contact us with your Builder API Key, use case, expected volume, and relevant info (app, docs, X profile).
**Unlocks over Unverified:**
* 15x daily Relayer transaction limit
* RevShare Protocol Access
* Telegram channel
* Leaderboard visibility
* Eligible for Weekly Rewards Program
* Promotion and verified affiliate badge from @PolymarketBuild
***
### Partner
<Card title="Unlimited transactions/day" icon="handshake">
Enterprise tier for high-volume integrations and strategic partners.
</Card>
**How to apply:**
Reach out to discuss partnership opportunities.
**Unlocks over Verified:**
* Unlimited Relayer transactions
* Highest API rate limits
* Elevated engineering support
* Elevated and coordinated marketing support
* Priority access to new features and products
* Multiplier on the Weekly Rewards Program
***
## Contact
Ready to upgrade or have questions?
* [builder@polymarket.com](mailto:builder@polymarket.com)
***
## FAQ
<AccordionGroup>
<Accordion title="How do I know if I'm verified?">
Verification is displayed in your [Builder Profile](https://polymarket.com/settings?tab=builder) settings.
</Accordion>
<Accordion title="What happens if I exceed my daily limit?">
Relayer requests beyond your daily limit will be rate-limited and return an error. Consider upgrading to Verified or Partner tier if you're hitting limits.
</Accordion>
<Accordion title="Can I get a temporary limit increase?">
For special events or product launches, contact [builder@polymarket.com](mailto:builder@polymarket.com)
</Accordion>
</AccordionGroup>
***
## Next Steps
<CardGroup cols={2}>
<Card title="Get Your Builder Keys" icon="key" href="/developers/builders/builder-profile">
Create Builder API credentials to get started
</Card>
<Card title="Use Your Builder Keys" icon="server" href="/developers/builders/relayer-client">
Configure Builder API credentials to attribute orders
</Card>
</CardGroup>
@@ -0,0 +1,358 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Order Attribution
> Learn how to attribute orders to your builder account
## Overview
The [CLOB (Central Limit Order Book)](/developers/CLOB/introduction) is Polymarket's order matching system. Order attribution adds builder authentication headers when placing orders through the CLOB Client, enabling Polymarket to credit trades to your builder account. This allows you to:
* Track volume on the [Builder Leaderboard](https://builders.polymarket.com/)
* Monitor performance via the Data API
***
## Builder API Credentials
Each builder receives API credentials from their [Builder Profile](/developers/builders/builder-profile):
| Credential | Description |
| ------------ | ------------------------------------ |
| `key` | Your builder API key identifier |
| `secret` | Secret key for signing requests |
| `passphrase` | Additional authentication passphrase |
<Warning>
**Security Notice**: Your Builder API keys must be kept secure. Never expose them in client-side code.
</Warning>
***
## Signing Methods
<Tabs>
<Tab title="Remote Signing (Recommended)">
Remote signing keeps your credentials secure on a server you control.
**How it works:**
1. User signs an order payload
2. Payload is sent to your builder signing server
3. Your server adds builder authentication headers
4. Complete order is sent to the CLOB
### Server Implementation
Your signing server receives request details and returns the authentication headers. Use the `buildHmacSignature` function from the SDK:
<CodeGroup>
```typescript TypeScript theme={null}
import {
buildHmacSignature,
BuilderApiKeyCreds
} from "@polymarket/builder-signing-sdk";
const BUILDER_CREDENTIALS: BuilderApiKeyCreds = {
key: process.env.POLY_BUILDER_API_KEY!,
secret: process.env.POLY_BUILDER_SECRET!,
passphrase: process.env.POLY_BUILDER_PASSPHRASE!,
};
// POST /sign - receives { method, path, body } from the client SDK
export async function handleSignRequest(request) {
const { method, path, body } = await request.json();
const timestamp = Date.now().toString();
const signature = buildHmacSignature(
BUILDER_CREDENTIALS.secret,
parseInt(timestamp),
method,
path,
body
);
return {
POLY_BUILDER_SIGNATURE: signature,
POLY_BUILDER_TIMESTAMP: timestamp,
POLY_BUILDER_API_KEY: BUILDER_CREDENTIALS.key,
POLY_BUILDER_PASSPHRASE: BUILDER_CREDENTIALS.passphrase,
};
}
```
```python Python theme={null}
import os
import time
from py_builder_signing_sdk.signing.hmac import build_hmac_signature
from py_builder_signing_sdk import BuilderApiKeyCreds
BUILDER_CREDENTIALS = BuilderApiKeyCreds(
key=os.environ["POLY_BUILDER_API_KEY"],
secret=os.environ["POLY_BUILDER_SECRET"],
passphrase=os.environ["POLY_BUILDER_PASSPHRASE"],
)
# POST /sign - receives { method, path, body } from the client SDK
def handle_sign_request(method: str, path: str, body: str):
timestamp = str(int(time.time()))
signature = build_hmac_signature(
BUILDER_CREDENTIALS.secret,
timestamp,
method,
path,
body
)
return {
"POLY_BUILDER_SIGNATURE": signature,
"POLY_BUILDER_TIMESTAMP": timestamp,
"POLY_BUILDER_API_KEY": BUILDER_CREDENTIALS.key,
"POLY_BUILDER_PASSPHRASE": BUILDER_CREDENTIALS.passphrase,
}
```
</CodeGroup>
<Warning>
Never commit credentials to version control. Use environment variables or a secrets manager.
</Warning>
### Client Configuration
Point your client to your signing server:
<CodeGroup>
```typescript TypeScript theme={null}
import { ClobClient } from "@polymarket/clob-client";
import { BuilderConfig } from "@polymarket/builder-signing-sdk";
// Point to your signing server
const builderConfig = new BuilderConfig({
remoteBuilderConfig: {
url: "https://your-server.com/sign"
}
});
// Or with optional authorization token
const builderConfigWithAuth = new BuilderConfig({
remoteBuilderConfig: {
url: "https://your-server.com/sign",
token: "your-auth-token"
}
});
const client = new ClobClient(
"https://clob.polymarket.com",
137,
signer, // ethers v5.x EOA signer
creds, // User's API Credentials
2, // signatureType for the Safe proxy wallet
funderAddress, // Safe proxy wallet address
undefined,
false,
builderConfig
);
// Orders automatically use the signing server
const order = await client.createOrder({
price: 0.40,
side: Side.BUY,
size: 5,
tokenID: "YOUR_TOKEN_ID"
});
const response = await client.postOrder(order);
```
```python Python theme={null}
from py_clob_client.client import ClobClient
from py_builder_signing_sdk import BuilderConfig, RemoteBuilderConfig
# Point to your signing server
builder_config = BuilderConfig(
remote_builder_config=RemoteBuilderConfig(
url="https://your-server.com/sign"
)
)
# Or with optional authorization token
builder_config_with_auth = BuilderConfig(
remote_builder_config=RemoteBuilderConfig(
url="https://your-server.com/sign",
token="your-auth-token"
)
)
client = ClobClient(
host="https://clob.polymarket.com",
chain_id=137,
key=private_key,
creds=creds, # User's API Credentials
signature_type=2, # signatureType for the Safe proxy wallet
funder=funder_address, # Safe proxy wallet address
builder_config=builder_config
)
# Orders automatically use the signing server
order = client.create_order({
"price": 0.40,
"side": "BUY",
"size": 5,
"token_id": "YOUR_TOKEN_ID"
})
response = client.post_order(order)
```
</CodeGroup>
### Troubleshooting
<AccordionGroup>
<Accordion title="Invalid Signature Errors">
**Error:** Client receives invalid signature errors
**Solution:**
1. Verify the request body is passed correctly as JSON
2. Check that `path`, `body`, and `method` match what the client sends
3. Ensure your server and client use the same Builder API credentials
</Accordion>
<Accordion title="Missing Credentials">
**Error:** `Builder credentials not configured` or undefined values
**Solution:** Ensure your environment variables are set:
* `POLY_BUILDER_API_KEY`
* `POLY_BUILDER_SECRET`
* `POLY_BUILDER_PASSPHRASE`
</Accordion>
</AccordionGroup>
</Tab>
<Tab title="Local Signing">
Sign orders locally when you control the entire order placement flow.
**How it works:**
1. Your system creates and signs orders on behalf of users
2. Your system uses Builder API credentials locally to add headers
3. Complete signed order is sent directly to the CLOB
<CodeGroup>
```typescript TypeScript theme={null}
import { ClobClient } from "@polymarket/clob-client";
import { BuilderConfig, BuilderApiKeyCreds } from "@polymarket/builder-signing-sdk";
// Configure with local builder credentials
const builderCreds: BuilderApiKeyCreds = {
key: process.env.POLY_BUILDER_API_KEY!,
secret: process.env.POLY_BUILDER_SECRET!,
passphrase: process.env.POLY_BUILDER_PASSPHRASE!
};
const builderConfig = new BuilderConfig({
localBuilderCreds: builderCreds
});
const client = new ClobClient(
"https://clob.polymarket.com",
137,
signer, // ethers v5.x EOA signer
creds, // User's API Credentials
2, // signatureType for the Safe proxy wallet
funderAddress, // Safe proxy wallet address
undefined,
false,
builderConfig
);
// Orders automatically include builder headers
const order = await client.createOrder({
price: 0.40,
side: Side.BUY,
size: 5,
tokenID: "YOUR_TOKEN_ID"
});
const response = await client.postOrder(order);
```
```python Python theme={null}
import os
from py_clob_client.client import ClobClient
from py_builder_signing_sdk import BuilderConfig, BuilderApiKeyCreds
# Configure with local builder credentials
builder_creds = BuilderApiKeyCreds(
key=os.environ["POLY_BUILDER_API_KEY"],
secret=os.environ["POLY_BUILDER_SECRET"],
passphrase=os.environ["POLY_BUILDER_PASSPHRASE"]
)
builder_config = BuilderConfig(
local_builder_creds=builder_creds
)
client = ClobClient(
host="https://clob.polymarket.com",
chain_id=137,
key=private_key,
creds=creds, # User's API Credentials
signature_type=2, # signatureType for the Safe proxy wallet
funder=funder_address, # Safe proxy wallet address
builder_config=builder_config
)
# Orders automatically include builder headers
order = client.create_order({
"price": 0.40,
"side": "BUY",
"size": 5,
"token_id": "YOUR_TOKEN_ID"
})
response = client.post_order(order)
```
</CodeGroup>
<Warning>
Never commit credentials to version control. Use environment variables or a secrets manager.
</Warning>
</Tab>
</Tabs>
***
## Authentication Headers
The SDK automatically generates and attaches these headers to each request:
| Header | Description |
| ------------------------- | ------------------------------------ |
| `POLY_BUILDER_API_KEY` | Your builder API key |
| `POLY_BUILDER_TIMESTAMP` | Unix timestamp of signature creation |
| `POLY_BUILDER_PASSPHRASE` | Your builder passphrase |
| `POLY_BUILDER_SIGNATURE` | HMAC signature of the request |
<Info>
With **local signing**, the SDK constructs and attaches these headers automatically. With **remote signing**, your server must return these headers (see Server Implementation above), and the SDK attaches them to the request.
</Info>
***
## Next Steps
<CardGroup cols={2}>
<Card title="Relayer Client" icon="bolt" href="/developers/builders/relayer-client">
Learn how to configure and use the Relay Client too!
</Card>
<Card title="CLOB Client Methods" icon="book" href="/developers/CLOB/clients/methods-overview">
Explore the complete CLOB client reference
</Card>
</CardGroup>
+917
View File
@@ -0,0 +1,917 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Relayer Client
> Use Polymarket's Polygon relayer to execute gasless transactions for your users
## Overview
The Relayer Client routes onchain transactions through Polymarket's infrastructure, providing gasless transactions for your users. Builder authentication is required to access the relayer.
<CardGroup cols={3}>
<Card title="Gasless Transactions" icon="gas-pump">
Polymarket pays all gas fees
</Card>
<Card title="Wallet Deployment" icon="wallet">
Deploy Safe or Proxy wallets
</Card>
<Card title="CTF Operations" icon="arrows-split-up-and-left">
Split, merge, and redeem positions
</Card>
</CardGroup>
***
## Builder API Credentials
Each builder receives API credentials from their [Builder Profile](/developers/builders/builder-profile):
| Credential | Description |
| ------------ | ------------------------------------ |
| `key` | Your builder API key identifier |
| `secret` | Secret key for signing requests |
| `passphrase` | Additional authentication passphrase |
<Warning>
**Security Notice**: Your Builder API keys must be kept secure. Never expose them in client-side code.
</Warning>
***
## Installation
<CodeGroup>
```bash TypeScript theme={null}
npm install @polymarket/builder-relayer-client
```
```bash Python theme={null}
pip install py-builder-relayer-client
```
</CodeGroup>
***
## Relayer Endpoint
All relayer requests are sent to Polymarket's relayer service on Polygon:
```
https://relayer-v2.polymarket.com/
```
***
## Signing Methods
<Tabs>
<Tab title="Remote Signing (Recommended)">
Remote signing keeps your credentials secure on a server you control.
**How it works:**
1. Client sends request details to your signing server
2. Your server generates the HMAC signature
3. Client attaches headers and sends to relayer
### Server Implementation
Your signing server receives request details and returns the authentication headers:
<CodeGroup>
```typescript TypeScript theme={null}
import {
buildHmacSignature,
BuilderApiKeyCreds
} from "@polymarket/builder-signing-sdk";
const BUILDER_CREDENTIALS: BuilderApiKeyCreds = {
key: process.env.POLY_BUILDER_API_KEY!,
secret: process.env.POLY_BUILDER_SECRET!,
passphrase: process.env.POLY_BUILDER_PASSPHRASE!,
};
// POST /sign - receives { method, path, body } from the client SDK
export async function handleSignRequest(request) {
const { method, path, body } = await request.json();
const timestamp = Date.now().toString();
const signature = buildHmacSignature(
BUILDER_CREDENTIALS.secret,
parseInt(timestamp),
method,
path,
body
);
return {
POLY_BUILDER_SIGNATURE: signature,
POLY_BUILDER_TIMESTAMP: timestamp,
POLY_BUILDER_API_KEY: BUILDER_CREDENTIALS.key,
POLY_BUILDER_PASSPHRASE: BUILDER_CREDENTIALS.passphrase,
};
}
```
```python Python theme={null}
import os
import time
from py_builder_signing_sdk.signing.hmac import build_hmac_signature
from py_builder_signing_sdk import BuilderApiKeyCreds
BUILDER_CREDENTIALS = BuilderApiKeyCreds(
key=os.environ["POLY_BUILDER_API_KEY"],
secret=os.environ["POLY_BUILDER_SECRET"],
passphrase=os.environ["POLY_BUILDER_PASSPHRASE"],
)
# POST /sign - receives { method, path, body } from the client SDK
def handle_sign_request(method: str, path: str, body: str):
timestamp = str(int(time.time()))
signature = build_hmac_signature(
BUILDER_CREDENTIALS.secret,
timestamp,
method,
path,
body
)
return {
"POLY_BUILDER_SIGNATURE": signature,
"POLY_BUILDER_TIMESTAMP": timestamp,
"POLY_BUILDER_API_KEY": BUILDER_CREDENTIALS.key,
"POLY_BUILDER_PASSPHRASE": BUILDER_CREDENTIALS.passphrase,
}
```
</CodeGroup>
<Warning>
Never commit credentials to version control. Use environment variables or a secrets manager.
</Warning>
### Client Configuration
Point your client to your signing server:
<CodeGroup>
```typescript TypeScript theme={null}
import { createWalletClient, http, Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { polygon } from "viem/chains";
import { RelayClient } from "@polymarket/builder-relayer-client";
import { BuilderConfig } from "@polymarket/builder-signing-sdk";
// Create wallet
const account = privateKeyToAccount(process.env.PRIVATE_KEY as Hex);
const wallet = createWalletClient({
account,
chain: polygon,
transport: http(process.env.RPC_URL)
});
// Configure remote signing
const builderConfig = new BuilderConfig({
remoteBuilderConfig: {
url: "https://your-server.com/sign"
}
});
const RELAYER_URL = "https://relayer-v2.polymarket.com/";
const CHAIN_ID = 137;
const client = new RelayClient(
RELAYER_URL,
CHAIN_ID,
wallet,
builderConfig
);
```
```python Python theme={null}
import os
from py_builder_relayer_client.client import RelayClient
from py_builder_signing_sdk import BuilderConfig, RemoteBuilderConfig
private_key = os.getenv("PRIVATE_KEY")
# Configure remote signing
builder_config = BuilderConfig(
remote_builder_config=RemoteBuilderConfig(
url="https://your-server.com/sign"
)
)
client = RelayClient(
"https://relayer-v2.polymarket.com",
137,
private_key,
builder_config
)
```
</CodeGroup>
</Tab>
<Tab title="Local Signing">
Sign locally when your backend handles all transactions.
**How it works:**
1. Your system creates transactions on behalf of users
2. Your system uses Builder API credentials locally to add headers
3. Complete signed request is sent directly to the relayer
<CodeGroup>
```typescript TypeScript theme={null}
import { createWalletClient, http, Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { polygon } from "viem/chains";
import { RelayClient } from "@polymarket/builder-relayer-client";
import { BuilderConfig } from "@polymarket/builder-signing-sdk";
// Create wallet
const account = privateKeyToAccount(process.env.PRIVATE_KEY as Hex);
const wallet = createWalletClient({
account,
chain: polygon,
transport: http(process.env.RPC_URL)
});
// Configure local signing
const builderConfig = new BuilderConfig({
localBuilderCreds: {
key: process.env.POLY_BUILDER_API_KEY!,
secret: process.env.POLY_BUILDER_SECRET!,
passphrase: process.env.POLY_BUILDER_PASSPHRASE!
}
});
const RELAYER_URL = "https://relayer-v2.polymarket.com/";
const CHAIN_ID = 137;
const client = new RelayClient(
RELAYER_URL,
CHAIN_ID,
wallet,
builderConfig
);
```
```python Python theme={null}
import os
from py_builder_relayer_client.client import RelayClient
from py_builder_signing_sdk import BuilderConfig, BuilderApiKeyCreds
private_key = os.getenv("PRIVATE_KEY")
# Configure local signing
builder_config = BuilderConfig(
local_builder_creds=BuilderApiKeyCreds(
key=os.getenv("POLY_BUILDER_API_KEY"),
secret=os.getenv("POLY_BUILDER_SECRET"),
passphrase=os.getenv("POLY_BUILDER_PASSPHRASE"),
)
)
client = RelayClient(
"https://relayer-v2.polymarket.com",
137,
private_key,
builder_config
)
```
</CodeGroup>
<Warning>
Never commit credentials to version control. Use environment variables or a secrets manager.
</Warning>
</Tab>
</Tabs>
***
## Authentication Headers
The SDK automatically generates and attaches these headers to each request:
| Header | Description |
| ------------------------- | ------------------------------------ |
| `POLY_BUILDER_API_KEY` | Your builder API key |
| `POLY_BUILDER_TIMESTAMP` | Unix timestamp of signature creation |
| `POLY_BUILDER_PASSPHRASE` | Your builder passphrase |
| `POLY_BUILDER_SIGNATURE` | HMAC signature of the request |
<Info>
With **local signing**, the SDK constructs and attaches these headers automatically. With **remote signing**, your server must return these headers (see Server Implementation above), and the SDK attaches them to the request.
</Info>
***
## Wallet Types
Choose your wallet type before using the relayer:
<Tabs>
<Tab title="Safe Wallets">
Gnosis Safe-based proxy wallets that require explicit deployment before use.
* **Best for:** Most builder integrations
* **Deployment:** Call `client.deploy()` before first transaction
* **Gas fees:** Paid by Polymarket
<CodeGroup>
```typescript TypeScript theme={null}
const client = new RelayClient(
"https://relayer-v2.polymarket.com",
137,
eoaSigner,
builderConfig,
RelayerTxType.SAFE // Default
);
// Deploy before first use
const response = await client.deploy();
const result = await response.wait();
console.log("Safe Address:", result?.proxyAddress);
```
```python Python theme={null}
from py_builder_relayer_client.client import RelayClient, RelayerTxType
client = RelayClient(
"https://relayer-v2.polymarket.com",
137,
private_key,
builder_config,
RelayerTxType.SAFE # Default
)
# Deploy before first use
response = client.deploy()
result = response.wait()
print(f"Safe Address: {result.proxy_address}")
```
</CodeGroup>
</Tab>
<Tab title="Proxy Wallets">
Custom Polymarket proxy wallets that auto-deploy on first transaction.
* **Used for:** Magic Link users from Polymarket.com
* **Deployment:** Automatic on first transaction
* **Gas fees:** Paid by Polymarket
<CodeGroup>
```typescript TypeScript theme={null}
const client = new RelayClient(
"https://relayer-v2.polymarket.com",
137,
eoaSigner,
builderConfig,
RelayerTxType.PROXY
);
// No deploy() needed - auto-deploys on first tx
await client.execute([transaction], "First transaction");
```
```python Python theme={null}
from py_builder_relayer_client.client import RelayClient, RelayerTxType
client = RelayClient(
"https://relayer-v2.polymarket.com",
137,
private_key,
builder_config,
RelayerTxType.PROXY
)
# No deploy() needed - auto-deploys on first tx
client.execute([transaction], "First transaction")
```
</CodeGroup>
</Tab>
</Tabs>
<Accordion title="Wallet Comparison Table">
| Feature | Safe Wallets | Proxy Wallets |
| ----------------- | :-----------------: | :---------------------: |
| Deployment | Explicit `deploy()` | Auto-deploy on first tx |
| Gas Fees | Polymarket pays | Polymarket pays |
| ERC20 Approvals | ✅ | ✅ |
| CTF Operations | ✅ | ✅ |
| Send Transactions | ✅ | ✅ |
</Accordion>
***
## Usage
### Deploy a Wallet
For Safe wallets, deploy before executing transactions:
<CodeGroup>
```typescript TypeScript theme={null}
const response = await client.deploy();
const result = await response.wait();
if (result) {
console.log("Safe deployed successfully!");
console.log("Transaction Hash:", result.transactionHash);
console.log("Safe Address:", result.proxyAddress);
}
```
```python Python theme={null}
response = client.deploy()
result = response.wait()
if result:
print("Safe deployed successfully!")
print(f"Transaction Hash: {result.transaction_hash}")
print(f"Safe Address: {result.proxy_address}")
```
</CodeGroup>
### Execute Transactions
The `execute` method sends transactions through the relayer. Pass an array of transactions to batch multiple operations in a single call.
<CodeGroup>
```typescript TypeScript theme={null}
interface Transaction {
to: string; // Target contract or wallet address
data: string; // Encoded function call (use "0x" for simple transfers)
value: string; // Amount of MATIC to send (usually "0")
}
const response = await client.execute(transactions, "Description");
const result = await response.wait();
if (result) {
console.log("Transaction confirmed:", result.transactionHash);
}
```
```python Python theme={null}
# Transaction dict format:
# { "to": str, "data": str, "value": str }
response = client.execute(transactions, "Description")
result = response.wait()
if result:
print(f"Transaction confirmed: {result.transaction_hash}")
```
</CodeGroup>
### Transaction Examples
<Tabs>
<Tab title="Transfer">
Transfer tokens to any address (e.g., withdrawals):
<CodeGroup>
```typescript TypeScript theme={null}
import { encodeFunctionData, parseUnits } from "viem";
const transferTx = {
to: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", // USDCe
data: encodeFunctionData({
abi: [{
name: "transfer",
type: "function",
inputs: [
{ name: "to", type: "address" },
{ name: "amount", type: "uint256" }
],
outputs: [{ type: "bool" }]
}],
functionName: "transfer",
args: [
"0xRecipientAddressHere",
parseUnits("100", 6) // 100 USDCe (6 decimals)
]
}),
value: "0"
};
const response = await client.execute([transferTx], "Transfer USDCe");
await response.wait();
```
```python Python theme={null}
from web3 import Web3
USDC_E = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"
transfer_tx = {
"to": USDC_E,
"data": Web3().eth.contract(
address=USDC_E,
abi=[{"name": "transfer", "type": "function", "inputs": [{"name": "to", "type": "address"}, {"name": "amount", "type": "uint256"}], "outputs": [{"type": "bool"}]}]
).encode_abi(abi_element_identifier="transfer", args=["0xRecipientAddressHere", 100 * 10**6]),
"value": "0"
}
response = client.execute([transfer_tx], "Transfer USDCe")
response.wait()
```
</CodeGroup>
</Tab>
<Tab title="Approve">
Set token allowances to enable trading:
<CodeGroup>
```typescript TypeScript theme={null}
import { encodeFunctionData, maxUint256 } from "viem";
const approveTx = {
to: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", // USDCe
data: encodeFunctionData({
abi: [{
name: "approve",
type: "function",
inputs: [
{ name: "spender", type: "address" },
{ name: "amount", type: "uint256" }
],
outputs: [{ type: "bool" }]
}],
functionName: "approve",
args: [
"0x4d97dcd97ec945f40cf65f87097ace5ea0476045", // CTF
maxUint256
]
}),
value: "0"
};
const response = await client.execute([approveTx], "Approve USDCe for CTF");
await response.wait();
```
```python Python theme={null}
from web3 import Web3
USDC_E = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"
CTF = "0x4d97dcd97ec945f40cf65f87097ace5ea0476045"
MAX_UINT256 = 2**256 - 1
approve_tx = {
"to": USDC_E,
"data": Web3().eth.contract(
address=USDC_E,
abi=[{"name": "approve", "type": "function", "inputs": [{"name": "spender", "type": "address"}, {"name": "amount", "type": "uint256"}], "outputs": [{"type": "bool"}]}]
).encode_abi(abi_element_identifier="approve", args=[CTF, MAX_UINT256]),
"value": "0"
}
response = client.execute([approve_tx], "Approve USDCe for CTF")
response.wait()
```
</CodeGroup>
</Tab>
<Tab title="Redeem Positions">
Redeem winning conditional tokens after market resolution:
<CodeGroup>
```typescript TypeScript theme={null}
import { encodeFunctionData } from "viem";
const redeemTx = {
to: ctfAddress,
data: encodeFunctionData({
abi: [{
name: "redeemPositions",
type: "function",
inputs: [
{ name: "collateralToken", type: "address" },
{ name: "parentCollectionId", type: "bytes32" },
{ name: "conditionId", type: "bytes32" },
{ name: "indexSets", type: "uint256[]" }
],
outputs: []
}],
functionName: "redeemPositions",
args: [collateralToken, parentCollectionId, conditionId, indexSets]
}),
value: "0"
};
const response = await client.execute([redeemTx], "Redeem positions");
await response.wait();
```
```python Python theme={null}
from web3 import Web3
CTF = "0x4d97dcd97ec945f40cf65f87097ace5ea0476045"
redeem_tx = {
"to": CTF,
"data": Web3().eth.contract(
address=CTF,
abi=[{"name": "redeemPositions", "type": "function", "inputs": [{"name": "collateralToken", "type": "address"}, {"name": "parentCollectionId", "type": "bytes32"}, {"name": "conditionId", "type": "bytes32"}, {"name": "indexSets", "type": "uint256[]"}], "outputs": []}]
).encode_abi(abi_element_identifier="redeemPositions", args=[collateral_token, parent_collection_id, condition_id, index_sets]),
"value": "0"
}
response = client.execute([redeem_tx], "Redeem positions")
response.wait()
```
</CodeGroup>
</Tab>
<Tab title="Split Positions">
Split collateral tokens into conditional outcome tokens:
<CodeGroup>
```typescript TypeScript theme={null}
import { encodeFunctionData } from "viem";
const splitTx = {
to: ctfAddress,
data: encodeFunctionData({
abi: [{
name: "splitPosition",
type: "function",
inputs: [
{ name: "collateralToken", type: "address" },
{ name: "parentCollectionId", type: "bytes32" },
{ name: "conditionId", type: "bytes32" },
{ name: "partition", type: "uint256[]" },
{ name: "amount", type: "uint256" }
],
outputs: []
}],
functionName: "splitPosition",
args: [collateralToken, parentCollectionId, conditionId, partition, amount]
}),
value: "0"
};
const response = await client.execute([splitTx], "Split positions");
await response.wait();
```
```python Python theme={null}
from web3 import Web3
CTF = "0x4d97dcd97ec945f40cf65f87097ace5ea0476045"
split_tx = {
"to": CTF,
"data": Web3().eth.contract(
address=CTF,
abi=[{"name": "splitPosition", "type": "function", "inputs": [{"name": "collateralToken", "type": "address"}, {"name": "parentCollectionId", "type": "bytes32"}, {"name": "conditionId", "type": "bytes32"}, {"name": "partition", "type": "uint256[]"}, {"name": "amount", "type": "uint256"}], "outputs": []}]
).encode_abi(abi_element_identifier="splitPosition", args=[collateral_token, parent_collection_id, condition_id, partition, amount]),
"value": "0"
}
response = client.execute([split_tx], "Split positions")
response.wait()
```
</CodeGroup>
</Tab>
<Tab title="Merge Positions">
Merge conditional tokens back into collateral:
<CodeGroup>
```typescript TypeScript theme={null}
import { encodeFunctionData } from "viem";
const mergeTx = {
to: ctfAddress,
data: encodeFunctionData({
abi: [{
name: "mergePositions",
type: "function",
inputs: [
{ name: "collateralToken", type: "address" },
{ name: "parentCollectionId", type: "bytes32" },
{ name: "conditionId", type: "bytes32" },
{ name: "partition", type: "uint256[]" },
{ name: "amount", type: "uint256" }
],
outputs: []
}],
functionName: "mergePositions",
args: [collateralToken, parentCollectionId, conditionId, partition, amount]
}),
value: "0"
};
const response = await client.execute([mergeTx], "Merge positions");
await response.wait();
```
```python Python theme={null}
from web3 import Web3
CTF = "0x4d97dcd97ec945f40cf65f87097ace5ea0476045"
merge_tx = {
"to": CTF,
"data": Web3().eth.contract(
address=CTF,
abi=[{"name": "mergePositions", "type": "function", "inputs": [{"name": "collateralToken", "type": "address"}, {"name": "parentCollectionId", "type": "bytes32"}, {"name": "conditionId", "type": "bytes32"}, {"name": "partition", "type": "uint256[]"}, {"name": "amount", "type": "uint256"}], "outputs": []}]
).encode_abi(abi_element_identifier="mergePositions", args=[collateral_token, parent_collection_id, condition_id, partition, amount]),
"value": "0"
}
response = client.execute([merge_tx], "Merge positions")
response.wait()
```
</CodeGroup>
</Tab>
<Tab title="Batch Transactions">
Execute multiple transactions atomically in a single call:
<CodeGroup>
```typescript TypeScript theme={null}
import { encodeFunctionData, parseUnits, maxUint256 } from "viem";
const erc20Abi = [
{
name: "approve",
type: "function",
inputs: [
{ name: "spender", type: "address" },
{ name: "amount", type: "uint256" }
],
outputs: [{ type: "bool" }]
},
{
name: "transfer",
type: "function",
inputs: [
{ name: "to", type: "address" },
{ name: "amount", type: "uint256" }
],
outputs: [{ type: "bool" }]
}
] as const;
// Approve CTF to spend USDCe
const approveTx = {
to: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
data: encodeFunctionData({
abi: erc20Abi,
functionName: "approve",
args: ["0x4d97dcd97ec945f40cf65f87097ace5ea0476045", maxUint256]
}),
value: "0"
};
// Transfer some USDCe to another wallet
const transferTx = {
to: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
data: encodeFunctionData({
abi: erc20Abi,
functionName: "transfer",
args: ["0xRecipientAddressHere", parseUnits("50", 6)]
}),
value: "0"
};
// Both transactions execute in one call
const response = await client.execute(
[approveTx, transferTx],
"Approve and transfer"
);
await response.wait();
```
```python Python theme={null}
from web3 import Web3
USDC_E = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"
CTF = "0x4d97dcd97ec945f40cf65f87097ace5ea0476045"
MAX_UINT256 = 2**256 - 1
erc20_abi = [
{"name": "approve", "type": "function", "inputs": [{"name": "spender", "type": "address"}, {"name": "amount", "type": "uint256"}], "outputs": [{"type": "bool"}]},
{"name": "transfer", "type": "function", "inputs": [{"name": "to", "type": "address"}, {"name": "amount", "type": "uint256"}], "outputs": [{"type": "bool"}]}
]
contract = Web3().eth.contract(address=USDC_E, abi=erc20_abi)
# Approve CTF to spend USDCe
approve_tx = {
"to": USDC_E,
"data": contract.encode_abi(abi_element_identifier="approve", args=[CTF, MAX_UINT256]),
"value": "0"
}
# Transfer some USDCe to another wallet
transfer_tx = {
"to": USDC_E,
"data": contract.encode_abi(abi_element_identifier="transfer", args=["0xRecipientAddressHere", 50 * 10**6]),
"value": "0"
}
# Both transactions execute in one call
response = client.execute([approve_tx, transfer_tx], "Approve and transfer")
response.wait()
```
</CodeGroup>
<Info>
Batching reduces latency and ensures all transactions succeed or fail together.
</Info>
</Tab>
</Tabs>
***
## Reference
### Contracts & Approvals
| Contract | Address | USDCe | Outcome Tokens |
| --------------------- | -------------------------------------------- | :---: | :------------: |
| USDCe | `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174` | — | — |
| CTF | `0x4d97dcd97ec945f40cf65f87097ace5ea0476045` | ✅ | — |
| CTF Exchange | `0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E` | ✅ | ✅ |
| Neg Risk CTF Exchange | `0xC5d563A36AE78145C45a50134d48A1215220f80a` | ✅ | ✅ |
| Neg Risk Adapter | `0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296` | — | ✅ |
### Transaction States
| State | Description |
| ----------------- | -------------------------------------------- |
| `STATE_NEW` | Transaction received by relayer |
| `STATE_EXECUTED` | Transaction executed onchain |
| `STATE_MINED` | Transaction included in a block |
| `STATE_CONFIRMED` | Transaction confirmed (final ✅) |
| `STATE_FAILED` | Transaction failed (terminal ❌) |
| `STATE_INVALID` | Transaction rejected as invalid (terminal ❌) |
### TypeScript Types
<Accordion title="View Type Definitions">
```typescript theme={null}
// Transaction type used in all examples
interface Transaction {
to: string;
data: string;
value: string;
}
// Wallet type selector
enum RelayerTxType {
SAFE = "SAFE",
PROXY = "PROXY"
}
// Transaction states
enum RelayerTransactionState {
STATE_NEW = "STATE_NEW",
STATE_EXECUTED = "STATE_EXECUTED",
STATE_MINED = "STATE_MINED",
STATE_CONFIRMED = "STATE_CONFIRMED",
STATE_FAILED = "STATE_FAILED",
STATE_INVALID = "STATE_INVALID"
}
// Response from relayer
interface RelayerTransaction {
transactionID: string;
transactionHash: string;
from: string;
to: string;
proxyAddress: string;
data: string;
state: string;
type: string;
metadata: string;
createdAt: Date;
updatedAt: Date;
}
```
</Accordion>
***
## Next Steps
<CardGroup cols={2}>
<Card title="Order Attribution" icon="tag" href="/developers/builders/order-attribution">
Attribute orders to your builder account
</Card>
<Card title="Example Apps" icon="code" href="/developers/builders/examples">
Complete integration examples
</Card>
</CardGroup>