Skip to content

Commit 7e442a4

Browse files
committed
[MNY-328] Dashboard: Add Bridge iframe page (#8525)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR primarily enhances the `bridge` functionality by introducing iframe support, updating component structures, and modifying environment variables. It also includes changes in layout and security policies related to the `bridge` feature. ### Detailed summary - Added `NEXT_PUBLIC_BRIDGE_IFRAME_CLIENT_ID` to environment variables. - Modified `BridgeProviders` to accept `clientId` and `forcedTheme`. - Updated `UniversalBridgeEmbed` to use dynamic `pageType`. - Created a new layout for `BridgeEmbedLayout`. - Enhanced security headers for `/bridge/embed`. - Refactored imports and paths for `data` and components. - Added `bridge-iframe` to `pageType` types across multiple files. - Implemented new parsing logic for search parameters in the iframe page. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a new /bridge/embed page to support an embeddable bridge iframe and a "bridge-iframe" flow. * **Security** * Updated content security headers and frame-ancestor rules to allow safe embedding of the bridge iframe. * **Chores** * Added environment variable for the bridge iframe client ID. * Simplified theme behavior to rely on the default dark theme. * **Analytics** * Added "bridge-iframe" page type to reporting to track iframe usage. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent a5b8885 commit 7e442a4

File tree

26 files changed

+232
-46
lines changed

26 files changed

+232
-46
lines changed

apps/dashboard/.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,6 @@ ANALYTICS_SERVICE_URL=""
6666
STRIPE_SECRET_KEY=""
6767
GROWTH_PLAN_SKU=""
6868
PAYMENT_METHOD_CONFIGURATION=""
69+
70+
# required for bridge iframe (/bridge/embed) page
71+
NEXT_PUBLIC_BRIDGE_IFRAME_CLIENT_ID=""

apps/dashboard/next.config.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ const ContentSecurityPolicy = `
1818
block-all-mixed-content;
1919
`;
2020

21+
const EmbedContentSecurityPolicy = `
22+
${ContentSecurityPolicy}
23+
frame-ancestors *;
24+
`;
25+
2126
const securityHeaders = [
2227
{
2328
key: "X-DNS-Prefetch-Control",
@@ -138,6 +143,24 @@ const baseNextConfig: NextConfig = {
138143
// Apply these headers to all routes in your application.
139144
source: "/(.*)",
140145
},
146+
{
147+
headers: [
148+
{
149+
key: "Content-Security-Policy",
150+
value: EmbedContentSecurityPolicy.replace(/\s{2,}/g, " ").trim(),
151+
},
152+
],
153+
source: "/bridge/embed",
154+
},
155+
{
156+
headers: [
157+
{
158+
key: "Content-Security-Policy",
159+
value: EmbedContentSecurityPolicy.replace(/\s{2,}/g, " ").trim(),
160+
},
161+
],
162+
source: "/bridge/embed/:path*",
163+
},
141164
];
142165
},
143166
images: {

apps/dashboard/src/@/analytics/report.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,13 @@ type TokenSwapParams = {
232232
buyTokenAddress: string;
233233
sellTokenChainId: number;
234234
sellTokenAddress: string;
235-
pageType: "asset" | "bridge" | "chain";
235+
pageType: "asset" | "bridge" | "chain" | "bridge-iframe";
236236
};
237237

238238
type TokenBuyParams = {
239239
buyTokenChainId: number | undefined;
240240
buyTokenAddress: string | undefined;
241-
pageType: "asset" | "bridge" | "chain";
241+
pageType: "asset" | "bridge" | "chain" | "bridge-iframe";
242242
};
243243

244244
/**
@@ -298,7 +298,7 @@ export function reportTokenSwapSuccessful(properties: TokenSwapParams) {
298298
* @MananTank
299299
*/
300300
export function reportSwapWidgetShown(properties: {
301-
pageType: "asset" | "bridge" | "chain";
301+
pageType: "asset" | "bridge" | "chain" | "bridge-iframe";
302302
}) {
303303
posthog.capture("swap widget shown", properties);
304304
}

apps/dashboard/src/@/components/blocks/BuyAndSwapEmbed.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
import { Button } from "@/components/ui/button";
2222
import {
2323
NEXT_PUBLIC_ASSET_PAGE_CLIENT_ID,
24+
NEXT_PUBLIC_BRIDGE_IFRAME_CLIENT_ID,
2425
NEXT_PUBLIC_BRIDGE_PAGE_CLIENT_ID,
2526
NEXT_PUBLIC_CHAIN_PAGE_CLIENT_ID,
2627
} from "@/constants/public-envs";
@@ -30,7 +31,7 @@ import { getSDKTheme } from "@/utils/sdk-component-theme";
3031
import { appMetadata } from "../../constants/connect";
3132
import { getConfiguredThirdwebClient } from "../../constants/thirdweb.server";
3233

33-
type PageType = "asset" | "bridge" | "chain";
34+
type PageType = "asset" | "bridge" | "chain" | "bridge-iframe";
3435

3536
export type BuyAndSwapEmbedProps = {
3637
buyTab:
@@ -92,7 +93,9 @@ export function BuyAndSwapEmbed(props: BuyAndSwapEmbedProps) {
9293
? NEXT_PUBLIC_BRIDGE_PAGE_CLIENT_ID
9394
: props.pageType === "chain"
9495
? NEXT_PUBLIC_CHAIN_PAGE_CLIENT_ID
95-
: undefined,
96+
: props.pageType === "bridge-iframe"
97+
? NEXT_PUBLIC_BRIDGE_IFRAME_CLIENT_ID
98+
: undefined,
9699
secretKey: undefined,
97100
teamId: undefined,
98101
});

apps/dashboard/src/@/constants/public-envs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,6 @@ export const NEXT_PUBLIC_CHAIN_PAGE_CLIENT_ID =
4141

4242
export const NEXT_PUBLIC_ASSET_PAGE_CLIENT_ID =
4343
process.env.NEXT_PUBLIC_ASSET_PAGE_CLIENT_ID;
44+
45+
export const NEXT_PUBLIC_BRIDGE_IFRAME_CLIENT_ID =
46+
process.env.NEXT_PUBLIC_BRIDGE_IFRAME_CLIENT_ID;

apps/dashboard/src/app/(app)/(dashboard)/tokens/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { Metadata } from "next";
33
import { unstable_cache } from "next/cache";
44
import { Bridge } from "thirdweb";
55
import { serverThirdwebClient } from "@/constants/thirdweb-client.server";
6-
import { bridgeStats } from "../../../bridge/data";
6+
import { bridgeStats } from "../../../bridge/(general)/data";
77
import { PageHeader } from "./components/header";
88
import { TokenPage } from "./components/token-page";
99

apps/dashboard/src/app/(app)/providers.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"use client";
22

33
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4-
import { usePathname } from "next/navigation";
54
import { ThemeProvider } from "next-themes";
65
import { NuqsAdapter } from "nuqs/adapters/next/app";
76
import { useEffect, useMemo } from "react";
@@ -25,9 +24,6 @@ export function AppRouterProviders(props: {
2524
children: React.ReactNode;
2625
autoConnect: boolean;
2726
}) {
28-
// get the current pathname
29-
const pathname = usePathname();
30-
3127
return (
3228
<NuqsAdapter>
3329
<QueryClientProvider client={queryClient}>
@@ -40,9 +36,6 @@ export function AppRouterProviders(props: {
4036
defaultTheme="dark"
4137
disableTransitionOnChange
4238
enableSystem={false}
43-
forcedTheme={
44-
pathname.startsWith("/get-started") ? "dark" : undefined
45-
}
4639
>
4740
<Toaster richColors />
4841
<SanctionedAddressesChecker>
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)