Back to Freedom.Tech Back
All Ledger Live Desktop releasesAll versions
Release Fri, Sep 11, 2026 6 min read

Ledger Live Desktop 4.20.0

Original release notes

4.20.0

Minor Changes

  • #21371 56bf73c Thanks @vpenskyi-ledger! - Fix NoFundsStake modal passing raw currency object to Swap live-app instead of expected { toCurrencyId } format, causing the Receive field to not be pre-filled when navigating from Earn zero-balance account flow

The perps receiving step used one description for both states, so users who already had a Hyperliquid account were told to add one. It now reads "Select an account you want to deposit funds into to place your trades" when accounts exist, and keeps "To fund your perps, you need a Hyperliquid account.

  • #21515 7f4723c Thanks @sarneijim! - Bump Segment analytics SDKs for retry, rate-limit and security fixes (LIVE-35839)
  • #21433 8f8f1a4 Thanks @mcayuelas-ledger! - Add a web ContactAddressPicker dialog skeleton to the Pay contact flow and open it from the desktop Pay tab when a contact is pressed. The address list UI and the account/send handoff on address selection land in follow-ups.
  • #21355 fc74af8 Thanks @semeano! - Offer the Zcash memo only to shielded recipients. A memo travels in a shielded output, so a transparent recipient could never receive one, yet the send flow showed the input for every Zcash address and made the user fill or skip it. Send descriptors can now distinguish static memo support from recipient-specific visibility, and a memo left over from an earlier shielded recipient is dropped when the recipient turns transparent, so it can no longer reach the transaction builder.
  • #21367 d182d46 Thanks @claudiiafg! - Fix the Ledger Sync entry point from Contacts: align the introduction copy and artwork with the production design, only show it when the user actually tries to add a contact or an address, start the flow on "Choose your sync method", and return to Contacts instead of the Portfolio once the flow is done on Mobile.
  • #21470 5b79eb3 Thanks @claudiiafg! - Fix the Contacts add address flow stalling on Continue by only offering networks the device can register an address on: EVM networks running their own coin app, such as Ethereum Classic, Sonic and Sei, are no longer selectable
  • #21453 3b0dbae Thanks @mcayuelas-ledger! - Add the web ContactAddressPicker dialog to the Pay contact flow and open it from the desktop Pay tab when a contact is pressed. The picker lists the contact's addresses segmented by network with asset-aware icons, resolved through the view model, and exposes an optional add-address action that routes to the contact's add-address flow. Address grouping, icon resolution and truncation are shared from @features/flow-contacts. The account/send handoff on address selection lands in a follow-up.
  • #21587 46b51dd Thanks @claudiiafg! - Fix the Contacts feature introduction so closing it counts as seen and keeps you on the Contacts list, instead of navigating back and reopening the introduction on the next visit.
  • #21746 c2e2276 Thanks @amaslakov! - Add the error message shown when the protocol refuses a Tezos stake amount as too small
  • #21401 8c40cc1 Thanks @claudiiafg! - Skip the extra confirmation modal when editing a contact or address name. Apply changes now starts the device action directly when needed, and the Apply CTA shows the Ledger logo in that case.
  • #21440 0089a4b Thanks @claudiiafg! - Drive Contacts add-address confirmation through the Device Intent Executor instead of mocked Continue screens, including prefill and Send entry points.
  • #21374 d6e689f Thanks @tonykhaov! - Update the desktop Pay feature tour layout and copy to match mockups (LIVE-36499).
  • #21418 60ee73c Thanks @liviuciulinaru! - Rename CARD_API_URL to CARD_BAANX_API_URL, keep the production defaults, and drop the Env vars section from the Card / Pay DevTool.
  • #21248 9672658 Thanks @OlivierFreyssinet! - Edit an external address on the device from Contacts. The device intent now calls @ledgerhq/device-contacts-kit's ContactsManager.editExternalAddressIdentifier() and ContactsManager.editExternalAddressScope(), each returning the rotated address proof to persist while the group's name proof passes through untouched, and both apps render the confirmation step and one InfoState per failure.

The device serves address and label edits as two separate commands, so an edit changing both asks the user to confirm twice, showing the same waiting screen for each step rather than numbering them. Nothing partial is ever stored: an abandoned or rejected edit leaves the record untouched, and a retry restarts the whole chain.

  • #21247 a55d4ca Thanks @OlivierFreyssinet! - Rename a contact on the device from Contacts. The device intent now calls @ledgerhq/device-contacts-kit's ContactsManager.renameContact(), which returns the rotated name proof to persist, and both apps render the confirmation step and one InfoState per failure. A rejection keeps the job open so the user can retry on the same device.

Rename is a blockchain-agnostic dashboard operation, so it initializes on the dashboard (BOLOS) rather than a coin app: a contact with no address is renameable, and an outdated device surfaces as an OS-update screen instead of an app-update one.

  • #21269 8c83fe6 Thanks @aussedatlo! - Show the emulated device's screen at the foot of the desktop sidebar while the mock server transport is driving it, and let its buttons and touchscreen be pressed.
  • #21269 9c67330 Thanks @aussedatlo! - Let a launch MOCK_SERVER_TRANSPORT=1 turn the mock server transport on, instead of the developer toggle's stored value always winning.
  • #21269 8f8d63e Thanks @aussedatlo! - Add a "Mock server transport" toggle in the desktop developer settings, so the Device Management Kit connects to a device mock server instead of a physical device. Configured by MOCK_SERVER_TRANSPORT, MOCK_SERVER_TRANSPORT_URL, MOCK_SERVER_SESSION and MOCK_SERVER_SEED, with a top bar indicator showing whether the server is reachable.
  • #21390 8c98d3b Thanks @gre-ledger! - Remove Storybook from the desktop app: drop the .storybook config, the rsbuild.storybook.config.js builder, every *.stories.* file and the Storybook-only dependencies (storybook, @storybook/*, storybook-react-rsbuild, @rsbuild/*, @vitest/mocker, events). The STORYBOOK_ENV branches around electron access are gone, so clipboard and shell are now imported directly, and the shared Jest electron mock exposes clipboard. The now-dead *.stories.tsx exclusions in the repo Sonar and @ledgerhq/react-ui build configs are removed too.
  • coin-casper: createApi() now returns a CoinModuleImpl (dropping the throwing stubs for unsupported capabilities; withDefaults fills them). craftTransactionData delegates to the framework helper. getTransferIdFromMemo bridges the legacy StringMemo<"transferId"> shape and the new {type:"transferId"} framework shape until LIVE-35735 unifies them.
  • live-common: Casper added to genericCoinFrameworkFamilies.json; LiveConfig key config_casper_generic_bridge (default true) provides a runtime kill-switch to fall back to the legacy bridge without a deploy.
  • Desktop/Mobile: useTransferIdChange hook extracted and shared between MemoField / TransferIdField / MemoTagInput / ScreenEditTransferId; now writes both transferId (legacy bridge) and memoType/memoValue (generic path) so both bridges read the same user input correctly.
  • #21513 9dd7db0 Thanks @mcayuelas-ledger! - Add a Pay success screen to the Send flow. When the flow is launched from the Pay tab and the transaction succeeds, it now routes to a dedicated PAY_SUCCESS step that shows the recipient, amount, source account (with network icon) and a link to the transaction details, instead of the standard confirmation step. Exposes a presentational PaySuccess component from @features/flow-pay-contact and wires it in ledger-live-desktop via an MVVM PaySuccessScreen + usePaySuccessViewModel.