polynode 0.10.1__tar.gz → 0.10.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {polynode-0.10.1 → polynode-0.10.3}/PKG-INFO +1 -1
  2. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/eip712.py +85 -14
  3. {polynode-0.10.1 → polynode-0.10.3}/pyproject.toml +1 -1
  4. {polynode-0.10.1 → polynode-0.10.3}/.gitignore +0 -0
  5. {polynode-0.10.1 → polynode-0.10.3}/README.md +0 -0
  6. {polynode-0.10.1 → polynode-0.10.3}/polynode/__init__.py +0 -0
  7. {polynode-0.10.1 → polynode-0.10.3}/polynode/_version.py +0 -0
  8. {polynode-0.10.1 → polynode-0.10.3}/polynode/cache/__init__.py +0 -0
  9. {polynode-0.10.1 → polynode-0.10.3}/polynode/client.py +0 -0
  10. {polynode-0.10.1 → polynode-0.10.3}/polynode/engine.py +0 -0
  11. {polynode-0.10.1 → polynode-0.10.3}/polynode/errors.py +0 -0
  12. {polynode-0.10.1 → polynode-0.10.3}/polynode/orderbook.py +0 -0
  13. {polynode-0.10.1 → polynode-0.10.3}/polynode/orderbook_state.py +0 -0
  14. {polynode-0.10.1 → polynode-0.10.3}/polynode/redemption_watcher.py +0 -0
  15. {polynode-0.10.1 → polynode-0.10.3}/polynode/short_form.py +0 -0
  16. {polynode-0.10.1 → polynode-0.10.3}/polynode/subscription.py +0 -0
  17. {polynode-0.10.1 → polynode-0.10.3}/polynode/testing.py +0 -0
  18. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/V2_ORDER_FLOW.md +0 -0
  19. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/__init__.py +0 -0
  20. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/clob_api.py +0 -0
  21. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/constants.py +0 -0
  22. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/cosigner.py +0 -0
  23. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/escrow.py +0 -0
  24. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/onboarding.py +0 -0
  25. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/position_management.py +0 -0
  26. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/privy.py +0 -0
  27. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/relayer.py +0 -0
  28. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/signer.py +0 -0
  29. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/sqlite_backend.py +0 -0
  30. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/trader.py +0 -0
  31. {polynode-0.10.1 → polynode-0.10.3}/polynode/trading/types.py +0 -0
  32. {polynode-0.10.1 → polynode-0.10.3}/polynode/types/__init__.py +0 -0
  33. {polynode-0.10.1 → polynode-0.10.3}/polynode/types/enums.py +0 -0
  34. {polynode-0.10.1 → polynode-0.10.3}/polynode/types/events.py +0 -0
  35. {polynode-0.10.1 → polynode-0.10.3}/polynode/types/orderbook.py +0 -0
  36. {polynode-0.10.1 → polynode-0.10.3}/polynode/types/rest.py +0 -0
  37. {polynode-0.10.1 → polynode-0.10.3}/polynode/types/short_form.py +0 -0
  38. {polynode-0.10.1 → polynode-0.10.3}/polynode/types/ws.py +0 -0
  39. {polynode-0.10.1 → polynode-0.10.3}/polynode/ws.py +0 -0
  40. {polynode-0.10.1 → polynode-0.10.3}/tests/__init__.py +0 -0
  41. {polynode-0.10.1 → polynode-0.10.3}/tests/conftest.py +0 -0
  42. {polynode-0.10.1 → polynode-0.10.3}/tests/test_client.py +0 -0
  43. {polynode-0.10.1 → polynode-0.10.3}/tests/test_orderbook.py +0 -0
  44. {polynode-0.10.1 → polynode-0.10.3}/tests/test_trading.py +0 -0
  45. {polynode-0.10.1 → polynode-0.10.3}/tests/test_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polynode
3
- Version: 0.10.1
3
+ Version: 0.10.3
4
4
  Summary: Python SDK for the PolyNode real-time prediction market data platform
5
5
  Project-URL: Homepage, https://polynode.dev
6
6
  Project-URL: Documentation, https://docs.polynode.dev
@@ -79,6 +79,22 @@ ORDER_TYPES_V2 = {
79
79
  ],
80
80
  }
81
81
 
82
+ # ── POLY_1271 (Solady TypedDataSign) ──
83
+
84
+ ORDER_TYPE_STRING = b"Order(uint256 salt,address maker,address signer,uint256 tokenId,uint256 makerAmount,uint256 takerAmount,uint8 side,uint8 signatureType,uint256 timestamp,bytes32 metadata,bytes32 builder)"
85
+
86
+ TYPED_DATA_SIGN_TYPES = {
87
+ "TypedDataSign": [
88
+ {"name": "contents", "type": "Order"},
89
+ {"name": "name", "type": "string"},
90
+ {"name": "version", "type": "string"},
91
+ {"name": "chainId", "type": "uint256"},
92
+ {"name": "verifyingContract", "type": "address"},
93
+ {"name": "salt", "type": "bytes32"},
94
+ ],
95
+ "Order": ORDER_TYPES_V2["Order"],
96
+ }
97
+
82
98
 
83
99
  def compute_amounts(
84
100
  price: float,
@@ -304,28 +320,83 @@ async def create_signed_order_v2(
304
320
  builder=builder,
305
321
  )
306
322
 
307
- signature = await sign_typed_data(payload)
308
- if not signature.startswith("0x"):
309
- signature = f"0x{signature}"
310
-
311
- # Normalize v to raw recovery id (0/1): CLOB expects v=0/1 for order signatures
312
- sig_bytes = bytearray(bytes.fromhex(signature[2:]))
313
- if len(sig_bytes) == 65 and sig_bytes[-1] >= 27:
314
- sig_bytes[-1] -= 27
315
- signature = "0x" + sig_bytes.hex()
323
+ if signature_type == SignatureType.POLY_1271:
324
+ # POLY_1271: use TypedDataSign as primary type, then wrap the signature
325
+ zero_bytes32 = "0x" + "00" * 32
326
+ tds_payload = Eip712Payload(
327
+ domain=payload.domain,
328
+ types=TYPED_DATA_SIGN_TYPES,
329
+ primary_type="TypedDataSign",
330
+ message={
331
+ "contents": payload.message,
332
+ "name": "DepositWallet",
333
+ "version": "1",
334
+ "chainId": 137,
335
+ "verifyingContract": funder_address,
336
+ "salt": zero_bytes32,
337
+ },
338
+ )
339
+ inner_sig = await sign_typed_data(tds_payload)
340
+ if not inner_sig.startswith("0x"):
341
+ inner_sig = f"0x{inner_sig}"
342
+ inner_bytes = bytearray(bytes.fromhex(inner_sig[2:]))
343
+ if len(inner_bytes) == 65 and inner_bytes[-1] >= 27:
344
+ inner_bytes[-1] -= 27
345
+
346
+ # Compute app domain separator and contents hash for wrapping
347
+ from eth_utils import keccak
348
+ from eth_abi import encode
349
+
350
+ domain_type = b"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
351
+ app_dom_sep = keccak(encode(
352
+ ["bytes32", "bytes32", "bytes32", "uint256", "address"],
353
+ [keccak(domain_type), keccak(b"Polymarket CTF Exchange"), keccak(b"2"),
354
+ payload.domain["chainId"], payload.domain["verifyingContract"]],
355
+ ))
356
+ order_type_hash = keccak(ORDER_TYPE_STRING)
357
+ contents_hash = keccak(encode(
358
+ ["bytes32", "uint256", "address", "address", "uint256", "uint256", "uint256",
359
+ "uint8", "uint8", "uint256", "bytes32", "bytes32"],
360
+ [order_type_hash, payload.message["salt"], payload.message["maker"],
361
+ payload.message["signer"], payload.message["tokenId"],
362
+ payload.message["makerAmount"], payload.message["takerAmount"],
363
+ payload.message["side"], payload.message["signatureType"],
364
+ payload.message["timestamp"], bytes.fromhex(payload.message["metadata"][2:]),
365
+ bytes.fromhex(payload.message["builder"][2:])],
366
+ ))
367
+
368
+ # Wrap: innerSig(65) + appDomSep(32) + contentsHash(32) + typeString(186) + len(2)
369
+ wrapped = bytearray()
370
+ wrapped.extend(inner_bytes)
371
+ wrapped.extend(app_dom_sep)
372
+ wrapped.extend(contents_hash)
373
+ wrapped.extend(ORDER_TYPE_STRING)
374
+ type_len = len(ORDER_TYPE_STRING)
375
+ wrapped.append((type_len >> 8) & 0xFF)
376
+ wrapped.append(type_len & 0xFF)
377
+ signature = "0x" + wrapped.hex()
378
+ else:
379
+ signature = await sign_typed_data(payload)
380
+ if not signature.startswith("0x"):
381
+ signature = f"0x{signature}"
382
+ # Normalize v to raw recovery id (0/1): CLOB expects v=0/1 for order signatures
383
+ sig_bytes = bytearray(bytes.fromhex(signature[2:]))
384
+ if len(sig_bytes) == 65 and sig_bytes[-1] >= 27:
385
+ sig_bytes[-1] -= 27
386
+ signature = "0x" + sig_bytes.hex()
316
387
 
317
388
  return {
318
389
  "salt": payload.message["salt"], # number
319
390
  "maker": funder_address,
320
391
  "signer": signer_address,
321
- "taker": "0x0000000000000000000000000000000000000000", # zero = public order (post-sign field)
392
+ "taker": "0x0000000000000000000000000000000000000000",
322
393
  "tokenId": token_id,
323
394
  "makerAmount": str(maker_amount),
324
395
  "takerAmount": str(taker_amount),
325
- "side": side, # string "BUY"/"SELL"
326
- "signatureType": int(signature_type), # number
327
- "timestamp": str(payload.message["timestamp"]), # string
328
- "expiration": "0", # "0" = no expiration (matches @polymarket/clob-client-v2)
396
+ "side": side,
397
+ "signatureType": int(signature_type),
398
+ "timestamp": str(payload.message["timestamp"]),
399
+ "expiration": "0",
329
400
  "metadata": payload.message["metadata"],
330
401
  "builder": payload.message["builder"],
331
402
  "signature": signature,
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "polynode"
7
- version = "0.10.1"
7
+ version = "0.10.3"
8
8
  description = "Python SDK for the PolyNode real-time prediction market data platform"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes