diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/PageHeader.tsx b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/PageHeader.tsx
new file mode 100644
index 00000000000..593b8e1fe8a
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/PageHeader.tsx
@@ -0,0 +1,24 @@
+import { TrackedLinkTW } from "@/components/ui/tracked-link";
+
+export function PageHeader() {
+ return (
+
+
In-App Wallets
+
+
+ A wallet infrastructure that enables apps to create, manage, and control
+ their users wallets. Email login, social login, and bring-your-own auth
+ supported.{" "}
+
+ Learn more
+
+
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/[clientId]/page.tsx b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/[clientId]/page.tsx
new file mode 100644
index 00000000000..2b928b9944f
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/[clientId]/page.tsx
@@ -0,0 +1,50 @@
+import { redirect } from "next/navigation";
+import { EmbeddedWallets } from "../../../../../../components/embedded-wallets";
+import { getAuthToken } from "../../../../../api/lib/getAuthToken";
+import { PageHeader } from "../PageHeader";
+import { getInAppWalletSupportedAPIKeys } from "../getInAppWalletSupportedAPIKeys";
+import { InAppWalletsAPIKeysMenu } from "../inAppWalletsAPIKeysMenu";
+
+export default async function Page(props: {
+ params: {
+ clientId: string;
+ };
+ searchParams: {
+ tab?: string;
+ };
+}) {
+ const authToken = getAuthToken();
+ const { clientId } = props.params;
+
+ if (!authToken) {
+ redirect(
+ `/login?next=${encodeURIComponent(`/dashboard/connect/in-app-wallets/${clientId}`)}`,
+ );
+ }
+
+ const apiKeys = await getInAppWalletSupportedAPIKeys();
+ const apiKey = apiKeys.find((key) => key.key === clientId);
+
+ if (!apiKey) {
+ redirect("/dashboard/connect/in-app-wallets");
+ }
+
+ return (
+
+ {/* header */}
+
+
+
+
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/getInAppWalletSupportedAPIKeys.ts b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/getInAppWalletSupportedAPIKeys.ts
new file mode 100644
index 00000000000..5c8454b4235
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/getInAppWalletSupportedAPIKeys.ts
@@ -0,0 +1,7 @@
+import { getApiKeys } from "../../../../api/lib/getAPIKeys";
+
+export async function getInAppWalletSupportedAPIKeys() {
+ return (await getApiKeys()).filter((key) => {
+ return !!(key.services || []).find((srv) => srv.name === "embeddedWallets");
+ });
+}
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/inAppWalletsAPIKeysMenu.tsx b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/inAppWalletsAPIKeysMenu.tsx
new file mode 100644
index 00000000000..9d1ee930bcf
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/inAppWalletsAPIKeysMenu.tsx
@@ -0,0 +1,21 @@
+"use client";
+
+import { useDashboardRouter } from "@/lib/DashboardRouter";
+import type { ApiKey } from "@3rdweb-sdk/react/hooks/useApi";
+import { ApiKeysMenu } from "../../../../../components/settings/ApiKeys/Menu";
+
+export function InAppWalletsAPIKeysMenu(props: {
+ apiKeys: Pick[];
+ selectedAPIKey: Pick;
+}) {
+ const router = useDashboardRouter();
+ return (
+ {
+ router.push(`/dashboard/connect/in-app-wallets/${key.key}`);
+ }}
+ />
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/layout.tsx b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/layout.tsx
new file mode 100644
index 00000000000..2c9758c30e2
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/layout.tsx
@@ -0,0 +1,17 @@
+import { AnalyticsCallout } from "../../../../team/[team_slug]/[project_slug]/connect/in-app-wallets/_components/AnalyticsCallout";
+import { InAppWaletFooterSection } from "../../../../team/[team_slug]/[project_slug]/connect/in-app-wallets/_components/footer";
+
+export default function Layout(props: {
+ children: React.ReactNode;
+}) {
+ return (
+
+ {props.children}
+
+ {/* Footer */}
+
+
+
+
+ );
+}
diff --git a/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/page.tsx b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/page.tsx
new file mode 100644
index 00000000000..c4d75d74e9c
--- /dev/null
+++ b/apps/dashboard/src/app/(dashboard)/dashboard/connect/in-app-wallets/page.tsx
@@ -0,0 +1,30 @@
+import { redirect } from "next/navigation";
+import { NoApiKeys } from "../../../../../components/settings/ApiKeys/NoApiKeys";
+import { getAuthToken } from "../../../../api/lib/getAuthToken";
+import { PageHeader } from "./PageHeader";
+import { getInAppWalletSupportedAPIKeys } from "./getInAppWalletSupportedAPIKeys";
+
+export default async function Page() {
+ const authToken = getAuthToken();
+
+ if (!authToken) {
+ redirect(
+ `/login?next=${encodeURIComponent("/dashboard/connect/in-app-wallets")}`,
+ );
+ }
+
+ const apiKeys = await getInAppWalletSupportedAPIKeys();
+ const firstKey = apiKeys[0];
+
+ if (firstKey) {
+ redirect(`/dashboard/connect/in-app-wallets/${firstKey.key}`);
+ }
+
+ return (
+
+ );
+}
diff --git a/apps/dashboard/src/components/embedded-wallets/index.tsx b/apps/dashboard/src/components/embedded-wallets/index.tsx
index 8f292be8898..6c6ce2a84c3 100644
--- a/apps/dashboard/src/components/embedded-wallets/index.tsx
+++ b/apps/dashboard/src/components/embedded-wallets/index.tsx
@@ -2,7 +2,6 @@
import { TabButtons } from "@/components/ui/tabs";
import type { ApiKey } from "@3rdweb-sdk/react/hooks/useApi";
-import { useSearchParams } from "next/navigation";
import { useState } from "react";
import { InAppWalletSettingsPage } from "./Configure";
import { InAppWalletUsersPageContent } from "./Users";
@@ -19,16 +18,16 @@ interface EmbeddedWalletsProps {
| "key"
>;
trackingCategory: string;
+ defaultTab: 0 | 1;
}
export const EmbeddedWallets: React.FC = ({
apiKey,
trackingCategory,
+ defaultTab,
}) => {
- const searchParams = useSearchParams();
- const defaultTabIndex = searchParams?.get("tab") === "1" ? 1 : 0;
const [selectedTab, setSelectedTab] = useState<"users" | "config">(
- defaultTabIndex === 0 ? "users" : "config",
+ defaultTab === 0 ? "users" : "config",
);
function updateSearchParams(value: string) {
diff --git a/apps/dashboard/src/page-id.ts b/apps/dashboard/src/page-id.ts
index 02ee6d12492..dd488d90025 100644
--- a/apps/dashboard/src/page-id.ts
+++ b/apps/dashboard/src/page-id.ts
@@ -98,8 +98,6 @@ export enum PageId {
// thirdweb.com/dashboard/connect/smart-wallet
DashboardConnectAccountAbstraction = "dashboard-wallets-smart-wallet",
- // thirdweb.com/dashboard/connect/embedded
- DashboardConnectEmbeddedWallets = "dashboard-wallets-embedded",
// thirdweb.com/dashboard/contracts/build
DashboardContractsBuild = "dashboard-contracts-build",
diff --git a/apps/dashboard/src/pages/dashboard/connect/in-app-wallets.tsx b/apps/dashboard/src/pages/dashboard/connect/in-app-wallets.tsx
deleted file mode 100644
index 8176ac64831..00000000000
--- a/apps/dashboard/src/pages/dashboard/connect/in-app-wallets.tsx
+++ /dev/null
@@ -1,137 +0,0 @@
-import { Spinner } from "@/components/ui/Spinner/Spinner";
-import { TrackedLinkTW } from "@/components/ui/tracked-link";
-import { type ApiKey, useApiKeys } from "@3rdweb-sdk/react/hooks/useApi";
-import { useLoggedInUser } from "@3rdweb-sdk/react/hooks/useLoggedInUser";
-import { AppLayout } from "components/app-layouts/app";
-import { EmbeddedWallets } from "components/embedded-wallets";
-import { ApiKeysMenu } from "components/settings/ApiKeys/Menu";
-import { NoApiKeys } from "components/settings/ApiKeys/NoApiKeys";
-// import { ConnectSidebar } from "core-ui/sidebar/connect";
-import { useRouter } from "next/router";
-import { PageId } from "page-id";
-import { useMemo, useState } from "react";
-import type { ThirdwebNextPage } from "utils/types";
-import { ConnectSidebarLayout } from "../../../app/(dashboard)/dashboard/connect/DashboardConnectLayout";
-import { AnalyticsCallout } from "../../../app/team/[team_slug]/[project_slug]/connect/in-app-wallets/_components/AnalyticsCallout";
-import { InAppWaletFooterSection } from "../../../app/team/[team_slug]/[project_slug]/connect/in-app-wallets/_components/footer";
-
-const TRACKING_CATEGORY = "embedded-wallet";
-
-const DashboardConnectEmbeddedWallets: ThirdwebNextPage = () => {
- const router = useRouter();
- const defaultClientId = router.query.clientId?.toString();
- const { isPending } = useLoggedInUser();
- const keysQuery = useApiKeys();
-
- const [selectedKey_, setSelectedKey] = useState();
-
- const apiKeys = useMemo(() => {
- return (keysQuery?.data || []).filter((key) => {
- return !!(key.services || []).find(
- (srv) => srv.name === "embeddedWallets",
- );
- });
- }, [keysQuery]);
-
- const hasApiKeys = apiKeys.length > 0;
-
- // compute the actual selected key based on if there is a state, if there is a query param, or otherwise the first one
- const selectedKey = useMemo(() => {
- if (selectedKey_) {
- return selectedKey_;
- }
- if (apiKeys.length) {
- if (defaultClientId) {
- return apiKeys.find((k) => k.key === defaultClientId);
- }
- return apiKeys[0];
- }
- return undefined;
- }, [apiKeys, defaultClientId, selectedKey_]);
-
- if (isPending) {
- return (
-
-
-
- );
- }
-
- return (
-
-
-
-
- In-App Wallets
-
-
-
-
-
- A wallet infrastructure that enables apps to create, manage, and
- control their users wallets. Email login, social login, and
- bring-your-own auth supported.{" "}
-
- Learn more
-
-
-
-
-
- {hasApiKeys && selectedKey && (
-
- )}
-
-
-
-
-
- {keysQuery.isPending ? (
-
-
-
- ) : (
- <>
- {!hasApiKeys &&
}
-
- {hasApiKeys && selectedKey && (
-
- )}
- >
- )}
-
-
-
-
-
-
-
- );
-};
-
-DashboardConnectEmbeddedWallets.getLayout = (page, props) => (
-
- {page}
-
-);
-
-DashboardConnectEmbeddedWallets.pageId = PageId.DashboardConnectEmbeddedWallets;
-
-export default DashboardConnectEmbeddedWallets;