Retail limit order UX: open orders, fees, claims, and min_return (#419) #944

Merged
PlasticDigits merged 1 commit from issue-419-retail-limit-order-ux into main 2026-06-26 03:35:49 +00:00
PlasticDigits commented 2026-06-25 22:31:07 +00:00 (Migrated from gitlab.com)

Summary

Retail limit-order UX for #419 on /limits and /trade:

  • My open limits is the primary surface (above place forms), loaded via getTraderLimitPlacements(wallet, { pair }).
  • Active rows expose one-click Cancel (shared useLimitOrderCancelMutation); manual Order ID cancel is collapsed under Advanced.
  • Maker fee pre-submit copy uses retail percent labels (bpsToPercentLabel) — not bps-only jargon.
  • Parked rows split Expired — refund pending vs Dust — claim remaining (remaining_escrow < 10 → Claim dust).
  • Market hybrid tab surfaces min return + 10% pool-leg copy and book-walk spillover tooltip.
  • Pause/blacklist still disables cancel/claim with existing copy (L6).

Docs: docs/limit-orders.md, docs/frontend.md, skills/AGENTS_FRONTEND_LIMIT_PARKED_EXPIRED.md.

Acceptance checklist

Criterion Verification Result
Connected wallet sees open limits without typing Order ID for cancel make test-frontend — LimitOrderMyPlacementsPanel.test.tsx cancel row test; manual: /limits → My open limits → Cancel on row PASS
Maker placement fee explained in pre-submit (no raw bps jargon only) LimitOrderPreSubmitSummary.test.tsx; manual: pre-submit shows "Small fee… about 0.15%" PASS
Dust/expiry claim paths visible with plain-language labels limitPlacementLifecycle.test.ts; LimitOrderMyPlacementsPanel.test.tsx Claim dust; manual: parked sections PASS
min_return / belief price requirement surfaced before hybrid market submit TradeMarketOrderPanel.submitSnapshot.test.tsx hybrid notice; manual: /trade Market tab hybrid copy PASS
Pause state disables cancel/claim with existing copy LimitOrderMyPlacementsPanel.test.tsx paused tests; existing pause banners PASS
Screenshot: My limits panel with cancel action Manual LocalTerra: connect wallet → place limit → Cancel on row in My open limits SKIP (no screenshot attached in MR)
Screenshot: Limit pre-submit — maker fee + min_return copy Manual: limit pre-submit + market hybrid notice SKIP (no screenshot attached in MR)
Screenshot: Parked/expired claim row Manual: seed parked row → Claim refund / Claim dust row SKIP (no screenshot attached in MR)

Blockers: Screenshot acceptance items need manual capture on LocalTerra (functionality verified via unit tests).

Verification checklist (third parties)

export PATH="$HOME/.nvm/versions/node/$(cat .nvmrc)/bin:$PATH"
make test-frontend

Manual (needs make setup-cloud-localterra + make dev):

  1. /limits — connect wallet, place a limit, confirm My open limits shows the row with Cancel (no Order ID typing).
  2. Pre-submit — confirm maker fee shows percent copy (e.g. "about 0.15%").
  3. /trade → Market tab — enable hybrid; confirm min return notice before submit.
  4. If parked rows exist — confirm Claim refund vs Claim dust labels; pause pair and confirm buttons show Unavailable (pair paused).
## Summary Retail limit-order UX for #419 on `/limits` and `/trade`: - **My open limits** is the primary surface (above place forms), loaded via `getTraderLimitPlacements(wallet, { pair })`. - Active rows expose **one-click Cancel** (shared `useLimitOrderCancelMutation`); manual Order ID cancel is collapsed under **Advanced**. - **Maker fee** pre-submit copy uses retail percent labels (`bpsToPercentLabel`) — not bps-only jargon. - Parked rows split **Expired — refund pending** vs **Dust — claim remaining** (`remaining_escrow < 10` → **Claim dust**). - **Market** hybrid tab surfaces **min return** + 10% pool-leg copy and book-walk spillover tooltip. - Pause/blacklist still disables cancel/claim with existing copy (L6). Docs: `docs/limit-orders.md`, `docs/frontend.md`, `skills/AGENTS_FRONTEND_LIMIT_PARKED_EXPIRED.md`. ## Acceptance checklist | Criterion | Verification | Result | |-----------|--------------|--------| | Connected wallet sees open limits without typing Order ID for cancel | `make test-frontend` — `LimitOrderMyPlacementsPanel.test.tsx` cancel row test; manual: `/limits` → **My open limits** → **Cancel** on row | PASS | | Maker placement fee explained in pre-submit (no raw bps jargon only) | `LimitOrderPreSubmitSummary.test.tsx`; manual: pre-submit shows "Small fee… about 0.15%" | PASS | | Dust/expiry claim paths visible with plain-language labels | `limitPlacementLifecycle.test.ts`; `LimitOrderMyPlacementsPanel.test.tsx` Claim dust; manual: parked sections | PASS | | `min_return` / belief price requirement surfaced before hybrid market submit | `TradeMarketOrderPanel.submitSnapshot.test.tsx` hybrid notice; manual: `/trade` Market tab hybrid copy | PASS | | Pause state disables cancel/claim with existing copy | `LimitOrderMyPlacementsPanel.test.tsx` paused tests; existing pause banners | PASS | | Screenshot: My limits panel with cancel action | Manual LocalTerra: connect wallet → place limit → **Cancel** on row in **My open limits** | SKIP (no screenshot attached in MR) | | Screenshot: Limit pre-submit — maker fee + min_return copy | Manual: limit pre-submit + market hybrid notice | SKIP (no screenshot attached in MR) | | Screenshot: Parked/expired claim row | Manual: seed parked row → **Claim refund** / **Claim dust** row | SKIP (no screenshot attached in MR) | **Blockers:** Screenshot acceptance items need manual capture on LocalTerra (functionality verified via unit tests). ## Verification checklist (third parties) ```bash export PATH="$HOME/.nvm/versions/node/$(cat .nvmrc)/bin:$PATH" make test-frontend ``` Manual (needs `make setup-cloud-localterra` + `make dev`): 1. `/limits` — connect wallet, place a limit, confirm **My open limits** shows the row with **Cancel** (no Order ID typing). 2. Pre-submit — confirm maker fee shows percent copy (e.g. "about 0.15%"). 3. `/trade` → Market tab — enable hybrid; confirm **min return** notice before submit. 4. If parked rows exist — confirm **Claim refund** vs **Claim dust** labels; pause pair and confirm buttons show **Unavailable (pair paused)**.
PlasticDigits commented 2026-06-25 22:33:17 +00:00 (Migrated from gitlab.com)

Security review — MR !944

Commit reviewed: 15802093ed5b5280392a5effc51ce21aa8936a65

Scope: Retail limit-order UX (#419) — LimitOrderMyPlacementsPanel one-click cancel/claim, wallet-scoped getTraderLimitPlacements, fee/min-return copy, dust vs expired partitioning, docs/skills/tests. Frontend-only; no smart-contract or indexer handler changes in this diff.

Method: Traced attacker-controlled inputs (indexer rows, order IDs, error strings) to sinks (React render, cancel/claim mutations, confirm dialogs). Verified on-chain controls for CancelLimitOrder / ClaimExpiredLimitOrder (owner check + gate_trading_blacklist + pause gate in smartcontracts/contracts/pair/src/contract.rs).

Outcome: FINDINGS: 0 medium+

No inline threads — nothing met the reporting bar.

Areas checked (no issues)

Area Result
Authz / cancel & claim One-click actions use order_id from wallet-scoped indexer data; mutations call existing useLimitOrderCancelMutation / useLimitExpiredClaimMutation → on-chain owner + blacklist enforcement. Wrong/third-party IDs revert (Unauthorized), not fund loss.
XSS / HTML injection Indexer fields rendered as React text nodes; errors pass through TxResultAlert → humanizeUserFacingError. No dangerouslySetInnerHTML added.
URL / path injection getTraderLimitPlacements uses existing pathSegment (encodeURIComponent); no new SSRF surface.
Privacy regression Switch from pair-wide getPairLimitPlacements + client filter to getTraderLimitPlacements(wallet, { pair }) reduces exposure of other makers' order metadata in the browser.
Blacklist UX gap on /limits LimitOrdersPage panel omits cancelDisabled/claimsDisabled props that /trade passes — pre-existing page never wired useTradingBlacklist; on-chain still blocks blacklisted senders. Gas-waste UX only, not an exploitable bypass.
Dependencies / supply chain No new packages in diff.

Label: block:security not applied.

## Security review — MR !944 **Commit reviewed:** `15802093ed5b5280392a5effc51ce21aa8936a65` **Scope:** Retail limit-order UX (#419) — `LimitOrderMyPlacementsPanel` one-click cancel/claim, wallet-scoped `getTraderLimitPlacements`, fee/min-return copy, dust vs expired partitioning, docs/skills/tests. Frontend-only; no smart-contract or indexer handler changes in this diff. **Method:** Traced attacker-controlled inputs (indexer rows, order IDs, error strings) to sinks (React render, cancel/claim mutations, confirm dialogs). Verified on-chain controls for `CancelLimitOrder` / `ClaimExpiredLimitOrder` (owner check + `gate_trading_blacklist` + pause gate in `smartcontracts/contracts/pair/src/contract.rs`). **Outcome:** **FINDINGS: 0** medium+ No inline threads — nothing met the reporting bar. ### Areas checked (no issues) | Area | Result | |------|--------| | **Authz / cancel & claim** | One-click actions use `order_id` from wallet-scoped indexer data; mutations call existing `useLimitOrderCancelMutation` / `useLimitExpiredClaimMutation` → on-chain owner + blacklist enforcement. Wrong/third-party IDs revert (`Unauthorized`), not fund loss. | | **XSS / HTML injection** | Indexer fields rendered as React text nodes; errors pass through `TxResultAlert` → `humanizeUserFacingError`. No `dangerouslySetInnerHTML` added. | | **URL / path injection** | `getTraderLimitPlacements` uses existing `pathSegment` (`encodeURIComponent`); no new SSRF surface. | | **Privacy regression** | Switch from pair-wide `getPairLimitPlacements` + client filter to `getTraderLimitPlacements(wallet, { pair })` **reduces** exposure of other makers' order metadata in the browser. | | **Blacklist UX gap on `/limits`** | `LimitOrdersPage` panel omits `cancelDisabled`/`claimsDisabled` props that `/trade` passes — pre-existing page never wired `useTradingBlacklist`; on-chain still blocks blacklisted senders. Gas-waste UX only, not an exploitable bypass. | | **Dependencies / supply chain** | No new packages in diff. | **Label:** `block:security` not applied.
PlasticDigits commented 2026-06-26 03:35:50 +00:00 (Migrated from gitlab.com)

mentioned in commit aac5dcea3a

mentioned in commit aac5dcea3ad885d0f75d6b295ad839a20044335f
PlasticDigits (Migrated from gitlab.com) merged commit aac5dcea3a into main 2026-06-26 03:35:50 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic!944
No description provided.