No order type selector on /trade — only limit order form present, no market order type or disabled-type rationale (W7:C1) #152

Closed
opened 2026-05-11 12:14:19 +00:00 by totdking · 16 comments
totdking commented 2026-05-11 12:14:19 +00:00 (Migrated from gitlab.com)
No description provided.
totdking commented 2026-05-11 12:20:55 +00:00 (Migrated from gitlab.com)

Issue Summary

The /trade page offers no order type selector. Only a "Place Limit" form and a "Cancel Limit" form are present. There is no market order type, no type switcher, no disabled-type indicator, and no rationale explaining why market orders are unavailable.


Reproduction Steps

  1. Complete full local setup (LocalTerra running, contracts deployed, indexer running, frontend running)
  2. Connect a Station wallet configured for localterra
  3. Navigate to /trade (or /trade/<pair_address>)
  4. Select any pair — tested with EMBER / CORAL (terra146...c9mjav)
  5. Observe the right-hand Order Ticket panel

Expected Behavior

An order type selector (tab or dropdown) allowing the trader to choose between at least Market and Limit order types. If market orders are intentionally unsupported or not yet implemented, the UI should show the option as disabled with a visible reason (tooltip or label).


Actual Behavior

The panel renders a "Place Limit" section and a "Cancel Limit" section only. No order type selector control exists. A CEX-migrant trader has no way to carry out market orders, simply because there is no ui entry that supports


Environment Details

Field Value
OS macOS (Apple M1 Pro, 14-inch)
Browser Google Chrome (desktop)
Viewport ~1440px desktop
Network localterra (local Docker)
Frontend VITE_NETWORK=local npm run dev at localhost:3000
Indexer Running (make indexer-dev)
Contracts Deployed via make deploy-local

Wallet / Device Details

  • Wallet: All wallets
  • Wallet state: Connected — terra1...sl7cvv
  • Pair tested: EMBER / CORAL (terra146...c9mjav)

Screenshots

See attached screenshot showing the /trade Order Ticket panel with only "Place Limit" and "Cancel Limit" sections — no order type selector present.

image.png{width="900" height="544"}


Severity / Impact

LAUNCH-BLOCKER. Market orders cannot be tested at all — the UI provides no surface for them. This blocks W7-C1 verification entirely: there is no order type selector to navigate, toggle, hover, or keyboard-through. It also cascades into W7-C3 (price input tick enforcement is only testable on limit), W7-C5 (TIF options, which differ by order type), and W7-C8 (submit CTA label is hardcoded to "Place Limit" rather than reflecting the active order type and side). A hybrid DEX that presents only limit order entry with no market order path — and no explanation that market orders are unsupported or planned — gives CEX-migrant traders no fast-execution route and no clarity on what the product supports. This must be resolved or explicitly scoped out (with in-UI messaging) before launch.

cc : @PlasticDigits LAUNCH BLOCKER !

~"blocker:limit-orders"


### Issue Summary The `/trade` page offers no order type selector. Only a "Place Limit" form and a "Cancel Limit" form are present. There is no market order type, no type switcher, no disabled-type indicator, and no rationale explaining why market orders are unavailable. --- ### Reproduction Steps 1. Complete full local setup (LocalTerra running, contracts deployed, indexer running, frontend running) 2. Connect a Station wallet configured for localterra 3. Navigate to `/trade` (or `/trade/<pair_address>`) 4. Select any pair — tested with EMBER / CORAL (`terra146...c9mjav`) 5. Observe the right-hand Order Ticket panel --- ### Expected Behavior An order type selector (tab or dropdown) allowing the trader to choose between at least **Market** and **Limit** order types. If market orders are intentionally unsupported or not yet implemented, the UI should show the option as disabled with a visible reason (tooltip or label). --- ### Actual Behavior The panel renders a "Place Limit" section and a "Cancel Limit" section only. No order type selector control exists. A CEX-migrant trader has no way to carry out market orders, simply because there is no ui entry that supports --- ### Environment Details | Field | Value | |-------|-------| | OS | macOS (Apple M1 Pro, 14-inch) | | Browser | Google Chrome (desktop) | | Viewport | \~1440px desktop | | Network | `localterra` (local Docker) | | Frontend | `VITE_NETWORK=local npm run dev` at `localhost:3000` | | Indexer | Running (`make indexer-dev`) | | Contracts | Deployed via `make deploy-local` | --- ### Wallet / Device Details - **Wallet:** All wallets - **Wallet state:** Connected — `terra1...sl7cvv` - **Pair tested:** EMBER / CORAL (`terra146...c9mjav`) --- ### Screenshots > See attached screenshot showing the `/trade` Order Ticket panel with only "Place Limit" and "Cancel Limit" sections — no order type selector present. ![image.png](/uploads/d5a04ccd59a6dd86058639c58bc65c13/image.png){width="900" height="544"} --- ### Severity / Impact **LAUNCH-BLOCKER.** Market orders cannot be tested at all — the UI provides no surface for them. This blocks W7-C1 verification entirely: there is no order type selector to navigate, toggle, hover, or keyboard-through. It also cascades into W7-C3 (price input tick enforcement is only testable on limit), W7-C5 (TIF options, which differ by order type), and W7-C8 (submit CTA label is hardcoded to "Place Limit" rather than reflecting the active order type and side). A hybrid DEX that presents only limit order entry with no market order path — and no explanation that market orders are unsupported or planned — gives CEX-migrant traders no fast-execution route and no clarity on what the product supports. This must be resolved or explicitly scoped out (with in-UI messaging) before launch. cc : @PlasticDigits LAUNCH BLOCKER ! ~"blocker:limit-orders" ---
totdking commented 2026-05-11 12:23:09 +00:00 (Migrated from gitlab.com)

changed title from No order type selector on `/trade` — only limit order form present, no market order type or disabled-type rationale to No order type selector on `/trade` — only limit order form present, no market order type or disabled-type rationale (W7:C1)

<p>changed title from <code class="idiff">No order type selector on `/trade` — only limit order form present, no market order type or disabled-type rationale</code> to <code class="idiff">No order type selector on `/trade` — only limit order form present, no market order type or disabled-type rationale<span class="idiff left right addition"> (W7:C1)</span></code></p>
totdking commented 2026-05-11 12:23:09 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
totdking commented 2026-05-11 17:31:47 +00:00 (Migrated from gitlab.com)

mentioned in issue #116

mentioned in issue #116
PlasticDigits commented 2026-05-12 07:55:39 +00:00 (Migrated from gitlab.com)

mentioned in commit 965baf9cd9

mentioned in commit 965baf9cd930cbcd8b9507756b2ce50e153c01a9
PlasticDigits commented 2026-05-12 07:55:39 +00:00 (Migrated from gitlab.com)

mentioned in commit 3ede6ca8de

mentioned in commit 3ede6ca8dedb48293053e75337c138a42fc57119
PlasticDigits commented 2026-05-12 07:56:03 +00:00 (Migrated from gitlab.com)

Update (GitLab #152) — shipped on main @ 3ede6ca

Implemented Limit / Market tabs on /trade, market execution with global slippage + optional hybrid (indexer POST /route/solve when available, else pair hybrid_simulation / pool fallback), expected receive + min after slippage, and two-tx LUNC preflight for increase_allowance + swap.

Limit path now stacks three client guards before place: book-head crossing (bid must stay below best ask; ask above best bid — limit-book?limit=1), tape-reference direction (#154), plus existing escrow + native gas gates.

Verification checklist (for QA / @brouie)

  • /trade/:pair shows Limit and Market tabs; keyboard focus order still sane with the Bid/Ask radiogroup (#153).
  • Market tab: enter amount → quote card shows Expected receive + Min. after slippage; toggling hybrid changes disclosure; Price impact too high disables submit when spread preflight trips.
  • Market submit path: with hybrid + indexer up, confirm txs match router ops when indexer returns estimated_amount_out; with indexer down, confirm direct pair swap still broadcasts.
  • Limit tab: with a non-empty book, confirm a bid at/above best ask (and ask at/below best bid) is blocked with inline warning; tape-direction gate (#154) still blocks wrong-side limits vs last trade.
  • Pause pair (L6): market and limit submit stay disabled; copy mentions swaps.
  • npm run test:unit in frontend-dapp (Vitest) passes locally.

Issue left open pending your sign-off.

cc @brouie — please verify on LocalTerra + indexer when you have a moment.

## Update (GitLab #152) — shipped on `main` @ 3ede6ca Implemented **Limit / Market** tabs on `/trade`, **market** execution with **global slippage** + optional **hybrid** (indexer `POST /route/solve` when available, else pair `hybrid_simulation` / pool fallback), **expected receive** + **min after slippage**, and **two-tx** LUNC preflight for `increase_allowance` + swap. **Limit** path now stacks **three** client guards before place: **book-head crossing** (bid must stay **below** best ask; ask **above** best bid — `limit-book?limit=1`), **tape-reference direction** (#154), plus existing escrow + native gas gates. ### Verification checklist (for QA / @brouie) - [ ] `/trade/:pair` shows **Limit** and **Market** tabs; keyboard focus order still sane with the **Bid/Ask** radiogroup (#153). - [ ] **Market** tab: enter amount → quote card shows **Expected receive** + **Min. after slippage**; toggling **hybrid** changes disclosure; **Price impact too high** disables submit when spread preflight trips. - [ ] **Market** submit path: with hybrid + indexer up, confirm txs match **router** ops when indexer returns `estimated_amount_out`; with indexer down, confirm **direct pair** `swap` still broadcasts. - [ ] **Limit** tab: with a non-empty book, confirm a bid **at/above** best ask (and ask **at/below** best bid) is **blocked** with inline warning; tape-direction gate (#154) still blocks wrong-side limits vs last trade. - [ ] Pause pair (L6): **market** and **limit** submit stay disabled; copy mentions swaps. - [ ] `npm run test:unit` in `frontend-dapp` (Vitest) passes locally. Issue left **open** pending your sign-off. cc @brouie — please verify on LocalTerra + indexer when you have a moment.
PlasticDigits commented 2026-05-26 12:21:54 +00:00 (Migrated from gitlab.com)

mentioned in issue #201

mentioned in issue #201
PlasticDigits commented 2026-05-27 04:44:16 +00:00 (Migrated from gitlab.com)

QA verification sign-off (@brouie / agent)

Verified on LocalTerra + host Postgres + indexer (:3001) + frontend (:3000) + 30/30 bot swarm.

Checklist

  • /trade/:pair Limit / Market tabs — EMBER/CORAL pair shows both tabs (data-testid=trade-order-tab-limit|market); Bid/Ask radiogroup uses WAI-ARIA role=radiogroup with arrow-key side switching (trade-ticket-side-*).
  • Market tab quote UX — Amount 10 CORAL → quote card shows Expected receive + Min. after slippage; hybrid ON shows Indexer hybrid disclosure; hybrid OFF shows Direct pair · hybrid_simulation (pool-only leg) disclosure.
  • Market submit (hybrid + indexer up) — Market buy broadcast succeeded (Market swap submitted toast) with hybrid routing + indexer quote path on connected local wallet.
  • Limit book-head crossing guard — Buy limit price 1.06 (≥ best ask 1.056645) blocks submit with best-ask crossing warning; unit tests in limitOrderNonCrossing.test.ts.
  • Pause pair (L6) — TradePage.test.tsx asserts pause banner copy mentions swaps and disables limit submit; market panel gates on !isPaused in TradeMarketOrderPanel.
  • npm run test:unit — 599/599 pass (including TradePage #152 tab test + router hybrid message-shape tests).

Notes

  • Indexer-down direct-pair fallback not isolated in this pass (indexer stayed healthy); code path falls through postRouteSolve → simulateHybridSwap → swap() when indexer ops absent.
  • Fix already on main (Limit/Market tabs, market panel, crossing guards) — no additional code changes required for #152.

Closing as verified.

## QA verification sign-off (@brouie / agent) Verified on LocalTerra + host Postgres + indexer (`:3001`) + frontend (`:3000`) + 30/30 bot swarm. ### Checklist - [x] **`/trade/:pair` Limit / Market tabs** — EMBER/CORAL pair shows both tabs (`data-testid=trade-order-tab-limit|market`); Bid/Ask radiogroup uses WAI-ARIA `role=radiogroup` with arrow-key side switching (`trade-ticket-side-*`). - [x] **Market tab quote UX** — Amount `10` CORAL → quote card shows **Expected receive** + **Min. after slippage**; hybrid ON shows **Indexer hybrid** disclosure; hybrid OFF shows **Direct pair · hybrid_simulation (pool-only leg)** disclosure. - [x] **Market submit (hybrid + indexer up)** — **Market buy** broadcast succeeded (`Market swap submitted` toast) with hybrid routing + indexer quote path on connected local wallet. - [x] **Limit book-head crossing guard** — Buy limit price `1.06` (≥ best ask `1.056645`) blocks submit with best-ask crossing warning; unit tests in `limitOrderNonCrossing.test.ts`. - [x] **Pause pair (L6)** — `TradePage.test.tsx` asserts pause banner copy mentions **swaps** and disables limit submit; market panel gates on `!isPaused` in `TradeMarketOrderPanel`. - [x] **`npm run test:unit`** — 599/599 pass (including `TradePage` #152 tab test + router hybrid message-shape tests). ### Notes - **Indexer-down direct-pair fallback** not isolated in this pass (indexer stayed healthy); code path falls through `postRouteSolve` → `simulateHybridSwap` → `swap()` when indexer ops absent. - Fix already on `main` (Limit/Market tabs, market panel, crossing guards) — no additional code changes required for #152. Closing as verified.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-05-27 04:44:18 +00:00
PlasticDigits commented 2026-06-05 04:41:22 +00:00 (Migrated from gitlab.com)

mentioned in merge request !767

mentioned in merge request !767
PlasticDigits commented 2026-06-05 05:42:28 +00:00 (Migrated from gitlab.com)

mentioned in issue #321

mentioned in issue #321
PlasticDigits commented 2026-06-05 11:03:56 +00:00 (Migrated from gitlab.com)

mentioned in issue #297

mentioned in issue #297
PlasticDigits commented 2026-08-17 10:26:08 +00:00 (Migrated from gitlab.com)

mentioned in issue #546

mentioned in issue #546
PlasticDigits commented 2026-08-17 10:26:08 +00:00 (Migrated from gitlab.com)

marked as related to #546

marked as related to #546
PlasticDigits commented 2026-08-22 12:26:36 +00:00 (Migrated from gitlab.com)

mentioned in issue #597

mentioned in issue #597
PlasticDigits commented 2026-08-28 05:28:47 +00:00 (Migrated from gitlab.com)

mentioned in issue #693

mentioned in issue #693
Sign in to join this conversation.
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#152
No description provided.