PreFundedEscrow smart contract on Polygon (chainId 137). USDC sits in the escrow under your wallet’s beneficial ownership; PMXT cannot move funds without an EIP-712 signature from your wallet. This page walks through the full lifecycle: approve, deposit, trade, withdraw.
You fund Polygon only. USDC always sits in the Polygon
PreFundedEscrow
for the currently hosted trading venues (Polymarket, Opinion, and
Limitless). For hosted venues that don’t settle on Polygon (Opinion on BSC,
Limitless on Base), PMXT operates an internal cross-chain leg that holds
outcome tokens on the venue’s chain; you neither fund nor sign anything on
that side. Pass any EVM-compatible private key; the same EVM wallet/key can
trade the currently hosted venues.Why escrow at all?
Polymarket’s CLOB exchange expects the submitter to be the operator of the user’s CLOB proxy wallet. That proxy is created by Polymarket’s USDC.e adapter and is non-trivial to operate from a third-party context. PMXT’sPreFundedEscrow solves this by acting as a pre-funded operator: the user deposits USDC once, PMXT routes orders against that balance, and the user can withdraw at any time. The user signs every order with EIP-712 against the Polygon escrow’s domain; the escrow contract can only spend USDC against signed orders, never unilaterally.
For Opinion, the same Polygon escrow balance funds a cross-chain settlement leg into a BSC-side VenueEscrow that holds Opinion outcome tokens — you still only deposit on Polygon, and your EIP-712 signature still targets the Polygon escrow domain. The BSC hop is PMXT’s plumbing.
The client.escrow namespace
Hosted exchange clients (Polymarket, Opinion, Limitless) expose an escrow namespace. Every method builds an unsigned transaction. Your wallet — MetaMask, ethers Wallet, viem, web3.py, etc. — is responsible for signing and broadcasting it. PMXT never holds your private key.
See the source:
sdks/python/pmxt/escrow.py and sdks/typescript/pmxt/escrow.ts.
1. Approve and deposit
Before the first deposit, the escrow contract needs permission to pull USDC from your wallet (a standard ERC-20 approval). Then you deposit. For most users, the dashboard handles both in a single connected-wallet flow.Recommended: use the dashboard
Open pmxt.dev/dashboard, connect the wallet whose address you passed to the SDK, and use the Deposit flow. Your wallet (MetaMask, Rabby, WalletConnect, etc.) prompts you to sign — PMXT never sees your private key.- Go to pmxt.dev/dashboard and connect the matching wallet.
- Click Deposit and enter the USDC amount.
- Approve the USDC allowance in your wallet (one-time per token).
- Confirm the deposit transaction in your wallet.
Approval is one-time per token + spender; the deposit itself is one-time setup before your first trade. If you ever rotate the escrow contract (rare, gated on a PMXT migration announcement), you’ll need to re-approve.
Advanced: programmatic approve + deposit
Advanced: programmatic approve + deposit
If you’re scripting deposits (CI, treasury automation, custom wallet integrations), DepositAmounts are in whole USDC (6 decimals); the SDK validates precision and rejects values like
client.escrow builds unsigned transactions you sign and broadcast with your own wallet library.Approve0.0000001.2. Confirm the deposit
After the deposit transaction confirms on-chain, the balance shows up in escrow.fetch_balance is the canonical check.
On-chain confirmation usually takes 2–5 seconds on Polygon. If
fetch_balance still reads zero 30 seconds after broadcast, check the tx on Polygonscan — a failed deposit (e.g. due to missing approval) will not update escrow state.3. Trade
With escrow funded, you can trade.create_order and submit_order debit the escrow balance; cancel_order releases the reservation. No additional escrow calls are needed during normal trading — the balance just gets spent.
4. Withdraw
Withdrawals are a two-step timelock. You firstrequest a withdrawal; after a contract-enforced delay (~1 hour in production), you claim it. You can also cancel a pending request.
The timelock is a security feature — it gives you a window to detect and abort an unauthorized withdrawal even if the operator key were compromised. Because the escrow is non-custodial, every withdrawal step requires a signature from your wallet.
Recommended: withdraw from the dashboard
The dashboard handles the full request → wait → claim journey as one user flow.- Open pmxt.dev/dashboard and connect your wallet.
- Click Withdraw, enter the USDC amount, and confirm the request transaction in your wallet.
- Wait for the timelock to elapse (~1 hour in production). The dashboard shows a countdown for each pending request.
- Come back, click Claim on the matured request, and confirm the claim transaction in your wallet. Funds move from escrow to your wallet.
Advanced: programmatic withdraw
Advanced: programmatic withdraw
For scripted withdrawals, Inspect pending withdrawalsClaimOnce CancelIf you change your mind during the timelock window, cancel a pending request and the funds remain in escrow as free balance.
client.escrow.withdraw_tx builds unsigned request / claim / cancel transactions you sign and broadcast with your own wallet library.Requestclaimable_at has passed, claim the funds — they move from escrow to your wallet.claim does not take an amount. It claims all matured requests at once. The escrow tracks individual request maturities; only matured ones settle.Errors you might hit
MissingWalletAddress—client.escrow.*requireswallet_addresson the exchange constructor. Pass it explicitly.ValidationError: amount precision exceeds 6 decimals— round before passing.InsufficientEscrowBalance(during a trade) — deposit more before retrying, or wait for matured withdrawals to clear pending positions.HostedTradingError(5xx) — transient server error; retry with backoff. See Hosted errors.
Source references
- Python:
sdks/python/pmxt/escrow.py - TypeScript:
sdks/typescript/pmxt/escrow.ts

