Integrate CL8Y Legal clickwrap (Terra Classic TermsGate) into DEX frontend #517

Closed
opened 2026-08-11 02:12:12 +00:00 by PlasticDigits · 17 comments
PlasticDigits commented 2026-08-11 02:12:12 +00:00 (Migrated from gitlab.com)

Summary

Add @plasticdigits/cl8y-clickwrap to frontend-dapp so 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

  • Stack: Vite + React 19 SPA under frontend-dapp/ (@cl8y-dex/frontend), React Router, Zustand wallet store, TanStack Query. Static nginx SPA deploy.
  • Prod hosts: https://dex.cl8y.com (frontend), https://indexer.dex.cl8y.com (indexer). Soft-launch env templates in deployments/mainnet-soft-launch/.
  • Wallet: useWalletStore exposes address (terra1…) via Keplr / Station / Cosmostation / WalletConnect (frontend-dapp/src/hooks/useWallet.ts, services/terraclassic/wallet.ts, components/wallet/WalletModal.tsx).
  • Existing legal UX (not clickwrap): first-visit RiskAcknowledgementModal (localStorage cl8y-dex-risk-ack, versioned in utils/riskAcknowledgement.ts), footer NFA (LegalFooterNotice), env ribbon. Mounted in components/common/Layout.tsx. Documented in docs/frontend.md and skills/AGENTS_FRONTEND_RISK_DISCLAIMERS.md.
  • No dependency on @plasticdigits/cl8y-clickwrap today; no Legal API calls; production CSP connect-src is narrowed (LCD/RPC/indexer/WC) and does not currently allow api.terms.cl8y.com (viteCsp.ts).
  • Legal platform (separate repo cl8y-ecosystem-legal): public API + portal; Terra Classic signs via Keplr ADR-036 on columbus-5; acceptance is per property (hostname). SDK: npm @plasticdigits/cl8y-clickwrap.

Why this is needed

  • Soft-launch DEX users interact with experimental AMM / LP / limit / wrap flows; ecosystem T&Cs must be wallet-bound and versioned, not only a localStorage NFA modal.
  • Signing once on cl8y.com does not satisfy dex.cl8y.com (property-scoped acceptances). A DEX-specific property + gate is required.
  • Portal + API already implement disclosure, consent checkbox, Content-SHA256 message binding, and Terra Classic verify. Reimplementing signing in the DEX would diverge and create security debt.
  • Without clickwrap, unsigned accounts can still submit swaps / LP / claims after connect.

Constraints / guardrails

  1. Do not replace the anonymous first-visit risk acknowledgement with clickwrap; sequence them (browse → risk ack → connect → terms gate for txs / connected shell).
  2. Network: SDK TerraClassic / API TERRA_CLASSIC only for this dapp (not EVM).
  3. Property: register and use dex.cl8y.com (match browser Origin), unless product explicitly chooses a shared cl8y.com property (document the choice).
  4. Redirects: portal only auto-navigates allowlisted origins — add https://dex.cl8y.com to Legal portal VITE_REDIRECT_URI_ALLOWLIST. Prefer sanitizeRedirectUri / isAllowedRedirectUri client-side for fail-fast UX; portal remains source of truth.
  5. CORS: add https://dex.cl8y.com to Legal API CORS_ORIGINS (and localhost only for local/dev if needed).
  6. CSP: extend production connect-src for https://api.terms.cl8y.com (and https://terms.cl8y.com if needed). Do not widen to blanket https:.
  7. No custom Terra verify in the DEX — redirect to portal sign_urls.terra_classic.
  8. Fail closed on transactional UI when status is unknown/error after connect (do not treat API failure as signed). Browse-only pages may remain usable when disconnected.
  9. E2E: provide a Playwright escape hatch (mock status or env), analogous to VITE_PLAYWRIGHT_E2E skipping the risk modal — never disable the gate silently in production builds.
  10. Secrets: no ADMIN_TOKEN in the frontend. Public Legal endpoints only.
  11. Keep NFA/footer copy; clickwrap is acceptance evidence, not a substitute for risk disclosure.

Relevant files

DEX (cl8y-dex-terraclassic)

Area Paths
App shell / mount point frontend-dapp/src/App.tsx, frontend-dapp/src/components/common/Layout.tsx
Wallet address frontend-dapp/src/hooks/useWallet.ts, frontend-dapp/src/services/terraclassic/wallet.ts, frontend-dapp/src/components/wallet/*
Existing legal frontend-dapp/src/components/legal/*, frontend-dapp/src/utils/riskAcknowledgement.ts
Tx surfaces to protect pages/SwapPage.tsx, TradePage.tsx, PoolPage.tsx, LimitOrdersPage.tsx, WrapPage.tsx, Ust1Page.tsx, CreatePairPage.tsx, trade/limit claim hooks (useLimitExpiredClaimMutation.ts, etc.)
CSP frontend-dapp Vite CSP helper (viteCsp.ts or equivalent)
Env / deploy frontend-dapp/.env.example, deployments/mainnet-soft-launch/frontend.env.example, docker/frontend/nginx.conf
Tests frontend-dapp Vitest legal tests, playwright.config.ts, e2e projects
Docs / skills docs/frontend.md, skills/AGENTS_FRONTEND_RISK_DISCLAIMERS.md, soft-launch runbooks
Area Notes
SDK @plasticdigits/cl8y-clickwrap — TermsGate, useSignatureStatus, createClient, buildSignUrl
API https://api.terms.cl8y.com — /api/v1/terms/latest, /signatures/status; wallet submit on portal
Portal https://terms.cl8y.com/sign/terra-classic?property=dex.cl8y.com
Ops Register property dex.cl8y.com; update CORS_ORIGINS + portal redirect allowlist

  1. Dependency: add @plasticdigits/cl8y-clickwrap (+ React peers already present).
  2. Client singleton: createClient({ apiBaseUrl, termsBaseUrl }) with production defaults; optional VITE_LEGAL_API_BASE_URL / VITE_LEGAL_TERMS_BASE_URL for non-prod override.
  3. Property constant: dex.cl8y.com (env-overridable only if needed for local; prefer mock in e2e).
  4. UI integration (preferred): thin ConnectedTermsGate in Layout.tsx (beside RiskAcknowledgementModal):
    • No address → render children (browse OK).
    • Address present → wrap with TermsGate (network=TerraClassic, account=address, redirectUri=window.location.href, appName="CL8Y DEX").
  5. Alternative (stricter / less shell-invasive): leave shell ungated for connected browse, but disable/block submit CTAs on swap/trade/pool/claim/wrap/create until signed_latest via useSignatureStatus. Prefer shell TermsGate unless UX requires otherwise — document choice in PR.
  6. Ops checklist (same MR notes or follow-up): Legal admin register property; Coolify Legal API CORS_ORIGINS includes https://dex.cl8y.com; rebuild Legal web with redirect allowlist including https://dex.cl8y.com.
  7. CSP + env examples updated in the same MR as the frontend wiring.
  8. Docs: update frontend risk/legal skill + soft-launch checklist with clickwrap + ops allowlists.
import { createClient } from '@plasticdigits/cl8y-clickwrap'
import { TermsGate } from '@plasticdigits/cl8y-clickwrap/react'

const legalClient = createClient()

function ConnectedTermsGate({ children }: { children: React.ReactNode }) {
  const address = useWalletStore((s) => s.address)
  if (!address) return <>{children}</>
  return (
    <TermsGate
      client={legalClient}
      property="dex.cl8y.com"
      network="TerraClassic"
      account={address}
      redirectUri={window.location.href}
      appName="CL8Y DEX"
    >
      {children}
    </TermsGate>
  )
}

Acceptance criteria

  • @plasticdigits/cl8y-clickwrap installed and used; no forked Terra ADR-036 verify in the DEX.
  • Property dex.cl8y.com registered on Legal API; frontend uses that property consistently.
  • Connected wallet without signed_latest cannot complete swap / LP provide-withdraw / limit place / expired claim / wrap / create-pair (gate or submit block — as chosen above).
  • Connected wallet with signed_latest can use those flows without extra friction.
  • Redirect to portal uses Terra Classic sign URL; return to DEX via allowlisted redirect_uri; status re-checked (focus / poll).
  • Existing RiskAcknowledgementModal still works for first visit; e2e skip behavior preserved/extended.
  • Production CSP allows Legal API; Legal CORS + portal redirect allowlist updated for https://dex.cl8y.com.
  • Footer NFA / risk copy retained.
  • Docs/skills/env examples updated.
  • Unit + Playwright coverage for gate behavior (see test plans).

Test plan — functional paths

  1. Disconnected browse: open /, /pool, /trade — risk modal (if first visit) works; no Legal redirect; pages render.
  2. Connect unsigned: connect Keplr/Station — TermsGate (or CTA block) shows accept path; swap submit does not send chain txs until signed.
  3. Accept path: follow portal /sign/terra-classic?property=dex.cl8y.com, consent + ADR-036 sign, redirect back — signed_latest true; swap/LP CTAs work.
  4. Already signed: reconnect / reload with prior signature — no forced re-sign; children render.
  5. Terms version bump: after Legal publishes new latest, previously signed account becomes unsigned for property — gate returns; must re-sign.
  6. Account switch: switch terra1 account — status re-fetched for new account; unsigned account gated.
  7. Disconnect: disconnect wallet — gate clears; browse OK.
  8. Focus re-poll: after portal tab return, status refreshes without full remount (SDK focus behavior).
  9. Claim path: unsigned user with claimable expired limit — claim blocked until signed; after sign, claim works.
  10. Local/e2e: Playwright can run smoke/tx suites without production Legal dependency (mock or env skip); production build must not ship skip enabled.

Test plan — attack / hack / abuse vectors

Vector Expectation
Skip gate via deep link / direct route Shell or submit-level gate still blocks txs when unsigned; no route bypass.
Forge localStorage / risk-ack only Risk ack ≠ Legal signature; clickwrap still required after connect.
Open redirect via redirect_uri Portal must not navigate to attacker origin; DEX only passes own origin URLs; portal allowlist enforced.
Property confusion DEX must not check wrong property (false signed_latest); assert constant/VITE_ property in tests.
Network confusion (EVM vs Terra) Must query/sign TERRA_CLASSIC, not EVM.
Stale signed UI after version bump Poll/focus must not cache forever; after bump, gate reappears.
API down / 5xx / timeout Fail closed for transactional actions (not signed / unknown — do not enable submit).
CORS / CSP bypass attempts Browser blocks illegal cross-origin; CSP must not use wildcard connect-src as the fix.
Simulated / dev wallet in prod VITE_DEV_MODE simulated wallet must not be available in production builds.
Clickjacking / overlay on Accept Prefer portal for signing; DEX gate should not embed untrusted iframes for accept.
Replay / wrong account proof Rely on Legal API verify; DEX only trusts getSignatureStatus for the connected address.
XSS stealing redirect Keep SPA XSS hygiene; never navigate to unsanitized redirect_uri without allowlist helpers.

Verification criteria

  • Manual on soft-launch: connect on 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> returns signed_latest: true after accept.
  • Browser network tab: status calls succeed (CORS OK); no CSP violations for Legal API.
  • Portal redirect back to 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.
  • Ops: Legal Coolify env shows dex.cl8y.com in CORS_ORIGINS and portal build allowlist; property exists via admin API or documented registration step.

Out of scope

  • Telegram / EVM clickwrap on this DEX.
  • Changing Legal API crypto, message format, or terms oracle.
  • Replacing footer NFA copy wholesale.
  • Indexer changes (unless proxying Legal — not recommended).
## Summary Add `@plasticdigits/cl8y-clickwrap` to `frontend-dapp` so 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 - **Stack:** Vite + React 19 SPA under `frontend-dapp/` (`@cl8y-dex/frontend`), React Router, Zustand wallet store, TanStack Query. Static nginx SPA deploy. - **Prod hosts:** `https://dex.cl8y.com` (frontend), `https://indexer.dex.cl8y.com` (indexer). Soft-launch env templates in `deployments/mainnet-soft-launch/`. - **Wallet:** `useWalletStore` exposes `address` (`terra1…`) via Keplr / Station / Cosmostation / WalletConnect (`frontend-dapp/src/hooks/useWallet.ts`, `services/terraclassic/wallet.ts`, `components/wallet/WalletModal.tsx`). - **Existing legal UX (not clickwrap):** first-visit `RiskAcknowledgementModal` (localStorage `cl8y-dex-risk-ack`, versioned in `utils/riskAcknowledgement.ts`), footer NFA (`LegalFooterNotice`), env ribbon. Mounted in `components/common/Layout.tsx`. Documented in `docs/frontend.md` and `skills/AGENTS_FRONTEND_RISK_DISCLAIMERS.md`. - **No** dependency on `@plasticdigits/cl8y-clickwrap` today; no Legal API calls; production CSP `connect-src` is narrowed (LCD/RPC/indexer/WC) and does **not** currently allow `api.terms.cl8y.com` (`viteCsp.ts`). - **Legal platform (separate repo `cl8y-ecosystem-legal`):** public API + portal; Terra Classic signs via Keplr ADR-036 on `columbus-5`; acceptance is **per property** (hostname). SDK: npm `@plasticdigits/cl8y-clickwrap`. --- ## Why this is needed - Soft-launch DEX users interact with experimental AMM / LP / limit / wrap flows; ecosystem T&Cs must be **wallet-bound and versioned**, not only a localStorage NFA modal. - Signing once on `cl8y.com` does **not** satisfy `dex.cl8y.com` (property-scoped acceptances). A DEX-specific property + gate is required. - Portal + API already implement disclosure, consent checkbox, Content-SHA256 message binding, and Terra Classic verify. Reimplementing signing in the DEX would diverge and create security debt. - Without clickwrap, unsigned accounts can still submit swaps / LP / claims after connect. --- ## Constraints / guardrails 1. **Do not replace** the anonymous first-visit risk acknowledgement with clickwrap; sequence them (browse → risk ack → connect → terms gate for txs / connected shell). 2. **Network:** SDK `TerraClassic` / API `TERRA_CLASSIC` only for this dapp (not EVM). 3. **Property:** register and use **`dex.cl8y.com`** (match browser Origin), unless product explicitly chooses a shared `cl8y.com` property (document the choice). 4. **Redirects:** portal only auto-navigates allowlisted origins — add `https://dex.cl8y.com` to Legal portal `VITE_REDIRECT_URI_ALLOWLIST`. Prefer `sanitizeRedirectUri` / `isAllowedRedirectUri` client-side for fail-fast UX; portal remains source of truth. 5. **CORS:** add `https://dex.cl8y.com` to Legal API `CORS_ORIGINS` (and localhost only for local/dev if needed). 6. **CSP:** extend production `connect-src` for `https://api.terms.cl8y.com` (and `https://terms.cl8y.com` if needed). Do not widen to blanket `https:`. 7. **No custom Terra verify** in the DEX — redirect to portal `sign_urls.terra_classic`. 8. **Fail closed on transactional UI** when status is unknown/error after connect (do not treat API failure as signed). Browse-only pages may remain usable when disconnected. 9. **E2E:** provide a Playwright escape hatch (mock status or env), analogous to `VITE_PLAYWRIGHT_E2E` skipping the risk modal — never disable the gate silently in production builds. 10. **Secrets:** no `ADMIN_TOKEN` in the frontend. Public Legal endpoints only. 11. Keep NFA/footer copy; clickwrap is acceptance evidence, not a substitute for risk disclosure. --- ## Relevant files ### DEX (`cl8y-dex-terraclassic`) | Area | Paths | |------|--------| | App shell / mount point | `frontend-dapp/src/App.tsx`, `frontend-dapp/src/components/common/Layout.tsx` | | Wallet address | `frontend-dapp/src/hooks/useWallet.ts`, `frontend-dapp/src/services/terraclassic/wallet.ts`, `frontend-dapp/src/components/wallet/*` | | Existing legal | `frontend-dapp/src/components/legal/*`, `frontend-dapp/src/utils/riskAcknowledgement.ts` | | Tx surfaces to protect | `pages/SwapPage.tsx`, `TradePage.tsx`, `PoolPage.tsx`, `LimitOrdersPage.tsx`, `WrapPage.tsx`, `Ust1Page.tsx`, `CreatePairPage.tsx`, trade/limit claim hooks (`useLimitExpiredClaimMutation.ts`, etc.) | | CSP | `frontend-dapp` Vite CSP helper (`viteCsp.ts` or equivalent) | | Env / deploy | `frontend-dapp/.env.example`, `deployments/mainnet-soft-launch/frontend.env.example`, `docker/frontend/nginx.conf` | | Tests | `frontend-dapp` Vitest legal tests, `playwright.config.ts`, e2e projects | | Docs / skills | `docs/frontend.md`, `skills/AGENTS_FRONTEND_RISK_DISCLAIMERS.md`, soft-launch runbooks | ### Legal platform (ops / cross-repo) | Area | Notes | |------|--------| | SDK | `@plasticdigits/cl8y-clickwrap` — `TermsGate`, `useSignatureStatus`, `createClient`, `buildSignUrl` | | API | `https://api.terms.cl8y.com` — `/api/v1/terms/latest`, `/signatures/status`; wallet submit on portal | | Portal | `https://terms.cl8y.com/sign/terra-classic?property=dex.cl8y.com` | | Ops | Register property `dex.cl8y.com`; update `CORS_ORIGINS` + portal redirect allowlist | --- ## Recommended direction 1. **Dependency:** add `@plasticdigits/cl8y-clickwrap` (+ React peers already present). 2. **Client singleton:** `createClient({ apiBaseUrl, termsBaseUrl })` with production defaults; optional `VITE_LEGAL_API_BASE_URL` / `VITE_LEGAL_TERMS_BASE_URL` for non-prod override. 3. **Property constant:** `dex.cl8y.com` (env-overridable only if needed for local; prefer mock in e2e). 4. **UI integration (preferred):** thin `ConnectedTermsGate` in `Layout.tsx` (beside `RiskAcknowledgementModal`): - No address → render children (browse OK). - Address present → wrap with `TermsGate` (`network=TerraClassic`, `account=address`, `redirectUri=window.location.href`, `appName="CL8Y DEX"`). 5. **Alternative (stricter / less shell-invasive):** leave shell ungated for connected browse, but disable/block submit CTAs on swap/trade/pool/claim/wrap/create until `signed_latest` via `useSignatureStatus`. Prefer shell `TermsGate` unless UX requires otherwise — document choice in PR. 6. **Ops checklist (same MR notes or follow-up):** Legal admin register property; Coolify Legal API `CORS_ORIGINS` includes `https://dex.cl8y.com`; rebuild Legal web with redirect allowlist including `https://dex.cl8y.com`. 7. **CSP + env examples** updated in the same MR as the frontend wiring. 8. **Docs:** update frontend risk/legal skill + soft-launch checklist with clickwrap + ops allowlists. ```tsx import { createClient } from '@plasticdigits/cl8y-clickwrap' import { TermsGate } from '@plasticdigits/cl8y-clickwrap/react' const legalClient = createClient() function ConnectedTermsGate({ children }: { children: React.ReactNode }) { const address = useWalletStore((s) => s.address) if (!address) return <>{children}</> return ( <TermsGate client={legalClient} property="dex.cl8y.com" network="TerraClassic" account={address} redirectUri={window.location.href} appName="CL8Y DEX" > {children} </TermsGate> ) } ``` --- ## Acceptance criteria - [ ] `@plasticdigits/cl8y-clickwrap` installed and used; no forked Terra ADR-036 verify in the DEX. - [ ] Property **`dex.cl8y.com`** registered on Legal API; frontend uses that property consistently. - [ ] Connected wallet without `signed_latest` cannot complete swap / LP provide-withdraw / limit place / expired claim / wrap / create-pair (gate or submit block — as chosen above). - [ ] Connected wallet with `signed_latest` can use those flows without extra friction. - [ ] Redirect to portal uses Terra Classic sign URL; return to DEX via allowlisted `redirect_uri`; status re-checked (focus / poll). - [ ] Existing `RiskAcknowledgementModal` still works for first visit; e2e skip behavior preserved/extended. - [ ] Production CSP allows Legal API; Legal CORS + portal redirect allowlist updated for `https://dex.cl8y.com`. - [ ] Footer NFA / risk copy retained. - [ ] Docs/skills/env examples updated. - [ ] Unit + Playwright coverage for gate behavior (see test plans). --- ## Test plan — functional paths 1. **Disconnected browse:** open `/`, `/pool`, `/trade` — risk modal (if first visit) works; no Legal redirect; pages render. 2. **Connect unsigned:** connect Keplr/Station — TermsGate (or CTA block) shows accept path; swap submit does not send chain txs until signed. 3. **Accept path:** follow portal `/sign/terra-classic?property=dex.cl8y.com`, consent + ADR-036 sign, redirect back — `signed_latest` true; swap/LP CTAs work. 4. **Already signed:** reconnect / reload with prior signature — no forced re-sign; children render. 5. **Terms version bump:** after Legal publishes new latest, previously signed account becomes unsigned for property — gate returns; must re-sign. 6. **Account switch:** switch `terra1` account — status re-fetched for new account; unsigned account gated. 7. **Disconnect:** disconnect wallet — gate clears; browse OK. 8. **Focus re-poll:** after portal tab return, status refreshes without full remount (SDK focus behavior). 9. **Claim path:** unsigned user with claimable expired limit — claim blocked until signed; after sign, claim works. 10. **Local/e2e:** Playwright can run smoke/tx suites without production Legal dependency (mock or env skip); production build must not ship skip enabled. --- ## Test plan — attack / hack / abuse vectors | Vector | Expectation | |--------|-------------| | **Skip gate via deep link / direct route** | Shell or submit-level gate still blocks txs when unsigned; no route bypass. | | **Forge localStorage / risk-ack only** | Risk ack ≠ Legal signature; clickwrap still required after connect. | | **Open redirect via `redirect_uri`** | Portal must not navigate to attacker origin; DEX only passes own origin URLs; portal allowlist enforced. | | **Property confusion** | DEX must not check wrong property (false `signed_latest`); assert constant/`VITE_` property in tests. | | **Network confusion (EVM vs Terra)** | Must query/sign `TERRA_CLASSIC`, not `EVM`. | | **Stale signed UI after version bump** | Poll/focus must not cache forever; after bump, gate reappears. | | **API down / 5xx / timeout** | Fail closed for transactional actions (not signed / unknown — do not enable submit). | | **CORS / CSP bypass attempts** | Browser blocks illegal cross-origin; CSP must not use wildcard `connect-src` as the fix. | | **Simulated / dev wallet in prod** | `VITE_DEV_MODE` simulated wallet must not be available in production builds. | | **Clickjacking / overlay on Accept** | Prefer portal for signing; DEX gate should not embed untrusted iframes for accept. | | **Replay / wrong account proof** | Rely on Legal API verify; DEX only trusts `getSignatureStatus` for the connected address. | | **XSS stealing redirect** | Keep SPA XSS hygiene; never navigate to unsanitized `redirect_uri` without allowlist helpers. | --- ## Verification criteria - Manual on soft-launch: connect on `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>` returns `signed_latest: true` after accept. - Browser network tab: status calls succeed (CORS OK); no CSP violations for Legal API. - Portal redirect back to `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. - Ops: Legal Coolify env shows `dex.cl8y.com` in `CORS_ORIGINS` and portal build allowlist; property exists via admin API or documented registration step. --- ## Out of scope - Telegram / EVM clickwrap on this DEX. - Changing Legal API crypto, message format, or terms oracle. - Replacing footer NFA copy wholesale. - Indexer changes (unless proxying Legal — not recommended).
PlasticDigits commented 2026-08-11 03:14:42 +00:00 (Migrated from gitlab.com)

mentioned in commit d671811274

mentioned in commit d6718112740398f2631c49b35bfa63e4cef98197
PlasticDigits commented 2026-08-11 03:14:44 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1051

mentioned in merge request !1051
PlasticDigits commented 2026-08-11 03:27:32 +00:00 (Migrated from gitlab.com)

mentioned in commit 6e3e2b7c85

mentioned in commit 6e3e2b7c85b04e73b142a3a1e216730ad9a798c3
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-08-11 03:27:39 +00:00
PlasticDigits commented 2026-08-11 03:30:51 +00:00 (Migrated from gitlab.com)

mentioned in commit 7bd861fff0

mentioned in commit 7bd861fff0e0fc90d66318c7c63479ed558723cb
PlasticDigits commented 2026-08-11 03:32:06 +00:00 (Migrated from gitlab.com)

mentioned in commit d44474899a

mentioned in commit d44474899af95b7d00609b39756033d47912d15c
PlasticDigits commented 2026-08-15 09:36:29 +00:00 (Migrated from gitlab.com)

mentioned in issue PlasticDigits2/ustr-cmm#12

mentioned in issue PlasticDigits2/ustr-cmm#12
PlasticDigits commented 2026-08-16 07:14:04 +00:00 (Migrated from gitlab.com)

mentioned in issue #531

mentioned in issue #531
PlasticDigits commented 2026-08-16 09:55:50 +00:00 (Migrated from gitlab.com)

mentioned in issue #533

mentioned in issue #533
PlasticDigits commented 2026-08-17 03:45:50 +00:00 (Migrated from gitlab.com)

mentioned in issue #542

mentioned in issue #542
PlasticDigits commented 2026-08-18 00:20:45 +00:00 (Migrated from gitlab.com)

marked as related to #554

marked as related to #554
PlasticDigits commented 2026-08-21 11:32:37 +00:00 (Migrated from gitlab.com)

mentioned in issue #588

mentioned in issue #588
PlasticDigits commented 2026-08-24 03:15:46 +00:00 (Migrated from gitlab.com)

mentioned in issue #619

mentioned in issue #619
PlasticDigits commented 2026-08-26 04:08:01 +00:00 (Migrated from gitlab.com)

marked as related to #658

marked as related to #658
PlasticDigits commented 2026-08-26 04:08:01 +00:00 (Migrated from gitlab.com)

mentioned in issue #658

mentioned in issue #658
PlasticDigits commented 2026-08-26 04:13:32 +00:00 (Migrated from gitlab.com)

mentioned in issue #663

mentioned in issue #663
PlasticDigits commented 2026-08-26 04:23:24 +00:00 (Migrated from gitlab.com)

mentioned in issue #672

mentioned in issue #672
PlasticDigits commented 2026-08-30 02:48:10 +00:00 (Migrated from gitlab.com)

mentioned in issue #706

mentioned in issue #706
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#517
No description provided.