Skip to content

fix: resolve HTTP 400 invalid order payload via official py-clob-client-v2 SDK (signature_type=3 / POLY_1271)#5

Open
matteocelani wants to merge 1 commit into
strongca22-cpu:mainfrom
matteocelani:fix/invalid-order-payload
Open

fix: resolve HTTP 400 invalid order payload via official py-clob-client-v2 SDK (signature_type=3 / POLY_1271)#5
matteocelani wants to merge 1 commit into
strongca22-cpu:mainfrom
matteocelani:fix/invalid-order-payload

Conversation

@matteocelani

@matteocelani matteocelani commented May 13, 2026

Copy link
Copy Markdown

Description

This PR resolves the HTTP 400 — Invalid order payload errors that occurred when placing orders on the Polymarket CLOB V2.

Root cause: the bot manually constructed and signed EIP-712 payloads via a custom OrderSigner. Polymarket migrated to CLOB V2 (April 28 2026) with new exchange contracts and an updated EIP-712 schema, breaking the custom signer.

The legacy custom signing flow has been replaced with the official py-clob-client-v2 Python SDK, which handles EIP-712 typed-data signing, HMAC L2 auth, and payload construction internally.

Wallet flow used

Polymarket accounts created via the web UI (MetaMask connection) follow the deposit-wallet flow:

  • The user's funds (pUSD) are held by a smart-contract deposit wallet (the "Safe API address" shown in Polymarket profile, e.g. 0x0ada…).
  • Orders are signed using SignatureTypeV2.POLY_1271 (signature_type=3) with the deposit wallet address as funder.
  • Per-account ERC-1271 validation is performed by Polymarket against the deposit wallet contract.

Changes

  • Dependency: Replaced legacy py-clob-client with py-clob-client-v2>=1.0.0.
  • Bot logic (src/bot.py): connect() derives API credentials via the official SDK; place_order() delegates entirely to sdk_client.create_and_post_order().
  • Credential caching (src/bot.py + src/client.py): cached api_creds.json is now bound to a safe_address and auto-invalidated when the configured funder changes, preventing stale credentials from carrying over after a wallet swap.
  • Default config (config/default.yaml, src/config.py): signature_type=3 (POLY_1271 — deposit-wallet flow).

How to migrate

  1. Set POLY_PRIVATE_KEY and POLY_SAFE_ADDRESS (deposit wallet shown on Polymarket profile as "Solo per uso API") in config/.env.
  2. Remove any stale data/api_creds.json.
  3. Restart the bot — credentials are re-derived automatically against the configured safe.

Fixes #6.

@matteocelani matteocelani changed the title fix: correct order payload format for Polymarket CLOB API fix: migrate order signing to Polymarket CLOB V2 May 13, 2026
@matteocelani matteocelani force-pushed the fix/invalid-order-payload branch from a6754de to df6004b Compare May 14, 2026 10:51
@matteocelani matteocelani changed the title fix: migrate order signing to Polymarket CLOB V2 fix: resolve HTTP 400 invalid order payload via official py-clob-client-v2 SDK May 14, 2026
@matteocelani matteocelani changed the title fix: resolve HTTP 400 invalid order payload via official py-clob-client-v2 SDK fix: resolve HTTP 400 invalid order payload via official py-clob-client-v2 SDK (signature_type=3 / POLY_1271) May 15, 2026
… (POLY_1271)

Polymarket migrated to CLOB V2 (April 28 2026) with new exchange contracts and
an updated EIP-712 schema, breaking the bot's hand-rolled OrderSigner.

Replaces the legacy custom signer with the official py-clob-client-v2 SDK,
which handles V2 typed-data signing, HMAC L2 auth, and payload construction.

Accounts created via the Polymarket web UI follow the deposit-wallet flow: pUSD
is held on a smart-contract deposit wallet (the "Solo per uso API" address on
the user profile). Orders use signature_type=3 (POLY_1271) with the deposit
wallet as funder; the backend validates the ERC-1271-wrapped signature against
the contract.

- Dependency: py-clob-client -> py-clob-client-v2>=1.0.0
- src/bot.py: connect() derives API credentials via SDK; place_order delegates
  to sdk_client.create_and_post_order; cancel/get_orders use SDK too
- Credential caching (src/bot.py + src/client.py): cached api_creds.json is
  bound to the safe_address it was derived for; stale creds are auto-purged
  when the configured funder changes
- src/config.py + config/default.yaml: default signature_type=3
- src/signer.py: kept for backward compatibility (no longer used for orders)
- strategies/gabagool_strategy.py + src/main.py + src/telegram_notifier.py:
  hook the new place_order error contract for clearer Telegram alerts

Fixes strongca22-cpu#6.
@matteocelani matteocelani force-pushed the fix/invalid-order-payload branch from df6004b to 9815677 Compare May 15, 2026 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTTP 400 invalid order payload after Polymarket CLOB V2 migration

1 participant