CLOB v2 "invalid signature" 调试文档
Status: ✅ RESOLVED (2026-04-29)
问题
通过 web 界面挂单时,返回 HTTP 400:
{"error":"invalid signature"}
根因(3 个)
🔴 根因 1: eth_account 0.13.x 非标准 EIP-712 编码
eth_account 0.13.7 使用 \x01 作为 EIP-712 version byte,而非传统规范的 \x19\x01 前缀。
这导致签名的 digest hash 与 viem(npm 客户端使用的签名库)和 Polymarket 链上合约不一致。
修复: 降级到 eth_account==0.12.4,该版本使用标准 \x19\x01 前缀。
🔴 根因 2: Order timestamp 单位错误(秒 vs 毫秒)
npm v2 的 buildOrderCreationArgs 使用 Date.now()(毫秒,13位整数),
而 Python 使用 int(time.time())(Unix 秒,10位整数)。
这导致 EIP-712 签名中的 timestamp 字段值不同,签名哈希不匹配。
修复: 改为 int(time.time() * 1000)。
🔴 根因 3: Verifying contract 使用 v1 地址
EIP-712 domain 的 verifyingContract 必须是 v2 交易所合约地址,
而非 v1 地址。不同的合约地址产生不同的 domain separator,导致签名无效。
| 类型 | v1 地址 | v2 地址 |
|---|---|---|
| CTF Exchange | 0x4bFb41... | 0xE11118... |
| Neg Risk Exchange | 0xC5d563... | 0xe2222d... |
修复: 添加 EXCHANGE_ADDRESS_V2 和 NEG_RISK_EXCHANGE_ADDRESS_V2,_get_verifying_contract() 返回 v2 地址。
修复验证
HTTP 400 {"error":"invalid signature"}HTTP 400 {"error":"not enough balance / allowance"} — 签名已验证通过额外改进
_l2_sign(): 添加服务器时间同步(GET /time),避免时钟偏差_l2_sign(): 添加诊断日志(HMAC message、secret hex、signature 等)get_clob_version() 方法(GET /version)get_orders() 端点确认为 /data/orders(npm v2 的 GET_OPEN_ORDERS)