diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json
index 31cb53a4a13..c4271869b7b 100644
--- a/apps/dashboard/package.json
+++ b/apps/dashboard/package.json
@@ -53,6 +53,7 @@
"@tanstack/react-query": "5.59.13",
"@tanstack/react-table": "^8.17.3",
"@thirdweb-dev/service-utils": "workspace:*",
+ "@vercel/functions": "^1.4.2",
"@vercel/og": "^0.6.2",
"abitype": "1.0.6",
"chakra-react-select": "^4.7.6",
@@ -69,7 +70,7 @@
"ipaddr.js": "^2.2.0",
"lottie-react": "^2.4.0",
"lucide-react": "0.452.0",
- "next": "14.2.15",
+ "next": "15.0.0",
"next-plausible": "^3.12.0",
"next-seo": "^6.5.0",
"next-themes": "^0.3.0",
@@ -107,8 +108,8 @@
"devDependencies": {
"@chakra-ui/cli": "^2.4.1",
"@chromatic-com/storybook": "2.0.2",
- "@next/bundle-analyzer": "14.2.15",
- "@next/eslint-plugin-next": "14.2.15",
+ "@next/bundle-analyzer": "15.0.0",
+ "@next/eslint-plugin-next": "15.0.0",
"@playwright/test": "1.47.2",
"@storybook/addon-essentials": "8.3.5",
"@storybook/addon-interactions": "8.3.5",
@@ -124,8 +125,8 @@
"@types/papaparse": "^5.3.15",
"@types/pluralize": "^0.0.33",
"@types/qrcode": "^1.5.5",
- "@types/react": "^18.3.11",
- "@types/react-dom": "^18.3.1",
+ "@types/react": "18.3.11",
+ "@types/react-dom": "18.3.1",
"@types/react-table": "^7.7.20",
"@types/spdx-correct": "^3.1.3",
"@types/swagger-ui-react": "^4.18.3",
@@ -143,5 +144,11 @@
"storybook": "8.3.5",
"tailwindcss": "3.4.13",
"typescript": "5.6.3"
+ },
+ "pnpm": {
+ "overrides": {
+ "@types/react": "18.3.11",
+ "@types/react-dom": "18.3.1"
+ }
}
}
diff --git a/apps/dashboard/src/@/api/projects.ts b/apps/dashboard/src/@/api/projects.ts
index 0c17dc450b2..ef2cbdbd558 100644
--- a/apps/dashboard/src/@/api/projects.ts
+++ b/apps/dashboard/src/@/api/projects.ts
@@ -21,7 +21,7 @@ export type Project = {
};
export async function getProjects(teamSlug: string) {
- const cookiesManager = cookies();
+ const cookiesManager = await cookies();
const activeAccount = cookiesManager.get(COOKIE_ACTIVE_ACCOUNT)?.value;
const token = activeAccount
? cookiesManager.get(COOKIE_PREFIX_TOKEN + activeAccount)?.value
@@ -46,7 +46,7 @@ export async function getProjects(teamSlug: string) {
}
export async function getProject(teamSlug: string, projectSlug: string) {
- const cookiesManager = cookies();
+ const cookiesManager = await cookies();
const activeAccount = cookiesManager.get(COOKIE_ACTIVE_ACCOUNT)?.value;
const token = activeAccount
? cookiesManager.get(COOKIE_PREFIX_TOKEN + activeAccount)?.value
diff --git a/apps/dashboard/src/@/api/team.ts b/apps/dashboard/src/@/api/team.ts
index 1759bb1624d..4ec8153815b 100644
--- a/apps/dashboard/src/@/api/team.ts
+++ b/apps/dashboard/src/@/api/team.ts
@@ -23,7 +23,7 @@ export type Team = {
};
export async function getTeamBySlug(slug: string) {
- const cookiesManager = cookies();
+ const cookiesManager = await cookies();
const activeAccount = cookiesManager.get(COOKIE_ACTIVE_ACCOUNT)?.value;
const token = activeAccount
? cookiesManager.get(COOKIE_PREFIX_TOKEN + activeAccount)?.value
@@ -45,7 +45,7 @@ export async function getTeamBySlug(slug: string) {
}
export async function getTeams() {
- const cookiesManager = cookies();
+ const cookiesManager = await cookies();
const activeAccount = cookiesManager.get(COOKIE_ACTIVE_ACCOUNT)?.value;
const token = activeAccount
? cookiesManager.get(COOKIE_PREFIX_TOKEN + activeAccount)?.value
diff --git a/apps/dashboard/src/@/constants/cookie.ts b/apps/dashboard/src/@/constants/cookie.ts
index 669cc606f7f..c64b933473e 100644
--- a/apps/dashboard/src/@/constants/cookie.ts
+++ b/apps/dashboard/src/@/constants/cookie.ts
@@ -1,12 +1,16 @@
-import { cookies } from "next/headers";
+import { type UnsafeUnwrappedCookies, cookies } from "next/headers";
export const COOKIE_ACTIVE_ACCOUNT = "tw_active_account";
export const COOKIE_PREFIX_TOKEN = "tw_token_";
export function getActiveAccountCookie() {
- return cookies().get(COOKIE_ACTIVE_ACCOUNT)?.value;
+ return (cookies() as unknown as UnsafeUnwrappedCookies).get(
+ COOKIE_ACTIVE_ACCOUNT,
+ )?.value;
}
export function getJWTCookie(address: string) {
- return cookies().get(COOKIE_PREFIX_TOKEN + address)?.value;
+ return (cookies() as unknown as UnsafeUnwrappedCookies).get(
+ COOKIE_PREFIX_TOKEN + address,
+ )?.value;
}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/components/server/chain-header.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/components/server/chain-header.tsx
index f057047b77c..1dac58a178b 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/components/server/chain-header.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/components/server/chain-header.tsx
@@ -17,7 +17,7 @@ type ChainHeaderProps = {
export function ChainHeader(props: ChainHeaderProps) {
return (
// force the banner image to be 4:1 aspect ratio and full-width on mobile devices
-
+ (
{!props.headerImageUrl &&
}
{props.headerImageUrl && (
// eslint-disable-next-line @next/next/no-img-element
-

+ />)
)}
{/* below header */}
@@ -65,6 +65,6 @@ export function ChainHeader(props: ChainHeaderProps) {
-
+ )
);
}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx
index e2fe40d0c2e..dcf842f334d 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/layout.tsx
@@ -32,9 +32,8 @@ import { ChainHeader } from "./components/server/chain-header";
// TODO: improve the behavior when clicking "Get started with thirdweb", currently just redirects to the dashboard
-export async function generateMetadata({
- params,
-}: { params: { chain_id: string } }): Promise {
+export async function generateMetadata(props: { params: Promise<{ chain_id: string }> }): Promise {
+ const params = await props.params;
const chain = await getChain(params.chain_id);
const sanitizedChainName = chain.name.replace("Mainnet", "").trim();
const title = `${sanitizedChainName}: RPC and Chain Settings`;
@@ -54,13 +53,18 @@ export async function generateMetadata({
}
// this is the dashboard layout file
-export default async function ChainPageLayout({
- children,
- params,
-}: {
- children: React.ReactNode;
- params: { chain_id: string };
-}) {
+export default async function ChainPageLayout(
+ props: {
+ children: React.ReactNode;
+ params: Promise<{ chain_id: string }>;
+ }
+) {
+ const params = await props.params;
+
+ const {
+ children
+ } = props;
+
const chain = await getChain(params.chain_id);
if (params.chain_id !== chain.slug) {
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/opengraph-image.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/opengraph-image.tsx
index bbc548926b7..0a04405bcf6 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/opengraph-image.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/opengraph-image.tsx
@@ -18,7 +18,7 @@ export const contentType = "image/png";
const TWLogo: React.FC = () => (
// biome-ignore lint/a11y/noSvgWithoutTitle: not needed
-
+ )
);
// Image generation
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/page.tsx
index 67a974a6590..2571241f7ad 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/page.tsx
@@ -13,9 +13,9 @@ import { ChainCTA } from "./components/server/cta-card";
import { ExplorersSection } from "./components/server/explorer-section";
export default async function Page(props: {
- params: { chain_id: string };
+ params: Promise<{ chain_id: string }>;
}) {
- const chain = await getChain(props.params.chain_id);
+ const chain = await getChain((await props.params).chain_id);
const chainMetadata = await getChainMetadata(chain.chainId);
const isDeprecated = chain.status === "deprecated";
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/popular/page.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/popular/page.tsx
index ebe8cbf0efe..846a3178f59 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/popular/page.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/popular/page.tsx
@@ -7,39 +7,35 @@ import { getChain } from "../../../utils";
export const dynamic = "force-dynamic";
export default async function Page(props: {
- params: { chain_id: string };
- searchParams: { page?: number; sortBy?: SortBy };
+ params: Promise<{ chain_id: string }>;
+ searchParams: Promise<{ page?: number; sortBy?: SortBy }>;
}) {
- const chain = await getChain(props.params.chain_id);
+ const chain = await getChain((await props.params).chain_id);
const topContracts = await fetchTopContracts({
chainId: chain.chainId,
- page: props.searchParams.page,
- sortBy: props.searchParams.sortBy,
+ page: (await props.searchParams).page,
+ sortBy: (await props.searchParams).sortBy,
perPage: 15,
timeRange: "month",
});
return (
-
+ (
Popular Contracts
-
Explore contracts on Ethereum and sort them by your preferred metrics
-
-
{topContracts.length > 0 && (
)}
-
{topContracts.length === 0 && (
@@ -48,6 +44,6 @@ export default async function Page(props: {
)}
-
+ )
);
}
diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/marketplace-table.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/marketplace-table.tsx
index 1784e397011..78a6cc8d6c8 100644
--- a/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/marketplace-table.tsx
+++ b/apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/marketplace-table.tsx
@@ -182,7 +182,7 @@ export const MarketplaceTable: React.FC = ({
>(null);
return (
-
+ (