"use client";
import React, { useState, useEffect } from "react";
import "@/styles/landing.css";
import Image from "next/image";
import {
ThemeIcon,
GitHubIcon,
SolidityIcon,
CairoIcon,
ConfidentialIcon,
StellarIcon,
StylusIcon,
TronIcon,
UniswapHooksIcon,
SuiIcon,
} from "@/components/icons";
import { ConfigModal } from "@/components/ConfigModal";
function ThemeToggle({ onThemeChange }) {
const [theme, setTheme] = useState("dark");
useEffect(() => {
const savedTheme = localStorage.getItem("theme");
if (savedTheme) {
setTheme(savedTheme);
applyTheme(savedTheme);
onThemeChange(savedTheme);
} else {
// Fallback to system default on first render
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
const systemTheme = systemPrefersDark ? "dark" : "light";
setTheme(systemTheme);
applyTheme(systemTheme);
onThemeChange(systemTheme);
}
}, [onThemeChange]);
const applyTheme = (newTheme) => {
const root = document.documentElement;
root.setAttribute("data-theme", newTheme);
};
const toggleTheme = () => {
const nextTheme = theme === "dark" ? "light" : "dark";
setTheme(nextTheme);
localStorage.setItem("theme", nextTheme);
applyTheme(nextTheme);
onThemeChange(nextTheme);
};
return (
);
}
function GitHubButton() {
return (
);
}
export default function HomePage() {
const [currentTheme, setCurrentTheme] = useState("dark");
const [isModalOpen, setIsModalOpen] = useState(false);
const [selectedMcp, setSelectedMcp] = useState(null);
const handleThemeChange = (theme) => {
setCurrentTheme(theme);
};
const getLogoSrc = () => {
return currentTheme === "light"
? "/OZ-Logo-BlackBG.png"
: "/OZ-Logo-WhiteBG.png";
};
const openModal = (mcp) => {
setSelectedMcp(mcp);
setIsModalOpen(true);
};
const closeModal = () => {
setIsModalOpen(false);
setSelectedMcp(null);
};
const BASE_URL =
process.env.NODE_ENV === "development"
? "http://localhost:3000/"
: "https://mcp.openzeppelin.com/";
const AVAILABLE_MCPS = [
{
name: "Solidity Contracts",
serverName: "OpenZeppelinSolidityContracts",
icon: SolidityIcon,
description:
"Generate Solidity secure smart contracts based on OpenZeppelin templates",
url: `${BASE_URL}contracts/solidity/mcp`,
npmMcpPackage: "@openzeppelin/contracts-mcp",
},
{
name: "Cairo Contracts",
serverName: "OpenZeppelinCairoContracts",
icon: CairoIcon,
description:
"Generate Cairo secure smart contracts based on OpenZeppelin templates",
url: `${BASE_URL}contracts/cairo/mcp`,
npmMcpPackage: "@openzeppelin/contracts-mcp",
},
{
name: "Confidential Contracts",
serverName: "OpenZeppelinConfidentialContracts",
icon: ConfidentialIcon,
description:
"Generate Confidential secure smart contracts based on OpenZeppelin templates",
url: `${BASE_URL}contracts/confidential/mcp`,
npmMcpPackage: "@openzeppelin/contracts-mcp",
},
{
name: "Stellar Contracts",
serverName: "OpenZeppelinStellarContracts",
icon: StellarIcon,
description:
"Generate Stellar secure smart contracts based on OpenZeppelin templates",
url: `${BASE_URL}contracts/stellar/mcp`,
npmMcpPackage: "@openzeppelin/contracts-mcp",
},
{
name: "Stylus Contracts",
serverName: "OpenZeppelinStylusContracts",
icon: StylusIcon,
description:
"Generate Stylus secure smart contracts based on OpenZeppelin templates",
url: `${BASE_URL}contracts/stylus/mcp`,
npmMcpPackage: "@openzeppelin/contracts-mcp",
},
{
name: "TRON Contracts",
serverName: "OpenZeppelinTronContracts",
icon: TronIcon,
description:
"Generate TRON secure smart contracts based on OpenZeppelin templates",
url: `${BASE_URL}contracts/tron/mcp`,
npmMcpPackage: "@openzeppelin/contracts-mcp",
},
{
name: "Uniswap Hooks",
serverName: "OpenZeppelinUniswapHooks",
icon: UniswapHooksIcon,
description:
"Generate Uniswap Hooks secure smart contracts based on OpenZeppelin templates",
url: `${BASE_URL}contracts/uniswap-hooks/mcp`,
npmMcpPackage: "@openzeppelin/contracts-mcp",
},
{
name: "Sui Contracts",
serverName: "OpenZeppelinSuiContracts",
icon: SuiIcon,
description:
"Compose Sui Move smart contracts based on OpenZeppelin's audited primitives",
url: `${BASE_URL}contracts/sui/mcp`,
// This server's data comes from the contracts-sui repo at runtime, not
// from the @openzeppelin/contracts-mcp npm package — attribute the source.
poweredBy: {
label: "OpenZeppelin/contracts-sui",
href: "https://github.com/OpenZeppelin/contracts-sui",
},
},
];
return (
MCP Servers
Model Context Protocol Servers
Repository for OpenZeppelin
Products
{AVAILABLE_MCPS.map((mcp, index) => (
openModal(mcp)}
>
{mcp.name}
{mcp.description}
{"View Setup Instructions →"}
))}
);
}