From 6113f3da4e0baba7cfcb10ffd7a0dc6ab52ec209 Mon Sep 17 00:00:00 2001 From: Manan Tank Date: Thu, 19 Jun 2025 18:05:25 +0530 Subject: [PATCH] Dashboard Project sidebar changes --- .../blocks/UpsellBannerCard.stories.tsx | 6 - .../@/components/blocks/UpsellBannerCard.tsx | 2 - .../overview/ContractOverviewPage.tsx | 2 - .../_components/FreePlanUpsellBannerUI.tsx | 2 - .../[project_slug]/(sidebar)/assets/cards.tsx | 4 +- .../[project_slug]/(sidebar)/assets/page.tsx | 6 +- .../components/ProjectFTUX/ProjectFTUX.tsx | 25 +-- .../components/ProjectSidebarLayout.tsx | 24 +-- .../in-app-wallets/_components/header.tsx | 2 +- .../connect/in-app-wallets/_constants.ts | 1 - .../connect/in-app-wallets/users/page.tsx | 2 - .../engine/cloud/analytics/ftux.client.tsx | 2 +- .../cloud/analytics/tx-chart/tx-chart-ui.tsx | 2 +- .../(sidebar)/engine/cloud/layout.tsx | 8 +- .../create-server-wallet.client.tsx | 8 +- .../cloud/vault/components/key-management.tsx | 104 --------- .../engine/dedicated/(general)/layout.tsx | 4 +- .../analytics/fetch-nebula-analytics.tsx | 55 ----- .../analytics/nebula-analytics-filter.tsx | 51 ----- .../analytics/nebula-analytics-page.tsx | 115 ---------- .../analytics/nebula-analytics-ui.stories.tsx | 68 ------ .../analytics/nebula-analytics-ui.tsx | 203 ------------------ .../nebula/components/analytics/utils.ts | 13 -- .../(sidebar)/nebula/layout.tsx | 71 ------ .../(sidebar)/nebula/nebula-ftux.tsx | 102 --------- .../[project_slug]/(sidebar)/nebula/page.tsx | 79 ------- .../settings/ProjectGeneralSettingsPage.tsx | 4 +- .../create-vault-account.client.tsx | 15 +- .../vault/components/key-management.tsx | 86 ++++++++ .../components/list-access-tokens.client.tsx | 2 +- .../components/rotate-admin-key.client.tsx | 2 +- .../[project_slug]/(sidebar)/vault/layout.tsx | 33 +++ .../{engine/cloud => }/vault/page.tsx | 2 +- .../embedded-wallets/Users/index.tsx | 1 - apps/dashboard/src/lib/time.ts | 13 -- packages/service-utils/src/core/services.ts | 4 +- 36 files changed, 171 insertions(+), 952 deletions(-) delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_constants.ts delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/key-management.tsx delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/fetch-nebula-analytics.tsx delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-filter.tsx delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-page.tsx delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.stories.tsx delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/utils.ts delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/layout.tsx delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/nebula-ftux.tsx delete mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/page.tsx rename apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/{engine/cloud => }/vault/components/create-vault-account.client.tsx (97%) create mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/key-management.tsx rename apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/{engine/cloud => }/vault/components/list-access-tokens.client.tsx (99%) rename apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/{engine/cloud => }/vault/components/rotate-admin-key.client.tsx (99%) create mode 100644 apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/layout.tsx rename apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/{engine/cloud => }/vault/page.tsx (92%) diff --git a/apps/dashboard/src/@/components/blocks/UpsellBannerCard.stories.tsx b/apps/dashboard/src/@/components/blocks/UpsellBannerCard.stories.tsx index 5dbcfead7c7..b0e8a245843 100644 --- a/apps/dashboard/src/@/components/blocks/UpsellBannerCard.stories.tsx +++ b/apps/dashboard/src/@/components/blocks/UpsellBannerCard.stories.tsx @@ -15,8 +15,6 @@ function Story() { icon: , link: "#", }} - trackingCategory="storybook" - trackingLabel="green" icon={} accentColor="green" /> @@ -31,8 +29,6 @@ function Story() { icon: , link: "#", }} - trackingCategory="storybook" - trackingLabel="blue" icon={} accentColor="blue" /> @@ -47,8 +43,6 @@ function Story() { icon: , link: "#", }} - trackingCategory="storybook" - trackingLabel="purple" accentColor="purple" /> diff --git a/apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx b/apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx index 4693a4186cf..94b70a7164c 100644 --- a/apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx +++ b/apps/dashboard/src/@/components/blocks/UpsellBannerCard.tsx @@ -44,8 +44,6 @@ type UpsellBannerCardProps = { target?: "_blank"; link: string; }; - trackingCategory: string; - trackingLabel: string; accentColor?: keyof typeof ACCENT; icon?: React.ReactNode; }; diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx index 16a9a8df78e..3725d6941ae 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx @@ -53,8 +53,6 @@ export const ContractOverviewPage: React.FC = ({ target: "_blank", link: `/${chainSlug}/${contract.address}`, }} - trackingCategory="erc20-contract" - trackingLabel="view-asset-page" accentColor="blue" /> )} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/FreePlanUpsellBannerUI.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/FreePlanUpsellBannerUI.tsx index 857bd8e7036..7e76b086db5 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/FreePlanUpsellBannerUI.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/(team)/_components/FreePlanUpsellBannerUI.tsx @@ -24,8 +24,6 @@ export function FreePlanUpsellBannerUI(props: { props.highlightPlan || "growth" }`, }} - trackingCategory="billingBanner" - trackingLabel="freePlan_viewPlans" icon={} accentColor="green" /> diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx index e9fe1a4649d..78910d3b90d 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx @@ -62,8 +62,8 @@ export function Cards(props: { /> { diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx index f32490c1062..92299731b88 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/page.tsx @@ -53,9 +53,9 @@ export default async function Page(props: { />
-

Your assets

+

Your Tokens

- List of all assets created or imported into this project + List of all tokens created or imported into this project

@@ -79,7 +79,7 @@ function AssetsHeader() {

- Assets + Tokens

Create and Manage tokens for your project diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx index 1b70b3fd1e8..13bffaff6d6 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx @@ -9,15 +9,15 @@ import { TypeScriptIcon } from "components/icons/brand-icons/TypeScriptIcon"; import { UnityIcon } from "components/icons/brand-icons/UnityIcon"; import { UnrealIcon } from "components/icons/brand-icons/UnrealIcon"; import { + ArrowLeftRightIcon, ChevronRightIcon, CircleAlertIcon, ExternalLinkIcon, } from "lucide-react"; import Link from "next/link"; import { ContractIcon } from "../../../../../../(dashboard)/(chain)/components/server/icons/ContractIcon"; -import { EngineIcon } from "../../../../../../(dashboard)/(chain)/components/server/icons/EngineIcon"; import { InsightIcon } from "../../../../../../(dashboard)/(chain)/components/server/icons/InsightIcon"; -import { NebulaIcon } from "../../../../../../(dashboard)/(chain)/components/server/icons/NebulaIcon"; +import { PayIcon } from "../../../../../../(dashboard)/(chain)/components/server/icons/PayIcon"; import { ClientIDSection } from "./ClientIDSection"; import { IntegrateAPIKeyCodeTabs } from "./IntegrateAPIKeyCodeTabs"; import { SecretKeySection } from "./SecretKeySection"; @@ -233,15 +233,13 @@ function ProductsSection(props: { description: string; href: string; icon: React.FC<{ className?: string }>; - trackingLabel: string; }> = [ { - title: "Engine", + title: "Transactions", description: "Scale your application with a backend server to read, write, and deploy contracts at production-grade.", - href: `/team/${props.teamSlug}/${props.projectSlug}/engine`, - icon: EngineIcon, - trackingLabel: "engine", + href: `/team/${props.teamSlug}/${props.projectSlug}/transactions`, + icon: ArrowLeftRightIcon, }, { title: "Contracts", @@ -249,7 +247,6 @@ function ProductsSection(props: { "Deploy your own contracts or leverage existing solutions for onchain implementation", href: `/team/${props.teamSlug}/${props.projectSlug}/contracts`, icon: ContractIcon, - trackingLabel: "contracts", }, { title: "Insight", @@ -257,15 +254,13 @@ function ProductsSection(props: { "Add indexing capabilities to retrieve real-time onchain data", href: `/team/${props.teamSlug}/${props.projectSlug}/insight`, icon: InsightIcon, - trackingLabel: "insight", }, { - title: "Nebula", + title: "Universal Bridge", description: - "Integrate a blockchain AI model to improve your users insight into your application and the blockchain", - href: `/team/${props.teamSlug}/${props.projectSlug}/nebula`, - icon: NebulaIcon, - trackingLabel: "nebula", + "Bridge, swap, and purchase cryptocurrencies with any fiat options or tokens via cross-chain routing", + href: `/team/${props.teamSlug}/${props.projectSlug}/universal-bridge`, + icon: PayIcon, }, ]; @@ -290,7 +285,6 @@ function ProductsSection(props: { description={product.description} href={product.href} icon={product.icon} - trackingLabel={product.trackingLabel} /> ))} @@ -303,7 +297,6 @@ function ProductCard(props: { description: string; href: string; icon: React.FC<{ className?: string }>; - trackingLabel: string; }) { return (

diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectSidebarLayout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectSidebarLayout.tsx index 5d996d59355..d7102cb9df9 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectSidebarLayout.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectSidebarLayout.tsx @@ -2,18 +2,18 @@ import { FullWidthSidebarLayout } from "@/components/blocks/SidebarLayout"; import { Badge } from "@/components/ui/badge"; import { + ArrowLeftRightIcon, BellIcon, BookTextIcon, BoxIcon, CoinsIcon, HomeIcon, + LockIcon, SettingsIcon, WalletIcon, } from "lucide-react"; import { ContractIcon } from "../../../../../(dashboard)/(chain)/components/server/icons/ContractIcon"; -import { EngineIcon } from "../../../../../(dashboard)/(chain)/components/server/icons/EngineIcon"; import { InsightIcon } from "../../../../../(dashboard)/(chain)/components/server/icons/InsightIcon"; -import { NebulaIcon } from "../../../../../(dashboard)/(chain)/components/server/icons/NebulaIcon"; import { PayIcon } from "../../../../../(dashboard)/(chain)/components/server/icons/PayIcon"; import { SmartAccountIcon } from "../../../../../(dashboard)/(chain)/components/server/icons/SmartAccountIcon"; @@ -33,7 +33,7 @@ export function ProjectSidebarLayout(props: { icon: HomeIcon, }, { - label: "In-App Wallets", + label: "Wallets", href: `${layoutPath}/connect/in-app-wallets`, icon: WalletIcon, }, @@ -53,18 +53,18 @@ export function ProjectSidebarLayout(props: { icon: ContractIcon, }, { - href: `${layoutPath}/assets`, + href: `${layoutPath}/tokens`, label: ( - Assets New + Tokens New ), icon: CoinsIcon, }, { href: `${layoutPath}/engine`, - label: "Engine", - icon: EngineIcon, + label: "Transactions", + icon: ArrowLeftRightIcon, }, { href: `${layoutPath}/insight`, @@ -72,10 +72,12 @@ export function ProjectSidebarLayout(props: { icon: InsightIcon, }, { - href: `${layoutPath}/nebula`, - label: "Nebula", - icon: NebulaIcon, + href: `${layoutPath}/vault`, + label: "Vault", + icon: LockIcon, }, + ]} + footerSidebarLinks={[ { href: `${layoutPath}/webhooks`, label: ( @@ -85,8 +87,6 @@ export function ProjectSidebarLayout(props: { ), icon: BellIcon, }, - ]} - footerSidebarLinks={[ { href: `${layoutPath}/settings`, label: "Project Settings", diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/header.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/header.tsx index 30e106dd9fa..dc61c459979 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/header.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_components/header.tsx @@ -4,7 +4,7 @@ export async function InAppWalletsHeader() { return (

- In-App Wallets + Wallets

A wallet infrastructure that enables apps to create, manage, and control diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_constants.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_constants.ts deleted file mode 100644 index f50b20dd636..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/_constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const TRACKING_CATEGORY = "team/in-app-wallets"; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/users/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/users/page.tsx index 093558b4a71..a1f0ce5ed5b 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/users/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/users/page.tsx @@ -4,7 +4,6 @@ import { InAppWalletUsersPageContent } from "components/embedded-wallets/Users"; import { redirect } from "next/navigation"; import { getAuthToken } from "../../../../../../../api/lib/getAuthToken"; import { loginRedirect } from "../../../../../../../login/loginRedirect"; -import { TRACKING_CATEGORY } from "../_constants"; export default async function Page(props: { params: Promise<{ team_slug: string; project_slug: string }>; @@ -33,7 +32,6 @@ export default async function Page(props: { return ( diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/ftux.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/ftux.client.tsx index 345b95f6a1c..79cd708767e 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/ftux.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/ftux.client.tsx @@ -5,9 +5,9 @@ import { type Step, StepsCard } from "components/dashboard/StepsCard"; import Link from "next/link"; import { useMemo, useState } from "react"; import type { ThirdwebClient } from "thirdweb"; +import { CreateVaultAccountButton } from "../../../vault/components/create-vault-account.client"; import CreateServerWallet from "../server-wallets/components/create-server-wallet.client"; import type { Wallet } from "../server-wallets/wallet-table/types"; -import CreateVaultAccountButton from "../vault/components/create-vault-account.client"; import { SendTestTransaction } from "./send-test-tx.client"; import { deleteUserAccessToken } from "./utils"; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx index b97c3f44382..3bb82113d15 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/tx-chart/tx-chart-ui.tsx @@ -185,7 +185,7 @@ function EmptyChartContent(props: { variant="primary" onClick={() => { router.push( - `/team/${props.teamSlug}/${props.project.slug}/engine/cloud/vault`, + `/team/${props.teamSlug}/${props.project.slug}/vault`, ); }} > diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/layout.tsx index 8246256d7a9..13be81a2cd5 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/layout.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/layout.tsx @@ -35,12 +35,12 @@ function TransactionsLayout(props: {

- Engine{" "} + Transactions{" "} - Cloud + Engine Cloud

diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/create-server-wallet.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/create-server-wallet.client.tsx index 2ec6fd295a3..841d4440923 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/create-server-wallet.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/create-server-wallet.client.tsx @@ -86,9 +86,7 @@ export default function CreateServerWallet(props: { const handleCreateServerWallet = async () => { if (!props.managementAccessToken) { - router.push( - `/team/${props.teamSlug}/${props.project.slug}/engine/cloud/vault`, - ); + router.push(`/team/${props.teamSlug}/${props.project.slug}/vault`); } else { await createEoaMutation.mutateAsync({ managementAccessToken: props.managementAccessToken, @@ -106,9 +104,7 @@ export default function CreateServerWallet(props: { onClick={() => props.managementAccessToken ? setModalOpen(true) - : router.push( - `/team/${props.teamSlug}/${props.project.slug}/engine/cloud/vault`, - ) + : router.push(`/team/${props.teamSlug}/${props.project.slug}/vault`) } className="flex flex-row items-center gap-2" > diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/key-management.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/key-management.tsx deleted file mode 100644 index 7f05b0a3da3..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/key-management.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import type { Project } from "@/api/projects"; -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; -import { InfoIcon } from "lucide-react"; -import Link from "next/link"; -import CreateVaultAccountButton from "./create-vault-account.client"; -import ListAccessTokens from "./list-access-tokens.client"; -import RotateAdminKeyButton from "./rotate-admin-key.client"; - -export function KeyManagement({ - maskedAdminKey, - project, -}: { maskedAdminKey?: string; project: Project }) { - return ( -
-
-
-

Vault

-

- Secure, non-custodial key management system for your server wallets.{" "} - - Learn more. - -

-
- {!maskedAdminKey ? ( - - ) : ( -
- )} -
- {maskedAdminKey ? ( - <> -
-
-

- Admin Key -

-

- This key is used to create new server wallets and access tokens. -
We do not store this key. If you lose it, you can rotate - it to create a new one. Doing so will invalidate all existing - access tokens. -

-
-
-
-

- {maskedAdminKey} -

-
- -
-
-
- - - ) : null} -
- ); -} - -async function CreateVaultAccountAlert(props: { - project: Project; -}) { - return ( -
-
- - - - What is Vault? - - - Vault is thirdweb's non-custodial key management system for your - server wallets that allows you to: -
    -
  • Create multiple server wallets.
  • -
  • Create Vault access tokens.
  • -
  • Sign transactions using a Vault access token.
  • -
- Your keys are stored in a hardware enclave, and all requests are - end-to-end encrypted.{" "} - - Learn more about Vault security model. - -
- Creating server wallets and access tokens requires a Vault admin - account. Create one below to get started. - -
- -
-
- -
-
- ); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(general)/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(general)/layout.tsx index b8c10047be1..950cfa42a6f 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(general)/layout.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(general)/layout.tsx @@ -25,12 +25,12 @@ export default async function Layout(props: {

- Engine{" "} + Transactions{" "} - Dedicated + Dedicated Engine

diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/fetch-nebula-analytics.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/fetch-nebula-analytics.tsx deleted file mode 100644 index 2b5f5c34b2f..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/fetch-nebula-analytics.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import "server-only"; -import { ANALYTICS_SERVICE_URL } from "@/constants/server-envs"; -import { unstable_cache } from "next/cache"; - -export type NebulaAnalyticsDataItem = { - date: string; - totalPromptTokens: number; - totalCompletionTokens: number; - totalSessions: number; - totalRequests: number; -}; - -export const fetchNebulaAnalytics = unstable_cache( - async (params: { - teamId: string; - projectId: string; - authToken: string; - from: string; - to: string; - period: "day" | "week" | "month" | "year" | "all"; - }) => { - const analyticsEndpoint = ANALYTICS_SERVICE_URL; - const url = new URL(`${analyticsEndpoint}/v2/nebula/usage`); - url.searchParams.set("teamId", params.teamId); - url.searchParams.set("projectId", params.projectId); - url.searchParams.set("from", params.from); - url.searchParams.set("to", params.to); - url.searchParams.set("period", params.period); - - const res = await fetch(url, { - headers: { - Authorization: `Bearer ${params.authToken}`, - }, - }); - - if (!res.ok) { - const error = await res.text(); - return { - ok: false as const, - error: error, - }; - } - - const resData = await res.json(); - - return { - ok: true as const, - data: resData.data as NebulaAnalyticsDataItem[], - }; - }, - ["nebula-analytics"], - { - revalidate: 60 * 60, // 1 hour - }, -); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-filter.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-filter.tsx deleted file mode 100644 index 76a2d83ad8f..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-filter.tsx +++ /dev/null @@ -1,51 +0,0 @@ -"use client"; - -import { normalizeTimeISOString } from "@/lib/time"; -import { DateRangeSelector } from "components/analytics/date-range-selector"; -import { IntervalSelector } from "components/analytics/interval-selector"; -import { getNebulaFiltersFromSearchParams } from "lib/time"; -import { - useResponsiveSearchParams, - useSetResponsiveSearchParams, -} from "responsive-rsc"; - -export function NebulaAnalyticsFilter() { - const responsiveSearchParams = useResponsiveSearchParams(); - const setResponsiveSearchParams = useSetResponsiveSearchParams(); - - const { range, interval } = getNebulaFiltersFromSearchParams({ - from: responsiveSearchParams.from, - to: responsiveSearchParams.to, - interval: responsiveSearchParams.interval, - }); - - return ( -

- { - setResponsiveSearchParams((v) => { - return { - ...v, - from: normalizeTimeISOString(newRange.from), - to: normalizeTimeISOString(newRange.to), - }; - }); - }} - /> - - { - setResponsiveSearchParams((v) => { - return { - ...v, - interval: newInterval, - }; - }); - }} - /> -
- ); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-page.tsx deleted file mode 100644 index 6c3e69f3c59..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-page.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { Button } from "@/components/ui/button"; -import { normalizeTimeISOString } from "@/lib/time"; -import { FileCode2Icon, MessageSquareQuoteIcon } from "lucide-react"; -import Link from "next/link"; -import { - ResponsiveSearchParamsProvider, - ResponsiveSuspense, -} from "responsive-rsc"; -import { fetchNebulaAnalytics } from "./fetch-nebula-analytics"; -import { NebulaAnalyticsFilter } from "./nebula-analytics-filter"; -import { NebulaAnalyticsDashboardUI } from "./nebula-analytics-ui"; -import { getNebulaAnalyticsRangeFromSearchParams } from "./utils"; - -export function NebulaAnalyticsPage(props: { - searchParams: { - from: string | undefined | string[]; - to: string | undefined | string[]; - interval: string | undefined | string[]; - }; - teamId: string; - authToken: string; - projectId: string; -}) { - return ( - -
-
-

Nebula

- -
- - - -
-
-
- -
-
-

Analytics

- -
- } - > - - -
-
- ); -} - -async function NebulaAnalyticDashboard(props: { - teamId: string; - authToken: string; - projectId: string; - searchParams: { - from: string | undefined | string[]; - to: string | undefined | string[]; - interval: string | undefined | string[]; - }; -}) { - const { range, interval } = getNebulaAnalyticsRangeFromSearchParams( - props.searchParams, - ); - - const res = await fetchNebulaAnalytics({ - teamId: props.teamId, - authToken: props.authToken, - projectId: props.projectId, - from: normalizeTimeISOString(range.from), - to: normalizeTimeISOString(range.to), - // internally renamed - period: interval, - }); - - if (!res.ok) { - return ( -
-
-

- Failed to fetch Nebula analytics -

-

{res.error}

-
-
- ); - } - - return ; -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.stories.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.stories.tsx deleted file mode 100644 index 45902917035..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.stories.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/nextjs"; -import { subDays } from "date-fns"; -import type { NebulaAnalyticsDataItem } from "./fetch-nebula-analytics"; -import { NebulaAnalyticsDashboardUI } from "./nebula-analytics-ui"; - -const meta = { - title: "Nebula/Analytics", - component: NebulaAnalyticsDashboardUI, - parameters: { - nextjs: { - appDirectory: true, - }, - }, - decorators: [ - (Story) => ( -
- -
- ), - ], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const SixtyDays: Story = { - args: { - data: generateRandomNebulaAnalyticsData(60), - isPending: false, - }, -}; - -export const ThirtyDays: Story = { - args: { - data: generateRandomNebulaAnalyticsData(30), - isPending: false, - }, -}; - -export const SevenDays: Story = { - args: { - data: generateRandomNebulaAnalyticsData(7), - isPending: false, - }, -}; - -export const Pending: Story = { - args: { - data: [], - isPending: true, - }, -}; - -function generateRandomNebulaAnalyticsData( - days: number, -): NebulaAnalyticsDataItem[] { - return Array.from({ length: days }, (_, i) => ({ - date: subDays(new Date(), i).toISOString(), - totalPromptTokens: randomInt(500, 700 + i * 100), - totalCompletionTokens: randomInt(1000, 2000 + i * 100), - totalSessions: randomInt(400, 1000 + i * 100), - totalRequests: randomInt(4000, 5000 + i * 100), - })); -} - -function randomInt(min: number, max: number) { - return Math.floor(Math.random() * (max - min + 1)) + min; -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx deleted file mode 100644 index 24120f9165f..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/nebula-analytics-ui.tsx +++ /dev/null @@ -1,203 +0,0 @@ -"use client"; - -import { ThirdwebAreaChart } from "@/components/blocks/charts/area-chart"; -import { SkeletonContainer } from "@/components/ui/skeleton"; -import { format } from "date-fns"; -import { - ActivityIcon, - MessageCircleQuestionIcon, - MessageSquareIcon, - MessageSquareQuoteIcon, -} from "lucide-react"; -import { useMemo } from "react"; -import type { NebulaAnalyticsDataItem } from "./fetch-nebula-analytics"; - -type ChartData = { - time: Date; - totalPromptTokens: number; - totalCompletionTokens: number; - totalSessions: number; - totalRequests: number; -}; - -type AnalyticsChartProps = { - data: ChartData[]; - isPending: boolean; - title: string; - description: string; - dataKey: keyof ChartData; - color: string; -}; - -function AnalyticsChart({ - data, - isPending, - title, - description, - dataKey, - color, -}: AnalyticsChartProps) { - return ( - ({ - ...item, - time: item.time.getTime(), - }))} - isPending={isPending} - header={{ - title, - description, - titleClassName: "text-xl mb-1", - }} - chartClassName="aspect-[1.5] lg:aspect-[2.5]" - hideLabel={false} - toolTipLabelFormatter={toolTipLabelFormatter} - config={{ - [dataKey]: { - label: title, - color, - }, - }} - /> - ); -} - -export function NebulaAnalyticsDashboardUI(props: { - data: NebulaAnalyticsDataItem[]; - isPending: boolean; -}) { - const data = useMemo(() => { - const val: { - totalPromptTokens: number; - totalCompletionTokens: number; - totalSessions: number; - totalRequests: number; - chartData: ChartData[]; - } = { - totalPromptTokens: 0, - totalCompletionTokens: 0, - totalSessions: 0, - totalRequests: 0, - chartData: [], - }; - - for (const item of props.data) { - val.totalPromptTokens += item.totalPromptTokens; - val.totalCompletionTokens += item.totalCompletionTokens; - val.totalSessions += item.totalSessions; - val.totalRequests += item.totalRequests; - val.chartData.push({ - totalPromptTokens: item.totalPromptTokens, - totalCompletionTokens: item.totalCompletionTokens, - totalSessions: item.totalSessions, - totalRequests: item.totalRequests, - time: new Date(item.date), - }); - } - - return val; - }, [props.data]); - - return ( -
-
- - - - -
- -
- -
- - - - - - - -
-
- ); -} - -function toolTipLabelFormatter(_v: string, item: unknown) { - if (Array.isArray(item)) { - const time = item[0].payload.time as number; - return format(new Date(time), "MMM d, yyyy"); - } - return undefined; -} - -function StatCard(props: { - title: string; - value: number; - icon: React.FC<{ className?: string }>; - isPending: boolean; -}) { - return ( -
-
-

{props.title}

- -
- ( -

{v}

- )} - /> -
- ); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/utils.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/utils.ts deleted file mode 100644 index a361b20ae65..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/components/analytics/utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getNebulaFiltersFromSearchParams } from "lib/time"; - -export function getNebulaAnalyticsRangeFromSearchParams(searchParams: { - from: string | undefined | string[]; - to: string | undefined | string[]; - interval: string | undefined | string[]; -}) { - return getNebulaFiltersFromSearchParams({ - from: searchParams.from, - to: searchParams.to, - interval: searchParams.interval, - }); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/layout.tsx deleted file mode 100644 index f7d5c5aff05..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/layout.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { FooterLinksSection } from "../components/footer/FooterLinksSection"; - -export default function Layout(props: { - children: React.ReactNode; -}) { - return ( -
-
{props.children}
-
-
-
- -
-
-
- ); -} - -function NebulaFooter() { - return ( - - ); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/nebula-ftux.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/nebula-ftux.tsx deleted file mode 100644 index 7eb8b8e2efe..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/nebula-ftux.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { CodeServer } from "@/components/ui/code/code.server"; -import { SecretKeySection } from "../components/ProjectFTUX/SecretKeySection"; -import { WaitingForIntegrationCard } from "../components/WaitingForIntegrationCard/WaitingForIntegrationCard"; - -export function NebulaFTUX(props: { - secretKeyMasked: string; - teamId: string; - projectId: string; -}) { - return ( - - ), - }, - { - label: "Python", - code: ( - - ), - }, - { - label: "Curl", - code: ( - - ), - }, - ]} - ctas={[ - { - label: "Try on Playground", - href: "https://nebula.thirdweb.com/", - }, - { - label: "View Docs", - href: "https://portal.thirdweb.com/nebula", - }, - ]} - > - -
- - ); -} - -const jsCode = `\ -// Example: Send message to Nebula -// Replace PROJECT_SECRET_KEY with your project's full secret key - -const res = await fetch("https://nebula-api.thirdweb.com/chat", { - method: "POST", - headers: { - "x-secret-key": "PROJECT_SECRET_KEY", - }, - body: { - message: "Hello", - stream: false, - }, -}); - -const data = await res.json(); -`; - -const curlCode = `\ -# Example: Send message to Nebula -# Replace PROJECT_SECRET_KEY with your project's full secret key - -curl -X POST https://nebula-api.thirdweb.com/chat \ --H "x-secret-key:PROJECT_SECRET_KEY" \ --d '{ - "message": "Hello", - "stream": false, -}' -`; - -const pythonCode = `\ -# Example: Send message to Nebula -# Replace PROJECT_SECRET_KEY with your project's full secret key - -import requests - -response = requests.post("https://nebula-api.thirdweb.com/chat", headers={ - "x-secret-key": "PROJECT_SECRET_KEY" -}, json={ - "message": "Hello", - "stream": False, -}) - -data = response.json() -`; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/page.tsx deleted file mode 100644 index 05643837434..00000000000 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/nebula/page.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { isProjectActive } from "@/api/analytics"; -import { getProject } from "@/api/projects"; -import { getTeamBySlug } from "@/api/team"; -import { redirect } from "next/navigation"; -import { getAuthToken } from "../../../../../api/lib/getAuthToken"; -import { loginRedirect } from "../../../../../login/loginRedirect"; -import { NebulaAnalyticsPage } from "./components/analytics/nebula-analytics-page"; -import { NebulaFTUX } from "./nebula-ftux"; - -export default async function Page(props: { - params: Promise<{ - team_slug: string; - project_slug: string; - }>; - searchParams: Promise<{ - from: string | undefined | string[]; - to: string | undefined | string[]; - interval: string | undefined | string[]; - }>; -}) { - const [params, searchParams] = await Promise.all([ - props.params, - props.searchParams, - ]); - - const [authToken, team, project] = await Promise.all([ - getAuthToken(), - getTeamBySlug(params.team_slug), - getProject(params.team_slug, params.project_slug), - ]); - - if (!team) { - redirect("/team"); - } - - if (!project) { - redirect(`/team/${params.team_slug}`); - } - - if (!authToken) { - loginRedirect(`/team/${params.team_slug}/${params.project_slug}/nebula`); - } - - const activeResponse = await isProjectActive({ - teamId: team.id, - projectId: project.id, - }); - - const showFTUX = !activeResponse.nebula; - - if (showFTUX) { - return ( -
-
-
-

Nebula

-
-
- -
- -
-
- ); - } - - return ( - - ); -} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx index a18c8253202..90c5f8bb2e8 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx @@ -761,7 +761,7 @@ function EnabledServicesSetting(props: { return (
{/* Left */}
@@ -780,7 +780,7 @@ function EnabledServicesSetting(props: { asChild size="sm" variant="outline" - className="min-w-32 justify-between gap-2" + className="h-auto justify-between gap-2 rounded-full bg-background py-1" > Configure diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/create-vault-account.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/create-vault-account.client.tsx similarity index 97% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/create-vault-account.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/create-vault-account.client.tsx index b129944158c..5dcc541c7cc 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/create-vault-account.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/create-vault-account.client.tsx @@ -15,18 +15,23 @@ import { useDashboardRouter } from "@/lib/DashboardRouter"; import { cn } from "@/lib/utils"; import { useMutation } from "@tanstack/react-query"; import { createServiceAccount } from "@thirdweb-dev/vault-sdk"; -import { CheckIcon, DownloadIcon, Loader2Icon, LockIcon } from "lucide-react"; +import { + CheckIcon, + DownloadIcon, + Loader2Icon, + UserLockIcon, +} from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; -import { storeUserAccessToken } from "../../analytics/utils"; +import { storeUserAccessToken } from "../../engine/cloud/analytics/utils"; import { createManagementAccessToken, createWalletAccessToken, initVaultClient, maskSecret, -} from "../../lib/vault.client"; +} from "../../engine/cloud/lib/vault.client"; -export default function CreateVaultAccountButton(props: { +export function CreateVaultAccountButton(props: { project: Project; onUserAccessTokenCreated?: (userAccessToken: string) => void; }) { @@ -151,7 +156,7 @@ export default function CreateVaultAccountButton(props: { {isLoading ? ( ) : ( - + )} {"Create Vault Admin Account"} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/key-management.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/key-management.tsx new file mode 100644 index 00000000000..5bf8aa21931 --- /dev/null +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/key-management.tsx @@ -0,0 +1,86 @@ +import type { Project } from "@/api/projects"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { InfoIcon } from "lucide-react"; +import Link from "next/link"; +import { CreateVaultAccountButton } from "./create-vault-account.client"; +import ListAccessTokens from "./list-access-tokens.client"; +import RotateAdminKeyButton from "./rotate-admin-key.client"; + +export function KeyManagement({ + maskedAdminKey, + project, +}: { maskedAdminKey?: string; project: Project }) { + return ( +
+ {!maskedAdminKey && } + + {maskedAdminKey && ( + <> +
+
+

+ Admin Key +

+

+ This key is used to create new server wallets and access tokens. +
We do not store this key. If you lose it, you can rotate + it to create a new one. Doing so will invalidate all existing + access tokens. +

+
+
+
+

+ {maskedAdminKey} +

+
+ +
+
+
+ + + )} +
+ ); +} + +async function CreateVaultAccountAlert(props: { + project: Project; +}) { + return ( +
+ + + + What is Vault? + + + Vault is thirdweb's non-custodial key management system for your + server wallets that allows you to: +
    +
  • Create multiple server wallets.
  • +
  • Create Vault access tokens.
  • +
  • Sign transactions using a Vault access token.
  • +
+ Your keys are stored in a hardware enclave, and all requests are + end-to-end encrypted.{" "} + + Learn more about Vault security model. + +
+ Creating server wallets and access tokens requires a Vault admin + account. Create one below to get started. + +
+ + + +
+ ); +} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/list-access-tokens.client.tsx similarity index 99% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/list-access-tokens.client.tsx index d551f3ecb9b..175fd32010f 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/list-access-tokens.client.tsx @@ -20,7 +20,7 @@ import { SERVER_WALLET_MANAGEMENT_ACCESS_TOKEN_PURPOSE, createWalletAccessToken, initVaultClient, -} from "../../lib/vault.client"; +} from "../../engine/cloud/lib/vault.client"; export default function ListAccessTokens(props: { project: Project; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/rotate-admin-key.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx similarity index 99% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/rotate-admin-key.client.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx index 6c3d62473b2..dae5b3fd31f 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/rotate-admin-key.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/rotate-admin-key.client.tsx @@ -31,7 +31,7 @@ import { createWalletAccessToken, initVaultClient, maskSecret, -} from "../../lib/vault.client"; +} from "../../engine/cloud/lib/vault.client"; export default function RotateAdminKeyButton(props: { project: Project }) { const [modalOpen, setModalOpen] = useState(false); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/layout.tsx new file mode 100644 index 00000000000..c7dda5e1f69 --- /dev/null +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/layout.tsx @@ -0,0 +1,33 @@ +import Link from "next/link"; + +export default function VaultLayout(props: { + children: React.ReactNode; +}) { + return ( +
+
+
+

Vault

+

+ Secure, non-custodial key management system for your server wallets.{" "} + + Learn more. + +

+
+
+
+ +
+ {props.children} +
+ +
+
+ ); +} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/page.tsx similarity index 92% rename from apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/page.tsx rename to apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/page.tsx index f3c3d783165..2e4b27fc815 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/page.tsx @@ -1,6 +1,6 @@ import { getProject } from "@/api/projects"; +import { getAuthToken } from "@app/api/lib/getAuthToken"; import { notFound } from "next/navigation"; -import { getAuthToken } from "../../../../../../../api/lib/getAuthToken"; import { KeyManagement } from "./components/key-management"; export default async function VaultPage(props: { diff --git a/apps/dashboard/src/components/embedded-wallets/Users/index.tsx b/apps/dashboard/src/components/embedded-wallets/Users/index.tsx index f0dba99f450..8f223185227 100644 --- a/apps/dashboard/src/components/embedded-wallets/Users/index.tsx +++ b/apps/dashboard/src/components/embedded-wallets/Users/index.tsx @@ -36,7 +36,6 @@ const getUserIdentifier = (accounts: WalletUser["linkedAccounts"]) => { const columnHelper = createColumnHelper(); export function InAppWalletUsersPageContent(props: { - trackingCategory: string; authToken: string; projectClientId: string; client: ThirdwebClient; diff --git a/apps/dashboard/src/lib/time.ts b/apps/dashboard/src/lib/time.ts index 6b06f0e1395..95652750079 100644 --- a/apps/dashboard/src/lib/time.ts +++ b/apps/dashboard/src/lib/time.ts @@ -1,19 +1,6 @@ import { getFiltersFromSearchParams } from "@/lib/time"; import type { DurationId } from "../components/analytics/date-range-selector"; -export function getNebulaFiltersFromSearchParams(params: { - from: string | undefined | string[]; - to: string | undefined | string[]; - interval: string | undefined | string[]; -}) { - return getFiltersFromSearchParams({ - from: params.from, - to: params.to, - interval: params.interval, - defaultRange: "last-30", - }); -} - export function getUniversalBridgeFiltersFromSearchParams(params: { from: string | undefined | string[]; to: string | undefined | string[]; diff --git a/packages/service-utils/src/core/services.ts b/packages/service-utils/src/core/services.ts index 928a59731c8..8212e2dbce0 100644 --- a/packages/service-utils/src/core/services.ts +++ b/packages/service-utils/src/core/services.ts @@ -39,7 +39,7 @@ export const SERVICE_DEFINITIONS = { }, embeddedWallets: { name: "embeddedWallets", - title: "In-App Wallets", + title: "Wallets", description: "E-mail and social login wallets for easy web3 onboarding", // all actions allowed actions: [], @@ -76,7 +76,7 @@ export const SERVICE_DEFINITIONS = { }, engineCloud: { name: "engineCloud", - title: "Engine Cloud", + title: "Transactions", description: "Transaction API and Server wallets with high transaction throughput and low latency", // all actions allowed