Skip to content

fix: accept GTD expiration boundary#46

Merged
cesarenaldi merged 2 commits into
mainfrom
feature/dev-136-fix-python-sdk-gtd-expiration-boundary-validation
May 26, 2026
Merged

fix: accept GTD expiration boundary#46
cesarenaldi merged 2 commits into
mainfrom
feature/dev-136-fix-python-sdk-gtd-expiration-boundary-validation

Conversation

@cesarenaldi
Copy link
Copy Markdown
Collaborator

@cesarenaldi cesarenaldi commented May 26, 2026

Summary

  • Align GTD expiration validation with the CLOB boundary by accepting expirations exactly 60 seconds in the future.
  • Add deterministic unit coverage for the below-boundary and at-boundary cases.
  • Document that immediate submissions should use extra expiration buffer for latency and clock skew.

Verification

  • uv run pytest tests/unit/test_order_limit.py
  • uv run ruff check src/polymarket/_internal/actions/orders/limit.py src/polymarket/clients/secure.py src/polymarket/clients/async_secure.py tests/unit/test_order_limit.py
  • uv run ruff format --check src/polymarket/_internal/actions/orders/limit.py src/polymarket/clients/secure.py src/polymarket/clients/async_secure.py tests/unit/test_order_limit.py
  • uv run pyright src/polymarket/_internal/actions/orders/limit.py src/polymarket/clients/secure.py src/polymarket/clients/async_secure.py tests/unit/test_order_limit.py

Linear: DEV-136
Closes #44


Note

Low Risk
Small validation boundary fix for limit-order expiration with tests; no auth or payment paths touched.

Overview
GTD limit orders can use an expiration exactly 60 seconds ahead of “now.” Validation in validate_limit_order_params no longer rejects that timestamp: the check changes from expiration <= minimum to expiration < minimum, matching the CLOB’s inclusive minimum.

Docs on sync/async create_limit_order and place_limit_order now state the 60-second rule and suggest extra buffer for immediate posts (latency/clock skew).

Tests add frozen-clock cases for now + 59 (reject) and now + 60 (accept).

Reviewed by Cursor Bugbot for commit 20c9600. Bugbot is set up for automated code reviews on this repo. Configure here.

@Nexory
Copy link
Copy Markdown

Nexory commented May 26, 2026

Approach is exactly right (Option 1 from the issue), and good catch on aligning with the CLOB server-side rule rather than just patching the message.

The deterministic monkeypatch.setattr test pattern is clean — the two boundary cases (now + 59 rejected, now + 60 accepted) pin the contract precisely.

One minor consideration: a client that builds the order at now + 60 and ships it over the wire could land at the server slightly later, which would put effective remaining time below 60s. If the CLOB rule is also inclusive at the server (which your comment suggests), this is a non-issue. Flagging in case network latency is worth a 1-2s safety margin somewhere; otherwise LGTM.

@Nexory
Copy link
Copy Markdown

Nexory commented May 26, 2026

The docstring addition is the right call — keeps the boundary aligned with the server while making the buffer expectation explicit at the public API surface. "Use extra buffer for immediate submissions to account for latency and clock skew" is exactly the framing users need.

LGTM, thanks for the quick turnaround on both PRs.

@cesarenaldi cesarenaldi merged commit 3a5615f into main May 26, 2026
7 checks passed
@cesarenaldi cesarenaldi deleted the feature/dev-136-fix-python-sdk-gtd-expiration-boundary-validation branch May 26, 2026 13:23
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.

validate_limit_order_params: off-by-one between GTD expiration check and error message

2 participants