feat: /pool sortable table, UST1-first volume default, charts links, strip lectures #547
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#547
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?
Summary
Rebuild
/poolas a sortable table of pools (not a stack of cards), defaulting to UST1 markets first then 24h volume, with a Charts link on every row. Strip the page-chrome lectures (title, indexer/factory essays, pair-count trivia). Remove the unused Router-known filter. Make the How to add liquidity block fully dismissible.Bundle these into one frontend issue. Do not split “table vs cards” vs “UST1 first” vs “sort carets” vs “charts links” vs “delete header copy” vs “dismiss how-to” vs “drop Router-known.”
Related: #489 (anti-cognitive-overload), #531 (opt-in LP how-to), #533 (one-sided add/withdraw), #534 (catalog rank — explicitly skipped
/poollists today), #112 (indexer vs factory list + Router-known filter), #541 (token identity / explorer), #476 / #537 (pair fee-tier chrome), #215 (indexer outage banner).Current codebase
/poolis a human-facing page that currently reads like an indexer runbook.PoolPage.tsxloadsGET /api/v1/pairs(getPairs) withlimit=20, defaultsort=symbolorder=asc. Each row is aPoolCard: symbols, 24h vol, In router (factory) / Indexer only badges,PairTokenLinks, on-chain reserves, fee badge, Advanced two-sided provide/withdraw.MenuSelect(symbol/volume_24h/fee/created/id) and OrderMenuSelect(asc/desc). Choosing volume forcesorder=desc. Carets are not on column headers (there are no columns).sortIndexerPairsByCatalog(UST1 hub first, gems last, human 24h volume) is used on Trade/Limits/Charts pickers. Playbook explicitly says do not reorder/poolcard lists the user sorted by fee/created/id. Default pool list is A–Z symbol, so faucet gems and UST1 markets are interleaved by ticker.ChartsPage.tsxkeepsselectedPairAddrin React state only.App.tsxhas/chartswith no:pairAddr./trade/:pairAddralready deep-links Trade (which also embeds a chart). Pool cards have no Charts (or Trade) link.factoryPairAddresses(#112). Product: unused. Tests inPoolPage.test.tsxassert it.h2, “Browse pairs, compare fees…”, CL8Y eligibility note (pool-fee-discount-eligibility-note) +/tiers, List source: indexer vs factory paragraph + GitLabfrontend.mdlink, indexer-vs-factory drift note, right-rail N pair(s) (indexer total) / indexed tokens / on-chain (factory, router graph). This is agent/ops copy (#489 invariant 9).PoolLpHowto.tsx: first-visit hint is dismissible (cl8y-dex-pool-lp-howto-hint-dismissed). The<details>“How to add liquidity” stays on the page forever. Footer / Portfolio still link/pool#lp-howto.OneSidedAddCard+OneSidedWithdrawCardsit above the list (#533). Keep them.pool-market-data-outage-banner), fee-discount registry warning, pause/blacklist on provide, IL on Advanced provide. Pair-level fee CTA when unwired/unregistered (I14 / #537).formatQuoteVolume24h(quote decimals) — P534-4. Do not regress toformatNum(raw).Why this is needed
/poolwas carved out; that carve-out is wrong for first paint./chartscannot be opened on a specific pool. Users who see a pool cannot jump to its tape.docs/frontend.md§ Liquidity pools list.<details>summary is always-on. Users asked for a dismiss on the how-to block itself;#lp-howtoand footer must still be able to restore it.Constraints / guardrails
<details>on/pooleither. Engineering docs stay in GitLab.getAllPairsPaginated).GET /api/v1/pairshas nosort=catalog. Re-sorting only the current 20 is not “UST1 first” globally. Default view must make page 1 UST1-hub economic pairs (then volume), gems last — fetch a large enough window and/or client-paginate catalog order. Typed search stays indexerrelevance/q(P534-6). User-chosen column sorts (volume, fee, created, name, id) use indexersort/orderand must not secretly re-apply catalog overlay (update the #534 playbook sentence that forbade/poolreorder — default catalog is in scope; user column sort is not overridden).formatQuoteVolume24h+ quote decimals. Do not sort 18-dec raw against 6-dec raw in the catalog default (P534-3)./charts/:pairAddrand/or?pair=) using the same Terra address rules astradePairRoute.ts. Invalid /javascript:/ HTML → no navigation (same spirit as T541-2).Linkonly; nowindow.opento untrusted hosts.<details>. Persist (extendpoolLpHowto.tsor a second key). Hash#lp-howtore-opens. Footer / Portfolio links still work. Copy stays inpoolLpHowtoCopy.ts; noinnerHTML; no APR. Update H531-7 (today: hint dismissible, details stay).pool-fee-discount-eligibility-notefrom the header. Row-level unregistered CTA / fee badge stays (I12/I14).role="table"(or native<table>),aria-sorton the active column, keyboard-activatable headers, caret is not the only sort indicator. Light + dark. Do not cover one-sided CTAs with how-to (position: relativeonly).TradesTable, portfolio tables). Mobile: horizontal scroll is OK; do not go back to stacked cards as the only layout without a documented exception.Relevant files
frontend-dapp/src/pages/PoolPage.tsxPoolCardlistfrontend-dapp/src/pages/PoolPage.test.tsxfrontend-dapp/src/pages/ChartsPage.tsxfrontend-dapp/src/App.tsx/chartsroutefrontend-dapp/src/utils/tradePairRoute.tsfrontend-dapp/src/utils/pairCatalogRank.tsfrontend-dapp/src/utils/pairListBadges.tsfrontend-dapp/src/utils/formatAmount.tsformatQuoteVolume24hfrontend-dapp/src/components/pool/PoolLpHowto.tsxfrontend-dapp/src/utils/poolLpHowto.tsfrontend-dapp/src/components/pool/OneSidedAddCard.tsx/OneSidedWithdrawCard.tsxfrontend-dapp/src/components/ui/PairTokenLinks.tsxdocs/frontend.md§ Liquidity pools list / pair catalog rank / retail copyskills/AGENTS_FRONTEND_COPY_COGNITIVE_LOAD.mdskills/AGENTS_FRONTEND_PAIR_CATALOG_RANK.md/poolexceptionskills/AGENTS_FRONTEND_POOL_LP_HOWTO.mdindexer/src/api/pairs.rssort=id|fee|created|symbol|volume_24h|relevanceRecommended direction
PoolPage: noh2“Liquidity Pools”, no browse subtitle, no list-source paragraph, no drift note, no indexer/factory/token counts, no header eligibility note. Search stays. Outage + registry warning stay.#lp-howtosection (hint + details). Persist.#lp-howtosets visible + opens<details>. Optional quiet “How to” text button if dismissed (not a paragraph).routerKnownOnlystate. Drop empty-state copy that only exists for that filter.PoolCardstack with a<table>(e.g.PoolPairsTable):getPool; do not N+1 LCD on every row for default paint; show vol/fee from indexer; lazy-load reserves on expand or omit from default columns), Charts link, optional compact factory/indexer mark.PairTokenLinks/ identity (T541-*); do not wrap the pair name in an explorer<a>.sortIndexerPairsByCatalog) so UST1 pairs first, then other economic hubs, human 24h volume within group, test pairs last. Implementation options (pick one, document infrontend.md):limitwell above 20) ofsort=volume_24h&order=desc, client catalog-sort, client-paginate; orsort=catalogonly if this issue also ships indexer work (optional; do not block the table on a new API if a client window is enough for current pair count).Linkto/charts/:pairAddr(mirror Trade). Charts page reads the param, validates bech32, selects that pair (fetchgetPairif not on the current menu page — Charts already hasneedsPairFetch). Unknown/invalid: stay on/chartswithout executing scripts; no wallet prompt.PoolPage.test.tsxassertions that require “List source” / pair counts / Router-known. Update #112 section infrontend.md(filter gone; badges optional). Update #534 playbook.make verify-issue-<iid>.Acceptance criteria
/poolpair list is a table with sortable headers. No stackedPoolCardas the primary list.symbolA–Z.volume_24h); formatted withformatQuoteVolume24h.#lp-howtorestores it. Footer/Portfolio still land on the how-to.make verify-issue-<iid>+ RTL + Playwright smoke (5 workers).Test plan (all paths)
IA / copy
/poolfirst visitLiquidity Poolsheading; no “List source”; no “indexed tokens”; no “factory, router graph”; no drift note; nopool-fee-discount-eligibility-noteq; empty → catalog default/pool#lp-howtopool-filter-routerSort / table
getPairscalled withsort=volume_24h; caret on Vol; gems may interleave by volume (catalog overlay off)orderasc↔desc; caret flipssort=symbol(or documented name key); caret moves; Vol caret inactiveTcompact junk (P534-4)button(orth+button); Enter/Space sorts;aria-sortCharts
Linkhref/charts/<pairAddr>(or documented query)/charts/not-a-terraor/charts/<script>→ no XSS; fallback empty/default pair; nojavascript:Provide / identity (regression)
PairTokenLinksgetExplorerAddressUrlonlypool-market-data-outage-banner; noVITE_INDEXER_URLleak (#215)Unit / RTL
PoolPage.test.tsx: default catalog order with mocked UST1 + gem pairs; no list-source strings; no Router-known; table role; header sort callsgetPairswith expectedsort/order.PoolLpHowto.test.tsx: dismiss hides details; hash reopens; storage key documented.pairCatalogRankstill covers UST1 vs gems (may add a pool-list helper test).Playwright (5 workers, smoke; tx not required unless provide expand is asserted on-chain)
/pooldesktopsort=volume_24h; caret updates/charts/…; pair selected#lp-howtoManual QA
/poolshould look like a tool (search + add + table), not a protocol README.Test plan — attack, hack, and abuse vectors
href.javascript:,data:, HTML, non-bech32 → no navigation / nodangerouslySetInnerHTML.Linkis same-origin path only; nohttps://evilfrom indexerwebsite/logo_url(T541-7).IndexerPairSortkeys; ignore crafted query strings if you add URL state.'1'/'0'; do notJSON.parseuntrusted localStorage into React nodes.position:fixedover wallet/clickwrap/provide (H531 in-flow).getPool/getPairFeeConfigfor every row on a large page (cards do this today — fix in the table design: indexer fields first; LCD on expand).FACTORY_PAIRS_MAX_FOR_POOL_LIST); missing factory membership ≠ “safe to hide.” Do not filter the list by factory by default (that was Router-known).getPairsstill retail banner; no host:port / env names.Verification criteria
make verify-issue-<iid>fails if: “List source”, “Router-known”,pool-fee-discount-eligibility-note, orh2Liquidity Pools still exist onPoolPage.tsx; how-to details remain undismissable;PoolCardis still the list; Charts route cannot take a pair address.Linkhref.docs/frontend.md+ skills (#489, #531 H531-7, #534/poolexception removed, #112 filter removed) match the UI.make test-frontendscoped Pool/Charts/how-to/catalog; no regression on #533 / #537 / #541 tests.Out of scope
volume_quote_24h(still raw)./chartscanvas or #524/#543 invert math.AddressRowclones on/pool.marked as related to #489
marked as related to #531
marked as related to #534
marked as related to #112
marked as related to #541
marked as related to #533
mentioned in commit
f9f0387af0mentioned in merge request !1077
mentioned in commit
7524010089Merged as !1077 onto
main(75240100) after resolving conflicts with !1076 (#548): Makefile keeps bothverify-issue-547andverify-issue-548;ChartsPagekeeps USD overview strip and/charts/:pairAddrdeep links.Remaining / post-merge:
—(documented P547-4): indexer list JSON has no timestamp; header sort still uses indexercreated.getPoolbefore Manage” assertion.valid :pairAddr) logs React Queryundefinedforindexer-pair-one(test passes)./poollayout, UST1-hub first, gems last, shareable Charts URL, light+dark carets) is still open.Tracking: new post-merge issue for remaining manual QA.
mentioned in issue #550
mentioned in issue #552
marked as related to #552
mentioned in issue #562
marked as related to #562
mentioned in issue #655
marked as related to #655
mentioned in issue #660
marked as related to #660
mentioned in issue #661
mentioned in issue #662
marked as related to #662
mentioned in issue #666
mentioned in issue #680
mentioned in issue #692
marked as related to #692