Skip to content

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 TypeStatus 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 bytes
args = abi.encode(factory, walletId)
salt = keccak256(args)
bytecodeHash = SoladyLibClone.initCodeHashERC1967(implementation, args)
depositWallet = CREATE2(factory, salt, bytecodeHash)
factory = 0x00000000000Fb5C9ADea0298D729A0CB3823Cc07
implementation = 0x58CA52ebe0DadfdF531Cde7062e76746de4Db1eB

Same 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.

Terminal window
polygolem deposit-wallet deploy --wait

After 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)

  1. App builds V2 order typed data (Polymarket CTF Exchange, version "2")
  2. EOA signs the order hash
  3. Signature is wrapped in an ERC-7739 TypedDataSign envelope
  4. Order is posted to CLOB with signatureType = 3
  5. CLOB calls isValidSignature() on the deposit wallet contract
  6. 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:

  1. Query Data API /positions?user=<depositWallet>.
  2. Treat redeemable=true as the readiness signal.
  3. Route standard markets through CtfCollateralAdapter.
  4. Route negative-risk markets through NegRiskCtfCollateralAdapter.
  5. 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