diff --git a/apps/dashboard/src/app/bridge/swap-widget/SwapWidgetEmbed.client.tsx b/apps/dashboard/src/app/bridge/swap-widget/SwapWidgetEmbed.client.tsx index a8836d29550..40c4b6cb475 100644 --- a/apps/dashboard/src/app/bridge/swap-widget/SwapWidgetEmbed.client.tsx +++ b/apps/dashboard/src/app/bridge/swap-widget/SwapWidgetEmbed.client.tsx @@ -16,6 +16,7 @@ export function SwapWidgetEmbed({ showThirdwebBranding, theme, currency, + persistTokenSelections, }: { buyChainId?: number; buyTokenAddress?: Address; @@ -26,6 +27,7 @@ export function SwapWidgetEmbed({ showThirdwebBranding?: boolean; theme: "light" | "dark"; currency?: SupportedFiatCurrency; + persistTokenSelections?: boolean; }) { const client = useMemo( () => @@ -77,6 +79,7 @@ export function SwapWidgetEmbed({ showThirdwebBranding={showThirdwebBranding} theme={theme} currency={currency} + persistTokenSelections={persistTokenSelections} onSuccess={() => { sendMessageToParent({ source: "swap-widget", diff --git a/apps/dashboard/src/app/bridge/swap-widget/page.tsx b/apps/dashboard/src/app/bridge/swap-widget/page.tsx index 622f57f8d02..dbd1d80a38f 100644 --- a/apps/dashboard/src/app/bridge/swap-widget/page.tsx +++ b/apps/dashboard/src/app/bridge/swap-widget/page.tsx @@ -51,7 +51,14 @@ export default async function Page(props: { // Optional params const showThirdwebBranding = parseQueryParams( searchParams.showThirdwebBranding, - (v) => v !== "false", + // biome-ignore lint/complexity/noUselessTernary: this is easier to understand + (v) => (v === "false" ? false : true), + ); + + const persistTokenSelections = parseQueryParams( + searchParams.persistTokenSelections, + // biome-ignore lint/complexity/noUselessTernary: this is easier to understand + (v) => (v === "false" ? false : true), ); const theme = @@ -76,6 +83,7 @@ export default async function Page(props: { showThirdwebBranding={showThirdwebBranding} theme={theme} currency={currency} + persistTokenSelections={persistTokenSelections} /> diff --git a/apps/playground-web/src/app/bridge/swap-widget/components/buildSwapIframeUrl.ts b/apps/playground-web/src/app/bridge/swap-widget/components/buildSwapIframeUrl.ts new file mode 100644 index 00000000000..ab16f579b87 --- /dev/null +++ b/apps/playground-web/src/app/bridge/swap-widget/components/buildSwapIframeUrl.ts @@ -0,0 +1,67 @@ +import type { SwapWidgetPlaygroundOptions } from "./types"; + +const SWAP_WIDGET_IFRAME_BASE_URL = "https://thirdweb.com/bridge/swap-widget"; + +export function buildSwapIframeUrl( + options: SwapWidgetPlaygroundOptions, + type: "code" | "preview" = "preview", +) { + const url = new URL(SWAP_WIDGET_IFRAME_BASE_URL); + + if (type === "preview") { + // always set it to false so playground doesn't show last used tokens + url.searchParams.set("persistTokenSelections", "false"); + } + + // Buy token params + if (options.prefill?.buyToken?.chainId) { + url.searchParams.set("buyChain", String(options.prefill.buyToken.chainId)); + + if (options.prefill.buyToken.tokenAddress) { + url.searchParams.set( + "buyTokenAddress", + options.prefill.buyToken.tokenAddress, + ); + } + + if (options.prefill.buyToken.amount) { + url.searchParams.set("buyAmount", options.prefill.buyToken.amount); + } + } + + // Sell token params + if (options.prefill?.sellToken?.chainId) { + url.searchParams.set( + "sellChain", + String(options.prefill.sellToken.chainId), + ); + + if (options.prefill.sellToken.tokenAddress) { + url.searchParams.set( + "sellTokenAddress", + options.prefill.sellToken.tokenAddress, + ); + } + + if (options.prefill.sellToken.amount) { + url.searchParams.set("sellAmount", options.prefill.sellToken.amount); + } + } + + // Theme (only add if light, dark is default) + if (options.theme.type === "light") { + url.searchParams.set("theme", "light"); + } + + // Currency (only add if not USD, USD is default) + if (options.currency && options.currency !== "USD") { + url.searchParams.set("currency", options.currency); + } + + // Branding + if (options.showThirdwebBranding === false) { + url.searchParams.set("showThirdwebBranding", "false"); + } + + return url.toString(); +} diff --git a/apps/playground-web/src/app/bridge/swap-widget/components/code.tsx b/apps/playground-web/src/app/bridge/swap-widget/components/code.tsx index 9e76d15b36f..9854a9339ac 100644 --- a/apps/playground-web/src/app/bridge/swap-widget/components/code.tsx +++ b/apps/playground-web/src/app/bridge/swap-widget/components/code.tsx @@ -1,6 +1,7 @@ import { lazy, Suspense } from "react"; import { LoadingDots } from "@/components/ui/LoadingDots"; import { quotes, stringifyImports, stringifyProps } from "@/lib/code-gen"; +import { buildSwapIframeUrl } from "./buildSwapIframeUrl"; import type { SwapWidgetPlaygroundOptions } from "./types"; const CodeClient = lazy(() => @@ -18,16 +19,35 @@ function CodeLoading() { } export function CodeGen(props: { options: SwapWidgetPlaygroundOptions }) { + const code = + props.options.integrationType === "iframe" + ? getIframeCode(props.options) + : getReactCode(props.options); + + const lang = props.options.integrationType === "iframe" ? "html" : "ts"; + return (
}> - +
); } -function getCode(options: SwapWidgetPlaygroundOptions) { +function getIframeCode(options: SwapWidgetPlaygroundOptions) { + // Use "code" type to exclude persistTokenSelections from the generated code + const iframeUrl = buildSwapIframeUrl(options, "code"); + + return `