bug(frontend): Android Chrome cannot complete Connect Wallet (Lunc Dash / Galaxy Station hang + Keplr extension-only) #554
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#554
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?
Working control (do not miss)
usera (Android 16 Chrome) successfully disconnected and reconnected a Terra wallet on
https://ust1cmm.com(ustr-cmm frontend). After reconnect they had the connected-wallet chrome (orange indicator, top right) and reached Accept T&C.That means ustr-cmm wallet connect works on the same device / browser / OS where DEX and bridge fail. Treat ustr-cmm
frontend/as the known-good connect implementation (PlasticDigits2/ustr-cmm). Diff DEX / bridge against it (wallet modal, WC pairing, deep links, overlays). Do not treat this incident as “mobile wallets are broken everywhere.”T&C after that successful ust1cmm connect still failed with
Keplr extension not found— that is the Legal portal signer (window.keplr), not a ustr-cmm connect bug.Summary
Community report (2026-08-17/18): on Android 16 Chrome,
https://dex.cl8y.comcannot complete Connect Wallet for Lunc Dash or Galaxy Station (UI sits on a spinner / “circles circling” and never shows an address). Keplr in that same Chrome tab is offered only as a desktop browser extension (Install / Extension pill); tapping it does not connect mobile Keplr. Workaround that does work: open the dApp inside the Keplr in-app browser. In-app Keplr (and, for one reporter, iOS Brave) can also complete Legal T&C. This issue bundles the DEX-side mobile Chrome connect gaps so the general public is not forced into an in-app browser.Follow-on to closed #519 / !1053. That work added the same-device pairing sheet (Open {wallet} + Copy pairing link). Ops #521 marked Coolify ship + device QA done. This report shows Android Chrome still fails after that ship.
Reporter notes (anonymized):
Cross-product (file separately; do not implement here):
bridge.cl8y.com— cannot tap Connect Terra Wallet (bridge repo).ust1cmm.com/ Legal portal — Accept T&C →Keplr extension not found(Legal portal useswindow.keplronly).Current codebase
frontend-dapp/src/components/wallet/WalletModal.tsxhard-codesWALLET_OPTIONS: Station / Keplr / Cosmostation asWalletType.EXTENSION; LuncDash / Galaxy Station asWalletType.WALLETCONNECT. There is no Keplr (or Station/Cosmostation) WalletConnect row. Missing extensions get a dimmed row + Install link (WALLET_EXTENSION_INSTALL_URL→https://www.keplr.app/download). The Keplr row remains clickable even when the extension is absent (disabledis onlyisConnecting).frontend-dapp/src/services/terraclassic/wallet.tsconstructsnew KeplrController(WC_PROJECT_ID)(cosmes does support Keplr WalletConnect) andnew GalaxyStationController(WC_PROJECT_ID), butnew LUNCDashController()with no project id (Lunc Dash WC v1 / custom bridge).connectTerraWalletawaitscontroller.connect()with no timeout and no abort.useWallet.tssetsisConnecting: truebefore the await and only clears it on success or thrown error.WalletButton.tsxdisables the header CTA and shows an animate-spin SVG; on viewports< smthe “Connecting...” label ishidden, so the user only sees circles.WalletModal.tsxalso shows “Connecting...” and disables every wallet row for the whole session wait.walletConnectPairing.ts+walletConnectPairingHook.ts(installed inmain.tsxbeforecreateRoot) +WalletConnectPairingModal.tsxinLayout.tsx. CosmesQRCodeModaldelegates toglobalThis.__CL8Y_WC_PAIRING_MODAL__on mobile. Desktop QR is unchanged (WC-M2). Deep links are user-gesture<a href>only (WC-M3).Modal.tsx(z-[9999], portaled todocument.body). Connect Wallet stays open whileconnect()is in flight. Dismissing the pairing sheet only clearsuseWalletConnectPairingStore; it does not abortcontroller.connect(), soisConnectingcan stay true forever (no Cancel, unlikecl8y-bridge-monorepoTerraWalletModal.cancelConnection).luncdash://wallet_connect?payload=…(buildLuncDashDeepLink). Galaxy Station on Android usesbuildAndroidWalletIntentagainst the cosmesandroidtemplate (tests usehttps://station.hexxagon.io/wcV2#Intent;package=io.hexxagon.station;scheme=galaxystation;end;). That yields an https URL with a#Intentfragment, not a leadingintent:URI. There is a Galaxy iOS unit test; no Android Galaxy deep-link test. Allowlist (WC-M5) includeswc:,luncdash:,keplrwallet:,galaxystation:,intent:, Hexxagon / Terra Station hosts —keplrwallet:is allowlisted even though the modal never starts Keplr WC.detectInAppBrowser.ConnectedTermsGateredirects toterms.cl8y.com(C1: DEX must not implement ADR-036). Portalweb/src/pages/terra.tsthrowsKeplr extension not foundwhen!window.keplr. Chrome Android will fail T&C even after a successful WC connect unless the user is in a Keplr-injected WebView. Track that in the Legal repo; DEX should not strand users with a dead Accept button.Existing tests:
walletConnectPairing.test.ts,walletConnectPairingHook.test.ts,WalletConnectPairingModal.test.tsx,cosmesPatch127.test.ts,WalletModal.test.tsx.make verify-issue-519is unit-only; it never exercised Android Chrome + real wallet apps.Why this is needed
KeplrControlleralready takesVITE_WC_PROJECT_ID; the UI never uses it. #521’s “Keplr Mobile same-device Open / Copy” checkbox is not reflected inWALLET_OPTIONS.isConnectingspinner with no cancel matches the reported “circles circling” and leaves the header CTA disabled.Constraints / guardrails
location.hreffrom the asyncdisplay_uricallback (WC-M3). Copy the rawwc:URI viaCopyButton(WC-M4). Pairing hrefs must passisAllowedWalletConnectDeepLink(WC-M5). Keep the cosmes hook + vanilla Open/Copy fallback andpatch-package(WC-M6). Keep in-app browser as an alternate path, documented in the modal — not “the” fix (WC-M7).@walletconnect/modal/ Reown AppKit just for this (playbook).luncdash://wallet_connect?payload=…unless vendor docs change; still ship Copy + genericwc:Open.<a href>/ button click).window.keplr, surface a short “open in Keplr browser to accept terms” path; portal signing belongs incl8y-ecosystem-legal.VITE_WC_PROJECT_ID: do not drop the Vite WC project-id guard (#378). Do not widen CSPconnect-srctohttps:.AGENTS_FRONTEND_COPY_COGNITIVE_LOAD.md.window.keplr/ Station / Cosmostation is injected.npx patch-package @goblinhunt/cosmesand updatefrontend-dapp/patches/.cosmes-patch-sha256.Relevant files
frontend-dapp/src/components/wallet/WalletModal.tsx,WalletButton.tsx,walletExtensionInstall.tsfrontend-dapp/src/hooks/useWallet.ts,services/terraclassic/wallet.tsutils/walletConnectPairing.ts,services/terraclassic/walletConnectPairingHook.ts,hooks/useWalletConnectPairingStore.ts,components/wallet/WalletConnectPairingModal.tsx,components/common/Layout.tsx,main.tsxfrontend-dapp/src/components/ui/Modal.tsxfrontend-dapp/patches/@goblinhunt+cosmes+0.0.71-ghunt.22.patchcomponents/legal/ConnectedTermsGate.tsx,utils/legalClickwrap.tsutils/__tests__/walletConnectPairing.test.ts,services/terraclassic/__tests__/walletConnectPairingHook.test.ts,components/wallet/__tests__/WalletConnectPairingModal.test.tsx,components/wallet/__tests__/WalletModal.test.tsx,hooks/__tests__/useWallet.test.ts,services/terraclassic/__tests__/cosmesPatch127.test.tsdocs/frontend.md§ WalletConnect same-device,skills/AGENTS_FRONTEND_WALLETCONNECT_MOBILE.md,skills/AGENTS_FRONTEND_WALLET_CONNECT_MODAL.md,QA_TEMPLATE.md§ 1.6make verify-issue-519(extend or addverify-issue-NNN)Recommended direction
controller.connect(), clearisConnecting, and restore the header CTA. Add a bounded WC wait (then a retail error + Retry), matching bridgecancelConnection.z-[9999]dialogs racing). Show Open {wallet}, Open wallet, Copy pairing link as soon asdisplay_urifires; never leave the user on a spinner-only header.luncdash://and Galaxy Station Android intent/universal-link templates on Chrome Android 16. Preferintent:/ documented vendor schemes that actually open the app; keep Copy pairing link. Add unit tests for Android UA + Galaxy Station (today only iOS is covered).isWalletConnectMobileClient()andwindow.keplris absent, offer Keplr via WalletConnect (WalletName.KEPLR+WalletType.WALLETCONNECT— controller already hasWC_PROJECT_ID) or a primary CTA to open the dApp in the Keplr in-app browser (keplrwallet:allowlisted). Do not send Android users to the Chrome Web Store. Whenwindow.keplris present (in-app browser), keep the existing Extension row (WC-M7).window.keplris missing, do not dump users on a portal that only throwsKeplr extension not foundwithout a next step.Acceptance criteria
terra1….isConnectingand re-enables Connect Wallet.javascript:/ arbitrary https from the payload.QA_TEMPLATE.md/AGENTS_FRONTEND_WALLETCONNECT_MOBILE.mdupdated;make verify-issue-NNNcovers new unit tests.Test plan (functional paths)
luncdash://;keplrwallet:/intent:allowlist; rejectjavascript:and off-allowlist https.isConnectingtrue during WC; Cancel/close/timeout sets false and does not persist a half-session; pairing close does not leave header disabled.window.keplrshows Keplr WC or in-app CTA, not Install-only; injectedwindow.keplrstill shows Extension + Ready.isWalletConnectMobileClient() === true; desktop UA still false.make verify-issue-519still green;WalletModal#139/#160/#490 tests still green.Test plan (attack / abuse / hack vectors)
uriisjavascript:…/data:/https://evil.example/wcandroid/iostemplates pointing off-allowlistisAllowedWalletConnectDeepLinkrejects;<a href>unsetcl8y_wallet_connectionlocalStorage for WCisPermanentError)wc:pairing URI, not extra scripts/HTMLintent:extra extras /S.browser_fallback_urlto attacker siteVerification criteria
New/extended Vitest suite green via
make verify-issue-NNN(or documented extension ofmake verify-issue-519).Manual matrix recorded on this issue (device / OS / browser / wallet / path / result):
Production
https://dex.cl8y.comafter Coolify rebuild (confirmnpm ciapplied@goblinhunt/cosmes@0.0.71-ghunt.22+ patch).Legal T&C on mobile Chrome tracked on the Legal issue; DEX must not claim “connect works” if Accept T&C is still
Keplr extension not foundoutside in-app Keplr.marked as related to #519
marked as related to #517
Same incident, other products (anonymized community report 2026-08-17/18):
Keplr extension not foundon mobile Chrome): https://gitlab.com/PlasticDigits/cl8y-ecosystem-legal/-/work_items/9CONNECT TCnot tappable on Android Chrome: https://gitlab.com/PlasticDigits/cl8y-bridge-monorepo/-/work_items/137Follow-up: higher-confidence root causes (code)
1. Pairing sheet is behind Connect Wallet (likely “circles circling”)
Both dialogs use
Modalatz-[9999]and portal todocument.body.Render order:
LayoutmountsWalletConnectPairingModalfirst;WalletButton(underOutlet) mountsWalletModallater. At equal z-index the later portal wins, so Connect Wallet stays on top.Sequence: tap Lunc Dash / Galaxy Station →
isConnecting: true→ Connect list shows Connecting… and disables rows; header shows the spinner (on small screens, spinner only). Cosmes then firesdisplay_uri→ pairing store opens under that dialog.#519Open / Copy controls are not tappable.controller.connect()waits forever for WCconnect/approval()(v1 Lunc DashWalletConnectV1+ custom bridge; v2 Galaxyapproval()). No timeout.Vanilla cosmes fallback uses
z-index: 10000and would appear above Connect Wallet; the hook path suppresses that overlay, so production is worse than the fallback for stacking.Fix direction: on hook
open(), close/hideWalletModal(keepisConnecting), or give the pairing portalz-[10001], or mount pairing after WalletModal. Closing pairing / Connect must abort the WC session.2. Keplr Chrome gap is UI-only — cosmes already has WC
KeplrControlleris constructed withVITE_WC_PROJECT_IDand already embeds:intent://wcV2#Intent;package=com.chainapsis.keplr;scheme=keplrwallet;end;keplrwallet://wcV2connectTerraWallet(WalletName.KEPLR, WalletType.WALLETCONNECT)is unused becauseWALLET_OPTIONSonly lists Keplr asEXTENSION.#519pairing already allowlistskeplrwallet:/ that intent. Adding a mobile Keplr WC row reuses the pairing sheet; it still needs the stacking fix or Open Keplr will be hidden the same way.3. Galaxy Android href shape (secondary, after sheet is visible)
Galaxy
androidtemplate ishttps://station.hexxagon.io/wcV2#Intent;package=io.hexxagon.station;scheme=galaxystation;end;→buildAndroidWalletIntentyields https +#Intentfragment, notintent://. Chrome Android 16 may open the website instead of the app. Unit tests cover Galaxy iOS only.4. Test gaps to add on the MR
isConnecting.window.keplroffers Keplr WC (or in-app CTA), not Install-only.changed the description
Working control — ustr-cmm connect succeeded on the same phone
usera (Android 16 Chrome) disconnected and reconnected on
https://ust1cmm.com(ustr-cmm). Wallet connect worked (orange indicator, then Accept T&C).Same session:
ust1cmm.com) connect: worksdex.cl8y.com) connect: does not (Lunc Dash / Galaxy Station spinner; Keplr extension-only)bridge.cl8y.com) connect: does not (cannot tap Connect Terra Wallet)Use
PlasticDigits2/ustr-cmmfrontend/as the reference. T&C failure after that connect is Legal portalwindow.keplr, not proof that ustr-cmm connect is broken.mentioned in merge request !1079
mentioned in merge request !1080
mentioned in commit
879202a0b1Merged in !1080 (no automerge, CI not waited — pipeline failed with
ci_quota_exceeded, not a test fail).Shipped vs #554 AC: pairing sheet is no longer covered by Connect Wallet; pending WC can be cancelled/timeout; mobile Chrome without
window.keplroffers Keplr via WalletConnect; Galaxy Station Android usesintent://; Legal shows Keplr-browser hint after WC without injected Keplr.Still open (manual / ops, not blocking the merge):
npm ciapplies the cosmes patchTracked in the post-merge follow-up after !1080–!1084.
mentioned in issue #560
marked as related to #560
Post-merge follow-up: #560
mentioned in issue PlasticDigits2/ustr-cmm#17
mentioned in issue #566
marked as related to #566
mentioned in merge request !1090
mentioned in issue #588
mentioned in issue #511
mentioned in issue #632
marked as related to #632
mentioned in issue #658
marked as related to #658
mentioned in issue #672
marked as related to #672
mentioned in merge request !1160