4.24.0
Minor Changes
-
#23017
eaff720Thanks @mcayuelas-ledger! - Show a concise message when adding an account fails because the provider returns a server or network error -
#22909
29ead28Thanks @LucasWerey! - fix(add-account): allow creating other BTC address types when the existing account is empty -
#22981
3faf47cThanks @LucasWerey! - Rename the market banner "View all" tile to "More" so it no longer gets cropped in longer languages. -
#22971
f8a4b3eThanks @LucasWerey! - fix(top-bar): keep a minimum width for the search and truncate the update pills on narrow windows -
#23139
320d2a1Thanks @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 -
#22519
d60f240Thanks @semeano! - feat(stacks): add desktop stake and unstake flowscoin-stacks:
spendableBalancenow excludes locked (staked) STX for every Stacks account, matchinggetBalance, which lowers the Send max for accounts with a stake.coin-stacks:
validateIntentrejects a stake during the pox-5 prepare phase (StacksStakeInPreparePhase), which the chain would abort while still charging the fee. -
#22843
c954015Thanks @semeano! - feat(stacks): add mobile stake and unstake flows -
#23143
4101467Thanks @LucasWerey! - refactor(contacts): clean up the Contacts debug toolsThe send-history contacts builder was copied in both apps. It now lives once in
@domain/entity-contact/schema.mockasmockContactsFromSendHistory.@features/platform-contacts
addsparseExcludedCurrencyIdsInput, which works likeparseEligibleAddressFamiliesInput. The
desktop tool no longer copies flag params into local state with effects. Its inputs show the flag
value unless you are editing them, usecn, and have no hard-coded strings left. The mobile tool
drops itsStyleSheet, shows the families as tags, and builds the flag preview in its view model. -
#23035
20bf9b0Thanks @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
4028b7eThanks @ooke-ledger! - Hold back a per-currency fee buffer when depositing the max of a native coin into perps, configured by the newptxTradeMaxConstantflag (feature_ptx_trade_max_constant). Only the MAX ratio is reduced; token accounts and other ratios are unchanged. -
#22860
21fa5a5Thanks @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
438c7b3Thanks @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 theperpetuals:fundflow, which rejects send-disabled families, so modular dialog analytics from that picker reportflow: "perpetuals:fund" -
#23182
0d31c6bThanks @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
1696c5dThanks @LucasWerey! - Wrap Analytics PnL cards and balance header on narrow windows instead of overflowing horizontally -
#22890
ee95a8eThanks @LucasWerey! - fix(cg-client): remove the unused CoinGecko supported coins list queryRemoves
getSupportedCoinsList,useGetSupportedCoinsListQuery,useSupportedCurrencies,MarketCoinSchema,SupportedCoinsSchemaand theMarketCoin/SupportedCoinstypes.useMarketDataProvidernow only returnssupportedCounterCurrencies. -
#22920
c45454eThanks @LucasWerey! - fix(errors): stop reporting DMK and empty errors as TranslatedError invalid usage -
#22866
52747b3Thanks @LucasWerey! - Name the default Me contact "Me" in the Pay tab contacts list instead of "My addresses (Me)" -
#23053
2a09181Thanks @mcayuelas-ledger! - Show each stablecoin as its own Pay balance filter option, including testnet holdings -
#22988
7cfa427Thanks @LucasWerey! - fix(crypto-addresses): keep the rename dialog open while accounts sync or countervalues refresh -
#23172
37f6895Thanks @mcayuelas-ledger! - fix(sidebar): reopen the sidebar after an automatic collapse -
#22436
23455abThanks @ysitbon! - Add the countervalues domain api: rate fetching, and the orchestration that folds rates into the entity state.@domain/api-market-countervaluesowns the Countervalues Service endpoints andloadCountervalues, which moves out of@ledgerhq/live-countervalues.- The endpoints are injected into the shared countervalues api from
@shared/api-servicesinstead 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. loadCountervaluestakes 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 theMOCK_COUNTERVALUESdispatcher 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-countervaluesdropsloadCountervalues, itsapientry point and the fetch contract types, and with them its dependencies on@ledgerhq/logs,@ledgerhq/live-network,@ledgerhq/live-promiseand@ledgerhq/live-env. It no longer reaches the network.- web-tools now registers the shared countervalues api, which its portfolio countervalues loading dispatches through.
cvsApiExtratakesgetCountervaluesServiceUrl, a getter read on every request, in place of thecountervaluesServiceUrlstring 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.
-
#23173
55e5d67Thanks @mcayuelas-ledger! - Show the full Assets column label in a tooltip when it is truncated -
#22759
bf29f88Thanks @qperrot! - fix(coin-bitcoin): read the explorer and tuning values from the injected coin configThe module no longer keeps configuration in module state.
createBridgestakes aContext
(ADR-019) and every bridge method resolvesconfig_currency_<id>fromcontext.config()at call
time. The endpointexplorer.urlis required and defaults to today's production host in each
servedconfig_currency_<id>(http://localhost:9876forbitcoin_regtest, whosebtc_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.calculationCacheTtlMsandfees.feeRatesCacheTtlMs
(5 min each) andsync.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 throughWalletBtcCurrency.explorerBatchSize, and the RBF ratio and
the unconfirmed-operation expiry are parameters.Breaking:
createBridges(signerContext, context)takes aContextinstead of a config getter;
setCoinConfig,getCoinConfig,CoinConfig,BitcoinConfigInfo,makeAssignFromAccountRaw
andgetMinRelayFeeare removed in favour ofBitcoinCoinConfig/BitcoinContextand
assignFromAccountRaw, andpostSyncbecomesmakePostSync(context). The module logs only
throughcontext.logger:buildTransaction,getTransactionStatus,prepareTransaction,
calculateFees,signAccountTx,ChainAdapter.resolveFeePerByte,buildSignRawOperationand the
hw-getAddress/hw-getFullViewingKeyresolvers take aLogger.prepareTransaction,getTransactionStatus,buildTransaction,
buildAccountTx,getOriginalTxFeeContext,getMinReplacementFeeSat,
getMinReplacementFeeRateSatVbandgetRbfContexttake the coin config as first parameter. The
getEditTransactionStatusandisStrategyDisabledbridge extensions require themainAccount. TheEXPLORER_REGTESTandBITCOIN_STUCK_TRANSACTION_TIMEOUTenvs are
removed, as are theconfig_currency_<id>defaults of the bitcoin-family currencies no loader
serves (bitcoin_private,game_credits,gochain,lbry,nix,ravencoin,resistance,
zclassic,zcoin). -
#22938
7a2505bThanks @qperrot! - Rename BNB Chain to BNB Smart Chain -
#22639
0c507ffThanks @live-github-bot! - Update @ledgerhq/coin-evm to 9.0.1 and pass a logger to its APIs -
#22599
d819300Thanks @OlivierFreyssinet! - Add failureType and subError properties to Device Intent Executor deviceflow_failed and deviceflow_aborted events -
#22418
48874b3Thanks @claudiiafg! - Add desktop E2E coverage for creating a contact, registering Ethereum addresses on the device and deleting both, and let device intents discover Speculos. -
#23021
3dacfc2Thanks @fAnselmi-Ledger! - Bump@ledgerhq/device-management-kitto 1.11.0 and@ledgerhq/dmk-ledger-walletto 0.7.0. -
#23246
71c5860Thanks @aussedatlo! - Bump@ledgerhq/dmk-ledger-walletto 0.7.1,@ledgerhq/device-transport-kit-speculosto 1.3.0 and@ledgerhq/speculos-device-controllerto 0.4.0. -
#23083
4c28d72Thanks @gre-ledger! - Bump@ledgerhq/ledger-key-ring-protocol,@ledgerhq/hw-ledger-key-ring-protocolto 1.0.0 and@ledgerhq/evm-toolsto 2.0.0 (ts-libs). No API change. -
#23184
3dda070Thanks @CremaFR! - Retry a swap up to twice, without showing the error, when the Exchange app rejects the provider signature (signVerificationFailatCHECK_TRANSACTION_SIGNATURE).executeSwaprequests a new nonce and calls/swapagain with the same parameters. Each rejected attempt is still reported to/swap/cancelled, with the attempt in the error message:Signature verification failed Code: R0for the first attempt, thenR1andR2for the retries. This replaces the[diagnostic=…]signature classification, which is removed -
#22745
db3bde1Thanks @lysyi3m! - Canton: hide Accept once an offer expires while the screen is open, and show a clear message instead of retry when accepting an expired offer -
#23008
ac0379eThanks @dilaouid! - fix(send): show a broadcast error on the new send flow confirmation and only offer to try again for temporary errors (network, server, locked device) -
#22387
3dd4ee2Thanks @lysyi3m! - feat(concordium): link the PLT support article from the token list and Receive alert -
#22811
3132a4aThanks @gre-ledger! - Consume@ledgerhq/ledger-key-ring-protocoland@ledgerhq/hw-ledger-key-ring-protocolfrom npm (they now live ints-libs), and bumpaxiosto 1.20.0. No API change. -
#22657
932097dThanks @claudiiafg! - Cover on-device contact rename in desktop E2E against the mock server, which keeps the OS available after the device leaves the Ethereum app. -
#22930
5f07a43Thanks @LucasWerey! - Keep the Ledger Wallet addresses entry at full height in the desktop contact detail on small windows, and let the empty detail scroll with the custom scrollbar (LIVE-38297). -
#22604
ca82e70Thanks @sarneijim! - Add anab_testsattribute to desktop and mobile analytics events with thetrackingConfigurationof each enabled English copy experiment, or{}when none applies -
#22603
9c0fecaThanks @sarneijim! - Addfeature_copy_*experiments to the feature flags debug screen soenabledandcopycan be mocked locally -
#22413
0f401bbThanks @Moustafa-Koterba! - feat(cosmos): move the Cosmos memo onto the shared generic-adapter memo fields (LIVE-36108)Prep work for the Cosmos generic-coin-framework migration (depends on LIVE-35735, already fixed):
the sharedtransactionToIntentonly readsmemoType/memoValue, fields the four Cosmos memo
write sites (desktop send field, mobile memo-tag input, mobile edit-memo screen, wallet-api
adapter) never set — they only wrote the legacymemofield. Left as is, flipping Cosmos into
genericCoinFrameworkFamilies.jsonin a later ticket would silently drop every memo, with no
error anywhere.Adds a
cosmosentry to the shared memo-application registry, addsmemoType/memoValueto
CosmosLikeTransactionalongside the existingmemofield (read unchanged by the live legacy
bridge), and centralizes the three-field patch in a singlecosmosMemoPatchhelper all four
write sites now call, so they can't drift out of sync. Also adds the memo length check
(CosmosMemoTooLong) to the AlpacavalidateIntent, which nothing previously enforced outside
the UI'smaxLengthtruncation. -
#23001
21ab07fThanks @ysitbon! - Move the countervalues Redux slice into@features/platform-market-countervalues: its reducer, action creators, initial state, state type and selectors. Both apps now mountcountervaluesReducerat the samecountervaluesstore key and keep their ownuseSelectorhooks, persistence, polling and user-settings computation. The action types keep the desktop strings, so mobile's pending, error and wipe actions are now namedCOUNTERVALUES_STATE_SET_PENDING,COUNTERVALUES_STATE_SET_ERRORandCOUNTERVALUES_WIPE. The reducer stays a plain function rather thancreateSlice, because immer would freeze the rate maps thatloadCountervaluesupdates in place. -
#23107
fa2c070Thanks @ysitbon! - Countervalues user settings are no longer stored in Redux: each app computes them and hands them to the provider through the bridge'suseUserSettings.@features/platform-market-countervalues: the slice loses itsuserSettingsfield,setCountervaluesUserSettings(COUNTERVALUES_USER_SETTINGS_SET) andcountervaluesUserSettingsSelector.- Desktop:
useCalculateCountervaluesUserSettingsreturns the memoized settings instead of dispatching them, and the bridge calls it directly. The provider sees the real tracking pairs and refresh rate from the first render instead of one render late, so the saved rates are restored once and the boot loads once. - Mobile: no runtime change; its tests read a shared test settings constant instead of the removed slice field.
-
#21799
2c4e8cbThanks @Moustafa-Koterba! - feat(lwd): fix modal height on send flow -
#22722
03aa2c9Thanks @LL782! - Import shared analytics directly in Desktop, coin-integration code -
#22744
5879819Thanks @ysitbon! - Import the countervalues logic, types and helpers from@domain/entity-market-countervaluesinstead of@ledgerhq/live-countervalues, and drop the legacy dependency. Specifier change only, no behaviour change. -
#22950
d1eeaabThanks @OlivierFreyssinet! - Stop setting the USER_ID env on desktop, now that the firmware checks read the user ID from the identities store -
#22789
8569110Thanks @LL782! - Remove stale analytics shim mocks and docs -
#22726
e21564cThanks @LL782! - Import shared analytics directly in engagement Desktop code -
#22724
46fe382Thanks @LL782! - Import shared analytics directly in live-devices Desktop code -
#22804
948cc81Thanks @ysitbon! - fix(desktop): build nightlies against the production Firebase projectDesktop nightlies compiled the whole
.env.staging, so they read feature flags from the Firebase
staging project while mobile nightlies read production. Nightlies keep the staging services (Braze,
Segment, Earn, Card, Datadog) but now take theirFIREBASE_*values from.env.production. -
#22859
c4cf243Thanks @sarneijim! - Port device onboarding into desktop DevTools -
#22727
5b11a5aThanks @LL782! - Import shared analytics directly in platform Desktop code -
#22935
8e427a6Thanks @ysitbon! - Read the countervalues provider and hooks,useUsdToFiatRateanduseGetCounterValueIdsPollingfrom@features/platform-market-countervaluesinstead of@ledgerhq/live-countervalues-reactand live-common, and drop the@ledgerhq/live-countervalues-reactdependency. The app and the test wrapper now mount the platform provider in place of the old one. -
#22662
487620cThanks @LL782! - Import shared analytics directly in ptx Desktop code -
#22725
a4c1969Thanks @LL782! - Import shared analytics directly in recover-software Desktop code -
#23012
1289c30Thanks @OlivierFreyssinet! - Remove the HTTP proxy device transport (DEVICE_PROXY_URL) from the desktop app, together with its IPC transport and thewindow.lld.transportbridge. Real devices and Speculos connect from the renderer through the Device Management Kit. -
#22694
d9d44dcThanks @LL782! - Import shared analytics directly in wallet-xp Desktop code -
#23219
c50dc4dThanks @dilaouid! - fix(send): resizeobserver amount fix -
#22803
0e3e7b0Thanks @ysitbon! - fix(feature-flags): show the Firebase project the build actually targetsThe debug feature flags screen read the project name from the
firebaseEnvironmentReadOnly
remote flag, a value set by hand in each Firebase project, so a staging build reported
ledger-live-production. It now reads the project id from the Firebase config bundled in the
build. -
#22795
ff5e1b0Thanks @ysitbon! - refactor(feature-flags): move the Firebase Remote Config mapping to@features/platform-feature-flags-firebase@features/platform-feature-flagsnow only exposes resolved flag state (hooks andFeatureToggle).formatToFirebaseFeatureId,formatDefaultFeatures,parseFirebaseFeaturesandRemoteConfigValueare imported from@features/platform-feature-flags-firebaseinstead; the./firebasesubpath is removed. No behavior change. -
#22352
c7e76f3Thanks @ishaba! - fix(babylon): remove pre-selected validator, default to show all -
#22950
dccba0cThanks @OlivierFreyssinet! - Compute the firmware distribution salt of the non-DMK firmware update checks from the identities store instead of the USER_ID env, so they use the same salt as the DMK -
#22591
828c892Thanks @sarneijim! - Apply enabledfeature_copy_*Remote Config values as English copy overrides, reusing the feature-flag fetch -
#22913
6bb4b44Thanks @mdomanski-ext-ledger! - feat(hedera): migrate desktop Hedera flows to the generic transaction shape and enable generic adapter -
#22784
e72683bThanks @mcayuelas-ledger! - Hide the Pay tab card and its history when the pay-tab flag's card param is false -
#22985
4182256Thanks @mdomanski-ext-ledger! - fix(hedera): generic adapter fixes for fee estimation, wallet API memo, token association wording, token receive and swap history saved by the legacy bridge -
#22640
8783545Thanks @francois-guerin-ledger! - chore(contacts): stop readingethereumLikeInfoand promotechainIdfrom coin config -
#22779
9c8a8f3Thanks @KVNLS! - The desktop app's own device animations are code-split per device model and loaded lazily instead of being read back through a runtimerequire(). The shared pin/continue animations are still bundled with the renderer. -
#22395
39d91b6Thanks @dilaouid! - feat(tracking): tracking error and warning in new send flow lwm -
#22743
4d9cfbdThanks @ysitbon! - Import the countervalues logic, types, helpers and mocks from@domain/entity-market-countervaluesinstead of@ledgerhq/live-countervalues, and depend on the entity package in place of the legacy one. Specifier change only, no behaviour change.Three app tests move with live-common because the
calculatethey mock is called inside live-common: desktop'suseHistoryOperationsand mobile'suseOperationsListViewModelanduseOperationsV1. Their mock has to name the same module live-common imports. -
#23097
9bffec1Thanks @gre-ledger! - Move the updater signature check to@features/platform-app-update, so desktop no longer depends on@noble/curvesdirectly. -
#22975
11cc5fcThanks @ovoronkov-ledger! - Fix Market list and coin page showing the Settings currency symbol next to prices fetched in the currency picked from the Market dropdown -
#22969
fb02fb0Thanks @aussedatlo! - Show the mock server device as a floating window from@ledgerhq/device-mockserver-react, replacing the sidebar device screen. -
#22808
bac3334Thanks @live-github-bot! - Upgrade @ledgerhq/coin-evm to version 10.0.0 and remove obsolete gas tracker parameters -
#22765
e3e6c22Thanks @OlivierFreyssinet! - Extract the device discovery service and the connectivity types shared by device connection flows into adeviceConnectivityfolder. The discovery, connection and unknown error UI states now use the sharedConnectivityUIStateTypesenum.ConnectDeviceUIStateTypesbecomes a const object that includes these shared members, so type positions usetypeof ConnectDeviceUIStateTypes.Xor the newConnectDeviceUIStateTypetype. The device type moves to the shared part asDevice, and connectDevice keepsKnownDeviceas an alias of it. connectDevice behaviour is unchanged. -
#22915
957f451Thanks @dgreen-ledger! - Require a genuine-checked device ID before the sync onboarding companion -
#22695
570a8a0Thanks @mcayuelas-ledger! - Add a Pay tab screen test id and cover the stablecoin balance, filter, and deposit options -
#22878
d098cd3Thanks @tonykhaov! - Show a "Go to CL Card" disclaimer below the Pay contacts when thecard_disclaimerparam oflwdPayTabis on. It opens the same CL Card webview as "I have a card" on the Card screen. -
#22879
77e7162Thanks @tonykhaov! - Show the Card login on the desktop Pay tab when thecard_live_appparam oflwdPayTabis on. "Create an account" opens the card program live app and "Log in" opens the CL Card live app. -
#22876
d5de868Thanks @tonykhaov! - Read the desktop Pay card face (native, live app, disclaimer) from oneusePayCardFacehook. -
#22910
177a5b4Thanks @tonykhaov! - Pay card login: name Monavate instead of Baanx in "Log in to" and "Card provided by". -
#22649
514d6f9Thanks @koda-apps! - Show a newly linked Card asset when the user comes back to Pay from Baanx. -
#22877
f49824cThanks @tonykhaov! - Send the live app webview Back button to Pay when the webview was opened from Pay withfromPayTabstate. -
#22869
eb65ce4Thanks @mcayuelas-ledger! - Add feature-flag scenarios for the native Pay card, Card live app login, and CL Card disclaimer -
#22027
10e4a67Thanks @ooke-ledger! - Default the Perps deposit funding account to the USDC account with the highest non-zero spendable balance -
#22865
667d378Thanks @ysitbon! - Add@features/platform-market-countervalues, the countervalues React glue: the provider, its context and the hooks reading it, plususeUsdToFiatRateanduseGetCounterValueIdsPolling. It is a copy of@ledgerhq/live-countervalues-reactand of the two live-common hooks, which keep their own until their consumers move over.@ledgerhq/live-countervalues-reactreads the platform package'sCountervaluesContextinstead of creating its own, so a provider from either package serves the hooks of both. It stops exportingCountervaluesContext, which nothing imported, and drops its unused@ledgerhq/types-livedependency.- The platform package depends on no logging library. Desktop and mobile hand it their logger with
setCountervaluesLoggerat app setup, next to the rate lookups.
-
#22654
78b38fbThanks @dilaouid! - fix(send): sync account at the start of a send -
#23150
4dec481Thanks @tonykhaov! - Keep the device onboarding session in the machine context, follow a new session on reconnect, and let the host run the exit actions -
#23297
2989e37Thanks @francois-guerin-ledger! - fix(solana): refresh the blockhash after the device review to avoid "Blockhash not found" -
#22766
b2792d8Thanks @mcayuelas-ledger! - Show a setup state on the History card tab when the signed-in holder has not claimed a card yet. -
#22978
8102f7dThanks @LucasWerey! - Close the modular dialog, modals and drawer before handling any deeplink -
#23114
bdf552dThanks @ypolishchuk-ledger! - Bump Playwright from 1.60.0 to 1.63.0 and allure-playwright / allure-js-commons from 3.9.0 to 3.13.0 -
#22770
812d03fThanks @ooke-ledger! - Resolve the Perpscustom.perps.depositrequest with the swap ID and quoted amount once the deposit is broadcast, and reject it when the user cancels. The deposit request now lives inwallet-api/Perps/depositRequestand is shared by desktop and mobile -
#23024
c037aa8Thanks @mcayuelas-ledger! - Migrate desktop Add Account off pre-ldls onto Lumen and remove the React pre-ldls entry -
#22896
a663e23Thanks @mcayuelas-ledger! - Remove unused react-ui components and switch the desktop token list checkbox to Lumen -
#22830
8509abfThanks @KVNLS! - Move the desktop renderer's application database and device transport (HTTP proxy) access onto the preload bridge (window.lld.db,window.lld.transport), with one named method per operation. Password attempts against the account database are now throttled in the main process after five consecutive failures. -
#22831
fa15dfcThanks @KVNLS! - Move the auto-updater and deep-link channels and the remaining renderer IPC onto the preload bridge, in preparation for enablingcontextIsolation.Updater status and deep links are pushed to the renderer through
on*subscriptions that return an unsubscribe closure. App lifecycle, native dialogs, file operations, the screen-awake blocker and thelld.jsonstore writes go through named bridge methods instead ofipcRenderer. Channel names and main-side payloads are unchanged.With this, the only renderer
ipcRenderercall left is the Pay card PNG save, which moves onto the bridge with the other save dialogs in the next change. The only otherelectronimports outside main and the preload scripts are the three chokepoints introduced earlier — clipboard,webFrameandshell.openExternal, none of which are IPC — plus one type-only import.Log export now checks whether the save dialog was cancelled.
showSaveDialogalways resolves to an object, so the previousif (path)guard was always true and the export ran on cancel, relying on the main process to ignore a cancelled target. The observable behaviour is unchanged; the check now says what it means. -
#22832
20dccb1Thanks @KVNLS! - Move the desktop renderer's last Electron chokepoints (clipboard,webFrame,shell.openExternal) onto the preload bridge, and run the save dialogs in the main process. Main now keeps the chosen path for the log export, the operations CSV export and the Pay card PNG save, so the renderer can no longer hand an arbitrary path back to be written. The write handlers return"saved" | "canceled" | "failed", so cancelling an export is no longer reported as an error. Main registers every IPC handler through the sharedCHANNELScontract. -
#22829
8c4ccbeThanks @KVNLS! - Prepare the desktop renderer for running without Node integration: remove dead IPC channels and Node-only globals (global.localStorage,setImmediatein the post-onboarding redirect), replace winston in the renderer with a minimal logger of the same surface, route clipboard,webFrame, dialogs andosthrough single-purpose modules, import and export local Live App manifests with a file input and a download instead of the filesystem, and give the dev-only Firebase diagnostic its per-project configs from the build instead of reading.envfiles at runtime. No behaviour change. -
#22780
8d10218Thanks @KVNLS! - Add an explicit, allow-listed preload bridge (window.lld) for the desktop renderer, declared once insrc/bridge/contract.tsand imported by both sides. Main captures a bootstrap snapshot (env,os, paths, distribution channel) that the renderer reads synchronously,electron-storemoves into the main process, and the Datadog anonymizer reads its paths from the snapshot. TheCARD_SESSION_BOOTSTRAPcredential is kept out of the snapshot and handed over once per page load. The renderer still runs withnodeIntegrationon; the bridge works in both modes, so this changes no behaviour on its own. -
#22781
6c8bd31Thanks @KVNLS! - Build the desktop renderer as a web target instead ofelectron-renderer: Node builtins resolve at build time rather than as runtimerequire()calls, and the bundle has no externals.processreads are supplied from a snapshot captured in main at startup, deliberately not aprocess/browserpolyfill, which would reportplatform === "browser". A build-time guard fails the build on an unguardedprocessread or a baresetImmediate/clearImmediate, rather than letting it surface as a runtime crash.ZCash shielded sync receives its IPC channel through
setZCashIpcRendererinstead of reaching forelectron; the desktop app supplies it over the preload bridge.@ledgerhq/transaction-observability(the dApp intent'sapp_version) and@features/platform-device-action-content(the E2E animation switch) readprocess.envdirectly instead ofglobalThis.process, which the web-target renderer does not have. -
#22902
240ce9cThanks @gre-ledger! - chore: replace react-key-handler with an in-house hook for the Ctrl+E logs export shortcut, which behaves the same and drops about 21 MB of dependencies. -
#23140
b99f923Thanks @gre-ledger! - Play Lottie animations through the new@shared/lottiepackage: dotlottie on web (replacing the unmaintainedreact-lottie/lottie-web),lottie-react-nativeon mobile. -
#22950
8737f89Thanks @OlivierFreyssinet! - Keep the DMK firmware distribution salt in sync with the user ID of the identities store, so DMK flows follow the progressive OS rollout on desktop and mobile -
#23183
271861fThanks @mcayuelas-ledger! - fix(sidebar): always start fully open after a reload or app restart -
#22846
42d4dc2Thanks @benruseau! - Add the apply updates sub-step to the OS updates orchestrator, covering the OSU install, the MCU flash loop and the final firmware installWait out the device reboots each install and flash leaves behind, reconnecting under the same session id
Add the restore backup step, which runs as the last tenth of the bar when it follows an update and on its own when there is nothing left to update
Sync
BASE_SOCKET_URLto the DMK secure channel WebSocket URL -
#21839
6d744e0Thanks @YazhuEth! -estimateFeesnow returns the recipient token account, wallet address and input type of an SPL transfer alongside its fee, so the device screen names the destination; a recipient token account holding another token throwsSolanaTokenAccountHoldsAnotherToken.makeEmptyTokenAccountnow builds its id withencodeTokenAccountId, like the fourteen families that already do: the wallet-API placeholder previously used the contract address, so it matched no real sub-account id.Solana runs on the generic coin framework. The send and staking screens move onto the generic transaction shape, which names what it does — a mode, a memo, a stake account seed — instead of the nested command model the legacy bridge carried, and the apps now read it through one family module rather than reaching into the transaction themselves.
The behaviours the legacy bridge produced are restored on the generic path: an incoming SPL transfer produces an operation, a stake withdrawal empties the account rather than signing a stale amount, opening a token account is charged its rent, sending the maximum to a new stake account leaves enough to unstake it later, the device confirmation screen lists every row the device itself shows, and a token account's frozen state and Token-2022 extensions are back on screen.
A live app can again submit the four token and stake commands the wallet API defines, and a raw signature it gets back is hex, as the field it arrives in says. The device signer is selected through the family's own factory, so the
ldmkSolanaSignerflag and the transaction-check option it carries keep deciding, as they did before. The mock bridge is rewritten on the coin module, so a mocked signature still yields a transaction the wallet API can deserialize. -
#22304
e11e449Thanks @dilaouid! - feat(tracking): tracking error and warning in new send flow lwd -
#23112
7f0d867Thanks @amaslakov! - Harden the Tronify rent payment: Retry stays locked until a payment that may still land has expired, a rent price rise is shown and must be accepted before ordering again, a signed payment about to expire is refused before broadcast, and the unreachable contract-data failure is removed. -
#23032
bcd25fdThanks @OlivierFreyssinet! - chore(live-dmk): remove the ldmkTransport feature flagDeviceManagementKitProvideron desktop no longer takesldmkTransportEnabledand always provides
the Device Management Kit.useDeviceManagementKitnow returns a non-nullDeviceManagementKitand
throws outside the provider. The PayTab address verification always uses the Device Intent Executor,
and theisLDMKTransportEnabledanalytics property is removed. -
#22710
da9651fThanks @jcchevalier-ledger! - Keep explorer requests on the same Cloudflare load-balancer origin by replaying the__cflbaffinity cookie -
#22059
91ac227Thanks @Moustafa-Koterba! - feat(cosmos): Migrate the desktop staking UI onto the generic path -
#22760
4bab512Thanks @ishaba! - Add the Tronify sponsored send to the desktop Send flow behind thegasSponsorshipflag: a USDT transfer can pay its network fee with rented energy, signing the rent payment first, then the transfer once the energy is delivered on-chain. -
#23031
3264580Thanks @philipptpunkt! - PassswapApiEnv(stg|prd) to the Swap live app so it follows Wallet's Swap backend- Derived from the
SWAP_API_BASEurl via newgetSwapAPIEnvhelper in live-common - Unknown hosts (e.g. localhost) send nothing; the live app keeps its own default
- Stop passing the full
swapApiBaseurl; the live app no longer reads it
- Derived from the
-
#22891
cc764ecThanks @ooke-ledger! - Open swap history from theswap/historydeeplink, with the swap matchingswapIdopened -
#23185
437d666Thanks @LucasWerey! - Replace @react-native-community/netinfo with expo-network behind the new @shared/network-status package, and use it for the desktop network status -
#22708
ad3303bThanks @qperrot! - Let the Send flow dialog grow to fit its content so the Review button stays visible with long amount messages -
#22959
b46294eThanks @dilaouid! - feat(contact): display contact in tx details lwd -
#22953
f482212Thanks @OlivierFreyssinet! - chore(device): remove the legacy connectApp and the ldmkConnectApp feature flagconnectAppandconnectManagernow always use the Device Management Kit device actions and fail
withDmkTransportRequiredon a non-DMK transport.apps/inlineAppInstall,hw/isUpdateAvailable
andDeviceManagementKitTransport.listenLegacyConnectAppare removed. -
#23223
0a5b68dThanks @mdomanski-ext-ledger! - fix(hedera): skip association for erc-20 tokens in ReceiveWithAssociationModal and resolve the new association token in the legacy adapter -
#22818
c56dcb3Thanks @ysitbon! -useSendAmounttakes thecryptoCurrencyto convert instead of theaccountholding it. Callers resolve it withgetAccountCurrencyon the same account they passed before, so a token account still converts with its token. The hook no longer imports any account type or helper. -
#22989
8312d68Thanks @gre-ledger! - chore: takeuuidfrom the pnpm catalog (11.1.0)uuidwas spread over 8.3.2, 9.0.1 and 11.1.0. Every package now uses the catalog entry.@types/uuidis dropped: 11 ships its own types. The repo only importsv4,v5andparse(parsein a coin-solana test fixture), which behave the same across these majors. 11 typesv4with overloads, so passing it directly as a callback (useState(uuid)) no longer typechecks and is now wrapped (useState(() => uuid())). -
#22383
33094bcThanks @ysitbon! - Let wallet-pnl declare the countervalues interface it needsThe package computed profit and loss straight against the countervalues implementation, which
tied a pure pricing calculation to a concrete state shape. It now declares the three operations
it uses as aRateLookupinterface, treats the state as an opaque snapshot, and drops
@ledgerhq/live-countervaluesfrom its dependencies. The apps fill the interface at startup,
beside the crypto-assets store and the two lookups already registered there.The exported signatures keep their arity and the state argument is assignable as before, so no
caller needs a change for the interface.The third operation is a cache key.
getCostBasismemoises against a fingerprint of the rate
history relevant to a pair, which it used to compute inline from three countervalues helpers.
That computation moves to@domain/entity-market-countervaluesashistoryKey, beside the
lenseRateMapit is built on, so the three apps share one copy instead of each carrying its own
and risking drift. A drifted key serves a stale cost basis silently. The key string is unchanged,
and the existing cache tests pin it without being modified.The synthetic state builder moves with it.
buildCV,buildMultiCVanddailyHistory
construct countervalues state rather than reading it, so they cannot work against an opaque
snapshot; they now live behind@domain/entity-market-countervalues/mock, and
@ledgerhq/wallet-pnl/scenariosno longer exports them. The web-tools pnl-calculator imports them
from the entity directly.web-tools registers the interface too. It renders profit and loss through the same package but
was never a consumer of the two lookups registered previously, so it needed wiring of its own.
Patch Changes
- Updated dependencies [
320d2a1,5b62ecb,d60f240,c954015,4101467,20bf9b0,4028b7e,21fa5a5,438c7b3,ee95a8e,1bf1044,8376d49,75e55ba,52747b3,2a09181,5eca063,d6e7695,3f4e740,87de6a7,b9da45c,6e3211f,ef84a7c,20484ff,f047501,23455ab,94e247b,bf29f88,c9b7594,7a2505b,abf8d33,d33fd72,bc85ada,0c507ff,d819300,48874b3,4c28d72,e308deb,01ee590,3dda070,db3bde1,e7996b4,ac0379e,33467b2,932097d,5f07a43,ca82e70,0f401bb,3347eb8,21ab07f,9ddaa97,e80d009,fa2c070,d1eeaab,eb23867,90e805d,1f50e41,3dae3bb,ff5e1b0,7bf8668,f5fa6e1,dccba0c,7ff8f5b,826a87c,6bb4b44,9c9cae5,c59fbf4,dd2d1f8,b8fc9af,3a45eb3,29b0e0c,4182256,0a65851,3444d16,8783545,f3b3c1c,4d9cfbd,09db449,fb02fb0,bac3334,dad0153,82946e5,f9ebcf6,e3e6c22,99f7c87,77e7162,77e7162,57921f9,1b78e74,a99d63a,4aa7793,0e7d80a,5f7cc73,eb65ce4,aaedf56,c26bbea,667d378,f45fc80,78b38fb,4dec481,2989e37,b2792d8,6f2ecf8,18166fb,339d174,3160fa7,1a9b21e,812d03f,c037aa8,dce4fb6,a663e23,6c8bd31,bed3cf9,5e611ff,91ad9a0,2b2eee6,b99f923,9717369,63c700c,8737f89,42d4dc2,6d744e0,644071b,6756f58,7073e2d,35d9396,c92c32e,77d202b,9a39ad5,7f0d867,69284e8,bcd25fd,91ac227,4bab512,99b54cd,3264580,f482212,766d1eb,3cdcba9,0a5b68d,8312d68,c5c2815,b7cc410,74a7067,33094bc]:- @ledgerhq/asset-detail@0.12.0
- @ledgerhq/transaction-observability@0.5.0
- @ledgerhq/coin-stacks@0.33.0
- @ledgerhq/live-common@38.3.0
- @domain/entity-contact@0.12.0
- @features/platform-contacts@0.10.0
- @shared/clipboard@0.1.0
- @features/flow-pay-card-transactions@0.5.0
- @features/flow-contacts@0.14.0
- @features/flow-pay-request@0.8.0
- @shared/feature-flags@0.26.0
- @features/flow-contacts-introduction@1.4.0
- @features/flow-pay-contact@0.6.0
- @features/flow-pay-balance@0.7.0
- @ledgerhq/coin-bitcoin@0.55.0
- @ledgerhq/coin-zcash@0.11.0
- @domain/entity-currency-crypto@0.15.0
- @ledgerhq/wallet-btc@0.7.0
- @ledgerhq/ledger-wallet-framework@3.7.0
- @domain/api-market-countervalues@0.2.0
- @domain/entity-market-countervalues@0.3.0
- @shared/api-services@0.10.0
- @ledgerhq/coin-cardano@2.0.0
- @ledgerhq/types-live@6.127.0
- @shared/env@0.10.0
- @ledgerhq/live-dmk-shared@0.35.0
- @ledgerhq/live-dmk-desktop@0.24.0
- @ledgerhq/device-onboarding@0.5.0
- @ledgerhq/coin-canton@1.4.0
- @features/platform-card@0.8.0
- @features/flow-pay-card-auth@0.10.0
- @features/platform-content-ab-tests@0.2.0
- @ledgerhq/coin-cosmos@1.6.0
- @features/platform-market-countervalues@0.2.0
- @ledgerhq/asset-aggregation@0.18.0
- @ledgerhq/wallet-pnl@0.8.0
- @domain/entity-client-identity@0.3.0
- @features/platform-feature-flags-firebase@0.1.0
- @features/platform-feature-flags@0.9.0
- @domain/api-aggregated-assets@0.6.0
- @features/flow-pay-feature-tour@0.8.0
- @devtools/bindings@0.11.0
- @features/flow-pay-card-details@0.7.0
- @features/flow-pay-card@0.7.0
- @ledgerhq/react-ui@0.56.0
- @features/platform-device-action-content@0.4.0
- @ledgerhq/coin-filecoin@2.4.0
- @ledgerhq/live-send@0.1.3
- @features/flow-contacts-add-address@0.6.2
- @features/flow-contacts-add-contact@0.7.2
- @features/flow-contacts-delete-contact@0.2.5
- @features/flow-contacts-edit-address@0.4.2
- @features/flow-contacts-edit-contact@0.6.2
- @features/flow-contacts-list@0.9.1
- @ledgerhq/live-wallet@1.1.6
- @features/flow-pay-card-assets@0.3.1
- @features/flow-large-screen-upsell@2.2.2
- @features/platform-currencies@0.9.2
- @domain/api-currency-token@0.6.4
- @domain/entity-currency@0.4.6
- @domain/entity-currency-token@0.5.5
- @ledgerhq/wallet-analytics@0.5.1
- @ledgerhq/coin-casper@3.5.1
- @ledgerhq/coin-concordium@1.5.1
- @ledgerhq/live-signer-evm@0.24.1
- @domain/api-card-management@0.8.1
- @domain/api-currency-fiat@0.4.7
- @domain/api-market-index-altcoin-season@0.4.1
- @domain/api-market-index-fear-and-greed@0.4.1
- @domain/api-push-devices@0.2.8
- @features/platform-aggregated-assets@0.5.6
- @features/platform-env@0.4.2
- @ledgerhq/live-signer-tron@0.2.1
- @features/flow-analytics-consent@0.2.9
- @shared/analytics@0.4.0
- @shared/analytics-react@0.4.0
- @shared/auth@0.6.0
- @shared/cloud-sync@0.3.0
- @shared/i18n@0.2.0
- @shared/linking@0.3.0
- @shared/lottie@0.0.0
- @shared/network-status@0.0.0
- @shared/ui-info-state@0.4.0
- @features/flow-pay-card-widget@0.5.1
- @devtools/wire@0.5.1
- @domain/entity-account@0.0.1
- @domain/entity-account-alias@0.1.0
- @domain/entity-account-name@0.2.2
- @domain/entity-analytics-consent@0.2.2
- @domain/entity-card-asset-mapping@0.7.0
- @domain/entity-currency-fiat@0.4.0
- @domain/entity-currency-unit@0.3.0
- @domain/entity-interest-rate@0.3.0
- @domain/entity-market-index-fear-and-greed@0.3.0
- @domain/entity-recent-addresses@0.2.1
- @domain/entity-starred-account@0.0.1
- @domain/entity-wallet-sync@0.1.0
- @features/flow-fear-and-greed@0.3.0
- @features/platform-app-update@0.0.0
- @features/platform-device-intent@5.2.0
- @features/platform-pay-analytics@0.3.0
- @features/platform-style@0.4.0
- @features/platform-wallet-sync@0.1.3
- @ledgerhq/ethereum-provider@0.8.0
- @ledgerhq/live-dmk-speculos@0.11.0
- @ledgerhq/types-devices@7.1.0
- @devtools/shell@0.10.2