Deposit Wallets (POLY_1271)
Polygolem implements Polymarket CLOB V2’s deposit wallet (type 3 / POLY_1271) architecture as its supported live trading path. This page explains how it works, why new API users should use it, and how the signature flow differs from legacy wallet types.
Why Deposit Wallets
In May 2026, Polymarket migrated to CLOB V2 and blocked direct EOA orders for new API users. All new accounts must use POLY_1271 — the deposit wallet signature scheme. Polygolem was purpose-built for this migration.
| Signature Type | Status for New API Users |
|---|---|
| 0 (EOA) | Blocked |
| 1 (POLY_PROXY) | Blocked |
| 2 (GNOSIS_SAFE) | Blocked |
| 3 (POLY_1271 / Deposit Wallet) | Required |
Architecture
┌──────────────┐ ┌──────────────────┐ ┌─────────────────┐│ Your EOA │ signs │ Deposit Wallet │ holds │ pUSD + Tokens ││ (signer) │────────▶│ (POLY_1271) │────────▶│ (on-chain) │└──────────────┘ └──────────────────┘ └─────────────────┘ │ │ ERC-1271 ▼ ┌──────────────────┐ │ CLOB Exchange │ │ validates sig │ └──────────────────┘The EOA signs. The deposit wallet holds funds. The CLOB Exchange calls isValidSignature() on the deposit wallet to verify POLY_1271 typed orders. The wallet has no private key — it’s a smart contract that validates EOA signatures via ERC-1271.
CREATE2 Derivation
The deposit wallet address is deterministic — computed from the EOA address:
walletId = bytes32(owner) // owner address left-padded to 32 bytesargs = abi.encode(factory, walletId)salt = keccak256(args)bytecodeHash = SoladyLibClone.initCodeHashERC1967(implementation, args)depositWallet = CREATE2(factory, salt, bytecodeHash)
factory = 0x00000000000Fb5C9ADea0298D729A0CB3823Cc07implementation = 0x58CA52ebe0DadfdF531Cde7062e76746de4Db1eBSame EOA → same wallet address. Always. Pure local computation via polygolem deposit-wallet derive.
Deployment (Relayer)
The wallet is deployed via the Polymarket relayer. The factory’s deploy() is role-gated — only the relayer’s EOA holds the operator role. Deployment is gas-sponsored.
polygolem deposit-wallet deploy --waitAfter deployment, WALLET batches still route through the Polymarket relayer.
The factory’s proxy() function validates owner-signed batches, but the
production factory also gates proxy() with onlyOperator. A direct owner EOA
cannot use the factory as a permissionless fallback submitter.
The relayer’s /deployed endpoint can become a false-negative when a
WALLET-CREATE row is marked STATE_FAILED despite the underlying
transaction landing on Polygon. Polygolem and the go-bot SDK therefore use
Polygon eth_getCode as the source of truth: if bytecode exists at the
derived deposit-wallet address, the wallet is treated as deployed and
WALLET-CREATE is skipped. See
Deposit Wallet Lifecycle / Phase 2
for the full rule and the deposit-wallet status --json fields
(relayerDeployed, onchainCodeDeployed, deploymentStatusSource).
Signing Flow (POLY_1271)
- App builds V2 order typed data (
Polymarket CTF Exchange, version"2") - EOA signs the order hash
- Signature is wrapped in an ERC-7739 TypedDataSign envelope
- Order is posted to CLOB with
signatureType = 3 - CLOB calls
isValidSignature()on the deposit wallet contract - Deposit wallet validates the EOA signature via ERC-1271
The ERC-7739 wrapper structure:
innerSig(65) || appDomainSep(32) || contents(32) || contentsType(186) || uint16BE(186).
That is 317 bytes, encoded as 0x plus 634 hex chars.
Builder Attribution
V2 orders include a builder field (bytes32). Upstream uses this builder code
for order attribution. It is distinct from builder relayer credentials and does
not use POLY_BUILDER_* HMAC headers on the order request.
Polygolem signs orders with builder = bytes32(0) by default. Configure a
non-zero builder code with pkg/clob.Config.BuilderCode,
pkg/universal.Config.BuilderCode, CLI --builder-code, or
POLYMARKET_BUILDER_CODE.
Builder credentials (API key/secret/passphrase) are separate — used only for
relayer auth (WALLET-CREATE, WALLET batch). Never mix builder creds with
CLOB L2 creds.
Winning Position Redemption
Deposit wallets hold both pUSD and CTF ERC-1155 position tokens. After a CLOB
order fills, the wallet owns shares. That fill is only matched; it is not
evidence that the market won.
Redemption has its own lifecycle:
- Query Data API
/positions?user=<depositWallet>. - Treat
redeemable=trueas the readiness signal. - Route standard markets through
CtfCollateralAdapter. - Route negative-risk markets through
NegRiskCtfCollateralAdapter. - Submit the redeem call as an EOA-signed EIP-712 deposit-wallet WALLET batch.
The adapter uses conditionId, detects the wallet’s current winning CTF
balance, performs the underlying CTF redemption, wraps proceeds back into
pUSD, and sends pUSD to the deposit wallet.
Existing wallets that only ran the six-call trading approval batch must run a one-time adapter approval batch before first redeem. New wallet onboarding should include both trading approvals and adapter-readiness approvals.
Use polygolem deposit-wallet settlement-status as the read-only gate before
live trading. It proves the wallet is deployed, relayer credentials are loaded,
the Data API positions path works, and both V2 collateral adapters are
approved.
There is no raw CTF fallback, direct EOA bypass, or SAFE/PROXY shortcut for deposit-wallet positions. If the relayer rejects the adapter-targeted WALLET batch as not allowlisted, verify the adapter addresses against Polymarket’s current contracts reference first. Stale adapter constants caused the 2026-05-09 live blocker; current addresses plus the same rejection is the actual upstream-blocked state.
See Also
- Smart Contracts — factory addresses and ABI
- Deposit Wallet Lifecycle — full end-to-end walkthrough
- Redeeming Winning Positions — V2 settlement process
- CLOB API — order creation and signing
- Secrets Management — builder credential handling