fix(tron): disable auto-connect on load to prevent ledger modal persistence#790
fix(tron): disable auto-connect on load to prevent ledger modal persistence#790effie-ms wants to merge 8 commits into
Conversation
🦋 Changeset detectedLatest commit: 8c2bca0 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
E2E Examples — all passedAll examples passed in the latest run. |
E2E Playground resultsDetails
📥 Download full HTML report (open the run → Artifacts → |
|
NB: failed deployment - related to deleting the project from #772 - the Cloudflare deployment for that PR was failing as well, the reason might be in the constraints for project names - raised with DevOps for further investigation (DO-538). The newer deployment passes: https://23951d71.widget-fixledgerm.pages.dev/ |
🔍 QA Review — EMB-354 · fix(tron): disable auto-connect on load to prevent ledger modal persistencePR: #790 · Branch:
What this PR doesFixes a bug where the Tron Ledger "Log in with Ledger" modal persists (or immediately re-opens) after a failed Ledger connection (device unplugged, HID denied). Two independent issues are resolved:
|
| AC | Playground (this PR) | jumper.exchange (PR #2930) |
|---|---|---|
| AC1: No auto-open on page refresh | ✅ Fixed | ⏳ Pending #2930 merge |
| AC2: No modal interruption when switching wallets | ✅ Fixed | ⏳ Pending #2930 merge |
| AC3: Manual Ledger selection still works | ✅ Fixed | ✅ Per PR #2930 diff |
The ticket cannot be marked Verified until PR #2930 in jumper-exchange is also merged. PR #790 is correct and complete for its own scope (@lifi/widget-provider-tron / Playground).
Acceptance Criteria
| # | Criterion | Status | Notes |
|---|---|---|---|
| AC1 | After a failed Ledger connection, refreshing the page must not auto-open the Ledger modal | ✅ Pass (Playground) ⏳ Pending (jumper.exchange) | disableAutoConnectOnLoad in TronBaseProvider.tsx; companion fix in jumperexchange#2930 not merged |
| AC2 | After a failed Ledger connect, selecting a different wallet must proceed without interruption | ✅ Pass (Playground) ⏳ Pending (jumper.exchange) | Same root cause — auto-connect suppressed |
| AC3 | Manual Ledger wallet selection must still trigger the connect flow normally | ✅ Pass | Upstream hasManuallySetName ref guard preserves connect on manual selection |
Code Review
packages/widget-provider-tron/src/providers/TronBaseProvider.tsx
- return <WalletProvider adapters={adapters.current}>{children}</WalletProvider>
+ return (
+ <WalletProvider adapters={adapters.current} disableAutoConnectOnLoad>
+ {children}
+ </WalletProvider>
+ )✅ Correct approach. disableAutoConnectOnLoad is the canonical upstream API to prevent auto-connect on load. Manual connection flows are unaffected because the upstream hook uses a hasManuallySetName ref to re-enable connect after user selection.
✅ The tronAdapterName localStorage entry is deliberately preserved — it acts as "last selected" memory for future manual sessions, not a trigger for auto-connect.
pnpm-workspace.yaml
'@ledgerhq/hw-transport-webhid>@ledgerhq/hw-transport': '6.27.1'
'@ledgerhq/hw-app-trx>@ledgerhq/hw-transport': '6.27.1'✅ Scoped overrides are the right tool — they pin hw-transport only for the two specific dependency paths that cause the ES5/ES6 mismatch, without globally clamping the version.
ℹ️ The exact version pin (6.27.1, no range) is intentional to prevent pnpm from re-resolving to 6.35.2. Worth tracking as technical debt if LedgerHQ ships a unified ES5-compatible build above 6.27.x.
.changeset/fix-tron-ledger-modal.md
✅ Correct package (@lifi/widget-provider-tron) and bump type (patch).
Test Coverage
| Layer | Status | Notes |
|---|---|---|
| Unit tests | widget-provider-tron |
Pre-existing gap; hardware wallet connections are not feasible to unit-test without mocking the HID layer |
| E2E (Playwright) | ✅ 158 tests passed | All playground suites pass on commit 8c2bca0 |
| Manual | ✅ Deployment verified | Cloudflare preview 23951d71.widget-fixledgerm.pages.dev passes |
The absence of unit tests is a pre-existing structural gap in widget-provider-tron — no test infrastructure exists in that package. Given the hardware-dependent nature of the bug, E2E + manual verification is the practical coverage path.
Downstream Impact
| Area | Assessment |
|---|---|
| Auto-connect UX for Tron Ledger users (Playground) | Changed: Ledger modal no longer auto-opens on page load after a failed session. Desired behaviour. |
| Manual Tron Ledger connection (Playground) | Unchanged: selecting Ledger from wallet list still triggers the full connect flow |
| Other Tron wallets (non-Ledger) | No impact: other adapters are not aggressively auto-connect in the same way |
| jumper.exchange | Not yet fixed: requires PR jumperexchange/jumper-exchange#2930 to merge |
| Dependency tree | Bounded: hw-transport pin is scoped to two paths only |
| Package release | @lifi/widget-provider-tron → patch bump: changeset is correct |
🗒️ Non-blocking Observations
-
Companion PR reference outdated: jumperexchange/jumper-exchange#2930 body says
Mirrors lifinance/widget#772(the closed PR). Should be updated to reference the current PR fix(tron): disable auto-connect on load to prevent ledger modal persistence #790. -
Technical debt — exact version pin:
@ledgerhq/hw-transport: 6.27.1will not absorb security patches in the 6.27.x+ series. A follow-up ticket to revisit once LedgerHQ ships a version-compatible ES5 build would be prudent. -
Upstream root cause unaddressed: The real bug in
LedgerAdapter.connect()is thatcloseConnectingModal()is only called in the success path, not infinally. This PR correctly sidesteps the issue, but the upstream@tronweb3/tronwallet-adapter-ledgerlibrary should ideally be patched too. Consider filing an upstream issue.
✅ Verdict: Pass — PR #790 is correct and complete for the
@lifi/widget-provider-tronscope (Playground environment). All three ACs are met within this PR's boundary. E2E tests pass.
⚠️ Ticket cannot be Verified until jumperexchange/jumper-exchange#2930 is also merged. Please update #2930's PR body to reference #790 (not the closed #772).Reviewed by lifi-qa-agent[bot] · 2026-06-15
Which Linear task is linked to this PR?
https://linear.app/lifi-linear/issue/EMB-354/ledger-tron-login-popup-persists-after-wallet-reconnect
Why was it implemented this way?
1. Disable auto-connect on load
The Tron
WalletProviderpersists the selected adapter name (e.g."Ledger") inlocalStorageundertronAdapterName. WithautoConnectenabled by default, every page load triggersLedgerAdapter.connect(), which opens a Preact-rendered modal injected directly intodocument.body. If the connection fails (device unplugged, HID prompt denied), the modal DOM nodes leak —connect()only callscloseConnectingModal()in the happy path, not in thefinallyblock.Setting
disableAutoConnectOnLoadprevents auto-connect on initial page load while still allowing it after manual wallet selection (hasManuallySetNameref guards this in the upstream hook).2. Pin
@ledgerhq/hw-transportto 6.27.1Even after fixing auto-connect, connecting a Tron Ledger device throws
"Class constructor Transport cannot be invoked without 'new'". Root cause: pnpm resolves two versions of@ledgerhq/hw-transport— 6.27.1 (ES5-compiled, used by@tronweb3/tronwallet-adapter-ledger) and 6.35.2 (native ES6 classes, pulled in transitively). At runtime, the ES5-compiled@ledgerhq/hw-transport-webhid@6.27.1calls_super.call(this)on the ES6 nativeTransport@6.35.2class, which fails because ES6 classes cannot be called withoutnew.The fix adds scoped pnpm overrides forcing both
@ledgerhq/hw-transport-webhidand@ledgerhq/hw-app-trxto resolve@ledgerhq/hw-transportto6.27.1, ensuring a single ES5-compatible version throughout the dependency tree.Checklist before requesting a review