From 095643670a93d145006709d85900922d041577e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Fri, 13 Nov 2026 10:52:20 -0800 Subject: [PATCH 01/11] feat: replace the USDT0 promo with the Ethena launch on Home 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 --- @shared/api/internal.ts | 23 +- @shared/api/types/message-request.ts | 17 +- @shared/api/types/types.ts | 1 + @shared/constants/services.ts | 5 +- extension/e2e-tests/theme.test.ts | 21 +- .../helpers/__tests__/migrations.test.ts | 37 + .../src/background/helpers/dataStorage.ts | 24 + extension/src/background/index.ts | 2 + .../__tests__/claimEthenaLaunchPromo.test.ts | 55 + .../__tests__/createAccount.test.ts | 26 + .../__tests__/ethenaLaunchBanner.test.ts | 33 + .../__tests__/recoverAccount.test.ts | 17 + .../__tests__/resetWallet.test.ts | 11 +- .../handlers/claimEthenaLaunchPromo.ts | 32 + .../messageListener/handlers/createAccount.ts | 8 +- ...Banner.ts => dismissEthenaLaunchBanner.ts} | 6 +- ...d.ts => getEthenaLaunchBannerDismissed.ts} | 6 +- .../handlers/recoverAccount.ts | 8 +- .../messageListener/popupMessageListener.ts | 16 +- extension/src/constants/ethenaLaunchPromo.ts | 9 + extension/src/constants/localStorageTypes.ts | 3 +- extension/src/popup/Router.tsx | 9 + .../assets/ethena-launch-banner-glow.svg | 12 + .../popup/assets/ethena-launch-coin-dark.png | Bin 0 -> 100511 bytes .../popup/assets/ethena-launch-coin-light.png | Bin 0 -> 137310 bytes .../src/popup/assets/ethena-launch-wave.svg | 1611 +++++++++++++++++ extension/src/popup/assets/logo-susde.svg | 12 + extension/src/popup/assets/logo-usde.svg | 12 + extension/src/popup/assets/logo-usdt0.png | Bin 15645 -> 0 bytes extension/src/popup/assets/usdt0-arcs.svg | 20 - extension/src/popup/assets/usdt0-lockup.svg | 10 - .../account/AccountHeader/index.tsx | 4 +- .../__tests__/EthenaLaunchBanner.test.tsx | 103 ++ .../account/EthenaLaunchBanner/index.tsx | 91 + .../account/EthenaLaunchBanner/styles.scss | 102 ++ .../Usdt0LaunchSheet/index.tsx | 181 -- .../Usdt0LaunchSheet/styles.scss | 244 --- .../account/Usdt0LaunchBanner/index.tsx | 121 -- .../account/Usdt0LaunchBanner/styles.scss | 110 -- extension/src/popup/constants/routes.ts | 1 + .../src/popup/locales/en/translation.json | 22 +- .../src/popup/locales/pt/translation.json | 22 +- extension/src/popup/metrics/views.ts | 1 + .../styles/__tests__/varialPalette.test.ts | 22 +- .../src/popup/views/EthenaLaunch/index.tsx | 222 +++ .../src/popup/views/EthenaLaunch/styles.scss | 337 ++++ .../__tests__/UnlockAccount.test.tsx | 72 +- .../src/popup/views/UnlockAccount/index.tsx | 27 +- .../views/__tests__/EthenaLaunch.test.tsx | 166 ++ 49 files changed, 3125 insertions(+), 769 deletions(-) create mode 100644 extension/src/background/messageListener/__tests__/claimEthenaLaunchPromo.test.ts create mode 100644 extension/src/background/messageListener/__tests__/ethenaLaunchBanner.test.ts create mode 100644 extension/src/background/messageListener/handlers/claimEthenaLaunchPromo.ts rename extension/src/background/messageListener/handlers/{dismissUsdt0LaunchBanner.ts => dismissEthenaLaunchBanner.ts} (51%) rename extension/src/background/messageListener/handlers/{getUsdt0LaunchBannerDismissed.ts => getEthenaLaunchBannerDismissed.ts} (50%) create mode 100644 extension/src/constants/ethenaLaunchPromo.ts create mode 100644 extension/src/popup/assets/ethena-launch-banner-glow.svg create mode 100644 extension/src/popup/assets/ethena-launch-coin-dark.png create mode 100644 extension/src/popup/assets/ethena-launch-coin-light.png create mode 100644 extension/src/popup/assets/ethena-launch-wave.svg create mode 100644 extension/src/popup/assets/logo-susde.svg create mode 100644 extension/src/popup/assets/logo-usde.svg delete mode 100644 extension/src/popup/assets/logo-usdt0.png delete mode 100644 extension/src/popup/assets/usdt0-arcs.svg delete mode 100644 extension/src/popup/assets/usdt0-lockup.svg create mode 100644 extension/src/popup/components/account/EthenaLaunchBanner/__tests__/EthenaLaunchBanner.test.tsx create mode 100644 extension/src/popup/components/account/EthenaLaunchBanner/index.tsx create mode 100644 extension/src/popup/components/account/EthenaLaunchBanner/styles.scss delete mode 100644 extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx delete mode 100644 extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss delete mode 100644 extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx delete mode 100644 extension/src/popup/components/account/Usdt0LaunchBanner/styles.scss create mode 100644 extension/src/popup/views/EthenaLaunch/index.tsx create mode 100644 extension/src/popup/views/EthenaLaunch/styles.scss create mode 100644 extension/src/popup/views/__tests__/EthenaLaunch.test.tsx diff --git a/@shared/api/internal.ts b/@shared/api/internal.ts index 9ac546bf10..33d0b7c611 100644 --- a/@shared/api/internal.ts +++ b/@shared/api/internal.ts @@ -2587,10 +2587,10 @@ export const getTokenIds = async ({ return tokenIdList; }; -export const getUsdt0LaunchBannerDismissed = async (): Promise => { +export const getEthenaLaunchBannerDismissed = async (): Promise => { const { isDismissed, error } = await sendMessageToBackground({ activePublicKey: null, - type: SERVICE_TYPES.GET_USDT0_LAUNCH_BANNER_DISMISSED, + type: SERVICE_TYPES.GET_ETHENA_LAUNCH_BANNER_DISMISSED, }); if (error) { @@ -2600,12 +2600,12 @@ export const getUsdt0LaunchBannerDismissed = async (): Promise => { return !!isDismissed; }; -export const dismissUsdt0LaunchBanner = async (): Promise<{ +export const dismissEthenaLaunchBanner = async (): Promise<{ isDismissed: boolean; }> => { const { isDismissed, error } = await sendMessageToBackground({ activePublicKey: null, - type: SERVICE_TYPES.DISMISS_USDT0_LAUNCH_BANNER, + type: SERVICE_TYPES.DISMISS_ETHENA_LAUNCH_BANNER, }); if (error) { @@ -3186,6 +3186,21 @@ export const claimRebrandAnnouncement = async (): Promise => { return Boolean(shouldShowRebrandAnnouncement); }; +// True once per eligible wallet, like the rebrand announcement above: the +// background flips pending to seen as it answers. +export const claimEthenaLaunchPromo = async (): Promise => { + const { shouldShowEthenaLaunchPromo, error } = await sendMessageToBackground({ + activePublicKey: null, + type: SERVICE_TYPES.CLAIM_ETHENA_LAUNCH_PROMO, + }); + + if (error) { + throw new Error(error); + } + + return Boolean(shouldShowEthenaLaunchPromo); +}; + export const getCachedSwapTopTokens = async ( network: string, ): Promise<{ tokens: TrendingAsset[]; updatedAt: number } | null> => { diff --git a/@shared/api/types/message-request.ts b/@shared/api/types/message-request.ts index 206b06d1bb..6f68399a7b 100644 --- a/@shared/api/types/message-request.ts +++ b/@shared/api/types/message-request.ts @@ -436,12 +436,12 @@ export interface GetHiddenAssetsMessage extends BaseMessage { network: string; } -export interface GetUsdt0LaunchBannerDismissedMessage extends BaseMessage { - type: SERVICE_TYPES.GET_USDT0_LAUNCH_BANNER_DISMISSED; +export interface GetEthenaLaunchBannerDismissedMessage extends BaseMessage { + type: SERVICE_TYPES.GET_ETHENA_LAUNCH_BANNER_DISMISSED; } -export interface DismissUsdt0LaunchBannerMessage extends BaseMessage { - type: SERVICE_TYPES.DISMISS_USDT0_LAUNCH_BANNER; +export interface DismissEthenaLaunchBannerMessage extends BaseMessage { + type: SERVICE_TYPES.DISMISS_ETHENA_LAUNCH_BANNER; } export interface GetRecentProtocolsMessage extends BaseMessage { @@ -469,6 +469,10 @@ export interface ClaimRebrandAnnouncementMessage extends BaseMessage { type: SERVICE_TYPES.CLAIM_REBRAND_ANNOUNCEMENT; } +export interface ClaimEthenaLaunchPromoMessage extends BaseMessage { + type: SERVICE_TYPES.CLAIM_ETHENA_LAUNCH_PROMO; +} + export interface GetBlockaidDebugOverrideMessage extends BaseMessage { type: SERVICE_TYPES.GET_BLOCKAID_DEBUG_OVERRIDE; } @@ -590,14 +594,15 @@ export type ServiceMessageRequest = | GetIsAccountMismatchMessage | ChangeAssetVisibilityMessage | GetHiddenAssetsMessage - | GetUsdt0LaunchBannerDismissedMessage - | DismissUsdt0LaunchBannerMessage + | GetEthenaLaunchBannerDismissedMessage + | DismissEthenaLaunchBannerMessage | GetRecentProtocolsMessage | AddRecentProtocolMessage | ClearRecentProtocolsMessage | GetDiscoverWelcomeSeenMessage | DismissDiscoverWelcomeMessage | ClaimRebrandAnnouncementMessage + | ClaimEthenaLaunchPromoMessage | GetBlockaidDebugOverrideMessage | AddCollectibleMessage | GetCollectiblesMessage diff --git a/@shared/api/types/types.ts b/@shared/api/types/types.ts index ad2d12343c..d8eebd26c9 100644 --- a/@shared/api/types/types.ts +++ b/@shared/api/types/types.ts @@ -143,6 +143,7 @@ export interface Response { recentProtocols: RecentProtocolEntry[]; hasSeenDiscoverWelcome: boolean; shouldShowRebrandAnnouncement: boolean; + shouldShowEthenaLaunchPromo: boolean; cachedSwapTopTokens: { tokens: TrendingAsset[]; updatedAt: number } | null; } diff --git a/@shared/constants/services.ts b/@shared/constants/services.ts index 07edb2c45c..4b39836da9 100644 --- a/@shared/constants/services.ts +++ b/@shared/constants/services.ts @@ -55,8 +55,8 @@ export enum SERVICE_TYPES { CHANGE_ASSET_VISIBILITY = "CHANGE_ASSET_VISIBILITY", GET_HIDDEN_ASSETS = "GET_HIDDEN_ASSETS", GET_IS_ACCOUNT_MISMATCH = "GET_IS_ACCOUNT_MISMATCH", - GET_USDT0_LAUNCH_BANNER_DISMISSED = "GET_USDT0_LAUNCH_BANNER_DISMISSED", - DISMISS_USDT0_LAUNCH_BANNER = "DISMISS_USDT0_LAUNCH_BANNER", + GET_ETHENA_LAUNCH_BANNER_DISMISSED = "GET_ETHENA_LAUNCH_BANNER_DISMISSED", + DISMISS_ETHENA_LAUNCH_BANNER = "DISMISS_ETHENA_LAUNCH_BANNER", GET_BLOCKAID_DEBUG_OVERRIDE = "GET_BLOCKAID_DEBUG_OVERRIDE", SAVE_BLOCKAID_DEBUG_OVERRIDE = "SAVE_BLOCKAID_DEBUG_OVERRIDE", ADD_COLLECTIBLE = "ADD_COLLECTIBLE", @@ -72,6 +72,7 @@ export enum SERVICE_TYPES { GET_DISCOVER_WELCOME_SEEN = "GET_DISCOVER_WELCOME_SEEN", DISMISS_DISCOVER_WELCOME = "DISMISS_DISCOVER_WELCOME", CLAIM_REBRAND_ANNOUNCEMENT = "CLAIM_REBRAND_ANNOUNCEMENT", + CLAIM_ETHENA_LAUNCH_PROMO = "CLAIM_ETHENA_LAUNCH_PROMO", GET_CACHED_SWAP_TOP_TOKENS = "GET_CACHED_SWAP_TOP_TOKENS", CACHE_SWAP_TOP_TOKENS = "CACHE_SWAP_TOP_TOKENS", USER_ACTIVITY = "USER_ACTIVITY", diff --git a/extension/e2e-tests/theme.test.ts b/extension/e2e-tests/theme.test.ts index 1c4d617930..e461616440 100644 --- a/extension/e2e-tests/theme.test.ts +++ b/extension/e2e-tests/theme.test.ts @@ -81,29 +81,30 @@ test("welcome screen follows the color scheme", async ({ expect(await backdrop(body)).toBe(BASE_00.dark); }); -test("USDT0 sheet stays dark in light theme", async ({ +test("Ethena launch promo stays dark in light theme", async ({ page, extensionId, context, }) => { await page.emulateMedia({ colorScheme: "light" }); await loginToTestAccount({ page, extensionId, context }); - await page.getByTestId("usdt0-launch-banner-open").click(); - await expect(page.getByTestId("usdt0-launch-sheet")).toBeVisible(); + await page.getByTestId("ethena-launch-banner-open").click(); + const promo = page.getByTestId("ethena-launch"); + await expect(promo).toBeVisible(); - // Its hero art is fixed-dark, so the text over it must resolve dark-theme - // tokens even though the page is light. + // Its hero art is drawn for a black page, so the page and the text over it + // must resolve dark-theme tokens even though the app is light. const colorOf = (el: Element) => getComputedStyle(el).color; const darkGray12 = "rgb(237, 237, 237)"; + expect(await backdrop(promo)).toBe(BASE_00.dark); expect( await page - .locator(".Usdt0LaunchSheet__feature__title") - .first() + .getByRole("heading", { name: "Meet Ethena on Stellar" }) .evaluate(colorOf), ).toBe(darkGray12); - expect( - await page.getByTestId("usdt0-launch-sheet-close").evaluate(colorOf), - ).toBe(darkGray12); + expect(await page.getByTestId("ethena-launch-close").evaluate(colorOf)).toBe( + darkGray12, + ); }); // The lock screen and its Forgot password sheet resolve their colors in both diff --git a/extension/src/background/helpers/__tests__/migrations.test.ts b/extension/src/background/helpers/__tests__/migrations.test.ts index b251acf527..55c9cf6949 100644 --- a/extension/src/background/helpers/__tests__/migrations.test.ts +++ b/extension/src/background/helpers/__tests__/migrations.test.ts @@ -14,10 +14,12 @@ import { STORAGE_VERSION, KEY_ID_LIST, REBRAND_ANNOUNCEMENT_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS_ID, TOKEN_ID_LIST, } from "constants/localStorageTypes"; import * as DataStorage from "../dataStorage"; import { REBRAND_ANNOUNCEMENT_STATUS } from "constants/rebrandAnnouncement"; +import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import * as DataStorageAccess from "../dataStorageAccess"; import { DEFAULT_ASSETS_LISTS } from "@shared/constants/soroban/asset-list"; @@ -261,4 +263,39 @@ describe("Storage migrations", () => { ); }); }); + describe("markEthenaLaunchPromoEligibility", () => { + it("marks a wallet that exists when the launch build arrives as pending", async () => { + await mockStorage.set({ [KEY_ID_LIST]: ["key-1"] }); + + await DataStorage.markEthenaLaunchPromoEligibility(); + + const stored = await mockStorage.get(ETHENA_LAUNCH_PROMO_STATUS_ID); + expect(stored[ETHENA_LAUNCH_PROMO_STATUS_ID]).toEqual( + ETHENA_LAUNCH_PROMO_STATUS.PENDING, + ); + }); + + it("marks a fresh install as seen", async () => { + await DataStorage.markEthenaLaunchPromoEligibility(); + + const stored = await mockStorage.get(ETHENA_LAUNCH_PROMO_STATUS_ID); + expect(stored[ETHENA_LAUNCH_PROMO_STATUS_ID]).toEqual( + ETHENA_LAUNCH_PROMO_STATUS.SEEN, + ); + }); + + it("leaves a recorded status alone on later updates", async () => { + await mockStorage.set({ + [KEY_ID_LIST]: ["key-1"], + [ETHENA_LAUNCH_PROMO_STATUS_ID]: ETHENA_LAUNCH_PROMO_STATUS.SEEN, + }); + + await DataStorage.markEthenaLaunchPromoEligibility(); + + const stored = await mockStorage.get(ETHENA_LAUNCH_PROMO_STATUS_ID); + expect(stored[ETHENA_LAUNCH_PROMO_STATUS_ID]).toEqual( + ETHENA_LAUNCH_PROMO_STATUS.SEEN, + ); + }); + }); }); diff --git a/extension/src/background/helpers/dataStorage.ts b/extension/src/background/helpers/dataStorage.ts index 242c585891..07db6c354f 100644 --- a/extension/src/background/helpers/dataStorage.ts +++ b/extension/src/background/helpers/dataStorage.ts @@ -16,8 +16,10 @@ import { LAST_USED_ACCOUNT, KEY_ID_LIST, REBRAND_ANNOUNCEMENT_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS_ID, } from "constants/localStorageTypes"; import { REBRAND_ANNOUNCEMENT_STATUS } from "constants/rebrandAnnouncement"; +import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import { DEFAULT_NETWORKS, NetworkDetails, @@ -403,6 +405,28 @@ export const markRebrandAnnouncementEligibility = async () => { ); }; +/** + * Same once-per-install decision as the rebrand announcement, for the + * one-time Ethena launch promo: a wallet that already exists when the launch + * build first runs is marked pending; a fresh install is marked seen. + */ +export const markEthenaLaunchPromoEligibility = async () => { + const localStore = dataStorageAccess(browserLocalStorage); + + if (await localStore.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID)) { + return; + } + + const keyIdList = ((await localStore.getItem(KEY_ID_LIST)) || []) as string[]; + + await localStore.setItem( + ETHENA_LAUNCH_PROMO_STATUS_ID, + keyIdList.length + ? ETHENA_LAUNCH_PROMO_STATUS.PENDING + : ETHENA_LAUNCH_PROMO_STATUS.SEEN, + ); +}; + export const versionedMigration = async () => { // sequentially call migrations in order to enforce smooth schema upgrades diff --git a/extension/src/background/index.ts b/extension/src/background/index.ts index 9e20f856fe..c7db73b16e 100644 --- a/extension/src/background/index.ts +++ b/extension/src/background/index.ts @@ -41,6 +41,7 @@ import { migrateSorobanRpcUrlNetworkDetails, versionedMigration, markRebrandAnnouncementEligibility, + markEthenaLaunchPromoEligibility, } from "./helpers/dataStorage"; import { dataStorageAccess, @@ -211,6 +212,7 @@ export const initInstalledListener = () => { browser?.runtime?.onInstalled.addListener(migrateSorobanRpcUrlNetworkDetails); browser?.runtime?.onInstalled.addListener(versionedMigration); browser?.runtime?.onInstalled.addListener(markRebrandAnnouncementEligibility); + browser?.runtime?.onInstalled.addListener(markEthenaLaunchPromoEligibility); }; export const initSidebarBehavior = async () => { diff --git a/extension/src/background/messageListener/__tests__/claimEthenaLaunchPromo.test.ts b/extension/src/background/messageListener/__tests__/claimEthenaLaunchPromo.test.ts new file mode 100644 index 0000000000..a45ba1c374 --- /dev/null +++ b/extension/src/background/messageListener/__tests__/claimEthenaLaunchPromo.test.ts @@ -0,0 +1,55 @@ +import { mockDataStorage } from "background/messageListener/helpers/test-helpers"; +import { ETHENA_LAUNCH_PROMO_STATUS_ID } from "constants/localStorageTypes"; +import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; + +import { claimEthenaLaunchPromo } from "../handlers/claimEthenaLaunchPromo"; + +describe("claimEthenaLaunchPromo", () => { + beforeEach(async () => { + await mockDataStorage.remove(ETHENA_LAUNCH_PROMO_STATUS_ID); + }); + + it("says no when nothing has been recorded (fresh install)", async () => { + const result = await claimEthenaLaunchPromo({ + localStore: mockDataStorage, + }); + expect(result).toEqual({ shouldShowEthenaLaunchPromo: false }); + }); + + it("says yes once for a pending wallet and marks it seen", async () => { + await mockDataStorage.setItem( + ETHENA_LAUNCH_PROMO_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS.PENDING, + ); + + const first = await claimEthenaLaunchPromo({ + localStore: mockDataStorage, + }); + const second = await claimEthenaLaunchPromo({ + localStore: mockDataStorage, + }); + + expect(first).toEqual({ shouldShowEthenaLaunchPromo: true }); + expect(second).toEqual({ shouldShowEthenaLaunchPromo: false }); + expect( + await mockDataStorage.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID), + ).toEqual(ETHENA_LAUNCH_PROMO_STATUS.SEEN); + }); + + it("lets only one of several concurrent surfaces show it", async () => { + await mockDataStorage.setItem( + ETHENA_LAUNCH_PROMO_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS.PENDING, + ); + + const results = await Promise.all([ + claimEthenaLaunchPromo({ localStore: mockDataStorage }), + claimEthenaLaunchPromo({ localStore: mockDataStorage }), + claimEthenaLaunchPromo({ localStore: mockDataStorage }), + ]); + + expect(results.filter((r) => r.shouldShowEthenaLaunchPromo)).toHaveLength( + 1, + ); + }); +}); diff --git a/extension/src/background/messageListener/__tests__/createAccount.test.ts b/extension/src/background/messageListener/__tests__/createAccount.test.ts index 37adb37024..12c3a62ecd 100644 --- a/extension/src/background/messageListener/__tests__/createAccount.test.ts +++ b/extension/src/background/messageListener/__tests__/createAccount.test.ts @@ -14,7 +14,9 @@ import { KEY_ID_LIST, APPLICATION_ID, TEMPORARY_STORE_ID, + ETHENA_LAUNCH_PROMO_STATUS_ID, } from "constants/localStorageTypes"; +import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import { createAccount } from "background/messageListener/handlers/createAccount"; import { APPLICATION_STATE } from "@shared/constants/applicationState"; @@ -64,6 +66,30 @@ describe("Create account message listener", () => { expect(applicationState).toBe(APPLICATION_STATE.PASSWORD_CREATED); expect(tempStoreId[keyId]).toBeDefined(); }); + it("doesn't owe a new wallet the Ethena launch promo", async () => { + // Pending from a wallet that existed before the reset/onboarding. + await mockDataStorage.setItem( + ETHENA_LAUNCH_PROMO_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS.PENDING, + ); + + await popupMessageListener( + { + type: SERVICE_TYPES.CREATE_ACCOUNT, + password: "test", + isOverwritingAccount: false, + } as CreateAccountMessage, + mockSessionStore, + mockDataStorage, + mockKeyManager, + testAlarm as any, + { id: "fake-extension-id" }, + ); + + expect(await mockDataStorage.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID)).toBe( + ETHENA_LAUNCH_PROMO_STATUS.SEEN, + ); + }); it("can overwrite account", async () => { const response = (await popupMessageListener( { diff --git a/extension/src/background/messageListener/__tests__/ethenaLaunchBanner.test.ts b/extension/src/background/messageListener/__tests__/ethenaLaunchBanner.test.ts new file mode 100644 index 0000000000..e4c724c80f --- /dev/null +++ b/extension/src/background/messageListener/__tests__/ethenaLaunchBanner.test.ts @@ -0,0 +1,33 @@ +import { mockDataStorage } from "background/messageListener/helpers/test-helpers"; +import { ETHENA_LAUNCH_BANNER_DISMISSED } from "constants/localStorageTypes"; + +import { getEthenaLaunchBannerDismissed } from "../handlers/getEthenaLaunchBannerDismissed"; +import { dismissEthenaLaunchBanner } from "../handlers/dismissEthenaLaunchBanner"; + +describe("Ethena launch banner dismissal", () => { + beforeEach(async () => { + await mockDataStorage.remove(ETHENA_LAUNCH_BANNER_DISMISSED); + }); + + it("reports the banner as not dismissed until it is", async () => { + const result = await getEthenaLaunchBannerDismissed({ + localStore: mockDataStorage, + }); + expect(result).toEqual({ isDismissed: false }); + }); + + it("persists a dismissal and reports it from then on", async () => { + const dismissed = await dismissEthenaLaunchBanner({ + localStore: mockDataStorage, + }); + const lookup = await getEthenaLaunchBannerDismissed({ + localStore: mockDataStorage, + }); + + expect(dismissed).toEqual({ isDismissed: true }); + expect(lookup).toEqual({ isDismissed: true }); + expect(await mockDataStorage.getItem(ETHENA_LAUNCH_BANNER_DISMISSED)).toBe( + true, + ); + }); +}); diff --git a/extension/src/background/messageListener/__tests__/recoverAccount.test.ts b/extension/src/background/messageListener/__tests__/recoverAccount.test.ts index f726f78b5e..57bc391a12 100644 --- a/extension/src/background/messageListener/__tests__/recoverAccount.test.ts +++ b/extension/src/background/messageListener/__tests__/recoverAccount.test.ts @@ -9,6 +9,8 @@ import { mockStorageApi, MockBrowserAlarm, } from "background/messageListener/helpers/test-helpers"; +import { ETHENA_LAUNCH_PROMO_STATUS_ID } from "constants/localStorageTypes"; +import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; // Distinct keys per derivation index, so the recovery preload loop stores a // separate account for each one rather than collapsing into a single entry. @@ -71,4 +73,19 @@ describe("Recover account message listener", () => { true, ); }); + + // Recovery is onboarding (also the "forgot password" path), so it isn't + // followed by the one-time launch promo either. + it("doesn't owe a recovered wallet the Ethena launch promo", async () => { + await mockDataStorage.setItem( + ETHENA_LAUNCH_PROMO_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS.PENDING, + ); + + await recover(); + + expect(await mockDataStorage.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID)).toBe( + ETHENA_LAUNCH_PROMO_STATUS.SEEN, + ); + }); }); diff --git a/extension/src/background/messageListener/__tests__/resetWallet.test.ts b/extension/src/background/messageListener/__tests__/resetWallet.test.ts index 709ce68693..f9d3cbc7d9 100644 --- a/extension/src/background/messageListener/__tests__/resetWallet.test.ts +++ b/extension/src/background/messageListener/__tests__/resetWallet.test.ts @@ -23,6 +23,8 @@ import { CACHED_SWAP_TOP_TOKENS_ID, COLLECTIBLES_ID, DATA_SHARING_ID, + ETHENA_LAUNCH_BANNER_DISMISSED, + ETHENA_LAUNCH_PROMO_STATUS_ID, HAS_ACCOUNT_SUBSCRIPTION, HAS_SEEN_DISCOVER_WELCOME, HIDDEN_ASSETS, @@ -52,7 +54,6 @@ import { TEMPORARY_STORE_EXTRA_ID, TEMPORARY_STORE_ID, TOKEN_ID_LIST, - USDT0_LAUNCH_BANNER_DISMISSED, } from "constants/localStorageTypes"; jest.mock("stellar-hd-wallet", () => ({ @@ -118,10 +119,11 @@ const OLD_WALLET_DATA: Record = { [CACHED_SWAP_TOP_TOKENS_ID]: [], [CACHED_MEMO_REQUIRED_ACCOUNTS_ID]: [], [`${CACHED_MEMO_REQUIRED_ACCOUNTS_ID}_date`]: 1, - [USDT0_LAUNCH_BANNER_DISMISSED]: true, + [ETHENA_LAUNCH_BANNER_DISMISSED]: true, [HAS_SEEN_DISCOVER_WELCOME]: true, [IS_BLOCKAID_ANNOUNCED_ID]: true, [REBRAND_ANNOUNCEMENT_STATUS_ID]: "pending", + [ETHENA_LAUNCH_PROMO_STATUS_ID]: "pending", isTestnet: true, }; @@ -290,6 +292,10 @@ describe("RESET_WALLET", () => { CACHED_MEMO_REQUIRED_ACCOUNTS_ID, CACHED_SWAP_TOP_TOKENS_ID, COLLECTIBLES_ID, + ETHENA_LAUNCH_BANNER_DISMISSED, + // Whether this wallet is still owed the launch promo. Like the rebrand + // status below, create and import mark it seen for the next wallet. + ETHENA_LAUNCH_PROMO_STATUS_ID, HAS_ACCOUNT_SUBSCRIPTION, HAS_SEEN_DISCOVER_WELCOME, HIDDEN_ASSETS, @@ -308,7 +314,6 @@ describe("RESET_WALLET", () => { RECENT_PROTOCOLS, TEMPORARY_STORE_ID, TOKEN_ID_LIST, - USDT0_LAUNCH_BANNER_DISMISSED, ]; // Not top-level browser.storage.local keys: the metrics keys live in page // localStorage, and TEMPORARY_STORE_EXTRA_ID is nested in temporaryStore. diff --git a/extension/src/background/messageListener/handlers/claimEthenaLaunchPromo.ts b/extension/src/background/messageListener/handlers/claimEthenaLaunchPromo.ts new file mode 100644 index 0000000000..df6c45d7d2 --- /dev/null +++ b/extension/src/background/messageListener/handlers/claimEthenaLaunchPromo.ts @@ -0,0 +1,32 @@ +import { DataStorageAccess } from "background/helpers/dataStorageAccess"; +import { ETHENA_LAUNCH_PROMO_STATUS_ID } from "constants/localStorageTypes"; +import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; + +// Every surface unlocked by the same broadcast asks at once. Serialising the +// read-and-write means only the first one is told to show the promo. +let claimQueue: Promise = Promise.resolve(); + +export const claimEthenaLaunchPromo = ({ + localStore, +}: { + localStore: DataStorageAccess; +}): Promise<{ shouldShowEthenaLaunchPromo: boolean }> => { + const claim = claimQueue.then(async () => { + const status = await localStore.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID); + + if (status !== ETHENA_LAUNCH_PROMO_STATUS.PENDING) { + return { shouldShowEthenaLaunchPromo: false }; + } + + await localStore.setItem( + ETHENA_LAUNCH_PROMO_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS.SEEN, + ); + + return { shouldShowEthenaLaunchPromo: true }; + }); + + claimQueue = claim.catch(() => undefined); + + return claim; +}; diff --git a/extension/src/background/messageListener/handlers/createAccount.ts b/extension/src/background/messageListener/handlers/createAccount.ts index ad56571fea..18c964a5e1 100644 --- a/extension/src/background/messageListener/handlers/createAccount.ts +++ b/extension/src/background/messageListener/handlers/createAccount.ts @@ -9,9 +9,11 @@ import { DataStorageAccess } from "background/helpers/dataStorageAccess"; import { APPLICATION_ID, REBRAND_ANNOUNCEMENT_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS_ID, KEY_DERIVATION_NUMBER_ID, } from "constants/localStorageTypes"; import { REBRAND_ANNOUNCEMENT_STATUS } from "constants/rebrandAnnouncement"; +import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import { clearSession, SessionTimer } from "background/helpers/session"; import { storeAccount } from "../helpers/store-account"; import { APPLICATION_STATE } from "@shared/constants/applicationState"; @@ -77,11 +79,15 @@ export const createAccount = async ({ await localStore.setItem(APPLICATION_ID, APPLICATION_STATE.PASSWORD_CREATED); // A new wallet goes through onboarding, which must not be followed by the - // one-time rebrand announcement. + // one-time rebrand announcement or launch promo. await localStore.setItem( REBRAND_ANNOUNCEMENT_STATUS_ID, REBRAND_ANNOUNCEMENT_STATUS.SEEN, ); + await localStore.setItem( + ETHENA_LAUNCH_PROMO_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS.SEEN, + ); const currentState = sessionStore.getState(); diff --git a/extension/src/background/messageListener/handlers/dismissUsdt0LaunchBanner.ts b/extension/src/background/messageListener/handlers/dismissEthenaLaunchBanner.ts similarity index 51% rename from extension/src/background/messageListener/handlers/dismissUsdt0LaunchBanner.ts rename to extension/src/background/messageListener/handlers/dismissEthenaLaunchBanner.ts index fd163574fa..2c952f8a8d 100644 --- a/extension/src/background/messageListener/handlers/dismissUsdt0LaunchBanner.ts +++ b/extension/src/background/messageListener/handlers/dismissEthenaLaunchBanner.ts @@ -1,11 +1,11 @@ import { DataStorageAccess } from "background/helpers/dataStorageAccess"; -import { USDT0_LAUNCH_BANNER_DISMISSED } from "constants/localStorageTypes"; +import { ETHENA_LAUNCH_BANNER_DISMISSED } from "constants/localStorageTypes"; -export const dismissUsdt0LaunchBanner = async ({ +export const dismissEthenaLaunchBanner = async ({ localStore, }: { localStore: DataStorageAccess; }): Promise<{ isDismissed: boolean }> => { - await localStore.setItem(USDT0_LAUNCH_BANNER_DISMISSED, true); + await localStore.setItem(ETHENA_LAUNCH_BANNER_DISMISSED, true); return { isDismissed: true }; }; diff --git a/extension/src/background/messageListener/handlers/getUsdt0LaunchBannerDismissed.ts b/extension/src/background/messageListener/handlers/getEthenaLaunchBannerDismissed.ts similarity index 50% rename from extension/src/background/messageListener/handlers/getUsdt0LaunchBannerDismissed.ts rename to extension/src/background/messageListener/handlers/getEthenaLaunchBannerDismissed.ts index d0e9d6f350..7836c09fc9 100644 --- a/extension/src/background/messageListener/handlers/getUsdt0LaunchBannerDismissed.ts +++ b/extension/src/background/messageListener/handlers/getEthenaLaunchBannerDismissed.ts @@ -1,11 +1,11 @@ import { DataStorageAccess } from "background/helpers/dataStorageAccess"; -import { USDT0_LAUNCH_BANNER_DISMISSED } from "constants/localStorageTypes"; +import { ETHENA_LAUNCH_BANNER_DISMISSED } from "constants/localStorageTypes"; -export const getUsdt0LaunchBannerDismissed = async ({ +export const getEthenaLaunchBannerDismissed = async ({ localStore, }: { localStore: DataStorageAccess; }): Promise<{ isDismissed: boolean }> => { - const dismissed = await localStore.getItem(USDT0_LAUNCH_BANNER_DISMISSED); + const dismissed = await localStore.getItem(ETHENA_LAUNCH_BANNER_DISMISSED); return { isDismissed: !!dismissed }; }; diff --git a/extension/src/background/messageListener/handlers/recoverAccount.ts b/extension/src/background/messageListener/handlers/recoverAccount.ts index 55843f2516..db9321a589 100644 --- a/extension/src/background/messageListener/handlers/recoverAccount.ts +++ b/extension/src/background/messageListener/handlers/recoverAccount.ts @@ -15,10 +15,12 @@ import { ACCOUNT_NAME_LIST_ID, APPLICATION_ID, REBRAND_ANNOUNCEMENT_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS_ID, KEY_DERIVATION_NUMBER_ID, KEY_ID_LIST, } from "constants/localStorageTypes"; import { REBRAND_ANNOUNCEMENT_STATUS } from "constants/rebrandAnnouncement"; +import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import { clearSession, SessionTimer } from "background/helpers/session"; import { storeAccount } from "../helpers/store-account"; import { KeyManager } from "@stellar/typescript-wallet-sdk-km"; @@ -84,11 +86,15 @@ export const recoverAccount = async ({ await localStore.setItem(KEY_DERIVATION_NUMBER_ID, "0"); // Recovery is onboarding (also the "forgot password" path), which must - // not be followed by the one-time rebrand announcement. + // not be followed by the one-time rebrand announcement or launch promo. await localStore.setItem( REBRAND_ANNOUNCEMENT_STATUS_ID, REBRAND_ANNOUNCEMENT_STATUS.SEEN, ); + await localStore.setItem( + ETHENA_LAUNCH_PROMO_STATUS_ID, + ETHENA_LAUNCH_PROMO_STATUS.SEEN, + ); await clearSession({ localStore, sessionStore }); diff --git a/extension/src/background/messageListener/popupMessageListener.ts b/extension/src/background/messageListener/popupMessageListener.ts index 6eedf562d2..fc9a2669ef 100644 --- a/extension/src/background/messageListener/popupMessageListener.ts +++ b/extension/src/background/messageListener/popupMessageListener.ts @@ -91,8 +91,8 @@ import { modifyAssetsList } from "./handlers/modifyAssetsList"; import { getIsAccountMismatch } from "./handlers/getIsAccountMismatch"; import { changeAssetVisibility } from "./handlers/changeAssetVisibility"; import { getHiddenAssets } from "./handlers/getHiddenAssets"; -import { getUsdt0LaunchBannerDismissed } from "./handlers/getUsdt0LaunchBannerDismissed"; -import { dismissUsdt0LaunchBanner } from "./handlers/dismissUsdt0LaunchBanner"; +import { getEthenaLaunchBannerDismissed } from "./handlers/getEthenaLaunchBannerDismissed"; +import { dismissEthenaLaunchBanner } from "./handlers/dismissEthenaLaunchBanner"; import { loadBackendSettings } from "./handlers/loadBackendSettings"; import { saveBlockaidOverrideState } from "./handlers/saveDebugOverride"; import { getBlockaidOverrideState } from "./handlers/getDebugOverride"; @@ -106,6 +106,7 @@ import { clearRecentProtocols } from "./handlers/clearRecentProtocols"; import { getDiscoverWelcomeSeen } from "./handlers/getDiscoverWelcomeSeen"; import { dismissDiscoverWelcome } from "./handlers/dismissDiscoverWelcome"; import { claimRebrandAnnouncement } from "./handlers/claimRebrandAnnouncement"; +import { claimEthenaLaunchPromo } from "./handlers/claimEthenaLaunchPromo"; import { callBackendV2 } from "background/helpers/callBackendV2"; import { getCachedSwapTopTokens } from "./handlers/getCachedSwapTopTokens"; import { cacheSwapTopTokens } from "./handlers/cacheSwapTopTokens"; @@ -595,13 +596,13 @@ export const popupMessageListener = ( sessionStore, }); } - case SERVICE_TYPES.GET_USDT0_LAUNCH_BANNER_DISMISSED: { - return getUsdt0LaunchBannerDismissed({ + case SERVICE_TYPES.GET_ETHENA_LAUNCH_BANNER_DISMISSED: { + return getEthenaLaunchBannerDismissed({ localStore, }); } - case SERVICE_TYPES.DISMISS_USDT0_LAUNCH_BANNER: { - return dismissUsdt0LaunchBanner({ + case SERVICE_TYPES.DISMISS_ETHENA_LAUNCH_BANNER: { + return dismissEthenaLaunchBanner({ localStore, }); } @@ -654,6 +655,9 @@ export const popupMessageListener = ( case SERVICE_TYPES.CLAIM_REBRAND_ANNOUNCEMENT: { return claimRebrandAnnouncement({ localStore }); } + case SERVICE_TYPES.CLAIM_ETHENA_LAUNCH_PROMO: { + return claimEthenaLaunchPromo({ localStore }); + } case SERVICE_TYPES.GET_CACHED_SWAP_TOP_TOKENS: { return getCachedSwapTopTokens({ request, localStore }); } diff --git a/extension/src/constants/ethenaLaunchPromo.ts b/extension/src/constants/ethenaLaunchPromo.ts new file mode 100644 index 0000000000..a1575cc8ba --- /dev/null +++ b/extension/src/constants/ethenaLaunchPromo.ts @@ -0,0 +1,9 @@ +/** + * One-time full-screen "Meet Ethena on Stellar" promo, shown to wallets that + * existed when the launch build was installed: `PENDING` until shown, `SEEN` + * once shown or never owed. Fresh installs are marked `SEEN` on first run. + */ +export enum ETHENA_LAUNCH_PROMO_STATUS { + PENDING = "pending", + SEEN = "seen", +} diff --git a/extension/src/constants/localStorageTypes.ts b/extension/src/constants/localStorageTypes.ts index cbcfb1556d..feada41eb8 100644 --- a/extension/src/constants/localStorageTypes.ts +++ b/extension/src/constants/localStorageTypes.ts @@ -32,7 +32,7 @@ export const HIDDEN_COLLECTIBLES = "hiddenCollectibles"; export const HIDDEN_COLLECTIBLE_LIST = "hiddenCollectibleList"; export const TEMPORARY_STORE_ID = "temporaryStore"; export const TEMPORARY_STORE_EXTRA_ID = "temporaryStoreExtra"; -export const USDT0_LAUNCH_BANNER_DISMISSED = "usdt0LaunchBannerDismissed"; +export const ETHENA_LAUNCH_BANNER_DISMISSED = "ethenaLaunchBannerDismissed"; export const OVERRIDDEN_BLOCKAID_RESPONSE_ID = "overriddenBlockaidResponse"; export const COLLECTIBLES_ID = "collectibles"; export const IS_OPEN_SIDEBAR_BY_DEFAULT_ID = "isOpenSidebarByDefault"; @@ -40,4 +40,5 @@ export const METRICS_USER_ID = "metrics_user_id"; export const RECENT_PROTOCOLS = "recentProtocols"; export const HAS_SEEN_DISCOVER_WELCOME = "hasSeenDiscoverWelcome"; export const REBRAND_ANNOUNCEMENT_STATUS_ID = "rebrandAnnouncementStatus"; +export const ETHENA_LAUNCH_PROMO_STATUS_ID = "ethenaLaunchPromoStatus"; export const AUTO_LOCK_TIMEOUT_MINUTES_ID = "autoLockTimeoutMinutes"; diff --git a/extension/src/popup/Router.tsx b/extension/src/popup/Router.tsx index d534d5781e..7a31609ea4 100644 --- a/extension/src/popup/Router.tsx +++ b/extension/src/popup/Router.tsx @@ -41,6 +41,7 @@ import { SignTransaction } from "popup/views/SignTransaction"; import { SignAuthEntry } from "popup/views/SignAuthEntry"; import { UnlockAccount } from "popup/views/UnlockAccount"; import { RebrandAnnouncement } from "popup/views/RebrandAnnouncement"; +import { EthenaLaunch } from "popup/views/EthenaLaunch"; import { Welcome } from "popup/views/Welcome"; import { DisplayBackupPhrase } from "popup/views/DisplayBackupPhrase"; import { Debug } from "popup/views/Debug"; @@ -260,6 +261,14 @@ export const Router = () => ( } > + + + + } + > } diff --git a/extension/src/popup/assets/ethena-launch-banner-glow.svg b/extension/src/popup/assets/ethena-launch-banner-glow.svg new file mode 100644 index 0000000000..8df48f6fcb --- /dev/null +++ b/extension/src/popup/assets/ethena-launch-banner-glow.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/extension/src/popup/assets/ethena-launch-coin-dark.png b/extension/src/popup/assets/ethena-launch-coin-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..8c218cb546423e3174a8f444ef908354b1a8fe81 GIT binary patch literal 100511 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ǩ>mhj?UHfQs(iSjsb+DkGBf2d%>t zjc0-t%h=ek)=obvGsTvmQM_mbVBiwZSM^7Q?k-2mmc5ZmNtjxJx;lWKv?7Qe6@>s^ zi?op4W&wP=tYaEw(l|8KpANkBTKdbs_>1(1U;ZPl@Y$f}DfJs!4~|X`yLi-Y*iik@ z5B)%DQ4csbR9fo={sE!_bdQe!>~m*;`jo+4pss5Gd-UABQMMXp_D^N7yk}`oI&$c( z^!#%>(~B?ec9BsEyaA*Yl98{n_I$lbD`hT|8-dZn>#Bb@Hh?@0pb7z5Fb`d!O}A^c z7vzM-9?qRRok}A|%d1<5duM8De(mZ{ens6MGQD_Q$|bO%ft?3aUEA8((^lPy4Tw6s ze(8DrE8wnL&P0!KO~YnlC(Epkk7MdKsfD7(1?;09)T>o5vj5_FSyr^D!qan(%EOfk z-J*f1=(We|K+lQV2-=VymCp4Jw|$EEhN7s5j_NvP_Mj89Pg$deuLC@(-2dQ!l};)y zOB>|DT^I)`f%^Ah-;ki-Ra_&y;6E?ITvWRvB2DwY`}FX`k4cTBUM=NDa!Sj9o3|6|G{0tF3pRvjtd zGXm72*UoccofvxS?*??hz39cysb=u&TfRaA=QUdV>$UXQ6HjZqymM-h;$3rDxFD3S z(%02`~Wqn8AjP zt81{#(C$jCan42w9?%n;0C@F$^cl@3K7FO!gCn^Lm{9c%5pqQG0xdZze%bANS4~B5 zd|AcFQiKUIRA!_`%|ZqDiJ#*#OI5223Y^fbqOK{9NFxBxevybcDK3I>IIW_5L|}h@ zGO>y9E+T}7k~aw#yR!rJRE=!P*)#({L?wgl=H?#}a@9!`uyInL$HvWt$^(XknOs*~ z+|LtEMWWJ%&S#dv6xlCA;#bev04FAKrFT7BrUz?q*Lc8`R3V2CznT8(uOCity|rIf zBvJ`UIKUcJ2l2=c=}9G%zWY1BT}$FF*S-BC&)fz806+jqL_t)rd=ZUx{L+R9+EL5o z9=g$6VU^6&d_g+Dlm+hrsyQ|MPJYv- zHKi?Dr7}uPW##gl-ylUpGpjTxww|6I71C^ZT6sQm>Ya4{)Z68r@D=_el**qGPZ0*mIeTska$xvMUt0aR^K@S~u#*`*e(K`%?D>&-vNc==>*XkNoMe4{3%d1Bo<@Dm1Z<+()k*j=>M06M@Qsf!3@a&VrbsTcAjb zBz?rKoRl}7^G=6_KMgJ6#WjO)j-yxtV?ffqSPkF~^qh0;Ry8mMzkq(`O;haD8-fjQ@^#FPI$ji)>MX#>%C~K0H=2+=eBOIz3^zpcJ zuU%jZxVJR7XsO?2>QNt(rOd>B<&YBBrs#;flK>>@$C0qgv z7TAktqN(1!4YhP_qz28Ns6{kBn#Lvpb6rO@SUNVPb3Baz>hc`RC)Nr~PGVa2Ic*jU zj{=wg3_xvUcvwA722f=kDi7+Jd(@e>aFe|2A`TtI<=0vpx!_HOlux(-5&;C@6KN`T zM5+K&aEaaqTf$L1CmJ>&r5ptXugB*EFg z;Z!&qGWTnPZ_F?`DtU-I0}v4b^H}9jTMP=|@GHt7qf{gy0WG8Bo5-$r{~%Z#0r-lV z!5zN(_fG}<9NP2^7=FY_Z$zHkhZ?|w2SsfKKvo+#Fsij zWQNWI>Upq~yv11zrt)PXfK@(e^yon|N1>u`2i$dHMKdK!7J!|33~#;pTKeWUpApEP zWo1ew1#m}(c;1}tt<6<;-nmV(X&^tBptGwmfqY3{9(siSqVPMlTx$@~VJYkVK6CO& z>D;NqrOv6n<%as2@4oh*KYNoi#iNKb-!5J*g%Visz}{3-)6)>RLJf8`o)lmL>grIc zhpsE2E?qi3^>G9HsCw`tI=P1K7fXtZS^^b4FuHX2EP3PA8yy*yx<-2N2F>uBe+0x( zslqod8F;cEAvi0yCNF&AN~Lx6as`E;LLH2ab|uL+DX_44gcug}F{c-l`8S6-=)K|d z@8#xJATr+`D)R z?Xh%TcHj6Tmwps0#}U}`E-cgR+FQ2XA~&}B@TaF<^wy>7(DPu%@*KFU=Ppo(W?F!1 zfS;KvsgaNwWTuWyCz+h2R_h4jP|J2k*MjknU0X{OV30U-A5_19gIHeI$s z{3!>Di|br|Jv-I;j>fcG3*hlZH9Dfrzon9?8a*)ERdcSbs~N!yUQ#!*tP2K>;=jQ*1cH4A@TqX$c+t3=3tbMYAQ z1sEVQod7!kBw{(LD>ncI@BoaYnMH_Lx-S6L0w_@T6bj*imvR$U$YajoS9~VGGeq_%{TX?ojYID*97L5 zuCigT;53luR zxVCADUD<*I_=vLk>T9)L{>t*W-VKAdKzy#}9t}nwRLwnitYoHT5-GFDtg=DvVs#84 zFEtE$aNpa$ebNh;Rckg>3%la#{Sj zbV^`BE-CP?;xCn3zz%xqBNJA?lt+fkC9Gd2R1wD~hSSu2(laqyD=q{`*wiBqzbK9^9n@MROgOC;jxhjjEep@HAa zH(i#lxZ+A}_{@6a@QW}L=O5x&{+tPyZzYVtxIw~b$&i$Uber=K6nN+)D4zfy{3*ja z^^)neA3pSU`s!D|>e-*jglQ(v0zl=Nd--6sPFAhZ0L#rE-%jv#`N$nM=8>}Vp!hR0 z7~#SzzFJt40QE}5kyAq}@U2oWpF#Vco<5m99!a}ie>v@VdSm+d$M1EylaZqQNkI+i z?45Vsl3sr0^>kWm2a#C! zV4o6zV=g$Q6Psoxig2QmVIs%M<(=-;96x?Eb!+ni1FKXB)EXLrfx#h9dNDGDcf0~o zzlAY#^#T`|;$OuNpi<2d4PXuw6_pN)9KI$>OP2&t7%d#R;NUCP4p`>Y3IHZ%CM|}+ zL=_r-92S9um1g#`9CMUP^n^OSa0I*m{{S+1ldliRDdZ@*>s&;IN$(Fhf}kOt&>~x{vYr5hsWDV|dQ}&+Hn!IJmU>t{E{9Ob><}%g z8R{G!g&!6F-DiYBL`A34smCrA#lYaOZNVcPw!s+icWs4Ig4D~_zP7GTY#2-uQ0dbO6vzv`KnHQ}eMeNW5Bwd}y@lkfOEdE&4Z-a430$^`MusblGa z^wJY!L!L(f&%)}2cfzOq!i|odLDPA<_UtBJ&}JRHdgw8Ls;@?wMMmQh%N8@(iS^U& zT`#9cAAd$2k4cwbA-~lvdKZ|3b?depQm=M`n)U8cJl|a2${}>9Xiy#LtE1f5*ivrq zX!nd%22wAaKb~qQ4$L%FjoeUO*Zvcf+2V2Ol)!=ob{@f++AdkIl^aGit8_?%rGpwQ z9n`GB5$n+f+T-KuxoeO#p8@b=Weu8^rKZuzU@58@t@@{G!Ha)FE9sSN)=1F=ascK7 z{THe1 zWHBu&Ei(8JZMcb-J-E*~qd)R5qzY*kkTYfw;|6k|W60&ll?K$QJAd!} zA_DBKrqR`O?#<@B<-!r5gXxN&%PVd`cmp1?EYZ~d-rnWqrAvEs_DUVHjC-wbt}PX% zo9@+eyR4cRz2E@MD1U)G;4bh4vovRC0V7 zqGxA8vy;b<$gceb4W#bIs>Qh!EAisP0ASa+KwC@c-g|CS0ig16ar>H`&bNWx4au~g zPp9~^-1Ds8=i&2*Q&;Joa&>+653aiZiyLz3EnY5x5?Ii{K3LUQqY7R>Hd!hUjtbmI zW;7V8-nx2*BLd42jikygaG!U|-@SEN$pGx=;Tg=LQn7y|CXe*$ndwQz<){+SU$}5V z6Fyp{u8Fx&@$4zS03YrHV5ndLNdc-s>G0eUB}x%%T6XkokieQT&=>witl%Mkg`s1| z!fCUuQAlTJVU!#}JInd?-xnh+*1i@ZlZ&0HR& zXAU8l`I(WKqWo|o_NtVJ?uh3@!O_d+PQKBM!Ig3lqMNt0DHE)UA^`-Ygb8Kge)O#d~tEl zJAkZeL^NKY&O@oOsZmP`Gv+a-ow!bx8z=V9w3G%`RJUCI{ls28E{zgc(7-;?FwPES zHA7=k3&;v)RHkVo0`*}HhH_=^Oic3P)Oy_>C=E*(wqfIBRwKV~nXIG_u>67U#GnvE~0cfdy8IZDD)d-xhe}Os7&@AZkE2GXQMAm&;-+w{rd8Zuw zbwq{41+1Z>2!AR&17Y+69cV7`LuI$GL!j5me?-MMA3;^9TevIYkuFCOr_v;3e+P<$ zTTaS`0qFjV=hADhz9I9$ebN(4cMb4}Ns&+F2w6fHc3k@JKl?-JJHF$)rLPu%YFPyu zEg_BoR#(c5KLm;YEK^7np&=+7kvca+;GN^>Hv)|2Fv$&_C|$lPL%`JluPbUO`+L{x z$e_Vn8IAlxuLi*rfCQQXc68sBr3iEnebIw2_|9S#BmM?+A-~f!xC8KU^6YVkIi$uZ z)OvJi*67gCd2L+2Tl)4lDAN*Sw@SkDkZJObDdT%p5MkktrG#r6C4w zZJkobU?0pf)fYG~l8h~?`vvMF zBhvzOfwg+%fb@tI?yRF8W{#t>k{K&W$6jLQ>9EWnIY%-bCXN?nEzqXHD@^t-Uc3+h zZeR&u9f4jmP+PR1l&X(`27rlwB%;S>AJ;2<3OR963AttpYZmAcQrSj^+5dpL$R9^g z=@LAV13y*XHh^6~VNRq6>MLRY7V(0K;}9=SU2utzU_&JQ@grT(D<5__Amk}PlZb^6 z^vDBXotGY(NnC&OCx0#zK{lU`nUOHhf~j#rT@dNG@f;jYpa1EfOyBXHpA@*O=U&?= zaMw&Tx~9ym6uoYoH<;*NK6coz(mIN&C|$b%K7*fALu7e7cQ}P~`UL=UEcfUQhyrV< zl`m0;10ONttmIs@25{n#4k4QLNfi4-Ux2*as7zEw*uQ&;fuiRwAXo1`uM#Qn$L1Up zNKVu=%`MITIy`aoP{wfaioYw`S<|a zMqjD|M|9Q2ASnPpQo=?(W|&6re1sl4`gf^l+_M+31Mv8rI(^#q>orn|oYz1p=8pkP zks2nF!vgj$triIA7T>5V5RqN(1$N!BIn-vcsBrmJ)kPk)|I6TxX-1gLon_86HMC=ZR7%l$($ z0_a$=5pbt>KCS`LanvokcW)a2N58ItR9VAVk4`xH_DSh|&zwH1a?k*!dNYHvl3{I= z0F5XfbeN}4pVBTpOwrCdVP1U$OXX7BR?3vh4oLthI5byZa8uz~Z)Hed7%VeumN|9> zw{#C5mLJ9nB7>TF6>6G-zcCahq7|VNkM#4seB%(*14gC`{#IiUC{iHAVRC1hik2gy z85XUMp>e{3{jN}Lzf=7TJZU7C_)AJVw(hq+6`_dQx&)-aU z-Sgp8Rj)6iD(yRK{d-o=sKH~L!vn48!x?lHUzbn5l1@=}E@J)ok1HNzKYmOn0gUH( z=OS=Eb6zv8Y z85o)rumj+EcBxGnHDIc1sAFRAR62F}$#z|;7Y0o|QAzjci3eqm&3=~XurZ6|liAjN z1_TA^6+f?uINjY{s&ILiY(odQ5$}J#WSuxF97QX_=Di$v5s53kR|ae^3fwD}F$yqE zB%9$#z^+g94XV6M&o`huS!fM&A&t|K(D2Cdef8G^fklR($@jWitsNR_1DrqgiH{&U z0*rC^j{878F+o4h(#FSRCU`;M{(Hao2eRO)@i>Je5Jx9p4Z#N;1|Bl^RHJa>&>&`mR6A@ij_#cXmEOGaYn6@ih}(t5s~o4T z+})!`*669*B|3}3Ph{S5SvKU6Bjm%KQ-CJkKH3Mx$ zC6YniYswhNX#mt?*B5{RSn{RRAR>F`XCo=IIZ2UG3L&}TaDd$iq!p`XQLVV1zW zZ~q09frlQ{3;9r5x8(;Ly4NiGOwH(6@A&BO?8Nv`X;L=F6Pj&0nFmd=S*KUx*`rdY zu*M019{W+oge6rl^zUii`qf%X_3_oX{--!3bprD=F# zMqgkP2CV3@V?|Sdxnf2}^CkRa*dc7==h7mToF-{!XXGaXzVb%C=W-}lCiQDji4%es zx6Vy*qbSilga_P+JD1(y&V4*R%B4s&(u;D6F9K$y@{SD4@~E-7BVD)o+OW(r(_DbM z=(gO~+ml{+@nt$7`WTayj&%6NU@ob-p%L)&$5$t2zBC?_8mMAVfVQSO#cEwP+T3|y zboU>;GFM=8=`6YyMhPrTU{4RKT0E3iZT{if*44{?pk{n*`NZfzGN_LY3M2&X+KLS; z7^b}g>RwI&Kv&N)_Mi-Krxz^!W(mMwy=tX&?<48RVf9>O)<{L52SsJaB#vI}&0B6x z`}ZFx4Gj(C$|_N!4!a&y0IT91AQt$;oJT5o_~B%rtgfyxZP>6WU3cv@TDNA{AYSxD zjY0ZRKh z%vY9)fGvPTW2gbZ(uMOHH&Ac<)?2r!Oh?^oG>a^5lz~K3f#7AGwHg4%J}_DBk;?0i z+ipn@Xg&0;w`@&4S^;sURI3SSS}H=z;4=E`FBPRLdwAzuz%MVsI-ehwEw152R-HLl z`4WCekma(B{*ec1%z3=a*Os1tR#Rw3fMol3e(<~UVhbS8_4zk^2NZjnSUY|1MlPN z(0CnrrB$cx0vqa^s)wsrTv5OAGk-q%=6~WP`>z#&f)1j|Rqxf; zes9g_$lA%#{_>OneR6y-O^yQWEG3XZU0_bHhb0AAPJmrym|SCXGjyDJ4@=grZjwpk z+i&eNxMD%TdLgd8LLh)@^R=60`Z%bGOebuoK_x8SedsDxQ{EA;c=W1B3O1;kE?iVz z0IF}c=nxowI#*Y*57?2qq1BUM$J?WW_Teoge&wawZL(2po zlHdoa#DRF>HapfeQCSFdG^n_|uQ%Pk{pR#->dD`A=N)PN#*L||r88-hBdOKUQ6m$2 z_^gYUzM|;0Tc%tNPTO*le#mP9PHP?XSX^Ro2?&bqEdi$q{k`(OSLq`jvYJI zzz%6l20*8Q2w-=r_!ajmvk9ppX#g#hv!8;RNm;H65kW(eVJ?d{rH?M>7(p#?!4SKN?`nm`;HqN4+M1>~?>2`H5OSj#2tH3XMYNQ9HxP(jb00}nRrs3JMdzbC&0}$aw3?EL= z$q-fE#H<_yWFS(k%-w_p%#+VS@-Z|y3RK}+xfHi%A7CmfWs?14m6LSv&@s`J)3$9l ztL#~OCH6g~9N_JLgH0i0_*oV>D2z!vg93ThL}$5&>#n&fefZuxrLy@@+J5V;Y3=$A zsjjglO-cncp&eFOvR+m-Zg~0fQ7di1IGwAxD0W3W=ZRS20qcm3`(1nt?0|6uFjgZ;bqwn(v8JvmZBTw!uGE|hEh|h^ z57wGzIdy1d($li=dgBdtV^Y|R7PT?J1L$*U6<}{0d+LMg0+Kg1HE4P2uF`Pr>b3RD zZvC^-gMU?g8onn_i?{FR5?Ii{p3O_#MygY@B7r`>Pt z5(slo3?J->h01Ph*U@hb>hGuA1yhn zfm8IYJ9a!JV6SoA2h@>4;q*5lMJ5hXbedFJAG#FY$YS3@CdIDMiHb1z#WkW6#|L}} z$;_OV+{%*$AaDJe8^9po;Ug!s+tS&zb?XgUk0(}v%v=oI0FIB$3#mwkTPJ7G(%_$- z7d=ZRI1OsWH(^og(^hd?ZoDpi>qqW3&~MwiEiGTUCRNonV+vauo0KX-K+hP3EKJm~ zmpwfFd4oOtBN0g+>2Yg0oN|^V|NF{xhiv;J(mK!*eU?4yIFDFOSG22KHXKppi<<#aEd9(q_IxR+wLCYY$JjGmp|(1HDLOV2xK z>lgRDsigd?642wjb=x-CZ0{9~)FuW22fGp%_q+r25DCFA03`0`{Nhbf<56mD=}1?r z!C1F$jZGivWBM?ECoVpUsUJ4p{@T~R7QkSTfUlE}v?4LnXC|3dkv_MMW4Xd*FR_nQ z0E>!$P9q@Rtb(^lfh;E%9OdL+F}dn*cz8f+n4xt1#Od^kmYKcg>dVvGwQIak8(%8W zpkgWx;*xH01&IuF#g!DH7bx=l*j0+n$%m!tsjjNkDxH04>z3=&{U5$pK!2|Q@TOAN zl4XL?I_;`8qn(V@8mPyv=Loz9z>_9lSoR=g3&4*~(h4Uno!UO@N{9hC&pYOFk?9;S z6J!>;qhy1?egHf)c==D)g44V_1MH0RNX;byYCPE9(b-{D6>=6)D3h+P&b05%H?`jU zG38TS1>zpV5K+-n2k7}IpuwZT;GU&40Qx3b;xyDXRSlPVJBHTW@PDWM53^46;<12A zV8H|XiVyw5T~*^F+a?E2X;H5Mfx2{yS_gy0y{6q;mu^=*b-%oNfn^1N{x>WJ=&AeE zORhiEE^HP&B>m+1v!`vwN3R%wrs89jf%-<4F*4CRso8*MTrqgw2BZAoGc-hx8<+^F zC@!X=LP1B*5qX#xwQ|+kbiHN~4rl<3F^-wY`rNZG zdrJF_H*VGdb-i@t((MXVh;MejM%jcUAfCX>09r=uk;};ExhTnD^k6zkcKn}JE~K9Xm#QRn)K!=2^wPw?VCA~BGU*N zBKY3&Mo9R}O)#0sVO;F=PbDr5Vx};;V-eH7?$eWJQ;AM8Njj~#P;ILztb}^|R;8=2 zzQTE~Gz7#DE6j1(SYyZ2JH-!Bj{#IVG|(2kb)*H*QTQ={su1yGO_}=C+E|^&s(O2; zYS({#a_^UqWYG|D@mK&Qu;78c@7`azu{1IEp{a`}G|xs+>t(}9{qLK-yoC9C24$eR;z=K81QIt zS-gN$oD2WNUHDia=Pk-D2#|X|Sd#;J#eZ6bk*%j&lbW89HO(O4Ewjge#5%_6m`DZ{7n7m*YDK=5 z<_4MBEU6tXZJZe2_r<@>l1re)VO!T zHEoo6;+{Rb`NYjNGT!;QH{X?!3K{Q#D`%m{1tR?E?{HYi`li(0)}3y-Ws6iT+H+ME zn1lGF&oy{edCyMPmwEQtogP3nz*)T>X;mPCzB4!Srb&n^H>6)sW%+`PBo!8azOma; z>fU>`8$regFcrO^^?06r_C=N9o29oD{H6>cyXt8J9haC0 z2OqOcV{HvpTD{tQ^543ByDU@o=+jtwc0S*A=obe>92E~D758SKdw>IKK$~>6n^UQ| zwIglZv>~lqw@&72;}ItqidH;AZ{llY)4g0@S#V@&y`u~&z0mWdn6YQ7(U#=TFG`heba4xJZBS;V z%2Vmn<$@?|%AKzPu;Vf%TjwPP zhGf;jGQEI5`r0_kvaXqyE%6qC(?B|=jXAuDGgX>e;Tp+DIe*#9z)w&Bx zDknWrsi$Xoy7}fC)vFzI82m!d4*#gw^s1I>0?(6AKI!f009*dvGnhxzd{i6;ACvN< zqY_eJjIV(d<|=~VQ&1|*G~C-^K7dXT5&^H=0}Ur$$|~R<_U7c9nU6z*7j5Np^3(}! zEb&r$cIR{H^r=&}>{zj)*I!4Wg3xnPB1O_JLwMuo#0k;Kzfb)H9Fnrb0#pID05*rq z&GR4C!f-=cl&qz>HQjUP_VnQo-I;2%8ORaY;UDrHyOv{?FqF|0c|5 za_q&+`?mxZJg~Rk_Oop><(eO?x^TF@JaImi0rlxI0XMpJ>(%L4)1il%Czmw);4fNXUM}5p_ z=4viL#+&-6Uqucu!bdLssJBim-xLiEI^S(l$ISZEoIyp?n?LDu&(SJ%(DCC(({6n= z#Hx@~Quh%FjzlW$i<5|m4vZg&;wY}~3Ur!L@e3;GIE@CC*j}E15Cs`aA-CK?%`HcW zZdu$TWMMBr8xXe+bVm2}T1H{%k}f@q4y$WOxY)b` zS>S7l=3OIiQ2>!T#gpX@LBiW!p_2z3QP+$}FW;igpYOTrHjQ~~PyIs^>BzAYYE|h8 zD-j*yRX8eXr8B-QQEolISsSG7YYb)(FpmMSb_CQ7+pIPy_o+|qjmDz z8yjXvs+aXm)UMk*@%A6S9>o7-zfq?DWb8jUj2AqxFWLGt4U<)kpQ*ZVyuCbjM%@kV zk*7T)XX&v6;KF?7B0X$`&g?W));iiO$ZV~;;!-E{$47LNB<{7C~$ASrv1B7WH;LzBZrrbEH< zBslJKEE49le`Y8m|CtwlK?_g(eVAVN29O9h@*BHIN7fz!5l*a+cqXBPS1(>_nloq5 zs^QwDFOwbV>8GDbZ@>Mv)C%L;qOjFK-=a0ki3`ASR*vipOZpg50Qmlak<`)Nk-qKzd$r#AhVCkaT#OsIx(gA8|ZPQMX&DDdA8=EJZxBW>v`8P#(Kg;>w{4!Sr z|IJx{a2PIlVDDakUm9y&_dQjEr~68y#|`Y|nQ^_t44A6dZZOBZQJ^lsj(bh(pck(f zI`rAlwu_1bHc-If^C1f-||m`2`k!wu==$y4dvxwG-9 z&U>RU`r%P|0j~_kICR3_9Jtk=)hLANV4_HqW>79)u_A4`=?1A|Msg1kKKXPvkF`N& zW%;l)Js}+`)5o2jD=M7K+-aF}uqVJr+=?Id+EjK#7=if~r$v(kcqwGS)1A!iTJjkQdKz>-m8%O?yCk-1G88n<;5?KYvIL0t*h06j2b%YpZ$zP>5lq<4h|Xi_?Iztffjb&PgmYHu&^-M2R#J$l6NCHdlA2i%o_ zlrky-J3;oG1;SNVQ0FvjW0@umY7aJEwlsCDd~|B>m-OlKPj>u+BKRju=@MtWfPtMJ z%tPtI8-Fy_xcyf?UK+W$u{3a0){G-k#Yi24D#l>W%kI;rjskN1M{h)x->WD2CC@KB zFFn1&=FZ+UF6)D#fwKaQrPjF{*abq=WK8KcZQP`uW^L(!04LNjyq9r6<3Fx=>vU+` z_%7491C8Z~Dv~Z$TFZQiS4N!FlyNF5F^L8Z2cP1|+1}nJu-otD4PuZlz_*f?Xrl)m zJd9yxU`cT4$oz981Ks@Kf`n^GU5OJJBOng)8(?LL?dj~wRrotj7DwJi(F6lg8RXrA zucd5Vt}OpBszu#~v{nj0-+%FJI;pjC_G*%t)C^u5<)xQiD!p^$9Rbpmbjxj;kFZ3` z53nPacBztSDub~cg*>(~GLe=D^HIbp?vZI8z-M(&#Dec!eAIk}<<#oc>(UihY_gdw@i`0m zv1y-{A;B}x?367$Dl7~KGPsk|0@N*nHrUfbMbfcrh2&}vy7JDqsT_xA+Z(5Ad(Ten z{n8V2(k{B*uO+a6f&D?frkoFz>$m;<9qR6Gsk*pdHF!jCJU#Xaomj*$h>AK!Rx#GI zGYF@*Sry$AH!8YPUUuGcDi<%m7DVdkO=nKLt#w?MdND9S$D3KJ;-C^i|GswJdZ`O` z+u{b`bv33^%P|M;aCM0Na61ey(?+iq?4eRMHFe1R?rNpmmtD;Uj|d|=)F(q zoJsfIb-VW@eNi)M>DkT|GNn@-bG!-CjG|CVsL!I6zAasBz`W7b*q> z(=%12@wyeAoy%_c)1kwUNZ+}5yq`;8fde~5`%r4S_2)Ng!S0Wh&hOU>P=f++y}+C@ zmkE`Ouh}w2;4R=T%o`2nzSqkwkas0h#i9~)Ex$6IJ-$!+bj`%mHf5~Y&Pz_k@{Cla zzIpTYX}@&8!z06*XT$tJRXUxnR=!3>1Uv%xb;X^}!d@DXrc!HHrxG*&mM-l}*I##y zS2&~+6TcX^^O&oEeOi@t`SQN>&8MCc-Jp5Gq~J~Iz%w7zULA2MXpFn^<-RxyXZV?6 z@W~|6`*aS?E;G*2O(e|7R0T7L$hN66qas1B?+H=b6(Uli>=@LmmAVF?r-Ai614U)! zPVD+ew0yzvNWXgY=dF5p?X_3ali%E-^C|W2_X(6o1#&Ga+inexvgx)OQkzr?(J109 zkKX}677_528(QW-(DP?S$*rmspy_E z(GgkA1VjsO$00aBvVwv66z{~S%pPm&TC{Y+bsq3#0v%C&=%V+#q_ty8ufF!WmKb

ecqM34r&DPIb^iV#BGqYke9WJgb?kBWaa(_&I<6fROD}$#n(b3Lo zerHa}l4O?v4=WRU$IskNhL9p`jtCd^x;V1%x-I;QYfuEs4BFkqlwN-M zmGqQ=9zFd@+0VCXF2Kr_%d}c&n?VjUR+0eNL;gYn0FQSCY010H4P_pA!{%$eDBSbf z+yY;hic!*py60akWmuu2GO_;mvvi0i0 zPX)DF4gMf!Icn|WTYB#K=M|3((zzj&OYwaWa_~#X0aasO1kWO220B^ls-9_FH#M^F z%U=y?7k}TcC9r^jog#fu@9jgW`r4mqEZ5fmv#Rrl>XS?!)3kOzD)j8?O`(zj*ck|o z!BSm$tw9U-Sn`X`%N}(>q?)Wz*P5zo8`Eh2v9xCOdfN_TqNmM+sSvJUEm}r)*|J_u zXi}p>g_BfKIRkj3GUAJWu8@^0>Xh*FRc4bK0#GkWI)3ezbHx>x+pH2@J3Og~@Bq}{ zNDm&rZmAg_|N7VM2Nj}mjZ|^RL7qdxxF@{eSrA9KdzU3>H9pZTNVJzrc@$K=QNe!N@~z+S)M)3dX!z29GT;aFGI*a>|v4@=KZj~$c8 zFniP+ZOa&X>8?ly^mv(harwg^cdmhoGMn0ZE>FW}-byX{>}Fd!sa!Atb7et2Ko9A< z&DW_%ctk4}YFj&3P#!gasA@H@GP-iRx6S%91Vv>woni>EsfSX>jA~u%R_XA&wAAeu zH7Lvr306f9A5!8WBY^a}KDAkg+gh7SejJUMcFY5bBEUfoRkn)**|?pH6)wWv`Q#P? zmlZda@FFXjKp~Z&Z~`eV2ggx)&m&NzIe8RsE@}}#Tpc{3`GNDE8BPuaagScQ`RL8F z8Frzc*Fdav^MkUsIm_3MrrkgJX@Zq$2^=g?mt}(EAs=h$m1FvEXsH1a600v~S zyqOS?Zr`>=OB26iE1j6Eh6JM1%M{{B*c^{sMdKhBfn+4--Cs}xj~|Z6f7l-bXXMJ5)O08Mr}NU zdZ(#L1JPFxm+iEmQB_yzwHyHp~1DK!Tr*- z1h5yNt`))bf_u$%YNOs}CMNM#^WvkL$!@*o02lsLn;ESR+1ztQnizbCb!XIjUX{+A zKBY>c-izp{V(1_*zx)ahW*t3xR4>1ZG%$eWNKE6(NOdx(JED8rg}1ksNj=F{=4p>y}xo2O{!0fOGBO7Jr zI;;)SW09?#4AO|d-y6Gme@a>tesg;2nP>H7pm#5;`21e!E)IckAzG0)1r)i7e5ow5 zM?8*7Xe6#%y%t4**+Ex;C8`@5+tQXTH|guGTLb;P@3|P125av$YJ--82M(q;-`p4P zi0T97mEV1_J& zreVNAR8q$QKJfH82OfbCl`3snk%1#FP*5=VQD!*h4wCTB^p5180)&Gv#E=9R{EGO& zB(s`}ZV!HPqce}cHy0HP8V-(-KhtKRB1FGAp5=#_c;T(0LqD&cyq+E9O?k4r7QOg! zZK?Rq(RZ|V{A-DI1)qgg$?ep^IP2l&iK-+HrpONS1;Po+ z?o`IYk2>UgRhkIrN;rC9Ho2~?ZP3iZE!y%e7HEQpX^3aqsP$NATG(DBr@GGX z++`5R5HXj-Lbo!PV@0)0nKTDj(t=3gaYzO`9O|+oH$}=heY~L3PdMk|1eahDJi-S$ zo`|lF=&19ED^!qhm>`~=9-!j-FTxazL=cJG&sWzVQCVtYlyu1eJmt>hG*+J+l9ds? z_jc_@bi)nT3*5*2?f`al0^sQeHglik%k8pFR_7epe*pfbcY?XAPPBOch;K1N9)z*1 z@&3j8;zWW_zkqIWM0n&JHvld*Nx83gl_o1)R~j9a!GJ+qadJFjH#Taf@?(#w(V-p) z_>~v@gLjmX$tffYB-NEx9c9g!hQ=m$WU8v_%cC_bI%gWzKRL1c-yKl&N+}oeEnffs zF98tXk~pd+&c9x+s~?@IYSU(5>RCiJb|s9LH|%$#mtvoIx%DRVGV^l#rFJ}ur~gct z002M$Nkl!YXuBROVIYGv**rfljRMHMejUj zQ3@=)IRdBd+4fqLU*gL{C9fLf~Nh(~yRW4#-UGiQ!lZ~KnS)c7hue@oAwN*4_Q zfDq@nbp79Q|NXL(=~6g7`P>^-9QR5U(P{8Y9RE3+WH$K758lp{gP@XE5Clj-qQ7W> z0(=SP;Eul>3r_HJ!E!^oG=}aJ=6k0Hoet9wJ0i-3CqFzOt{nEj!4vZ{^W!UA1jhp< zRL-CY23bP;1$7p8DXxo|kVxDuC^MV|O8 zWz7^uS%nrXx!kH;cdTj}o|KfW7+sJBPH>@2Q!FrF#A9`DFAv><_NyP7dAzr zxQiPYL1akE4=wJ5wLWq%4?jquCK`YC;~KG;U$#e1z#t&V|;irvC4TsY@7*kha}=gmBLM`ty*P;c{G)=J6`+44trg5Gkv?0J6r zD$%<-r7vHsV;WfDbV^%BP8=`SP7d6)@{`XrhER*Y@3#`TWPp9>ukTUUy0mAesV~i> zTJ>YJsFdo0d+zSJsQTr~>&l{+mZ~!6j*8>gnM$O}Vh|MAjrVJ(qPDdjKs_VNlO;=g zG$ClnFFR;crM0a0??31ne(Tq*b1eqcqo-b@Uc12B03VzNs;a7NMt-}VVD=7xD-63Zy*$Kk6#4vH8TJ?|^D zSvwtm8N*~6xpfrO6?v#L;z6U&AS&ZHm`qlcw9DA!akXOSuN|8#ZI0NBzwfsaaJ72B z3HAR`9=+q!J4?;odP!wPqK`(smh&o&UR}MYe42)*QsD)sX7jmBRrM9`=sC(p<^N^x zJ;3Zbt~<|qozOWT=L`^unG_gAid0UdC|Sw&=e)LOy!Lp;Q9Jg`kUL(>TG~nu3bsd< zEK6E@Em@Xj1=|vpC{Y9m0wj@$92$*`&gpf(`ThT=?&}66@9ymP4MCB8yYIVoE1s%* z>tE-dI(3Smx->R$264>nRNvTg%UBttdYLRWao!0gK{sFS?w8uFrgb@zbDUq%K)k z|77D?Yv8!el}pwRxC&qy6tq;^{uY_GjnSoUuS%<+G z_tdrUGkK09I^AH7AN~d-fF;_u+RBRQI%)85c^YV_yT3r>X3(RNG`dhE2k|T-a$AsE zboq3txme{YsfGcbQhhH!jto+E;;xdSXRCWZYx~ACj}!(sy%RXprXiLod12GzkMBfV zW(THldB0SaiX#W-CxG>5!z9`#<80LNay_RQcoZi}iZn`8J#(0eP#!u7)?9xPtMF4v zcALKJmV6(7;tr$HbN0-6KQrYae@~ER+BCttV8MK^p0@0rG@>Iva^KlU>6C#^4lyv= zjxPo~X~?9~tg({}l;ba5@X7~Uh@yzo8(+z0jw{##&o5vfI=MT|YB`l=&8uPWdEQHR z-r#8Tp3=}o$MJjXcQNyC`Lzr#GJqA-F$mSvHl)$sW2xM<-0%AN3%%^@)9IJJsj(4o zpJnhofBs^+fM&{78#kEyHzy6pUvSqJzX(tPR)cK@^$^8`NCxYA#0S*qZS`>NS|D-> z9qSV(j-~HDx&y8qus0CWyNFY0$awQG14&U9R}TyfBmyo^ zeK$3%B+iA_aH zNC~WUQ3iy@#ns{&Ds~3?$jfDl!_0Z-d(&#_^n_JZ6s+=HtbYgymfbP*HrQJ)gq|wb zBDJpOn(^_M6&$V%kBzbs_tzf!CICkX>N$>RS_43p1BGgnijA8#p{lybB9eez72%Si zTZRd|`spjRI16VetEgVV}aWF50u4HIW3YsN2a811-iohY6;o?9&tJ2XGH zX!`$6&CsXbdAjz0`HP*U)+Ng;m)I18m(rWRPwUtg1?VLvOh3^jczN|Q+sCiCa3%L% z;_B0N7;(&;t5Yp{?SpVH;~0-pC)Q#Rbrvl{7qITz_p}!*$v*Zl9Zd^|)bR?~Fe=r+ zWo4UDCQ@{$gOZ~;EDuP43iLFhVR4C#pQR!5D8PQli*NL#tya96dT4M})HQQGkrJi1 zz2%3}j>jJ76Z%4`!C6vlvedtV!mohOP4M84po{%s7IYs9J`EpsqJL*MFWGrJbJL@@+cFQ z0u|aulq=&*hw{~v({GerlocgrdNP?g3VFGW4S1@%({imIP6p!254U0~R9{>28pi(2 zadg~|9y!K5%L0F~Y2w`ZWqBu+g2(A7@eVeoB}vbLh3Zz$E5dn+{~J#1;U=_U$!yr>G-nd3Ro z0?#L4=k@;^EUkRxq13kIo=OSpeKidxy^+909GO3R;?*8sPw&(pkhY-KV-SWVJiphH)?rEJ|y<^OcI=q3TE! zuxi!nbl2T?r_X-&vj9{0t17Op!9$6-S29Kd0jlAXI)^w2+Qb?|gVN-L6yZBO2y=Oc z8HXDRl!UyZIk{F7m(t4B8`8Vp^?PZ}nl(&BGYbNkD_q5BiM~WH^#GFQC$?>SJpI^@ zy^RTQ%IC|X056eZ9Fv1106N^Fr#MW8Zl?Q*W7oe=s8vSJEb1U&Rd_Xj1(Sv76j+ap z4tcTCb_UEhz3Dy%O>7dm4E-u0|6KI8X{)*$uD>DuJ?&2r1u)zhFnP9$rxf~$9GpBN zX1Wvt~>YZfK9AZcVI|FbXT4A-r-KCL^>t00kKabigx0&O)&;oh~pD%}B z$H|G|uTM614OZ&r(489TPts}E8!Y};JxrZ=>XcuAm4LPC&paw=#4VCuXF`v?GT5EU zE$dU6co*QJC4blQb4^N#+jNhB13hv4gg?dWnMBp(n?xZxrDZV-l`$Kr(xfIDDf!pYas(TQ~5 z8(z<6_ae%W%W-x zKYh>>qXFTOOHN(QK6ZRok^4*^yR9V4ui7*nm_%= zi9>*$3Dz^@Ypi2Q)n^Wy*anL%l$Wi*iM|jOPj1 zwT6TFe$4o?j$`yxsvjS?;o2Yjk`(u6j^|JdJfDC)nzjGQy{WF{Kx$bEA_&--M6H6f z0A2!y3=VWwPq6C6#ZN$vAiyWAc238DP(vPY{}ow{q{B=!ErBB&rIQaBEPH!B0v|gOKz^!s##y!vi9mED&UVlV9rTiIsvsx3wg^9{At7! z#~C!XZF_U>>|?>z(bU|iK~|bXh=Dla*NLw*5>b_{ zUZ*;5y#<|oo=b>A6eF_pRq^F04rkySpcB|MIuS>hRfM^W%Tkg5)Hg_IMNNgP4$43n zr>_Rlt2$^g+S#)g{Ja$yN4|0|&R8mfoov3n1PvJhq}oD^gAXp^-iws-)1Bh^;G%Ci z-xZMvi!Z$J*KY*LKU|_$qQO2U_m!38>f*Eu@K*wfYv!}1qTWY+LpUOZI*zj8lsmp6 zb;XN#Dgu+z9^4eEz8+HprP0aK*!fjwCYP=V!e@S;D=qN+1NOhUd!SS|>zk>aIh_*g zCrSWv72FE|*HxWN9XI=_f01__)ugN`^i)kz|t;n8xs=XI}2S23AdR~Mk(0FC}) z;3~lMISte;_8@&RDNBBuP}LduSaoshLrtMDp_QBk$M4(R%CTT-6s-*zqLS?uf8hu; z{O2s(C)9odD%n4I*~?yT?H;uQ560p8QBnNzp9g5&>WDa(L8kH-Iz1D#BY|?!b5~LT z*(r6$5rq&ibt{k)N321;8?{0`qhiZF(c;SH@&u?FY*(UQC~mnLmNU$N8JRl`PTn$e z$-a;Jnl>W49*%-b_fsbkU2#6JnQ2-Z&4P76c^W7 zUiKjG7#O&cc8q~RVRf~rJ=Tm?O67~4V-u5CEBegw+-ZU5AF$K5rOEOaE6t0`m0B&Y zXSE#QERgo6vpOK}aJpt8;Ken=Jr^RFy4nVD=-h|6 zq~2HE#~@&U2Y8#AL~TUg-qUlOiPRqKm~2liO^8-9_zToSGbU6YEiA0=_f-I*d$nVn!X!EKy)NqhT;(tB zPhT_AtT@?yJe@e%%@>CzPL;%wmB2}S#Y-ZCYp&kH7J*j-OvHn>f)2|@l*~!>B;yG9 z<4&I&Mb6XmFX9#HM6dkp&wCKpOor;?17Ct%KODn6XRQ~I99z%Sfa@}<2}l)gf$VbT zUt&T${GvT@<1nIz2e(zQHW|u;amF->GDVv@BK@>9)%2QQ8NrmW219e~fVl=4>D22v z=&M7TR&9J)ns%l1Tu+p*a{V_&4_+Fi(7G8LVL#M~lI*|N;MY_;mTJp=HMQl@Yo}F^pvJY~)+W)Xkxr z)2}C5K5LZ^oI7T9C+EE=l`+(Hsc*n5TrZqIZ*hz);0c@uvBt=*HEGM{&1gt8`qby| zENr?O)i$A{+TxJrQ8jE;d>Sb@JrV^!U!b$fbMeq=aWqeM%e? zT(iKv*v9SF+ipRJz6o$|oD#=~Yv+r@s+Rz740FR`Tzw3!Tsl82RVDmsyl#zRcCQ+l@+H~*hU(55#>2o1a@US=D<1@w&0degbc$?~( zTN>>_<}=0$)M&+NDQBElumzr%z@9#N)47_a`mdDcUJd)&g;dbDjW9%b928<7k*+C=IIB9DG{u^$ES zTiROb2#HNH=B1~0?@5amFJM8-900w^Vi`}KiW|3_J-GJ}(`3NU0B?@kGIoKlCN*mS zl12crE%kJtNGCWS{`O8Lv9$VCDuNQj(1D33w^Z3Qp=zL@&%N!<_oju5mr|}oGU(mM zS3?DnNO0>KK*Y6cg4JIEkq?7|!97GV1$a(f3y=*A#or|s;d-;P9|0P~`mlZe6kjvr zh?QcoRSX;jm_Rw9D-Td=GXFiwUhh`Bt+n%Lf~Zs2*;S`=;*|}gD2J_ zH~lIXi-w#u;wlXXKTxK|Fqi_WcnPq>&mgO>2Mdi{uA>ufj$B(hjvy||n;WURoZ{GX zmMSBFo%hHhB9)`RX%XZu?nRY?M43z`=*y0qlB|!`*I+|ttUJNRZ&>~#y`2Qi9M6#! zczyyqjaw>>e<^h>n=Caf0=t_7lm*-tvCy>u^x`Z4eG>2o&@+dQfiH9Fh;jh+NrAe= zI+{eq;L_wIoqGO_a4t-!p@AZ}H zu48DSELymr<_-6}7R!;XfKsE%u4pp15cw1Xi6?ATHsy+Iw+N(EQxVWw6e8|g`4(KZ zz{7_?mK&Yl|F9VY$*2z~FRAz5=a=IG@Qof5Ywf5nLwQf_$5U!1=O2XXCa#qb`o2&*(PF^;fu z0MAPc`x_>gMv9r==RylSZ-IT*VE1JJa_H_T>BWEzQfN}i&%E- zcp|M>xf~GdG*DUu1J~RDxXv=THH=0`TC(nZgzK4p%MvCHg9mB|k0V z`PO%KG0`|y5mP8;O8W63%78RLT@P500=Q4U^d(!r+U8b8nzaP9!RxOcc|sXj_3f8_9Ya06T+<4U`42PXVYnW+13Ir(R;Cm9a^n z$`QX)5d-6bkEVSC5p4jyiUpOrcKGVJca`X&b1{-a1@zX!`Q*3x~lLujmlVr%s zoH~_@gG#$xN-fIQl`{Y{yG2xS%2~uwJV)WG2Gotj#yX2Q_}9`_+DS_rm}}6HU~lS> zZcRQ&rh19H)nH&e)sGIYs$UEO+*;HkZ}~+ON6WA~J+6z(@dV0BP=qU~lT)@QOC_Eu z;zY5ID^6YSnp99pPHbnROSDY}eCK8&RZavCBkGYzjCBco9h6f;9o=XALTO~Ue_h0w z`F$?5!1ET^Y1~R_xc_fUUCS}g&gKGe*6gy*i;F15T)E`tvv?~D5C_mLdf{r$p16w7 zfFMv$h;w|_3D{Y5GHZ6492`v(tL}w6Dq*9e4{d}=v?VTC8zB~^)SxrGFg^UpwzPEV zk~DwbTyxyo6kD8kOsXP#Z)hxqSjIB<5&&BYop;?c7+6#jpetK44RE>oD(I)o?vsa@ zj6A@CsXn-NfCmt_bU=VEaN!BVxcka{URttne$AWidwr<|Ety$pN5~w4CR8mZ64wr} zOZ*|=R9TWEOZF}R6hKw4*&X)^D*!aG!GP&EJP<*Er5L)Cv8q$uhtn6n^i??aMA`Mu zH#$V-M)d%7@-qQ|Xp;B-`~OQ?w_ytvLWf`A4t@L(%Ro$#8RRKPv?@%0rpRubhTHHf zXw=nz`OCraou@M*NF$>P(u8Siy89(B@#LcxAxVTG_?(i1ha_Jmh=vLD%0)k5s_HnN zNK(CYs*=iCjsWPWe^oc#se&RU(4WeS_(~UtgK#Qc)LH(-Gn3BM1xlnMT4kG^eqg`I z)43=UWi5K9g~`ix#82}`n!jOZB@E+@q*)sLCoZx`Z)is4(T(`r_<249dukp!@^ysL zhf?Qe5U<0Ww-*|f>Pr=AxD?!bRhBLwFMyuOQbaEm13DrY+@(5H#Oe^U=oHtE#mCgL zF-^2@Mt6M}17Ll0in?_CM0Z-SaDh8mySJk4d zkAVkp67b6I$?UG#>AerW6B{hoGI0%U660tP^1ve?hZfNTjRMswxM#qQFyVB>BLZn$ z9igzx5iA?%i@cmR;z_rD_1cZ;^{;;=ZQcv`vA`x}kL`NJ3vlTolhOgEFk zHG2q34X_4OwP6VA<( zs349hS?11UE1DaV%U{F0-^kWzV`*q)GM&bBs%)W%Yo`mO^&eMl6P<;rws z0hK^Qd5Ve600_7P@RF{p5P^e#r}ypfH(-De8kn?|+lk{(r_X)v3+d8@3ryxUqfR1j zGJr*NMt;f-VBt-b4tZN^M|uz7e%~A3z;j@yEZSF`yN4Qqu)j9AXE5@_uRtG~6|Ti+ zF$n3k4?l$|bA@xI$fy|pxZ`U@;uOWHt#3~M_TT(mYHw|2<>`6+7%)ZNv?JOkJTxD0 zj#a8s52OHtrXIjl%lK(jQya50sLE4L@%g%jcM)H0l=IQE;EcFoS4ZZMHNO&rPUx`5 zLM5dG+=(nvp3CsB@}F89rM!GXtV+~R(7{{{rhj!WQI5EFzDdw!AE?xfU0mARyqr!p zb37MXfN$C7_ffm)7l%^A?6*}e_SBZf&hk!<(Xr@S?!d?a1PYosMLbiIh{hbdL@#jY z25*UCd96@Z-2H2lr z0aJZiy=pZZB51{`K(df$2Y^U+X>JIhEI3YKjoivlXSgXIx5N{=o;!EerVJ*rLBD+Y zLPR{&L$w5T1Uy9Xp-yTyFx=A8Seie7ZrZ!=2p~I1M~3^%C=#6+SO8C_z{bAn(~%dB z%K^&$9lvUfX%Q4N`$K?g0=tNe8j}o&R4!Z`NO#_OTN)hl0vH32z(=&IesV+(JUtfR zs8+9d>0M|WU6l?TKH;`ioSJFcJi&PvfUOdzfV^niXiK*_O-o6B7t~@ASCgdDV$y(6 z&l-T=ddL5Ut^0dXV?7MFI!Y{Y#QD(BCa1;)E+ShKr;l#imcIM#Z}O~osOGE%tVHmS zuAKSM^PPSuiu~NB1clp4a5`@M*ez#;FR)ftJYS6gvTInKj0ueDKuKmU6H@@ZABPXI zg87keThu1eOc0_tl%pRPUZuw6=uUN*$KI(-&{j0ic3|zXf0!?mSxagr8|VGs<-H#~ zSxq(LxMD5vya)EluGja}E?n`d%1ByX=|9dJtBt62z|ql>lQm(G@p{5koVzq(Bu^KJ zBTv^A&fO}Lg`8bi;)NO|lYdR~Qq7$Csd92>Do>)z-qM&xSR}G;-TKstEL@+;T}-6z z-?uN_j2J|QzDD7EVp3F`aOR2udv#+=JHQun$LeOFRF;55=LTqePncG$jv?#3h?Y#} z?D^c!VzZC=&L@CCJvI8JI&7#2s)JV2g1MdC&Z-57sSDsUy4F-f7C;2Rj|WAGc}3!#CwxqGZkY)Qg|y5e(e4CGF~G96+u%*4%-BJlZ?1ij)1#-4hO- zP=GokCyRSFY}lOM`v>nrGw0Q5_wJ*ZM9_xO(83wCe@&!8{0^Hn-H z-jIfCm(-P-mVa?<-v{?9`pj`xY)cItuTB@wAZ8q(FX#;yS0;Tx zsXB&SUE&vUKZ(!eo+Br1hWb^;hT z-*g=u@fe&(?F=L>LVeoOPV36ng z+?kb?u%YPO(c!BF5K6`>FawC3K16HvCi|&Y)J>e?Faw}uzQ<3T!TiDk?AomN7mZS> z?mCr~0L7>1!mTvYmKkMr=gl`DxD8eqA!vPcJ5D~K4FgigCF{{^qUMyYuBzz zr+UtsK$W3G*U+nGY{nh_JW4DMp6coG9K@OxE7SE?ZwAoIwwK>?`b;{-qOmh)&hcf? zFFPls1HK_zgQm?j@a!cP(;P-~OLJO?e!8q5vY^Y0%|`gLI(Gbg8W5LG9mUJ*pe6k0 z8+nN<=1_e#Xlbj&U2JA?s{1(QfZF&MG&>75fE-F@w{E%7gUMbIKc1RB`H^4Iv`*{D zq9xKv9aeUQyb+6@Ls5Y9jv^FQy6!ydyvQkNFY@zU;YD1HIk~p-EioALvBPHZ2<|n3 z%A)F2JHcw#n(|ta!x6+p;o&p$`>eLW3j)~FCl(*A{Wrs3oLI2_rz?GjSyh6Z)-Nlc z;Jkubfm$lmASFBZDXv{^T?OC(zGdzL{^FFs&e}9`c04V(aZ?&zv^7nf{&MOA*xTAB z()P!9r=R%Id+11$)?``CMCwCd`)+#EeXo^F*`M{Y|01oAQ9#zq=4)7BB7hWkJ|+%b zpdLUgaAJL-dk!1Q0m7<4g|a#Fsa5r}Cjc?M){c7*vKPf3<`hL?S+JXv6SMssSuy_)>q`*5=gzU`Cj*ZL%0&wnr)5i)GtnniQRXx#E7RkAmA4LkIcPzT+nBs2%c!mL6?3}h z0%2-z#dAxTr&pTlp&)@Dms};j*eW)(^`$TTBjso?fpN%X71tuNlNSk{sp_UYm1Ff{ zx6)=%=iZTAaCSMe<^nW1FLTHdUrD0?JsbVYl)y0Wo-|~lFnK#v!5W73tAvgpA#qCj9(w40HQLN^1zX_xFNy)SQ+gmZT=#2z zlMQWePXpt1X$)1h(m0(269d@}jOFNvTciaO`s#4(63Iy1qSK%bh?|?w;Ex&KBz{{3Ts?(DQ@&;B%*4Uv~FTY|^{Svw$Z zU2%aqFM~d<4U}>#U)al-=yNE(>Uav{fIC!Ng^TNy3E>fB?oCadaE(n&bfM-+N7dk< zBjbhL`cdnsqtEGTuj%ZVUD*TeS~eb^@N{W|C2ROLeu3IISd5R=rg_ zbKFt1+C%jCa4qB(5xSIY4DQh3gXu#b_(Odeki3YW)3_dy#ChbOXub^Is+2v{N}@pZ zb@omebyoz1D@-G2r8Ixu(sb8L?zHTCg!(H@aYP&P%A(P-ZQCPh_ft=Jo+rYgtr|B< zlz*;S&LaHL)+)6&BU-$0wj{AmbNjq>ag?vd=G7O@56}J7(D6@cBCDEPPW*#%iAMcF zq4r;)^92Cx_w%40NaZy@-d)$)^-`vnR#o~h&|lFl7TB39$Jm#FI{@4oFxGj3-6GK;= zy*{^Xdo0~}<3_|N%@%(Mn5~v5xrX`#{{mwWU7z+G8SEXTI7Fe>W)Z2lX3EkeU=7># zoxxv^wvjE;+O0|`@rB|mV?mV*;8zED02rpqvL*9M*g8gi@-Th^BZ)l(l(@yYl1wQ@ zn@~hR5gzh&i2SS0sD@#;NW@i6L6M?naLeU`b8bN&p{5cJ9{V~ z*GE@IXtbbO)9?Jw1L@?6qZn92ctiU+gK9e0KJxT4Dayp(aiV?X>qF5w^!)7PC*0h- z?L27niqx>N$BOilJ6`M+vf6aRbs%ljMb}BMI{wBt9%AJ(Ur7w48a4=sQ*lj%?p5m4 zAyQQ?D!3)7@}56;wjx#C=JvVi(r8l}Yg#)zHoN1K<9j}$38YN*RQewfm*`f_e^BXn zGrs_U{egI&cK^vl?RCFis?2JALuCM?BbZ-RC$wFd;Ko5oapVGTz}%d=?lqap)$(;@ z>jLx4sly^0)YB~9fkrx4me5?iX>L0B1Txu)p47+!*WuwZVu1x|!}>*-7$_tE?o3CI z_oP9#S-a+H_E1HfqJEV-4iXrNU+A=);$SU|(Q76@Uy2URjryN)OAc{k^%kR?J9map zjl~zLST1ryVNunSQEf)KymvBInPemP&z-@7yEVc)I15o6Tj4125t#Q{|*~)4=3I zMB)pzaj#!hjNtI$mwTs?Py9RXRC8qA^eU-2z8G)f=aM3gbIqAE@M`{HA=}RV#YaDq zKL7WhsmKOUh(tt}iiUdYytXZF4 z^~zW9rGg9{5nryX<3w9ku==R-dVDi zWsbJ!xbSLS`7vnd9fihA|YA$>%DY=PTVFRz+HC1b2{>KhtEDmhnBov9OhN) zR-_}xdb|Z3NJ~^frRdX%@}{r$34iA!;3^z)Mf{-1chG^K2`?g=j9e8i{Oij_u`gXb z4=9c^8GJlFiT(C<>sF_=oRaBE9!{;J3Tg~N5@+U%RmxNW&XynfB62ci#FdW@x1}34 z(y0BMrQ+vo40-w4D50a1HogNCNj0ls1?|H0k6-#idjGp0a1E&y}*a?v8QYp%JTfp9B2?4dU5D&%@ZE&w|+_%DCy zAHDuT`SCo7kz37i$&xF-KBj00A67q?I#~q_$4;c0Qb*VPbZHQC1K3VVO$$F=-t*xT zBrKBWTxKrMW(&NafPL)AKN_mN?$?&5){fh-HY&E0o&i83!mw3G1AG(cmOH5~U{>cWE5DsyVbmv9YNktzWk)?LT+|fYqkmA>$UH zOEX98yF?yNYdBSU-RILFF|A)KBDehNGIa=(ba+J5MK`LaMz)09yBE&0-*$Mu^X*5y zH2)^lM>{&&8MsEP;+aSooVs#U`$bMsQ`ML%m_7$M4)G|&aWj1;M?WSsu1f3d6xR_V zT||o98c_?;isDay=5N!3@A@4?YO&*x+s&Cp7Sq$Xss%B+2FaPGshFm(8Ws_=ALM9+ z4!Y#m%tkCX-+W8D?%J!_&|2m#^gMDQj;V4q@Ykfj|GUos{>(LrJ|a1u;<_x?T2YmI zWWc4!OX~wVF_m$i6~nS8)WO~Z{llfoXw&-IQp<|J8{hNC2aB8{@yzeD-2yKtU{~YT zZT#6&mBzLou2c|okMgRjZ&;Tdv5En`m@I{R7m!PyuB*X4i(UfIS(i=PS->k%Jm*TZ zCX$Vi?W*N#b}|h$`$ZhFn@M>YVRo~`bN{*)eF&| zW(6#oCkj)CQZ@A(Bp^O__O#{hW2kt}VZyevvlT>- z9;{zE)r|$}!dEevVu)pRam}jbsB9jwj=VTel@l`eprZit$S?A#`iTf1T!U2KiEPF6 zLE*l2ji&qsCgR*RPatg<4K70%4meBeE`JbQI_o3a@EO5*m&wdNM;DCMNiT9tayZ+ZUV({a-H0WN&8w-ah za5sl8AUBw2&RuR+rfQN@vUGN57k4f&PcZkTMqn7GUJ@ImESxOY$G?{W;|(`ArYH8G zY14NB$qm{sY!*@9(4MxeXR{fK?(EP$sO?Oo9!$%Yb^-K=P2hk~826hX>eQLy#(hiu ztJ+DUqe)bv>=cr(xCL(7xksx~&!0QZGV*37A;+zq)7*@W95LQbr>n4DCvN^EIv*RK z#2RI1TDoL$+WEwOIOH%ppozekOjWsx9px5fi*F7JbLOJSfswbIK8j?;weZi?Q?&)` z0(h-L)pm5f?7k#zmdAHK!E*R*fcgm9GpktGw8&aT6XVi`!45f<3%Vlng2tdjzdSbz z@R?iF?I*totx}`==_Cq5wIqM`>@M5;*}i>Sdgt%HGkyLaKEpE(-FUT;%hYIDq{dm$ zk*ioO!w#3tj~;@kP{GrVpjZA5i_q*eu;agY@rv}OH{NGaoc7>#R?5R=M^eq%oMR5- z^Pm4*`JaO=DxGdi>2UM5l%?)4|p>yUhO1;Cim62I1Ybs4kzFgk- zp&i7mrp}qnT%N@ic)gnN)?mo1%#@v^yq`#y7c zUc4mWqO2%aGzsh@jR7*~Fj9z8`>86fkotSjFPDn-HTx0SzWNo23dqD6i_?@CNa7i7 zuP1JC*Aq{sZ+!h*>DY;5)UDAA!R9TPZyj=_)c_QB$pcb@wkXdUN0cGG9G6LfL6!WX zY|*7~4KPhu(xtTeh-4=iiec>JBf4*c#&A%P|o6?--pQ{Y<_G83I@=&uV zbQH_n;cN`*GG?xogGgZ{dMN?u6~J9)+-n>0=Bk~~n(=Q!GX`Ug=rK!9ozmg4Qu@(5 z>eJrCn^O1V*sq@K!Jf%*+PS+wtzI&Z&O-Y7O6j((%PL>^XKi)I=GPnNp)Mz2Cj-Kz z2Cb{b2?7kjs$jPTT=iPGL?@nPRj6by>b&yzl`!cncVeeT8*4xP^b^q9l)nA##&p+R z*SosJ^b6qlINiCGN1kZB*gKkTeGwlwgKtCI7V@Y(CJKs$H*lz|@nYeUwR<#J z0EW2Dy9<2ax<$AARTqJVp;iE;0>hgy9Ml&t@Dv(IV1R*jlz9f(dNEj|?Q!m0H`+6& z(|Jr5A7xS1KYjVjwi&Zw!-lkF%O)&pE=jYora8Bz%PUN^_()*qwt<#D^xCyCN>m?u zOoOQk>bUQ~&W`~5Vs9TCnjB8YjvPr(Jo#kWx$|)>QyyWE#t;}3>dQ#tiK5+=soFD+ z>GhKjH6m|?Mrn@a()AOE+K_f4Vv&o&4CqRn4~OOKW&U~P%GEYJHZpRC^zjau4&rEe zu>2aB$Uoh43J;}r4w;t7)U??d{Y~-N*Suth6ulknG01mig{KRF~1HKd5 znhdU7+^jlSEd$g9@^k@?J2UcfnFDTTFV?fj+xP6*VHLc#wk9UpHqj9$7}IiRHP zQ%~+l|L{3B5W(beCwlM;7cNS3=FPY0q?u2u2Id}G_@uh^w%gMPoUP_CC`~2h!h=@X z%ip9DlLyP=_4yVu$Z7Q?RM;WA~ z<`~Tzaohle=esD2n}R%fMBQ+Zv{;d=2UO7j$zYjS)HRVB&=sCJu5=5$V1YgTdDo80 zFARUGc5dU(SB4uVD*c&z)0-?Q3G#d|m_e^44v2L=d9!(PfbkEg;$+JtL)zb51a-qKu=TYAcM<@!pU+}L)}!k$S`72rd&Pb{;# zsWe(N@HBZM^5pTu_<@iBB;ZxqvSn3iqRf;iaRe+nMUUmgTvhfc`?;PyH<4cRs=JxQ z98G`u@lQIh8tl|)vam+BYXn5TC+~cy(`$LU1{wIdDrmsZ^QVC*N2JMxcVV1Bei4AT zL4;dTW{d&Q2$Wi;r zF{r%=P}Ua!&t2uaR2KwY6$Y_UY`?dr?c2YL=tY~CGeUBxT-mLU`bM3YDK$-QXcO(I z)9Rypl|HQ;?xsgoi~wuJBPv?$>Hq*h07*naR9_DO_H`;%zDO~3bt2NGG#_!u#*OP4 z{187Gk*qHRxlfYc~Zm zrzaB%G3nYBlmo(v%e{JYYkGKFh0p#WG*X(`F0WK+ZLNnxYzklpTqH9Vcg_y+23Hw< zs++*x3gUo?3CZv=R8`C72NN}wNpYhg27!6jfYa)Y5{|H$w1BRT@aD$)%IY;sOXb0+ zJeX#B1nBC(@ky`Ei^rLC8%%Gy_f_8S@?#(W1YpOP3kgIIdLTsSk3m3SE|B`3Q*BF_ ziV!#nkovbhsiAcMV{o!Hh2)jNom(PzOC$rf}Fb=BPWw1{^j8^7qw zZVO4&`wTeH*oFmT(mcKYNjSHs(?5RUYb*jf#lR%llcGVdIx?pK(*0GSjfZT=pE=i` ze&~&_Pe1a*Z)NwTRsgj?O225B<#H*LF(kIplWwy)T2M$=^?qF;hie7{99mpswMNmW zQ%7-)g6$!Msxg{tI(H6v`i)<2op*9s5(qYWVsz_D93# z%jescBavn+(*$Ujq}2kL*K$f?*w_lFqyF8(*~;#C?SOg*pss5>VI2T+2ZMpGZ4$-6 z(KqS@)KPNrcyW>quQ#qp>D4c7NE4_vj?!EDM=NPi@@;qUketl#s!6L>wxr$r*#(}} zs9+?(R0FroHhJh%YIR{fz+Ouy^$DQM{H#O-;#xI{m&FtYxd3;M9CUnvU_u^?S|v~Z zsojsIBWQGd`qN)bXL?RgY5=Jo?xeyjfrL6cX-O~6{p|UE?4RG4e&WY}6mV~&Oh6AB zRJKmc+zWO5wID!>!G(4O1Vj&he)-APhiH)?$01IrV9toB~c)uAE#lbgB&%e$!1ik!N(1h>_!nLJKBb z71Q|4A3{hH)qsj=2~}U7twV_*il-&cgxjac-RYfIw5MssFuVrz#fz7w8*aFcxqwT~ zXKLV6YSo_$Wi%i&Jjezc8q8E4r?XZ3qG8nx`SB3w;fI))AMqS{&Un{JYfJ+SFRFH$ zn#2(B<*{E-cW&wDLXBVWz&`rE_I;J1iNC8%)Rwx|(BS~}S~zgFHU-cDRnArb9V|>O z0J*Mh0`@k*9MCtQGXMzCTg6>VM8jU$O)xaG;F{~jHS?s!$L!@x_05|m)1pl^X#n8p zWf?XGAL$t4aMhvWl~}a|IWBUXeFw3P0`h>FECa7W?ygO(b!yTsz&rp8SOkpJ!2(3( z&Y3C8>~x0*paoQIvLk~n?Wdjs+|ere)Tch{g+R?s=(rc%UM_X|%+bnUvVN)ion^r#hR<2&d0M0I0 zdVn0FNyX`myP(v!(|#OY{fQbWzSHvK!Muv>B+QjioH(gRCP+T=F51Ixy;nrgAisIz z=Cp9ZLaZ$U?9i!!ii(?qS6sIRS?G)7$tQL(xblAB86~+8+$L5fDJl2U>nZQ4L#n5G z7t|)=-tEr0Vc+?M%&}J+ajLbhj7ymFfuhhSl-f82=$$$d*K`2r0`(R+bc4D;7!v}R3aQl6an)_~&ZB#h&H(J^V2a9 zrmjtmPo2J)UiFHXrChmVSJUmyQ-<2kMP&Op>;8GHD8^qr;BqWmX-a z$=9hQ)@E$z7G-+I2=Dv=6N@`g8JN?R(rp_7c{=j(?um35fVa*C@zl4}HL(1eR--BN z$c{cbDN+q1Tmiu>~I-l;kekp~`wd~|vPS-`~<;Kj>P0J1|Bulmjucrlg2ai=1v=0&o|+-bF?tJ(w^ zJDYcpjSgWh;c0B>%!)yf_M;dM0b|rzZ740I8*jW>PS>SMh$2_ZB(UlZLUlWJ7W7A? zNJ={rr=ZoNH{~jo!-JTdOU^5|qavt%rN+8p!IV z?)gn4zjylR$o{5@O5Ms8fO-cUdON3N>Tv0pPSMrC-Y#`UR2*9@PZy}O6`C|<;MQf- zPd370VUb{hy)O|Ek1|<0#3=(|kCaR4&ZPkSqMEe3yC&^AG@15XV%fX}om%BH!R~UE z(#j?Er8!;o>096F0f_htpbtsCEI4AW0&{W0h(KhDpx`zQdDY%1=uoeu=jI-5kXBcu z(`xcnVwpiy1rHwF2f*)5ANlD2MSOO~Vbzu5=m>x(jX6U5So1`ia-2AMCf&e3uK(q? z-;owAUPNjPq=Y~e0}6KpsMPAgox$WX z-{MADsk)cH-l|G)n5>cn*iW50O&-|H$5N--Na12Ub;g0+AJiVNz4kg!I*SPTJ9pw< zu6aTZs-I5&^zZ0OQn*R!13y1%`OA-gX%gwn!9LY!IWw9}89S@^5>uw7*=$~Z=bd+$ z-Vv;MN>L^!y(}L+!$tXlLpa&`8tPEDvt%8IY74@g@Q>~hlzBv2D))oH4X zluMOC^x97k!@1KDUbT+JKXlYx?CZY$smZkMINCF8g{Katz6|r5uHM*I8pNjhj$PeM zoYtV(p%s{lBMx0)?p`0D5Ix`Np+J2)iXb(H< zJjEu=e+Af#TP)*=MRHIQi*j%UI_Mg5_wJr^X~pst>39F@e_})G&FIs^wWBd3*?SGE zMonj?)%9cI&sX_Dl)^=0xTjrBw<}f+i>gE%68YectHy$yR=#-2Km2f4n*_kd_RYY+ zptsVS1yD(4Q$X#eQqr7{IN+sAmNH;11qJ!Q++Ariy;Ci^Q)&t1=K8Fng!9VyIm=t5>q~C})mz1q$qIc4sc|c)gfgJd0K41n%KoS~%^Ye0 zUd~r8Y5dy@=O(^#;dpKBZL0&=XCo4sgM581ockPf)@L(O+KG;P2V8n92;KxfaV8`& z26TbCx`UWLiB|x0tU8uhBm^<$zH9j!t`j6<63TO5L8+!sL_k7_9$&> zZcFb3-0!~YWy~uu@E~`uL2MM7I^5?$NmtDS1i=C$6P#-h_xSiA%#wYaMe{drEqzEZopjD zRJwu=w^=T`ASmck0UXl`n#woA{Org`{{GX|CrwS1dGi*gm%sd_p3@j)fQtN;yUrq= z9t-a#i!2Txb~=M80SyY@bC91(2miY&buKyQLk0ppVl0BG`3FSx`n!aA)G#g0}QL2Ypu?Uw;w z`TpUW%6atH&z!HMFCK@}pHoTmRvXkgZ`_f)}-SylTUl%6b@uP+944U$9kynK9n|qq+ zgodE28Y&-B29+unr=N?wVpPK+f;c5xzwySc>8?9pj2P@RelaItU{)@sU2#>6)?cvj z?cr}w7d<0o9bwALUrH1nS>w;)Iz?u_j~|68U8y2-4WkBjgfI-;qnH%1I40FL09>F7=}!gIR%-?2Y<~ zgNg0&(2QAFlMWvnPDkO&A9?g#8$i>h2hq&W{mf6KfB(zBgnYLHPLD-Y$YZtoF+@lPAjuU9 zE*?ArP7OBD&mdUJYAQt0oFlyy=I@<44z^Q+WrF%M9?LLq{x<(Oko2 zhto*R#GpJhoYt@3kUBcMTt+myk=IFz65TW|C@3ua9m#>XbR{5e3s1a6xBvAM^-weq zeADYiTP$6=D&2SQ>v`8o(2l*EBDW$t5;`y9s?EjGKel}v?odsP{PmXP!)>N=U37TH zZ4tv^3fE-4CdbE^IG1*eCQoHdO)_>u$Em(%ac7Pz+yXPe{)`8}>seXQH1P*t+Fd@` zeLU6P%!<+u`aBYmN*h3~)0{e75)wt(2=iQ^`V{KUzl=_}tnlpfwWgt$bV9G!S% zJl9{lme1XW^v_>;7^7Bgvh_lTas>K6&|q{>_XA+v*@1KQH=W!E=0K!DtMHS*!~6>u z&MMSd6>;vDun2kJ>D_6^$!m%GJ;$^~X9URXM#SVwCQ>3>)KXI?TSSP{K=U2SqRVjRA1*ToM z8W1#qwqpqG@g3XvIyvV7%?0K7%D4D3QCZ60B*YEQ@QE*mNGX}RL{n0C72(`tXNX#8 zE~Tzy@pkd$P@ddh966{lC03J^UDkt)M|-b?u#c^Uc?$<0mhq?K^g*B}*21(bDuz zsm?fsZ31?6*66URs>CNc>|J%pPaJqYxovE0sONWo82OoStwnomU z*4UXi!CcL99$3~-;oR?D&D-RusvCjH^N-<9rs$zA3$wH#d{8NeN2(Fwqqb5~nt z?));4fqoH;s!^ui^@>{MFx4d=qC*HCM}Sk*SN{6<_Y2~L;dJr*>2&DGQN&w(jaXhH zZoUMaqNC2MeHA8C47c5Or}f#3eBG`tzDkLycKMlp)2m=dQDmj|kLw*Gnz(lz9UAYH z?nSrTnRXG?n>O8;e)#QgMa}e_?d%s1JK{ywE>p2dt1TD5_RzoZ?q~vAc~LJ4jXYJZ z+Q$Jw7LgRju#n?(Plk>|o&t6~FKsL?S-S?0F-v$bY*g1WT-R8-NTxH#6>b6ePd(L{ z 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

x?PuME`?$x$C>WG&ee?CNmv7(y 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 c=|D*ylh literal 0 HcmV?d00001 diff --git a/extension/src/popup/assets/ethena-launch-wave.svg b/extension/src/popup/assets/ethena-launch-wave.svg new file mode 100644 index 0000000000..3654d2ea64 --- /dev/null +++ b/extension/src/popup/assets/ethena-launch-wave.svg @@ -0,0 +1,1611 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extension/src/popup/assets/logo-susde.svg b/extension/src/popup/assets/logo-susde.svg new file mode 100644 index 0000000000..d4fc91b838 --- /dev/null +++ b/extension/src/popup/assets/logo-susde.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/extension/src/popup/assets/logo-usde.svg b/extension/src/popup/assets/logo-usde.svg new file mode 100644 index 0000000000..e294c9fa3d --- /dev/null +++ b/extension/src/popup/assets/logo-usde.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/extension/src/popup/assets/logo-usdt0.png b/extension/src/popup/assets/logo-usdt0.png deleted file mode 100644 index b193faf698151bd4a09b9dad221021db00bb4d4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15645 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 - - - - - - - - - - - - - - - - - - - diff --git a/extension/src/popup/assets/usdt0-lockup.svg b/extension/src/popup/assets/usdt0-lockup.svg deleted file mode 100644 index cc9591d197..0000000000 --- a/extension/src/popup/assets/usdt0-lockup.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/extension/src/popup/components/account/AccountHeader/index.tsx b/extension/src/popup/components/account/AccountHeader/index.tsx index 0c8ebe77ef..4ab15241f3 100644 --- a/extension/src/popup/components/account/AccountHeader/index.tsx +++ b/extension/src/popup/components/account/AccountHeader/index.tsx @@ -12,7 +12,7 @@ import { navigateTo } from "popup/helpers/navigate"; import { AccountChip } from "popup/components/account/AccountChip"; import { AccountSheet } from "popup/components/account/AccountSheet"; import { ConnectedAppsSheet } from "popup/components/account/ConnectedAppsSheet"; -import { Usdt0LaunchBanner } from "popup/components/account/Usdt0LaunchBanner"; +import { EthenaLaunchBanner } from "popup/components/account/EthenaLaunchBanner"; import { AccountTabs } from "popup/components/account/AccountTabs"; import { MaintenanceBanner } from "popup/components/MaintenanceBanner"; @@ -128,7 +128,7 @@ export const AccountHeader = ({ ))} - + diff --git a/extension/src/popup/components/account/EthenaLaunchBanner/__tests__/EthenaLaunchBanner.test.tsx b/extension/src/popup/components/account/EthenaLaunchBanner/__tests__/EthenaLaunchBanner.test.tsx new file mode 100644 index 0000000000..01d374916f --- /dev/null +++ b/extension/src/popup/components/account/EthenaLaunchBanner/__tests__/EthenaLaunchBanner.test.tsx @@ -0,0 +1,103 @@ +import React from "react"; +import { render, screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { Route, Routes } from "react-router-dom"; +import { captureException } from "@sentry/browser"; + +import * as ApiInternal from "@shared/api/internal"; +import { ROUTES } from "popup/constants/routes"; +import { Wrapper } from "popup/__testHelpers__"; +import { EthenaLaunchBanner } from "popup/components/account/EthenaLaunchBanner"; + +jest.mock("@sentry/browser", () => ({ + ...jest.requireActual("@sentry/browser"), + captureException: jest.fn(), +})); + +const renderBanner = () => + render( + + + } /> + } + /> + + , + ); + +describe("EthenaLaunchBanner", () => { + afterEach(() => { + jest.restoreAllMocks(); + jest.clearAllMocks(); + }); + + it("shows the launch until it's dismissed", async () => { + jest + .spyOn(ApiInternal, "getEthenaLaunchBannerDismissed") + .mockResolvedValue(false); + renderBanner(); + + expect( + await screen.findByTestId("ethena-launch-banner"), + ).toBeInTheDocument(); + expect(screen.getByText("Meet Ethena on Stellar")).toBeInTheDocument(); + expect( + screen.getByText("USDe and sUSDe are now available."), + ).toBeInTheDocument(); + }); + + it("stays hidden once dismissed", async () => { + const lookup = jest + .spyOn(ApiInternal, "getEthenaLaunchBannerDismissed") + .mockResolvedValue(true); + renderBanner(); + + await waitFor(() => expect(lookup).toHaveBeenCalled()); + expect(screen.queryByTestId("ethena-launch-banner")).toBeNull(); + }); + + it("stays hidden when the dismissal can't be looked up", async () => { + const error = new Error("no background"); + jest + .spyOn(ApiInternal, "getEthenaLaunchBannerDismissed") + .mockRejectedValue(error); + renderBanner(); + + await waitFor(() => expect(captureException).toHaveBeenCalledWith(error)); + expect(screen.queryByTestId("ethena-launch-banner")).toBeNull(); + }); + + it("hides and remembers the dismissal", async () => { + jest + .spyOn(ApiInternal, "getEthenaLaunchBannerDismissed") + .mockResolvedValue(false); + const dismiss = jest + .spyOn(ApiInternal, "dismissEthenaLaunchBanner") + .mockResolvedValue({ isDismissed: true }); + renderBanner(); + + await userEvent.click( + await screen.findByTestId("ethena-launch-banner-dismiss"), + ); + + expect(dismiss).toHaveBeenCalled(); + await waitFor(() => + expect(screen.queryByTestId("ethena-launch-banner")).toBeNull(), + ); + }); + + it("opens the full-screen promo", async () => { + jest + .spyOn(ApiInternal, "getEthenaLaunchBannerDismissed") + .mockResolvedValue(false); + renderBanner(); + + await userEvent.click( + await screen.findByTestId("ethena-launch-banner-open"), + ); + + expect(await screen.findByTestId("ethena-launch-stub")).toBeInTheDocument(); + }); +}); diff --git a/extension/src/popup/components/account/EthenaLaunchBanner/index.tsx b/extension/src/popup/components/account/EthenaLaunchBanner/index.tsx new file mode 100644 index 0000000000..9143e8a03e --- /dev/null +++ b/extension/src/popup/components/account/EthenaLaunchBanner/index.tsx @@ -0,0 +1,91 @@ +import React, { useState, useEffect } from "react"; +import { Icon } from "@stellar/design-system"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import { captureException } from "@sentry/browser"; + +import { + getEthenaLaunchBannerDismissed, + dismissEthenaLaunchBanner, +} from "@shared/api/internal"; + +import { ROUTES } from "popup/constants/routes"; +import { navigateTo } from "popup/helpers/navigate"; +import EthenaLaunchBannerGlow from "popup/assets/ethena-launch-banner-glow.svg"; + +import "./styles.scss"; + +export const EthenaLaunchBanner = () => { + const { t } = useTranslation(); + const navigate = useNavigate(); + const [isDismissed, setIsDismissed] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const checkDismissedStatus = async () => { + try { + const dismissed = await getEthenaLaunchBannerDismissed(); + setIsDismissed(dismissed); + } catch (error) { + // Default to hiding the banner on messaging failure so we never + // re-show it to a user who has already dismissed it. + captureException(error); + setIsDismissed(true); + } finally { + setIsLoading(false); + } + }; + + checkDismissedStatus(); + }, []); + + const handleDismiss = async () => { + try { + const { isDismissed } = await dismissEthenaLaunchBanner(); + setIsDismissed(isDismissed); + } catch (error) { + captureException(error); + } + }; + + const handleBannerClick = () => { + navigateTo(ROUTES.ethenaLaunch, navigate); + }; + + // Don't show banner if loading or if dismissed + if (isLoading || isDismissed) { + return null; + } + + return ( +

+ ); +}; diff --git a/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss b/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss new file mode 100644 index 0000000000..435a09a915 --- /dev/null +++ b/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss @@ -0,0 +1,102 @@ +@use "../../../styles/utils.scss" as *; + +.EthenaLaunchBanner { + position: relative; + // Its own stacking context, so the dismiss button's z-index stays inside + // the banner instead of lifting it over Home's pinned header as the banner + // scrolls under it, and the glow can sit behind the copy at z-index -1. + isolation: isolate; + overflow: hidden; + // The campaign's fixed near-black surface, the same in both themes. + background: #070908; + // Dark mode outlines the card (below). The border is there in light mode + // too, transparent over the same fill, so the card is the same size in + // both; the padding is Figma's 12px/16px less that 1px. + border: pxToRem(1px) solid transparent; + border-radius: pxToRem(16px); + // No margins: this sits in `AccountHeader__account-info`, which spans the + // content column and spaces its children 16px apart, so the banner + // stretches to match the action tiles. + transition: opacity 0.2s ease; + + &:hover { + opacity: 0.9; + } + + // The blurred blue disc bleeding off the card's top-right corner. Offsets + // are Figma's, less the 1px border the padding box starts inside. + &__glow { + position: absolute; + z-index: -1; + top: pxToRem(-81px); + right: pxToRem(-80px); + width: pxToRem(263px); + height: pxToRem(263px); + max-width: none; + pointer-events: none; + } + + // The launch surface is a real - } - /> - -
-
-
- {t("USDT0 is now on Stellar")} -
- {/* global.scss forces `p` color to inherit (!important), which - would defeat the muted gray — render as div like the rows */} - - {t("Access USDT liquidity on Stellar with USDT0.")} - -
-
-
-
- -
-
- - {t("Move across networks")} - - - {t("Transfer USDT0 between Stellar and supported networks.")} - -
-
-
-
- -
-
- - {t("1:1 backed, unified liquidity")} - - - {t("USDT0 is backed 1:1 by USDT.")} - -
-
-
-
-
- - - -
- - - ); -}; diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss deleted file mode 100644 index 82a98c0217..0000000000 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss +++ /dev/null @@ -1,244 +0,0 @@ -@use "../../../../styles/utils.scss" as *; - -.Usdt0LaunchSheet { - position: relative; - height: 100%; - width: 100%; - background: var(--sds-clr-gray-01); - // Re-resolves inherited text against this subtree's theme class; body's - // color arrives already computed in the page theme. - color: var(--sds-clr-gray-12); - // Clip the oversized hero art horizontally, but keep a vertical scroll - // path so the footer CTAs stay reachable in short viewports (squat - // sidebar windows, high zoom) - overflow-x: hidden; - overflow-y: auto; - - &__background { - position: absolute; - top: 0; - left: 0; - right: 0; - height: pxToRem(429px); - pointer-events: none; - - &__gradient { - position: absolute; - top: 0; - left: 0; - right: 0; - height: pxToRem(377px); - // The hero (gradient + arcs image + fade + overlay) is one composite - // dark artwork — all its layers stay fixed-dark together; a tokenized - // stop here would split from the still-dark fade when the theme flips. - background: linear-gradient(180deg, #002d19 0%, #161616 100%); - } - - &__arcs { - position: absolute; - top: pxToRem(77px); - left: 50%; - transform: translateX(-50%); - width: pxToRem(395px); - height: pxToRem(180px); - max-width: none; - } - - &__fade { - position: absolute; - top: pxToRem(73px); - left: 0; - right: 0; - height: pxToRem(356px); - background: linear-gradient( - 180deg, - rgba(22, 23, 23, 0) 4.7%, - #151616 44.67% - ); - } - - &__overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - height: pxToRem(356px); - background: linear-gradient( - 180deg, - rgba(22, 23, 23, 0) 4.7%, - rgba(21, 22, 22, 0.78) 44.67% - ); - } - - &__lockup { - position: absolute; - top: pxToRem(135px); - left: 50%; - transform: translateX(-50%); - width: pxToRem(165px); - height: auto; - } - } - - &__content { - position: relative; - display: flex; - flex-direction: column; - // Fills the sheet but may grow past it, scrolling the root, when the - // viewport is shorter than the content - min-height: 100%; - padding-bottom: pxToRem(24px); - gap: pxToRem(32px); - } - - // Mirrors the View app header metrics (80px tall, 24px inset) so the X - // sits exactly where the QR code screen's does - &__header { - display: flex; - align-items: center; - min-height: pxToRem(80px); - padding: 0 pxToRem(24px); - } - - // The BackButton class supplies the geometry; a - - - !open && setIsSheetOpen(false)} - ariaLabel={t("USDT0 is now on Stellar")} - > -
- setIsSheetOpen(false)} /> -
-
- - ); -}; diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/styles.scss b/extension/src/popup/components/account/Usdt0LaunchBanner/styles.scss deleted file mode 100644 index 7a029c7f2b..0000000000 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/styles.scss +++ /dev/null @@ -1,110 +0,0 @@ -@use "../../../styles/utils.scss" as *; - -.Usdt0LaunchBanner { - position: relative; - // Its own stacking context, so the dismiss button's z-index stays inside - // the banner instead of lifting it over Home's pinned header as the banner - // scrolls under it. - isolation: isolate; - background: #002d19; - border-radius: pxToRem(12px); - // No margins: this sits in `AccountHeader__account-info`, which spans the - // content column and spaces its children 16px apart, so the banner - // stretches to match the action tiles and takes the same gap above and - // below them as Figma's balance, tiles and tabs. - display: flex; - align-items: center; - justify-content: space-between; - gap: pxToRem(12px); - transition: opacity 0.2s ease; - - &:hover { - opacity: 0.9; - } - - // The launch surface is a real + + + + + ); +}; + +/** + * Full-screen "Meet Ethena on Stellar" launch promo. UnlockAccount routes here + * once per eligible wallet (the background marks it seen as it hands it out), + * and the Home banner opens it on demand. Closing returns to the destination + * in location state, or Home. + */ +export const EthenaLaunch = () => { + const { t } = useTranslation(); + const navigate = useNavigate(); + const location = useLocation(); + const destination = get( + location, + "state.destination", + ROUTES.account, + ) as string; + + const handleClose = () => { + navigate(destination, { replace: true }); + }; + + const handleReceive = () => { + navigateTo(ROUTES.viewPublicKey, navigate); + }; + + const handleLearnMore = () => { + openTab(ETHENA_URL); + }; + + return ( + // Pinned dark: the hero art is drawn for a black page and there is no + // light design. +
+
+ +
+ +
+ + +
+ + {t("Meet Ethena on Stellar")} + +
+ {t("Discover USDe and sUSDe, now available on Stellar.")} +
+
+
+ {t("Scroll to discover tokens")} +
+
+ +
+ + + +
+
+ ); +}; diff --git a/extension/src/popup/views/EthenaLaunch/styles.scss b/extension/src/popup/views/EthenaLaunch/styles.scss new file mode 100644 index 0000000000..00cae353d7 --- /dev/null +++ b/extension/src/popup/views/EthenaLaunch/styles.scss @@ -0,0 +1,337 @@ +@use "../../styles/utils.scss" as *; + +// Figma's launch timeline (1s, plays once): the wave and the coins slide in +// over 800ms, the title and subtitle fade in from 200ms, the scroll cue from +// 400ms. +$enter-duration: 800ms; +$fade-duration: 500ms; +$copy-delay: 200ms; +$scroll-hint-delay: 400ms; +$slide-easing: cubic-bezier(0.22, 1, 0.36, 1); +$fade-easing: cubic-bezier(0.4, 0, 0.2, 1); + +// The design is a 360px column; wider windows centre it on the black page. +$column-width: 360px; + +.EthenaLaunch { + position: relative; + flex: 1; + min-height: 0; + overflow-x: hidden; + overflow-y: auto; + background: var(--sds-clr-base-00); + // Re-resolves inherited text against this subtree's theme class; body's + // color arrives already computed in the page theme. + color: var(--sds-clr-gray-12); + // No scrollbar, as in the design: the scroll cue says there's more below. + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } + + // Sticky, so the X stays reachable once the tokens scroll under it, and + // zero-height, so it overlays the hero instead of pushing it down. + &__header { + position: sticky; + top: 0; + z-index: 1; + height: 0; + display: flex; + justify-content: flex-end; + } + + &__close { + flex-shrink: 0; + width: pxToRem(24px); + height: pxToRem(24px); + margin: pxToRem(24px) pxToRem(16px) 0 0; + padding: 0; + background: none; + border: none; + cursor: pointer; + color: var(--sds-clr-gray-12); + + svg { + display: block; + width: pxToRem(24px); + height: pxToRem(24px); + @include icon-stroke(24, 1.5); + } + } + + // The first screen: at least as tall as the window, with the scroll cue on + // its bottom edge and the tokens starting below the fold. + &__hero { + position: relative; + width: pxToRem($column-width); + max-width: 100%; + min-height: 100%; + margin: 0 auto; + padding: pxToRem(130px) 0 pxToRem(16px); + display: flex; + flex-direction: column; + align-items: center; + gap: pxToRem(48px); + } + + // Figma clips the wave art to a 534x301 frame centred 50px left of the + // column; the image sits inside it at the frame's own offsets. + &__wave { + position: absolute; + top: pxToRem(48px); + left: calc(50% - #{pxToRem(317px)}); + width: pxToRem(534px); + height: pxToRem(301px); + overflow: hidden; + pointer-events: none; + animation: + EthenaLaunch-slide-in-x $enter-duration $slide-easing both, + EthenaLaunch-fade-in $enter-duration $fade-easing both; + + // The frame's side edges, and the bottom edge where the strokes run down + // to it on the left, fall outside the 360px popup. A wider sidebar or tab + // would show the strokes cut off there, so fade them out. + @media (min-width: 435px) { + mask-image: + linear-gradient( + to right, + transparent, + black 20%, + black 80%, + transparent + ), + linear-gradient(to bottom, black 60%, transparent); + mask-composite: intersect; + } + + img { + position: absolute; + top: pxToRem(-82.254px); + left: pxToRem(-163.603px); + width: pxToRem(786.059px); + height: pxToRem(476.965px); + max-width: none; + } + } + + // The two coins overlap as in Figma's stack: the dark one on top. + &__coins { + position: relative; + flex-shrink: 0; + width: pxToRem(240px); + height: pxToRem(195.5px); + } + + &__coin { + position: absolute; + max-width: none; + object-fit: cover; + animation: + EthenaLaunch-slide-in-y $enter-duration $slide-easing both, + EthenaLaunch-fade-in $enter-duration $fade-easing both; + + &--light { + top: pxToRem(53.55px); + left: pxToRem(84.71px); + width: pxToRem(155.294px); + height: pxToRem(141.961px); + } + + // The artwork carries empty space above the coin, which Figma crops. + &--dark { + top: 0; + left: 0; + width: pxToRem(187px); + height: pxToRem(161px); + object-position: bottom; + } + } + + &__intro { + display: flex; + flex-direction: column; + gap: pxToRem(8px); + width: 100%; + padding: 0 pxToRem(24px); + text-align: center; + animation: EthenaLaunch-fade-in $fade-duration $fade-easing $copy-delay both; + } + + &__subtitle { + font-size: pxToRem(14px); + line-height: pxToRem(20px); + color: var(--sds-clr-gray-11); + // Breaks after "sUSDe," as the design does, without hardcoding the + // break into the translated copy. + text-wrap: balance; + } + + &__scroll-hint { + // Pushed to the bottom of the first screen however tall the window is. + margin-top: auto; + display: flex; + flex-direction: column; + align-items: center; + gap: pxToRem(4px); + font-size: pxToRem(12px); + line-height: pxToRem(18px); + font-weight: var(--sds-fw-medium); + color: var(--sds-clr-gray-11); + text-align: center; + animation: EthenaLaunch-fade-in $fade-duration $fade-easing + $scroll-hint-delay both; + + svg { + width: pxToRem(18px); + height: pxToRem(18px); + color: var(--sds-clr-gray-09); + @include icon-stroke(18); + } + } + + &__tokens { + width: pxToRem($column-width); + max-width: 100%; + margin: 0 auto; + padding-bottom: pxToRem(24px); + display: flex; + flex-direction: column; + align-items: center; + } + + &__token { + width: 100%; + padding: pxToRem(16px) pxToRem(24px); + display: flex; + flex-direction: column; + gap: pxToRem(24px); + + &__info { + display: flex; + flex-direction: column; + gap: pxToRem(8px); + } + + &__heading { + display: flex; + align-items: center; + gap: pxToRem(12px); + } + + &__logo { + flex-shrink: 0; + width: pxToRem(40px); + height: pxToRem(40px); + } + + &__code { + font-size: pxToRem(16px); + line-height: pxToRem(24px); + font-weight: var(--sds-fw-semi-bold); + color: var(--sds-clr-gray-12); + } + + &__name, + &__description { + font-size: pxToRem(12px); + line-height: pxToRem(18px); + font-weight: var(--sds-fw-medium); + color: var(--sds-clr-gray-11); + } + + &__actions { + display: flex; + flex-direction: column; + gap: pxToRem(8px); + } + } + + // Borderless text button per design. No SDS Button variant is transparent, + // so it's hand-rolled at Figma's metrics (32px tall, 14/20 text). + &__transfer { + display: flex; + align-items: center; + justify-content: center; + gap: pxToRem(4px); + width: 100%; + height: pxToRem(32px); + padding: pxToRem(6px) pxToRem(12px); + background: none; + border: none; + border-radius: pxToRem(100px); + cursor: pointer; + color: var(--sds-clr-gray-12); + font-family: inherit; + font-size: pxToRem(14px); + font-weight: var(--sds-fw-semi-bold); + line-height: pxToRem(20px); + + &:hover { + // Opaque fallback first: manifest v2 still allows Firefox < 113, no + // color-mix + background: var(--sds-clr-gray-04); + background: color-mix(in srgb, var(--sds-clr-gray-12) 10%, transparent); + } + + svg { + width: pxToRem(16px); + height: pxToRem(16px); + @include icon-stroke(16); + } + } + + &__learn-more { + display: flex; + align-items: center; + gap: pxToRem(8px); + margin-top: pxToRem(24px); + padding: 0; + background: none; + border: none; + cursor: pointer; + color: var(--sds-clr-gray-09); + font-family: inherit; + font-size: pxToRem(12px); + font-weight: var(--sds-fw-medium); + line-height: pxToRem(18px); + + &:hover { + color: var(--sds-clr-gray-11); + } + + svg { + width: pxToRem(14px); + height: pxToRem(14px); + color: var(--sds-clr-gray-10); + @include icon-stroke(14, 1.5); + } + } + + @media (prefers-reduced-motion: reduce) { + &__wave, + &__coin, + &__intro, + &__scroll-hint { + animation: none; + } + } +} + +@keyframes EthenaLaunch-fade-in { + from { + opacity: 0; + } +} + +@keyframes EthenaLaunch-slide-in-x { + from { + transform: translateX(-20px); + } +} + +@keyframes EthenaLaunch-slide-in-y { + from { + transform: translateY(40px); + } +} diff --git a/extension/src/popup/views/UnlockAccount/__tests__/UnlockAccount.test.tsx b/extension/src/popup/views/UnlockAccount/__tests__/UnlockAccount.test.tsx index c123dd1cb2..5cee4ed6fb 100644 --- a/extension/src/popup/views/UnlockAccount/__tests__/UnlockAccount.test.tsx +++ b/extension/src/popup/views/UnlockAccount/__tests__/UnlockAccount.test.tsx @@ -50,6 +50,10 @@ const renderLockScreen = ( path={ROUTES.rebrandAnnouncement} element={
} /> + } + /> , ); @@ -61,10 +65,12 @@ const typePasswordAndUnlock = async (password: string) => { describe("UnlockAccount", () => { beforeEach(() => { - // Only wallets that pre-date the rebrand are owed the announcement. + // Only wallets that pre-date the rebrand are owed the announcement, and + // only wallets that pre-date the launch build are owed its promo. jest .spyOn(ApiInternal, "claimRebrandAnnouncement") .mockResolvedValue(false); + jest.spyOn(ApiInternal, "claimEthenaLaunchPromo").mockResolvedValue(false); }); afterEach(() => { @@ -140,6 +146,70 @@ describe("UnlockAccount", () => { expect(screen.queryByTestId("account-view-stub")).toBeNull(); }); + it("shows the one-time Ethena launch promo on the way Home to a wallet that's owed it", async () => { + jest + .spyOn(ApiInternal, "confirmPassword") + .mockResolvedValue(unlockedResponse as any); + jest.spyOn(ApiInternal, "claimEthenaLaunchPromo").mockResolvedValue(true); + renderLockScreen(); + + await typePasswordAndUnlock("my password"); + + expect(await screen.findByTestId("ethena-launch-stub")).toBeInTheDocument(); + expect(screen.queryByTestId("account-view-stub")).toBeNull(); + }); + + it("goes Home when the launch promo can't be claimed", async () => { + jest + .spyOn(ApiInternal, "confirmPassword") + .mockResolvedValue(unlockedResponse as any); + jest + .spyOn(ApiInternal, "claimEthenaLaunchPromo") + .mockRejectedValue(new Error("no background")); + renderLockScreen(); + + await typePasswordAndUnlock("my password"); + + expect(await screen.findByTestId("account-view-stub")).toBeInTheDocument(); + }); + + it("keeps a dApp request ahead of the launch promo, which stays owed", async () => { + jest + .spyOn(ApiInternal, "confirmPassword") + .mockResolvedValue(unlockedResponse as any); + const claimPromo = jest + .spyOn(ApiInternal, "claimEthenaLaunchPromo") + .mockResolvedValue(true); + renderLockScreen({ + pathname: ROUTES.unlockAccount, + search: "?request=abc", + state: { from: { pathname: ROUTES.grantAccess } }, + }); + + await typePasswordAndUnlock("my password"); + + expect(await screen.findByTestId("grant-access-stub")).toBeInTheDocument(); + expect(claimPromo).not.toHaveBeenCalled(); + }); + + it("shows the rebrand announcement first and leaves the launch promo owed", async () => { + jest + .spyOn(ApiInternal, "confirmPassword") + .mockResolvedValue(unlockedResponse as any); + jest.spyOn(ApiInternal, "claimRebrandAnnouncement").mockResolvedValue(true); + const claimPromo = jest + .spyOn(ApiInternal, "claimEthenaLaunchPromo") + .mockResolvedValue(true); + renderLockScreen(); + + await typePasswordAndUnlock("my password"); + + expect( + await screen.findByTestId("rebrand-announcement-stub"), + ).toBeInTheDocument(); + expect(claimPromo).not.toHaveBeenCalled(); + }); + it("shows Incorrect Password and stays locked on a wrong password", async () => { jest .spyOn(ApiInternal, "confirmPassword") diff --git a/extension/src/popup/views/UnlockAccount/index.tsx b/extension/src/popup/views/UnlockAccount/index.tsx index aa7e2f3963..22f58b3b82 100644 --- a/extension/src/popup/views/UnlockAccount/index.tsx +++ b/extension/src/popup/views/UnlockAccount/index.tsx @@ -17,7 +17,10 @@ import { confirmPassword, hasPrivateKeySelector, } from "popup/ducks/accountServices"; -import { claimRebrandAnnouncement } from "@shared/api/internal"; +import { + claimEthenaLaunchPromo, + claimRebrandAnnouncement, +} from "@shared/api/internal"; import { ForgotPasswordSheet } from "./ForgotPasswordSheet"; @@ -71,6 +74,11 @@ export const UnlockAccount = () => { // Wallets that pre-date the rebrand get the one-time announcement before // their destination. The background hands it out once, so of several // surfaces unlocked by the same broadcast only the first shows it. + // + // Wallets that pre-date the Ethena launch build get its one-time promo + // the same way, but only on the way Home: a dApp request isn't held up + // for it, and at most one takeover plays per unlock. Either way the + // promo stays owed until a later unlock claims it. const continueToDestination = async () => { let shouldShowAnnouncement = false; try { @@ -87,6 +95,23 @@ export const UnlockAccount = () => { return; } + let shouldShowLaunchPromo = false; + if (destination === ROUTES.account) { + try { + shouldShowLaunchPromo = await claimEthenaLaunchPromo(); + } catch { + // Fail closed: a messaging failure skips the promo. + } + } + + if (shouldShowLaunchPromo) { + navigate(ROUTES.ethenaLaunch, { + replace: true, + state: { destination: target }, + }); + return; + } + navigate(target, { replace: true }); }; diff --git a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx new file mode 100644 index 0000000000..ee0af2200d --- /dev/null +++ b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx @@ -0,0 +1,166 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { Route, Routes } from "react-router-dom"; + +import { ROUTES } from "popup/constants/routes"; +import { Wrapper } from "popup/__testHelpers__"; +import { EthenaLaunch } from "popup/views/EthenaLaunch"; + +jest.mock("popup/helpers/navigate", () => ({ + ...jest.requireActual("popup/helpers/navigate"), + openTab: jest.fn(), +})); + +// The global mock returns keys verbatim; the per-token labels need their +// {{code}} filled in to be told apart. +jest.mock("react-i18next", () => ({ + useTranslation: () => ({ + t: (key: string, values: Record = {}) => + Object.entries(values).reduce( + (text, [name, value]) => text.split(`{{${name}}}`).join(value), + key, + ), + }), +})); + +const { openTab } = jest.requireMock( + "popup/helpers/navigate", +); + +const SUSHI_STELLAR_SWAP_URL = "https://www.sushi.com/stellar/swap"; +const STARGATE_USDE_URL = + "https://stargate.finance/?srcChain=ethereum&srcToken=0x4c9EDD5852cd905f086C759E8383e09bff1E68B3&dstChain=stellar&dstToken=CCNOV6XVI2O5BSTA3232GIRUQULDEBV7IWGKM6QKI6II5OIIQTU24JJN"; +const STARGATE_SUSDE_URL = + "https://stargate.finance/?srcChain=ethereum&srcToken=0x9D39A5DE30e57443BfF2A8307A4256c8797A3497&dstChain=stellar&dstToken=CACSKWC753QVGC4J6YPDBIR2BEHFVWIAE7CBSS3HOVYMN623OAIQYE2M"; + +const renderView = (destination?: string) => + render( + + + } /> + account-home
} /> + settings-home} /> + view-public-key} + /> + + , + ); + +describe("EthenaLaunch", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("introduces Ethena and both of its tokens", () => { + renderView(); + + expect( + screen.getByRole("heading", { name: "Meet Ethena on Stellar" }), + ).toBeInTheDocument(); + expect( + screen.getByText("Discover USDe and sUSDe, now available on Stellar."), + ).toBeInTheDocument(); + expect(screen.getByText("Scroll to discover tokens")).toBeInTheDocument(); + expect(screen.getByText("Synthetic Dollar")).toBeInTheDocument(); + expect( + screen.getByText( + "A synthetic dollar designed to maintain a value of $1.", + ), + ).toBeInTheDocument(); + expect(screen.getByText("Staked USDe")).toBeInTheDocument(); + expect( + screen.getByText( + "A staked version of USDe that accrues variable protocol rewards.", + ), + ).toBeInTheDocument(); + }); + + it("stays on the dark theme whatever the app theme is", () => { + renderView(); + + expect(screen.getByTestId("ethena-launch")).toHaveClass("sds-theme-dark"); + }); + + it("swaps on Sushi for either token", async () => { + renderView(); + + await userEvent.click(screen.getByTestId("ethena-launch-swap-usde")); + await userEvent.click(screen.getByTestId("ethena-launch-swap-susde")); + + expect(screen.getByTestId("ethena-launch-swap-usde")).toHaveTextContent( + "Swap to USDe", + ); + expect(screen.getByTestId("ethena-launch-swap-susde")).toHaveTextContent( + "Swap to sUSDe", + ); + expect(openTab).toHaveBeenNthCalledWith(1, SUSHI_STELLAR_SWAP_URL); + expect(openTab).toHaveBeenNthCalledWith(2, SUSHI_STELLAR_SWAP_URL); + }); + + it("transfers each token to Stellar through Stargate", async () => { + renderView(); + + await userEvent.click(screen.getByTestId("ethena-launch-transfer-usde")); + await userEvent.click(screen.getByTestId("ethena-launch-transfer-susde")); + + expect(openTab).toHaveBeenNthCalledWith(1, STARGATE_USDE_URL); + expect(openTab).toHaveBeenNthCalledWith(2, STARGATE_SUSDE_URL); + }); + + it("receives USDe on the wallet's address screen", async () => { + renderView(); + + expect(screen.getByTestId("ethena-launch-receive-usde")).toHaveTextContent( + "Receive USDe", + ); + await userEvent.click(screen.getByTestId("ethena-launch-receive-usde")); + + expect(await screen.findByText("view-public-key")).toBeInTheDocument(); + }); + + it("receives sUSDe on the wallet's address screen", async () => { + renderView(); + + expect(screen.getByTestId("ethena-launch-receive-susde")).toHaveTextContent( + "Receive sUSDe", + ); + await userEvent.click(screen.getByTestId("ethena-launch-receive-susde")); + + expect(await screen.findByText("view-public-key")).toBeInTheDocument(); + }); + + it("links out to Ethena", async () => { + renderView(); + + await userEvent.click(screen.getByTestId("ethena-launch-learn-more")); + + expect(openTab).toHaveBeenCalledWith("https://ethena.fi/"); + }); + + it("closes to the destination it was given", async () => { + renderView(ROUTES.settings); + + await userEvent.click(screen.getByTestId("ethena-launch-close")); + + expect(await screen.findByText("settings-home")).toBeInTheDocument(); + }); + + it("closes to the account view when no destination was given", async () => { + renderView(); + + await userEvent.click(screen.getByTestId("ethena-launch-close")); + + expect(await screen.findByText("account-home")).toBeInTheDocument(); + }); +}); From e40c2667c56122837a82d5b6924fc0e427358894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Fri, 13 Nov 2026 14:18:28 -0800 Subject: [PATCH 02/11] fix: link "Learn more about Ethena" to Ethena's docs Co-Authored-By: Claude Opus 5.5 --- extension/src/popup/views/EthenaLaunch/index.tsx | 4 ++-- extension/src/popup/views/__tests__/EthenaLaunch.test.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extension/src/popup/views/EthenaLaunch/index.tsx b/extension/src/popup/views/EthenaLaunch/index.tsx index 2fcb31ea0e..085848580d 100644 --- a/extension/src/popup/views/EthenaLaunch/index.tsx +++ b/extension/src/popup/views/EthenaLaunch/index.tsx @@ -24,7 +24,7 @@ const STARGATE_USDE_URL = "https://stargate.finance/?srcChain=ethereum&srcToken=0x4c9EDD5852cd905f086C759E8383e09bff1E68B3&dstChain=stellar&dstToken=CCNOV6XVI2O5BSTA3232GIRUQULDEBV7IWGKM6QKI6II5OIIQTU24JJN"; const STARGATE_SUSDE_URL = "https://stargate.finance/?srcChain=ethereum&srcToken=0x9D39A5DE30e57443BfF2A8307A4256c8797A3497&dstChain=stellar&dstToken=CACSKWC753QVGC4J6YPDBIR2BEHFVWIAE7CBSS3HOVYMN623OAIQYE2M"; -const ETHENA_URL = "https://ethena.fi/"; +const ETHENA_DOCS_URL = "https://docs.ethena.fi/"; interface EthenaTokenSectionProps { id: string; @@ -130,7 +130,7 @@ export const EthenaLaunch = () => { }; const handleLearnMore = () => { - openTab(ETHENA_URL); + openTab(ETHENA_DOCS_URL); }; return ( diff --git a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx index ee0af2200d..dff97dec01 100644 --- a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx +++ b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx @@ -140,12 +140,12 @@ describe("EthenaLaunch", () => { expect(await screen.findByText("view-public-key")).toBeInTheDocument(); }); - it("links out to Ethena", async () => { + it("links out to Ethena's docs", async () => { renderView(); await userEvent.click(screen.getByTestId("ethena-launch-learn-more")); - expect(openTab).toHaveBeenCalledWith("https://ethena.fi/"); + expect(openTab).toHaveBeenCalledWith("https://docs.ethena.fi/"); }); it("closes to the destination it was given", async () => { From 3b80dea32f6b159e46ceb22119ec6820ae41e5df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Fri, 13 Nov 2026 14:19:01 -0800 Subject: [PATCH 03/11] fix: show the Ethena launch banner the same in both themes 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 --- extension/e2e-tests/theme.test.ts | 135 ++++++++++++++++-- .../account/EthenaLaunchBanner/styles.scss | 38 +++-- .../styles/__tests__/varialPalette.test.ts | 9 +- 3 files changed, 147 insertions(+), 35 deletions(-) diff --git a/extension/e2e-tests/theme.test.ts b/extension/e2e-tests/theme.test.ts index e461616440..259867291a 100644 --- a/extension/e2e-tests/theme.test.ts +++ b/extension/e2e-tests/theme.test.ts @@ -48,6 +48,16 @@ const backdrop = (locator: Locator) => return ""; }); +const computed = ( + locator: Locator, + property: + | "color" + | "backgroundColor" + | "borderTopWidth" + | "fill" + | "fontWeight", +) => locator.evaluate((el, prop) => getComputedStyle(el)[prop], property); + // Varial pages sit on base-00; sheets floating over them stay on gray-01. const BASE_00 = { light: "rgb(255, 255, 255)", dark: "rgb(0, 0, 0)" }; const GRAY_01 = { light: "rgb(252, 252, 252)", dark: "rgb(22, 22, 22)" }; @@ -81,7 +91,102 @@ test("welcome screen follows the color scheme", async ({ expect(await backdrop(body)).toBe(BASE_00.dark); }); -test("Ethena launch promo stays dark in light theme", async ({ +// The Ethena launch is one design in both themes. These compare whole renders +// across a live theme change rather than spot-checking a few colors, so any +// property that follows the theme fails the test, named. + +// Waits out entrance animations and transitions, so a render is of the +// settled UI rather than a frame of its motion. +const settle = (locator: Locator) => + locator.evaluate(async (root) => { + await Promise.all( + root.getAnimations({ subtree: true }).map(({ finished }) => finished), + ); + }); + +// Every computed property of every element under the locator, in document +// order. Custom properties are left out: they're the theme's inputs, and one +// changes what's drawn only through the properties that use it, which are +// compared themselves. +const renderedStyles = (locator: Locator) => + locator.evaluate((root) => + [root, ...Array.from(root.querySelectorAll("*"))].map((el) => { + const style = getComputedStyle(el); + const properties: Record = {}; + for (let i = 0; i < style.length; i += 1) { + const name = style.item(i); + if (!name.startsWith("--")) { + properties[name] = style.getPropertyValue(name); + } + } + return { + element: `${el.tagName.toLowerCase()}.${el.getAttribute("class") ?? ""}`, + properties, + }; + }), + ); + +type RenderedStyles = Awaited>; + +// What changed between two renders of the same elements, one line per +// property, so a failure says exactly what the theme flipped. +const styleChanges = (before: RenderedStyles, after: RenderedStyles) => [ + ...(after.length === before.length + ? [] + : [`${before.length} elements → ${after.length}`]), + ...before.flatMap(({ element, properties }, index) => + Object.entries(properties) + .filter(([name, value]) => after[index]?.properties[name] !== value) + .map( + ([name, value]) => + `${element} ${name}: ${value} → ${after[index]?.properties[name]}`, + ), + ), +]; + +test("Ethena launch banner looks the same in both themes", async ({ + page, + extensionId, + context, +}) => { + await page.emulateMedia({ colorScheme: "light" }); + await loginToTestAccount({ page, extensionId, context }); + const banner = page.getByTestId("ethena-launch-banner"); + await expect(banner).toBeVisible(); + // Off the banner, so neither render is of its hover state. + await page.mouse.move(0, 0); + await settle(banner); + const light = await renderedStyles(banner); + + await page.emulateMedia({ colorScheme: "dark" }); + await expect(page.locator("body")).toHaveClass(/sds-theme-dark/); + await settle(banner); + expect(styleChanges(light, await renderedStyles(banner))).toEqual([]); + + // And it's Figma's banner (4414:42195): the near-black card with no + // outline, white title, light-gray subtitle and gray X. + expect({ + card: await computed(banner, "backgroundColor"), + outline: await computed(banner, "borderTopWidth"), + title: await computed(banner.getByText("Meet Ethena on Stellar"), "color"), + subtitle: await computed( + banner.getByText("USDe and sUSDe are now available."), + "color", + ), + dismiss: await computed( + page.getByTestId("ethena-launch-banner-dismiss"), + "color", + ), + }).toEqual({ + card: "rgb(7, 9, 8)", + outline: "0px", + title: "rgb(255, 255, 255)", + subtitle: "rgb(199, 199, 199)", + dismiss: "rgb(133, 133, 133)", + }); +}); + +test("Ethena launch promo looks the same in both themes", async ({ page, extensionId, context, @@ -91,30 +196,38 @@ test("Ethena launch promo stays dark in light theme", async ({ await page.getByTestId("ethena-launch-banner-open").click(); const promo = page.getByTestId("ethena-launch"); await expect(promo).toBeVisible(); + await settle(promo); // Its hero art is drawn for a black page, so the page and the text over it // must resolve dark-theme tokens even though the app is light. - const colorOf = (el: Element) => getComputedStyle(el).color; const darkGray12 = "rgb(237, 237, 237)"; expect(await backdrop(promo)).toBe(BASE_00.dark); expect( - await page - .getByRole("heading", { name: "Meet Ethena on Stellar" }) - .evaluate(colorOf), + await computed( + page.getByRole("heading", { name: "Meet Ethena on Stellar" }), + "color", + ), ).toBe(darkGray12); - expect(await page.getByTestId("ethena-launch-close").evaluate(colorOf)).toBe( + expect(await computed(page.getByTestId("ethena-launch-close"), "color")).toBe( darkGray12, ); + // It fills the window, so none of the themed page shows around it. + expect(await promo.boundingBox()).toEqual({ + x: 0, + y: 0, + ...page.viewportSize(), + }); + const light = await renderedStyles(promo); + + await page.emulateMedia({ colorScheme: "dark" }); + await expect(page.locator("body")).toHaveClass(/sds-theme-dark/); + await settle(promo); + expect(styleChanges(light, await renderedStyles(promo))).toEqual([]); }); // The lock screen and its Forgot password sheet resolve their colors in both // themes. Expected values are the resolved tokens: gray, red and base from // SDS's .sds-theme-* blocks, lilac from varialPalette.scss. -const computed = ( - locator: Locator, - property: "color" | "backgroundColor" | "fill" | "fontWeight", -) => locator.evaluate((el, prop) => getComputedStyle(el)[prop], property); - const lockScreenColors = async (page: Page) => ({ heading: await computed( page.getByRole("heading", { name: "Welcome back" }), diff --git a/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss b/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss index 435a09a915..7559faf401 100644 --- a/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss +++ b/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss @@ -1,5 +1,7 @@ @use "../../../styles/utils.scss" as *; +// Figma's banner (4414:42195), drawn the same in both themes: the campaign's +// fixed near-black card, with fixed colors on it rather than theme tokens. .EthenaLaunchBanner { position: relative; // Its own stacking context, so the dismiss button's z-index stays inside @@ -7,13 +9,13 @@ // scrolls under it, and the glow can sit behind the copy at z-index -1. isolation: isolate; overflow: hidden; - // The campaign's fixed near-black surface, the same in both themes. background: #070908; - // Dark mode outlines the card (below). The border is there in light mode - // too, transparent over the same fill, so the card is the same size in - // both; the padding is Figma's 12px/16px less that 1px. - border: pxToRem(1px) solid transparent; border-radius: pxToRem(16px); + // The copy is white unless it says otherwise. + color: var(--sds-clr-white); + // What the browser draws itself, like the keyboard focus ring, follows the + // color scheme. Fixed to the dark card's so it doesn't flip either. + color-scheme: dark; // No margins: this sits in `AccountHeader__account-info`, which spans the // content column and spaces its children 16px apart, so the banner // stretches to match the action tiles. @@ -23,13 +25,13 @@ opacity: 0.9; } - // The blurred blue disc bleeding off the card's top-right corner. Offsets - // are Figma's, less the 1px border the padding box starts inside. + // The blurred blue disc bleeding off the card's top-right corner, at + // Figma's offsets. &__glow { position: absolute; z-index: -1; - top: pxToRem(-81px); - right: pxToRem(-80px); + top: pxToRem(-80px); + right: pxToRem(-79px); width: pxToRem(263px); height: pxToRem(263px); max-width: none; @@ -45,21 +47,20 @@ display: flex; flex-direction: column; width: 100%; - padding: pxToRem(11px) pxToRem(40px) pxToRem(11px) pxToRem(15px); + padding: pxToRem(12px) pxToRem(40px) pxToRem(12px) pxToRem(16px); background: none; border: none; border-radius: inherit; + color: inherit; font: inherit; text-align: left; cursor: pointer; } - // The surface doesn't follow the theme, so neither does its copy. &__title { font-size: pxToRem(14px); line-height: pxToRem(20px); font-weight: var(--sds-fw-semi-bold); - color: var(--sds-clr-white); } &__subtitle { @@ -69,10 +70,12 @@ color: #c7c7c7; } + // The X sits 12px in from the top and right, as in Figma, inside its 4px + // hover padding. &__dismiss { position: absolute; - top: pxToRem(7px); - right: pxToRem(7px); + top: pxToRem(8px); + right: pxToRem(8px); z-index: 1; display: flex; align-items: center; @@ -82,8 +85,7 @@ border: none; border-radius: pxToRem(16px); cursor: pointer; - // Gray/10 is the X's color in both of Figma's themes. - color: var(--sds-clr-gray-10); + color: #858585; &:hover { background: rgba(255, 255, 255, 0.1); @@ -96,7 +98,3 @@ } } } - -.sds-theme-dark .EthenaLaunchBanner { - border-color: var(--sds-clr-gray-04); -} diff --git a/extension/src/popup/styles/__tests__/varialPalette.test.ts b/extension/src/popup/styles/__tests__/varialPalette.test.ts index 01051b1487..f7ba67086e 100644 --- a/extension/src/popup/styles/__tests__/varialPalette.test.ts +++ b/extension/src/popup/styles/__tests__/varialPalette.test.ts @@ -84,12 +84,13 @@ const ALLOWED_RAW_COLORS: Record = { "popup/styles/varialPalette.scss": ["*"], // Emulates the browser's native focus ring; deliberately not themed. "popup/styles/utils.scss": ["rgb(153, 200, 255)"], - // Ethena launch banner: the campaign's fixed near-black surface and the - // dismiss-button hover drawn on it (correct in both themes). + // Ethena launch banner: one design in both themes, Figma's (4414:42195). + // The campaign's fixed near-black surface and the colors drawn on it. "popup/components/account/EthenaLaunchBanner/styles.scss": [ "#070908", - "#c7c7c7", // subtitle on the fixed campaign surface; must not theme-flip - "rgba(255, 255, 255, 0.1)", + "#c7c7c7", // subtitle + "#858585", // dismiss X + "rgba(255, 255, 255, 0.1)", // dismiss hover ], // Account avatar artwork; fixed so an avatar looks the same in both themes. "popup/components/identicons/IdenticonImg/colors.ts": ["*"], From d3bbf2b75eff026beeba5ce2aca03531c1e8554f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Fri, 13 Nov 2026 15:39:39 -0800 Subject: [PATCH 04/11] fix: outline the Ethena launch banner in dark mode 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 --- extension/e2e-tests/ethenaLaunch.test.ts | 61 +++++++++++++++++++ extension/e2e-tests/theme.test.ts | 35 ++++++----- .../account/EthenaLaunchBanner/styles.scss | 19 +++++- .../styles/__tests__/varialPalette.test.ts | 4 +- 4 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 extension/e2e-tests/ethenaLaunch.test.ts diff --git a/extension/e2e-tests/ethenaLaunch.test.ts b/extension/e2e-tests/ethenaLaunch.test.ts new file mode 100644 index 0000000000..e58c88fd78 --- /dev/null +++ b/extension/e2e-tests/ethenaLaunch.test.ts @@ -0,0 +1,61 @@ +import type { BrowserContext } from "@playwright/test"; +import { test, expect } from "./test-fixtures"; +import { loginToTestAccount } from "./helpers/login"; + +// How much of a screenshot is drawn in Chrome's focus ring blue for a dark +// color scheme (#99c8ff), which the banner pins in both themes. Decoded on a +// blank page, outside the extension's CSP. +const focusRingPixels = async (context: BrowserContext, png: Buffer) => { + const blank = await context.newPage(); + const result = await blank.evaluate(async (base64) => { + const image = new Image(); + image.src = `data:image/png;base64,${base64}`; + await image.decode(); + const canvas = new OffscreenCanvas(image.width, image.height); + const context2d = canvas.getContext("2d")!; + context2d.drawImage(image, 0, 0); + const { data } = context2d.getImageData(0, 0, image.width, image.height); + let pixels = 0; + for (let i = 0; i < data.length; i += 4) { + const distance = + Math.abs(data[i] - 0x99) + + Math.abs(data[i + 1] - 0xc8) + + Math.abs(data[i + 2] - 0xff); + if (distance < 48) { + pixels += 1; + } + } + return { pixels, perimeter: 2 * (image.width + image.height) }; + }, png.toString("base64")); + await blank.close(); + return result; +}; + +for (const colorScheme of ["dark", "light"] as const) { + test(`Ethena launch banner shows keyboard focus on its main button in ${colorScheme} mode`, async ({ + page, + extensionId, + context, + }) => { + await page.emulateMedia({ colorScheme }); + await loginToTestAccount({ page, extensionId, context }); + const banner = page.getByTestId("ethena-launch-banner"); + await expect(banner).toBeVisible(); + // Off the banner, so the shot isn't of its hover state. + await page.mouse.move(0, 0); + + // Back from the dismiss button, as a keyboard user reaches it. + await page.getByTestId("ethena-launch-banner-dismiss").focus(); + await page.keyboard.press("Shift+Tab"); + await expect(page.getByTestId("ethena-launch-banner-open")).toBeFocused(); + + // The button fills the card, which clips anything drawn outside it, and + // dark mode's outline covers the card's edge. The ring only shows all the + // way round if it's drawn inside both. + const { pixels, perimeter } = await focusRingPixels( + context, + await banner.screenshot(), + ); + expect(pixels).toBeGreaterThan(perimeter); + }); +} diff --git a/extension/e2e-tests/theme.test.ts b/extension/e2e-tests/theme.test.ts index 259867291a..0f0d92d23b 100644 --- a/extension/e2e-tests/theme.test.ts +++ b/extension/e2e-tests/theme.test.ts @@ -50,12 +50,7 @@ const backdrop = (locator: Locator) => const computed = ( locator: Locator, - property: - | "color" - | "backgroundColor" - | "borderTopWidth" - | "fill" - | "fontWeight", + property: "color" | "backgroundColor" | "fill" | "fontWeight", ) => locator.evaluate((el, prop) => getComputedStyle(el)[prop], property); // Varial pages sit on base-00; sheets floating over them stay on gray-01. @@ -91,9 +86,10 @@ test("welcome screen follows the color scheme", async ({ expect(await backdrop(body)).toBe(BASE_00.dark); }); -// The Ethena launch is one design in both themes. These compare whole renders -// across a live theme change rather than spot-checking a few colors, so any -// property that follows the theme fails the test, named. +// The Ethena launch is one design in both themes, but for the banner's outline +// in dark mode. These compare whole renders across a live theme change rather +// than spot-checking a few colors, so any property that follows the theme +// shows up, named. // Waits out entrance animations and transitions, so a render is of the // settled UI rather than a frame of its motion. @@ -144,7 +140,7 @@ const styleChanges = (before: RenderedStyles, after: RenderedStyles) => [ ), ]; -test("Ethena launch banner looks the same in both themes", async ({ +test("Ethena launch banner only adds an outline in dark mode", async ({ page, extensionId, context, @@ -161,13 +157,21 @@ test("Ethena launch banner looks the same in both themes", async ({ await page.emulateMedia({ colorScheme: "dark" }); await expect(page.locator("body")).toHaveClass(/sds-theme-dark/); await settle(banner); - expect(styleChanges(light, await renderedStyles(banner))).toEqual([]); - - // And it's Figma's banner (4414:42195): the near-black card with no - // outline, white title, light-gray subtitle and gray X. + // Dark mode outlines the card in gray-04, so it stands out on the black + // page (Figma 4414:59535). Drawn inside the card, it moves nothing, and + // nothing else follows the theme. (Light mode's 3px is the initial width, + // which Chrome reports while the style is none; nothing is drawn.) + expect(styleChanges(light, await renderedStyles(banner))).toEqual([ + "div.EthenaLaunchBanner outline-color: rgb(255, 255, 255) → rgb(40, 40, 40)", + "div.EthenaLaunchBanner outline-offset: 0px → -1px", + "div.EthenaLaunchBanner outline-style: none → solid", + "div.EthenaLaunchBanner outline-width: 3px → 1px", + ]); + + // Otherwise it's Figma's banner (4414:42195): the near-black card, white + // title, light-gray subtitle and gray X. expect({ card: await computed(banner, "backgroundColor"), - outline: await computed(banner, "borderTopWidth"), title: await computed(banner.getByText("Meet Ethena on Stellar"), "color"), subtitle: await computed( banner.getByText("USDe and sUSDe are now available."), @@ -179,7 +183,6 @@ test("Ethena launch banner looks the same in both themes", async ({ ), }).toEqual({ card: "rgb(7, 9, 8)", - outline: "0px", title: "rgb(255, 255, 255)", subtitle: "rgb(199, 199, 199)", dismiss: "rgb(133, 133, 133)", diff --git a/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss b/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss index 7559faf401..5e280080a6 100644 --- a/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss +++ b/extension/src/popup/components/account/EthenaLaunchBanner/styles.scss @@ -1,7 +1,8 @@ @use "../../../styles/utils.scss" as *; -// Figma's banner (4414:42195), drawn the same in both themes: the campaign's -// fixed near-black card, with fixed colors on it rather than theme tokens. +// Figma's banner (4414:42195): the campaign's fixed near-black card, with +// fixed colors on it rather than theme tokens, so it's the same in both themes +// apart from dark mode's outline (below). .EthenaLaunchBanner { position: relative; // Its own stacking context, so the dismiss button's z-index stays inside @@ -55,6 +56,12 @@ font: inherit; text-align: left; cursor: pointer; + + // The card clips anything drawn outside it, and dark mode's outline + // covers its edge, so the keyboard focus ring goes inside both. + &:focus-visible { + outline-offset: pxToRem(-3px); + } } &__title { @@ -98,3 +105,11 @@ } } } + +// Dark mode outlines the card, so it stands out on the black page (Figma +// 4414:59535). An inset outline rather than a border: it takes no space, so +// nothing on the card moves, and like Figma's stroke it's drawn over the glow. +.sds-theme-dark .EthenaLaunchBanner { + outline: pxToRem(1px) solid var(--sds-clr-gray-04); + outline-offset: pxToRem(-1px); +} diff --git a/extension/src/popup/styles/__tests__/varialPalette.test.ts b/extension/src/popup/styles/__tests__/varialPalette.test.ts index f7ba67086e..a832840663 100644 --- a/extension/src/popup/styles/__tests__/varialPalette.test.ts +++ b/extension/src/popup/styles/__tests__/varialPalette.test.ts @@ -84,8 +84,8 @@ const ALLOWED_RAW_COLORS: Record = { "popup/styles/varialPalette.scss": ["*"], // Emulates the browser's native focus ring; deliberately not themed. "popup/styles/utils.scss": ["rgb(153, 200, 255)"], - // Ethena launch banner: one design in both themes, Figma's (4414:42195). - // The campaign's fixed near-black surface and the colors drawn on it. + // Ethena launch banner (Figma 4414:42195): the campaign's fixed near-black + // surface and the colors drawn on it, which don't follow the theme. "popup/components/account/EthenaLaunchBanner/styles.scss": [ "#070908", "#c7c7c7", // subtitle From 85ad74b20d45dc3f286916a345fa805d01a6fd7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Fri, 13 Nov 2026 16:13:31 -0800 Subject: [PATCH 05/11] feat: Ethena promo once for every wallet, Sushi pairs and a sticky bar - 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 --- extension/e2e-tests/ethenaLaunch.test.ts | 67 ++++++++++++++++++- extension/e2e-tests/helpers/ethenaLaunch.ts | 11 +++ extension/e2e-tests/onboarding.test.ts | 8 ++- .../helpers/__tests__/migrations.test.ts | 37 ---------- .../src/background/helpers/dataStorage.ts | 24 ------- extension/src/background/index.ts | 2 - .../__tests__/claimEthenaLaunchPromo.test.ts | 40 +++++------ .../__tests__/createAccount.test.ts | 20 +++--- .../__tests__/recoverAccount.test.ts | 21 +++--- .../__tests__/resetWallet.test.ts | 9 ++- .../handlers/claimEthenaLaunchPromo.ts | 14 ++-- .../messageListener/handlers/createAccount.ts | 8 +-- .../handlers/recoverAccount.ts | 8 +-- extension/src/constants/ethenaLaunchPromo.ts | 9 --- extension/src/constants/localStorageTypes.ts | 2 +- .../src/popup/basics/layout/View/styles.scss | 11 +-- extension/src/popup/styles/utils.scss | 11 +++ .../src/popup/views/EthenaLaunch/index.tsx | 60 ++++++++++++----- .../src/popup/views/EthenaLaunch/styles.scss | 33 ++++++++- .../src/popup/views/UnlockAccount/index.tsx | 2 +- .../views/__tests__/EthenaLaunch.test.tsx | 29 ++++++-- 21 files changed, 242 insertions(+), 184 deletions(-) create mode 100644 extension/e2e-tests/helpers/ethenaLaunch.ts delete mode 100644 extension/src/constants/ethenaLaunchPromo.ts diff --git a/extension/e2e-tests/ethenaLaunch.test.ts b/extension/e2e-tests/ethenaLaunch.test.ts index e58c88fd78..2fe380f956 100644 --- a/extension/e2e-tests/ethenaLaunch.test.ts +++ b/extension/e2e-tests/ethenaLaunch.test.ts @@ -1,6 +1,69 @@ -import type { BrowserContext } from "@playwright/test"; +import type { BrowserContext, Page } from "@playwright/test"; import { test, expect } from "./test-fixtures"; -import { loginToTestAccount } from "./helpers/login"; +import { loginToTestAccount, PASSWORD } from "./helpers/login"; +import { goToSettings } from "./helpers/network"; +import { closeEthenaLaunchPromo } from "./helpers/ethenaLaunch"; + +const lockAndUnlock = async (page: Page) => { + await goToSettings(page); + await page.getByText("Log Out").click(); + await expect(page.getByText("Welcome back")).toBeVisible(); + await page.locator("#password-input").fill(PASSWORD); + await page.getByRole("button", { name: "Unlock" }).click(); +}; + +test("every wallet sees the Ethena launch promo once, on its first unlock to Home", async ({ + page, + extensionId, + context, +}) => { + test.slow(); + // A wallet set up just now, as on a new install. Onboarding ends on Home; + // the promo waits for an unlock. + await loginToTestAccount({ page, extensionId, context }); + await expect(page.getByTestId("account-view")).toBeVisible(); + await expect(page.getByTestId("ethena-launch")).toHaveCount(0); + + await lockAndUnlock(page); + await closeEthenaLaunchPromo(page); + await expect(page.getByTestId("account-view")).toBeVisible(); + + // Once only: the next unlock goes straight Home. + await lockAndUnlock(page); + await expect(page.getByTestId("account-view")).toBeVisible({ + timeout: 30000, + }); + await expect(page.getByTestId("ethena-launch")).toHaveCount(0); +}); + +test("Ethena launch promo keeps its close button on a bar as the page scrolls", async ({ + page, + extensionId, + context, +}) => { + await loginToTestAccount({ page, extensionId, context }); + await page.getByTestId("ethena-launch-banner-open").click(); + const promo = page.getByTestId("ethena-launch"); + const close = page.getByTestId("ethena-launch-close"); + await expect(promo).toBeVisible(); + const atTop = await close.boundingBox(); + const barOpacity = () => + page + .getByTestId("ethena-launch-header") + .evaluate((el) => getComputedStyle(el, "::before").opacity); + expect(await barOpacity()).toBe("0"); + + // Down to the tokens: the X stays put, now on the bar, which the tokens + // fade out under. + await promo.evaluate((el) => el.scrollTo(0, el.scrollHeight)); + await expect(page.getByTestId("ethena-launch-learn-more")).toBeInViewport(); + expect(await close.boundingBox()).toEqual(atTop); + await expect.poll(barOpacity).toBe("1"); + + // Back at the top, the bar clears so the hero shows as designed. + await promo.evaluate((el) => el.scrollTo(0, 0)); + await expect.poll(barOpacity).toBe("0"); +}); // How much of a screenshot is drawn in Chrome's focus ring blue for a dark // color scheme (#99c8ff), which the banner pins in both themes. Decoded on a diff --git a/extension/e2e-tests/helpers/ethenaLaunch.ts b/extension/e2e-tests/helpers/ethenaLaunch.ts new file mode 100644 index 0000000000..96a80a3449 --- /dev/null +++ b/extension/e2e-tests/helpers/ethenaLaunch.ts @@ -0,0 +1,11 @@ +import { expect, Page } from "@playwright/test"; + +// Every wallet sees the one-time Ethena launch promo on its first unlock to +// Home. Closes it there, back to Home. +export const closeEthenaLaunchPromo = async (page: Page) => { + await expect(page.getByTestId("ethena-launch")).toBeVisible({ + timeout: 30000, + }); + await page.getByTestId("ethena-launch-close").click(); + await expect(page.getByTestId("ethena-launch")).toBeHidden(); +}; diff --git a/extension/e2e-tests/onboarding.test.ts b/extension/e2e-tests/onboarding.test.ts index 7c509313b3..0515f89955 100644 --- a/extension/e2e-tests/onboarding.test.ts +++ b/extension/e2e-tests/onboarding.test.ts @@ -9,6 +9,7 @@ import { } from "./helpers/onboarding"; import type { Page } from "@playwright/test"; import { goToSettings } from "./helpers/network"; +import { closeEthenaLaunchPromo } from "./helpers/ethenaLaunch"; const { generateMnemonic } = StellarHDWallet; @@ -448,11 +449,13 @@ const expectOnlyNewWalletAccount = async (page: Page, extensionId: string) => { }; // The page where the reset started is still on the lock screen; the new -// wallet's password unlocks it. +// wallet's password unlocks it. It's the new wallet's first unlock, so the +// one-time Ethena launch promo comes first. const unlockOriginalPage = async (page: Page) => { await expect(page.getByText("Welcome back")).toBeVisible(); await page.locator("#password-input").fill(PASSWORD); await page.getByRole("button", { name: "Unlock" }).click(); + await closeEthenaLaunchPromo(page); await expect(page.getByTestId("account-view")).toBeVisible({ timeout: 30000, }); @@ -542,8 +545,11 @@ test("Closing the Forgot password sheet keeps the wallet", async ({ await page.getByTestId("forgot-password-sheet-close").click(); await expect(page.getByTestId("forgot-password-sheet")).toBeHidden(); + // The wallet's first unlock, so the one-time Ethena launch promo comes + // first. await page.locator("#password-input").fill(PASSWORD); await page.getByRole("button", { name: "Unlock" }).click(); + await closeEthenaLaunchPromo(page); await expect(page.getByTestId("account-view")).toBeVisible({ timeout: 30000, }); diff --git a/extension/src/background/helpers/__tests__/migrations.test.ts b/extension/src/background/helpers/__tests__/migrations.test.ts index 55c9cf6949..b251acf527 100644 --- a/extension/src/background/helpers/__tests__/migrations.test.ts +++ b/extension/src/background/helpers/__tests__/migrations.test.ts @@ -14,12 +14,10 @@ import { STORAGE_VERSION, KEY_ID_LIST, REBRAND_ANNOUNCEMENT_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS_ID, TOKEN_ID_LIST, } from "constants/localStorageTypes"; import * as DataStorage from "../dataStorage"; import { REBRAND_ANNOUNCEMENT_STATUS } from "constants/rebrandAnnouncement"; -import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import * as DataStorageAccess from "../dataStorageAccess"; import { DEFAULT_ASSETS_LISTS } from "@shared/constants/soroban/asset-list"; @@ -263,39 +261,4 @@ describe("Storage migrations", () => { ); }); }); - describe("markEthenaLaunchPromoEligibility", () => { - it("marks a wallet that exists when the launch build arrives as pending", async () => { - await mockStorage.set({ [KEY_ID_LIST]: ["key-1"] }); - - await DataStorage.markEthenaLaunchPromoEligibility(); - - const stored = await mockStorage.get(ETHENA_LAUNCH_PROMO_STATUS_ID); - expect(stored[ETHENA_LAUNCH_PROMO_STATUS_ID]).toEqual( - ETHENA_LAUNCH_PROMO_STATUS.PENDING, - ); - }); - - it("marks a fresh install as seen", async () => { - await DataStorage.markEthenaLaunchPromoEligibility(); - - const stored = await mockStorage.get(ETHENA_LAUNCH_PROMO_STATUS_ID); - expect(stored[ETHENA_LAUNCH_PROMO_STATUS_ID]).toEqual( - ETHENA_LAUNCH_PROMO_STATUS.SEEN, - ); - }); - - it("leaves a recorded status alone on later updates", async () => { - await mockStorage.set({ - [KEY_ID_LIST]: ["key-1"], - [ETHENA_LAUNCH_PROMO_STATUS_ID]: ETHENA_LAUNCH_PROMO_STATUS.SEEN, - }); - - await DataStorage.markEthenaLaunchPromoEligibility(); - - const stored = await mockStorage.get(ETHENA_LAUNCH_PROMO_STATUS_ID); - expect(stored[ETHENA_LAUNCH_PROMO_STATUS_ID]).toEqual( - ETHENA_LAUNCH_PROMO_STATUS.SEEN, - ); - }); - }); }); diff --git a/extension/src/background/helpers/dataStorage.ts b/extension/src/background/helpers/dataStorage.ts index 07db6c354f..242c585891 100644 --- a/extension/src/background/helpers/dataStorage.ts +++ b/extension/src/background/helpers/dataStorage.ts @@ -16,10 +16,8 @@ import { LAST_USED_ACCOUNT, KEY_ID_LIST, REBRAND_ANNOUNCEMENT_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS_ID, } from "constants/localStorageTypes"; import { REBRAND_ANNOUNCEMENT_STATUS } from "constants/rebrandAnnouncement"; -import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import { DEFAULT_NETWORKS, NetworkDetails, @@ -405,28 +403,6 @@ export const markRebrandAnnouncementEligibility = async () => { ); }; -/** - * Same once-per-install decision as the rebrand announcement, for the - * one-time Ethena launch promo: a wallet that already exists when the launch - * build first runs is marked pending; a fresh install is marked seen. - */ -export const markEthenaLaunchPromoEligibility = async () => { - const localStore = dataStorageAccess(browserLocalStorage); - - if (await localStore.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID)) { - return; - } - - const keyIdList = ((await localStore.getItem(KEY_ID_LIST)) || []) as string[]; - - await localStore.setItem( - ETHENA_LAUNCH_PROMO_STATUS_ID, - keyIdList.length - ? ETHENA_LAUNCH_PROMO_STATUS.PENDING - : ETHENA_LAUNCH_PROMO_STATUS.SEEN, - ); -}; - export const versionedMigration = async () => { // sequentially call migrations in order to enforce smooth schema upgrades diff --git a/extension/src/background/index.ts b/extension/src/background/index.ts index c7db73b16e..9e20f856fe 100644 --- a/extension/src/background/index.ts +++ b/extension/src/background/index.ts @@ -41,7 +41,6 @@ import { migrateSorobanRpcUrlNetworkDetails, versionedMigration, markRebrandAnnouncementEligibility, - markEthenaLaunchPromoEligibility, } from "./helpers/dataStorage"; import { dataStorageAccess, @@ -212,7 +211,6 @@ export const initInstalledListener = () => { browser?.runtime?.onInstalled.addListener(migrateSorobanRpcUrlNetworkDetails); browser?.runtime?.onInstalled.addListener(versionedMigration); browser?.runtime?.onInstalled.addListener(markRebrandAnnouncementEligibility); - browser?.runtime?.onInstalled.addListener(markEthenaLaunchPromoEligibility); }; export const initSidebarBehavior = async () => { diff --git a/extension/src/background/messageListener/__tests__/claimEthenaLaunchPromo.test.ts b/extension/src/background/messageListener/__tests__/claimEthenaLaunchPromo.test.ts index a45ba1c374..864fa25607 100644 --- a/extension/src/background/messageListener/__tests__/claimEthenaLaunchPromo.test.ts +++ b/extension/src/background/messageListener/__tests__/claimEthenaLaunchPromo.test.ts @@ -1,27 +1,14 @@ import { mockDataStorage } from "background/messageListener/helpers/test-helpers"; -import { ETHENA_LAUNCH_PROMO_STATUS_ID } from "constants/localStorageTypes"; -import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; +import { HAS_SEEN_ETHENA_LAUNCH_PROMO } from "constants/localStorageTypes"; import { claimEthenaLaunchPromo } from "../handlers/claimEthenaLaunchPromo"; describe("claimEthenaLaunchPromo", () => { beforeEach(async () => { - await mockDataStorage.remove(ETHENA_LAUNCH_PROMO_STATUS_ID); + await mockDataStorage.remove(HAS_SEEN_ETHENA_LAUNCH_PROMO); }); - it("says no when nothing has been recorded (fresh install)", async () => { - const result = await claimEthenaLaunchPromo({ - localStore: mockDataStorage, - }); - expect(result).toEqual({ shouldShowEthenaLaunchPromo: false }); - }); - - it("says yes once for a pending wallet and marks it seen", async () => { - await mockDataStorage.setItem( - ETHENA_LAUNCH_PROMO_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS.PENDING, - ); - + it("says yes once to any wallet that hasn't seen it, then remembers", async () => { const first = await claimEthenaLaunchPromo({ localStore: mockDataStorage, }); @@ -31,17 +18,22 @@ describe("claimEthenaLaunchPromo", () => { expect(first).toEqual({ shouldShowEthenaLaunchPromo: true }); expect(second).toEqual({ shouldShowEthenaLaunchPromo: false }); - expect( - await mockDataStorage.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID), - ).toEqual(ETHENA_LAUNCH_PROMO_STATUS.SEEN); + expect(await mockDataStorage.getItem(HAS_SEEN_ETHENA_LAUNCH_PROMO)).toBe( + true, + ); }); - it("lets only one of several concurrent surfaces show it", async () => { - await mockDataStorage.setItem( - ETHENA_LAUNCH_PROMO_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS.PENDING, - ); + it("says no once it's been seen", async () => { + await mockDataStorage.setItem(HAS_SEEN_ETHENA_LAUNCH_PROMO, true); + + const result = await claimEthenaLaunchPromo({ + localStore: mockDataStorage, + }); + expect(result).toEqual({ shouldShowEthenaLaunchPromo: false }); + }); + + it("lets only one of several concurrent surfaces show it", async () => { const results = await Promise.all([ claimEthenaLaunchPromo({ localStore: mockDataStorage }), claimEthenaLaunchPromo({ localStore: mockDataStorage }), diff --git a/extension/src/background/messageListener/__tests__/createAccount.test.ts b/extension/src/background/messageListener/__tests__/createAccount.test.ts index 12c3a62ecd..042e730d20 100644 --- a/extension/src/background/messageListener/__tests__/createAccount.test.ts +++ b/extension/src/background/messageListener/__tests__/createAccount.test.ts @@ -14,10 +14,10 @@ import { KEY_ID_LIST, APPLICATION_ID, TEMPORARY_STORE_ID, - ETHENA_LAUNCH_PROMO_STATUS_ID, + HAS_SEEN_ETHENA_LAUNCH_PROMO, } from "constants/localStorageTypes"; -import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import { createAccount } from "background/messageListener/handlers/createAccount"; +import { claimEthenaLaunchPromo } from "background/messageListener/handlers/claimEthenaLaunchPromo"; import { APPLICATION_STATE } from "@shared/constants/applicationState"; jest.mock("stellar-hd-wallet", () => { @@ -66,12 +66,10 @@ describe("Create account message listener", () => { expect(applicationState).toBe(APPLICATION_STATE.PASSWORD_CREATED); expect(tempStoreId[keyId]).toBeDefined(); }); - it("doesn't owe a new wallet the Ethena launch promo", async () => { - // Pending from a wallet that existed before the reset/onboarding. - await mockDataStorage.setItem( - ETHENA_LAUNCH_PROMO_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS.PENDING, - ); + // Every wallet sees the launch promo once, a new one too: on its first + // unlock to Home. + it("leaves a new wallet owed the Ethena launch promo", async () => { + await mockDataStorage.remove(HAS_SEEN_ETHENA_LAUNCH_PROMO); await popupMessageListener( { @@ -86,9 +84,9 @@ describe("Create account message listener", () => { { id: "fake-extension-id" }, ); - expect(await mockDataStorage.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID)).toBe( - ETHENA_LAUNCH_PROMO_STATUS.SEEN, - ); + expect( + await claimEthenaLaunchPromo({ localStore: mockDataStorage }), + ).toEqual({ shouldShowEthenaLaunchPromo: true }); }); it("can overwrite account", async () => { const response = (await popupMessageListener( diff --git a/extension/src/background/messageListener/__tests__/recoverAccount.test.ts b/extension/src/background/messageListener/__tests__/recoverAccount.test.ts index 57bc391a12..e86ec83961 100644 --- a/extension/src/background/messageListener/__tests__/recoverAccount.test.ts +++ b/extension/src/background/messageListener/__tests__/recoverAccount.test.ts @@ -9,8 +9,8 @@ import { mockStorageApi, MockBrowserAlarm, } from "background/messageListener/helpers/test-helpers"; -import { ETHENA_LAUNCH_PROMO_STATUS_ID } from "constants/localStorageTypes"; -import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; +import { HAS_SEEN_ETHENA_LAUNCH_PROMO } from "constants/localStorageTypes"; +import { claimEthenaLaunchPromo } from "background/messageListener/handlers/claimEthenaLaunchPromo"; // Distinct keys per derivation index, so the recovery preload loop stores a // separate account for each one rather than collapsing into a single entry. @@ -74,18 +74,15 @@ describe("Recover account message listener", () => { ); }); - // Recovery is onboarding (also the "forgot password" path), so it isn't - // followed by the one-time launch promo either. - it("doesn't owe a recovered wallet the Ethena launch promo", async () => { - await mockDataStorage.setItem( - ETHENA_LAUNCH_PROMO_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS.PENDING, - ); + // Every wallet sees the launch promo once, an imported one too: on its + // first unlock to Home. + it("leaves a recovered wallet owed the Ethena launch promo", async () => { + await mockDataStorage.remove(HAS_SEEN_ETHENA_LAUNCH_PROMO); await recover(); - expect(await mockDataStorage.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID)).toBe( - ETHENA_LAUNCH_PROMO_STATUS.SEEN, - ); + expect( + await claimEthenaLaunchPromo({ localStore: mockDataStorage }), + ).toEqual({ shouldShowEthenaLaunchPromo: true }); }); }); diff --git a/extension/src/background/messageListener/__tests__/resetWallet.test.ts b/extension/src/background/messageListener/__tests__/resetWallet.test.ts index f9d3cbc7d9..6a6ba1eba5 100644 --- a/extension/src/background/messageListener/__tests__/resetWallet.test.ts +++ b/extension/src/background/messageListener/__tests__/resetWallet.test.ts @@ -24,9 +24,9 @@ import { COLLECTIBLES_ID, DATA_SHARING_ID, ETHENA_LAUNCH_BANNER_DISMISSED, - ETHENA_LAUNCH_PROMO_STATUS_ID, HAS_ACCOUNT_SUBSCRIPTION, HAS_SEEN_DISCOVER_WELCOME, + HAS_SEEN_ETHENA_LAUNCH_PROMO, HIDDEN_ASSETS, HIDDEN_ASSET_LIST, HIDDEN_COLLECTIBLES, @@ -121,9 +121,9 @@ const OLD_WALLET_DATA: Record = { [`${CACHED_MEMO_REQUIRED_ACCOUNTS_ID}_date`]: 1, [ETHENA_LAUNCH_BANNER_DISMISSED]: true, [HAS_SEEN_DISCOVER_WELCOME]: true, + [HAS_SEEN_ETHENA_LAUNCH_PROMO]: true, [IS_BLOCKAID_ANNOUNCED_ID]: true, [REBRAND_ANNOUNCEMENT_STATUS_ID]: "pending", - [ETHENA_LAUNCH_PROMO_STATUS_ID]: "pending", isTestnet: true, }; @@ -293,11 +293,10 @@ describe("RESET_WALLET", () => { CACHED_SWAP_TOP_TOKENS_ID, COLLECTIBLES_ID, ETHENA_LAUNCH_BANNER_DISMISSED, - // Whether this wallet is still owed the launch promo. Like the rebrand - // status below, create and import mark it seen for the next wallet. - ETHENA_LAUNCH_PROMO_STATUS_ID, HAS_ACCOUNT_SUBSCRIPTION, HAS_SEEN_DISCOVER_WELCOME, + // Every wallet sees the launch promo once, so the next wallet does too. + HAS_SEEN_ETHENA_LAUNCH_PROMO, HIDDEN_ASSETS, HIDDEN_ASSET_LIST, HIDDEN_COLLECTIBLES, diff --git a/extension/src/background/messageListener/handlers/claimEthenaLaunchPromo.ts b/extension/src/background/messageListener/handlers/claimEthenaLaunchPromo.ts index df6c45d7d2..ee8dc5f17f 100644 --- a/extension/src/background/messageListener/handlers/claimEthenaLaunchPromo.ts +++ b/extension/src/background/messageListener/handlers/claimEthenaLaunchPromo.ts @@ -1,27 +1,23 @@ import { DataStorageAccess } from "background/helpers/dataStorageAccess"; -import { ETHENA_LAUNCH_PROMO_STATUS_ID } from "constants/localStorageTypes"; -import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; +import { HAS_SEEN_ETHENA_LAUNCH_PROMO } from "constants/localStorageTypes"; // Every surface unlocked by the same broadcast asks at once. Serialising the // read-and-write means only the first one is told to show the promo. let claimQueue: Promise = Promise.resolve(); +// Every wallet sees the one-time launch promo once, whether it's an existing +// install or a new one: the first claim gets it, and marks it seen. export const claimEthenaLaunchPromo = ({ localStore, }: { localStore: DataStorageAccess; }): Promise<{ shouldShowEthenaLaunchPromo: boolean }> => { const claim = claimQueue.then(async () => { - const status = await localStore.getItem(ETHENA_LAUNCH_PROMO_STATUS_ID); - - if (status !== ETHENA_LAUNCH_PROMO_STATUS.PENDING) { + if (await localStore.getItem(HAS_SEEN_ETHENA_LAUNCH_PROMO)) { return { shouldShowEthenaLaunchPromo: false }; } - await localStore.setItem( - ETHENA_LAUNCH_PROMO_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS.SEEN, - ); + await localStore.setItem(HAS_SEEN_ETHENA_LAUNCH_PROMO, true); return { shouldShowEthenaLaunchPromo: true }; }); diff --git a/extension/src/background/messageListener/handlers/createAccount.ts b/extension/src/background/messageListener/handlers/createAccount.ts index 18c964a5e1..ad56571fea 100644 --- a/extension/src/background/messageListener/handlers/createAccount.ts +++ b/extension/src/background/messageListener/handlers/createAccount.ts @@ -9,11 +9,9 @@ import { DataStorageAccess } from "background/helpers/dataStorageAccess"; import { APPLICATION_ID, REBRAND_ANNOUNCEMENT_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS_ID, KEY_DERIVATION_NUMBER_ID, } from "constants/localStorageTypes"; import { REBRAND_ANNOUNCEMENT_STATUS } from "constants/rebrandAnnouncement"; -import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import { clearSession, SessionTimer } from "background/helpers/session"; import { storeAccount } from "../helpers/store-account"; import { APPLICATION_STATE } from "@shared/constants/applicationState"; @@ -79,15 +77,11 @@ export const createAccount = async ({ await localStore.setItem(APPLICATION_ID, APPLICATION_STATE.PASSWORD_CREATED); // A new wallet goes through onboarding, which must not be followed by the - // one-time rebrand announcement or launch promo. + // one-time rebrand announcement. await localStore.setItem( REBRAND_ANNOUNCEMENT_STATUS_ID, REBRAND_ANNOUNCEMENT_STATUS.SEEN, ); - await localStore.setItem( - ETHENA_LAUNCH_PROMO_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS.SEEN, - ); const currentState = sessionStore.getState(); diff --git a/extension/src/background/messageListener/handlers/recoverAccount.ts b/extension/src/background/messageListener/handlers/recoverAccount.ts index db9321a589..55843f2516 100644 --- a/extension/src/background/messageListener/handlers/recoverAccount.ts +++ b/extension/src/background/messageListener/handlers/recoverAccount.ts @@ -15,12 +15,10 @@ import { ACCOUNT_NAME_LIST_ID, APPLICATION_ID, REBRAND_ANNOUNCEMENT_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS_ID, KEY_DERIVATION_NUMBER_ID, KEY_ID_LIST, } from "constants/localStorageTypes"; import { REBRAND_ANNOUNCEMENT_STATUS } from "constants/rebrandAnnouncement"; -import { ETHENA_LAUNCH_PROMO_STATUS } from "constants/ethenaLaunchPromo"; import { clearSession, SessionTimer } from "background/helpers/session"; import { storeAccount } from "../helpers/store-account"; import { KeyManager } from "@stellar/typescript-wallet-sdk-km"; @@ -86,15 +84,11 @@ export const recoverAccount = async ({ await localStore.setItem(KEY_DERIVATION_NUMBER_ID, "0"); // Recovery is onboarding (also the "forgot password" path), which must - // not be followed by the one-time rebrand announcement or launch promo. + // not be followed by the one-time rebrand announcement. await localStore.setItem( REBRAND_ANNOUNCEMENT_STATUS_ID, REBRAND_ANNOUNCEMENT_STATUS.SEEN, ); - await localStore.setItem( - ETHENA_LAUNCH_PROMO_STATUS_ID, - ETHENA_LAUNCH_PROMO_STATUS.SEEN, - ); await clearSession({ localStore, sessionStore }); diff --git a/extension/src/constants/ethenaLaunchPromo.ts b/extension/src/constants/ethenaLaunchPromo.ts deleted file mode 100644 index a1575cc8ba..0000000000 --- a/extension/src/constants/ethenaLaunchPromo.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * One-time full-screen "Meet Ethena on Stellar" promo, shown to wallets that - * existed when the launch build was installed: `PENDING` until shown, `SEEN` - * once shown or never owed. Fresh installs are marked `SEEN` on first run. - */ -export enum ETHENA_LAUNCH_PROMO_STATUS { - PENDING = "pending", - SEEN = "seen", -} diff --git a/extension/src/constants/localStorageTypes.ts b/extension/src/constants/localStorageTypes.ts index feada41eb8..69f4ca5d21 100644 --- a/extension/src/constants/localStorageTypes.ts +++ b/extension/src/constants/localStorageTypes.ts @@ -40,5 +40,5 @@ export const METRICS_USER_ID = "metrics_user_id"; export const RECENT_PROTOCOLS = "recentProtocols"; export const HAS_SEEN_DISCOVER_WELCOME = "hasSeenDiscoverWelcome"; export const REBRAND_ANNOUNCEMENT_STATUS_ID = "rebrandAnnouncementStatus"; -export const ETHENA_LAUNCH_PROMO_STATUS_ID = "ethenaLaunchPromoStatus"; +export const HAS_SEEN_ETHENA_LAUNCH_PROMO = "hasSeenEthenaLaunchPromo"; export const AUTO_LOCK_TIMEOUT_MINUTES_ID = "autoLockTimeoutMinutes"; diff --git a/extension/src/popup/basics/layout/View/styles.scss b/extension/src/popup/basics/layout/View/styles.scss index 9d1ba57e10..4d5bc41dd5 100644 --- a/extension/src/popup/basics/layout/View/styles.scss +++ b/extension/src/popup/basics/layout/View/styles.scss @@ -30,16 +30,11 @@ flex-shrink: 0; flex-grow: 0; - // Figma's Top (3705-77862; mobile's HeaderFade): the page color runs solid - // to 80.714% of the header and is clear by 93.214%, so content scrolling up - // under it fades out. + // Figma's Top (3705-77862; mobile's HeaderFade): content scrolling up + // under the header fades out. @mixin header-fade { z-index: var(--z-index--app-header); - background: linear-gradient( - to bottom, - var(--sds-clr-base-00) 80.714%, - transparent 93.214% - ); + @include header-fade-background; } // Home's top row stays pinned while the balance, the tiles and the lists diff --git a/extension/src/popup/styles/utils.scss b/extension/src/popup/styles/utils.scss index c8ee99e1d1..7cf3031602 100644 --- a/extension/src/popup/styles/utils.scss +++ b/extension/src/popup/styles/utils.scss @@ -28,3 +28,14 @@ $base-font-size: 16px; outline-style: auto; outline-width: 1px; } + +// Figma's Top (3705-77862; mobile's HeaderFade), for a header that stays +// pinned over scrolling content: the page color runs solid to 80.714% of the +// header and is clear by 93.214%, so content scrolling up under it fades out. +@mixin header-fade-background { + background: linear-gradient( + to bottom, + var(--sds-clr-base-00) 80.714%, + transparent 93.214% + ); +} diff --git a/extension/src/popup/views/EthenaLaunch/index.tsx b/extension/src/popup/views/EthenaLaunch/index.tsx index 085848580d..956c856b83 100644 --- a/extension/src/popup/views/EthenaLaunch/index.tsx +++ b/extension/src/popup/views/EthenaLaunch/index.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import { Button, Heading, Icon } from "@stellar/design-system"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; @@ -15,15 +15,25 @@ import LogoSusde from "popup/assets/logo-susde.svg"; import "./styles.scss"; -// Sushi's Stellar swap page reads no URL parameters (its pair is set in -// code), so this can only land on it; the user picks USDe or sUSDe there. -const SUSHI_STELLAR_SWAP_URL = "https://www.sushi.com/stellar/swap"; -// Stargate, from Ethereum to Stellar with the token preselected on both -// sides. Addresses are the ones LayerZero's transfer token list publishes. -const STARGATE_USDE_URL = - "https://stargate.finance/?srcChain=ethereum&srcToken=0x4c9EDD5852cd905f086C759E8383e09bff1E68B3&dstChain=stellar&dstToken=CCNOV6XVI2O5BSTA3232GIRUQULDEBV7IWGKM6QKI6II5OIIQTU24JJN"; -const STARGATE_SUSDE_URL = - "https://stargate.finance/?srcChain=ethereum&srcToken=0x9D39A5DE30e57443BfF2A8307A4256c8797A3497&dstChain=stellar&dstToken=CACSKWC753QVGC4J6YPDBIR2BEHFVWIAE7CBSS3HOVYMN623OAIQYE2M"; +// Mainnet token contracts on Stellar: XLM's Stellar Asset Contract, and USDe's +// and sUSDe's, which LayerZero's transfer token list also publishes. +const XLM_CONTRACT_ID = + "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA"; +const USDE_CONTRACT_ID = + "CCNOV6XVI2O5BSTA3232GIRUQULDEBV7IWGKM6QKI6II5OIIQTU24JJN"; +const SUSDE_CONTRACT_ID = + "CACSKWC753QVGC4J6YPDBIR2BEHFVWIAE7CBSS3HOVYMN623OAIQYE2M"; +// The same tokens on Ethereum, from the same list. +const USDE_ETHEREUM_ADDRESS = "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3"; +const SUSDE_ETHEREUM_ADDRESS = "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497"; + +// Sushi's Stellar swap, from XLM to the token. Sushi is adding these +// parameters; until they ship, the page opens on its default pair. +const sushiSwapUrl = (contractId: string) => + `https://www.sushi.com/stellar/swap?token0=${XLM_CONTRACT_ID}&token1=${contractId}`; +// Stargate, from Ethereum to Stellar with the token preselected on both sides. +const stargateUrl = (ethereumAddress: string, contractId: string) => + `https://stargate.finance/?srcChain=ethereum&srcToken=${ethereumAddress}&dstChain=stellar&dstToken=${contractId}`; const ETHENA_DOCS_URL = "https://docs.ethena.fi/"; interface EthenaTokenSectionProps { @@ -32,6 +42,7 @@ interface EthenaTokenSectionProps { logo: string; name: string; description: string; + swapUrl: string; transferUrl: string; onReceive: () => void; } @@ -42,13 +53,14 @@ const EthenaTokenSection = ({ logo, name, description, + swapUrl, transferUrl, onReceive, }: EthenaTokenSectionProps) => { const { t } = useTranslation(); const handleSwap = () => { - openTab(SUSHI_STELLAR_SWAP_URL); + openTab(swapUrl); }; const handleTransfer = () => { @@ -107,7 +119,7 @@ const EthenaTokenSection = ({ /** * Full-screen "Meet Ethena on Stellar" launch promo. UnlockAccount routes here - * once per eligible wallet (the background marks it seen as it hands it out), + * once per wallet (the background marks it seen as it hands it out), * and the Home banner opens it on demand. Closing returns to the destination * in location state, or Home. */ @@ -121,6 +133,13 @@ export const EthenaLaunch = () => { ROUTES.account, ) as string; + // The close button's bar fills in once the page scrolls (see styles). + const [isScrolled, setIsScrolled] = useState(false); + + const handleScroll = (event: React.UIEvent) => { + setIsScrolled(event.currentTarget.scrollTop > 0); + }; + const handleClose = () => { navigate(destination, { replace: true }); }; @@ -136,8 +155,15 @@ export const EthenaLaunch = () => { return ( // Pinned dark: the hero art is drawn for a black page and there is no // light design. -
-
+
+
+
diff --git a/extension/src/popup/views/EthenaLaunch/styles.scss b/extension/src/popup/views/EthenaLaunch/styles.scss index 71f37330c8..f0e852290d 100644 --- a/extension/src/popup/views/EthenaLaunch/styles.scss +++ b/extension/src/popup/views/EthenaLaunch/styles.scss @@ -190,6 +190,7 @@ $header-fade-in: 200ms; text-wrap: balance; } + // A button: it scrolls the tokens into view (see handleScrollToTokens). &__scroll-hint { // Pushed to the bottom of the first screen however tall the window is. margin-top: auto; @@ -197,6 +198,11 @@ $header-fade-in: 200ms; flex-direction: column; align-items: center; gap: pxToRem(4px); + padding: 0; + background: none; + border: none; + cursor: pointer; + font-family: inherit; font-size: pxToRem(12px); line-height: pxToRem(18px); font-weight: var(--sds-fw-medium); @@ -205,6 +211,10 @@ $header-fade-in: 200ms; animation: EthenaLaunch-fade-in $fade-duration $fade-easing $scroll-hint-delay both; + &:hover { + color: var(--sds-clr-gray-12); + } + svg { width: pxToRem(18px); height: pxToRem(18px); @@ -271,15 +281,16 @@ $header-fade-in: 200ms; } // Borderless text button per design. No SDS Button variant is transparent, - // so it's hand-rolled at Figma's metrics (32px tall, 14/20 text). + // so it's hand-rolled at the metrics of SDS's lg Button, which Swap and + // Receive above it are: 40px tall, 14/22 text and a 14px icon. &__transfer { display: flex; align-items: center; justify-content: center; gap: pxToRem(4px); width: 100%; - height: pxToRem(32px); - padding: pxToRem(6px) pxToRem(12px); + height: pxToRem(40px); + padding: pxToRem(8px) pxToRem(12px); background: none; border: none; border-radius: pxToRem(100px); @@ -288,7 +299,7 @@ $header-fade-in: 200ms; font-family: inherit; font-size: pxToRem(14px); font-weight: var(--sds-fw-semi-bold); - line-height: pxToRem(20px); + line-height: pxToRem(22px); &:hover { // Opaque fallback first: manifest v2 still allows Firefox < 113, no @@ -297,10 +308,10 @@ $header-fade-in: 200ms; background: color-mix(in srgb, var(--sds-clr-gray-12) 10%, transparent); } + // Sized like the icon in an SDS Button, so its stroke matches Swap's. svg { - width: pxToRem(16px); - height: pxToRem(16px); - @include icon-stroke(16); + width: pxToRem(14px); + height: pxToRem(14px); } } diff --git a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx index 3408878c5b..58a1e2ed8d 100644 --- a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx +++ b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx @@ -111,6 +111,67 @@ describe("EthenaLaunch", () => { expect(header).not.toHaveClass("EthenaLaunch__header--scrolled"); }); + describe("scroll cue", () => { + // jsdom has no layout: the cue 544px down a page scrolled 20px, under + // the 80px bar. + const layOut = () => { + const page = screen.getByTestId("ethena-launch"); + const cue = screen.getByRole("button", { + name: "Scroll to discover tokens", + }); + const scrollTo = jest.fn(); + page.scrollTo = scrollTo; + page.scrollTop = 20; + jest + .spyOn(page, "getBoundingClientRect") + .mockReturnValue({ top: 0 } as DOMRect); + jest + .spyOn(cue, "getBoundingClientRect") + .mockReturnValue({ top: 544 } as DOMRect); + Object.defineProperty( + screen.getByTestId("ethena-launch-header"), + "offsetHeight", + { configurable: true, value: 80 }, + ); + return { cue, scrollTo }; + }; + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it("scrolls the tokens up until the cue is 60px below the bar", async () => { + renderView(); + const { cue, scrollTo } = layOut(); + + await userEvent.click(cue); + + expect(scrollTo).toHaveBeenCalledWith({ + top: 20 + 544 - 80 - 60, + behavior: "smooth", + }); + }); + + it("jumps there instead under reduced motion", async () => { + jest.spyOn(window, "matchMedia").mockImplementation( + (query: string) => + ({ + matches: query === "(prefers-reduced-motion: reduce)", + media: query, + }) as MediaQueryList, + ); + renderView(); + const { cue, scrollTo } = layOut(); + + await userEvent.click(cue); + + expect(scrollTo).toHaveBeenCalledWith({ + top: 20 + 544 - 80 - 60, + behavior: "auto", + }); + }); + }); + it("swaps from XLM to each token on Sushi", async () => { renderView(); From 8256fec041b1399b46af04abe21a2a25688bf20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Fri, 13 Nov 2026 17:32:16 -0800 Subject: [PATCH 08/11] feat: bring the Ethena promo back from Receive as it was left 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 --- extension/e2e-tests/ethenaLaunch.test.ts | 25 +++++++++++ .../src/popup/views/EthenaLaunch/index.tsx | 40 +++++++++++++---- .../src/popup/views/EthenaLaunch/styles.scss | 11 +++++ .../views/__tests__/EthenaLaunch.test.tsx | 45 ++++++++++++++++--- 4 files changed, 107 insertions(+), 14 deletions(-) diff --git a/extension/e2e-tests/ethenaLaunch.test.ts b/extension/e2e-tests/ethenaLaunch.test.ts index 70f7c1fc08..b96163b171 100644 --- a/extension/e2e-tests/ethenaLaunch.test.ts +++ b/extension/e2e-tests/ethenaLaunch.test.ts @@ -111,6 +111,31 @@ test("Ethena launch promo's scroll cue scrolls the tokens into view", async ({ await expect(page.getByTestId("ethena-launch-swap-usde")).toBeInViewport(); }); +test("Ethena launch promo comes back from Receive as it was left", async ({ + page, + extensionId, + context, +}) => { + await loginToTestAccount({ page, extensionId, context }); + await page.getByTestId("ethena-launch-banner-open").click(); + const promo = page.getByTestId("ethena-launch"); + await expect(promo).toBeVisible(); + await promo.evaluate((el) => el.scrollTo(0, 400)); + const left = await promo.evaluate((el) => el.scrollTop); + expect(left).toBeGreaterThan(0); + + await page.getByTestId("ethena-launch-receive-usde").click(); + await expect(page.getByTestId("view-public-key-account-name")).toBeVisible(); + await page.getByTestId("BackButton").click(); + + // Where it was, with nothing replaying. + await expect(promo).toBeVisible(); + expect(await promo.evaluate((el) => el.scrollTop)).toBe(left); + expect( + await promo.evaluate((el) => el.getAnimations({ subtree: true }).length), + ).toBe(0); +}); + test("Ethena launch promo keeps its close button on a bar as the page scrolls", async ({ page, extensionId, diff --git a/extension/src/popup/views/EthenaLaunch/index.tsx b/extension/src/popup/views/EthenaLaunch/index.tsx index 81abc8f45f..7d241b7156 100644 --- a/extension/src/popup/views/EthenaLaunch/index.tsx +++ b/extension/src/popup/views/EthenaLaunch/index.tsx @@ -1,8 +1,7 @@ -import React, { useRef, useState } from "react"; +import React, { useLayoutEffect, useRef, useState } from "react"; import { Button, Heading, Icon } from "@stellar/design-system"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; -import get from "lodash/get"; import { ROUTES } from "popup/constants/routes"; import { navigateTo, openTab } from "popup/helpers/navigate"; @@ -122,6 +121,13 @@ const EthenaTokenSection = ({ ); }; +interface EthenaLaunchLocationState { + // Where closing goes: UnlockAccount's original destination, or Home. + destination?: string; + // How far the page was scrolled when it left for Receive. + scrollTop?: number; +} + /** * Full-screen "Meet Ethena on Stellar" launch promo. UnlockAccount routes here * once per eligible wallet (the background marks it seen as it hands it out), @@ -132,17 +138,24 @@ export const EthenaLaunch = () => { const { t } = useTranslation(); const navigate = useNavigate(); const location = useLocation(); - const destination = get( - location, - "state.destination", - ROUTES.account, - ) as string; + const locationState = (location.state ?? {}) as EthenaLaunchLocationState; + const destination = locationState.destination ?? ROUTES.account; + // Back from Receive's address screen: the page comes back as it was left, + // scrolled where it was and without replaying the intro. + const returnScrollTop = locationState.scrollTop; const pageRef = useRef(null); const headerRef = useRef(null); // The close button's bar fills in once the page scrolls (see styles). - const [isScrolled, setIsScrolled] = useState(false); + const [isScrolled, setIsScrolled] = useState(Boolean(returnScrollTop)); + + // Before the first paint, so the page never shows at the top first. + useLayoutEffect(() => { + if (returnScrollTop !== undefined && pageRef.current) { + pageRef.current.scrollTop = returnScrollTop; + } + }, [returnScrollTop]); const handleScroll = (event: React.UIEvent) => { setIsScrolled(event.currentTarget.scrollTop > 0); @@ -170,6 +183,15 @@ export const EthenaLaunch = () => { }; const handleReceive = () => { + // The address screen closes by going back, to this history entry, so + // note in it where the page is. + navigate(`${location.pathname}${location.search}`, { + replace: true, + state: { + ...locationState, + scrollTop: pageRef.current?.scrollTop ?? 0, + }, + }); navigateTo(ROUTES.viewPublicKey, navigate); }; @@ -182,7 +204,7 @@ export const EthenaLaunch = () => { // light design.
diff --git a/extension/src/popup/views/EthenaLaunch/styles.scss b/extension/src/popup/views/EthenaLaunch/styles.scss index f0e852290d..468771d670 100644 --- a/extension/src/popup/views/EthenaLaunch/styles.scss +++ b/extension/src/popup/views/EthenaLaunch/styles.scss @@ -342,6 +342,17 @@ $header-fade-in: 200ms; } } + // Back from Receive's address screen, as it was left: the intro doesn't + // replay. + &--returning { + .EthenaLaunch__wave, + .EthenaLaunch__coin, + .EthenaLaunch__intro, + .EthenaLaunch__scroll-hint { + animation: none; + } + } + @media (prefers-reduced-motion: reduce) { &__wave, &__coin, diff --git a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx index 58a1e2ed8d..03fa1eebb6 100644 --- a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx +++ b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx @@ -1,7 +1,7 @@ import React from "react"; import { fireEvent, render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; -import { Route, Routes } from "react-router-dom"; +import { Route, Routes, useNavigate } from "react-router-dom"; import { ROUTES } from "popup/constants/routes"; import { Wrapper } from "popup/__testHelpers__"; @@ -38,6 +38,16 @@ const STARGATE_USDE_URL = const STARGATE_SUSDE_URL = "https://stargate.finance/?srcChain=ethereum&srcToken=0x9D39A5DE30e57443BfF2A8307A4256c8797A3497&dstChain=stellar&dstToken=CACSKWC753QVGC4J6YPDBIR2BEHFVWIAE7CBSS3HOVYMN623OAIQYE2M"; +// The address screen, closed the way the real one is: back in history. +const ViewPublicKeyStub = () => { + const navigate = useNavigate(); + return ( + + ); +}; + const renderView = (destination?: string) => render( } /> account-home
} /> settings-home
} /> - view-public-key
} - /> + } /> , ); @@ -220,6 +227,34 @@ describe("EthenaLaunch", () => { expect(await screen.findByText("view-public-key")).toBeInTheDocument(); }); + it("comes back from Receive as it was left: same scroll, no intro", async () => { + renderView(); + const page = screen.getByTestId("ethena-launch"); + expect(page).not.toHaveClass("EthenaLaunch--returning"); + page.scrollTop = 420; + fireEvent.scroll(page); + + await userEvent.click(screen.getByTestId("ethena-launch-receive-usde")); + await userEvent.click(await screen.findByText("view-public-key")); + + const returned = await screen.findByTestId("ethena-launch"); + expect(returned).toHaveClass("EthenaLaunch--returning"); + expect(returned.scrollTop).toBe(420); + expect(screen.getByTestId("ethena-launch-header")).toHaveClass( + "EthenaLaunch__header--scrolled", + ); + }); + + it("still closes to its destination after a trip to Receive", async () => { + renderView(ROUTES.settings); + + await userEvent.click(screen.getByTestId("ethena-launch-receive-usde")); + await userEvent.click(await screen.findByText("view-public-key")); + await userEvent.click(await screen.findByTestId("ethena-launch-close")); + + expect(await screen.findByText("settings-home")).toBeInTheDocument(); + }); + it("links out to Ethena's docs", async () => { renderView(); From 87ec59e9b74584279e9a09adaeee0e04ace8526d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Fri, 13 Nov 2026 17:43:20 -0800 Subject: [PATCH 09/11] fix: keep the Ethena promo in Home's frame in fullscreen mode 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 --- extension/e2e-tests/ethenaLaunch.test.ts | 37 ++++ extension/e2e-tests/theme.test.ts | 6 - .../src/popup/views/EthenaLaunch/index.tsx | 194 +++++++++--------- .../src/popup/views/EthenaLaunch/styles.scss | 22 +- 4 files changed, 152 insertions(+), 107 deletions(-) diff --git a/extension/e2e-tests/ethenaLaunch.test.ts b/extension/e2e-tests/ethenaLaunch.test.ts index b96163b171..27c3c0f8e3 100644 --- a/extension/e2e-tests/ethenaLaunch.test.ts +++ b/extension/e2e-tests/ethenaLaunch.test.ts @@ -57,6 +57,43 @@ test("a wallet that predates the launch sees the Ethena launch promo once, on it await expect(page.getByTestId("ethena-launch")).toHaveCount(0); }); +test("Ethena launch promo sits in Home's frame in a wide window, filling it", async ({ + page, + extensionId, + context, +}) => { + // The fixture's window is wide, like fullscreen mode's tab. + await loginToTestAccount({ page, extensionId, context }); + const frameOf = (selector: string) => + page.locator(selector).evaluate((el) => { + const { x, width, height } = el.getBoundingClientRect(); + const style = getComputedStyle(el); + return { + x, + width, + height, + borders: `${style.borderLeft} | ${style.borderRight}`, + }; + }); + const home = await frameOf(".AccountHeader__hero"); + expect(home.width).toBeLessThan(page.viewportSize()!.width); + + await page.getByTestId("ethena-launch-banner-open").click(); + await expect(page.getByTestId("ethena-launch")).toBeVisible(); + const promo = await frameOf('[data-testid="ethena-launch-frame"]'); + + // Same place, width and borders as Home's, all the way down. + expect({ ...promo, height: undefined }).toEqual({ + ...home, + height: undefined, + }); + expect(promo.height).toBe(page.viewportSize()!.height); + // The content stretches across it: Swap spans the frame less its borders + // and 24px gutters, as other fullscreen screens' buttons do. + const swap = await page.getByTestId("ethena-launch-swap-usde").boundingBox(); + expect(swap!.width).toBe(promo.width - 2 - 2 * 24); +}); + test("Ethena launch promo's token actions are all the same size", async ({ page, extensionId, diff --git a/extension/e2e-tests/theme.test.ts b/extension/e2e-tests/theme.test.ts index 0f0d92d23b..5e45381dc7 100644 --- a/extension/e2e-tests/theme.test.ts +++ b/extension/e2e-tests/theme.test.ts @@ -214,12 +214,6 @@ test("Ethena launch promo looks the same in both themes", async ({ expect(await computed(page.getByTestId("ethena-launch-close"), "color")).toBe( darkGray12, ); - // It fills the window, so none of the themed page shows around it. - expect(await promo.boundingBox()).toEqual({ - x: 0, - y: 0, - ...page.viewportSize(), - }); const light = await renderedStyles(promo); await page.emulateMedia({ colorScheme: "dark" }); diff --git a/extension/src/popup/views/EthenaLaunch/index.tsx b/extension/src/popup/views/EthenaLaunch/index.tsx index 7d241b7156..3e2550e654 100644 --- a/extension/src/popup/views/EthenaLaunch/index.tsx +++ b/extension/src/popup/views/EthenaLaunch/index.tsx @@ -3,6 +3,7 @@ import { Button, Heading, Icon } from "@stellar/design-system"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; +import { View } from "popup/basics/layout/View"; import { ROUTES } from "popup/constants/routes"; import { navigateTo, openTab } from "popup/helpers/navigate"; @@ -200,105 +201,114 @@ export const EthenaLaunch = () => { }; return ( - // Pinned dark: the hero art is drawn for a black page and there is no - // light design. -
+ {/* Pinned dark: the hero art is drawn for a black page and there is no + light design. */}
- -
- -
- -
+ +
+ - -
-
- - {t("Meet Ethena on Stellar")} - -
- {t("Discover USDe and sUSDe, now available on Stellar.")} -
-
- - - -
- - - -
-
+ {t("Learn more about Ethena")} + + + + + ); }; diff --git a/extension/src/popup/views/EthenaLaunch/styles.scss b/extension/src/popup/views/EthenaLaunch/styles.scss index 468771d670..a7b08a055c 100644 --- a/extension/src/popup/views/EthenaLaunch/styles.scss +++ b/extension/src/popup/views/EthenaLaunch/styles.scss @@ -10,9 +10,6 @@ $scroll-hint-delay: 400ms; $slide-easing: cubic-bezier(0.22, 1, 0.36, 1); $fade-easing: cubic-bezier(0.4, 0, 0.2, 1); -// The design is a 360px column; wider windows centre it on the black page. -$column-width: 360px; - // The close button's bar is Home's pinned header: as tall, with the same fade. $header-height: 80px; $header-fade-in: 200ms; @@ -34,6 +31,17 @@ $header-fade-in: 200ms; display: none; } + // Home's frame (a View inset): the whole window in the popup and sidebar, + // a centred column with vertical borders in fullscreen mode. The promo + // fills it, top to bottom. + &__frame { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + width: 100%; + } + // Sticky, so the X stays put while the page scrolls under it, and pulled // back over the hero by its own height, so it pushes nothing down. &__header { @@ -87,10 +95,8 @@ $header-fade-in: 200ms; // its bottom edge and the tokens starting below the fold. &__hero { position: relative; - width: pxToRem($column-width); - max-width: 100%; + width: 100%; min-height: 100%; - margin: 0 auto; padding: pxToRem(130px) 0 pxToRem(16px); display: flex; flex-direction: column; @@ -224,9 +230,7 @@ $header-fade-in: 200ms; } &__tokens { - width: pxToRem($column-width); - max-width: 100%; - margin: 0 auto; + width: 100%; padding-bottom: pxToRem(24px); display: flex; flex-direction: column; From fcf5cbbe3c0fc38298477ce25f175f664c70cfb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Fri, 13 Nov 2026 17:44:11 -0800 Subject: [PATCH 10/11] feat: Esc closes the Ethena promo and the address screen, not the popup 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 --- extension/e2e-tests/ethenaLaunch.test.ts | 20 ++++++++ .../hooks/__tests__/useEscapeToClose.test.ts | 49 +++++++++++++++++++ .../popup/helpers/hooks/useEscapeToClose.ts | 28 +++++++++++ .../src/popup/views/EthenaLaunch/index.tsx | 4 ++ .../src/popup/views/ViewPublicKey/index.tsx | 7 ++- .../views/__tests__/EthenaLaunch.test.tsx | 10 ++++ 6 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 extension/src/popup/helpers/hooks/__tests__/useEscapeToClose.test.ts create mode 100644 extension/src/popup/helpers/hooks/useEscapeToClose.ts diff --git a/extension/e2e-tests/ethenaLaunch.test.ts b/extension/e2e-tests/ethenaLaunch.test.ts index 27c3c0f8e3..58cba00c85 100644 --- a/extension/e2e-tests/ethenaLaunch.test.ts +++ b/extension/e2e-tests/ethenaLaunch.test.ts @@ -173,6 +173,26 @@ test("Ethena launch promo comes back from Receive as it was left", async ({ ).toBe(0); }); +test("Esc closes the address screen, then the Ethena launch promo", async ({ + page, + extensionId, + context, +}) => { + await loginToTestAccount({ page, extensionId, context }); + await page.getByTestId("ethena-launch-banner-open").click(); + await expect(page.getByTestId("ethena-launch")).toBeVisible(); + + // The address screen: Esc goes back to the promo, like its X. + await page.getByTestId("ethena-launch-receive-usde").click(); + await expect(page.getByTestId("view-public-key-account-name")).toBeVisible(); + await page.keyboard.press("Escape"); + await expect(page.getByTestId("ethena-launch")).toBeVisible(); + + // The promo: Esc goes Home, like its X. + await page.keyboard.press("Escape"); + await expect(page.getByTestId("account-view")).toBeVisible(); +}); + test("Ethena launch promo keeps its close button on a bar as the page scrolls", async ({ page, extensionId, diff --git a/extension/src/popup/helpers/hooks/__tests__/useEscapeToClose.test.ts b/extension/src/popup/helpers/hooks/__tests__/useEscapeToClose.test.ts new file mode 100644 index 0000000000..be6a3d029d --- /dev/null +++ b/extension/src/popup/helpers/hooks/__tests__/useEscapeToClose.test.ts @@ -0,0 +1,49 @@ +import { fireEvent, renderHook } from "@testing-library/react"; + +import { useEscapeToClose } from "../useEscapeToClose"; + +// fireEvent returns false when a listener called preventDefault(). +const pressEscape = () => fireEvent.keyDown(document, { key: "Escape" }); + +describe("useEscapeToClose", () => { + it("closes the screen on Esc, and marks the key handled so the popup stays open", () => { + const onClose = jest.fn(); + renderHook(() => useEscapeToClose(onClose)); + + expect(pressEscape()).toBe(false); + expect(onClose).toHaveBeenCalledTimes(1); + }); + + it("ignores other keys", () => { + const onClose = jest.fn(); + renderHook(() => useEscapeToClose(onClose)); + + expect(fireEvent.keyDown(document, { key: "Enter" })).toBe(true); + expect(onClose).not.toHaveBeenCalled(); + }); + + it("leaves an Esc that something else already handled", () => { + const onClose = jest.fn(); + renderHook(() => useEscapeToClose(onClose)); + const handled = new KeyboardEvent("keydown", { + key: "Escape", + bubbles: true, + cancelable: true, + }); + handled.preventDefault(); + + document.dispatchEvent(handled); + + expect(onClose).not.toHaveBeenCalled(); + }); + + it("stops listening once the screen is gone", () => { + const onClose = jest.fn(); + const { unmount } = renderHook(() => useEscapeToClose(onClose)); + + unmount(); + pressEscape(); + + expect(onClose).not.toHaveBeenCalled(); + }); +}); diff --git a/extension/src/popup/helpers/hooks/useEscapeToClose.ts b/extension/src/popup/helpers/hooks/useEscapeToClose.ts new file mode 100644 index 0000000000..41da5926bc --- /dev/null +++ b/extension/src/popup/helpers/hooks/useEscapeToClose.ts @@ -0,0 +1,28 @@ +import { useEffect, useRef } from "react"; + +/** + * Esc closes the calling screen (runs `onClose`) instead of the whole popup. + * Chrome closes an extension popup on an Esc the page leaves unhandled, so + * this marks the key handled. An Esc something else already handled, like an + * open sheet, is left to it. + */ +export const useEscapeToClose = (onClose: () => void) => { + // The latest callback, without re-subscribing on every render. + const onCloseRef = useRef(onClose); + onCloseRef.current = onClose; + + useEffect(() => { + const onKeyDown = (event: KeyboardEvent) => { + if (event.key !== "Escape" || event.defaultPrevented) { + return; + } + event.preventDefault(); + onCloseRef.current(); + }; + + document.addEventListener("keydown", onKeyDown); + return () => { + document.removeEventListener("keydown", onKeyDown); + }; + }, []); +}; diff --git a/extension/src/popup/views/EthenaLaunch/index.tsx b/extension/src/popup/views/EthenaLaunch/index.tsx index 3e2550e654..ce6fa83ef1 100644 --- a/extension/src/popup/views/EthenaLaunch/index.tsx +++ b/extension/src/popup/views/EthenaLaunch/index.tsx @@ -6,6 +6,7 @@ import { useLocation, useNavigate } from "react-router-dom"; import { View } from "popup/basics/layout/View"; import { ROUTES } from "popup/constants/routes"; import { navigateTo, openTab } from "popup/helpers/navigate"; +import { useEscapeToClose } from "popup/helpers/hooks/useEscapeToClose"; import EthenaLaunchWave from "popup/assets/ethena-launch-wave.svg"; import EthenaCoinLight from "popup/assets/ethena-launch-coin-light.png"; @@ -183,6 +184,9 @@ export const EthenaLaunch = () => { navigate(destination, { replace: true }); }; + // Esc closes the promo like the X does, rather than the popup. + useEscapeToClose(handleClose); + const handleReceive = () => { // The address screen closes by going back, to this history entry, so // note in it where the page is. diff --git a/extension/src/popup/views/ViewPublicKey/index.tsx b/extension/src/popup/views/ViewPublicKey/index.tsx index 37524954b9..915cbad91d 100644 --- a/extension/src/popup/views/ViewPublicKey/index.tsx +++ b/extension/src/popup/views/ViewPublicKey/index.tsx @@ -3,12 +3,13 @@ import { useSelector } from "react-redux"; import { QRCodeSVG } from "qrcode.react"; import { Icon, Button, Notification } from "@stellar/design-system"; import { useTranslation } from "react-i18next"; -import { Navigate, useLocation } from "react-router-dom"; +import { Navigate, useLocation, useNavigate } from "react-router-dom"; import { emitMetric } from "helpers/metrics"; import { truncatedPublicKey } from "helpers/stellar"; import { METRIC_NAMES } from "popup/constants/metricsNames"; import { closeWindow, openTab } from "popup/helpers/navigate"; +import { useEscapeToClose } from "popup/helpers/hooks/useEscapeToClose"; import { View } from "popup/basics/layout/View"; import { showToast } from "popup/basics/shadcn/Toast"; import { accountNameSelector } from "popup/ducks/accountServices"; @@ -26,9 +27,13 @@ import "./styles.scss"; export const ViewPublicKey = () => { const { t } = useTranslation(); const location = useLocation(); + const navigate = useNavigate(); const accountName = useSelector(accountNameSelector); const { state, fetchData } = useGetAppData(); + // Esc goes back like the X does, rather than closing the popup. + useEscapeToClose(() => navigate(-1)); + useEffect(() => { const getData = async () => { await fetchData(); diff --git a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx index 03fa1eebb6..687fda8fca 100644 --- a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx +++ b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx @@ -271,6 +271,16 @@ describe("EthenaLaunch", () => { expect(await screen.findByText("settings-home")).toBeInTheDocument(); }); + it("closes to its destination on Esc, keeping the popup open", async () => { + renderView(ROUTES.settings); + + // fireEvent returns false when the key was marked handled, which is what + // stops Chrome closing the popup on Esc. + expect(fireEvent.keyDown(document, { key: "Escape" })).toBe(false); + + expect(await screen.findByText("settings-home")).toBeInTheDocument(); + }); + it("closes to the account view when no destination was given", async () => { renderView(); From cf078392c1b392e6cccb93a9bafa3180a7367968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Fri, 13 Nov 2026 17:56:19 -0800 Subject: [PATCH 11/11] fix: stop the scroll cue 20px below the close button's bar Co-Authored-By: Claude Opus 5.5 --- extension/e2e-tests/ethenaLaunch.test.ts | 4 ++-- extension/src/popup/views/EthenaLaunch/index.tsx | 2 +- extension/src/popup/views/__tests__/EthenaLaunch.test.tsx | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/extension/e2e-tests/ethenaLaunch.test.ts b/extension/e2e-tests/ethenaLaunch.test.ts index 58cba00c85..b080cb64cd 100644 --- a/extension/e2e-tests/ethenaLaunch.test.ts +++ b/extension/e2e-tests/ethenaLaunch.test.ts @@ -135,7 +135,7 @@ test("Ethena launch promo's scroll cue scrolls the tokens into view", async ({ await cue.click(); - // It stops with the cue 60px below the close button's bar, the tokens + // It stops with the cue 20px below the close button's bar, the tokens // under it. const gap = async () => { const [barBox, cueBox] = await Promise.all([ @@ -144,7 +144,7 @@ test("Ethena launch promo's scroll cue scrolls the tokens into view", async ({ ]); return Math.round(cueBox!.y - (barBox!.y + barBox!.height)); }; - await expect.poll(gap).toBe(60); + await expect.poll(gap).toBe(20); await expect(page.getByTestId("ethena-launch-swap-usde")).toBeInViewport(); }); diff --git a/extension/src/popup/views/EthenaLaunch/index.tsx b/extension/src/popup/views/EthenaLaunch/index.tsx index ce6fa83ef1..7cb8923ce9 100644 --- a/extension/src/popup/views/EthenaLaunch/index.tsx +++ b/extension/src/popup/views/EthenaLaunch/index.tsx @@ -39,7 +39,7 @@ const ETHENA_DOCS_URL = "https://docs.ethena.fi/"; // The scroll cue scrolls the page until it sits this far below the close // button's bar, with the tokens under it. -const SCROLL_CUE_GAP = 60; +const SCROLL_CUE_GAP = 20; const REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)"; interface EthenaTokenSectionProps { diff --git a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx index 687fda8fca..516ac6dcab 100644 --- a/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx +++ b/extension/src/popup/views/__tests__/EthenaLaunch.test.tsx @@ -147,14 +147,14 @@ describe("EthenaLaunch", () => { jest.restoreAllMocks(); }); - it("scrolls the tokens up until the cue is 60px below the bar", async () => { + it("scrolls the tokens up until the cue is 20px below the bar", async () => { renderView(); const { cue, scrollTo } = layOut(); await userEvent.click(cue); expect(scrollTo).toHaveBeenCalledWith({ - top: 20 + 544 - 80 - 60, + top: 20 + 544 - 80 - 20, behavior: "smooth", }); }); @@ -173,7 +173,7 @@ describe("EthenaLaunch", () => { await userEvent.click(cue); expect(scrollTo).toHaveBeenCalledWith({ - top: 20 + 544 - 80 - 60, + top: 20 + 544 - 80 - 20, behavior: "auto", }); });