From 6eea2d33ee4aa23a8533cb4cf284f575477c6e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Mon, 31 Aug 2026 16:59:45 -0700 Subject: [PATCH 01/22] feat: add USDT0 launch banner and promo sheet to Home MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a dismissible "USDT0 is live on Stellar" promo banner to the Home screen, between the action buttons and the account tabs. Tapping it opens a fullscreen sheet that slides up from the bottom with the USDT0 launch details; its "Transfer USDT0" button routes to the Add funds screen. The banner reuses the implementation of the old "Introducing Freighter Mobile" promo (removed in #2962) — dismissal persisted in background-owned storage via message handlers — renamed to "USDT0 Launch Banner" throughout, with the green USDT0 color, copy, and logo. The sheet follows the Discover fullscreen bottom-sheet pattern (radix Sheet, side="bottom"). Co-Authored-By: Claude Fable 5 --- @shared/api/internal.ts | 28 +++ @shared/api/types/message-request.ts | 10 + @shared/constants/services.ts | 2 + .../handlers/dismissUsdt0LaunchBanner.ts | 12 ++ .../handlers/getUsdt0LaunchBannerDismissed.ts | 11 + .../messageListener/popupMessageListener.ts | 12 ++ extension/src/constants/localStorageTypes.ts | 1 + extension/src/popup/assets/logo-usdt0.png | Bin 0 -> 15645 bytes extension/src/popup/assets/usdt0-arcs.svg | 20 ++ extension/src/popup/assets/usdt0-lockup.svg | 10 + .../account/AccountHeader/index.tsx | 2 + .../Usdt0LaunchSheet/index.tsx | 137 +++++++++++++ .../Usdt0LaunchSheet/styles.scss | 188 ++++++++++++++++++ .../account/Usdt0LaunchBanner/index.tsx | 121 +++++++++++ .../account/Usdt0LaunchBanner/styles.scss | 100 ++++++++++ .../src/popup/locales/en/translation.json | 9 + .../src/popup/locales/pt/translation.json | 9 + 17 files changed, 672 insertions(+) create mode 100644 extension/src/background/messageListener/handlers/dismissUsdt0LaunchBanner.ts create mode 100644 extension/src/background/messageListener/handlers/getUsdt0LaunchBannerDismissed.ts create mode 100644 extension/src/popup/assets/logo-usdt0.png create mode 100644 extension/src/popup/assets/usdt0-arcs.svg create mode 100644 extension/src/popup/assets/usdt0-lockup.svg create mode 100644 extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx create mode 100644 extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss create mode 100644 extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx create mode 100644 extension/src/popup/components/account/Usdt0LaunchBanner/styles.scss diff --git a/@shared/api/internal.ts b/@shared/api/internal.ts index 9e145871f5..a6ad3858e8 100644 --- a/@shared/api/internal.ts +++ b/@shared/api/internal.ts @@ -2199,6 +2199,34 @@ export const getTokenIds = async ({ return tokenIdList; }; +export const getUsdt0LaunchBannerDismissed = async (): Promise => { + const { isDismissed, error } = await sendMessageToBackground({ + activePublicKey: null, + type: SERVICE_TYPES.GET_USDT0_LAUNCH_BANNER_DISMISSED, + }); + + if (error) { + return false; + } + + return !!isDismissed; +}; + +export const dismissUsdt0LaunchBanner = async (): Promise<{ + isDismissed: boolean; +}> => { + const { isDismissed, error } = await sendMessageToBackground({ + activePublicKey: null, + type: SERVICE_TYPES.DISMISS_USDT0_LAUNCH_BANNER, + }); + + if (error) { + throw new Error(error); + } + + return { isDismissed: !!isDismissed }; +}; + export const removeTokenId = async ({ activePublicKey, contractId, diff --git a/@shared/api/types/message-request.ts b/@shared/api/types/message-request.ts index 5dc83dd06a..53db55f049 100644 --- a/@shared/api/types/message-request.ts +++ b/@shared/api/types/message-request.ts @@ -428,6 +428,14 @@ export interface GetHiddenAssetsMessage extends BaseMessage { type: SERVICE_TYPES.GET_HIDDEN_ASSETS; } +export interface GetUsdt0LaunchBannerDismissedMessage extends BaseMessage { + type: SERVICE_TYPES.GET_USDT0_LAUNCH_BANNER_DISMISSED; +} + +export interface DismissUsdt0LaunchBannerMessage extends BaseMessage { + type: SERVICE_TYPES.DISMISS_USDT0_LAUNCH_BANNER; +} + export interface GetRecentProtocolsMessage extends BaseMessage { type: SERVICE_TYPES.GET_RECENT_PROTOCOLS; } @@ -565,6 +573,8 @@ export type ServiceMessageRequest = | GetIsAccountMismatchMessage | ChangeAssetVisibilityMessage | GetHiddenAssetsMessage + | GetUsdt0LaunchBannerDismissedMessage + | DismissUsdt0LaunchBannerMessage | GetRecentProtocolsMessage | AddRecentProtocolMessage | ClearRecentProtocolsMessage diff --git a/@shared/constants/services.ts b/@shared/constants/services.ts index d788684012..9c967543a3 100644 --- a/@shared/constants/services.ts +++ b/@shared/constants/services.ts @@ -54,6 +54,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_BLOCKAID_DEBUG_OVERRIDE = "GET_BLOCKAID_DEBUG_OVERRIDE", SAVE_BLOCKAID_DEBUG_OVERRIDE = "SAVE_BLOCKAID_DEBUG_OVERRIDE", ADD_COLLECTIBLE = "ADD_COLLECTIBLE", diff --git a/extension/src/background/messageListener/handlers/dismissUsdt0LaunchBanner.ts b/extension/src/background/messageListener/handlers/dismissUsdt0LaunchBanner.ts new file mode 100644 index 0000000000..0bc315e063 --- /dev/null +++ b/extension/src/background/messageListener/handlers/dismissUsdt0LaunchBanner.ts @@ -0,0 +1,12 @@ +import { DataStorageAccess } from "background/helpers/dataStorageAccess"; +import { USDT0_LAUNCH_BANNER_DISMISSED } from "constants/localStorageTypes"; + +export const dismissUsdt0LaunchBanner = async ({ + localStore, +}: { + localStore: DataStorageAccess; +}): Promise<{ isDismissed: boolean }> => { + await localStore.setItem(USDT0_LAUNCH_BANNER_DISMISSED, true); + const isDismissed = await localStore.getItem(USDT0_LAUNCH_BANNER_DISMISSED); + return { isDismissed: !!isDismissed }; +}; diff --git a/extension/src/background/messageListener/handlers/getUsdt0LaunchBannerDismissed.ts b/extension/src/background/messageListener/handlers/getUsdt0LaunchBannerDismissed.ts new file mode 100644 index 0000000000..d0e9d6f350 --- /dev/null +++ b/extension/src/background/messageListener/handlers/getUsdt0LaunchBannerDismissed.ts @@ -0,0 +1,11 @@ +import { DataStorageAccess } from "background/helpers/dataStorageAccess"; +import { USDT0_LAUNCH_BANNER_DISMISSED } from "constants/localStorageTypes"; + +export const getUsdt0LaunchBannerDismissed = async ({ + localStore, +}: { + localStore: DataStorageAccess; +}): Promise<{ isDismissed: boolean }> => { + const dismissed = await localStore.getItem(USDT0_LAUNCH_BANNER_DISMISSED); + return { isDismissed: !!dismissed }; +}; diff --git a/extension/src/background/messageListener/popupMessageListener.ts b/extension/src/background/messageListener/popupMessageListener.ts index a3b42240e9..68a66236a0 100644 --- a/extension/src/background/messageListener/popupMessageListener.ts +++ b/extension/src/background/messageListener/popupMessageListener.ts @@ -90,6 +90,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 { loadBackendSettings } from "./handlers/loadBackendSettings"; import { saveBlockaidOverrideState } from "./handlers/saveDebugOverride"; import { getBlockaidOverrideState } from "./handlers/getDebugOverride"; @@ -579,6 +581,16 @@ export const popupMessageListener = ( localStore, }); } + case SERVICE_TYPES.GET_USDT0_LAUNCH_BANNER_DISMISSED: { + return getUsdt0LaunchBannerDismissed({ + localStore, + }); + } + case SERVICE_TYPES.DISMISS_USDT0_LAUNCH_BANNER: { + return dismissUsdt0LaunchBanner({ + localStore, + }); + } case SERVICE_TYPES.GET_BLOCKAID_DEBUG_OVERRIDE: { return getBlockaidOverrideState({ localStore, diff --git a/extension/src/constants/localStorageTypes.ts b/extension/src/constants/localStorageTypes.ts index d69f3a7627..3bca199400 100644 --- a/extension/src/constants/localStorageTypes.ts +++ b/extension/src/constants/localStorageTypes.ts @@ -28,6 +28,7 @@ export const HIDDEN_ASSETS = "hiddenAssets"; export const HIDDEN_COLLECTIBLES = "hiddenCollectibles"; export const TEMPORARY_STORE_ID = "temporaryStore"; export const TEMPORARY_STORE_EXTRA_ID = "temporaryStoreExtra"; +export const USDT0_LAUNCH_BANNER_DISMISSED = "usdt0LaunchBannerDismissed"; export const OVERRIDDEN_BLOCKAID_RESPONSE_ID = "overriddenBlockaidResponse"; export const COLLECTIBLES_ID = "collectibles"; export const IS_OPEN_SIDEBAR_BY_DEFAULT_ID = "isOpenSidebarByDefault"; diff --git a/extension/src/popup/assets/logo-usdt0.png b/extension/src/popup/assets/logo-usdt0.png new file mode 100644 index 0000000000000000000000000000000000000000..b193faf698151bd4a09b9dad221021db00bb4d4c GIT binary patch literal 15645 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 + + + + + + + + + + + + + + + + + + + diff --git a/extension/src/popup/assets/usdt0-lockup.svg b/extension/src/popup/assets/usdt0-lockup.svg new file mode 100644 index 0000000000..cc9591d197 --- /dev/null +++ b/extension/src/popup/assets/usdt0-lockup.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/extension/src/popup/components/account/AccountHeader/index.tsx b/extension/src/popup/components/account/AccountHeader/index.tsx index 66e8c311e4..e6f9a61bd6 100644 --- a/extension/src/popup/components/account/AccountHeader/index.tsx +++ b/extension/src/popup/components/account/AccountHeader/index.tsx @@ -27,6 +27,7 @@ import { signOut } from "popup/ducks/accountServices"; import { AccountHeaderModal } from "popup/components/account/AccountHeaderModal"; import { NetworkIcon } from "popup/components/manageNetwork/NetworkIcon"; import { NetworkDetails } from "@shared/constants/stellar"; +import { Usdt0LaunchBanner } from "popup/components/account/Usdt0LaunchBanner"; import { AccountTabs } from "popup/components/account/AccountTabs"; import { MaintenanceBanner } from "popup/components/MaintenanceBanner"; import { getNetworkDisplayName } from "./getNetworkDisplayName"; @@ -416,6 +417,7 @@ export const AccountHeader = ({ + {isBackgroundActive ? createPortal( void; +} + +export const Usdt0LaunchSheet = ({ onClose }: Usdt0LaunchSheetProps) => { + const { t } = useTranslation(); + const navigate = useNavigate(); + + const handleTransferClick = () => { + onClose(); + navigateTo(ROUTES.addFunds, navigate); + }; + + return ( +
+
+
+ +
+
+ USDT0 +
+
+
+ +
+
+
+
+ {t("USDT0 is now on Stellar")} +
+ + {t( + "Move USDT across supported networks and access it on Stellar with USDT0.", + )} + +
+
+
+
+ +
+
+ + {t("Move across networks")} + + + {t("Transfer USDT between Stellar and supported networks.")} + +
+
+
+
+ +
+
+ + {t("1:1 backed, unified liquidity")} + + + {t( + "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.", + )} + +
+
+
+
+
+ +
+
+
+ ); +}; diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss new file mode 100644 index 0000000000..fc6e1a0d08 --- /dev/null +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss @@ -0,0 +1,188 @@ +@use "../../../../styles/utils.scss" as *; + +.Usdt0LaunchSheet { + position: relative; + height: 100%; + width: 100%; + background: var(--sds-clr-gray-01); + overflow: hidden; + + &__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); + 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; + height: 100%; + padding: pxToRem(24px) 0; + gap: pxToRem(32px); + } + + &__header { + display: flex; + align-items: center; + padding: 0 pxToRem(24px); + } + + &__close { + background: none; + border: none; + padding: 0; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + color: var(--sds-clr-gray-12); + + svg { + width: pxToRem(24px); + height: pxToRem(24px); + } + } + + &__body { + flex: 1; + min-height: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-end; + gap: pxToRem(32px); + padding: 0 pxToRem(24px); + } + + &__heading { + display: flex; + flex-direction: column; + align-items: center; + gap: pxToRem(4px); + text-align: center; + width: 100%; + } + + &__title { + font-size: pxToRem(24px); + line-height: pxToRem(32px); + font-weight: var(--sds-fw-medium); + letter-spacing: -0.04em; + color: var(--sds-clr-gray-12); + } + + &__description { + color: var(--sds-clr-gray-11); + margin: 0; + } + + &__features { + display: flex; + flex-direction: column; + gap: pxToRem(16px); + width: 100%; + } + + &__feature { + display: flex; + align-items: center; + gap: pxToRem(12px); + + &__icon { + width: pxToRem(32px); + height: pxToRem(32px); + flex-shrink: 0; + background: #222222; + border-radius: pxToRem(4px); + display: flex; + align-items: center; + justify-content: center; + color: var(--sds-clr-gray-11); + + svg { + width: pxToRem(14px); + height: pxToRem(14px); + } + } + + &__text { + display: flex; + flex-direction: column; + gap: pxToRem(2px); + flex: 1; + min-width: 0; + } + + &__title { + color: var(--sds-clr-gray-12); + margin: 0; + } + + &__description { + color: var(--sds-clr-gray-11); + margin: 0; + } + } + + &__footer { + padding: 0 pxToRem(24px); + } +} diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx b/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx new file mode 100644 index 0000000000..56a89e88d4 --- /dev/null +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx @@ -0,0 +1,121 @@ +import React, { useState, useEffect } from "react"; +import { Icon, Text } from "@stellar/design-system"; +import { useTranslation } from "react-i18next"; +import { captureException } from "@sentry/browser"; + +import { + getUsdt0LaunchBannerDismissed, + dismissUsdt0LaunchBanner, +} from "@shared/api/internal"; + +import { + Sheet, + SheetContent, + SheetTitle, + ScreenReaderOnly, +} from "popup/basics/shadcn/Sheet"; +import Usdt0Logo from "popup/assets/logo-usdt0.png"; +import { Usdt0LaunchSheet } from "./Usdt0LaunchSheet"; + +import "./styles.scss"; + +export const Usdt0LaunchBanner = () => { + const { t } = useTranslation(); + const [isDismissed, setIsDismissed] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [isSheetOpen, setIsSheetOpen] = useState(false); + + useEffect(() => { + const checkDismissedStatus = async () => { + try { + const dismissed = await getUsdt0LaunchBannerDismissed(); + setIsDismissed(dismissed); + } catch (error) { + captureException(error); + setIsDismissed(false); + } finally { + setIsLoading(false); + } + }; + + checkDismissedStatus(); + }, []); + + const handleDismiss = async (e: React.MouseEvent) => { + e.stopPropagation(); + try { + const { isDismissed } = await dismissUsdt0LaunchBanner(); + setIsDismissed(isDismissed); + } catch (error) { + captureException(error); + } + }; + + const handleBannerClick = () => { + setIsSheetOpen(true); + }; + + // Don't show banner if loading or if dismissed + if (isLoading || isDismissed) { + return null; + } + + return ( + <> +
+
+
+ USDT0 logo +
+
+ + {t("USDT0 is live on Stellar")} + + + {t("Cross-chain access to USDT")} + +
+
+ +
+ !open && setIsSheetOpen(false)} + > + e.preventDefault()} + aria-describedby={undefined} + side="bottom" + className="Usdt0LaunchBanner__sheet" + > + + {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 new file mode 100644 index 0000000000..91d91de9ea --- /dev/null +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/styles.scss @@ -0,0 +1,100 @@ +@use "../../../styles/utils.scss" as *; + +.Usdt0LaunchBanner { + position: relative; + background: #002d19; + border-radius: pxToRem(12px); + padding: pxToRem(16px); + // No horizontal offsets: this sits in `AccountHeader__account-info__details`, + // which spans the full content column, so the banner stretches to match the + // action tiles and tab strip. + margin-bottom: pxToRem(16px); + margin-top: 0; + display: flex; + align-items: center; + justify-content: space-between; + gap: pxToRem(12px); + cursor: pointer; + transition: opacity 0.2s ease; + + &:hover { + opacity: 0.9; + } + + &__content { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + gap: pxToRem(12px); + max-width: 100%; + margin: 0 auto; + } + + &__text { + display: flex; + flex-direction: column; + gap: pxToRem(2px); + flex: 1; + } + + &__title { + color: var(--sds-clr-gray-12); + margin: 0; + font-size: pxToRem(14px); + } + + &__subtitle { + color: var(--sds-clr-gray-11); + margin: 0; + font-size: pxToRem(12px); + } + + &__logo { + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + + img { + width: pxToRem(38px); + height: pxToRem(38px); + object-fit: cover; + border-radius: pxToRem(8px); + box-shadow: 0 pxToRem(4px) pxToRem(10px) 0 rgba(0, 0, 0, 0.25); + } + } + + &__dismiss { + position: absolute; + top: pxToRem(8px); + right: pxToRem(8px); + background: none; + border: none; + cursor: pointer; + padding: pxToRem(4px); + display: flex; + align-items: center; + justify-content: center; + color: var(--sds-clr-gray-12); + border-radius: pxToRem(16px); + z-index: 10; + pointer-events: auto; + + &:hover { + opacity: 1; + background: rgba(255, 255, 255, 0.1); + } + + svg { + width: pxToRem(16px); + height: pxToRem(16px); + } + } + + &__sheet { + background: var(--sds-clr-gray-01); + height: 100%; + width: 100%; + } +} diff --git a/extension/src/popup/locales/en/translation.json b/extension/src/popup/locales/en/translation.json index e81b50bf19..53fe3d41cc 100644 --- a/extension/src/popup/locales/en/translation.json +++ b/extension/src/popup/locales/en/translation.json @@ -3,6 +3,7 @@ "{{domain}} is not currently connected to Freighter": "{{domain}} is not currently connected to Freighter", "* All Stellar accounts must maintain a minimum balance of lumens.": "* All Stellar accounts must maintain a minimum balance of lumens.", "0.5 XLM required": "0.5 XLM required", + "1:1 backed, unified liquidity": "1:1 backed, unified liquidity", "A destination account requires the use of the memo field which is not present in the transaction you’re about to sign.": "A destination account requires the use of the memo field which is not present in the transaction you’re about to sign.", "A new signing request arrived while you were reviewing another. Please review it carefully before approving.": "A new signing request arrived while you were reviewing another. Please review it carefully before approving.", "A token was flagged as malicious": "A token was flagged as malicious", @@ -166,6 +167,7 @@ "Create Contract": "Create Contract", "Create New Address": "Create New Address", "Create new wallet": "Create new wallet", + "Cross-chain access to USDT": "Cross-chain access to USDT", "Current Network": "Current Network", "Custom": "Custom", "dApps": "dApps", @@ -395,6 +397,8 @@ "Minimum XLM needed": "Minimum XLM needed", "Minted": "Minted", "More options": "More options", + "Move across networks": "Move across networks", + "Move USDT across supported networks and access it on Stellar with USDT0.": "Move USDT across supported networks and access it on Stellar with USDT0.", "Multiple assets": "Multiple assets", "Multiple assets have a similar code, please check the domain before adding.": "Multiple assets have a similar code, please check the domain before adding.", "must be at least": "must be at least", @@ -694,6 +698,8 @@ "Transaction Timeout": "Transaction Timeout", "Transfer from another account": "Transfer from another account", "Transfer from Coinbase & other options": "Transfer from Coinbase & other options", + "Transfer USDT between Stellar and supported networks.": "Transfer USDT between Stellar and supported networks.", + "Transfer USDT0": "Transfer USDT0", "Trending": "Trending", "trustlines": "trustlines", "Trustor": "Trustor", @@ -722,6 +728,9 @@ "Update the Stellar app on your Ledger to version {{version}} or later to sign messages.": "Update the Stellar app on your Ledger to version {{version}} or later to sign messages.", "Upload Contract Wasm": "Upload Contract Wasm", "Usage data sharing": "Usage data sharing", + "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.": "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.", + "USDT0 is live on Stellar": "USDT0 is live on Stellar", + "USDT0 is now on Stellar": "USDT0 is now on Stellar", "Use caution when connecting to domains without an SSL certificate.": "Use caution when connecting to domains without an SSL certificate.", "Use default account": "Use default account", "Use experimental API's and connect to the Futurenet, a test network.": "Use experimental API's and connect to the Futurenet, a test network.", diff --git a/extension/src/popup/locales/pt/translation.json b/extension/src/popup/locales/pt/translation.json index c88416ffae..8a4aaab943 100644 --- a/extension/src/popup/locales/pt/translation.json +++ b/extension/src/popup/locales/pt/translation.json @@ -3,6 +3,7 @@ "{{domain}} is not currently connected to Freighter": "{{domain}} não está atualmente conectado ao Freighter", "* All Stellar accounts must maintain a minimum balance of lumens.": "* Todas as contas Stellar devem manter um saldo mínimo de lumens.", "0.5 XLM required": "0,5 XLM necessários", + "1:1 backed, unified liquidity": "Lastro 1:1, liquidez unificada", "A destination account requires the use of the memo field which is not present in the transaction you’re about to sign.": "Uma conta de destino requer o uso do campo memo que não está presente na transação que você está prestes a assinar.", "A new signing request arrived while you were reviewing another. Please review it carefully before approving.": "Uma nova solicitação de assinatura chegou enquanto você revisava outra. Revise-a com atenção antes de aprovar.", "A token was flagged as malicious": "Um token foi sinalizado como malicioso", @@ -166,6 +167,7 @@ "Create Contract": "Criar Contrato", "Create New Address": "Criar Novo Endereço", "Create new wallet": "Criar nova carteira", + "Cross-chain access to USDT": "Acesso cross-chain ao USDT", "Current Network": "Rede Atual", "Custom": "Personalizado", "dApps": "dApps", @@ -395,6 +397,8 @@ "Minimum XLM needed": "XLM mínimo necessário", "Minted": "Cunhado", "More options": "Mais opções", + "Move across networks": "Mova entre redes", + "Move USDT across supported networks and access it on Stellar with USDT0.": "Mova USDT entre redes suportadas e acesse na Stellar com USDT0.", "Multiple assets": "Múltiplos ativos", "Multiple assets have a similar code, please check the domain before adding.": "Vários ativos têm um código similar, verifique o domínio antes de adicionar.", "must be at least": "deve ser pelo menos", @@ -694,6 +698,8 @@ "Transaction Timeout": "Tempo Limite da Transação", "Transfer from another account": "Transferir de outra conta", "Transfer from Coinbase & other options": "Transferir do Coinbase e outras opções", + "Transfer USDT between Stellar and supported networks.": "Transfira USDT entre a Stellar e redes suportadas.", + "Transfer USDT0": "Transferir USDT0", "Trending": "Em alta", "trustlines": "linhas de confiança", "Trustor": "Fidedigno", @@ -722,6 +728,9 @@ "Update the Stellar app on your Ledger to version {{version}} or later to sign messages.": "Atualize o aplicativo Stellar no seu Ledger para a versão {{version}} ou posterior para assinar mensagens.", "Upload Contract Wasm": "Carregar Wasm do Contrato", "Usage data sharing": "Compartilhamento de dados de uso", + "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.": "USDT0 tem lastro 1:1 em USDT, sem versões wrapped fragmentadas.", + "USDT0 is live on Stellar": "USDT0 chegou na Stellar", + "USDT0 is now on Stellar": "USDT0 agora na Stellar", "Use caution when connecting to domains without an SSL certificate.": "Use cautela ao se conectar a domínios sem um certificado SSL.", "Use default account": "Usar conta padrão", "Use experimental API's and connect to the Futurenet, a test network.": "Use APIs experimentais e conecte-se ao Futurenet, uma rede de testes.", From 44bfe2367858dc4ec7eb59b89a7d4800eccec254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Tue, 1 Sep 2026 11:18:28 -0700 Subject: [PATCH 02/22] fix: use lg size for the Transfer USDT0 CTA Matches the app's bottom-sheet CTA convention (InfoBottomSheet uses size="lg" variant="secondary" isRounded); md was borrowed from the Discover welcome modal, which isn't a sheet footer. Co-Authored-By: Claude Fable 5 --- .../account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx index a8a465cf2c..ca4049d399 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx @@ -121,7 +121,7 @@ export const Usdt0LaunchSheet = ({ onClose }: Usdt0LaunchSheetProps) => {
-
+
diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx b/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx index a811b424c8..7e46689f8b 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx @@ -69,7 +69,7 @@ export const Usdt0LaunchBanner = () => { data-testid="usdt0-launch-banner-open" >
- USDT0 logo + {t("USDT0
so the sheet is reachable by - // keyboard — reset the user-agent button chrome + // keyboard — reset the user-agent button chrome. It carries the card's + // 16px padding so the entire card (minus the dismiss button) is a + // click target, matching the whole-card hover cue. &__content { background: none; border: none; + border-radius: inherit; font: inherit; text-align: left; cursor: pointer; @@ -35,7 +37,7 @@ gap: pxToRem(12px); max-width: 100%; margin: 0 auto; - padding: 0; + padding: pxToRem(16px); } &__text { diff --git a/extension/src/popup/locales/en/translation.json b/extension/src/popup/locales/en/translation.json index be762559ab..af93dc8519 100644 --- a/extension/src/popup/locales/en/translation.json +++ b/extension/src/popup/locales/en/translation.json @@ -729,9 +729,11 @@ "Update the Stellar app on your Ledger to version {{version}} or later to sign messages.": "Update the Stellar app on your Ledger to version {{version}} or later to sign messages.", "Upload Contract Wasm": "Upload Contract Wasm", "Usage data sharing": "Usage data sharing", + "USDT0": "USDT0", "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.": "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.", "USDT0 is live on Stellar": "USDT0 is live on Stellar", "USDT0 is now on Stellar": "USDT0 is now on Stellar", + "USDT0 logo": "USDT0 logo", "Use caution when connecting to domains without an SSL certificate.": "Use caution when connecting to domains without an SSL certificate.", "Use default account": "Use default account", "Use experimental API's and connect to the Futurenet, a test network.": "Use experimental API's and connect to the Futurenet, a test network.", diff --git a/extension/src/popup/locales/pt/translation.json b/extension/src/popup/locales/pt/translation.json index 57feb54dbc..95d56e8f03 100644 --- a/extension/src/popup/locales/pt/translation.json +++ b/extension/src/popup/locales/pt/translation.json @@ -729,9 +729,11 @@ "Update the Stellar app on your Ledger to version {{version}} or later to sign messages.": "Atualize o aplicativo Stellar no seu Ledger para a versão {{version}} ou posterior para assinar mensagens.", "Upload Contract Wasm": "Carregar Wasm do Contrato", "Usage data sharing": "Compartilhamento de dados de uso", + "USDT0": "USDT0", "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.": "USDT0 tem lastro 1:1 em USDT, sem versões wrapped fragmentadas.", "USDT0 is live on Stellar": "USDT0 chegou na Stellar", "USDT0 is now on Stellar": "USDT0 agora na Stellar", + "USDT0 logo": "Logo USDT0", "Use caution when connecting to domains without an SSL certificate.": "Use cautela ao se conectar a domínios sem um certificado SSL.", "Use default account": "Usar conta padrão", "Use experimental API's and connect to the Futurenet, a test network.": "Use APIs experimentais e conecte-se ao Futurenet, uma rede de testes.", From 3ce8068f0df0330cd76c74d542e8da708d6cf337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Tue, 1 Sep 2026 14:35:42 -0700 Subject: [PATCH 11/22] fix: make the banner logo decorative for assistive tech MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The logo sits inside the labeled launch button, so its alt text was prepended to the button's accessible name as redundant noise — the title text already names USDT0. Empty alt lets screen readers announce only the action text; drops the now-unused "USDT0 logo" locale keys. Co-Authored-By: Claude Fable 5 --- .../src/popup/components/account/Usdt0LaunchBanner/index.tsx | 5 ++++- extension/src/popup/locales/en/translation.json | 1 - extension/src/popup/locales/pt/translation.json | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx b/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx index 7e46689f8b..6303f21b60 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/index.tsx @@ -69,7 +69,10 @@ export const Usdt0LaunchBanner = () => { data-testid="usdt0-launch-banner-open" >
- {t("USDT0 + {/* Decorative inside the labeled launch button — the title text + already names USDT0, so a non-empty alt would only add noise + to the button's accessible name */} +
Date: Tue, 1 Sep 2026 18:07:31 -0700 Subject: [PATCH 12/22] feat: split the USDT0 sheet CTA into Receive and Bridge actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the sheet to the revised design: shorter description and feature copy, and two footer actions replacing "Transfer USDT0" — "Receive USDT0" navigates to the account QR screen (same route as Add funds' wallet-transfer option) and "Bridge to Stellar" opens the usdt0.to bridge in a new tab, like Discover dApp links. The bridge button is hand-rolled since no SDS Button variant is borderless. Co-Authored-By: Claude Fable 5 --- .../Usdt0LaunchSheet/index.tsx | 38 ++++++++++++------- .../Usdt0LaunchSheet/styles.scss | 32 ++++++++++++++++ .../src/popup/locales/en/translation.json | 9 +++-- .../src/popup/locales/pt/translation.json | 9 +++-- 4 files changed, 67 insertions(+), 21 deletions(-) diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx index f6c723e874..2bcb9bbff6 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/index.tsx @@ -4,12 +4,15 @@ import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { ROUTES } from "popup/constants/routes"; -import { navigateTo } from "popup/helpers/navigate"; +import { navigateTo, openTab } from "popup/helpers/navigate"; import Usdt0Arcs from "popup/assets/usdt0-arcs.svg"; import Usdt0Lockup from "popup/assets/usdt0-lockup.svg"; import "./styles.scss"; +const USDT0_BRIDGE_URL = + "https://usdt0.to/transfer?source=ethereum&destination=stellar&token=usdt0"; + interface Usdt0LaunchSheetProps { onClose: () => void; } @@ -18,9 +21,13 @@ export const Usdt0LaunchSheet = ({ onClose }: Usdt0LaunchSheetProps) => { const { t } = useTranslation(); const navigate = useNavigate(); - const handleTransferClick = () => { + const handleReceiveClick = () => { onClose(); - navigateTo(ROUTES.addFunds, navigate); + navigateTo(ROUTES.viewPublicKey, navigate); + }; + + const handleBridgeClick = () => { + openTab(USDT0_BRIDGE_URL); }; return ( @@ -65,9 +72,7 @@ export const Usdt0LaunchSheet = ({ onClose }: Usdt0LaunchSheetProps) => { weight="regular" addlClassName="Usdt0LaunchSheet__description" > - {t( - "Move USDT across supported networks and access it on Stellar with USDT0.", - )} + {t("Access USDT liquidity on Stellar with USDT0.")}
@@ -90,7 +95,7 @@ export const Usdt0LaunchSheet = ({ onClose }: Usdt0LaunchSheetProps) => { weight="regular" addlClassName="Usdt0LaunchSheet__feature__description" > - {t("Transfer USDT between Stellar and supported networks.")} + {t("Transfer USDT0 between Stellar and supported networks.")}
@@ -113,9 +118,7 @@ export const Usdt0LaunchSheet = ({ onClose }: Usdt0LaunchSheetProps) => { weight="regular" addlClassName="Usdt0LaunchSheet__feature__description" > - {t( - "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.", - )} + {t("USDT0 is backed 1:1 by USDT.")}
@@ -127,11 +130,20 @@ export const Usdt0LaunchSheet = ({ onClose }: Usdt0LaunchSheetProps) => { variant="secondary" isFullWidth isRounded - onClick={handleTransferClick} - data-testid="usdt0-launch-sheet-transfer" + onClick={handleReceiveClick} + data-testid="usdt0-launch-sheet-receive" > - {t("Transfer USDT0")} + {t("Receive USDT0")} + diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss index 62e0ba9a66..8091cf3b33 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss @@ -189,6 +189,38 @@ } &__footer { + display: flex; + flex-direction: column; + gap: pxToRem(8px); padding: 0 pxToRem(24px); } + + // Borderless text button per design — no SDS Button variant is + // transparent, so it's hand-rolled like the close button + &__bridge { + background: none; + border: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: pxToRem(4px); + width: 100%; + padding: pxToRem(8px) pxToRem(12px); + border-radius: pxToRem(100px); + 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 { + background: rgba(255, 255, 255, 0.1); + } + + svg { + width: pxToRem(16px); + height: pxToRem(16px); + } + } } diff --git a/extension/src/popup/locales/en/translation.json b/extension/src/popup/locales/en/translation.json index eb4e84c953..706e196368 100644 --- a/extension/src/popup/locales/en/translation.json +++ b/extension/src/popup/locales/en/translation.json @@ -11,6 +11,7 @@ "About": "About", "About unverified tokens": "About unverified tokens", "About verified tokens": "About verified tokens", + "Access USDT liquidity on Stellar with USDT0.": "Access USDT liquidity on Stellar with USDT0.", "Account": "Account", "Account details": "Account details", "Account ID": "Account ID", @@ -95,6 +96,7 @@ "Blockaid Response Override": "Blockaid Response Override", "Blockaid unfunded destination": "This is a new account and needs 1 XLM in order to get started. Any transaction to send non-XLM to an unfunded account will fail.", "Blockaid unfunded destination native": "This is a new account and needs at least 1 XLM to be created. Sending less than 1 XLM to create it will fail.", + "Bridge to Stellar": "Bridge to Stellar", "Bump To": "Bump To", "Buy Amount": "Buy Amount", "Buy with Coinbase": "Buy with Coinbase", @@ -399,7 +401,6 @@ "Minted": "Minted", "More options": "More options", "Move across networks": "Move across networks", - "Move USDT across supported networks and access it on Stellar with USDT0.": "Move USDT across supported networks and access it on Stellar with USDT0.", "Multiple assets": "Multiple assets", "Multiple assets have a similar code, please check the domain before adding.": "Multiple assets have a similar code, please check the domain before adding.", "must be at least": "must be at least", @@ -484,6 +485,7 @@ "Read before importing your key": "Read before importing your key", "Ready to migrate": "Ready to migrate", "Receive funds from another wallet": "Receive funds from another wallet", + "Receive USDT0": "Receive USDT0", "Received": "Received", "Recent": "Recent", "Recents": "Recents", @@ -699,8 +701,7 @@ "Transaction Timeout": "Transaction Timeout", "Transfer from another account": "Transfer from another account", "Transfer from Coinbase & other options": "Transfer from Coinbase & other options", - "Transfer USDT between Stellar and supported networks.": "Transfer USDT between Stellar and supported networks.", - "Transfer USDT0": "Transfer USDT0", + "Transfer USDT0 between Stellar and supported networks.": "Transfer USDT0 between Stellar and supported networks.", "Trending": "Trending", "trustlines": "trustlines", "Trustor": "Trustor", @@ -730,7 +731,7 @@ "Upload Contract Wasm": "Upload Contract Wasm", "Usage data sharing": "Usage data sharing", "USDT0": "USDT0", - "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.": "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.", + "USDT0 is backed 1:1 by USDT.": "USDT0 is backed 1:1 by USDT.", "USDT0 is live on Stellar": "USDT0 is live on Stellar", "USDT0 is now on Stellar": "USDT0 is now on Stellar", "Use caution when connecting to domains without an SSL certificate.": "Use caution when connecting to domains without an SSL certificate.", diff --git a/extension/src/popup/locales/pt/translation.json b/extension/src/popup/locales/pt/translation.json index 31cf3b1bc7..1aeb454128 100644 --- a/extension/src/popup/locales/pt/translation.json +++ b/extension/src/popup/locales/pt/translation.json @@ -11,6 +11,7 @@ "About": "Sobre", "About unverified tokens": "Sobre tokens não verificados", "About verified tokens": "Sobre tokens verificados", + "Access USDT liquidity on Stellar with USDT0.": "Acesse a liquidez do USDT na Stellar com USDT0.", "Account": "Conta", "Account details": "Detalhes da conta", "Account ID": "ID da Conta", @@ -95,6 +96,7 @@ "Blockaid Response Override": "Substituição de Resposta do Blockaid", "Blockaid unfunded destination": "Esta é uma nova conta e precisa de 1 XLM para começar. Qualquer transação para enviar não-XLM para uma conta não financiada falhará.", "Blockaid unfunded destination native": "Esta é uma nova conta e precisa de pelo menos 1 XLM para ser criada. Enviar menos de 1 XLM para criá-la falhará.", + "Bridge to Stellar": "Bridge para Stellar", "Bump To": "Bump Para", "Buy Amount": "Quantia de Compra", "Buy with Coinbase": "Comprar com Coinbase", @@ -399,7 +401,6 @@ "Minted": "Cunhado", "More options": "Mais opções", "Move across networks": "Mova entre redes", - "Move USDT across supported networks and access it on Stellar with USDT0.": "Mova USDT entre redes suportadas e acesse na Stellar com USDT0.", "Multiple assets": "Múltiplos ativos", "Multiple assets have a similar code, please check the domain before adding.": "Vários ativos têm um código similar, verifique o domínio antes de adicionar.", "must be at least": "deve ser pelo menos", @@ -484,6 +485,7 @@ "Read before importing your key": "Leia antes de importar sua chave", "Ready to migrate": "Pronto para migrar", "Receive funds from another wallet": "Receber fundos de outra carteira", + "Receive USDT0": "Receber USDT0", "Received": "Recebido", "Recent": "Recentes", "Recents": "Recentes", @@ -699,8 +701,7 @@ "Transaction Timeout": "Tempo Limite da Transação", "Transfer from another account": "Transferir de outra conta", "Transfer from Coinbase & other options": "Transferir do Coinbase e outras opções", - "Transfer USDT between Stellar and supported networks.": "Transfira USDT entre a Stellar e redes suportadas.", - "Transfer USDT0": "Transferir USDT0", + "Transfer USDT0 between Stellar and supported networks.": "Transfira USDT0 entre a Stellar e redes suportadas.", "Trending": "Em alta", "trustlines": "linhas de confiança", "Trustor": "Fidedigno", @@ -730,7 +731,7 @@ "Upload Contract Wasm": "Carregar Wasm do Contrato", "Usage data sharing": "Compartilhamento de dados de uso", "USDT0": "USDT0", - "USDT0 is backed 1:1 by USDT, without fragmented wrapped versions.": "USDT0 tem lastro 1:1 em USDT, sem versões wrapped fragmentadas.", + "USDT0 is backed 1:1 by USDT.": "USDT0 tem lastro 1:1 em USDT.", "USDT0 is live on Stellar": "USDT0 chegou na Stellar", "USDT0 is now on Stellar": "USDT0 agora na Stellar", "Use caution when connecting to domains without an SSL certificate.": "Use cautela ao se conectar a domínios sem um certificado SSL.", From bda0c8464370b989d2bcf292fc3c70ef5f817e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Tue, 1 Sep 2026 18:21:02 -0700 Subject: [PATCH 13/22] fix: restore 32px clearance above the USDT0 sheet footer The two-button footer is 44px taller than the single CTA it replaced, so the fixed hero offset left only ~24px above "Receive USDT0" in the 600px popup; start the content 8px higher to match the design. Co-Authored-By: Claude Fable 5 --- .../account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss index 8091cf3b33..202abafcc1 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss @@ -109,11 +109,12 @@ align-items: center; // Content flows right below the hero art instead of anchoring to the // bottom, so taller viewports (sidebar mode) leave the extra space - // between the features and the footer button. The top padding clears + // between the features and the footer buttons. The top padding clears // the absolutely-positioned hero (arcs end 257px from the sheet top, - // the body starts at 80px), reproducing the 600px-popup layout. + // the body starts at 80px), reproducing the 600px-popup layout with + // the design's 32px clearance above the footer. justify-content: flex-start; - padding: pxToRem(188px) pxToRem(24px) 0; + padding: pxToRem(180px) pxToRem(24px) 0; gap: pxToRem(32px); } From 61b4e505c4f7d2f8aef2001bfba3997ea23cd793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Tue, 1 Sep 2026 18:26:30 -0700 Subject: [PATCH 14/22] fix: reuse the QR screen's BackButton for the USDT0 sheet close Render the shared BackButton (via customButtonComponent, keeping a semantic + {/* Same BackButton as the QR code screen's X, supplied as a real + + } + />
diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss index 202abafcc1..6208541ccb 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss @@ -75,30 +75,24 @@ display: flex; flex-direction: column; height: 100%; - padding: pxToRem(24px) 0; + 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 +
diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss index 1415b2fd0e..dde28511d4 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss @@ -202,7 +202,7 @@ // Borderless text button per design — no SDS Button variant is // transparent, so it's hand-rolled like the close button - &__bridge { + &__transfer { background: none; border: none; cursor: pointer; diff --git a/extension/src/popup/locales/en/translation.json b/extension/src/popup/locales/en/translation.json index 706e196368..2dbd18ed10 100644 --- a/extension/src/popup/locales/en/translation.json +++ b/extension/src/popup/locales/en/translation.json @@ -96,7 +96,6 @@ "Blockaid Response Override": "Blockaid Response Override", "Blockaid unfunded destination": "This is a new account and needs 1 XLM in order to get started. Any transaction to send non-XLM to an unfunded account will fail.", "Blockaid unfunded destination native": "This is a new account and needs at least 1 XLM to be created. Sending less than 1 XLM to create it will fail.", - "Bridge to Stellar": "Bridge to Stellar", "Bump To": "Bump To", "Buy Amount": "Buy Amount", "Buy with Coinbase": "Buy with Coinbase", @@ -605,6 +604,7 @@ "Swap Settings": "Swap Settings", "Swap source token logo": "Swap source token logo", "Swap to": "Swap to", + "Swap to USDT0": "Swap to USDT0", "Swapped!": "Swapped!", "Swapping": "Swapping", "Switch to this network": "Switch to this network", @@ -701,6 +701,7 @@ "Transaction Timeout": "Transaction Timeout", "Transfer from another account": "Transfer from another account", "Transfer from Coinbase & other options": "Transfer from Coinbase & other options", + "Transfer to Stellar": "Transfer to Stellar", "Transfer USDT0 between Stellar and supported networks.": "Transfer USDT0 between Stellar and supported networks.", "Trending": "Trending", "trustlines": "trustlines", diff --git a/extension/src/popup/locales/pt/translation.json b/extension/src/popup/locales/pt/translation.json index 1aeb454128..464ae1a4c3 100644 --- a/extension/src/popup/locales/pt/translation.json +++ b/extension/src/popup/locales/pt/translation.json @@ -96,7 +96,6 @@ "Blockaid Response Override": "Substituição de Resposta do Blockaid", "Blockaid unfunded destination": "Esta é uma nova conta e precisa de 1 XLM para começar. Qualquer transação para enviar não-XLM para uma conta não financiada falhará.", "Blockaid unfunded destination native": "Esta é uma nova conta e precisa de pelo menos 1 XLM para ser criada. Enviar menos de 1 XLM para criá-la falhará.", - "Bridge to Stellar": "Bridge para Stellar", "Bump To": "Bump Para", "Buy Amount": "Quantia de Compra", "Buy with Coinbase": "Comprar com Coinbase", @@ -605,6 +604,7 @@ "Swap Settings": "Configurações de Troca", "Swap source token logo": "Logotipo do token de origem da troca", "Swap to": "Trocar para", + "Swap to USDT0": "Trocar para USDT0", "Swapped!": "Trocado!", "Swapping": "Trocando", "Switch to this network": "Alternar para esta rede", @@ -701,6 +701,7 @@ "Transaction Timeout": "Tempo Limite da Transação", "Transfer from another account": "Transferir de outra conta", "Transfer from Coinbase & other options": "Transferir do Coinbase e outras opções", + "Transfer to Stellar": "Transferir para Stellar", "Transfer USDT0 between Stellar and supported networks.": "Transfira USDT0 entre a Stellar e redes suportadas.", "Trending": "Em alta", "trustlines": "linhas de confiança", From a26d1d991b8c018054c6a60d2533112cc5a2b8b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Wed, 2 Sep 2026 13:28:35 -0700 Subject: [PATCH 21/22] fix: fit all three USDT0 sheet actions in the 600px popup The third button pushed the footer past the popup, so the last action needed a scroll to reach. Raise the copy column (body top padding 148px -> 88px, the most the height budget allows) and give the borderless action the design's 6px vertical padding. The hero lockup is absolutely positioned, so the "USDT0" title stays where it is. Co-Authored-By: Claude Fable 5 --- .../Usdt0LaunchSheet/styles.scss | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss index dde28511d4..5c6f914ca9 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss @@ -110,13 +110,15 @@ align-items: center; // Content flows right below the hero art instead of anchoring to the // bottom, so taller viewports (sidebar mode) leave the extra space - // between the features and the footer buttons. The top padding clears - // the absolutely-positioned hero (arcs end 257px from the sheet top, - // the body starts at 112px after the 80px header and 32px gap), - // reproducing the 600px-popup layout with the design's 32px clearance - // above the footer. + // between the features and the footer buttons. + // + // The top padding is what fits the three footer actions in the 600px + // popup without scrolling: 80 (header) + 64 (two 32px column gaps) + + // 128 (footer) + 24 (bottom padding) = 296px of chrome, plus 212px of + // copy, leaves 92px. The USDT0 lockup stays put — it belongs to the + // absolutely-positioned hero. justify-content: flex-start; - padding: pxToRem(148px) pxToRem(24px) 0; + padding: pxToRem(88px) pxToRem(24px) 0; gap: pxToRem(32px); } @@ -211,7 +213,7 @@ justify-content: center; gap: pxToRem(4px); width: 100%; - padding: pxToRem(8px) pxToRem(12px); + padding: pxToRem(6px) pxToRem(12px); border-radius: pxToRem(100px); color: var(--sds-clr-gray-12); font-family: inherit; From 08f040ffe3ec68dcbed8cfd39632a9ab975613e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Wed, 2 Sep 2026 13:30:36 -0700 Subject: [PATCH 22/22] fix: size the Transfer to Stellar action like the lg buttons above it Mirrors the SDS lg metrics (40px tall, 8px/12px padding, 14/22 text) on the hand-rolled borderless button, and takes the extra 8px back from the copy column so the three actions still clear the 600px popup. Co-Authored-By: Claude Fable 5 --- .../Usdt0LaunchSheet/styles.scss | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss index 5c6f914ca9..c94a0676f1 100644 --- a/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss +++ b/extension/src/popup/components/account/Usdt0LaunchBanner/Usdt0LaunchSheet/styles.scss @@ -114,11 +114,11 @@ // // The top padding is what fits the three footer actions in the 600px // popup without scrolling: 80 (header) + 64 (two 32px column gaps) + - // 128 (footer) + 24 (bottom padding) = 296px of chrome, plus 212px of - // copy, leaves 92px. The USDT0 lockup stays put — it belongs to the + // 136 (footer) + 24 (bottom padding) = 304px of chrome, plus 212px of + // copy, leaves 84px. The USDT0 lockup stays put — it belongs to the // absolutely-positioned hero. justify-content: flex-start; - padding: pxToRem(88px) pxToRem(24px) 0; + padding: pxToRem(80px) pxToRem(24px) 0; gap: pxToRem(32px); } @@ -203,7 +203,9 @@ } // Borderless text button per design — no SDS Button variant is - // transparent, so it's hand-rolled like the close button + // transparent, so it's hand-rolled like the close button, mirroring the + // SDS `lg` metrics (40px tall, 8px/12px padding, 14/22 text) of the two + // buttons above it &__transfer { background: none; border: none; @@ -213,13 +215,14 @@ justify-content: center; gap: pxToRem(4px); width: 100%; - padding: pxToRem(6px) pxToRem(12px); + height: pxToRem(40px); + padding: pxToRem(8px) pxToRem(12px); border-radius: pxToRem(100px); color: var(--sds-clr-gray-12); font-family: inherit; font-size: pxToRem(14px); font-weight: var(--sds-fw-semi-bold); - line-height: pxToRem(20px); + line-height: pxToRem(22px); &:hover { background: rgba(255, 255, 255, 0.1);