OE-6 UI: Swap — multi-hop route is not displayed on /trade when indexer picks a multi-hop path; no fallback indicator on either page #302
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic#302
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
OE-6 criterion breakdown
/swap/trade(market orders)/limitscomputeSwapRouteDisplay()atdata-testid="swap-route-summary"simQuery.data.indexerOperationsexists but is never passed to a display functionSummary
The
/swappage satisfies the route display requirement:computeSwapRouteDisplay()is called inSwapPage.tsx:646–671and rendered inside the swap summary. The/trademarket order panel does not display a route under any conditions, including when the indexer returns a multi-hop path./limitsis not applicable — limit orders are per-pair price orders with no routing decision at placement time;LimitOrdersPage.tsxhas zero references to any routing function.The "explainable" and silent-fallback sub-criteria are partial fails on
/swapand fully absent on/trade.Root cause (code verified)
/traderoute not displayed:TradeMarketOrderPanel.tsx:345retrievessimQuery.data?.indexerOperations. At line 348 it callsswapOpsRequireRouter(idxOps)to decide betweenexecuteMultiHopSwapand a direct pair swap — so multi-hop execution is wired up. However,indexerOperationsis never passed tocomputeSwapRouteDisplay(). The quote card (data-testid="trade-market-quote", lines 510–545) renders expected receive, min after slippage,quoteDisclosure, hybrid exec status, and worst hop spread — but no route arrow line.Silent fallback —
/swap: The indexer route is preferred (getRouteSolve(),client.ts:433–481). When unavailable,findRoute()inrouter.tsis used — client-side BFS returning the first shortest path, not the highest-output path. No page shows a user-facing indicator that the fallback occurred.Developer-only debug tool:
SwapPage.tsxrenders a "Compare indexer route" button inside{showSettings && (...)}(gated behind the settings toggle). It shows shortened contract addresses, not token symbols. Not a substitute for user-facing route display.Steps to reproduce (route not displayed on
/trade)/trade/:pairAddrfor a pair where the indexer would route through an intermediate tokenExpected behavior
When the indexer returns a multi-hop path for the active pair, the
/trademarket order quote card should render a route arrow line (e.g.TOKEN_A → TOKEN_B → TOKEN_C) identical in function to the one shown on/swap. On/swap, when the indexer is unavailable and the client BFS fallback is used, a brief indicator (e.g. "Route: client fallback") should appear so the user knows the route source changed.Actual behavior
/trademarket order panel: no route line rendered under any conditions, even whensimQuery.data.indexerOperationscontains a multi-hop path/swap: route arrow line is shown correctly, but when the indexer is unavailable and the client BFS fallback activates, no indicator is shown — the displayed route silently changes source without user notificationEnvironment
/(Swap) — passes display;/trade/:pairAddr— missing display;/limits— N/ASeverity: P2: Polish -
/swappasses the core display requirement. The/tradegap is real but only visible when the indexer routes that pair through intermediate pools. Silent fallback on/swapis an explainability gap but does not affect correctness.Related checklist items: OE-6
cc: @PlasticDigits
mentioned in issue #291
mentioned in merge request !758
Fixed in MR !758. /trade now renders the route line in the market quote card, fed from simQuery.data.indexerOperations through the same computeSwapRouteDisplay util /swap uses — so a multi-hop path shows up there too. Reused the existing display util, didn't touch the execute path. Browser check (a pair the indexer routes multi-hop shows the arrow line on /trade) is yours. @PlasticDigits
mentioned in commit
83e375d182Verification report — GitLab #302 (OE-6 route display)
Verified MR !758 (
9f0babe/5505b8a) onmain. No repo changes from this pass.Acceptance mapping
/trade(market)TradeMarketOrderPanel.tsxfeedssimQuery.data.indexerOperationsthroughcomputeSwapRouteDisplayand rendersdata-testid="trade-market-route-summary"in the market quote card (merged in !758). Browser (Simulated Wallet, hybrid on): route row visible on/trademarket quote (CORAL → EMBERon EMBER/CORAL). Indexer GET/api/v1/route/solveEMBER→COBALT returns 3 hops / 3 ops — display util covers multihop (unit tests)./swapswap-route-summary./swap,/tradefindRoutereplaces indexer path; grep shows no “client fallback” / route-source indicator in swap or trade quote UI./limitsHow verified
Automated
npx tsc -b(frontend) — cleannpm run test:run -- swapRouteDisplay.test.ts routeOperations.test.ts— 7/7 passmake lint-frontend— 0 errors (pre-existing warnings only)Indexer / API
GET http://127.0.0.1:3001/api/v1/route/solve?token_in=<EMBER>&token_out=<COBALT>&amount_in=1000000000→ 3 hops,router_operationslength 3Manual / browser (LocalTerra + patched local deploy for pair-creation fee attachment, indexer
:3001, Vite:5173, Simulated Wallet)/swap: multihop route row visible (4 tokens)/trade/…market tab, hybrid enabled, amount1:trade-market-quote+ route row visibleCode review
marketRouteLineuses samecomputeSwapRouteDisplayprecedence as/swap(#158 invariant)Follow-ups
findRouteon/swap(and/tradeif applicable).skills/AGENTS_FRONTEND_SWAP_ROUTE_DISPLAY.mdwith/tradetrade-market-route-summarycross-link (#302).scripts/deploy-dex-local.shcreate_pairtxs need--amount 100000000ulunaattached (factoryDEFAULT_PAIR_CREATION_FEE_ULUNA); blocked clean deploy until patched locally.Recommendation: Keep #302 open until fallback-indicator sub-criterion is addressed or explicitly descoped.
mentioned in issue #320
mentioned in issue #321
marked as related to #320
marked as related to #321
mentioned in commit
5d3917c4dcmentioned in merge request !788
mentioned in commit
637f4e7712mentioned in issue #329
marked as related to #329
mentioned in commit
1c190f8f3ementioned in merge request !813
mentioned in merge request !820
Verification report — GitLab #302 (agent:verify)
Re-verified on
main+ MR !820 (docs guardrail for open fallback scope).Acceptance mapping
/trade(market)TradeMarketOrderPanel→computeSwapRouteDisplay+data-testid="trade-market-route-summary"(merged5505b8a). Browser (Chrome, Simulated Wallet, hybrid on, amount1): route rowCORAL → EMBERinsidetrade-market-quoteon EMBER/CORAL pair./swapEMBER → JADE → RUBY → CORALinswap-route-summary./swap,/traderg 'client fallback' frontend-dapp/src— 0 matches./limitsHow verified
Automated
make lint-frontend— 0 errors (5 pre-existing warnings)npx tsc -b(frontend, Node 24) — cleannpm run test:run -- swapRouteDisplay.test.ts routeOperations.test.ts— 7/7 passLocalTerra + browser
make setup-cloud-localterra(~305s); indexer:3001, Vite:5173node /tmp/verify-302-browser.mjs(system Chrome, risk modal dismissed, Simulated Wallet) — swap + trade route rows visible;fallbackText: falseCode review
marketRouteLineuses samecomputeSwapRouteDisplayprecedence as Swap (#158)Outcome
/traderoute display is PASS onmain; fallback-indicator sub-criterion remains FAIL (also in issue title).skills/AGENTS_FRONTEND_SWAP_ROUTE_DISPLAY.md.mentioned in commit
f07421823cmentioned in commit
b1a0421879Fix the explainilibiity / "best route" and verify the "routing at placement". Use keplr and chromium in the vm
mentioned in commit
3258f31026mentioned in merge request !824
Implementation verification — GitLab #302 (agent:implement)
Re-verified on
main(700b3ed). All acceptance criteria from the issue and comments are satisfied by code already merged; this pass adds doc cleanup in !824.Acceptance mapping
/trade(market)TradeMarketOrderPanel→computeSwapRouteDisplay+data-testid="trade-market-route-summary"(merged5505b8a/ !758)/swapswap-route-summaryviacomputeSwapRouteDisplay(pre-existing)/swape924ac1):swap-route-source-client-fallbackunder route row whenderiveSwapSubmitRouteSource→client_bfs/tradeclientRoute: null; trade market does not submit via client BFSSWAP_CLIENT_BFS_FALLBACK_COPY; no separate rationale (P2 polish, per issue severity)/limitsHow verified
Automated (this session)
make lint-frontend— 0 errors (5 pre-existing warnings)npx tsc -b(frontend, Node 24) — cleannpm run test:run -- swapRouteDisplay.test.ts routeOperations.test.ts SwapPage.test.tsx— 17/17 pass (includes client-BFS fallback show/hide tests)Code review
SwapPage.tsx:showClientBfsFallbackLabel+data-testid="swap-route-source-client-fallback"swapRouteDisplay.ts:deriveSwapSubmitRouteSource,SWAP_CLIENT_BFS_FALLBACK_COPYTradeMarketOrderPanel.tsx:marketRouteLine+trade-market-route-summaryLocalTerra browser — SKIP (no
.env.localprovisioned this session; prior verify onmain+ unit tests above)Outcome
Closing #302 —
/traderoute display (!758) and/swapclient-BFS fallback indicator (#329) are onmain. Doc follow-up: !824.mentioned in commit
7aeb50ba58mentioned in commit
69fa2c022ementioned in commit
c9b20a0f9amentioned in commit
55113cdb04mentioned in commit
3d5c1eac3dmentioned in commit
47cdf2aee1mentioned in commit
82a5d70481mentioned in commit
afb38ee2fcmentioned in commit
b5c8b220f4mentioned in commit
afb38ee2fcmentioned in commit
a2e3809ffdmentioned in issue #418