Back to Freedom.Tech Back
All Ledger Live Desktop releasesAll versions
Release Wed, Aug 19, 2026 6 min read

Ledger Live Desktop 4.17.0

Original release notes

4.17.0

Minor Changes

  • #20611 5a87153 Thanks @mcayuelas-ledger! - Mount the first-time Pay tab FeatureTour on the PayTab screen in both apps. Visibility is self-gated by the payCard slice (shown on first visit, hidden after dismissal), copy is injected from app-owned i18n keys (payTab.featureTour.\*), and analytics are wired through the view-model. Adds unit and integration coverage for the conditional rendering.
  • #20655 ec8baad Thanks @mcayuelas-ledger! - Add the desktop Pay hero for the aggregated stablecoin balance. Introduces the @features/flow-pay-card-balance package with props-only empty and funded states, wired into the desktop Pay tab and tracking Page Pay with the active balance_filter (LIVE-34896).
  • #20713 a3164d8 Thanks @mcayuelas-ledger! - Add the mobile Pay hero for the aggregated stablecoin balance. The @features/flow-pay-card-balance package gains props-only native empty and funded states, and both apps now share the portfolio aggregation through aggregatePayCardBalance (LIVE-34898). The hero is mounted at the top of the mobile Pay tab, which tracks Page Pay with the active balance_filter on view.
  • #20844 5ff320a Thanks @mcayuelas-ledger! - Wire the desktop Pay tab "Add stablecoin" tile to the shared Deposit options dialog: pressing it opens the dialog and each option routes to its desktop flow (bank transfer, swap, buy) or the receive asset flow filtered to stablecoins.

Render the deposit options as Lumen ListItem rows.

  • #20644 936abf0 Thanks @LucasWerey! - chore(deps): bump Lumen design system to latest and migrate CSS to tailwind v4 style
  • #20815 54fcd49 Thanks @cted-ledger! - Exclude immature Ironwood notes from the spendable pool. A shielded note is only spendable once its transaction is buried deep enough to have a witness at the builder's anchor, so a freshly scanned change note is no longer selected while a second send is prepared within the same confirmation window. The rule is applied wherever the spendable pool is derived - note selection, max-spendable and amount validation - and the send flow now reports insufficient spendable funds instead of failing when the transaction is built. Funds held by maturing notes stay part of the account's total balance.
  • #20833 2ab3cb8 Thanks @tonykhaov! - Require utmContent on buildLargeScreenUpsellCtaLink (breaking) and personalise the Backup Hub Recovery Key row for Nano S / SP / X with a warning and large-screen upsell CTA (LIVE-35484).
  • #20683 74de0e5 Thanks @RobinVncnt! - Show only one portfolio Braze banner when the placement area is too narrow for two readable columns, using CSS container queries instead of JS width measurement.
  • #20702 e07e0ba Thanks @mcayuelas-ledger! - Scaffold the Card API on a single endpoint-less cardApi service (DDD, CMC/DADA pattern): add the services/card transport in @shared/api-services with Bearer + x-client-key (CARD_BAANX_CLIENT_KEY) + one 401-refresh, the @domain/api-card-management endpoint injector, the @features/platform-card in-memory session and getCardSessionToken/refreshCardSession accessors, the CARD_API_URL / CARD_BAANX_CLIENT_KEY envs, and register cardApi in both apps. The legacy payCardApi Card Auth holdout is left untouched pending its migration onto cardApi (LIVE-33829).
  • #20684 ead65e0 Thanks @sarneijim! - Update LNS upsell banner opt-in/opt-out copy and per-placement images to match mobile.
  • #20571 7c8d5df Thanks @live-github-bot! - Thread the coin-module Context (ADR-019) explicitly through the coin-evm, coin-vechain and coin-near api and logic layers instead of resolving configuration from the module-level getCoinConfig singleton. Exported logic functions now take the context as their first argument, resolve config from it (await context.config(currencyId)), and pass an explicit, required config down to the network layer - no config? optionals and no singleton reads on the data path. getCoinConfig/setCoinConfig remain only as the compatibility surface for the classic account bridge. Ledger Live consumers (live-common, desktop, mobile and coin-celo) are updated to resolve and pass config/context explicitly. Also fixes a coin-polkadot type-inference issue where getTransactionMaterialWithMetadata's cache-key extractor narrowed the cached signature and dropped the config argument.
  • #20759 526ca7b Thanks @claudiiafg! - Extract shared Contacts tracking hooks and move currency analytics resolution to platform-contacts.
  • #20420 494963b Thanks @jiyuzhuang! - Fix apps not being restored after a firmware update during Early Security Checks (ESC) in sync onboarding
  • #20856 d0ac51c Thanks @mcayuelas-ledger! - Wire the Pay tab "Add stablecoin" tile to the shared Deposit options overlay on both platforms: pressing it opens the dialog (desktop) or bottom sheet (mobile), and each option routes to its platform flow (bank transfer, swap, buy) or the receive flow filtered to stablecoins.

Extract a shared useDepositOptionsAdapter hook in @features/flow-pay-card-deposit so desktop and mobile no longer duplicate the deposit options open/close state and props shape.

  • #20784 19e578a Thanks @mcayuelas-ledger! - Move the Pay Card UI Redux state out of the removed @domain/entity-pay-card package into the owning feature flows: the balance filter goes to @features/flow-pay-card-balance and the feature-tour seen flag to @features/flow-pay-card-feature-tour. The apps keep persisting it under the existing payCard key (no data migration). Both flows expose a UI-free ./state entry so store, persistence and test setup can use the slice without pulling in the flow UI.
  • #20929 dcb3340 Thanks @jiyuzhuang! - Skip installed-app listing before the ESC firmware update drawer on unseeded devices (LIVE-36215)
  • #20906 dbb2ee0 Thanks @LL782! - Fix Ledger Sync being wiped on every launch when Password Lock is enabled. app.trustchain is an encrypted db path, so before unlock it reads back as a ciphertext string; importing it regenerated member credentials, nulled the trustchain, and persisted that fresh state over the encrypted blob in plaintext. The import is now skipped while the value is still a string, and trustchain writes are suppressed while the app is locked.
  • #20662 a736d28 Thanks @RobinVncnt! - Add the Braze category content cards data layer on desktop, with single and bulk dismiss
  • #20703 c8d9b15 Thanks @amaslakov! - Surface ICP neuron staking on the account page: a stake banner for accounts that can afford a neuron

but hold none, a balance summary footer showing total staked and total maturity, and Stake / Manage Neurons actions in the account header. The send flow now explains that the memo is protocol-derived for create_neuron and increase_stake instead of offering an editable field. The two neuron flow modals are registered but their bodies land separately.

  • #20789 fe57525 Thanks @sarneijim! - Fix Large Screen Upsell competing-modal handling on desktop: do not consume retriesModal when blocked/preempted, rename persisted retries to retriesModal (legacy reset on LWD only), and track modal_blocked.
  • #20803 13d6db5 Thanks @sarneijim! - Extend desktop always-on upsell banners to Nano SP and Nano X using the shared largeScreenUpsell audience and cooldown (LIVE-35397).
  • #20719 5b39a67 Thanks @sarneijim! - Drive desktop LNS upsell banners from largeScreenUpsell and remove the legacy lldNanoSUpsellBanners flag (LIVE-35487).
  • #20794 29347c9 Thanks @LL782! - Replace the useTrack hook with the module-level track function

Internal refactor ahead of the analytics package migration. Every event keeps the properties it emits today: desktop reads the drawer name from the drawer context (or passes the custom-lock-screen constant directly) at each call site, and mobile's swap entry point rebuilds its router-derived page with usePageNameFromRoute.