github LedgerHQ/ledger-live live-mobile@4.19.0

3 hours ago

4.19.0

Minor Changes

  • #21092 dd9fe60 Thanks @tonykhaov! - Add the native Pay Request receive stack screen (close, QR, share, copy, verify).

  • #20818 f9be984 Thanks @beths-ledger! - Emit earn_transaction_completed / earn_transaction_failed for native staking, from the account-bridge seam.

    Every transaction route resolves its bridge through getAccountBridge, so wrapAccountBridge — which already hosts the sanctioned-address check — is the one place that sees them all. It now decorates signOperation (emitting a classified failure, then re-raising the original error untouched) and broadcast (success or classified failure). The device-action layer adds the one signal the bridge cannot see: closing the sign prompt is an unsubscribe rather than an error, so abandonment is reported from there.

    This replaces UI-inferred bottom-of-funnel tracking for staking, where a user reaching the final screen was counted as converted whether or not a transaction ever landed. No analytics event is produced for non-staking transactions. The seam observes every sign and broadcast outcome, and the Segment mapping is what drops the ones with no derived staking action — so plain sends and swaps reach no analytics sink, and no currency allowlist is needed.

    Desktop and mobile each register a Segment observer at startup; track already self-gates on analytics consent. Desktop also registers a dev-only console observer so the whole seam can be watched locally across every staking route and coin. The existing Datadog useBroadcast path is untouched.

  • #20973 7d02f4b Thanks @claudiiafg! - Fix mobile bottom sheets that could not be reopened after being closed.

  • #21151 545e419 Thanks @claudiiafg! - Fix the odd Add contact transition on Mobile by focusing the contact name field only once the drawer has finished opening, so the keyboard no longer resizes the dynamically sized drawer mid-animation. Adds an onOpened callback to QueuedBottomSheet and makes ContactNameInput focus reactively rather than only on mount.

  • #21234 7fae8f5 Thanks @claudiiafg! - Fix the keyboard flickering open and shut on the Mobile edit contact drawer, which focused its name field as soon as it mounted and so raised the keyboard into a drawer that was still animating. The field now waits for its drawer to settle before taking focus, as the add contact drawer already did, and focus is opt-in so no other drawer can raise the keyboard by accident.

    Also give the add contact, edit contact and Send add new contact drawers the same keyboard clearance as the add address and edit address drawers, so every contact drawer leaves the same gap above the keyboard on iOS instead of sitting flush against it.

  • #21164 a2be85c Thanks @tonykhaov! - Wire Pay Request Verify on mobile (intro sheet, DIE address confirmation, tracking).
    Share getAddressVerification (maps refuse / unsupported) in the platform intent package.

  • #21156 5820213 Thanks @vpenskyi-ledger! - Refactor account.request cancel-navigation out of useUiHook and fix premature cancel in the inline add-account flow.

    Refactor (LIVE-36323): Remove host-specific shouldGoBackOnCancelRef from useUiHook. Expose plain onAccountRequestCancel / onAccountRequestSuccess callbacks instead. Exchange and Buy host screens now own the one-shot dismiss rule directly (shouldGoBackRef in PTX/index.tsx), eliminating the goBackOnAccountRequestCancel boolean→string→boolean round-trip through inputs.

    Bug fix (flagged by Earn team): Since 6f1e402, closeDrawer fired onCancel immediately when the user tapped "Add Account" in the modular drawer, breaking Earn's inline add-account flow. Introduce hideModularDrawer — a Redux action that sets isOpen = false without clearing callbackId or cancelCallbackId. The navigate-to-device step uses this silent hide so account.request stays pending. The real cancel still fires via onCloseNavigation if the user abandons the device flow.

  • #21243 2e92399 Thanks @henri-ly! - Show the Contacts feature introduction in the new Send flow recipient step, for currency families eligible to the address book when the contacts feature flag is on and the user has not dismissed it yet.

  • #21162 dff2a65 Thanks @sarneijim! - Add missing Touchscreen Upgrade Program tracking for Backup Hub Recovery Key upsell and Lazy Onboarding Banner (LIVE-36494)

  • #21098 0f71eeb Thanks @gre-ledger! - Upgrade rsbuild to 2.1.13, rspack to 2.1.10, and rslib to 0.23.2

  • #21348 46f41d2 Thanks @deepyjr! - Update the Contacts feature introduction image and English copy, and remove its description field from the shared contract.

  • #21244 f4986f8 Thanks @mcayuelas-ledger! - Show a host-provided Crypto card title on the Pay Card web and native views

  • #21150 61dc07a Thanks @deepyjr! - Refresh countervalues when the mobile app resumes or reconnects

  • #21113 a6e4ace Thanks @dilaouid! - feat(send): add a contact from an address in the send flow

  • #21363 ce47443 Thanks @liviuciulinaru! - Read CARD_API_URL and CARD_BAANX_CLIENT_KEY on every use, and not one time at boot. The debug settings can now change the Card tenant without a restart. The mobile app also applies its .env values before the store reads them.

  • #20117 6780db0 Thanks @shazzzam! - Celo: show a clear "temporarily unavailable" message when voting is blocked during on-chain epoch processing, instead of a generic "RPC request failed" error

  • #21235 7ae6040 Thanks @deepyjr! - Add explicit close controls to Contacts address entry forms on mobile.

  • #21220 bb44e2c Thanks @OlivierFreyssinet! - Move the Contacts device intent renderers into the apps.

    @features/platform-contacts/device/intents now exports component-less
    IntentDefinitions. Each app owns its renderers under
    src/mvvm/features/Contacts/deviceIntents/, composes them into
    IntentPlatformDefinitions and injects them into useContactsIntentsOrchestrator,
    which no longer imports a production intent implementation.

    A features/ package cannot resolve translations today, so a renderer that shows
    translated copy has to live in the app.

  • #21128 31223eb Thanks @OlivierFreyssinet! - Orchestrate Contacts device confirmations through the Device Intent Executor.

  • #21236 c62986b Thanks @OlivierFreyssinet! - Register an external address on the device from Contacts. The device intent now calls @ledgerhq/device-contacts-kit's ContactsManager.registerExternalAddress(), each failure gets its own JobState (app version too low, invalid input, device rejected, existing-group verification failed, unsupported operation, device error), 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.

  • #21185 cef29a0 Thanks @OlivierFreyssinet! - Add shared Contacts kit wiring: version-requirement wrappers over @ledgerhq/device-contacts-kit, composed with each app's app-global floor into the Contacts device intents' minimum app-version floor.

  • #21226 a2360f0 Thanks @sarneijim! - Add QA device simulation dev tool in Debug > Configuration (LIVE-33169)

  • #21222 fcdac1c Thanks @gre-ledger! - Wire Env, Trustchain and Cloud Sync devtools into LLD and web-tools; wire Env devtool into LLM.

  • #21142 a51303c Thanks @dilaouid! - feat(send): add a contact from an address in the send flow on lwm

  • #21089 803c2db Thanks @Valentin-Ledger! - Add earn/simulate deeplink to open the rewards simulator

  • #21085 60c41bd Thanks @deepyjr! - Fix Contacts address drawers so the confirm button stays visible above the keyboard on Android

  • #21347 b3a86f5 Thanks @mcayuelas-ledger! - Move Pay balance/action-tile copy resolution into @features/flow-pay-balance via @shared/i18n so hosts no longer pass translated labels.

  • #21014 e1c2a4b Thanks @mcayuelas-ledger! - Fix Pay tab bottom sheets so the filter opens expanded and deposit options stay fully visible

  • #21117 1190ce1 Thanks @Sebastien-Dav1d! - Declares expo-document-picker as an optional peer dependency (and devDependency) in @devtools/feature-flags, removing it from regular dependencies. Adds it as a direct dependency in ledger-live-mobile so autolinking resolves correctly on the native side.

  • #21190 aafcdb7 Thanks @vtaranushenko-ext-ledger! - Preserve transferId through the generic adapter for Casper

  • #21138 c804d67 Thanks @dilaouid! - fix(lwm): fix tracking filter for the new send flow

  • #21142 11a1e34 Thanks @dilaouid! - feat(send): add address to an existing account in the send

  • #21306 40f6c6d Thanks @alexstapenka-ledger! - Fix Earn inline add-account: resolve account.request before popping the stack, so Wallet API success is not ignored after a premature cancel.

  • #21287 34fc080 Thanks @mcayuelas-ledger! - Order Pay contacts by last sent-to, then last added, derived at read time from account OUT operations

  • #21209 a334296 Thanks @mcayuelas-ledger! - Wire the Pay contacts empty state to the shared Add contact dialog, Ledger Sync gate, and a host-injected createContactCreationPort.

  • #21208 1b789dc Thanks @amaslakov! - Celo: add USAT (Tether America USD) to the fee currencies that can be selected to pay gas

  • #21126 6c97b3f Thanks @RobinVncnt! - Stack the LNS upsell banner above the hardware carousel instead of squeezing it into a tile slot, share a carousel with action cards only on mobile, and stop the Content Cards QA console from collapsing every Top wallet preset into the "alwayson" category

  • #20931 75711a2 Thanks @VicAlbr! - Split the Ledger Wallet Mobile Ledger Sync E2E test into five suites, one per Xray ticket, each
    booting the app already a member of a freshly created trustchain and destroying it afterwards. The
    mobile suite now shares the Ledger Sync CLI layer from live-e2e-shared instead of keeping a
    near-verbatim copy, and a TrustchainPage asserts trustchain contents through the CLI. On the app
    side this adds a Detox-only importTrustchain bridge message so a test can pre-seed the trustchain,
    and testIDs on the TinyCard CTA and the manage-instances row so the synchronized instances list is
    reachable from tests — the card's testID sat on a non-touchable container, so taps on it did nothing.

    Also fixes addAccountAtIndex, which cleared the selection whenever exactly one account was
    discovered: it tapped "deselect all" only for multiple accounts but tapped the account row
    unconditionally, and a lone account arrives already selected, so Confirm was disabled and account
    discovery timed out.

  • #21175 911a996 Thanks @tonykhaov! - Show Pay action tiles in every hero state (LIVE-36422).

  • #21099 c8614bf Thanks @mcayuelas-ledger! - Add @features/flow-pay-card, a Contacts-style orchestrator that aggregates the Pay Card leaf flows behind a single Card entry point. It follows the app MVVM split — a Card container wires a shared useCardViewModel to the platform CardView — and composes the card face from @features/flow-pay-card-details (CardVisual with the balance overlay, or the bare CardArtwork) with the authentication controls (CardLogin / CardLogout from @features/flow-pay-card-auth), each of which still decides on its own whether it belongs on screen.

    The flow owns the (currently mocked) card balance and assembles the overlay itself, so hosts no longer pass a pre-built visual: they hand over only what they alone know — formatCountervalue (needs the app's locale and counter-value currency) and balanceLabel (i18n). Both apps now mount Card instead of wiring CardLogin / CardLogout directly: desktop in the Pay tab's right panel, mobile in the Pay tab body. The package composes rather than re-exports: apps that need a single leaf or its Redux state (@features/flow-pay-card-auth/state) keep importing that leaf directly.

  • #21281 3ff0cde Thanks @mcayuelas-ledger! - Cap the mobile Pay contacts strip at 8 and add a see-all control that opens the Contacts flow with a "Pay contact" page title.

  • #21144 62008f0 Thanks @tonykhaov! - Keep Pay hero empty vs funded from cached holdings; skeleton the amount only when funded (LIVE-36422).

  • #21227 d278ab7 Thanks @tonykhaov! - Fix Pay Request crash when the selected token is not yet a sub-account.

  • #21118 6f8acaf Thanks @tonykhaov! - Share the Pay request card as a PNG from the native Share action

  • #21242 3b3c696 Thanks @dilaouid! - feat(send): add to an existing contact in send flow lwm

  • #21284 6cef6b5 Thanks @benruseau! - Add an OS updates orchestrator playground in Developer settings

  • #21266 9faeaf8 Thanks @mcayuelas-ledger! - Rename the request receive save helpers and the summary test id to drop their redundant "card" suffix

  • #21288 95fae8f Thanks @mcayuelas-ledger! - Add a "Load contacts from send history" generator to the mobile Contacts devtool

  • #21324 1b3e5ad Thanks @deepyjr! - Explain unavailable assets and networks in Contacts currency selection

  • #21217 7a1a622 Thanks @mcayuelas-ledger! - Show the Card screen background on the Pay tab

  • #21145 5bcc7f1 Thanks @tonykhaov! - Rename the Pay request flow package from @features/flow-pay-card-request to @features/flow-pay-request.

  • #21139 848b4bd Thanks @OlivierFreyssinet! - Move the InfoState component (and its web-only dialog background tone plumbing) out of ledger-live-desktop and live-mobile into a new shared package, @shared/ui-info-state, so it can be reused in the DDD architecture

  • #21177 6f4814b Thanks @claudiiafg! - Fix the mobile Contacts edit address sheet staying hidden behind the keyboard, and retract the keyboard when a bottom sheet starts closing so the sheet can be reopened afterwards.

  • #20935 27388a8 Thanks @dilaouid! - Move Solana staking onto the generic StakingResources account attribute.

    Breaking for @ledgerhq/coin-solana. SolanaResources, SolanaResourcesRaw, toSolanaResourcesRaw and fromSolanaResourcesRaw are gone. SolanaAccount is now an alias of StakingAccount, so read staking data from account.stakingResources instead of account.solanaResources. A stake is a StakingDelegation or a StakingUnbonding (SolanaStakingPosition) rather than a SolanaStake: its stake account address is positionId, its validator is validatorAddress, and the former activation.active / activation.inactive / withdrawable fields are activeAmount / inactiveAmount / withdrawableAmount. listSolanaStakingPositions, solanaActivationState and stakeActions from @ledgerhq/coin-solana/logic cover the common access patterns. Accounts already persisted with a solanaResources blob are migrated on hydration, so no resync is needed.

    @ledgerhq/types-live gains StakingPositionDetails, mixed into StakingDelegation and StakingUnbonding for chains that materialize each position as its own on-chain account, plus actionFeeReserve on StakingResources. Both are optional, so other chains are unaffected.

    @ledgerhq/wallet-cli's earn positions output changes shape: on EarnSolanaStake, stakeBalance and withdrawable go from number to an integer decimal string, so lamport amounts above Number.MAX_SAFE_INTEGER stay exact. Anything reading those two fields numerically needs updating.

    @ledgerhq/ledger-wallet-framework now exports the generic StakingResources serializer (toStakingResourcesRaw, fromStakingResourcesRaw, assignStakingResourcesToAccountRaw, assignStakingResourcesFromAccountRaw), moved out of the EVM family in live-common so every coin module can use it.

  • #21131 09af9b1 Thanks @mcayuelas-ledger! - Rename the Pay flow packages to drop the redundant card segment: @features/flow-pay-card-balance@features/flow-pay-balance, @features/flow-pay-card-deposit@features/flow-pay-deposit, and @features/flow-pay-card-feature-tour@features/flow-pay-feature-tour. Package paths, npm names and all imports are updated; persisted Redux state keys and component test IDs are unchanged.

  • #21258 ad1c0ff Thanks @mcayuelas-ledger! - Add the contacts section to the Pay tab, with a leading Pay tile opening the send flow. Balance, Contacts and Card now share a s24 gap and inherit their horizontal padding from the Pay tab container.

  • #21265 5b78670 Thanks @gre-ledger! - Add @shared/i18n, a thin i18n context bridge so features/* and domain/* components can call useTranslation() and render <Trans> instead of receiving translated strings as props.

    Both apps now build their i18next engine with an explicit createInstance() rather than the global singleton, and mount <I18nProvider> at their root alongside the existing <I18nextProvider>. Non-React call sites import the app instance (~/renderer/i18n/init on Desktop, ~/i18n/instance on Mobile) instead of i18next, enforced by a lint rule.

    @features/flow-pay-feature-tour is the pilot: it resolves its own payTab.featureTour.* copy and no longer takes any copy props.

  • #21132 6cc7ac6 Thanks @dilaouid! - chore(send): remove addressBook property from the coin descriptor

  • #21188 c8bb138 Thanks @Moustafa-Koterba! - feat(lwdm): ask ledger sync on add contact

  • #21291 d6b6687 Thanks @deepyjr! - Fix the QR scanner opening animation on mobile.

  • #21130 45eddc1 Thanks @jiyuzhuang! - Fix welcome screen story flicker: keep the stepper from snapping full before video durations load, rewind each story when it ends and when it comes on stage, and make the stepper follow playback even when the system asks for reduced motion

  • #21152 116f006 Thanks @alexstapenka-ledger! - Add the stableSavings feature flag, forward it to Earn on initial load, and send it to Mixpanel as a boolean identify trait on desktop and mobile.

  • #21005 99533b3 Thanks @jiyuzhuang! - Wire mobile Braze consent toggles to the identity lifecycle

  • #21097 65d468b Thanks @sarneijim! - Open the Ledger Recover deeplink instead of the intro bottom sheet when tapping Ledger Recover in the Backup hub

  • #21141 e2f2cfa Thanks @OlivierFreyssinet! - Migrate the DeviceActionContent component into a new @features/platform-device-action-content package so DDD flows can render it, decoupling it from the DeviceModelId enum. Also render Lumen Tag labels and Banner titles as text in the shared web/native passthrough test stubs.

    The package now exposes getDeviceActionAnimation, and both apps resolve their pin/continue device animations through it instead of keeping byte-identical copies of the same 20 Lottie files each. This drops ~2.5 MB of duplicated animation JSON from the desktop and mobile bundles.

    @features/platform-style gains useThemeVariant(), returning the active "light" | "dark" variant from the style provider both apps already mount, plus a ./hooks entry point so reading it doesn't pull the providers into a consumer's bundle. DeviceActionContent picks its animation through that hook, so neither app injects a theme any more and the component can be used from deeply nested features/ trees. It reads the styled-components context directly rather than useTheme, which throws when no provider is mounted.

  • #21270 5b9df59 Thanks @OlivierFreyssinet! - Map the DMK invalid firmware metadata error to a dedicated InvalidProvider blocking state, so the Device Intent Executor shows a clear "Invalid Provider" screen with a "Go to settings" action instead of a raw error

  • #21245 45ea28b Thanks @OlivierFreyssinet! - Provide the EVM address book to the DMK Ethereum signer, so registered contacts can be clear-signed.

    toEvmAddressBook maps the Contacts state to an EvmAddressBook snapshot, keeping EVM-family addresses only. Each app registers it on evmAddressBookProvider at its composition root, and DmkSignerEth reads it once per instance, so the recipient and the signing account are matched against the same snapshot. Records whose proof material does not decode are dropped, and signing is left untouched when no contact is usable.

    Ledger account contacts are not provided yet: the snapshot always carries an empty ledgerAccounts.

  • #21357 9f0b607 Thanks @mcayuelas-ledger! - Resolve Pay deposit-options copy inside @features/flow-pay-deposit through @shared/i18n instead of receiving translated strings as props. The deposit options view-model now calls useTranslation() for its payTab.deposit.* keys, so both apps stop building DepositOptionsLabels and passing them to useDepositOptionsAdapter.

  • #21049 27ea1f5 Thanks @dilaouid! - feat(send): select which address of a contact receives the funds in the Send recipient step

Patch Changes

  • Updated dependencies [dd9fe60, edad3fb, 0b024e8, 244454b, 7d02f4b, 545e419, 7fae8f5, a2be85c, 5e45fdd, e6d6ed6, 46f41d2, f4986f8, ce47443, 37cc17e, 9a1a1df, a4f727d, da47556, beaaa31, 83b019e, 36b7fda, a29f6a0, d4d3258, f99b720, 02c9ccf, e723d82, bb44e2c, 31223eb, c62986b, cef29a0, 0639bea, cdbc3ac, 114420e, 60c41bd, 46d23e1, b3a86f5, e1c2a4b, a8c34d0, aafcdb7, 34fc080, 41faac4, 0df32c7, a334296, 2c70999, 1ef101a, 911a996, 0500726, c8614bf, aa8f4bf, 1e0763e, 0127ebd, 3ff0cde, 62008f0, 6f8acaf, 3b3c696, 9faeaf8, 5bcc7f1, 848b4bd, 6f4814b, 27388a8, 6cef6b5, 09af9b1, ad1c0ff, c20677f, 5b78670, 1cf5583, c8bb138, 116f006, 9a3746d, e2f2cfa, 5b9df59, cf9a982, 45ea28b, f0f9990, 9f0b607, 9d5a6d9]:
    • @features/flow-pay-request@0.3.0
    • @ledgerhq/transaction-observability@0.2.0
    • @shared/ui-queued-bottom-sheet@0.2.0
    • @features/flow-contacts@0.9.0
    • @features/platform-contacts@0.5.0
    • @features/flow-contacts-add-contact@0.5.0
    • @features/flow-contacts-edit-contact@0.3.0
    • @shared/ui-info-state@0.2.0
    • @features/platform-verify-address-intent@0.3.0
    • @shared/env@0.5.0
    • @domain/entity-currency-crypto@0.11.0
    • @features/flow-contacts-introduction@1.0.0
    • @features/flow-pay-card@0.2.0
    • @shared/api-services@0.6.0
    • @ledgerhq/coin-canton@1.1.0
    • @ledgerhq/coin-casper@3.2.0
    • @ledgerhq/coin-concordium@1.1.0
    • @ledgerhq/coin-cosmos@1.1.0
    • @ledgerhq/coin-evm@5.2.0
    • @ledgerhq/coin-filecoin@2.1.0
    • @ledgerhq/coin-multiversx@1.1.0
    • @ledgerhq/coin-stacks@0.30.0
    • @features/flow-contacts-list@0.5.0
    • @features/flow-contacts-delete-contact@0.2.0
    • @features/flow-contacts-edit-address@0.2.0
    • @features/flow-contacts-add-address@0.3.0
    • @features/flow-pay-contact@0.2.0
    • @features/flow-pay-balance@0.4.0
    • @features/flow-pay-deposit@0.3.0
    • @shared/auth@0.6.0
    • @shared/cloud-sync@0.3.0
    • @shared/feature-flags@0.21.0
    • @features/platform-currencies@0.7.0
    • @domain/api-currency-token@0.6.0
    • @features/flow-pay-card-auth@0.5.0
    • @ledgerhq/types-live@6.122.0
    • @ledgerhq/ledger-wallet-framework@3.2.0
    • @ledgerhq/live-dmk-shared@0.32.0
    • @features/flow-pay-feature-tour@0.4.0
    • @devtools/bindings@0.6.0
    • @shared/i18n@0.2.0
    • @features/platform-device-action-content@0.2.0
    • @features/platform-style@0.3.0
    • @ledgerhq/live-signer-evm@0.23.0
    • @features/platform-device-intent@5.2.0
    • @domain/api-aggregated-assets@0.4.2
    • @features/platform-aggregated-assets@0.5.1
    • @features/platform-env@0.2.3
    • @ledgerhq/ledger-key-ring-protocol@0.21.1
    • @ledgerhq/live-dmk-mobile@0.29.6
    • @ledgerhq/live-dmk-speculos@0.10.7
    • @ledgerhq/wallet-analytics@0.3.6
    • @ledgerhq/wallet-pnl@0.7.9
    • @domain/entity-contact@0.8.1
    • @domain/entity-currency@0.4.2
    • @domain/entity-currency-token@0.5.1
    • @ledgerhq/coin-bitcoin@0.51.3
    • @ledgerhq/live-currency-format@0.14.3
    • @ledgerhq/live-wallet@1.1.1
    • @domain/api-altcoins-sentiment@0.3.4
    • @domain/api-currency-fiat@0.4.3
    • @domain/api-market-sentiment@0.3.4
    • @domain/api-push-devices@0.2.4
    • @domain/entity-account-name@0.2.2
    • @domain/entity-recent-addresses@0.2.1
    • @features/platform-wallet-sync@0.1.3
    • @features/flow-large-screen-upsell@2.0.1
    • @features/platform-feature-flags@0.6.8
    • @domain/entity-analytics-consent@0.2.2
    • @features/flow-app-lock@0.2.0
    • @features/platform-card@0.3.1
    • @ledgerhq/device-core@0.11.14
    • @ledgerhq/domain-service@1.8.17
    • @ledgerhq/live-countervalues@0.24.5
    • @ledgerhq/live-countervalues-react@0.16.9
    • @devtools/shell@0.9.1
    • @features/flow-analytics-consent@0.2.4

Don't miss a new ledger-live release

NewReleases is sending notifications on new releases.