Original release notes
4.17.0
Minor Changes
- #20611
5a87153Thanks @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.
- #20713
a3164d8Thanks @mcayuelas-ledger! - Add the mobile Pay hero for the aggregated stablecoin balance. The@features/flow-pay-card-balancepackage gains props-only native empty and funded states, and both apps now share the portfolio aggregation throughaggregatePayCardBalance(LIVE-34898). The hero is mounted at the top of the mobile Pay tab, which tracksPage Paywith the activebalance_filteron view.
- #20807
aac2ee0Thanks @LucasWerey! - Force a dark background on the Android 12+ system splash screen shown between the launcher tap and the splash screen. It followed the device theme, showing a white background in light mode, because thewindowSplashScreenBackgroundit was configured with belongs tocore-splashscreenand never reached the platform.
- #20840
72c8fbfThanks @deepyjr! - Add a Contacts feature introduction toggle to Mobile Debug settings.
- #20735
c3b8717Thanks @mcayuelas-ledger! - Add a stablecoin balance filter picker to the Pay card hero.
- #20704
d83149cThanks @tonykhaov! - Fix Segment analytics flush on AppState background, show delivery status in analytics console, log Segment flushes to the analytics overlay, and warn once in Datadog when events are skipped with no Segment client
- #20581
8ae48eeThanks @liviuciulinaru! - Fix the Pay tab navigator route name collision
- #20702
e07e0baThanks @mcayuelas-ledger! - Scaffold the Card API on a single endpoint-lesscardApiservice (DDD, CMC/DADA pattern): add theservices/cardtransport in@shared/api-serviceswith Bearer +x-client-key(CARD_BAANX_CLIENT_KEY) + one 401-refresh, the@domain/api-card-managementendpoint injector, the@features/platform-cardin-memory session andgetCardSessionToken/refreshCardSessionaccessors, theCARD_API_URL/CARD_BAANX_CLIENT_KEYenvs, and registercardApiin both apps. The legacypayCardApiCard Auth holdout is left untouched pending its migration ontocardApi(LIVE-33829).
- #20674
81a708dThanks @sarneijim! - Expose lazyOnboardingBanner flag enabled state and mode on Segment identify
- #20571
7c8d5dfThanks @live-github-bot! - Thread the coin-moduleContext(ADR-019) explicitly through the coin-evm, coin-vechain and coin-near api and logic layers instead of resolving configuration from the module-levelgetCoinConfigsingleton. Exported logic functions now take the context as their first argument, resolveconfigfrom it (await context.config(currencyId)), and pass an explicit, requiredconfigdown to the network layer - noconfig?optionals and no singleton reads on the data path.getCoinConfig/setCoinConfigremain 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 wheregetTransactionMaterialWithMetadata's cache-key extractor narrowed the cached signature and dropped theconfigargument.
- #20077
89171eaThanks @jiyuzhuang! - Drop legacy ticker lookup from Large Mover landing page (LIVE-34635)
- #20856
d0ac51cThanks @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.
- #20907
da0a5ceThanks @fAnselmi-Ledger! - Add Solana TXC flag
- #20784
19e578aThanks @mcayuelas-ledger! - Move the Pay Card UI Redux state out of the removed@domain/entity-pay-cardpackage into the owning feature flows: the balance filter goes to@features/flow-pay-card-balanceand the feature-tour seen flag to@features/flow-pay-card-feature-tour. The apps keep persisting it under the existingpayCardkey (no data migration). Both flows expose a UI-free./stateentry so store, persistence and test setup can use the slice without pulling in the flow UI.
- #20778
eecf99aThanks @francois-guerin-ledger! - chore(coin-evm): replaceCryptoCurrencywithcurrencyId
- #20724
8eb38c0Thanks @deepyjr! - Fixed reopening an address after cancelling its edit drawer in Contacts.
- #20745
ec6fa1bThanks @claudiiafg! - Fixed reopening the delete contact confirmation sheet after cancelling it by opening delete only after the actions menu sheet has fully dismissed.
- #20744
c65ca3eThanks @RobinVncnt! - Fix "Close all" link color in the top-wallet hardware carousel small cards to match the muted gray used elsewhere on the screen
- #20589
bad0305Thanks @sarneijim! - Add the Lazy Onboarding Tour drawer to the lazy onboarding banner, with updated banner/tour copy and imagery
- #20751
7ed4ee1Thanks @sarneijim! - Refresh lazy onboarding tour slide assets, follow app theme in the tour drawer, and track banner press/dismiss.
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.
- #20743
ac097e6Thanks @VicAlbr! - Fix scroll targeting and silent failures in the Ledger Wallet Mobile E2E suite: target leaf rows
instead of viewport-tall wrappers so assertions reach the default 75% visibility honestly, delete the visibilityPercentage parameter so no site can lower the gate, name the scroll container at every call site that used to let the engine guess one, replace the unexplained pixel steps with the default, count rows by existence rather than by what fits the screen, log the scroll errors scrollOnce used to swallow and correct its "bottom" fallback direction, make the isIdVisible/isIdPresent probes index-safe so a shared id stops being reported as invisible, and assert visibility where the suite previously only proved an element existed in the tree. On the app side, the accounts list scrollable now carries a stable accounts-list testID instead of one keyed on the account count.
- #19581
6a437fdThanks @Moustafa-Koterba! - feat(lwdm): improve error context on datadog
- #20750
352c6a3Thanks @francois-guerin-ledger! - chore(coin-evm): movegetDefaultFeeUnitandgetMessagePropertiesto llc
- #20806
eb4d29eThanks @mcayuelas-ledger! - Drop the redundantPayCardprefix from the public API of@features/flow-pay-card-balance. The package path already scopes the feature, matching sibling flows (FeatureTour,CardLogin). The hero is now exported asBalance, withuseBalanceData,aggregateBalance,buildBalanceDataandBalance*types.
- #20642
a61f702Thanks @mcayuelas-ledger! - Persist the pay card hero balance filter across app restarts
- #20755
e291645Thanks @mcayuelas-ledger! - Add the mobile stable balance filter (native select under the hero + queued bottom-sheet picker) and share the filter option and stablecoin logic between desktop and mobile
- #20096
e54d98bThanks @liviuciulinaru! - Integrate the Card API and give its endpoints a domain owner
@domain/api-card-management gains the Card Auth contract: authorize initiation, authorization-code exchange, session refresh, logout and the user read, with their zod wire schemas and inferred types. They inject into the shared cardApi service, so one reducer, one middleware and one cache serve the Card backend, and the base query supplies the base URL, x-client-key and the Authorization: Bearer header from the @features/platform-card session.
@features/flow-pay-card-auth owns no network contract any more. It keeps the auth-only payCardAuth slice and the CardLogin component; useCardLoginViewModel imports its hook from @domain/api-card-management, and that import is what triggers the injection. @domain/api-pay-card

