Align trade bid/ask labels and slippage terminology for CEX migrants #412

Closed
opened 2026-06-25 14:12:42 +00:00 by PlasticDigits · 10 comments
PlasticDigits commented 2026-06-25 14:12:42 +00:00 (Migrated from gitlab.com)

Parent

#411 — Updated Gap Analysis (bundle: recommendations 1 + 4)

Current codebase

  • frontend-dapp/src/utils/tradeDirectionSideLabels.ts returns bidLabel: "Buy {base}" and askLabel: "Buy {quote}" while TradeOrderTicket.tsx renders the heading as {verb} {receive} — on the ask side that is "Sell {base}", so the bid/ask buttons and ticket title use contradictory verbs.
  • LimitOrderBidAskSideSelector.tsx and TradeOrderTicket.tsx consume the labels.
  • Slippage is named inconsistently: Settings use "Slippage Tolerance" (SwapPage.tsx), pre-sign / chain paths use "max spread" (humanizeTerraTxError.ts, stores/dex.ts → maxSpreadStr), and route metrics expose "expected slippage" / routeSlippagePercent (swapRouteSlippage.ts, indexer route_slippage.rs #293).
  • Transaction deadline (deadlineSeconds: 300 in stores/dex.ts) is never surfaced in Swap Settings.

Why needed

CEX/DEX migrants map Buy/Sell to base-asset semantics. Contradictory bid/ask vs ticket copy erodes trust on the highest-traffic pro surface (/trade). Split slippage terminology causes users to misconfigure protection and misread chain rejections.

Constraints / guardrails

  • Preserve correct bid = buy base / ask = sell base book semantics; do not break limitOrderNonCrossing.ts or post-only guards.
  • Keep humanizeTerraTxError.ts chain-log mapping accurate — retail label unification must not regress #134 / #135 error copy.
  • Distinguish slippage tolerance (user guard) from route slippage (#293 cross-rate metric) in tooltips, not by reusing the same label.
  • Mobile: base/quote price help is hidden lg:block in TradeOrderTicket.tsx — any copy fix should remain readable on small screens.

Relevant files

  • frontend-dapp/src/utils/tradeDirectionSideLabels.ts
  • frontend-dapp/src/utils/__tests__/tradeDirectionSideLabels.test.ts
  • frontend-dapp/src/components/trade/LimitOrderBidAskSideSelector.tsx
  • frontend-dapp/src/components/trade/TradeOrderTicket.tsx
  • frontend-dapp/src/pages/SwapPage.tsx (Settings slippage block)
  • frontend-dapp/src/utils/swapRouteSlippage.ts
  • frontend-dapp/src/utils/humanizeTerraTxError.ts
  • frontend-dapp/src/stores/dex.ts
  • docs/swap-max-spread-ux.md
  1. Change bid/ask labels to CEX-standard "Buy {base}" / "Sell {base}" (or short "Buy" / "Sell" with base symbol only in the ticket heading).
  2. Pick one retail term for the user guard (e.g. "Slippage protection") across Settings, pre-submit summaries, and humanized tx errors; footnote that on-chain the parameter is max_spread.
  3. Add transaction deadline (seconds / minutes) to Swap Settings with the same presets pattern as slippage.
  4. Add tooltip on route slippage line clarifying it is an execution-quality metric, not the tolerance setting.

Acceptance criteria

  • Bid/ask buttons and ticket heading use consistent Buy/Sell semantics for the same side.
  • Unit tests cover label semantics for both sides.
  • Settings, pre-submit, and humanized chain errors use unified slippage-protection wording.
  • Tx deadline is visible and editable in Swap Settings (default 300s).
  • Route slippage (#293) remains labeled distinctly from tolerance.
  • Screenshot: /trade order ticket — bid selected, ask selected — buttons and heading agree.
  • Screenshot: Swap Settings showing slippage + deadline with unified labels.

Test plan

  • cd frontend-dapp && npm run test:unit — extend tradeDirectionSideLabels.test.ts; humanizeUserFacingError.test.ts if error strings change.
  • make lint-frontend
  • Manual: /trade toggle bid/ask; confirm heading + buttons; place no tx required.
  • Manual: Swap Settings — change slippage and deadline; confirm store persistence.

Attack / abuse test plan

  • N/A (copy/IA only). Verify expert-mode block threshold (#293) still applies after label changes.

Verification criteria

  • No regression in TradePage.test.tsx bid/ask / limit tab tests.
  • make test-frontend green.
## Parent [#411 — Updated Gap Analysis](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/411) (bundle: recommendations 1 + 4) ## Current codebase - `frontend-dapp/src/utils/tradeDirectionSideLabels.ts` returns `bidLabel: "Buy {base}"` and `askLabel: "Buy {quote}"` while `TradeOrderTicket.tsx` renders the heading as `{verb} {receive}` — on the ask side that is **"Sell {base}"**, so the bid/ask buttons and ticket title use contradictory verbs. - `LimitOrderBidAskSideSelector.tsx` and `TradeOrderTicket.tsx` consume the labels. - Slippage is named inconsistently: Settings use **"Slippage Tolerance"** (`SwapPage.tsx`), pre-sign / chain paths use **"max spread"** (`humanizeTerraTxError.ts`, `stores/dex.ts` → `maxSpreadStr`), and route metrics expose **"expected slippage"** / `routeSlippagePercent` (`swapRouteSlippage.ts`, indexer `route_slippage.rs` #293). - Transaction deadline (`deadlineSeconds: 300` in `stores/dex.ts`) is never surfaced in Swap Settings. ## Why needed CEX/DEX migrants map **Buy/Sell** to base-asset semantics. Contradictory bid/ask vs ticket copy erodes trust on the highest-traffic pro surface (`/trade`). Split slippage terminology causes users to misconfigure protection and misread chain rejections. ## Constraints / guardrails - Preserve correct **bid = buy base / ask = sell base** book semantics; do not break `limitOrderNonCrossing.ts` or post-only guards. - Keep `humanizeTerraTxError.ts` chain-log mapping accurate — retail label unification must not regress #134 / #135 error copy. - Distinguish **slippage tolerance** (user guard) from **route slippage** (#293 cross-rate metric) in tooltips, not by reusing the same label. - Mobile: base/quote price help is `hidden lg:block` in `TradeOrderTicket.tsx` — any copy fix should remain readable on small screens. ## Relevant files - `frontend-dapp/src/utils/tradeDirectionSideLabels.ts` - `frontend-dapp/src/utils/__tests__/tradeDirectionSideLabels.test.ts` - `frontend-dapp/src/components/trade/LimitOrderBidAskSideSelector.tsx` - `frontend-dapp/src/components/trade/TradeOrderTicket.tsx` - `frontend-dapp/src/pages/SwapPage.tsx` (Settings slippage block) - `frontend-dapp/src/utils/swapRouteSlippage.ts` - `frontend-dapp/src/utils/humanizeTerraTxError.ts` - `frontend-dapp/src/stores/dex.ts` - `docs/swap-max-spread-ux.md` ## Recommended direction 1. Change bid/ask labels to CEX-standard **"Buy {base}"** / **"Sell {base}"** (or short **"Buy"** / **"Sell"** with base symbol only in the ticket heading). 2. Pick one retail term for the user guard (e.g. **"Slippage protection"**) across Settings, pre-submit summaries, and humanized tx errors; footnote that on-chain the parameter is `max_spread`. 3. Add **transaction deadline** (seconds / minutes) to Swap Settings with the same presets pattern as slippage. 4. Add tooltip on route slippage line clarifying it is an execution-quality metric, not the tolerance setting. ## Acceptance criteria - [ ] Bid/ask buttons and ticket heading use consistent Buy/Sell semantics for the same side. - [ ] Unit tests cover label semantics for both sides. - [ ] Settings, pre-submit, and humanized chain errors use unified slippage-protection wording. - [ ] Tx deadline is visible and editable in Swap Settings (default 300s). - [ ] Route slippage (#293) remains labeled distinctly from tolerance. - [ ] **Screenshot:** `/trade` order ticket — bid selected, ask selected — buttons and heading agree. - [ ] **Screenshot:** Swap Settings showing slippage + deadline with unified labels. ## Test plan - `cd frontend-dapp && npm run test:unit` — extend `tradeDirectionSideLabels.test.ts`; `humanizeUserFacingError.test.ts` if error strings change. - `make lint-frontend` - Manual: `/trade` toggle bid/ask; confirm heading + buttons; place no tx required. - Manual: Swap Settings — change slippage and deadline; confirm store persistence. ## Attack / abuse test plan - N/A (copy/IA only). Verify expert-mode block threshold (#293) still applies after label changes. ## Verification criteria - No regression in `TradePage.test.tsx` bid/ask / limit tab tests. - `make test-frontend` green.
PlasticDigits commented 2026-06-25 14:13:22 +00:00 (Migrated from gitlab.com)

mentioned in issue #411

mentioned in issue #411
PlasticDigits commented 2026-06-25 20:44:13 +00:00 (Migrated from gitlab.com)

mentioned in commit dc7ec3abea

mentioned in commit dc7ec3abea7e26e04d17e085ee5db682181ba822
PlasticDigits commented 2026-06-25 20:44:38 +00:00 (Migrated from gitlab.com)

mentioned in merge request !939

mentioned in merge request !939
PlasticDigits commented 2026-06-25 21:51:31 +00:00 (Migrated from gitlab.com)

mentioned in commit 35fba18e01

mentioned in commit 35fba18e011c668090da540ea35b83334e5db7b5
PlasticDigits commented 2026-06-26 06:52:57 +00:00 (Migrated from gitlab.com)

Verification — #412 (PASS)

Verified on main @ 6ffd7f44 (implementation merged in dc7ec3ab).

Acceptance criteria

Item Result How verified
Bid/ask buttons and ticket heading use consistent Buy/Sell semantics PASS Playwright on http://127.0.0.1:5173/trade/terra17w9r…m79v6 (EMBER/COBALT): bid Buy EMBER ↔ heading Buy EMBER; ask Sell EMBER ↔ heading Sell EMBER. Screenshots: /tmp/issue-412-screenshots/trade-bid-selected.png, trade-ask-selected.png
Unit tests cover label semantics PASS tradeDirectionSideLabels.test.ts — Buy/Sell base for both sides
Settings, pre-submit, humanized errors use unified slippage-protection wording PASS slippageProtectionCopy.ts (Slippage protection); SwapPage.tsx, SwapPreSubmitSummary.tsx, humanizeTerraTxError.ts; tests in slippageProtectionCopy.test.ts, humanizeTerraTxError.test.ts, humanizeUserFacingError.test.ts
Tx deadline visible/editable in Swap Settings (default 300s) PASS stores/dex.ts deadlineSeconds: 300; Swap Settings presets + custom input; SwapPage.test.tsx retail panel test
Route slippage (#293) labeled distinctly from tolerance PASS Expected slippage + help tooltip (ROUTE_EXECUTION_SLIPPAGE_TOOLTIP) vs Slippage protection in Settings
Screenshot: /trade bid + ask PASS See screenshots above
Screenshot: Swap Settings slippage + deadline PASS /tmp/issue-412-screenshots/swap-settings-slippage-deadline.png
TradePage.test.tsx bid/ask / limit tab — no regression PASS Included in make test-frontend
make test-frontend green PASS 184 files, 1084 tests
make lint-frontend PASS 0 errors (5 pre-existing hook warnings)
cd frontend-dapp && npm run test:unit PASS 1084 tests

Manual QA notes

  • LocalTerra stack provisioned (make setup-cloud-localterra --fresh --skip-build), indexer + Vite dev server for browser checks.
  • Risk-acknowledgement modal dismissed before interaction (first-visit gate).
  • Expert-mode 30% route-slippage block unchanged (#293).

Repo changes

None — verification only; no MR opened.

## Verification — #412 (PASS) Verified on `main` @ `6ffd7f44` (implementation merged in `dc7ec3ab`). ### Acceptance criteria | Item | Result | How verified | |------|--------|--------------| | Bid/ask buttons and ticket heading use consistent Buy/Sell semantics | **PASS** | Playwright on `http://127.0.0.1:5173/trade/terra17w9r…m79v6` (EMBER/COBALT): bid **Buy EMBER** ↔ heading **Buy EMBER**; ask **Sell EMBER** ↔ heading **Sell EMBER**. Screenshots: `/tmp/issue-412-screenshots/trade-bid-selected.png`, `trade-ask-selected.png` | | Unit tests cover label semantics | **PASS** | `tradeDirectionSideLabels.test.ts` — Buy/Sell base for both sides | | Settings, pre-submit, humanized errors use unified slippage-protection wording | **PASS** | `slippageProtectionCopy.ts` (`Slippage protection`); `SwapPage.tsx`, `SwapPreSubmitSummary.tsx`, `humanizeTerraTxError.ts`; tests in `slippageProtectionCopy.test.ts`, `humanizeTerraTxError.test.ts`, `humanizeUserFacingError.test.ts` | | Tx deadline visible/editable in Swap Settings (default 300s) | **PASS** | `stores/dex.ts` `deadlineSeconds: 300`; Swap Settings presets + custom input; `SwapPage.test.tsx` retail panel test | | Route slippage (#293) labeled distinctly from tolerance | **PASS** | **Expected slippage** + help tooltip (`ROUTE_EXECUTION_SLIPPAGE_TOOLTIP`) vs **Slippage protection** in Settings | | Screenshot: `/trade` bid + ask | **PASS** | See screenshots above | | Screenshot: Swap Settings slippage + deadline | **PASS** | `/tmp/issue-412-screenshots/swap-settings-slippage-deadline.png` | | `TradePage.test.tsx` bid/ask / limit tab — no regression | **PASS** | Included in `make test-frontend` | | `make test-frontend` green | **PASS** | 184 files, 1084 tests | | `make lint-frontend` | **PASS** | 0 errors (5 pre-existing hook warnings) | | `cd frontend-dapp && npm run test:unit` | **PASS** | 1084 tests | ### Manual QA notes - LocalTerra stack provisioned (`make setup-cloud-localterra --fresh --skip-build`), indexer + Vite dev server for browser checks. - Risk-acknowledgement modal dismissed before interaction (first-visit gate). - Expert-mode 30% route-slippage block unchanged (#293). ### Repo changes None — verification only; no MR opened.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-26 06:52:59 +00:00
PlasticDigits commented 2026-08-15 12:19:48 +00:00 (Migrated from gitlab.com)

mentioned in issue #524

mentioned in issue #524
PlasticDigits commented 2026-08-15 12:19:50 +00:00 (Migrated from gitlab.com)

marked as related to #524

marked as related to #524
PlasticDigits commented 2026-08-15 21:45:47 +00:00 (Migrated from gitlab.com)

mentioned in issue #528

mentioned in issue #528
PlasticDigits commented 2026-08-15 21:45:49 +00:00 (Migrated from gitlab.com)

marked as related to #528

marked as related to #528
PlasticDigits commented 2026-08-18 12:09:31 +00:00 (Migrated from gitlab.com)

mentioned in issue #563

mentioned in issue #563
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#412
No description provided.