feat(frontend): Terra Classic wallet parity with ustr-cmm #17

Closed
opened 2026-08-18 15:21:50 +00:00 by PlasticDigits · 1 comment
PlasticDigits commented 2026-08-18 15:21:50 +00:00 (Migrated from gitlab.com)

Summary

dex.cl8y.com Connect Wallet does not offer the full Terra Classic wallet set that ustr-cmm already supports (https://ust1cmm.com, repo PlasticDigits2/ustr-cmm). Retail users who connect on CMM with Leap (and, on the CMM preregister dApp, extra WalletConnect paths) cannot do the same on the DEX.

Goal: DEX Connect Wallet + sign/broadcast must support every Terra Classic wallet ustr-cmm supports, without regressing the DEX-only mobile pairing work (#519 / #554) and without restoring the dead Leap Install URL that #159 removed.

Reference implementation: ustr-cmm frontend/src/services/wallet.ts (header: Station, Keplr, LUNC Dash, Galaxy Station, Leap, Cosmostation) and frontend/src/components/common/WalletButton.tsx. Extra WC rows also exist in ustr-cmm contracts/external/cmm-ustc-preregister/frontend-dapp/.


Problem statement

CMM and DEX share @goblinhunt/cosmes controllers, but the DEX product surface is a subset. Anyone already using Leap (or CMM’s extra WC wallets) hits a dead end on the DEX even though the same chain, same terra1… accounts, and the same cosmes stack work on ust1cmm.com.

Closed #159 removed Leap because leapwallet.io/download 404’d (“Leap Wallet is being sunset”). That was the right fix for a broken Install CTA. It also dropped connect for users who already have the Leap extension (window.leap) — which CMM still offers.


Evidence / current gap

Wallet Transport ustr-cmm production frontend/ ustr-cmm preregister Terra Classic page DEX today
Station Extension yes yes yes
Keplr Extension yes (“Keplr, Trust Wallet & compatible”) yes yes
Keplr WalletConnect no (extension-only in CMM modal) yes yes on mobile Chrome without window.keplr (#554 WC-M10)
Leap Extension yes (WC path below) no — controllers, modal row, install URL, and persisted-session reconnect all stripped (#159)
Leap WalletConnect no yes no
Cosmostation Extension yes (WC path below) yes
Cosmostation WalletConnect no yes no
LUNC Dash WalletConnect yes yes yes
Galaxy Station WalletConnect yes yes yes
Station WalletConnect no yes controller already special-cases Station WC in wallet.ts; no Connect list row
Compass / other cosmes WalletName — not offered not offered not offered — out of scope unless CMM adds it

DEX files that encode the subset:

  • frontend-dapp/src/components/wallet/connectWalletOptions.ts — Station, Keplr, Cosmostation, LuncDash, Galaxy Station only
  • frontend-dapp/src/services/terraclassic/wallet.ts — no LeapController; TerraWalletBackend excludes leap
  • frontend-dapp/src/hooks/useWallet.ts — clears persisted Leap sessions on load
  • frontend-dapp/src/components/wallet/walletIconSrc.ts / WalletModal.test.tsx — tests assert Leap is absent
  • frontend-dapp/src/services/terraclassic/walletExtensionInstall.ts — no Leap detection / no install URL (intentional #159)
  • Docs / playbooks: docs/frontend.md, QA_TEMPLATE.md, skills/AGENTS_FRONTEND_WALLET_CONNECT_MODAL.md

ustr-cmm already wires LeapController, window.leap detect, and experimentalSuggestChain for Leap alongside Station / Keplr / Cosmostation.


Constraints / guardrails

  1. Do not restore a dead Leap Install URL. #159 stays valid: never ship an Install CTA to leapwallet.io/download (or any other 404). If Leap has a live download page, use that; otherwise offer Leap only when injected (window.leap) and/or via WalletConnect — no fake Install.
  2. Keep WC-M1–WC-M12 for every new WalletConnect row (#519 / #554): same-device Open + Copy on mobile, desktop QR unchanged, user-gesture deep links, wc: copy via CopyButton, scheme allowlist, bounded connect/cancel, no AppKit/Web3Modal just for this.
  3. Do not treat WC rows as missing extensions (#139 / #160).
  4. Logos (#490): any new production row needs a local /wallets/* asset + PROVENANCE.md entry. No CDN hotlink.
  5. Production CSP / VITE_WC_PROJECT_ID: do not drop the Vite WC project-id guard (#378).
  6. Legal C1: DEX still must not implement ADR-036; after WC connect without window.keplr, keep the Keplr-browser hint for terms.
  7. Compass / Initia / other successors are out of scope unless they appear in ustr-cmm’s Terra Classic connect list.
  8. Simulated Wallet stays LocalTerra/dev-only.

Proposed solution (high level)

Match ustr-cmm’s Terra Classic connect list on the DEX, using the DEX’s existing modal / pairing / cancel stack (do not copy CMM’s glass modal wholesale).

  1. Leap extension (required for CMM production parity): re-add LeapController, window.leap detection, chain suggest, persist/TerraWalletBackend 'leap', Connect row, logo. Reverse the “purge Leap localStorage on load” behaviour so a valid Leap session can reconnect. Install CTA only if a live official URL exists.
  2. WalletConnect parity with CMM preregister (same repo): add Connect rows (mobile-first, same pattern as Keplr WC-M10) for wallets CMM already connects via WC: Leap, Station, Cosmostation. Extend isAllowedWalletConnectDeepLink only with documented vendor schemes (Leap / Station already partially represented via Hexxagon / Terra Station hosts).
  3. Trust Wallet: CMM labels Keplr as “Keplr, Trust Wallet & compatible”. DEX already uses Keplr injection; document that Trust (Keplr-compatible) is covered by the Keplr row — do not add a duplicate Trust row unless CMM does.
  4. Docs / QA / playbooks: update docs/frontend.md, QA_TEMPLATE.md, AGENTS_FRONTEND_WALLET_CONNECT_MODAL.md, AGENTS_FRONTEND_WALLETCONNECT_MOBILE.md. Flip tests that currently require Leap to be absent.

Acceptance criteria

  • Connect Wallet lists every Terra Classic wallet ustr-cmm production frontend/ lists: Station, Keplr, Leap, Cosmostation, LUNC Dash, Galaxy Station.
  • Leap extension: when window.leap is present, row is Ready and connect + suggest-chain + sign (swap or dummy execute) works on columbus-5 / LocalTerra.
  • Leap Install never points at a 404 / sunset page. Missing extension: subdued row without a dead link, or a verified live URL.
  • Persisted Leap session reconnects (today it is deleted on load).
  • CMM preregister WC wallets that are still in that repo (Leap WC, Station WC, Cosmostation WC) are connectable from DEX Connect Wallet on mobile Chrome via the existing pairing sheet (Open + Copy), without breaking Keplr / Lunc Dash / Galaxy Station #554.
  • Desktop: new WC wallets stay QR-only (WC-M2); Station / Keplr / Cosmostation / Leap extension paths unchanged when injected.
  • Pairing hrefs stay on an explicit allowlist (WC-M5); no javascript: / arbitrary https from the payload.
  • Circular logo + provenance for every new production row (#490).
  • Docs, QA template, agent playbooks, and make verify-issue-NNN updated. Tests that asserted “no Leap” are replaced with the new contract.

Test plan (functional)

  1. Unit — options: resolveConnectWalletOptions includes Leap; mobile without injection offers Leap/Station/Cosmostation WC where in scope; injected extension still Extension + Ready.
  2. Unit — detection: isBrowserWalletExtensionDetected(WalletName.LEAP) follows window.leap; WC-only names still not treated as missing extensions.
  3. Unit — persistence: saved Leap session reconnects; garbage / sunset-only names still purged.
  4. Unit — pairing: new Leap/Station/Cosmostation deep-link schemes (if added) pass allowlist tests; javascript: / off-allowlist https rejected.
  5. Vitest modal / icons: Leap row + logo; no dead Install href.
  6. Manual desktop: Leap extension connect + swap (or Place limit) on LocalTerra / columbus-5; Station / Keplr / Cosmostation regression.
  7. Manual Android Chrome: Leap / Station / Cosmostation WC Open + Copy (if shipped); Lunc Dash / Galaxy Station / Keplr WC still complete (#554).
  8. Regression: make verify-issue-554 / make verify-issue-519 stay green.

Test plan (attack / abuse)

Vector Expectation
Fake window.leap object that throws on connect Retail error; no hang; header CTA recovers
Pairing URI javascript: / data: / attacker https Rejected (WC-M5)
Late WC session after Cancel Must not attach; Leap reconnect must not loop spinner
Dead Install URL regression CI / unit asserts Install href (if any) is live-shape https: and not leapwallet.io/download
Logo / CSP No remote wallet-icon fetch; local /wallets/* only

Verification

  • make verify-issue-NNN (new) plus existing make verify-issue-554.
  • Manual matrix on this issue: desktop Leap extension; mobile WC for each newly added wallet; CMM-parity checklist vs ust1cmm.com Connect modal.

Owner type

frontend

Priority

P2 — wallet coverage / retail reach; not a funds-at-risk bug. Blocks users who already live in Leap / CMM WC wallets.

  • ustr-cmm: PlasticDigits2/ustr-cmm frontend/src/services/wallet.ts, frontend/src/components/common/WalletButton.tsx, preregister frontend-dapp/src/pages/TerraClassicPage.tsx
  • DEX: #159 (Leap removed — revisit, do not restore 404 Install), #519 / #554 (mobile WC), #490 (logos), #139 / #160 (install UX)
## Summary `dex.cl8y.com` Connect Wallet does **not** offer the full Terra Classic wallet set that **ustr-cmm** already supports (`https://ust1cmm.com`, repo [`PlasticDigits2/ustr-cmm`](https://gitlab.com/PlasticDigits2/ustr-cmm)). Retail users who connect on CMM with **Leap** (and, on the CMM preregister dApp, extra WalletConnect paths) cannot do the same on the DEX. **Goal:** DEX Connect Wallet + sign/broadcast must support **every Terra Classic wallet ustr-cmm supports**, without regressing the DEX-only mobile pairing work ([#519](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/519) / [#554](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/554)) and without restoring the dead Leap **Install** URL that [#159](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/159) removed. Reference implementation: ustr-cmm `frontend/src/services/wallet.ts` (header: Station, Keplr, LUNC Dash, Galaxy Station, Leap, Cosmostation) and `frontend/src/components/common/WalletButton.tsx`. Extra WC rows also exist in ustr-cmm `contracts/external/cmm-ustc-preregister/frontend-dapp/`. --- ## Problem statement CMM and DEX share `@goblinhunt/cosmes` controllers, but the DEX product surface is a subset. Anyone already using Leap (or CMM’s extra WC wallets) hits a dead end on the DEX even though the same chain, same `terra1…` accounts, and the same cosmes stack work on `ust1cmm.com`. Closed [#159](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/159) removed Leap because `leapwallet.io/download` 404’d (“Leap Wallet is being sunset”). That was the right fix for a broken **Install** CTA. It also dropped connect for users who **already have** the Leap extension (`window.leap`) — which CMM still offers. --- ## Evidence / current gap | Wallet | Transport | ustr-cmm production `frontend/` | ustr-cmm preregister Terra Classic page | DEX today | |--------|-----------|----------------------------------|-----------------------------------------|-----------| | Station | Extension | yes | yes | yes | | Keplr | Extension | yes (“Keplr, Trust Wallet & compatible”) | yes | yes | | Keplr | WalletConnect | no (extension-only in CMM modal) | yes | yes on mobile Chrome without `window.keplr` ([#554](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/554) **WC-M10**) | | Leap | Extension | **yes** | (WC path below) | **no** — controllers, modal row, install URL, and persisted-session reconnect all stripped ([#159](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/159)) | | Leap | WalletConnect | no | **yes** | **no** | | Cosmostation | Extension | yes | (WC path below) | yes | | Cosmostation | WalletConnect | no | **yes** | **no** | | LUNC Dash | WalletConnect | yes | yes | yes | | Galaxy Station | WalletConnect | yes | yes | yes | | Station | WalletConnect | no | **yes** | controller already special-cases Station WC in `wallet.ts`; **no Connect list row** | | Compass / other cosmes `WalletName` | — | **not offered** | **not offered** | not offered — **out of scope** unless CMM adds it | DEX files that encode the subset: - `frontend-dapp/src/components/wallet/connectWalletOptions.ts` — Station, Keplr, Cosmostation, LuncDash, Galaxy Station only - `frontend-dapp/src/services/terraclassic/wallet.ts` — no `LeapController`; `TerraWalletBackend` excludes `leap` - `frontend-dapp/src/hooks/useWallet.ts` — **clears** persisted Leap sessions on load - `frontend-dapp/src/components/wallet/walletIconSrc.ts` / `WalletModal.test.tsx` — tests **assert** Leap is absent - `frontend-dapp/src/services/terraclassic/walletExtensionInstall.ts` — no Leap detection / no install URL (intentional #159) - Docs / playbooks: `docs/frontend.md`, `QA_TEMPLATE.md`, `skills/AGENTS_FRONTEND_WALLET_CONNECT_MODAL.md` ustr-cmm already wires `LeapController`, `window.leap` detect, and `experimentalSuggestChain` for Leap alongside Station / Keplr / Cosmostation. --- ## Constraints / guardrails 1. **Do not restore a dead Leap Install URL.** [#159](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/159) stays valid: never ship an **Install** CTA to `leapwallet.io/download` (or any other 404). If Leap has a live download page, use that; otherwise offer Leap **only when injected** (`window.leap`) and/or via WalletConnect — no fake Install. 2. **Keep WC-M1–WC-M12** for every new WalletConnect row ([#519](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/519) / [#554](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/554)): same-device Open + Copy on mobile, desktop QR unchanged, user-gesture deep links, `wc:` copy via `CopyButton`, scheme allowlist, bounded connect/cancel, no AppKit/Web3Modal just for this. 3. **Do not treat WC rows as missing extensions** ([#139](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/139) / [#160](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/160)). 4. **Logos (#490):** any new production row needs a local `/wallets/*` asset + `PROVENANCE.md` entry. No CDN hotlink. 5. **Production CSP / `VITE_WC_PROJECT_ID`:** do not drop the Vite WC project-id guard ([#378](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/378)). 6. **Legal C1:** DEX still must not implement ADR-036; after WC connect without `window.keplr`, keep the Keplr-browser hint for terms. 7. **Compass / Initia / other successors** are out of scope unless they appear in ustr-cmm’s Terra Classic connect list. 8. **Simulated Wallet** stays LocalTerra/dev-only. --- ## Proposed solution (high level) Match ustr-cmm’s Terra Classic connect list on the DEX, using the DEX’s existing modal / pairing / cancel stack (do not copy CMM’s glass modal wholesale). 1. **Leap extension (required for CMM production parity):** re-add `LeapController`, `window.leap` detection, chain suggest, persist/`TerraWalletBackend` `'leap'`, Connect row, logo. Reverse the “purge Leap localStorage on load” behaviour so a valid Leap session can reconnect. Install CTA only if a **live** official URL exists. 2. **WalletConnect parity with CMM preregister (same repo):** add Connect rows (mobile-first, same pattern as Keplr **WC-M10**) for wallets CMM already connects via WC: **Leap**, **Station**, **Cosmostation**. Extend `isAllowedWalletConnectDeepLink` only with documented vendor schemes (Leap / Station already partially represented via Hexxagon / Terra Station hosts). 3. **Trust Wallet:** CMM labels Keplr as “Keplr, Trust Wallet & compatible”. DEX already uses Keplr injection; document that Trust (Keplr-compatible) is covered by the Keplr row — do not add a duplicate Trust row unless CMM does. 4. **Docs / QA / playbooks:** update `docs/frontend.md`, `QA_TEMPLATE.md`, `AGENTS_FRONTEND_WALLET_CONNECT_MODAL.md`, `AGENTS_FRONTEND_WALLETCONNECT_MOBILE.md`. Flip tests that currently **require** Leap to be absent. --- ## Acceptance criteria - [ ] Connect Wallet lists every Terra Classic wallet ustr-cmm production `frontend/` lists: **Station, Keplr, Leap, Cosmostation, LUNC Dash, Galaxy Station**. - [ ] Leap extension: when `window.leap` is present, row is Ready and connect + suggest-chain + sign (swap or dummy execute) works on columbus-5 / LocalTerra. - [ ] Leap **Install** never points at a 404 / sunset page. Missing extension: subdued row without a dead link, or a verified live URL. - [ ] Persisted Leap session reconnects (today it is deleted on load). - [ ] CMM preregister WC wallets that are still in that repo (**Leap WC, Station WC, Cosmostation WC**) are connectable from DEX Connect Wallet on mobile Chrome via the existing pairing sheet (Open + Copy), without breaking Keplr / Lunc Dash / Galaxy Station [#554](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/554). - [ ] Desktop: new WC wallets stay QR-only (**WC-M2**); Station / Keplr / Cosmostation / Leap **extension** paths unchanged when injected. - [ ] Pairing hrefs stay on an explicit allowlist (**WC-M5**); no `javascript:` / arbitrary https from the payload. - [ ] Circular logo + provenance for every new production row ([#490](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/490)). - [ ] Docs, QA template, agent playbooks, and `make verify-issue-NNN` updated. Tests that asserted “no Leap” are replaced with the new contract. --- ## Test plan (functional) 1. **Unit — options:** `resolveConnectWalletOptions` includes Leap; mobile without injection offers Leap/Station/Cosmostation WC where in scope; injected extension still Extension + Ready. 2. **Unit — detection:** `isBrowserWalletExtensionDetected(WalletName.LEAP)` follows `window.leap`; WC-only names still not treated as missing extensions. 3. **Unit — persistence:** saved Leap session reconnects; garbage / sunset-only names still purged. 4. **Unit — pairing:** new Leap/Station/Cosmostation deep-link schemes (if added) pass allowlist tests; `javascript:` / off-allowlist https rejected. 5. **Vitest modal / icons:** Leap row + logo; no dead Install href. 6. **Manual desktop:** Leap extension connect + swap (or Place limit) on LocalTerra / columbus-5; Station / Keplr / Cosmostation regression. 7. **Manual Android Chrome:** Leap / Station / Cosmostation WC Open + Copy (if shipped); Lunc Dash / Galaxy Station / Keplr WC still complete ([#554](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/554)). 8. **Regression:** `make verify-issue-554` / `make verify-issue-519` stay green. ## Test plan (attack / abuse) | Vector | Expectation | |--------|-------------| | Fake `window.leap` object that throws on connect | Retail error; no hang; header CTA recovers | | Pairing URI `javascript:` / `data:` / attacker https | Rejected (**WC-M5**) | | Late WC session after Cancel | Must not attach; Leap reconnect must not loop spinner | | Dead Install URL regression | CI / unit asserts Install href (if any) is live-shape `https:` and **not** `leapwallet.io/download` | | Logo / CSP | No remote wallet-icon fetch; local `/wallets/*` only | ## Verification - `make verify-issue-NNN` (new) plus existing `make verify-issue-554`. - Manual matrix on this issue: desktop Leap extension; mobile WC for each newly added wallet; CMM-parity checklist vs `ust1cmm.com` Connect modal. ## Owner type frontend ## Priority P2 — wallet coverage / retail reach; not a funds-at-risk bug. Blocks users who already live in Leap / CMM WC wallets. ## Related - ustr-cmm: [`PlasticDigits2/ustr-cmm`](https://gitlab.com/PlasticDigits2/ustr-cmm) `frontend/src/services/wallet.ts`, `frontend/src/components/common/WalletButton.tsx`, preregister `frontend-dapp/src/pages/TerraClassicPage.tsx` - DEX: [#159](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/159) (Leap removed — **revisit**, do not restore 404 Install), [#519](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/519) / [#554](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/554) (mobile WC), [#490](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/490) (logos), [#139](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/139) / [#160](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/160) (install UX)
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-08-24 00:09:28 +00:00
PlasticDigits commented 2026-08-24 00:34:02 +00:00 (Migrated from gitlab.com)

mentioned in issue #18

mentioned in issue #18
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/ustr-cmm#17
No description provided.