Original release notes
4.24.0
Minor Changes
- #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
- #23025
6ec6cb7Thanks @LucasWerey! - Align the Contacts search no-results state with the design and update its copy
- #23143
4101467Thanks @LucasWerey! - refactor(contacts): clean up the Contacts debug tools
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.
- #23101
6da6010Thanks @LucasWerey! - Replace react-native-linear-gradient with Lumen LinearGradient
- #23064
82e9e1eThanks @koda-apps! - Replace react-native-device-info and react-native-version-number with expo-device and expo-application
- #23062
3bd2949Thanks @LucasWerey! - Replace react-native-image-picker with expo-image-picker for the custom lock screen gallery import
- #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"
- #22890
ee95a8eThanks @LucasWerey! - fix(cg-client): remove the unused CoinGecko supported coins list query
Removes getSupportedCoinsList, useGetSupportedCoinsListQuery, useSupportedCurrencies, MarketCoinSchema, SupportedCoinsSchema and the MarketCoin / SupportedCoins types. useMarketDataProvider now only returns supportedCounterCurrencies.
- #23228
27d0cc9Thanks @ovoronkov-ledger! - fix(receive): keep network warning above verify address cta (LIVE-38002)
- #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
- #23126
f0210f9Thanks @dgreen-ledger! - fix(notifications): request POST_NOTIFICATIONS on Android 13+
Firebase's requestPermission is a no-op on Android, so since #13457 the system notification prompt was never shown on Android 13 and above: tapping allow opened App info and push notifications stayed blocked. The app now requests POST_NOTIFICATIONS through PermissionsAndroid on Android 13+, and only opens the settings once the permission can no longer be requested.
- #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.
- #22689
011766dThanks @LucasWerey! - Report revamped protection clicks asbutton_clickedand completed activation, deactivation, and migration asencryption_updated
- #22648
15491fbThanks @LucasWerey! - Move the app lock UI shared by several journeys into@features/platform-app-lock.
PasswordField and the password draft (PasswordDraftProvider, usePasswordDraft) leave @features/flow-app-lock, which no longer exports them, for @features/platform-app-lock, exported from its native entry only. This is the first step of splitting the app lock flow into one package per journey: unlock, password setup and removal, longer password and the protection prompt each need these pieces, and none of them should depend on another journey to get them. No behaviour changes.
- #22817
57b333dThanks @LucasWerey! - Move the mandatory longer-password journey out of@features/flow-app-lockinto a new@features/flow-app-longer-passwordpackage:useLongerPasswordViewModel,LongerPasswordViewand its enter and confirm steps,ChangePasswordSheetandPasswordChangedSheet. The app's longer-password gate imports them from there, and the enter and confirm steps still reuse@features/flow-app-password-setup, which@features/flow-app-lockno longer depends on. No behaviour change.
- #22792
9894c78Thanks @LucasWerey! - Move the password removal journey - the Deactivate password step and the sheet that keeps the last protection while a card is active - out of@features/flow-app-lockinto a new@features/flow-app-password-removalpackage. The Settings password and biometrics rows and the Deactivate password screen import it from there. No behaviour change.
- #22785
6225945Thanks @LucasWerey! - Move the app password setup steps into their own flow package,@features/flow-app-password-setup.
The Setup password and Confirm password steps (useSetupPasswordViewModel, SetupPasswordView, useConfirmPasswordViewModel, ConfirmPasswordView) leave @features/flow-app-lock, which no longer exports them, for steps/SetupPassword and steps/ConfirmPassword in the new package. The app's add-password screens import them from there, and the longer-password journey, still in @features/flow-app-lock, reuses them through the new package. Third step of splitting the app lock flow into one package per journey. No behaviour changes.
- #22828
9a947efThanks @LucasWerey! - Move the app protection prompt -useProtectionPromptViewModel,EnableProtectionSheetandProtectionEnabledSheet- into a new@features/flow-app-protection-promptpackage, and delete@features/flow-app-lock, now empty. The app's protection prompt imports from the new package. Last step of splitting the app lock flow into one package per journey. No behaviour change.
- #22693
b18cbdbThanks @LucasWerey! - Move the app unlock journey into its own flow package,@features/flow-app-unlock.
The unlock screen (useUnlockViewModel, UnlockView, the splash and focus rules) and the forgotten password sheet leave @features/flow-app-lock, which no longer exports them. They follow the flow layout, steps/Unlock with the sheet under steps/Unlock/components, and the app's unlock screen imports them from the new package. Second step of splitting the app lock flow into one package per journey. No behaviour changes.
- #22993
6b2c0c6Thanks @ovoronkov-ledger! - fix(asset-detail): stop cropping translated time range labels in the chart selector (LIVE-33383)

