diff --git a/.changeset/orange-snakes-stay.md b/.changeset/orange-snakes-stay.md
new file mode 100644
index 00000000..ae9e9fb9
--- /dev/null
+++ b/.changeset/orange-snakes-stay.md
@@ -0,0 +1,5 @@
+---
+"@stakekit/widget": patch
+---
+
+feat: ledger live usde banner
diff --git a/package.json b/package.json
index 69b389f7..f26d8bfa 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
"knip": "^5.57.1",
"turbo": "^2.5.3"
},
- "packageManager": "pnpm@10.11.0",
+ "packageManager": "pnpm@10.11.1",
"pnpm": {
"overrides": {
"@types/react": "19.0.10",
diff --git a/packages/widget/src/components/atoms/icons/balance.tsx b/packages/widget/src/components/atoms/icons/balance.tsx
new file mode 100644
index 00000000..67614113
--- /dev/null
+++ b/packages/widget/src/components/atoms/icons/balance.tsx
@@ -0,0 +1,17 @@
+export const Balance = () => (
+
+);
diff --git a/packages/widget/src/domain/types/tokens.ts b/packages/widget/src/domain/types/tokens.ts
index 05a59ab4..92af25e3 100644
--- a/packages/widget/src/domain/types/tokens.ts
+++ b/packages/widget/src/domain/types/tokens.ts
@@ -1,3 +1,7 @@
-import type { TokenDto } from "@stakekit/api-hooks";
+import { EvmNetworks, type TokenDto } from "@stakekit/api-hooks";
export type TokenString = `${TokenDto["network"]}-${TokenDto["address"]}`;
+
+export const isUSDeToken = (token: TokenDto) =>
+ token.network === EvmNetworks.ethereum &&
+ token.address === "0x4c9edd5852cd905f086c759e8383e09bff1e68b3";
diff --git a/packages/widget/src/pages/details/earn-page/components/select-token-section/index.tsx b/packages/widget/src/pages/details/earn-page/components/select-token-section/index.tsx
index 53b5cc9a..b57fa750 100644
--- a/packages/widget/src/pages/details/earn-page/components/select-token-section/index.tsx
+++ b/packages/widget/src/pages/details/earn-page/components/select-token-section/index.tsx
@@ -1,11 +1,20 @@
import { Box, NumberInput, Text } from "@sk-widget/components";
import { ContentLoaderSquare } from "@sk-widget/components/atoms/content-loader";
+import { Balance } from "@sk-widget/components/atoms/icons/balance";
import { MaxButton } from "@sk-widget/components/atoms/max-button";
import * as AmountToggle from "@sk-widget/components/molecules/amount-toggle";
-import { priceTxt } from "@sk-widget/pages/details/earn-page/components/select-token-section/styles.css";
+import { isUSDeToken } from "@sk-widget/domain/types";
+import {
+ bottomBanner,
+ bottomBannerBottomRadius,
+ bottomBannerText,
+ priceTxt,
+} from "@sk-widget/pages/details/earn-page/components/select-token-section/styles.css";
import { useEarnPageContext } from "@sk-widget/pages/details/earn-page/state/earn-page-context";
import { useSettings } from "@sk-widget/providers/settings";
-import { Just } from "purify-ts";
+import { useSKWallet } from "@sk-widget/providers/sk-wallet";
+import clsx from "clsx";
+import { Just, Maybe } from "purify-ts";
import { useTranslation } from "react-i18next";
import { SelectToken } from "./select-token";
import { SelectTokenTitle } from "./title";
@@ -15,6 +24,8 @@ export const SelectTokenSection = () => {
const { variant } = useSettings();
+ const { isLedgerLive } = useSKWallet();
+
const {
appLoading,
selectedTokenAvailableAmount,
@@ -28,6 +39,7 @@ export const SelectTokenSection = () => {
stakeMinAmount,
symbol,
isStakeTokenSameAsGasToken,
+ selectedToken,
} = useEarnPageContext();
const isLoading = appLoading || selectTokenIsLoading;
@@ -50,6 +62,18 @@ export const SelectTokenSection = () => {
const errorBalance = stakeAmountGreaterThanAvailableAmount;
+ const showBottomUSDeBanner = Maybe.fromRecord({
+ selectedTokenAvailableAmount,
+ selectedToken,
+ })
+ .filter(
+ (val) =>
+ isLedgerLive &&
+ val.selectedTokenAvailableAmount.amount.isZero() &&
+ isUSDeToken(val.selectedToken)
+ )
+ .isJust();
+
const minStakeAmount = Just([
stakeMinAmount
.map((v) => `${t("shared.min")} ${v} ${symbol}`)
@@ -82,110 +106,133 @@ export const SelectTokenSection = () => {
) : (
-
- {variant === "zerion" && (
-
-
- {minStakeAmount}
-
- )}
-
-
-
-
-
-
-
-
-
-
-
- {variant !== "zerion" && minStakeAmount}
-
+
-
-
- {formattedPrice}
-
+ {variant === "zerion" && (
+
+
+ {minStakeAmount}
+
+ )}
+
+
+
+
+
+
+
+
+
+ {variant !== "zerion" && minStakeAmount}
+
-
-
- {selectedTokenAvailableAmount
- .map((v) =>
- variant === "zerion" ? (
- <>
- {t("shared.balance")}:
-
- {v.shortFormattedAmount} {v.symbol}
-
- >
- ) : (
-
-
- {({ state }) => (
-
- {state === "full"
- ? v.fullFormattedAmount
- : v.shortFormattedAmount}
- {v.symbol} {t("shared.available")}
-
- )}
-
-
- )
- )
- .extractNullable()}
+
+
+ {formattedPrice}
- {!isStakeTokenSameAsGasToken && }
+
+
+
+ {selectedTokenAvailableAmount
+ .map((v) =>
+ variant === "zerion" ? (
+ <>
+ {t("shared.balance")}:
+
+ {v.shortFormattedAmount} {v.symbol}
+
+ >
+ ) : (
+
+
+ {({ state }) => (
+
+ {state === "full"
+ ? v.fullFormattedAmount
+ : v.shortFormattedAmount}
+ {v.symbol} {t("shared.available")}
+
+ )}
+
+
+ )
+ )
+ .extractNullable()}
+
+
+
+ {!isStakeTokenSameAsGasToken && (
+
+ )}
+
+
+ {showBottomUSDeBanner && (
+
+
+
+ {t("select_token.usde_banner")}
+
+
+ )}
);
};
diff --git a/packages/widget/src/pages/details/earn-page/components/select-token-section/styles.css.ts b/packages/widget/src/pages/details/earn-page/components/select-token-section/styles.css.ts
index 5df027ce..9d592b2b 100644
--- a/packages/widget/src/pages/details/earn-page/components/select-token-section/styles.css.ts
+++ b/packages/widget/src/pages/details/earn-page/components/select-token-section/styles.css.ts
@@ -1,5 +1,25 @@
+import { atoms } from "@sk-widget/styles/theme";
import { style } from "@vanilla-extract/css";
export const priceTxt = style({
flexGrow: 999,
});
+
+export const bottomBannerBottomRadius = style({
+ borderBottomLeftRadius: 0,
+ borderBottomRightRadius: 0,
+});
+
+export const bottomBanner = style([
+ atoms({ borderRadius: "xl" }),
+ {
+ borderTopLeftRadius: 0,
+ borderTopRightRadius: 0,
+ background:
+ "linear-gradient(90deg, #4B2921 0%, #723426 25.78%, #994238 59.59%, #7C3C48 100%)",
+ },
+]);
+
+export const bottomBannerText = style({
+ fontSize: "12px",
+});
diff --git a/packages/widget/src/translation/English/translations.json b/packages/widget/src/translation/English/translations.json
index 2356c9c0..fd3d0757 100644
--- a/packages/widget/src/translation/English/translations.json
+++ b/packages/widget/src/translation/English/translations.json
@@ -458,7 +458,8 @@
},
"select_token": {
"title": "Select token",
- "n_available_opps": "{{count}} available opportunities"
+ "n_available_opps": "{{count}} available opportunities",
+ "usde_banner": "Missing USDe balance? Swap now and start earning!"
},
"referral_lock": {
"title": "Referral check",