Repository navigation
Conversation
Swaps the USDT0 launch banner and sheet for the Ethena (USDe and sUSDe) launch, following the Varial Figma "Promo banner" section. - Home banner "Meet Ethena on Stellar": dismissible, on the same background-owned storage plumbing the USDT0 banner used (renamed SERVICE_TYPES, handlers, storage key and internal API). - Full-screen promo at /ethena-launch with Figma's 1s entrance animation (off under prefers-reduced-motion). Per token: Swap opens Sushi's Stellar swap, Receive the address screen, and Transfer to Stellar opens Stargate from Ethereum with the token preselected on both sides. - Shown once after the update, on the Varial announcement's trigger: wallets that exist when the build installs are marked pending, fresh installs and new or imported wallets seen, and UnlockAccount claims it once on the way Home. A dApp request isn't held up for it, and when the rebrand announcement is also owed that plays first and the promo waits for a later unlock. - Tapping the banner opens the same promo again. Removes the USDT0 sheet, its assets and its strings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The banner is one design in both themes, Figma's (4414:42195): no dark-mode outline, and the X keeps Figma's gray instead of following the theme's gray-10. Its copy and the browser-drawn focus ring are pinned too, so nothing on the card flips with the theme. The theme e2e tests now diff every computed style of the banner and of the full-screen promo across a live theme change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
PR Preview build is ready: https://github.com/stellar/freighter/releases/tag/untagged-22ee77e0d8fa1044dc0e |
Figma's dark Home (4414:59535) outlines the banner in gray-04, so the near-black card stands out on the black page. It's an inset outline: it takes no space, so nothing on the card moves. The outline covers the card's edge, where the only visible part of the keyboard focus ring on the card's main button was drawn (the card clips the rest). The ring now goes inside the button, and a new e2e test checks it shows all the way round in both themes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The one-time promo now shows once to every wallet, new or existing, on an unlock to Home (after the rebrand announcement if that's owed). It's a plain "has seen it" flag: no install-time marking, and creating or importing a wallet no longer marks it seen. Onboarding e2e flows that unlock a wallet for the first time close the promo first, and a new e2e test covers once-and-only-once. - Swap opens Sushi's Stellar swap from XLM to the token, by contract address (token0/token1), which Sushi is adding. - The close button sits on a sticky bar that fills in once the page scrolls, with Home's header fade, now a shared mixin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Back to the Varial announcement's rule: wallets that exist when this version installs get the promo once, on their next unlock to Home. Fresh installs, and wallets created or imported after, skip it so it doesn't follow onboarding; Home's banner still opens it. This restores the trigger from before 85ad74b and keeps that commit's Sushi links and sticky bar. Two e2e tests cover the rule: a wallet set up on this install skips it and can open it from the banner, and a wallet that predates the launch sees it once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Transfer to Stellar is now the height of SDS's lg Button, like Swap and Receive (40px, 14/22 text), with a 14px arrow like theirs. - "Scroll to discover tokens" is a button: it scrolls the page until the cue sits 60px below the close button's bar, the tokens under it (smoothly, or straight there under reduced motion). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Receive opens the address screen, whose X goes back in history, which remounted the promo at the top and replayed its intro. The promo now notes its scroll position in its own history entry before it goes, and coming back restores it before the first paint, with the close button's bar already in place and no intro. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In fullscreen mode the promo took the whole tab. It now sits in the same frame as Home (View's inset: centred, up to 848px, with its vertical borders from 850px), and its content fills the frame instead of a fixed 360px column, so its buttons span it like other fullscreen screens' do. The popup is unchanged, pixel for pixel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chrome closes an extension popup on an Esc the page leaves unhandled. A small useEscapeToClose hook marks it handled and closes the screen instead: the promo goes where its X goes, and the address screen goes back, like its X. An Esc something else already handled is left alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hena-stargate-launch
There was a problem hiding this comment.
🟡 Changes recommended
Active issues remain because concurrent unlock surfaces can both display takeover screens, and the new claim failure path silently drops messaging errors instead of reporting them.
2 open issues
What changed in this PR
Replaces the USDT0 Home promotion with an Ethena launch experience for USDe and sUSDe on Stellar. The PR adds one-time eligibility handling, a full-screen token guide, a new Home banner, updated messaging and localization, and removes the previous USDT0 campaign.
Changes:
- Adds the Ethena promo route, animations, token actions, receive flow, external links, accessibility behavior, and metrics.
- Adds persistent eligibility and claim handling, unlock routing, background messaging, and onboarding exclusions.
- Replaces USDT0 components, translations, styles, and assets with Ethena equivalents and adds comprehensive unit and E2E coverage.
| File | Description |
|---|---|
| extension/src/popup/views/ViewPublicKey/index.tsx | Adds Escape-to-back behavior for the address screen. |
| extension/src/popup/views/UnlockAccount/index.tsx | Claims and routes eligible unlocks to the Ethena promo. |
| extension/src/popup/views/UnlockAccount/__tests__/UnlockAccount.test.tsx | Tests Ethena promo routing, priority, and failure handling. |
| extension/src/popup/views/EthenaLaunch/styles.scss | Defines the full-screen promo layout, animation, scrolling, and responsive styling. |
| extension/src/popup/views/EthenaLaunch/index.tsx | Implements the Ethena full-screen launch experience and token actions. |
| extension/src/popup/views/__tests__/EthenaLaunch.test.tsx | Tests promo content, actions, navigation, scrolling, and Escape handling. |
| extension/src/popup/styles/utils.scss | Adds the shared pinned-header fade mixin. |
| extension/src/popup/styles/__tests__/varialPalette.test.ts | Updates the fixed-color allowlist for Ethena campaign styling. |
| extension/src/popup/Router.tsx | Registers the verified Ethena promo route. |
| extension/src/popup/metrics/views.ts | Adds Ethena screen metrics. |
| extension/src/popup/locales/pt/translation.json | Adds Portuguese Ethena translations and removes USDT0 strings. |
| extension/src/popup/locales/en/translation.json | Adds English Ethena translations and removes USDT0 strings. |
| extension/src/popup/helpers/hooks/useEscapeToClose.ts | Adds reusable Escape-to-close behavior. |
| extension/src/popup/helpers/hooks/__tests__/useEscapeToClose.test.ts | Tests Escape handling and cleanup. |
| extension/src/popup/constants/routes.ts | Adds the Ethena route constant. |
| extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss | Removes the obsolete USDT0 sheet styles. |
| extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx | Removes the obsolete USDT0 sheet component. |
| extension/src/popup/components/account/Usdt0LaunchBanner/styles.scss | Removes the obsolete USDT0 banner styles. |
| extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx | Removes the obsolete USDT0 banner component. |
| extension/src/popup/components/account/EthenaLaunchBanner/styles.scss | Styles the new Ethena Home banner across themes. |
| extension/src/popup/components/account/EthenaLaunchBanner/index.tsx | Implements Ethena banner dismissal and promo navigation. |
| extension/src/popup/components/account/EthenaLaunchBanner/__tests__/EthenaLaunchBanner.test.tsx | Tests banner loading, dismissal, errors, and navigation. |
| extension/src/popup/components/account/AccountHeader/index.tsx | Replaces the USDT0 banner with the Ethena banner. |
| extension/src/popup/basics/layout/View/styles.scss | Uses the shared header fade mixin. |
| extension/src/popup/assets/usdt0-lockup.svg | Removes the obsolete USDT0 lockup asset. |
| extension/src/popup/assets/usdt0-arcs.svg | Removes the obsolete USDT0 artwork. |
| extension/src/popup/assets/logo-usde.svg | Adds the USDe token logo. |
| extension/src/popup/assets/logo-susde.svg | Adds the sUSDe token logo. |
| extension/src/popup/assets/ethena-launch-banner-glow.svg | Adds the Ethena banner glow artwork. |
| extension/src/constants/localStorageTypes.ts | Adds Ethena banner and promo storage keys. |
| extension/src/constants/ethenaLaunchPromo.ts | Defines Ethena promo eligibility states. |
| extension/src/background/messageListener/popupMessageListener.ts | Registers Ethena banner and promo message handlers. |
| extension/src/background/messageListener/handlers/recoverAccount.ts | Prevents recovered wallets from inheriting the promo. |
| extension/src/background/messageListener/handlers/getEthenaLaunchBannerDismissed.ts | Reads Ethena banner dismissal state. |
| extension/src/background/messageListener/handlers/dismissEthenaLaunchBanner.ts | Persists Ethena banner dismissal state. |
| extension/src/background/messageListener/handlers/createAccount.ts | Prevents newly created wallets from inheriting the promo. |
| extension/src/background/messageListener/handlers/claimEthenaLaunchPromo.ts | Atomically claims the one-time Ethena promo. |
| extension/src/background/messageListener/__tests__/resetWallet.test.ts | Updates reset-wallet coverage for Ethena storage state. |
| extension/src/background/messageListener/__tests__/recoverAccount.test.ts | Tests recovered-wallet promo state. |
| extension/src/background/messageListener/__tests__/ethenaLaunchBanner.test.ts | Tests Ethena banner storage handlers. |
| extension/src/background/messageListener/__tests__/createAccount.test.ts | Tests new-wallet promo state. |
| extension/src/background/messageListener/__tests__/claimEthenaLaunchPromo.test.ts | Tests one-time and concurrent promo claims. |
| extension/src/background/index.ts | Registers install-time Ethena promo eligibility initialization. |
| extension/src/background/helpers/dataStorage.ts | Determines promo eligibility during installation and updates. |
| extension/src/background/helpers/__tests__/migrations.test.ts | Tests promo eligibility initialization and persistence. |
| extension/e2e-tests/theme.test.ts | Verifies Ethena theme invariance and banner styling. |
| extension/e2e-tests/ethenaLaunch.test.ts | Covers end-to-end promo lifecycle, layout, actions, scrolling, and keyboard behavior. |
| @shared/constants/services.ts | Adds Ethena internal message types. |
| @shared/api/types/types.ts | Adds shared typing for the Ethena promo response. |
| @shared/api/types/message-request.ts | Defines Ethena message request types. |
| @shared/api/internal.ts | Exposes Ethena dismissal and promo-claim APIs. |
Review effort: Lite
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |


TL;DR
Replaces the USDT0 launch on Home with the Ethena launch: USDe and sUSDe on Stellar, with Stargate for transfers. A "Meet Ethena on Stellar" banner on Home opens a full-screen promo that plays Figma's intro animation and lists both tokens, each with Swap (Sushi, from XLM to the token), Receive (the wallet's address screen) and Transfer to Stellar (Stargate, from Ethereum with the token preselected). "Learn more about Ethena" opens Ethena's docs.
Wallets that already exist when this version installs also see the promo once, on their next unlock to Home. This reuses the trigger of the Varial rebrand announcement: new and imported wallets skip it, so it doesn't follow onboarding (Home's banner still opens it). The banner and the promo look the same in light and dark themes, except that dark mode outlines the banner so it stands out on the black page. The USDT0 banner and sheet are removed.
Designs: Figma. The Discover screen in that section isn't part of this PR.
Follow-ups
token0andtoken1params to its Stellar swap page soon; until that ships, Swap opens on Sushi's default pair with USDT0 as destination.Video sample (light theme variation shown at the end)
ethena-launch.mov
Implementation details (for agents)
What changed
markEthenaLaunchPromoEligibility(dataStorage.ts#L408-L428) runs onruntime.onInstalled(index.ts#L215). An install that finds wallets marksethenaLaunchPromoStatuspending; one that finds none marks it seen. A status that's already set is kept, so later updates don't re-arm it.CLAIM_ETHENA_LAUNCH_PROMO(claimEthenaLaunchPromo.ts) turns pending into seen and answers whether to show it. Claims run one at a time, so two surfaces can't both win.UnlockAccount(index.tsx#L78-L115) claims it only when the unlock is headed Home, after the rebrand claim, and fails closed. It passes the destination in route state, and closing the promo returns there.EthenaLaunch(index.tsx, styles.scss), at/ethena-launchbehindVerifiedAccountRoute, screen nameethena_launch:sds-theme-darkon its root), since its hero art is drawn for a black page.prefers-reduced-motion.Buttons (lg, secondary and tertiary). Transfer is hand-rolled because no SDS variant is transparent, at the same 40px height with the same 14px arrow (styles.scss#L287-L320).useEscapeToClosehook (useEscapeToClose.ts) marks the key handled, which keeps Chrome from closing the popup (index.tsx#L187-L188, ViewPublicKey/index.tsx#L34-L35).token0andtoken1contract addresses; Stargate from Ethereum to Stellar with the token preselected on both sides; Ethena's docs. The USDe and sUSDe addresses are the ones LayerZero's transfer token list publishes.EthenaLaunchBanner(index.tsx, styles.scss), inAccountHeaderwhere the USDT0 banner was:GET_ETHENA_LAUNCH_BANNER_DISMISSED,DISMISS_ETHENA_LAUNCH_BANNER, keyethenaLaunchBannerDismissed). The banner stays hidden while that loads, and if the lookup fails.color-scheme: darkkeeps the browser's focus ring the same in both themes. The card's main button draws it inside, since the card clips anything outside it and the outline covers its edge.Verification
yarn test:ci: 2,707 tests pass, 0 failures. New tests cover the claim, the eligibility on install, create and recover marking it seen, the dismissal handlers, the unlock routing (promo on the way Home, fail closed, a dApp request goes first, the rebrand announcement goes first), the promo view (links, Receive, close, the bar, the scroll cue, coming back from Receive, Esc), the Esc hook and the banner.yarn build:extensionpasses. ESLint and Prettier are clean on the changed files.theme.test.ts5/5 and the newethenaLaunch.test.ts10/10. Two new theme tests (theme.test.ts#L89-L223) diff every computed style of the banner and of the promo across a live light-to-dark switch; the only change they accept is the banner's dark-mode outline. They also check the banner against Figma's values. ethenaLaunch.test.ts checks that a wallet set up on this install skips the promo and can open it from the banner, that a wallet that predates the launch sees it once, that the promo sits in Home's frame in a wide window and fills it, that the token actions are all the same size, that the scroll cue stops 20px below the bar, that the promo comes back from Receive as it was left, that Esc closes the address screen and then the promo, that the close button stays put on the bar as the page scrolls, and that keyboard focus on the banner's main button draws a full ring in both themes.yarn test:e2e): passes in CI on cf07839 (thetestcheck).🤖 Generated with Claude Code