Integrate CL8Y Legal clickwrap (Terra Classic TermsGate) into DEX frontend #517
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#517
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
@plasticdigits/cl8y-clickwraptofrontend-dappso connected Terra Classic wallets must accept the latest CL8Y ecosystem Terms & Conditions (per property) before using transactional DEX surfaces. Signing happens on the hosted portal (terms.cl8y.com); status is checked against the Legal API (api.terms.cl8y.com).This issue bundles: SDK install + wiring, coexistence with the existing first-visit risk acknowledgement, CSP/CORS/ops allowlists, property registration, and tests (happy path + abuse vectors).
Current codebase
frontend-dapp/(@cl8y-dex/frontend), React Router, Zustand wallet store, TanStack Query. Static nginx SPA deploy.https://dex.cl8y.com(frontend),https://indexer.dex.cl8y.com(indexer). Soft-launch env templates indeployments/mainnet-soft-launch/.useWalletStoreexposesaddress(terra1…) via Keplr / Station / Cosmostation / WalletConnect (frontend-dapp/src/hooks/useWallet.ts,services/terraclassic/wallet.ts,components/wallet/WalletModal.tsx).RiskAcknowledgementModal(localStoragecl8y-dex-risk-ack, versioned inutils/riskAcknowledgement.ts), footer NFA (LegalFooterNotice), env ribbon. Mounted incomponents/common/Layout.tsx. Documented indocs/frontend.mdandskills/AGENTS_FRONTEND_RISK_DISCLAIMERS.md.@plasticdigits/cl8y-clickwraptoday; no Legal API calls; production CSPconnect-srcis narrowed (LCD/RPC/indexer/WC) and does not currently allowapi.terms.cl8y.com(viteCsp.ts).cl8y-ecosystem-legal): public API + portal; Terra Classic signs via Keplr ADR-036 oncolumbus-5; acceptance is per property (hostname). SDK: npm@plasticdigits/cl8y-clickwrap.Why this is needed
cl8y.comdoes not satisfydex.cl8y.com(property-scoped acceptances). A DEX-specific property + gate is required.Constraints / guardrails
TerraClassic/ APITERRA_CLASSIConly for this dapp (not EVM).dex.cl8y.com(match browser Origin), unless product explicitly chooses a sharedcl8y.comproperty (document the choice).https://dex.cl8y.comto Legal portalVITE_REDIRECT_URI_ALLOWLIST. PrefersanitizeRedirectUri/isAllowedRedirectUriclient-side for fail-fast UX; portal remains source of truth.https://dex.cl8y.comto Legal APICORS_ORIGINS(and localhost only for local/dev if needed).connect-srcforhttps://api.terms.cl8y.com(andhttps://terms.cl8y.comif needed). Do not widen to blankethttps:.sign_urls.terra_classic.VITE_PLAYWRIGHT_E2Eskipping the risk modal — never disable the gate silently in production builds.ADMIN_TOKENin the frontend. Public Legal endpoints only.Relevant files
DEX (
cl8y-dex-terraclassic)frontend-dapp/src/App.tsx,frontend-dapp/src/components/common/Layout.tsxfrontend-dapp/src/hooks/useWallet.ts,frontend-dapp/src/services/terraclassic/wallet.ts,frontend-dapp/src/components/wallet/*frontend-dapp/src/components/legal/*,frontend-dapp/src/utils/riskAcknowledgement.tspages/SwapPage.tsx,TradePage.tsx,PoolPage.tsx,LimitOrdersPage.tsx,WrapPage.tsx,Ust1Page.tsx,CreatePairPage.tsx, trade/limit claim hooks (useLimitExpiredClaimMutation.ts, etc.)frontend-dappVite CSP helper (viteCsp.tsor equivalent)frontend-dapp/.env.example,deployments/mainnet-soft-launch/frontend.env.example,docker/frontend/nginx.conffrontend-dappVitest legal tests,playwright.config.ts, e2e projectsdocs/frontend.md,skills/AGENTS_FRONTEND_RISK_DISCLAIMERS.md, soft-launch runbooksLegal platform (ops / cross-repo)
@plasticdigits/cl8y-clickwrap—TermsGate,useSignatureStatus,createClient,buildSignUrlhttps://api.terms.cl8y.com—/api/v1/terms/latest,/signatures/status; wallet submit on portalhttps://terms.cl8y.com/sign/terra-classic?property=dex.cl8y.comdex.cl8y.com; updateCORS_ORIGINS+ portal redirect allowlistRecommended direction
@plasticdigits/cl8y-clickwrap(+ React peers already present).createClient({ apiBaseUrl, termsBaseUrl })with production defaults; optionalVITE_LEGAL_API_BASE_URL/VITE_LEGAL_TERMS_BASE_URLfor non-prod override.dex.cl8y.com(env-overridable only if needed for local; prefer mock in e2e).ConnectedTermsGateinLayout.tsx(besideRiskAcknowledgementModal):TermsGate(network=TerraClassic,account=address,redirectUri=window.location.href,appName="CL8Y DEX").signed_latestviauseSignatureStatus. Prefer shellTermsGateunless UX requires otherwise — document choice in PR.CORS_ORIGINSincludeshttps://dex.cl8y.com; rebuild Legal web with redirect allowlist includinghttps://dex.cl8y.com.Acceptance criteria
@plasticdigits/cl8y-clickwrapinstalled and used; no forked Terra ADR-036 verify in the DEX.dex.cl8y.comregistered on Legal API; frontend uses that property consistently.signed_latestcannot complete swap / LP provide-withdraw / limit place / expired claim / wrap / create-pair (gate or submit block — as chosen above).signed_latestcan use those flows without extra friction.redirect_uri; status re-checked (focus / poll).RiskAcknowledgementModalstill works for first visit; e2e skip behavior preserved/extended.https://dex.cl8y.com.Test plan — functional paths
/,/pool,/trade— risk modal (if first visit) works; no Legal redirect; pages render./sign/terra-classic?property=dex.cl8y.com, consent + ADR-036 sign, redirect back —signed_latesttrue; swap/LP CTAs work.terra1account — status re-fetched for new account; unsigned account gated.Test plan — attack / hack / abuse vectors
redirect_urisigned_latest); assert constant/VITE_property in tests.TERRA_CLASSIC, notEVM.connect-srcas the fix.VITE_DEV_MODEsimulated wallet must not be available in production builds.getSignatureStatusfor the connected address.redirect_uriwithout allowlist helpers.Verification criteria
https://dex.cl8y.com→ unsigned → portal sign → return → one successful swap or LP action.GET https://api.terms.cl8y.com/api/v1/signatures/status?property=dex.cl8y.com&network=TERRA_CLASSIC&account=<terra1>returnssigned_latest: trueafter accept.https://dex.cl8y.com/...succeeds (allowlist OK).npm run test:run(unit) green for new gate/legal tests; Playwright smoke (and tx project if applicable) green with mock/skip strategy documented.dex.cl8y.cominCORS_ORIGINSand portal build allowlist; property exists via admin API or documented registration step.Out of scope
mentioned in commit
d671811274mentioned in merge request !1051
mentioned in commit
6e3e2b7c85mentioned in commit
7bd861fff0mentioned in commit
d44474899amentioned in issue PlasticDigits2/ustr-cmm#12
mentioned in issue #531
mentioned in issue #533
mentioned in issue #542
marked as related to #554
mentioned in issue #588
mentioned in issue #619
marked as related to #658
mentioned in issue #658
mentioned in issue #663
mentioned in issue #672
mentioned in issue #706