Polymarket’s Builder program enables apps to earn fees on trades they route through the platform. This guide demonstrates how to integrate Polymarket trading using Privy for authentication and embedded wallet provisioning—giving your users a seamless, gasless trading experience with web2-style onboarding.
First, wrap your app with PrivyProvider and use Privy’s hooks to handle login. When users authenticate, Privy automatically provisions an embedded wallet:
Next, set up a server-side API route to keep your builder credentials secure. The example includes this at app/api/polymarket/sign/route.ts.This endpoint generates HMAC signatures for the RelayClient and ClobClient:
This reference implementation exposes builder credentials to the client. For production, implement
a proxy pattern where the server makes all CLOB/Relay requests, or add auth token validation
before returning credentials.
Polymarket uses Gnosis Safe wallets for trading. The hooks/useSafeDeployment.ts hook handles this.First, derive the Safe address from the user’s EOA (this is deterministic—the same EOA always gets the same Safe):
Report incorrect code
Copy
Ask AI
import {deriveSafe} from '@polymarket/builder-relayer-client/dist/builder/derive';import {getContractConfig} from '@polymarket/builder-relayer-client/dist/config';import {POLYGON_CHAIN_ID} from '@/constants/polymarket';const config = getContractConfig(POLYGON_CHAIN_ID);const safeAddress = deriveSafe(eoaAddress, config.SafeContracts.SafeFactory);
Then check if the Safe exists and deploy it if needed:
Report incorrect code
Copy
Ask AI
import {RelayClient, RelayerTransactionState} from '@polymarket/builder-relayer-client';async function deploySafe(relayClient: RelayClient): Promise<string> { // Prompts signer for a signature const response = await relayClient.deploy(); // Poll until the transaction is mined/confirmed (60s timeout, 3s interval) const result = await relayClient.pollUntilState( response.transactionID, [ RelayerTransactionState.STATE_MINED, RelayerTransactionState.STATE_CONFIRMED, RelayerTransactionState.STATE_FAILED ], '60', 3000 ); return result.proxyAddress;}
The Safe holds the user’s USDC.e and outcome tokens. Deployment is gasless—Polymarket’s relayer covers the cost.
User API Credentials authenticate requests to the CLOB. The hooks/useUserApiCredentials.ts hook handles this.For new users, create credentials:
Report incorrect code
Copy
Ask AI
import {ClobClient} from '@polymarket/clob-client';import {CLOB_API_URL, POLYGON_CHAIN_ID} from '@/constants/polymarket';import {useWallet} from '@/providers/WalletContext';const {eoaAddress, ethersSigner} = useWallet();const tempClient = new ClobClient(CLOB_API_URL, POLYGON_CHAIN_ID, ethersSigner);const creds = await tempClient.createApiKey(); // Prompts for signature
For returning users, derive existing credentials:
Report incorrect code
Copy
Ask AI
const creds = await tempClient.deriveApiKey(); // Prompts for signature
Both methods require the user to sign an EIP-712 message. The example stores credentials in localStorage for convenience, but production apps should use secure httpOnly cookies or server-side session management.
Before trading, the Safe must approve Polymarket’s contracts. The hooks/useTokenApprovals.ts hook batches all approvals into a single transaction.USDC.e (ERC-20) approvals for: