Frontend: fee-discount registry outage warning for traders #374
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#374
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?
Parent
Follow-up from GitLab #365 — approved verification follow-up 2: non-blocking frontend banner when a registered trader may be charged full fee because the registry LCD is unreachable.
Parent gap: GitLab #361 register item M2.
Current codebase
!registrationQuery.data?.registered(frontend-dapp/src/pages/SwapPage.tsx) — conflates “not registered” with “registered but discount unreadable”.frontend-dapp/src/services/terraclassic/feeDiscount.ts(getRegistration,getDiscount).getFeeDiscountHealth()→GET /api/v1/health/fee-discount(frontend-dapp/src/services/indexer/client.ts).main:frontend-dapp/src/utils/feeDiscountRegistryWarning.ts(resolveFeeDiscountRegistryStatus,shouldShowFeeDiscountRegistryWarning,FEE_DISCOUNT_REGISTRY_WARNING_TEXT). Swap page wires registration/discount query errors + indexer health into an amber non-blocking banner. Unit tests:frontend-dapp/src/utils/__tests__/feeDiscountRegistryWarning.test.ts. SwapPage mocksgetFeeDiscountHealthin tests.TradeMarketOrderPanel.tsx,TradePage.tsx) does not yet surface the registry-outage warning — scope here is Swap (primary retail fee-discount UX); extend to Trade only if market quotes use the same registration/discount path.Why needed
Registered tier holders can be charged full pair fee when the registry contract is paused or LCD queries fail, with no UI signal today. Traders may assume their discount still applies because registration UI previously showed them as registered (indexer tier sync or stale LCD success).
Constraints / guardrails
unregisteredvsregistry_unreachablevsregisteredwhere data allows; do not show the outage banner for genuinely unregistered wallets.statusoralertas appropriate; amber/warning styling consistent with swap indexer-outage banners).Relevant files
frontend-dapp/src/utils/feeDiscountRegistryWarning.tsfrontend-dapp/src/pages/SwapPage.tsxfrontend-dapp/src/services/terraclassic/feeDiscount.tsfrontend-dapp/src/services/indexer/client.ts(getFeeDiscountHealth)frontend-dapp/src/utils/__tests__/feeDiscountRegistryWarning.test.tsfrontend-dapp/src/pages/SwapPage.test.tsx(add regression for banner visibility)skills/AGENTS_FEE_DISCOUNT_TIERS.md§ Registry outage observabilityRecommended direction
showFeeDiscountRegistryWarningviashouldShowFeeDiscountRegistryWarning:registry_unreachablewhenregistrationQuery.isError || discountQuery.isError, or indexer healthconfigured && fee_discount_registry_ok === false.!registration?.registeredand LCD queries succeeded (show existing “Hold CL8Y…” path instead).FEE_DISCOUNT_REGISTRY_WARNING_TEXT(“Fee discount unavailable; full pair fee may apply until the registry is reachable again.”).staleTime(e.g. 30s) whenFEE_DISCOUNT_CONTRACT_ADDRESSis configured.Acceptance criteria
get_registrationorget_discountLCD query sees non-blocking outage warning on Swap.fee_discount_registry_ok: falsesees the same warning even if local LCD queries have not yet errored.resolveFeeDiscountRegistryStatusmatrix and SwapPage banner visibility.Test plan
make test-frontend—feeDiscountRegistryWarning.test.ts,SwapPage.test.tsxregistry-outage casesfee_discount_registry_ok: false) with successful LCD registration read → warning still shownAttack / abuse test plan
Verification criteria
registrationQuery.isError→ banner visible; swap button enabled.fee_discount_registry_ok: falsefrom indexer → banner visible without per-trader error details in UI.mentioned in issue #365
mentioned in merge request !892
mentioned in commit
16f31c3d35mentioned in merge request !893
mentioned in commit
8160805ff8Checked the source + unit layer on my side on main
edbe288.The logic and wiring look right:
What's not covered yet, so I'm not closing from my side:
So: implementation and util tests good; needs the page-level banner test plus the browser confirm before I'd sign it off. @PlasticDigits
mentioned in commit
d7dcfe81e7mentioned in merge request !896
Filled the gap I flagged — the missing SwapPage banner-visibility test (AC5).
Branch qa/374-swappage-registry-banner-test (commit
d7dcfe8), MR !896. New file SwapPage.feeDiscountRegistryBanner.test.tsx, 4 page-level cases:The fee-discount queries gate on FEE_DISCOUNT_CONTRACT_ADDRESS, which is empty in the test env, so the file mocks @/utils/constants truthy — scoped to this file, the existing SwapPage.test.tsx 13 tests are unaffected (verified green). Test-only, tsc -b clean.
Needs your review/merge. After that the only thing left on #374 is the browser walkthrough (banner actually rendering on Swap, a11y role, unregistered staying on the CTA), which I'll pick up on the frontend pass. @PlasticDigits
mentioned in commit
44d73ee47cmentioned in commit
d013b611abmentioned in commit
a17df69fcbmentioned in commit
17453e7a49mentioned in merge request !899
mentioned in commit
3ece932132Verification — GitLab #374 (PASS)
Verified on
main@78e3222with LocalTerra (make setup-cloud-localterra --fresh --skip-build), indexer tmuxindexer-dev, andmake dev(http://127.0.0.1:5173).Acceptance criteria
get_registration/get_discountLCD → non-blocking amber warning on SwapfeeDiscountRegistryWarning.test.ts;SwapPage.feeDiscountRegistryBanner.test.tsx;SwapPage.test.tsx§ registry outage; browser (Playwright/Chromium): block fee-discount LCD smart queries →[data-testid="swap-fee-discount-registry-warning"]visiblefee_discount_registry_ok: false→ same warningFEE_DISCOUNT_ADDRESSat invalid contract →GET /api/v1/health/fee-discountreturnedok:falsewhile LCDget_registrationstill succeeded → banner rendered without mockSwapPage.test.tsx+SwapPage.feeDiscountRegistryBanner.test.tsx; browser after on-chainderegister+ quoted swap (Hold CL8Y…visible, no outage banner)SwapPage.feeDiscountRegistryBanner.test.tsx(indexerok:falsecase asserts Swap enabled);SwapPage.test.tsxregistry-outage casesresolveFeeDiscountRegistryStatusmatrix + SwapPage banner visibilitySwapPage.test.tsxcases (30/30 targeted vitest green)Automated commands (all green)
Manual / browser (LocalTerra)
VITE_DEV_MNEMONIC), risk-ack dismissed, Swap page.fee_discount_registry_ok: false): amber banner,role="status",alert-warning, stable copy — no raw LCD errors or addresses in UI.FEE_DISCOUNT_ADDRESSinindexer/.env, restarted indexer — banner appeared with real health endpoint (restored env after).Attack / abuse checks
FEE_DISCOUNT_REGISTRY_WARNING_TEXT); util test + browser assert noterra1…/error/ stack traces in banner text. PASSNotes
make verify-issue-365); this issue’s frontend observability scope is satisfied.Closing as verified.
mentioned in issue #476