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

Ledger Live Desktop 4.24.0

Original release notes

4.24.0

Minor Changes

  • #23017 eaff720 Thanks @mcayuelas-ledger! - Show a concise message when adding an account fails because the provider returns a server or network error
  • #22909 29ead28 Thanks @LucasWerey! - fix(add-account): allow creating other BTC address types when the existing account is empty
  • #22981 3faf47c Thanks @LucasWerey! - Rename the market banner "View all" tile to "More" so it no longer gets cropped in longer languages.
  • #22971 f8a4b3e Thanks @LucasWerey! - fix(top-bar): keep a minimum width for the search and truncate the update pills on narrow windows
  • #23139 320d2a1 Thanks @mcayuelas-ledger! - Resolve the market id of an asset from the ledger ids when needed, so favorites added from search show up in the Market banner

coin-stacks: spendableBalance now excludes locked (staked) STX for every Stacks account, matching getBalance, which lowers the Send max for accounts with a stake.

coin-stacks: validateIntent rejects a stake during the pox-5 prepare phase (StacksStakeInPreparePhase), which the chain would abort while still charging the fee.

The send-history contacts builder was copied in both apps. It now lives once in @domain/entity-contact/schema.mock as mockContactsFromSendHistory. @features/platform-contacts adds parseExcludedCurrencyIdsInput, which works like parseEligibleAddressFamiliesInput. The desktop tool no longer copies flag params into local state with effects. Its inputs show the flag value unless you are editing them, use cn, and have no hard-coded strings left. The mobile tool drops its StyleSheet, shows the families as tags, and builds the flag preview in its view model.

  • #23035 20bf9b0 Thanks @LucasWerey! - Route every copy/paste through the new @shared/clipboard package (expo-clipboard replaces @react-native-clipboard/clipboard on mobile) and enforce it with lint rules; copy feedback now only shows once the copy succeeded
  • #23043 4028b7e Thanks @ooke-ledger! - Hold back a per-currency fee buffer when depositing the max of a native coin into perps, configured by the new ptxTradeMaxConstant flag (feature_ptx_trade_max_constant). Only the MAX ratio is reduced; token accounts and other ratios are unchanged.
  • #22860 21fa5a5 Thanks @ooke-ledger! - Send the user back to the perps deposit form when they retry after a "not enough balance" error. Retrying re-ran the same deposit, which could only fail again; the form now reopens with the draft amount and funding account so the amount can be lowered. Other errors still retry in place
  • #22856 438c7b3 Thanks @ooke-ledger! - Hide accounts that cannot send, such as HyperCore, from the perps deposit funding picker. The receiving HyperCore account was still offered as a funding source even though a deposit cannot be sent from it. The picker now opens in the perpetuals:fund flow, which rejects send-disabled families, so modular dialog analytics from that picker report flow: "perpetuals:fund"
  • #23182 0d31c6b Thanks @ooke-ledger! - Open swap from Market only after the user has picked the network and account to swap from, whenever they hold an account on any of the asset's networks.
  • #22904 1696c5d Thanks @LucasWerey! - Wrap Analytics PnL cards and balance header on narrow windows instead of overflowing horizontally

Removes getSupportedCoinsList, useGetSupportedCoinsListQuery, useSupportedCurrencies, MarketCoinSchema, SupportedCoinsSchema and the MarketCoin / SupportedCoins types. useMarketDataProvider now only returns supportedCounterCurrencies.

  • #22920 c45454e Thanks @LucasWerey! - fix(errors): stop reporting DMK and empty errors as TranslatedError invalid usage
  • #22866 52747b3 Thanks @LucasWerey! - Name the default Me contact "Me" in the Pay tab contacts list instead of "My addresses (Me)"
  • #22988 7cfa427 Thanks @LucasWerey! - fix(crypto-addresses): keep the rename dialog open while accounts sync or countervalues refresh
  • #22436 23455ab Thanks @ysitbon! - Add the countervalues domain api: rate fetching, and the orchestration that folds rates into the entity state.
  • @domain/api-market-countervalues owns the Countervalues Service endpoints and loadCountervalues, which moves out of @ledgerhq/live-countervalues.
  • The endpoints are injected into the shared countervalues api from @shared/api-services instead of standing up a second slice. The duplicate client in live-common is removed, so each app registers one countervalues reducer where it previously registered two against the same host. That slice is an RTK Query cache and is not persisted, so there is no stored state to migrate.
  • loadCountervalues takes its rates as an argument rather than reaching for a module-level client. The apps compose one in the countervalues bridge they already own; tests pass a mock directly, which removes the MOCK_COUNTERVALUES dispatcher hidden inside the fetch path.
  • Rate failures carry the HTTP status through unchanged, so an unsupported pair still clears its cache on 422, an HTTP failure still increments the per-pair backoff, and an offline period still does not.
  • Rate requests keep the previous request policy: a 60s timeout, so a hung connection can no longer stall countervalues polling, and the same retries as before. The two endpoints moved out of live-common keep not retrying.
  • @ledgerhq/live-countervalues drops loadCountervalues, its api entry point and the fetch contract types, and with them its dependencies on @ledgerhq/logs, @ledgerhq/live-network, @ledgerhq/live-promise and @ledgerhq/live-env. It no longer reaches the network.
  • web-tools now registers the shared countervalues api, which its portfolio countervalues loading dispatches through.
  • cvsApiExtra takes getCountervaluesServiceUrl, a getter read on every request, in place of the countervaluesServiceUrl string read once at store creation. Switching the developer staging toggle now applies to the next countervalues request again, as it did before the rates moved onto the shared api.
  • #22759 bf29f88 Thanks @qperrot! - fix(coin-bitcoin): read the explorer and tuning values from the injected coin config

The module no longer keeps configuration in module state. createBridges takes a Context (ADR-019) and every bridge method resolves config_currency_<id> from context.config() at call time. The endpoint explorer.url is required and defaults to today's production host in each served config_currency_<id> (http://localhost:9876 for bitcoin_regtest, whose btc_regtest explorer id also moves to its config). The optional fields fall back to named module defaults: explorer.batchSize (DEFAULT_EXPLORER_BATCH_SIZE, 1000), fees.stuckTransactionTimeoutMs (DEFAULT_STUCK_TRANSACTION_TIMEOUT_MS, 20 min), fees.rbfMinBumpRatio (DEFAULT_RBF_MIN_BUMP_RATIO, 0.1), fees.calculationCacheTtlMs and fees.feeRatesCacheTtlMs (5 min each) and sync.replacedOperationExpiryMs (DEFAULT_REPLACED_OPERATION_EXPIRY_MS, 2 h). The explorer is bound to a wallet-btc account from the config at use, so deserialization stays config-free and a remote change applies on the next call. wallet-btc still reads no configuration: the batch size is injected through WalletBtcCurrency.explorerBatchSize, and the RBF ratio and the unconfirmed-operation expiry are parameters.

Breaking: createBridges(signerContext, context) takes a Context instead of a config getter; setCoinConfig, getCoinConfig, CoinConfig, BitcoinConfigInfo, makeAssignFromAccountRaw and getMinRelayFee are removed in favour of BitcoinCoinConfig / BitcoinContext and assignFromAccountRaw, and postSync becomes makePostSync(context). The module logs only through context.logger: buildTransaction, getTransactionStatus, prepareTransaction, calculateFees, signAccountTx, ChainAdapter.resolveFeePerByte, buildSignRawOperation and the hw-getAddress / hw-getFullViewingKey resolvers take a Logger. prepareTransaction, getTransactionStatus, buildTransaction, buildAccountTx, getOriginalTxFeeContext, getMinReplacementFeeSat, getMinReplacementFeeRateSatVb and getRbfContext take the coin config as first parameter. The getEditTransactionStatus and isStrategyDisabled bridge extensions require the mainAccount. The EXPLORER_REGTEST and BITCOIN_STUCK_TRANSACTION_TIMEOUT envs are removed, as are the config_currency_<id> defaults of the bitcoin-family currencies no loader serves (bitcoin_private, game_credits, gochain, lbry, nix, ravencoin, resistance, zclassic, zcoin).