Footer: official CL8Y product links (homepage + Bridge) #663
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#663
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
Add a compact official CL8Y product row to the dApp shell footer: CL8Y homepage (
https://cl8y.com/) and CL8Y Bridge (https://bridge.cl8y.com/). Traders who arrive ondex.cl8y.comhave no in-app way to reach sibling products today.This is one product change: homepage + Bridge share the same chrome, allowlist, and outbound-link rules. Do not split them. Do not implement bridge, GameFi, or cross-chain logic in this repo.
Current codebase
The global shell footer is only network risk + legal. It does not link any other CL8Y property.
Shell footer (
Layout)frontend-dapp/src/components/common/Layout.tsxrenders onefooter.app-footer-shellon every route:EnvironmentRibbon— chain / env strip (local/testnet/mainnet). Desktop/tablet omit headerNetworkBadge(#483); this strip carries network context.CL8Y DEX · Terra Classic(plain<p>, not a link).LegalFooterNotice— only afterRouteContentReadyProviderreports the lazy page mounted (#179 LCP; #138 NFA-after-nav). Failsafe:ROUTE_CONTENT_READY_FAILSAFE_MS.ConnectedTermsGate(#517) wraps<Outlet>only. Header and footer stay mounted so an unsigned wallet can disconnect. There is no product-link component.Legal notice links (keep)
LegalFooterNoticeis one paragraph:NFA_SHORTdocs/security-posture.mdSECURITY_POSTURE_DOC_URL, new tab (#387)docs/user-incident-faq.md/pool#lp-howtotarget=_blank(#531)Regression:
LegalFooterNotice.test.tsx.Header / More are in-app only
navItems.tsis DEX routes (Swap,Pool,Trade, More → Protocol / Tiers / Create Pair / Wrap / UST1 / Create Token / …). External origins must not be added to header More.Header brand is logo + CL8Y DEX only. E2E forbids a “Terra Classic ecosystem” kicker (#136,
e2e/navigation.spec.ts).CSP / clickwrap (relevant, not blocking)
viteCsp.tsproduction CSP:form-action 'self',frame-ancestors 'none',connect-srcis an allowlist (LCD, indexer, WalletConnect,api.terms.cl8y.com,terms.cl8y.com). A normal<a href="https://…">navigation does not needconnect-src. Do not add blankethttps:toconnect-src. Do not iframebridge.cl8y.com.Legal property stays
dex.cl8y.com. Clickwrap is not required to leave the DEX.Official destinations (live)
https://cl8y.com/https://bridge.cl8y.com/This DEX is already
https://dex.cl8y.com— do not self-link.terms.cl8y.comis Legal, not a product tile.Why this is needed
Users treat
dex.cl8y.comas the CL8Y product they already trust. Sibling surfaces (homepage, Bridge) exist and are official, but the shell gives zero outbound path. People looking for wrap-across-chains or the rest of the ecosystem bounce or follow unofficial links.The footer is the correct place: it is persistent, not a Swap lecture banner (#489 invariant 9), and does not crowd the sticky header (#136, #483).
Constraints / guardrails
https://cl8y.com/andhttps://bridge.cl8y.com/. Rejecthttp:,//,javascript:,data:, query/hash rewrite, user/pass in URL, and lookalikes (cl8y.com.evil, homoglyphs). NoVITE_*URL override on production (Coolify build-arg injection).rel="noopener noreferrer". Prevents tabnabbing (window.opener) and referrer leakage of DEX paths.LegalFooterNotice. Do not splice “Bridge” into the NFA / Security / Report sentence. Legal links stay first-class; product links must not look like incident/security chrome.window.openuser-controlled URLs. Noconnect-srcexpansion. Noform-actionto those origins.padding-bottom: calc(var(--app-mobile-nav-stack) + 16px)). Links wrap; no overlap with Swap/Trade/Pool/Limits/More. No nestedcard-glass/shell-panelinside the footer (#653).Relevant files
frontend-dapp/src/components/common/Layout.tsxfrontend-dapp/src/components/legal/LegalFooterNotice.tsxfrontend-dapp/src/components/legal/EnvironmentRibbon.tsxfrontend-dapp/src/components/legal/legalCopy.tsfrontend-dapp/src/index.css.app-footer*,.app-legal-footer*, mobile clearancefrontend-dapp/src/components/common/navItems.tsfrontend-dapp/viteCsp.tsconnect-src/form-actionfrontend-dapp/src/utils/legalClickwrap.tsdex.cl8y.comfrontend-dapp/src/components/legal/__tests__/LegalFooterNotice.test.tsxfrontend-dapp/e2e/navigation.spec.tsdocs/frontend.md§ Risk surfacing / responsive shellskills/AGENTS_FRONTEND_RISK_DISCLAIMERS.mdskills/AGENTS_FRONTEND_RESPONSIVE_HEADER.mdskills/AGENTS_FRONTEND_COPY_COGNITIVE_LOAD.mddocs/security-posture.mdNew (recommended):
frontend-dapp/src/utils/cl8yProductLinks.ts(allowlist + types) +Cl8yProductLinks(or similar) + Vitest +make verify-issue-<iid>.Recommended direction
CL8Y_PRODUCT_LINKSasas const{ id, label, href }[]with only the two HTTPS origins above. Export aisAllowedCl8yProductHref(href)helper used by tests (and optionally by the renderer as a belt-and-suspenders check that returnsnullon mismatch).nav(e.g.aria-label="CL8Y products") inside.app-footer-copy, below the title and beside or aboveLegalFooterNotice— not inside the NFA<p>. Use existing footer link styles (underline,--ink-subtle); no new gold marketing card.target="_blank",rel="noopener noreferrer", stabledata-testid(footer-product-home,footer-product-bridge).docs/frontend.md(footer subsection) and a short playbook note (risk-disclaimers or a tinyAGENTS_FRONTEND_PRODUCT_LINKS.md) so agents do not dump these URLs into header More or Swap copy.make verify-issue-<iid>(Vitest + Playwright navigation slice). Keep 5 Playwright workers for smoke.Acceptance criteria
https://cl8y.com/and Bridge →https://bridge.cl8y.com/(exact origin + HTTPS, trailing slash optional but host/protocol exact).relcontainingnoopenerandnoreferrer.LegalFooterNoticestill shows NFA + Security + Incidents + LP how-to + Report with existing testids and destinations.window.openof non-allowlisted URLs, noVITE_*product URL, no CSPconnect-src/form-actionchange.make verify-issue-<iid>(or documented equivalent) is green.Test plan (all paths)
Unit / RTL
http://cl8y.com,https://cl8y.com.evil,https://evil.com/?u=https://cl8y.com,javascript:alert(1),data:text/html,…,//bridge.cl8y.com,https://user:pass@cl8y.com,https://bridge.cl8y.com.attacker, homoglyph host, empty, relative/bridge.LegalFooterNoticesuite still passes unchanged.nav+ legal notice after ready.Playwright (
e2e/navigation.spec.tsor sibling smoke)footer.app-footer-shell.target=_blank+relassertions (do not depend on a live third-party tab if CI is offline — assert attributes)..app-mobile-nav-shell.Manual / live (not a merge blocker if CI is offline)
https://dex.cl8y.com(or local Vite); destinations load the real properties.Docs
docs/frontend.mdfooter table lists the two products.navItems.ts.Test plan (attack, hack, abuse)
searchParams, hash, or indexer field. Helper rejects any non-allowlisted string.cl8y.com.evil,xn--punycode,cI8y.comfail the helper and never render.javascript:,data:,vbscript:,http:, protocol-relative//never becomehref.relincludesnoopener(andnoreferrer). Nowindow.open(url)without the same features.noreferrersodex.cl8y.com/trade/<pair>is not sent to the sibling origin.import.meta.env.VITE_CL8Y_*_URLfor these hrefs. A poisoned build-arg must not retarget the footer.https:toconnect-srcor changeform-action/frame-ancestors. Linking is navigation, not fetch.frame-ancestors 'none'.https://dex.cl8y.comproduct tile (user is already here).window.openeraccess to the DEX (noopener). Footer must not auto-navigate the current tab away mid-sign.Verification criteria
Issue is done when:
LegalFooterNoticetests) pass viascripts/with-node.sh.make verify-issue-<iid>(or the commands listed in the MR) is the documented regression path.docs/frontend.md+ skill updated;navItems.ts/ CSP unchanged except unrelated drive-bys (there should be none).Out of scope: implementing the Bridge, PROTOCASS/GameFi, social icons, whitepaper PDF in the footer, indexer/CORS changes, clickwrap property changes.
Owner / priority
mentioned in commit
28e505b56bmentioned in merge request !1154
mentioned in merge request !1156
mentioned in commit
98b2da570fmentioned in commit
dc869a7fe8mentioned in commit
723c426856Merged to
mainvia !1156. Catalog conflicts with later MRs were unioned (keep footer Homepage + Bridge).Leftover: live footer still shows Homepage and Bridge after Coolify frontend rebuild. Optional Playwright
e2e/footer-product-links-663.spec.tswhen LocalTerra is up.mentioned in issue #673