github LedgerHQ/ledger-live live-mobile@4.23.0

4 hours ago

4.23.0

Minor Changes

  • #22217 63960b1 Thanks @vpenskyi-ledger! - Fix the Swap receive field staying empty when reaching Swap from the Earn no-funds screen. Desktop now always identifies a token by toTokenId (plus its toToken alias), which toCurrencyId alone could not do; mobile passed no parameters at all and now forwards the asset. On both, an account the Earn live app synthesised for a token the user does not hold is no longer sent as an unresolvable id

  • #22404 b42673e Thanks @philipptpunkt! - Read the card cashback banner from GET /v1/card/cashback

    • Add getCardCashback endpoint, resolving the asset's currency/network pair (both nullable) to its ledgerId
    • Remove getRewardWallet (GET /v1/wallet/reward), its schema, types, mock and handlers
    • useCardCashback replaces useCardRewardWallet in the reward banner
    • Banner subtitle now shows the rate and ticker: "Total cashback · 1% in BTC"
    • cardRewardsAvailable / cardRewardCurrency analytics now read the cashback (amount > 0)
  • #22450 2d869a5 Thanks @LucasWerey! - fix(i18n): keep Thai selected across app restarts

    Removes the llmThai / lldThai feature flags. Flags resolve on their enabled: false default
    until the first remote fetch settles, so on every cold start the locale guard saw Thai as
    unsupported and persisted English over the user's choice.

  • #22667 d90780a Thanks @LucasWerey! - Fix the receive screen "Need a Tag/Memo?" link hit area overlapping the Copy address button (LIVE-38004).

  • #22840 e4c24f3 Thanks @LucasWerey! - Name the default Me contact "Me" in the Pay tab contacts list instead of "My addresses (Me)"

  • #22401 b239a21 Thanks @dilaouid! - fix(lwm): object in operation extra malformatted

  • #22381 c5964f8 Thanks @ysitbon! - Rename @domain/api-market-sentiment to @domain/api-market-index-fear-and-greed, and its exported api from marketSentimentApi to fearAndGreedApi, so the name states which CoinMarketCap index the package serves

  • #22453 370f955 Thanks @LucasWerey! - Track the add-password flow through @shared/analytics, per the Password tracking plan.

    The protection drawer reports its enable button as button_clicked with the variant it offers, and a stored password reports encryption_activated with type: "password" and the entry point it came from. That source is passed by each caller — settings from the Settings row, card from the Pay tab — and carried through the flow's route params instead of being guessed from where the user happens to be. password_enabled and biometrics_enabled join every event and the user's traits, read from whichever scheme protects the app, and the traits are refreshed as soon as a password is stored. No payload carries the password or anything derived from it.

    The Settings password and biometrics toggles report toggle_clicked with enabled set to the state the toggle had when it was tapped, on both the revamped and the legacy rows, and the revamped rows now track through @shared/analytics too.

  • #22629 5f20e00 Thanks @LucasWerey! - Lock the app only after it has been away for 15 seconds.

    The gate used to lock the moment the app left. It now notes when the app leaves and decides when it comes back: away for 15 seconds or more, the app locks; back sooner, it opens where the user left it. The lock on launch is unchanged, so an app the system ended while away still asks on the way back.

    While the app is away, protected content is covered, so the app switcher and the moment of return show a cover rather than the wallet. Under Detox the grace is one second, so e2e specs do not wait out the real one. On Android the return comes from the process lifecycle, like the departure, through a new appDidEnterForeground event on AppVisibilityModule; on iOS it is AppState turning active.

  • #22287 5f34cb6 Thanks @LucasWerey! - Stop a card holder from leaving the app with nothing protecting it.

    Both protection rows in Settings let anyone turn protection off, so someone holding a card could strip the app of its last lock. Without a card that stays allowed — the app lock is opt-in — but a card turns "at least one protection" into a rule.

    Removing the last one is now refused, and a sheet says why at the moment the user asks, rather than a disabled row that explains nothing. Removing one of two is still allowed: at least one protection is the invariant, and which one is the user's choice — so a password can still be swapped for biometrics, or the reverse.

    What counts as holding a card is the card session stored on the device, which @features/platform-card owns — not Pay's feature flag, and not whether the Pay tab has been opened. A holder who has not been near Pay on this launch is still a holder, and turning Pay's flag off does not turn the rule off. The session is read when the user asks to remove a protection, not when Settings opens, so a tap can never land before the answer, and a session that started or ended with Settings open is seen. A session that cannot be read counts as a card: a refusal can be retried, while a removal cannot be taken back.

    The rule applies to the revamped rows. The legacy rows shown while lwmPasswordRevamp is off are left as they are.

  • #22347 e012138 Thanks @LucasWerey! - Require a password of at least six characters from users who set a shorter one, the next time they get in.

    Any length was accepted before this epic — "1" among them — so the minimum the new screens enforce would otherwise apply to new passwords only. The prompt cannot be dismissed: there is no close button, the backdrop does not take a press, and the Android back button is swallowed while it holds the screen. A prompt that can be put off is one that short passwords outlive.

    It runs after a successful unlock, not at boot, because that is when the password has been proven and its length is known. Four steps: a sheet that says why, the new password, its confirmation, and a sheet that says it worked. The old password is never asked for again — they just typed it to get in.

    The requirement is stored, beside the verifier it describes. The protection state is deliberately not persisted, since a second source of truth about whether a password exists is a lockout risk, and this mark cannot be recomputed from a digest: a verifier says nothing about the length of the password behind it. So it rides in the same keychain record, written and cleared by the single write that sets the password it describes, and the two cannot disagree.

    It is also re-derived at every password unlock, which is what heals a record written before the mark existed, and what corrects one whose password was changed elsewhere. The stored mark still earns its place: a biometric unlock never sees a password, and the prompt is owed on that boot too.

    A write the keychain declines is reported as a failure rather than as a password change, so the confirmation holds instead of sending the user off with a verifier that is still the old one. The mark's own repair at unlock is best-effort by contrast: metadata must never cost somebody an unlock they have just earned.

    An overlay rather than a route: a route is presented over the app in its own window, and the sheets — which present into the app's window — would be visible through it while taking none of the taps aimed at them.

  • #22556 2074967 Thanks @LucasWerey! - Stop locking the app on Android for flows the app itself starts.

    Clearing the cache reboots the React tree without restarting the process, and the gate took its remount for a launch and locked again. Whether the launch lock was decided now lives in the app-lock state, which a reboot leaves in place, so it is decided once per process.

    Sharing an address or logs, or saving a file from the share sheet, hands the screen to another app, which Android reports as the app leaving. Those flows now go through leaveAppFor, which holds the background lock off until Android resumes the app. The share promise settles before the user is back, so the hold ends on the resume rather than on the promise, and at once if the task fails before anything was shown. iOS keeps its share sheet inside the app and is unaffected.

  • #22435 1647f38 Thanks @LucasWerey! - Stop locking the app behind a permission prompt on Android.

    React Native's AppState reports background on Android as soon as the activity pauses, and a permission dialog is enough to pause it, so the app lock read a prompt shown over the app as the user leaving. Granting the camera put the user back on the unlock screen instead of the camera.

    On Android, the lock now follows the process lifecycle, which only stops once no screen of the app is visible — the signal native apps use for "the app went to the background". iOS keeps AppState, whose background already means the app has left. The platform split lives in one adapter, so the gate asks a single question on both.

    isAppBackgrounded, which only the gate used, is removed from @features/platform-app-lock.

  • #22417 8b387f4 Thanks @LucasWerey! - Resume after a biometric prompt only once the app is active again, and let the enable button show it is waiting.

    On iOS the system answers the prompt while the Face ID sheet is still leaving, with the app not yet back in the foreground, and native UI presented in that window never appears. The Card login hit it first: pressing Continue straight after enabling Face ID opened no browser, and the web browser module then refused every later attempt until the app was relaunched, because it had recorded a session that never started.

    Every biometric prompt in the app now waits for the app to be active before answering, whatever the answer. The wait is bounded, so an event that never arrives cannot hold anyone up, and it does not apply to an app the user has sent to the background.

    The system prompt also leaves the app pressable, so pressing "Enable Face ID" again while it was up opened a second one. The button now shows its spinner while the prompt is pending and ignores further presses. InfoState CTAs gain a loading flag for it.

  • #22653 e8d5e1b Thanks @OlivierFreyssinet! - Bump DMK dependencies: device-management-kit 1.10.0, device-signer-kit-solana 1.13.3, device-signer-kit-ethereum 1.18.1, context-module 2.6.0, dmk-ledger-wallet 0.6.0, device-contacts-kit 0.5.0, signer-utils 1.3.0, device-transport-kit-mockserver 1.1.2

  • #22615 7bc8d65 Thanks @mcayuelas-ledger! - Open the Pay request flow from the Add stablecoin "Crypto address" option instead of the standard Receive flow

  • #22563 3e7af98 Thanks @gre-ledger! - Bump react-native-config to 1.7.2 and drop its pnpmfile peer patch

  • #21976 26e51d9 Thanks @claudiiafg! - Add mobile E2E coverage for creating a contact, registering EVM addresses on the device and deleting both, and let device intents run against Speculos by registering it as a discoverable transport. Speculos specs can now pin an OS version so the run uses the Ethereum build the contacts intents require, which the app catalog does not serve yet.

  • #22523 774877b Thanks @RobinVncnt! - Drive the shared device onboarding flow from mobile DevTools

  • #22492 d883e5b Thanks @mcayuelas-ledger! - Add 16px horizontal inset to the History crypto/card type switcher.

  • #22568 c1f5830 Thanks @tonykhaov! - Add a "Pay contact success (Me)" dev tools quick action, and use valid EVM addresses in the Me contact mock so its seeded addresses can be sent to.

  • #22470 6a5972d Thanks @liviuciulinaru! - Close the card details sheet when an asset top up opens.

  • #22319 94e86c6 Thanks @tonykhaov! - Add long-press and accessibility controls for reordering card assets, with the add-asset footer pinned to the sheet's own footer slot, a bigger drag-handle touch target, and fixes for a stuck-elevated drag row and a spinner flash on a same-position drop

  • #22379 ad2f1de Thanks @philipptpunkt! - Let the card transaction history read past its first page.

    • Both platforms read on by scrolling: native through the list's onEndReached, web through an observer on a sentinel at the end of the table.
    • A spinner marks the page in flight; no new copy, so nothing to translate.
    • Both take loadMore/isLoadingMore from the shared view model, so the three-row previews on the Pay surfaces are unaffected.
  • #22432 cfb7566 Thanks @tonykhaov! - Show the cashback a card transaction earned in its detail view

  • #22370 c2c4de5 Thanks @gre-ledger! - Replace the react-native-level-fs based fs polyfill with a stub and drop asyncstorage-down, its pnpmfile peer extension and its patch

  • #22474 1a26e59 Thanks @live-github-bot! - Update coin module dependencies (coin-evm, coin-module-framework, coin-stellar, coin-tezos) and rebuild the lockfile

  • #22572 6e76dda Thanks @tonykhaov! - ContactAvatar takes isMe and is the only avatar that formats the Me label, so a Me avatar is announced once as " (Me)". MeAvatar takes a display-ready label and is no longer exported; ME_AVATAR_URL stays exported. PaySuccessRecipient.isMe is now required.

  • #22656 486a1a4 Thanks @LucasWerey! - Only mention ENS in the contact address input placeholder for networks that support domain resolution (LIVE-38284).

  • #22527 c5cdada Thanks @qperrot! - Fix Cosmos claim rewards showing a generic loader instead of the transaction confirmation screen while signing on the device

  • #22348 f7cd861 Thanks @ysitbon! - Let asset-aggregation and wallet-analytics declare the countervalues interface they need

    Both packages only ever needed one countervalues operation, calculate, over a state they
    receive as a parameter and never inspect. They now declare that operation themselves as a
    RateLookup interface, treat the state as an opaque RateSnapshot, and drop
    @ledgerhq/live-countervalues from their dependencies entirely. The apps fill the interface
    at startup, beside the crypto-assets store and the currencies resolver.

    No caller changes: the exported signatures keep their arity and the state argument is
    assignable as before, so the 41 files consuming these two packages are untouched.

    Tests get simpler as a side effect. Mocking countervalues was a module mock reaching across a
    package boundary; it is now an injected fake passed to setRateLookup.

  • #22268 87a0aa7 Thanks @gre-ledger! - Upgrade Datadog React Native SDK to 3.7.0 (@datadog/mobile-react-native and @datadog/mobile-react-navigation). The v3 configuration is restructured into nested rumConfiguration / logsConfiguration / traceConfiguration objects; the remote llmDatadog feature-flag params (kept in the flat v2 shape) are remapped to the v3 shape at initialization, and startTrackingViews now takes a { viewNamePredicate } options object.

  • #22503 33b4952 Thanks @daniel-choinski-ledger! - Inject the Tron address book into the DMK Tron signer so Tron transactions can clear-sign saved contact names.

    Adds a generic AddressBookProvider<T> in live-dmk-shared (the EVM provider is refactored onto it), a tronAddressBookProvider instance, a pure toTronAddressBook mapper (Contact[] -> TronAddressBook, Tron-family only, no chain id, ledgerAccounts always empty), and registers the source at each app's composition root. An absent or empty book leaves signing behavior unchanged.

  • #22481 d6866e7 Thanks @mcayuelas-ledger! - adapt crypto card title to be consistent

  • #22058 f8c92f9 Thanks @alexstapenka-ledger! - Instrument the shared sign/broadcast bridge defensively and dispatch consent-independent Earn
    transaction lifecycle events for native staking and allow-listed dApps on Desktop and Mobile.

  • #22788 3699ef4 Thanks @mcayuelas-ledger! - Hide the Pay tab card and its history when the pay-tab flag's card param is false

  • #22473 03058f9 Thanks @qperrot! - Fix: update external app warning

  • #21137 8959a04 Thanks @amaslakov! - Add the Internet Computer staking and neuron management flows, the account staking banner and the staked balance footer, behind the llmIcpStaking flag

  • #22614 b4599a5 Thanks @mcayuelas-ledger! - Update the verify address next steps copy, add a third step, and size the mobile shield spot to match desktop

  • #22495 7d246d2 Thanks @dilaouid! - fix(send): retract the keyboard before the skip-memo warning opens in the new send flow LWM

  • #22290 e6c39d9 Thanks @vtaranushenko-ext-ledger! - Add aleo staking unbond flow

  • #22498 917815d Thanks @gre-ledger! - Drop the unused detox pnpmfile dependency extension

  • #22369 8475c70 Thanks @ysitbon! - refactor(domain): rename the altcoins-sentiment entity to market-index-altcoin-season

    @domain/entity-altcoins-sentiment becomes @domain/entity-market-index-altcoin-season. The
    package holds the CoinMarketCap Altcoin Season Index, so the new name puts it in a
    market-index-* namespace alongside the other CoinMarketCap index rather than using
    sentiment as a second top-level name for the same kind of thing.

    Pure rename: the exported AltcoinSeasonIndexSchema and AltcoinSeasonIndex are unchanged,
    and every call site now imports from the new specifier.

  • #22571 e3c51c5 Thanks @tonykhaov! - Show a matched Me contact as " (Me)" in Send: the recipient card, the "Address matched" row, the amount step "To" header, the Pay success title and the History counterparty. MatchedContact and RecipientHeaderContact now carry isMe, and RecipientHeaderPresentation.label is renamed recipientDisplayValue and never holds a contact name.

  • #22409 632b767 Thanks @martijnhjk! - Start the mobile app with an injected Card session for local development and E2E. CARD_SESSION_BOOTSTRAP takes a PayCardSession as JSON: Detox passes it as a launch argument, and Metro local reads process.env only in __DEV__. A Detox launch with no payload clears any leftover keychain session so a no-card run cannot inherit the previous one. Keeping it out of @shared/env and committed .env files keeps the bearer token out of getAllEnvs() and out of the shipped artifact. The app seeds cardSession and marks signed in when the build is development or launched with DETOX.

  • #22534 db76f12 Thanks @ysitbon! - fix(feature-flags): wait for the flag cache before the first render

    LedgerStoreProvider now waits for the feature-flags cache read, in parallel with the storage
    reads it already awaits, before flipping ready. Providers rendered above WaitForAppReady used
    to mount on the compiled defaults when they won the race against the cache, which is how a
    flag-gated language could be persisted back to English.

    A feature-flags re-resolution that throws at boot is now reported, with console.error and an
    explicit DdRum.addError, since it happens before Datadog starts intercepting console errors.

  • #22570 dfd53ad Thanks @tonykhaov! - Show the Me contact as " (Me)", or "My addresses (Me)" when it was never renamed, through one rule: formatContactDisplayName, wrapped by useContactDisplayName. It replaces createMeDisplayNameFormatter, resolveMeContactDisplayName, identityFormatMeDisplayName and every formatMeDisplayName label. Contact list items keep the raw name plus isMe, and rows render through the hook. Fixes the Me name in the Send recipient list, Pay contacts, the History scope and the address dialog. The Me address picker says "Select my address". Adds @features/platform-contacts/testing.

  • #22512 c63d0fa Thanks @tonykhaov! - Always show Me in the Send recipient contact list, with only its addresses on the account network, ordered like the other contacts (last sent to first). Draw Me with one MeAvatar everywhere: ContactAvatar renders it for the Me contact, so the meAvatarSrc, avatarSrc and isMe avatar props are gone.

  • #22573 9e54487 Thanks @tonykhaov! - Add useOtherContactsAddresses(excludeContactId?) so the duplicate-address list is built in one place, with each owner's display name: "This address is already used for My addresses (Me)." It replaces five copies in the Contacts and Send view models.

  • #22321 83fac3e Thanks @philipptpunkt! - Read the Pay Card transaction history one page at a time.

    • getCardTransactions is an infinite query; useGetCardTransactionsQuery becomes useGetCardTransactionsInfiniteQuery.
    • page moves off the filters onto the query's page param, so PayCardTransactionsRequest is filters only.
    • The provider answers a page past the end with an empty array, so an empty page ends the reading. No page size is documented, so a short page is read past at the cost of one further request.
    • A failure over pages already read no longer blanks the list — a later page or a failed refresh alike. Such a failure is not announced anywhere yet.
    • useCardTransactionsViewModel exposes loadMore and isLoadingMore; no surface calls them yet.
    • The joined list is ordered by dateTime, newest first, with repeats dropped, because a charge landing between two reads shifts the paging. The ordering applies to callers that only ever read one page.
    • toPayGlobalProperties takes hasCardTransactions: boolean in place of the transaction list, so analytics reads the first page through hasCardTransactions rather than joining the cached history on every track().
    • loadMore is not offered once a read has failed, so a scroll-driven caller cannot turn one failure into a request loop.
    • The MSW mock pages, and its page size drops from the 10 #22236 sliced at to 6 — 10 exceeded the eight-charge fixture, so that mock never paged.
  • #22303 0cb7653 Thanks @mcayuelas-ledger! - Attach Pay Mixpanel user properties when the Pay flag is on.

  • #22577 b6a9b53 Thanks @mcayuelas-ledger! - Fix Pay analytics events that never reached Segment, and align the feature-intro page names.

    Pay tracking no longer travels through a React context: @features/platform-pay-analytics exposes
    module-level trackers built on @shared/analytics, and every Pay flow imports the one it needs.
    The provider could not be reached from inside @gorhom/bottom-sheet portals on mobile, so the card
    details sheet and the reward-currencies CTA silently dropped their events. The onTrackEvent prop
    is gone from every Pay flow package and from both host apps.

    Card milestone events are now planned from a first-read baseline, so they no longer replay on each
    login. Feature-intro pages report as Page Feature Intro <flow>, and the bank transfer flow is
    named Cash to stable instead of C2S.

  • #22592 46f0f94 Thanks @mcayuelas-ledger! - Show a dedicated empty and error state in Pay card assets and hide Manage until the list is ready.

  • #22545 ea90542 Thanks @liviuciulinaru! - feat(pay-card): show every login error in a retryable panel

  • #22535 e8518d7 Thanks @LucasWerey! - Wait for the app to be active before opening the Card's secure browser, instead of after every biometric prompt.

    A Dynamic Island plays Face ID's success animation for about 2.5 seconds after the system has answered, and the app stays inactive throughout. An ASWebAuthenticationSession started in that window never appears, and the web browser module then refuses every later session as one already open, so the login button kept spinning until the app was relaunched.

    The wait for the app to be active now sits in openHostedUrlInSecureBrowser, right before the session starts, and resolves on the app's active event, bounded at five seconds against a lost event. A biometric prompt answers straight away again, so the "Face ID enabled" sheet shows while the island is still animating and the wait overlaps the time spent reading it, rather than adding to it. The app's prompt wrapper is removed.

  • #22391 99449b1 Thanks @mcayuelas-ledger! - Share one hosted-page opener on the Pay Tab card.

    • Bind PIN, Baanx, order-card, add-asset, and asset top-up/withdraw through a single helper.
    • Pass host card props through to @features/flow-pay-card instead of listing each field.
  • #22328 41eca65 Thanks @liviuciulinaru! - Open top-up in the legacy cl-card live app when the new legacyTopUp param of lwdPayTab or lwmPayTab is on.

  • #22293 912b087 Thanks @liviuciulinaru! - Keep the aspect ratio of the login intro hero image and theme the desktop row icons

  • #22546 defb949 Thanks @liviuciulinaru! - fix(pay-card): keep the card visible, with a loading balance, while the session resolves

  • #22359 8c8defd Thanks @liviuciulinaru! - Open every Baanx hosted page on the card manifest in the Discover webview, as desktop does, instead of the secure browser.

  • #22414 9e0d43d Thanks @liviuciulinaru! - Open only the top-up page in the Discover webview; send the other hosted pages back to the secure browser.

  • #22469 5957a79 Thanks @liviuciulinaru! - Open withdraw like top-up: in the Discover webview, or in the legacy cl-card app when legacyTopUp is on.

  • #22682 f678cbd Thanks @tonykhaov! - Mention Monavate instead of Baanx in the Pay card add asset and withdraw copy.

  • #22908 23ee31c Thanks @tonykhaov! - Pay card login: name Monavate instead of Baanx in "Log in to" and "Card provided by".

  • #22446 3d41eab Thanks @mcayuelas-ledger! - Open the hosted cashback page from the Pay card reward banner

  • #22353 ae229f2 Thanks @philipptpunkt! - Show a counter-value on the card rewards banner.

    • The reward wallet now carries the currency it is denominated in, like a linked wallet does.
    • The banner prices it with the host's rates and leads with the counter-value.
    • The amount is formatted as a token, not as fiat.
    • A reward nothing can price shows the asset amount alone.
    • priceWallet is renamed getCounterValue: it converts an amount, it does not price a wallet.
  • #22424 3fdebf4 Thanks @mcayuelas-ledger! - Refetch card wallet status when returning from Apple or Google Pay so the add-to-wallet CTA can hide.

  • #22241 3b95cbb Thanks @tonykhaov! - Include the Me contact in Pay contact strips and contact selection, keeping the existing order.

  • #22358 973a613 Thanks @mcayuelas-ledger! - Show a Pay disclaimer at the bottom of the desktop Card panel and the mobile Pay tab.

  • #22440 a39ba90 Thanks @mcayuelas-ledger! - Fix remaining Pay Mixpanel events and user properties from the tracking plan

  • #22479 b809e60 Thanks @tonykhaov! - Open the stablecoin Send flow from the Pay New tile. Going back from amount after picking a contact shows the full contact list instead of a prefilled search.

  • #22240 b2c3742 Thanks @tonykhaov! - Show an empty-search state in Pay contact selection and dismiss the keyboard before opening a contact.

  • #22427 b9742c4 Thanks @mcayuelas-ledger! - Drop brackets around the recipient name on the Pay send confirmation screen.

  • #22889 fe55ea3 Thanks @mcayuelas-ledger! - Add feature-flag scenarios for the native Pay card, Card live app login, and CL Card disclaimer

  • #22402 dccea32 Thanks @mcayuelas-ledger! - Polish the Pay tab: keep the last row of every Pay bottom sheet clear of the Android navigation bar and the iOS home indicator, size the card action buttons to md, make the desktop contacts table responsive with a wider name column, wrap the address-picker title, add 32px of scroll padding, widen the history tabs, fix the disclaimer copy and use the shield icon on verify address

  • #22478 006991d Thanks @tonykhaov! - Align the Pay tab with the Home screen: its background fades out on scroll, and the balance and action tiles use the same hero spacing as Home. The Home, Pay, Swap and Earn tabs now share one Reanimated-based background.

  • #22031 f28215d Thanks @ooke-ledger! - Reserve height for the Perps deposit quoted-amount and status rows so the form no longer jumps when switching between the provider notice, the quote, and the error message

  • #22033 db7b972 Thanks @ooke-ledger! - Keep the entered Perps deposit amount when switching the funding asset/account instead of resetting it

  • #22488 1302bc7 Thanks @LL782! - Replace mutable analytics screen refs with a function-only tracking-page API.

  • #22550 86dbc48 Thanks @alexstapenka-ledger! - Add the ptxEarnCtaOnMobile feature flag and send it to Mixpanel as a boolean identify trait. Earn reads it via Wallet API.

  • #22549 24e881b Thanks @mcayuelas-ledger! - Hide Pay and card history amounts when discreet mode is enabled, and toggle it from the Pay balance

  • #22501 909c761 Thanks @LucasWerey! - Fix a bottom sheet reopening right after being swiped down before its entrance animation finished. Only a dismissal started for a previous presentation now puts the sheet back on screen.

  • #22767 8947c0b Thanks @mcayuelas-ledger! - Show a setup state on the History card tab when the signed-in holder has not claimed a card yet.

  • #22562 b8a4056 Thanks @philipptpunkt! - Keep re-reading the Pay Card status after the holder returns from Apple or Google Wallet, and when the app comes back to the foreground

  • #22543 f13b830 Thanks @gre-ledger! - Drop unmaintained rn-fetch-blob dependency, use expo-file-system for exporting logs

  • #22498 2a2cee9 Thanks @gre-ledger! - Replace react-native-easy-markdown with @ronradtke/react-native-markdown-display

  • #22378 87de096 Thanks @ysitbon! - refactor(domain): rename @domain/api-altcoins-sentiment to @domain/api-market-index-altcoin-season

    The package wraps one specific CoinMarketCap product, the Altcoin Season Index, so the old name
    used sentiment as a top-level leaf for something that measures capital rotation rather than
    sentiment. The new name places it in the market-index-* namespace alongside its Fear and Greed
    sibling and uses the provider's own product name for the leaf.

    The exported api follows the package leaf: altcoinsSentimentApi becomes altcoinSeasonApi and
    the AltcoinsSentimentApi type becomes AltcoinSeasonApi. ALTCOIN_SEASON_INDEX_TAGS,
    transformAltcoinSeasonIndexResponse and useGetAltcoinSeasonIndexLatestQuery are unchanged.
    The README, which documented an implementation the package never had, is rewritten against the
    code. No behaviour change.

  • #22376 cdcb834 Thanks @ysitbon! - refactor(market): rename the Fear & Greed entity package to the market-index-* namespace

    @domain/entity-market-sentiment becomes @domain/entity-market-index-fear-and-greed, and
    domain/entity/market-sentiment becomes domain/entity/market-index-fear-and-greed. The old
    name used a namespace as a leaf: it holds one specific CoinMarketCap index, not market sentiment
    in general, which left the sibling Altcoin Season index with nowhere to sit.

    Pure rename. No behaviour change, and no symbol changes inside the package: FearAndGreedIndexSchema
    and FearAndGreedIndex already carried the index's real name.

  • #22510 d7287f3 Thanks @tonykhaov! - Stop the Send header from jumping down when the Send flow opens.

  • #22579 0e98a58 Thanks @vpenskyi-ledger! - Re-read SWAP_API_BASE on every swap/Perps quote request instead of baking it into the store at startup, so a debug-menu override reaches the aggregator without an app restart

  • #22392 a6b6959 Thanks @CremaFR! - Include Exchange and signing app versions on swap cancel payloads

  • #22382 c119e0d Thanks @mcayuelas-ledger! - Redirect the "choose card type" onboarding step to the Baanx hosted order-card page, and align pay bottom sheet spacing and tile styles

  • #22522 e19e6cf Thanks @mcayuelas-ledger! - Fix the cropped transaction name and date on a card charge funded by several assets, and round card crypto amounts like the rest of the product. A devtool action and a mock fixture now produce such a charge.

  • #22330 1b1a6ae Thanks @henri-ly! - Add send-recipient-card-title and recipient-contact-name test ids to the new send flow's recipient card and amount step header, so automation can assert the matched contact is carried through the flow

  • #22054 8c486aa Thanks @aussedatlo! - Add @ledgerhq/live-signer-tron, wrapping @ledgerhq/device-signer-kit-tron as DmkSignerTron
    alongside the legacy hw-app-trx path as LegacySignerTron. families/tron/setup.ts picks
    between them, using the DMK signer only on a DMK transport with the new ldmkTronSigner feature
    flag on. The flag is disabled by default, so Tron keeps signing through hw-app-trx.

  • #22471 0d6407c Thanks @mateuszpalosz-ext! - aleo operation details extended with staking details

  • #22524 720f918 Thanks @liviuciulinaru! - fix(wallet-api): close the exchange screen after a live app exchange on mobile

  • #22360 f153062 Thanks @LL782! - Wire mobile analytics through the shared analytics packages

Patch Changes

  • Updated dependencies [b42673e, e8d72da, 2d869a5, d5dfa07, 4fc2063, e4c24f3, c5964f8, 370f955, 5f34cb6, e012138, 2074967, 1647f38, 8b387f4, e8d5e1b, c95a00f, 3e7af98, 26e51d9, eddfcd4, 6a5972d, 3e7bbe9, c32cde3, ad2f1de, cee85b4, 6baab2e, cfb7566, bc28500, 4d84f2b, 5adf8f3, 6e76dda, 486a1a4, f7cd861, f1d8aac, 33b4952, e9af9cb, d6866e7, f8c92f9, 7fd570c, e046686, 739334b, b4599a5, 8475c70, 381bd0b, dfd53ad, c63d0fa, 9e54487, 83fac3e, 56640ba, b6a9b53, 68f4179, 8ecbe06, 46f0f94, ea90542, e8518d7, 56640ba, 5ff6348, 3b5a959, 41eca65, 912b087, defb949, 70d0b90, 887561b, aee5fe8, 3d41eab, ae229f2, 3fdebf4, 3b95cbb, 973a613, a39ba90, fc6f187, 6fa8121, b2c3742, fe55ea3, dccea32, 006991d, a025d7a, 1302bc7, 86dbc48, 24e881b, 909c761, 8947c0b, b8a4056, 9cafda0, b4a23ea, a896fca, 87de096, cdcb834, 4f0fdc3, 3fdfcc0, 93e6db2, 8a305ed, c020110, 0e98a58, c119e0d, e19e6cf, 8c486aa, 88bae04, df5d8c9, f7ba21f, 62cc42f]:
    • @domain/api-card-management@0.8.0
    • @features/flow-pay-card-details@0.6.0
    • @features/platform-pay-analytics@0.3.0
    • @features/flow-contacts-list@0.9.0
    • @ledgerhq/types-live@6.126.0
    • @domain/entity-contact@0.11.0
    • @features/flow-contacts-introduction@1.3.0
    • @features/flow-pay-contact@0.5.0
    • @domain/api-market-index-fear-and-greed@0.4.0
    • @features/flow-app-lock@0.6.0
    • @features/platform-app-lock@0.5.0
    • @shared/ui-info-state@0.4.0
    • @ledgerhq/live-dmk-shared@0.34.0
    • @ledgerhq/live-dmk-mobile@0.30.0
    • @ledgerhq/live-signer-evm@0.24.0
    • @ledgerhq/device-onboarding@0.4.0
    • @ledgerhq/coin-casper@3.5.0
    • @features/platform-device-action-content@0.3.0
    • @features/flow-contacts@0.13.0
    • @features/flow-pay-card-assets@0.3.0
    • @shared/ui-queued-bottom-sheet@0.6.0
    • @features/flow-pay-balance@0.6.0
    • @features/flow-pay-card-transactions@0.4.0
    • @features/platform-card@0.7.0
    • @features/flow-pay-card-auth@0.9.0
    • @features/flow-pay-card@0.6.0
    • @features/flow-pay-card-widget@0.5.0
    • @shared/feature-flags@0.25.0
    • @shared/env@0.9.0
    • @features/platform-contacts@0.9.0
    • @ledgerhq/wallet-analytics@0.5.0
    • @ledgerhq/ledger-wallet-framework@3.6.0
    • @domain/entity-currency-crypto@0.14.0
    • @ledgerhq/coin-bitcoin@0.54.0
    • @ledgerhq/live-signer-tron@0.2.0
    • @ledgerhq/transaction-observability@0.4.0
    • @ledgerhq/coin-cosmos@1.5.0
    • @features/flow-pay-feature-tour@0.7.0
    • @features/flow-pay-request@0.7.0
    • @domain/entity-market-index-altcoin-season@0.3.0
    • @ledgerhq/coin-canton@1.3.0
    • @ledgerhq/coin-concordium@1.5.0
    • @ledgerhq/coin-filecoin@2.3.0
    • @ledgerhq/coin-multiversx@1.3.0
    • @ledgerhq/coin-stacks@0.32.0
    • @features/flow-pay-bank-transfer@0.4.0
    • @features/flow-pay-deposit@0.5.0
    • @devtools/bindings@0.10.0
    • @shared/analytics@0.4.0
    • @domain/api-market-index-altcoin-season@0.4.0
    • @domain/entity-market-index-fear-and-greed@0.3.0
    • @shared/analytics-react@0.4.0
    • @shared/api-services@0.9.0
    • @ledgerhq/device-core@0.11.18
    • @ledgerhq/live-countervalues-react@0.18.2
    • @ledgerhq/live-send@0.1.2
    • @ledgerhq/live-wallet@1.1.5
    • @ledgerhq/wallet-pnl@0.7.13
    • @features/flow-contacts-add-address@0.6.1
    • @features/flow-contacts-add-contact@0.7.1
    • @features/flow-contacts-delete-contact@0.2.4
    • @features/flow-contacts-edit-address@0.4.1
    • @features/flow-contacts-edit-contact@0.6.1
    • @features/flow-large-screen-upsell@2.2.1
    • @features/platform-currencies@0.9.1
    • @features/platform-feature-flags@0.8.1
    • @domain/api-aggregated-assets@0.5.3
    • @features/platform-aggregated-assets@0.5.5
    • @features/platform-env@0.4.1
    • @ledgerhq/live-countervalues@0.26.2
    • @domain/api-currency-token@0.6.3
    • @domain/entity-currency@0.4.5
    • @domain/entity-currency-token@0.5.4
    • @domain/api-currency-fiat@0.4.6
    • @domain/api-push-devices@0.2.7
    • @devtools/shell@0.10.1
    • @features/flow-analytics-consent@0.2.8

Don't miss a new ledger-live release

NewReleases is sending notifications on new releases.