├── .eslintrc.json ├── public ├── favicon.png ├── img │ ├── bg1.jpg │ ├── bg2.jpg │ ├── bg3.jpg │ ├── bg4.jpg │ ├── bg5.jpg │ ├── bg6.jpg │ ├── bg7.jpg │ ├── eth.png │ ├── ufo.png │ ├── wtf.png │ ├── token1.png │ ├── lecture.png │ ├── mars-bg.png │ ├── martian.png │ ├── preview.jfif │ ├── logo-mars.png │ ├── presalelive.png │ ├── swap-back.png │ ├── sparkle.svg │ ├── planets │ │ ├── 10.svg │ │ ├── 2.svg │ │ ├── 3.svg │ │ ├── 4.svg │ │ ├── 5.svg │ │ ├── 6.svg │ │ ├── 7.svg │ │ ├── 8.svg │ │ ├── 9.svg │ │ └── 1.svg │ ├── base-logo.svg │ └── home.svg ├── fonts │ ├── text.woff2 │ ├── ugly.woff2 │ ├── Catfiles.woff │ └── title.woff2 └── images │ ├── fail.png │ ├── question.png │ ├── success.png │ └── warning.png ├── postcss.config.js ├── src ├── types │ ├── utils.ts │ └── chain.ts ├── hooks │ ├── useActiveWeb3.tsx │ ├── useToastr.tsx │ └── useAPI.tsx ├── components │ ├── nft │ │ ├── loader.tsx │ │ ├── lazyImage.tsx │ │ ├── loaderItem.tsx │ │ ├── nftItem.tsx │ │ └── mintItem.tsx │ ├── presale │ │ ├── congratulate.tsx │ │ ├── header.tsx │ │ ├── connectButton.tsx │ │ └── topOwners.tsx │ ├── main │ │ ├── footer.tsx │ │ ├── address.tsx │ │ ├── faqItem.tsx │ │ ├── faq.tsx │ │ ├── mintSuccessModal.tsx │ │ ├── tokenomics.tsx │ │ ├── nft.tsx │ │ ├── roadMap.tsx │ │ └── header.tsx │ └── ui │ │ ├── topMeteors.tsx │ │ ├── meteors.tsx │ │ ├── sparkle.tsx │ │ └── sparkles.tsx ├── providers │ ├── index.tsx │ ├── rainbowProvider.tsx │ ├── web3Provider.tsx │ └── toastProvider.tsx ├── utils │ ├── cn.ts │ ├── useRandomInterval.ts │ └── methods.ts ├── constants │ ├── wagmiConfig.ts │ ├── config.ts │ ├── abis │ │ ├── mars.json │ │ ├── usdc.json │ │ ├── marsNft.json │ │ └── presale.json │ └── abis.js └── app │ ├── layout.tsx │ ├── presale │ └── page.tsx │ ├── page.tsx │ └── nft │ ├── page.tsx │ └── mint │ └── page.tsx ├── next.config.mjs ├── .gitignore ├── tsconfig.json ├── tailwind.config.ts ├── package.json └── README.md /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/favicon.png -------------------------------------------------------------------------------- /public/img/bg1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/bg1.jpg -------------------------------------------------------------------------------- /public/img/bg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/bg2.jpg -------------------------------------------------------------------------------- /public/img/bg3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/bg3.jpg -------------------------------------------------------------------------------- /public/img/bg4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/bg4.jpg -------------------------------------------------------------------------------- /public/img/bg5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/bg5.jpg -------------------------------------------------------------------------------- /public/img/bg6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/bg6.jpg -------------------------------------------------------------------------------- /public/img/bg7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/bg7.jpg -------------------------------------------------------------------------------- /public/img/eth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/eth.png -------------------------------------------------------------------------------- /public/img/ufo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/ufo.png -------------------------------------------------------------------------------- /public/img/wtf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/wtf.png -------------------------------------------------------------------------------- /public/img/token1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/token1.png -------------------------------------------------------------------------------- /public/fonts/text.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/fonts/text.woff2 -------------------------------------------------------------------------------- /public/fonts/ugly.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/fonts/ugly.woff2 -------------------------------------------------------------------------------- /public/images/fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/images/fail.png -------------------------------------------------------------------------------- /public/img/lecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/lecture.png -------------------------------------------------------------------------------- /public/img/mars-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/mars-bg.png -------------------------------------------------------------------------------- /public/img/martian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/martian.png -------------------------------------------------------------------------------- /public/img/preview.jfif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/preview.jfif -------------------------------------------------------------------------------- /public/fonts/Catfiles.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/fonts/Catfiles.woff -------------------------------------------------------------------------------- /public/fonts/title.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/fonts/title.woff2 -------------------------------------------------------------------------------- /public/images/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/images/question.png -------------------------------------------------------------------------------- /public/images/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/images/success.png -------------------------------------------------------------------------------- /public/images/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/images/warning.png -------------------------------------------------------------------------------- /public/img/logo-mars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/logo-mars.png -------------------------------------------------------------------------------- /public/img/presalelive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/presalelive.png -------------------------------------------------------------------------------- /public/img/swap-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/top0329/mars-wtf-frontend/HEAD/public/img/swap-back.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /src/types/utils.ts: -------------------------------------------------------------------------------- 1 | export type NFT = { 2 | _id: string; 3 | name: string; 4 | description: string; 5 | image: string; 6 | minted?: boolean 7 | }; -------------------------------------------------------------------------------- /src/hooks/useActiveWeb3.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Web3Context } from "@/providers/web3Provider"; 3 | 4 | const useActiveWeb3 = () => { 5 | const context = React.useContext(Web3Context); 6 | if (!context) { 7 | throw new Error(""); 8 | } else { 9 | return context; 10 | } 11 | }; 12 | 13 | export default useActiveWeb3; -------------------------------------------------------------------------------- /src/hooks/useToastr.tsx: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | 3 | import { ToastContext } from "@/providers/toastProvider"; 4 | 5 | /** 6 | * 7 | * @returns context { showNotification(text:string) } 8 | */ 9 | const useToastr = () => { 10 | const context = useContext(ToastContext); 11 | if ( !context ) throw new Error("No notification") 12 | return context; 13 | } 14 | 15 | export default useToastr; -------------------------------------------------------------------------------- /public/img/sparkle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/components/nft/loader.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import LoaderItem from './loaderItem'; 3 | 4 | const NFTLoader = () => { 5 | return ( 6 | 7 | { 8 | new Array (30).fill("").map((item: string, index: number) => ( 9 | 10 | )) 11 | } 12 | 13 | ) 14 | } 15 | 16 | export default NFTLoader; -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: false, 4 | images: { 5 | remotePatterns: [ 6 | { 7 | protocol: "https", 8 | hostname: "**", 9 | }, 10 | ], 11 | }, 12 | webpack: config => { 13 | config.externals.push('pino-pretty', 'lokijs', 'encoding'); 14 | config.resolve.fallback = { fs: false, net: false, tls: false }; 15 | return config; 16 | }, 17 | }; 18 | 19 | export default nextConfig; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /src/types/chain.ts: -------------------------------------------------------------------------------- 1 | export interface CHAIN { 2 | name: string, 3 | ticker: string, 4 | symbol: string, 5 | rpc: string, 6 | chainId: number, 7 | explorer: string, 8 | } 9 | 10 | export interface CONTRACT { 11 | presale: { 12 | address: string, 13 | abi: any 14 | }, 15 | usdc: { 16 | address: string, 17 | abi: any 18 | }, 19 | mars: { 20 | address: string, 21 | abi: any 22 | }, 23 | nft: { 24 | address: string, 25 | abi: any 26 | } 27 | } 28 | 29 | export type NFT = { 30 | assetType: string, 31 | description: string, 32 | name: string, 33 | image: string 34 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": ["./src/*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/components/dragger.tsx"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /src/providers/index.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React from "react"; 3 | import dynamic from "next/dynamic"; 4 | 5 | const RainbowProvider = dynamic(() => import("@/providers/rainbowProvider"), { ssr: false }); 6 | const ActiveWeb3Provider = dynamic(() => import("@/providers/web3Provider"), { ssr: false }); 7 | const ToastProvider = dynamic(() => import("@/providers/toastProvider"), { ssr: false }); 8 | 9 | const ThemeClient = ({ children }: Readonly<{ children: React.ReactNode }>) => { 10 | return ( 11 | 12 | 13 | 14 | {children} 15 | 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default ThemeClient; 22 | -------------------------------------------------------------------------------- /src/utils/cn.ts: -------------------------------------------------------------------------------- 1 | import type {ClassValue} from "clsx"; 2 | 3 | import clsx from "clsx"; 4 | import {extendTailwindMerge} from "tailwind-merge"; 5 | 6 | const COMMON_UNITS = ["small", "medium", "large"]; 7 | 8 | /** 9 | * We need to extend the tailwind merge to include NextUI's custom classes. 10 | * 11 | * So we can use classes like `text-small` or `text-default-500` and override them. 12 | */ 13 | const twMerge = extendTailwindMerge({ 14 | extend: { 15 | theme: { 16 | opacity: ["disabled"], 17 | spacing: ["divider"], 18 | borderWidth: COMMON_UNITS, 19 | borderRadius: COMMON_UNITS, 20 | }, 21 | classGroups: { 22 | shadow: [{shadow: COMMON_UNITS}], 23 | "font-size": [{text: ["tiny", ...COMMON_UNITS]}], 24 | "bg-image": ["bg-stripe-gradient"], 25 | }, 26 | }, 27 | }); 28 | 29 | export function cn(...inputs: ClassValue[]) { 30 | return twMerge(clsx(inputs)); 31 | } -------------------------------------------------------------------------------- /src/hooks/useAPI.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import axios from "axios"; 3 | import { useRouter } from "next/navigation"; 4 | 5 | const useAPI = () => { 6 | const router = useRouter (); 7 | 8 | const api = axios.create({ 9 | // baseURL: 'http://localhost:5050/api', 10 | baseURL: 'https://vulcan-launchpad-1-0-0-backend.onrender.com/api', 11 | headers: { 12 | 'Content-Type': 'application/json', 13 | }, 14 | }); 15 | 16 | // api.interceptors.response.use( 17 | // (res) => res, 18 | // (err) => { 19 | // if (err.response.status === 401) { 20 | // // if (localStorage.getItem('token')) { 21 | // // localStorage.setItem('expired', true); 22 | // // } 23 | // axios.defaults.headers.common['x-auth-token'] = undefined; 24 | // router.push("/"); 25 | // } 26 | // return Promise.reject(err); 27 | // } 28 | // ); 29 | 30 | return api; 31 | }; 32 | 33 | export default useAPI; 34 | -------------------------------------------------------------------------------- /src/components/presale/congratulate.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import { chains } from '@/constants/wagmiConfig'; 3 | import React from 'react'; 4 | import Confetti from "react-confetti"; 5 | import useWindowSize from "react-use/lib/useWindowSize"; 6 | 7 | interface IProps { 8 | close: () => void 9 | } 10 | 11 | const BuySuccess = (props: IProps) => { 12 | 13 | const { width, height } = useWindowSize(); 14 | 15 | const init = () => { 16 | setTimeout (() => { 17 | props.close (); 18 | }, 10000) 19 | } 20 | 21 | React.useEffect(() => { 22 | init (); 23 | // eslint-disable-next-line react-hooks/exhaustive-deps 24 | }, []); 25 | 26 | return ( 27 |
28 |
29 | 30 |
31 |
32 | ) 33 | } 34 | 35 | export default BuySuccess; -------------------------------------------------------------------------------- /src/components/main/footer.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | import React from "react"; 3 | import { useRouter } from "next/navigation"; 4 | 5 | 6 | const Footer = () => { 7 | 8 | const router = useRouter (); 9 | 10 | return ( 11 | 29 | ); 30 | }; 31 | 32 | export default Footer; 33 | -------------------------------------------------------------------------------- /src/constants/wagmiConfig.ts: -------------------------------------------------------------------------------- 1 | import { 2 | metaMaskWallet, 3 | } from "@rainbow-me/rainbowkit/wallets"; 4 | import { type Chain } from 'viem' 5 | 6 | import { 7 | getDefaultWallets, 8 | getDefaultConfig, 9 | } from "@rainbow-me/rainbowkit"; 10 | 11 | import { sepolia, arbitrum, bsc, base } from "wagmi/chains"; 12 | import { Config } from "wagmi"; 13 | 14 | const { wallets } = getDefaultWallets(); 15 | 16 | export const chains: Chain[] = [ 17 | // arbitrum, 18 | // bsc, 19 | // base, 20 | sepolia, 21 | // ...(process.env.NEXT_PUBLIC_ENABLE_TESTNETS === 'true' ? [sepolia] : []), 22 | ] 23 | 24 | export const config: Config = getDefaultConfig({ 25 | appName: "RainbowKit demo", 26 | projectId: "e89228fed40d4c6e9520912214dfd68b", 27 | wallets: [ 28 | ...wallets, 29 | { 30 | groupName: "Other", 31 | wallets: [metaMaskWallet], 32 | }, 33 | ], 34 | //@ts-ignore 35 | chains: chains, 36 | ssr: true, 37 | }); -------------------------------------------------------------------------------- /src/providers/rainbowProvider.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React from "react"; 3 | import { 4 | RainbowKitProvider, 5 | darkTheme, 6 | lightTheme, 7 | AvatarComponent 8 | } from "@rainbow-me/rainbowkit"; 9 | import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; 10 | import { WagmiProvider } from "wagmi"; 11 | import { config } from "@/constants/wagmiConfig"; 12 | import Image from "next/image"; 13 | 14 | const queryClient = new QueryClient(); 15 | 16 | const CustomAvatar: AvatarComponent = ({ address, ensImage, size }) => 17 | avatar 24 | 25 | const RainbowProvider = ({ children }: { children: React.ReactNode }) => { 26 | return ( 27 | 28 | 29 | {children} 30 | 31 | 32 | ); 33 | }; 34 | 35 | export default RainbowProvider; 36 | -------------------------------------------------------------------------------- /src/components/nft/lazyImage.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import React from 'react'; 3 | import Image from 'next/image'; 4 | import {Button, Skeleton} from "@nextui-org/react"; 5 | 6 | interface IProps { 7 | src: string, 8 | className?: string 9 | } 10 | 11 | const LazyImage = ({ src, className }: IProps) => { 12 | 13 | const [loaded, setLoaded] = React.useState(false); 14 | 15 | return ( 16 | <> 17 | setLoaded(true)} 24 | sizes="100vw" 25 | layout="fill" 26 | objectFit="cover" 27 | priority={false} 28 | className={`w-full nft duration-400 transition-all`} 29 | /> 30 | 31 |
32 |
33 | 34 | ) 35 | } 36 | 37 | export default LazyImage; -------------------------------------------------------------------------------- /public/img/planets/10.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/img/planets/2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/img/planets/3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/img/planets/4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/img/planets/5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/img/planets/6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/img/planets/7.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/img/planets/8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/img/planets/9.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/components/ui/topMeteors.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import { cn } from "@/utils/cn"; 3 | import clsx from "clsx"; 4 | import React from "react"; 5 | 6 | const TopMeteors = ({ 7 | number, 8 | className, 9 | }: { 10 | number?: number; 11 | className?: string; 12 | }) => { 13 | const meteors = new Array(number || 20).fill(true); 14 | return ( 15 | <> 16 | {meteors.map((el, idx) => ( 17 | 31 | ))} 32 | 33 | ); 34 | }; 35 | 36 | export default TopMeteors; 37 | -------------------------------------------------------------------------------- /src/components/main/address.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Address = () => { 4 | 5 | const [copied, setCopied] = React.useState(false); 6 | 7 | const handleCopy = async() => { 8 | setCopied (true); 9 | setTimeout(() => { 10 | setCopied (false); 11 | }, 1000); 12 | } 13 | 14 | return ( 15 |
16 |
17 |

PRESALE LIVE

18 |
19 |
28 |
29 | 0xfB7176581a345b1168098b3BE9Fa7E15641e652f 30 | 31 | 34 |
35 |
36 |
37 | ); 38 | }; 39 | 40 | export default Address; 41 | -------------------------------------------------------------------------------- /src/utils/useRandomInterval.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // Utility helper for random number generation 3 | const random = (min: number, max: number) => Math.floor(Math.random() * (max - min)) + min; 4 | export const useRandomInterval = (callback: () => void, minDelay: number, maxDelay:number) => { 5 | const timeoutId = React.useRef | null>(null); 6 | const savedCallback = React.useRef(callback); 7 | React.useEffect(() => { 8 | savedCallback.current = callback; 9 | // eslint-disable-next-line react-hooks/exhaustive-deps 10 | }, [callback]); 11 | React.useEffect(() => { 12 | let isEnabled = 13 | typeof minDelay === 'number' && typeof maxDelay === 'number'; 14 | if (isEnabled) { 15 | const handleTick = () => { 16 | const nextTickAt = random(minDelay, maxDelay); 17 | timeoutId.current = setTimeout(() => { 18 | savedCallback.current(); 19 | handleTick(); 20 | }, nextTickAt); 21 | }; 22 | handleTick(); 23 | } 24 | //@ts-ignore 25 | return () => clearTimeout(timeoutId.current); 26 | // eslint-disable-next-line react-hooks/exhaustive-deps 27 | }, [minDelay, maxDelay]); 28 | const cancel = React.useCallback(function () { 29 | //@ts-ignore 30 | clearTimeout(timeoutId.current); 31 | }, []); 32 | return cancel; 33 | }; 34 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import localFont from 'next/font/local'; 3 | import { Inter } from "next/font/google"; 4 | import Provider from '@/providers'; 5 | import Head from 'next/head'; 6 | import "@rainbow-me/rainbowkit/styles.css"; 7 | import "./globals.css"; 8 | import "aos/dist/aos.css"; 9 | import 'swiper/css'; 10 | import 'swiper/css/effect-cards'; 11 | 12 | 13 | const inter = Inter({ subsets: ["latin"] }); 14 | 15 | const catFont = localFont({ 16 | src: [ 17 | { 18 | path: "../../public/fonts/Catfiles.woff", 19 | }, 20 | ], 21 | variable: "--font-cat", 22 | }); 23 | 24 | export const metadata: Metadata = { 25 | title: "Mars WTF", 26 | description: "BASE memecoin", 27 | icons: { 28 | icon: [ 29 | { 30 | media: "(prefers-color-scheme: light)", 31 | url: "/favicon.png", 32 | href: "/favicon.png", 33 | } 34 | ], 35 | }, 36 | }; 37 | 38 | export default function RootLayout({ 39 | children, 40 | }: Readonly<{ 41 | children: React.ReactNode; 42 | }>) { 43 | return ( 44 | 45 | 46 | 47 | 48 | 49 | 50 | {children} 51 | 52 | 53 | 54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /src/components/main/faqItem.tsx: -------------------------------------------------------------------------------- 1 | import { desigWallet } from "@rainbow-me/rainbowkit/wallets"; 2 | import React from "react"; 3 | 4 | const FaqItem = ({ title, description }: { title: string, description: string }) => { 5 | 6 | const [open, setOpen] = React.useState(false); 7 | 8 | return ( 9 |
setOpen(!open)} 18 | > 19 | 39 |
40 |

{ description }

41 |
42 |
43 | ); 44 | }; 45 | 46 | export default FaqItem; 47 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import { transform } from "next/dist/build/swc"; 2 | import type { Config } from "tailwindcss"; 3 | const { nextui } = require("@nextui-org/theme"); 4 | 5 | const config: Config = { 6 | content: [ 7 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 8 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 9 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 10 | "./src/**/*.{js,ts,jsx,tsx,mdx}", 11 | "./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}", 12 | ], 13 | theme: { 14 | extend: { 15 | fontFamily: { 16 | cat: ["var(--font-cat)"], 17 | }, 18 | backgroundImage: { 19 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", 20 | "gradient-conic": 21 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", 22 | }, 23 | screens: { 24 | 'xxs': '380px', 25 | 'xs': '450px', 26 | 'w1450': '1450px', 27 | 'w1080': '1080px', 28 | 'w1200': '1200px', 29 | 'w1300': '1300px', 30 | }, 31 | animation: { 32 | "meteor-effect": "meteor 5s linear infinite", 33 | }, 34 | keyframes: { 35 | meteor: { 36 | "0%": { transform: "rotate(215deg) translateX(0)", opacity: "1" }, 37 | "70%": { opacity: "1" }, 38 | "100%": { 39 | transform: "rotate(215deg) translateX(-500px)", 40 | opacity: "0", 41 | }, 42 | } 43 | } 44 | } 45 | }, 46 | plugins: [nextui()], 47 | }; 48 | export default config; 49 | -------------------------------------------------------------------------------- /src/components/main/faq.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | import React from "react"; 3 | import FaqItem from "@/components/main/faqItem"; 4 | 5 | type FAQ = { 6 | title: string, 7 | description: string 8 | } 9 | 10 | const faqs: FAQ[] = [ 11 | { 12 | title: 'WHO IS $MARSWTF?', 13 | description: 'MARSWTF is a meme coin created on and living in the Base Ecosystem!' 14 | }, 15 | { 16 | title: 'WHAT CHAIN IS APED ON?', 17 | description: '$MARSWTF is on the Base Chain, a layer 2 blockchain on the Ethereum network. Learn more about base chain here https://docs.base.org/' 18 | }, 19 | { 20 | title: 'HOW CAN I BUY $MARSWTF?', 21 | description: 'Please refer to our how to buy section mentioned above.' 22 | }, 23 | ] 24 | 25 | const FAQ = () => { 26 | 27 | 28 | 29 | return ( 30 |
31 |
32 |

41 | faq 42 |

43 |
44 | { 45 | faqs.map((_faq: FAQ) => ) 46 | } 47 |
48 |
49 |
50 | ); 51 | }; 52 | 53 | export default FAQ; 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "new-frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@iconify/react": "^4.1.1", 13 | "@nextui-org/react": "^2.4.2", 14 | "@nextui-org/system": "^2.2.2", 15 | "@nextui-org/theme": "^2.2.6", 16 | "@rainbow-me/rainbowkit": "^2.0.5", 17 | "@tsparticles/engine": "^3.3.0", 18 | "@tsparticles/react": "^3.0.0", 19 | "@tsparticles/slim": "^3.3.0", 20 | "aos": "^2.3.4", 21 | "axios": "^1.6.8", 22 | "clsx": "^2.1.0", 23 | "ethers": "^5.7.2", 24 | "framer-motion": "^11.2.12", 25 | "i": "^0.3.7", 26 | "jotai": "^2.8.0", 27 | "jquery": "^3.7.1", 28 | "next": "14.1.4", 29 | "npm": "^10.5.2", 30 | "pino-pretty": "^11.0.0", 31 | "react": "^18", 32 | "react-confetti": "^6.1.0", 33 | "react-dom": "^18", 34 | "react-fast-marquee": "^1.6.4", 35 | "react-hot-toast": "^2.4.1", 36 | "react-use": "^17.5.0", 37 | "swiper": "^11.1.4", 38 | "tailwind-merge": "^2.2.2", 39 | "viem": "^2.9.9", 40 | "wagmi": "^2.10.9", 41 | "web3": "^4.7.0" 42 | }, 43 | "devDependencies": { 44 | "@types/aos": "^3.0.7", 45 | "@types/jquery": "^3.5.29", 46 | "@types/node": "^20", 47 | "@types/react": "^18", 48 | "@types/react-dom": "^18", 49 | "autoprefixer": "^10.0.1", 50 | "eslint": "^8", 51 | "eslint-config-next": "14.1.4", 52 | "postcss": "^8", 53 | "tailwindcss": "^3.3.0", 54 | "typescript": "^5" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/components/ui/meteors.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import { cn } from "@/utils/cn"; 3 | import React from "react"; 4 | 5 | const Meteors = ({ 6 | number, 7 | className, 8 | poistion 9 | }: { 10 | number?: number; 11 | className?: string; 12 | poistion: string 13 | }) => { 14 | const meteors = new Array(number || 15).fill(true); 15 | return ( 16 | <> 17 | {meteors.map((el, idx) => ( 18 | 39 | ))} 40 | 41 | ); 42 | }; 43 | 44 | export default Meteors; 45 | -------------------------------------------------------------------------------- /public/img/base-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/components/nft/loaderItem.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import { Skeleton } from "@nextui-org/react"; 5 | import { cn } from "@/utils/cn"; 6 | 7 | export type PlaceListItemProps = Omit, "id"> & { 8 | isPopular?: boolean; 9 | isLoading?: boolean; 10 | removeWrapper?: boolean; 11 | }; 12 | 13 | const PlaceListItem = React.forwardRef( 14 | ( 15 | { removeWrapper, className, ...props }, 16 | ref, 17 | ) => { 18 | 19 | return ( 20 |
31 |
32 | 33 |
34 |
35 |
36 | 37 |
38 |
39 | 40 |
41 | 42 | 43 |
44 | 45 | 46 |
47 | 48 |
49 |
50 |
51 | ); 52 | }, 53 | ); 54 | 55 | PlaceListItem.displayName = "PlaceListItem"; 56 | 57 | export default PlaceListItem; 58 | -------------------------------------------------------------------------------- /public/img/planets/1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/providers/web3Provider.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React from "react"; 3 | import { type Chain, type Address, type Client } from "viem"; 4 | 5 | import { providers } from "ethers"; 6 | import { useAccount, useWalletClient } from "wagmi"; 7 | import { type UseAccountParameters } from "wagmi"; 8 | 9 | function clientToSigner(client: any) { 10 | const { account, chain, transport } = client; 11 | if (!account || !chain || !transport) { 12 | return undefined; 13 | } 14 | const network = { 15 | chainId: chain.id, 16 | name: chain.name, 17 | ensAddress: chain.contracts?.ensRegistry?.address, 18 | }; 19 | const provider = new providers.Web3Provider(transport, network); 20 | const signer = provider.getSigner(account.address); 21 | return signer; 22 | } 23 | 24 | interface IContext { 25 | chain: Chain | undefined, 26 | address: Address | undefined; 27 | chainId: number | undefined; 28 | isConnected: boolean; 29 | isConnecting: boolean; 30 | isReconnecting: boolean; 31 | isDisconnected: boolean; 32 | connector: any | undefined; 33 | signer: any | undefined; 34 | } 35 | 36 | export const Web3Context = React.createContext(undefined); 37 | 38 | const Web3ContextProvider = ({ 39 | children, 40 | }: Readonly<{ children: React.ReactNode }>) => { 41 | const { address, chain, isConnected, isConnecting, isReconnecting, connector, isDisconnected, chainId } = useAccount(); 42 | const { data } = useWalletClient({ chainId }); 43 | const client: Client = data as Client; 44 | 45 | const signer = React.useMemo(() => (client ? clientToSigner(client) : undefined), [client]); 46 | 47 | return ( 48 | 61 | {children} 62 | 63 | ); 64 | }; 65 | 66 | export default Web3ContextProvider; 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mars WTF Frontend 2 | 3 | A high-performance Web3 platform for Mars WTF meme token, built on Next.js and primarily deployed on Base Network. Features seamless NFT minting, real-time blockchain data integration, and an interactive presale dashboard. The platform leverages RainbowKit for multi-wallet connectivity, custom smart contract interactions, and IPFS/Pinata for decentralized NFT storage. 4 | 5 | ## Tech Stack 6 | 7 | - Next.js 8 | - TypeScript 9 | - RainbowKit for wallet connections 10 | - Wagmi for blockchain interactions 11 | - IPFS/Pinata for NFT storage 12 | - Vercel for deployment 13 | 14 | ## Features 15 | 16 | - Wallet Integration with multiple providers 17 | - NFT Minting Interface 18 | - Top Holders Leaderboard 19 | - Real-time Token Statistics 20 | - Custom Toast Notifications 21 | - Lazy Loading Images 22 | - Responsive Design 23 | 24 | ## Environment Setup 25 | 26 | 1. Clone the repository: 27 | ```bash 28 | git clone https://github.com/top0329/mars-wtf-frontend.git 29 | ``` 30 | 31 | 2. Install dependencies: 32 | ```bash 33 | npm install 34 | ``` 35 | 36 | 3. Configure environment variables: 37 | Create a `.env.local` file with: 38 | ```env 39 | NEXT_PUBLIC_ENABLE_TESTNETS=true 40 | ``` 41 | 42 | ## Development 43 | 44 | Run the development server: 45 | ```bash 46 | npm run dev 47 | ``` 48 | 49 | Access the development site at `http://localhost:3000` 50 | 51 | ## Smart Contract Addresses 52 | 53 | - Base Network: `0xD76e5a10702156c4155443EC93Ff634b6F12a312` 54 | - Sepolia Network: `0x10B70F96Eccba753231D853157386579301622eF` 55 | 56 | ## API Integration 57 | 58 | The backend API is hosted at: `https://mars-backend-t22d.vercel.app/api` 59 | 60 | ## Production Deployment 61 | 62 | This project is optimized for deployment on Vercel. Follow these steps: 63 | 64 | 1. Connect your repository to Vercel 65 | 2. Configure environment variables 66 | 3. Deploy 67 | 68 | ## Contributing 69 | 70 | 1. Fork the repository 71 | 2. Create a feature branch 72 | 3. Commit changes 73 | 4. Push to the branch 74 | 5. Open a Pull Request 75 | 76 | ## License 77 | 78 | MIT License 79 | 80 | ## Support 81 | 82 | For technical support or inquiries, please open an issue in the repository. 83 | -------------------------------------------------------------------------------- /src/components/main/mintSuccessModal.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import { chains } from '@/constants/wagmiConfig'; 3 | import { Icon } from '@iconify/react/dist/iconify.js'; 4 | import React from 'react'; 5 | import Confetti from "react-confetti"; 6 | import useWindowSize from "react-use/lib/useWindowSize"; 7 | 8 | interface IProps { 9 | name: string, 10 | description: string, 11 | image: string, 12 | hash: string, 13 | close: () => void 14 | } 15 | 16 | const MintSuccessModal = (props: IProps) => { 17 | 18 | const { width, height } = useWindowSize(); 19 | 20 | return ( 21 |
22 |
23 |
24 |
25 |
26 |
27 |
Mint Success
28 |
29 | 33 |
34 |
window.open(`https://sepolia.etherscan.io/tx/${props.hash}`)}>0x6c0c4610ecd6ed5fd13489b1228f9038a00c420f5ca351115b08a296cad98e84
35 |
36 |
37 | 41 | 42 |
43 |
44 | ) 45 | } 46 | 47 | export default MintSuccessModal; -------------------------------------------------------------------------------- /src/utils/methods.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { PINATA_KEY } from "@/constants/config"; 3 | /** 4 | * render string with ,,, 5 | * @param value 10,000,000 6 | * @returns 7 | */ 8 | export const _renderNumber = (value: number | string = 0) => { 9 | if (Number(value) === 0 && isNaN(Number(value))) return "0"; 10 | let [num, _decimal] = String(value).split("."); 11 | let _num = ""; 12 | let j = 1; 13 | for (let i = num.length - 1; i >= 1; i--, j++) { 14 | _num += num[i]; 15 | if (j % 3 === 0) _num += ","; 16 | } 17 | _num += num[0]; 18 | let str = _num.split("").reverse().reduce((acc: string, item: string) => acc += item, ""); 19 | if (_decimal) str += `.${_decimal.substring(0,2)}`; 20 | 21 | return str; 22 | }; 23 | 24 | export const uploadToPinata = async (data: string, onProgress?: any) => { 25 | try { 26 | const formData = new FormData(); 27 | const base64Response = await fetch(data); 28 | const newBlob = await base64Response.blob(); 29 | formData.append("file", newBlob); 30 | const { data: res } = await axios 31 | .post("https://api.pinata.cloud/pinning/pinFileToIPFS", formData, { 32 | maxContentLength: Infinity, 33 | maxBodyLength: Infinity, 34 | headers: { 35 | //@ts-ignore 36 | "Content-Type": `multipart/form-data; boundary=${formData._boundary}`, 37 | Authorization: `Bearer ${PINATA_KEY}`, 38 | }, 39 | onUploadProgress: onProgress, 40 | }); 41 | return Promise.resolve(`https://ipfs.io/ipfs/${res.IpfsHash}`); 42 | } catch (err) { 43 | console.log(err) 44 | return Promise.reject("failed") 45 | } 46 | }; 47 | 48 | /** 49 | * 50 | * @param {*} data data to upload file to IPFS 51 | * @param {*} progress callback to display progress (progress: number) => {} 52 | * @returns Promise 53 | */ 54 | export const uploadToIPFS = (data: File, progress: any) => new Promise(async(resolve, reject) => { 55 | const formData = new FormData(); 56 | formData.append('file', data) 57 | formData.append('pinataMetadata', JSON.stringify({ name: 'mars.wtf' })); 58 | formData.append('pinataOptions', JSON.stringify({ cidVersion: 0 })); 59 | 60 | const res = await axios.post('https://api.pinata.cloud/pinning/pinFileToIPFS', formData, { 61 | maxBodyLength: Infinity, 62 | headers: { 63 | //@ts-ignore 64 | 'Content-Type': `multipart/form-data; boundary=${formData._boundary}`, 65 | 'Authorization' : `Bearer ${PINATA_KEY}`, 66 | }, 67 | onUploadProgress: progress 68 | }).catch(err => { 69 | reject("IPFS projectInfo upload failed"); 70 | }); 71 | //@ts-ignore 72 | resolve("https://ipfs.io/ipfs/" + res.data.IpfsHash); 73 | }); 74 | -------------------------------------------------------------------------------- /src/components/ui/sparkle.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useRandomInterval } from "@/utils/useRandomInterval"; 3 | 4 | const random = (min: number, max: number) => Math.floor(Math.random() * (max - min)) + min; 5 | 6 | type Sparkle = { 7 | id: string, 8 | createdAt: number, 9 | color: string, 10 | size: number, 11 | style: Object 12 | } 13 | 14 | const DEFAULT_COLOR = 'hsl(50deg, 100%, 50%)'; 15 | const generateSparkle = (color = DEFAULT_COLOR, top: number, left: number, right: number, bottom: number) => { 16 | const sparkle: Sparkle = { 17 | id: String(random(10000, 99999)), 18 | createdAt: Date.now(), 19 | color, 20 | size: random(10, 20), 21 | style: { 22 | top: random(top, bottom) + '%', 23 | left: random(left, right) + '%', 24 | }, 25 | }; 26 | return sparkle; 27 | } 28 | 29 | const SparkleInstance = ({ color, size, style }: { color: string, size: number, style: Object }) => ( 30 |
31 | 38 | 39 | 40 |
41 | ); 42 | 43 | function Sparkles({ children, color = DEFAULT_COLOR, top = 0, left = 0, right = 100, bottom = 100, interval = 500 }: { children: any, color?: string, top?: number, left?: number, right?: number, bottom?: number, interval?: number }) { 44 | const [sparkles, setSparkles] = React.useState([1,2,3].map(i => generateSparkle(color, top, left, right, bottom))); 45 | 46 | useRandomInterval(() => { 47 | const now = Date.now(); 48 | // Create a new sparkle 49 | const sparkle = generateSparkle(color, top, left, right, bottom); 50 | // Clean up any "expired" sparkles 51 | const nextSparkles = sparkles.filter((sparkle: Sparkle) => { 52 | const delta = now - sparkle.createdAt; 53 | return delta < 1500; 54 | }); 55 | // Include our new sparkle 56 | //@ts-ignore 57 | nextSparkles.push(sparkle); 58 | // Make it so! 59 | setSparkles(nextSparkles); 60 | }, 50, interval); 61 | 62 | return ( 63 |
64 | {children} 65 | { 66 | sparkles.map((_sparkle: Sparkle, index: number) => ( 67 | 73 | )) 74 | } 75 |
76 | ) 77 | } 78 | 79 | export default Sparkles; 80 | -------------------------------------------------------------------------------- /src/constants/config.ts: -------------------------------------------------------------------------------- 1 | import type { CHAIN, CONTRACT } from "@/types/chain"; 2 | import NFT_ABI from '@/constants/abis/marsNft.json'; 3 | import PRESALE_ABI from '@/constants/abis/presale.json'; 4 | import MARS_ABI from '@/constants/abis/mars.json'; 5 | import USDC_ABI from '@/constants/abis/usdc.json'; 6 | 7 | export const PINATA_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mb3JtYXRpb24iOnsiaWQiOiI5NDlhYmU4Ni1lZTE5LTRiNTgtYjMwMS0wYzcyYzNhMGJjOWMiLCJlbWFpbCI6IncuYm9ubmVzQGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwaW5fcG9saWN5Ijp7InJlZ2lvbnMiOlt7ImlkIjoiRlJBMSIsImRlc2lyZWRSZXBsaWNhdGlvbkNvdW50IjoxfSx7ImlkIjoiTllDMSIsImRlc2lyZWRSZXBsaWNhdGlvbkNvdW50IjoxfV0sInZlcnNpb24iOjF9LCJtZmFfZW5hYmxlZCI6ZmFsc2UsInN0YXR1cyI6IkFDVElWRSJ9LCJhdXRoZW50aWNhdGlvblR5cGUiOiJzY29wZWRLZXkiLCJzY29wZWRLZXlLZXkiOiJmNmVhMzViMTg3MmViMjM5OWU1ZCIsInNjb3BlZEtleVNlY3JldCI6ImNiMWVmYjQyZjVmOTFjZDgzYzhhNWRhMmEyYWU5YzIzYzM0YzE0ZDU4OWRhODI3NjljZTg3MGJmNWU2NGMyOWYiLCJpYXQiOjE2OTQ2NjI5Nzd9.sUhRsFf1vXuCAvI8Sgl_K7gzUaASXGpGe5nST4rz8uo" 8 | export const SERVER_URL = 'https://mars-backend-t22d.vercel.app/api' 9 | // export const SERVER_URL = 'http://localhost:5050/api' 10 | 11 | export const NetworkId = { 12 | SEPOLIA: 11155111, 13 | BASE: 8453, 14 | SCROLL: 534352, 15 | }; 16 | 17 | export const BASE_URL = 'https://marswtf-backend.onrender.com'; 18 | // export const BASE_URL = 'http://localhost:5000'; 19 | export const USDC_ADDRESS = "0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8"; 20 | 21 | 22 | export const TOKEN_ADDRESSES = { 23 | [NetworkId.BASE]: "0xD76e5a10702156c4155443EC93Ff634b6F12a312",//verified & adjusted 24 | [NetworkId.SEPOLIA]: "0x10B70F96Eccba753231D853157386579301622eF"//verified 25 | } 26 | 27 | 28 | export const chains: Record = { 29 | 11155111: { 30 | name: "Sepolia test network", 31 | ticker: 'SEPOLIA', 32 | symbol: "ETH", 33 | rpc: "https://ethereum-sepolia-rpc.publicnode.com", 34 | chainId: 11155111, 35 | explorer: 'https://sepolia.etherscan.io' 36 | }, 37 | 8453: { 38 | name: "BASE", 39 | ticker: 'BASE', 40 | symbol: "ETH", 41 | rpc: "https://mainnet.base.org", 42 | chainId: 8453, 43 | explorer: 'https://basescan.org' 44 | }, 45 | } 46 | 47 | export const contracts: Record = { 48 | 11155111: { 49 | presale: { 50 | address: '0x3D770dD48a9a43D0cC8455aDBF57D8B02326a50b', 51 | abi: PRESALE_ABI, 52 | }, 53 | usdc: { 54 | address: '0xA1f5aE420cCAAadA3ddF121afA72E22483b538B9', 55 | abi: USDC_ABI, 56 | }, 57 | mars: { 58 | address: '0x5C2A60632BeaEb5aeF7F0D82088FC620BEC5b376', 59 | abi: MARS_ABI, 60 | }, 61 | nft: { 62 | address: '0xA9F7B854c755369c330F269e3bF6bb22E0BE2517', 63 | abi: NFT_ABI 64 | } 65 | }, 66 | // 8453: { 67 | // presale: { 68 | // address: '', 69 | // contract: '', 70 | // }, 71 | // usdc: { 72 | // address: '', 73 | // contract: '', 74 | // }, 75 | // mars: { 76 | // address: '', 77 | // contract: '', 78 | // }, 79 | // nft: { 80 | // address: '', 81 | // contract: '' 82 | // } 83 | // }, 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/app/presale/page.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | "use client" 3 | import React from "react"; 4 | import Header from "@/components/presale/header"; 5 | import AOS from "aos"; 6 | import Tokenomics from "@/components/main/tokenomics"; 7 | import Marquee from "react-fast-marquee"; 8 | import TopOwners from "@/components/presale/topOwners"; 9 | import { useRouter } from "next/navigation"; 10 | 11 | import dynamic from "next/dynamic"; 12 | import BuySuccess from "@/components/presale/congratulate"; 13 | 14 | const Sparkles = dynamic(() => import("@/components/ui/sparkle"), {ssr:false}); 15 | 16 | const SparklesCore = dynamic(() => import("@/components/ui/sparkles"), { ssr: false }); 17 | const Meteors = dynamic(() => import("@/components/ui/meteors"), {ssr: false}); 18 | 19 | const Presale = () => { 20 | 21 | const router = useRouter (); 22 | 23 | React.useEffect(() => { 24 | AOS.init(); 25 | // eslint-disable-next-line react-hooks/exhaustive-deps 26 | }, []); 27 | 28 | const Lecture = () => ( 29 |
38 | 39 |
40 | ); 41 | 42 | const Marqee = () => ( 43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |
58 |
59 | ) 60 | 61 | return ( 62 |
63 |
64 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | 81 | 82 |
83 | ); 84 | }; 85 | 86 | export default Presale; 87 | -------------------------------------------------------------------------------- /src/components/nft/nftItem.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import {Button, Image, Skeleton} from "@nextui-org/react"; 5 | import {Icon} from "@iconify/react"; 6 | import LazyImage from "./lazyImage"; 7 | 8 | import {cn} from "@/utils/cn"; 9 | import { NFT } from "@/types/utils"; 10 | 11 | export type PlaceListItemColor = { 12 | name: string; 13 | hex: string; 14 | }; 15 | 16 | export type PlaceListItemProps = Omit, "id"> & { 17 | isPopular?: boolean; 18 | isLoading?: boolean; 19 | removeWrapper?: boolean; 20 | } & NFT; 21 | 22 | const PlaceListItem = React.forwardRef( 23 | ( 24 | {name, isLoading, description, image, removeWrapper, className, ...props}, 25 | ref, 26 | ) => { 27 | const [isLiked, setIsLiked] = React.useState(false); 28 | 29 | return ( 30 |
41 | 57 | 58 |
59 | 62 |
63 | 64 |
65 | {isLoading ? ( 66 |
67 | 68 |
69 | 70 | 71 |
72 | 73 | 74 |
75 | 76 |
77 | ) : ( 78 | <> 79 |
80 |

{name}

81 | {/* {rating !== undefined ? ( 82 |
83 | 84 | {rating} 85 |
86 | ) : null} */} 87 |
88 | {description ?

{description}

: null} 89 | {/*

${price}

*/} 90 | 91 | )} 92 |
93 |
94 | ); 95 | }, 96 | ); 97 | 98 | PlaceListItem.displayName = "PlaceListItem"; 99 | 100 | export default PlaceListItem; 101 | -------------------------------------------------------------------------------- /src/components/nft/mintItem.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import {Button, Image, Skeleton} from "@nextui-org/react"; 5 | import {Icon} from "@iconify/react"; 6 | import LazyImage from "./lazyImage"; 7 | 8 | import {cn} from "@/utils/cn"; 9 | import { NFT } from "@/types/utils"; 10 | 11 | export type PlaceListItemColor = { 12 | name: string; 13 | hex: string; 14 | }; 15 | 16 | export type PlaceListItemProps = Omit, "id"> & { 17 | isPopular?: boolean; 18 | isLoading?: boolean; 19 | removeWrapper?: boolean; 20 | onMint: (_nft: NFT) => void; 21 | } & NFT; 22 | 23 | const PlaceListItem = React.forwardRef( 24 | ( 25 | {name, _id, isLoading, onMint, description, image, removeWrapper, className, ...props}, 26 | ref, 27 | ) => { 28 | const [isLiked, setIsLiked] = React.useState(false); 29 | 30 | return ( 31 |
42 | 58 | 59 |
60 | 63 | 66 |
67 | 68 | 69 |
70 | {isLoading ? ( 71 |
72 | 73 |
74 | 75 | 76 |
77 | 78 | 79 |
80 | 81 |
82 | ) : ( 83 | <> 84 |
85 |

{name}

86 | {/* {rating !== undefined ? ( 87 |
88 | 89 | {rating} 90 |
91 | ) : null} */} 92 |
93 | {description ?

{description}

: null} 94 | {/*

${price}

*/} 95 | 96 | )} 97 |
98 |
99 | ); 100 | }, 101 | ); 102 | 103 | PlaceListItem.displayName = "PlaceListItem"; 104 | 105 | export default PlaceListItem; 106 | -------------------------------------------------------------------------------- /public/img/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | /* eslint-disable @next/next/no-img-element */ 3 | import Image from "next/image"; 4 | import React from "react"; 5 | import AOS from "aos"; 6 | import Marquee from "react-fast-marquee"; 7 | import dynamic from "next/dynamic"; 8 | import { Icon } from "@iconify/react/dist/iconify.js"; 9 | 10 | import Header from "@/components/main/header"; 11 | import Tokenomics from "@/components/main/tokenomics"; 12 | import RoadMap from "@/components/main/roadMap"; 13 | import FAQ from "@/components/main/faq"; 14 | import Footer from "@/components/main/footer"; 15 | import Address from "@/components/main/address"; 16 | import NFTCard from "@/components/main/nft"; 17 | 18 | const SparklesCore = dynamic(() => import("@/components/ui/sparkles"), { ssr: false }); 19 | const Meteors = dynamic(() => import("@/components/ui/meteors"), {ssr: false}); 20 | 21 | import { useRouter } from "next/navigation"; 22 | import Sparkles from "@/components/ui/sparkle"; 23 | 24 | export default function Home() { 25 | 26 | const router = useRouter (); 27 | 28 | React.useEffect(() => { 29 | AOS.init(); 30 | // eslint-disable-next-line react-hooks/exhaustive-deps 31 | }, []); 32 | 33 | return ( 34 |
35 |
36 | 45 | 46 | 47 |
48 |
49 |
50 |
59 | 60 |
61 | 62 | 63 | {/* */} 70 |
71 | 72 |
73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 |
84 |
85 |
86 | 87 |
88 | 89 |
90 | 91 |
92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |
103 |
104 |
105 |
106 |
107 |
108 | ); 109 | } 110 | -------------------------------------------------------------------------------- /src/app/nft/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | /* eslint-disable @next/next/no-img-element */ 3 | import Image from "next/image"; 4 | import React from "react"; 5 | import AOS from "aos"; 6 | import dynamic from "next/dynamic"; 7 | 8 | const SparklesCore = dynamic(() => import("@/components/ui/sparkles"), { ssr: false }); 9 | const Meteors = dynamic(() => import("@/components/ui/meteors"), { ssr: false }); 10 | 11 | import { useRouter } from "next/navigation"; 12 | import Sparkles from "@/components/ui/sparkle"; 13 | import WalletConnectButton from "@/components/presale/connectButton"; 14 | import { NFT } from "@/types/utils"; 15 | import NFTItem from "@/components/nft/nftItem"; 16 | import { Contract, providers } from "ethers"; 17 | import { chains, contracts } from "@/constants/config"; 18 | import NFTLoader from "@/components/nft/loader"; 19 | 20 | 21 | export default function Home() { 22 | 23 | const router = useRouter(); 24 | const [showMintModal, setShowMintModal] = React.useState(false); 25 | const [nfts, setNfts] = React.useState([]); 26 | const [isLoading, setIsLoading] = React.useState(true); 27 | 28 | React.useEffect(() => { 29 | AOS.init(); 30 | // eslint-disable-next-line react-hooks/exhaustive-deps 31 | }, []); 32 | 33 | const initialize = async () => { 34 | try { 35 | setIsLoading(true); 36 | const chainId = 11155111; 37 | const _chain = chains[chainId]; 38 | // web3 provider 39 | const provider = new providers.JsonRpcProvider(_chain.rpc); 40 | const { address: contractAddress, abi } = contracts[chainId].nft; 41 | const _contract = new Contract(contractAddress, abi, provider); 42 | 43 | const _tokenNumber = await _contract.tokenNumber(); 44 | // get nfts 45 | const _nfts: NFT[] = await Promise.all(new Array(Number(_tokenNumber)).fill("").map(async (item: string, index: number) => { 46 | const _tokenURI = await _contract.tokenURI(index); 47 | const _response = await fetch(_tokenURI); 48 | const _data = await _response.json(); 49 | return { 50 | _id: index + '', 51 | name: String(_data.name), 52 | description: String(_data.description), 53 | image: String(_data.image) 54 | }; 55 | })); 56 | console.log(_nfts) 57 | setNfts(_nfts); 58 | 59 | } catch { 60 | 61 | } finally { 62 | setIsLoading(false); 63 | } 64 | } 65 | 66 | React.useEffect(() => { 67 | initialize(); 68 | // eslint-disable-next-line react-hooks/exhaustive-deps 69 | }, [showMintModal]); 70 | 71 | return ( 72 |
73 |
74 | 83 | 84 | 85 | 86 |
87 |
88 |
89 |
90 | 110 |
119 |

Mars NFT

120 |
121 |
130 | 131 | 132 | 133 |
134 |
135 |
136 | 137 |
138 | 139 |
140 | {/* {nfts.map((_nft: NFT) => ( 141 | 142 | ))} */} 143 | { 144 | isLoading ? : 145 | nfts.map((_nft: NFT, index: number) => ) 146 | } 147 |
148 |
149 | 150 |
151 |
152 | ); 153 | } 154 | -------------------------------------------------------------------------------- /src/app/nft/mint/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | /* eslint-disable @next/next/no-img-element */ 3 | import React from "react"; 4 | import AOS from "aos"; 5 | import dynamic from "next/dynamic"; 6 | 7 | const SparklesCore = dynamic(() => import("@/components/ui/sparkles"), { ssr: false }); 8 | const Meteors = dynamic(() => import("@/components/ui/meteors"), { ssr: false }); 9 | 10 | import { useRouter } from "next/navigation"; 11 | import Sparkles from "@/components/ui/sparkle"; 12 | import FreeMint from "@/components/main/mint"; 13 | import WalletConnectButton from "@/components/presale/connectButton"; 14 | import { NFT } from "@/types/utils"; 15 | import NftItem from "@/components/nft/mintItem"; 16 | import { SERVER_URL } from "@/constants/config"; 17 | import axios from "axios"; 18 | import NFTLoader from "@/components/nft/loader"; 19 | 20 | export default function Home() { 21 | 22 | const router = useRouter(); 23 | const [showMintModal, setShowMintModal] = React.useState(false); 24 | const [nfts, setNfts] = React.useState([]); 25 | const [isLoading, setIsLoading] = React.useState(true); 26 | const [nft, setNft] = React.useState(undefined); 27 | 28 | React.useEffect(() => { 29 | AOS.init(); 30 | // eslint-disable-next-line react-hooks/exhaustive-deps 31 | }, []); 32 | 33 | const intialize = async () => { 34 | try { 35 | setIsLoading (true); 36 | const data = await axios.get(`${SERVER_URL}/nft/nfts`); 37 | setNfts (data.data); 38 | } catch (err) { 39 | 40 | } finally { 41 | setIsLoading (false); 42 | } 43 | } 44 | React.useEffect(() => { 45 | intialize (); 46 | // eslint-disable-next-line react-hooks/exhaustive-deps 47 | }, []); 48 | 49 | 50 | const onMint = (_nft: NFT) => { 51 | setNft (_nft); 52 | setShowMintModal (true); 53 | } 54 | 55 | return ( 56 |
57 |
58 | 67 | 68 | 69 | 70 |
71 |
72 | {showMintModal && nft && setShowMintModal(false)} />} 73 |
74 |
75 | 97 |
106 |

mint mars NFT

107 |
108 |
117 | 118 | 119 | 120 |
121 |
122 |
123 |
124 |
{nfts.length}/5000
125 |
126 | { 127 | isLoading ? : 128 | nfts.map((_nft: NFT, index: number) => ) 129 | } 130 |
131 |
132 | 133 |
134 |
135 | ); 136 | } 137 | -------------------------------------------------------------------------------- /src/components/main/tokenomics.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | import React from "react"; 3 | 4 | const Tokenomics = () => { 5 | const chart = React.useRef(null); 6 | 7 | const [progress, setProgress] = React.useState(95); 8 | 9 | React.useEffect(() => { 10 | if (!chart.current) return; 11 | const canvas = document.getElementById("donutChart"); 12 | const ctx: CanvasRenderingContext2D = chart.current.getContext("2d") as CanvasRenderingContext2D; 13 | const centerX = chart.current.width / 2; 14 | const centerY = chart.current.height / 2; 15 | const radius = 175; // Adjust the radius 16 | const strokeWidth = 60; // Adjust the stroke width 17 | const borderThickness = 2; // Adjust the border thickness 18 | const parts = [12.5, 17.5, 10, 5, 5, 5, 10, 5, 30]; // Adjust the values 19 | const total = parts.reduce((acc, val) => acc + val, 0); 20 | const gap = 0.05; // Adjust the gap between parts 21 | const colors = [ 22 | "#EFB1EA", //pink 23 | "#F15A29", // orange 24 | "#662A75", //violet 25 | "#3E2274", //blue 26 | "#D1B4FF", //light gray 27 | "#42C7E8", //sky 28 | "#C56D74", // dark orange 29 | "#CB0A16", //red 30 | "#42C7E8", //sky 31 | ]; // Updated colors array 32 | 33 | let startAngle = -Math.PI / 2; 34 | for (let i = 0; i < parts.length; i++) { 35 | const percentage = parts[i] / total; 36 | const endAngle = startAngle + 2 * Math.PI * percentage; 37 | 38 | // Draw the border for each part 39 | ctx.beginPath(); 40 | ctx.arc(centerX, centerY, radius, startAngle, endAngle - gap); 41 | ctx.lineWidth = strokeWidth + borderThickness * 5; // Adjust border thickness 42 | ctx.strokeStyle = "#2D2D2D"; // Adjust border color 43 | ctx.stroke(); 44 | 45 | // Draw the donut part 46 | ctx.beginPath(); 47 | ctx.arc(centerX, centerY, radius, startAngle, endAngle - gap); 48 | ctx.lineWidth = strokeWidth; 49 | const partColor = colors[i]; 50 | ctx.strokeStyle = partColor; 51 | ctx.stroke(); 52 | 53 | startAngle = endAngle; 54 | } 55 | // eslint-disable-next-line react-hooks/exhaustive-deps 56 | }, [progress]); 57 | 58 | return ( 59 |
60 |
61 |
62 |

TOKENOMICS

63 |
64 |
65 |
66 |
75 |
    76 |
  • 77 | 12.5% 78 | tier1 private sale 79 |
  • 80 |
  • 81 | 17.5% 82 | tier2 private sale 83 |
  • 84 |
  • 85 | 10% 86 | AI Pepe holders airdrop 87 |
  • 88 |
  • 89 | 5% 90 | team (vested) 91 |
  • 92 |
93 |
94 |
103 |
104 | 105 |
106 | 107 |
108 |
117 |
    118 |
  • 119 | 5% 120 | advisors 121 |
  • 122 |
  • 123 | 5% 124 | market making 125 |
  • 126 |
  • 127 | 10% 128 | Marketing 129 |
  • 130 |
  • 131 | 5%, 30% 132 | CEX & Liquidity Provider 133 |
  • 134 |
135 |
136 |
137 |
146 |
    147 |
  • Symbol: MARSWTF
  • 148 |
  • Supply: 1 billion
  • 149 |
  • Network: BASE
  • 150 |
151 |
152 |
153 |
154 |
155 | ); 156 | }; 157 | 158 | export default Tokenomics; 159 | -------------------------------------------------------------------------------- /src/components/main/nft.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | "use client" 3 | import React from "react"; 4 | import { Icon } from "@iconify/react/dist/iconify.js"; 5 | import Image from "next/image"; 6 | import { Swiper, SwiperSlide } from 'swiper/react'; 7 | import { EffectCards } from 'swiper/modules'; 8 | import { Keyboard, Pagination, Navigation } from 'swiper/modules'; 9 | import Sparkles from "../ui/sparkle"; 10 | import { useRouter } from "next/navigation"; 11 | import { Contract, providers } from "ethers"; 12 | import { chains, contracts } from "@/constants/config"; 13 | import { NFT } from "@/types/chain"; 14 | 15 | const NFTCard = () => { 16 | const [nfts, setNfts] = React.useState([]); 17 | const router = useRouter (); 18 | 19 | const initialize = async () => { 20 | const chainId = 11155111; 21 | const _chain = chains[chainId]; 22 | // web3 provider 23 | const provider = new providers.JsonRpcProvider(_chain.rpc); 24 | const { address: contractAddress, abi } = contracts[chainId].nft; 25 | const _contract = new Contract(contractAddress, abi, provider); 26 | 27 | const _tokenNumber = await _contract.tokenNumber (); 28 | // get nfts 29 | const _nfts: NFT[] = await Promise.all(new Array(Number(_tokenNumber)).fill("").map(async(item: string, index: number) => { 30 | const _tokenURI = await _contract.tokenURI(index); 31 | const _response = await fetch(_tokenURI); 32 | const _data = await _response.json(); 33 | return _data; 34 | })); 35 | setNfts (_nfts); 36 | } 37 | 38 | React.useEffect(() => { 39 | initialize(); 40 | // eslint-disable-next-line react-hooks/exhaustive-deps 41 | }, []); 42 | 43 | return ( 44 |
54 |
55 |
56 |

Mars NFTs

57 |
58 |
59 | 70 | { 71 | nfts.length === 1 && 72 | 73 |
74 | me 82 |
83 |
{nfts[0].name}
84 |
85 | {/* onPlay(_movie.snippet.title, `https://www.youtube.com/watch?v=${_movie.snippet.resourceId.videoId}`)} icon="logos:youtube-icon" className="absolute left-1/2 top-1/2 text-5xl md:text-8xl -translate-x-1/2 -translate-y-1/2 hover:opacity-60 cursor-pointer" /> */} 86 |
87 |
88 | } 89 | { 90 | nfts.map((_nft: NFT, index: number) => ( 91 | 92 |
93 | me 101 |
102 |
{_nft.name}
103 |
104 | {/* onPlay(_movie.snippet.title, `https://www.youtube.com/watch?v=${_movie.snippet.resourceId.videoId}`)} icon="logos:youtube-icon" className="absolute left-1/2 top-1/2 text-5xl md:text-8xl -translate-x-1/2 -translate-y-1/2 hover:opacity-60 cursor-pointer" /> */} 105 |
106 |
107 | )) 108 | } 109 |
110 |
111 |
112 | 113 | router.push("/nft")} className="btn-primary text-white mb-24 cursor-pointer mt-10"> 114 | Mars NFT 115 | 116 | 117 |
118 | ); 119 | }; 120 | 121 | export default NFTCard; 122 | -------------------------------------------------------------------------------- /src/components/presale/header.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | "use client"; 3 | import React from "react"; 4 | import Marquee from "react-fast-marquee"; 5 | import Image from "next/image"; 6 | import dynamic from "next/dynamic"; 7 | import WalletConnectButton from "./connectButton"; 8 | import Buy from "./buy"; 9 | 10 | import { useRouter } from "next/navigation"; 11 | import BuySuccess from "./congratulate"; 12 | 13 | const Header = () => { 14 | 15 | const router = useRouter (); 16 | //congratulations 17 | const [showConfetti, setShowConfetti] = React.useState(false); 18 | 19 | const _renderMarquee = () => ( 20 | 21 |
25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 |
76 |
77 | ); 78 | 79 | const onBuySuccess = (hash: string) => { 80 | setShowConfetti (true); 81 | } 82 | 83 | return ( 84 |
85 |
86 |
87 |
96 | 113 |
114 |
123 |

$MARSWTF

124 |
125 |
134 | 135 |
136 |
137 |
138 |
139 |
148 |
149 |

STAGE1

150 |

151 | $MARSWTF
152 | PRESALE 153 |

154 |
155 |
156 | 164 |
165 |

YOUR MARS TICKET IS ABOUT TO BECOME A REALITY

166 |

BUY NOW BEFORE THE PRICE INCREASES

167 |
168 |
169 |
170 | 171 | 172 |
173 | 174 |
183 | { _renderMarquee () } 184 |
185 | { showConfetti && setShowConfetti (false)}/> } 186 |
187 | ); 188 | }; 189 | 190 | export default Header; 191 | -------------------------------------------------------------------------------- /src/components/presale/connectButton.tsx: -------------------------------------------------------------------------------- 1 | import { ConnectButton } from '@rainbow-me/rainbowkit'; 2 | import Image from 'next/image'; 3 | import React from 'react'; 4 | import { Icon } from '@iconify/react/dist/iconify.js'; 5 | import { useRouter } from 'next/navigation'; 6 | import useActiveWeb3 from '@/hooks/useActiveWeb3'; 7 | 8 | const WalletConnectButton = () => { 9 | 10 | const router = useRouter (); 11 | const { isConnected } = useActiveWeb3 (); 12 | const [isLoading, setIsLoading] = React.useState(false); 13 | 14 | 15 | 16 | return ( 17 | 18 | {({ 19 | account, 20 | chain, 21 | openAccountModal, 22 | openChainModal, 23 | openConnectModal, 24 | authenticationStatus, 25 | mounted, 26 | }) => { 27 | // Note: If your app doesn't use authentication, you 28 | // can remove all 'authenticationStatus' checks 29 | const ready = mounted && authenticationStatus !== 'loading'; 30 | const connected = 31 | ready && 32 | account && 33 | chain && 34 | (!authenticationStatus || 35 | authenticationStatus === 'authenticated'); 36 | return ( 37 |
47 | {(() => { 48 | if (!connected) { 49 | return ( 50 | 54 | ); 55 | } if (chain.unsupported) { 56 | return ( 57 | 65 | ); 66 | } 67 | return ( 68 |
69 | 88 | 89 | 126 |
127 | ); 128 | })()} 129 |
130 | ); 131 | }} 132 |
133 | ); 134 | }; 135 | 136 | export default WalletConnectButton; -------------------------------------------------------------------------------- /src/components/presale/topOwners.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | import React from "react"; 3 | import axios from "axios"; 4 | import Image from "next/image"; 5 | 6 | interface IHolder { 7 | wallet_address: string; 8 | amount: number; 9 | cnt: number; 10 | } 11 | 12 | const TopOwners = () => { 13 | const chart = React.useRef(null); 14 | 15 | const [holders, setHolders] = React.useState([]); 16 | 17 | React.useEffect(() => { 18 | if (!chart.current || holders.length === 0) return; 19 | const ctx: CanvasRenderingContext2D = chart.current.getContext( 20 | "2d" 21 | ) as CanvasRenderingContext2D; 22 | 23 | const _top10s = holders.slice(1, 11); 24 | const _total = _top10s.reduce( 25 | (accumulator: number, _user: IHolder) => 26 | accumulator + Number(_user.amount), 27 | 0 28 | ); 29 | 30 | const centerX = chart.current.width / 2; 31 | const centerY = chart.current.height / 2; 32 | const radius = 175; // Adjust the radius 33 | const strokeWidth = 60; // Adjust the stroke width 34 | const borderThickness = 2; // Adjust the border thickness 35 | const gap = 0.05; // Adjust the gap between parts 36 | const colors = [ 37 | "#CB0A16", //red 38 | "#EFB1EA", //pink 39 | "#F15A29", // orange 40 | "#662A75", //violet 41 | "#3E2274", //dark blue 42 | "#7e788b", //blue 43 | "#D1B4FF", //light gray 44 | "#C56D74", // dark orange 45 | "#67d626", //yello 46 | "#42C7E8", //sky 47 | ]; // Updated colors array 48 | 49 | let startAngle = -Math.PI / 2; 50 | for (let i = 0; i < 10; i++) { 51 | const percentage = Number(_top10s[i].amount) / _total; 52 | 53 | const endAngle = startAngle + 2 * Math.PI * percentage; 54 | 55 | // Draw the border for each part 56 | ctx.beginPath(); 57 | ctx.arc(centerX, centerY, radius, startAngle, endAngle - gap); 58 | ctx.lineWidth = strokeWidth + borderThickness * 5; // Adjust border thickness 59 | ctx.strokeStyle = "#2D2D2D"; // Adjust border color 60 | ctx.stroke(); 61 | 62 | // Draw the donut part 63 | ctx.beginPath(); 64 | ctx.arc(centerX, centerY, radius, startAngle, endAngle - gap); 65 | ctx.lineWidth = strokeWidth; 66 | const partColor = colors[i]; 67 | ctx.strokeStyle = partColor; 68 | ctx.stroke(); 69 | 70 | startAngle = endAngle; 71 | } 72 | // eslint-disable-next-line react-hooks/exhaustive-deps 73 | }, [holders]); 74 | 75 | React.useEffect(() => { 76 | axios 77 | .get(`https://marswtf-backend.onrender.com/api/holders`) 78 | .then(({ data: { holders } }) => { 79 | setHolders(holders); 80 | }) 81 | .catch((err) => { 82 | console.log(err); 83 | }); 84 | // eslint-disable-next-line react-hooks/exhaustive-deps 85 | }, []); 86 | 87 | 88 | 89 | return ( 90 | <> 91 |
92 |

TOP 10 OWNERS

93 |
103 |
112 |
113 | 114 |
115 | 121 |
122 | 123 |
124 | { 125 | holders[0] && 126 |
127 | 135 | {holders[1]?.wallet_address} 136 |
137 | } 138 | 139 | {holders.slice(2, 11).map((_holder: IHolder, index: number) => ( 140 |
144 | 152 | {_holder.wallet_address} 153 |
154 | ))} 155 |
156 |
157 |
158 |
159 |

TOP 100 OWNERS

160 |
169 | { 170 | holders.map((_holder: IHolder, index: number) => ( 171 |
172 | #{index+1} 173 | {_holder.wallet_address} 174 |
10ETH
175 |
176 | )) 177 | } 178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |

©COPYRIGHT2024

186 |

MARSWTF, LLC

187 |
188 | 189 | ); 190 | }; 191 | 192 | export default TopOwners; 193 | -------------------------------------------------------------------------------- /src/components/main/roadMap.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | import React from "react"; 3 | 4 | const RoadMap = () => { 5 | const chart = React.useRef(null); 6 | 7 | const [progress, setProgress] = React.useState(95); 8 | 9 | React.useEffect(() => { 10 | if (!chart.current) return; 11 | const canvas = document.getElementById("donutChart"); 12 | const ctx: CanvasRenderingContext2D = chart.current.getContext( 13 | "2d" 14 | ) as CanvasRenderingContext2D; 15 | const centerX = chart.current.width / 2; 16 | const centerY = chart.current.height / 2; 17 | const radius = 175; // Adjust the radius 18 | const strokeWidth = 60; // Adjust the stroke width 19 | const borderThickness = 2; // Adjust the border thickness 20 | const parts = [25, 15, 10, 6, 4, 10, 5, 25]; // Adjust the values 21 | const total = parts.reduce((acc, val) => acc + val, 0); 22 | const gap = 0.05; // Adjust the gap between parts 23 | const colors = [ 24 | "#EFB1EA", //pink 25 | "#F15A29", // orange 26 | "#662A75", //violet 27 | "#3E2274", //blue 28 | "#D1B4FF", //light gray 29 | "#42C7E8", //sky 30 | "#C56D74", // dark orange 31 | "#CB0A16", //red 32 | ]; // Updated colors array 33 | 34 | let startAngle = -Math.PI / 2; 35 | for (let i = 0; i < parts.length; i++) { 36 | const percentage = parts[i] / total; 37 | const endAngle = startAngle + 2 * Math.PI * percentage; 38 | 39 | // Draw the border for each part 40 | ctx.beginPath(); 41 | ctx.arc(centerX, centerY, radius, startAngle, endAngle); 42 | ctx.lineWidth = strokeWidth + borderThickness * 5; // Adjust border thickness 43 | ctx.strokeStyle = "#2D2D2D"; // Adjust border color 44 | ctx.stroke(); 45 | 46 | // Draw the donut part 47 | ctx.beginPath(); 48 | ctx.arc(centerX, centerY, radius, startAngle, endAngle); 49 | ctx.lineWidth = strokeWidth; 50 | const partColor = colors[i]; 51 | ctx.strokeStyle = partColor; 52 | ctx.stroke(); 53 | 54 | startAngle = endAngle + gap; 55 | } 56 | // eslint-disable-next-line react-hooks/exhaustive-deps 57 | }, [progress]); 58 | 59 | return ( 60 | <> 61 |
62 |

MARS 101

63 |
72 |
73 |

74 | $WENMars
75 | is where it's at, degens! 76 |

77 |

78 | Forget moon memes, Mars is the real game. Powered by Elon's 79 | dream and our degen spirit, this coin is your Mars ticket. 80 |

81 |

82 | It's not just hype; it's the heartbeat of our future 83 | Martian empire. Packed with utility, steeped in culture, $WENMars 84 | is the crypto rebellion we've been waiting for. 85 |

86 |

87 | Ready to rule the red planet? Grab $WENMars, join the charge, and 88 | let's plant our flag on Mars. Get in, strap up, we'e 89 | launching! 90 |

91 |
92 |
93 |
94 |
95 |

ROADMAP

96 |
97 |
98 |
107 |

Phase 1

108 |

Blast Off

109 |
    110 |
  • Token Drop: $WENMars hits the market.
  • 111 |
  • Telegram Takeover: Our Martian base.
  • 112 |
  • Meme War: We invade the net.
  • 113 |
  • Lock Liquidity: Secure the bag.
  • 114 |
115 |
116 |
125 |

Phase 2

126 |

Martian Expansion

127 |
    128 |
  • 129 | Cosmic Alliances: Partner with Martian research and space tech 130 | entities. 131 |
  • 132 |
  • 133 | Red Planet Rewards: Launch staking to earn exclusive Martian 134 | assets. 135 |
  • 136 |
  • 137 | Martian Media Blitz: Engage with influencers for galactic meme 138 | invasions. 139 |
  • 140 |
  • 141 | Telegram Mars Hub: Grow our channel into a thriving Martian 142 | community outpost. 143 |
  • 144 |
145 |
146 |
147 |
148 |
157 |

Phase 3

158 |

Build Mars

159 |
    160 |
  • NFT Drop: Own a piece of Mars.
  • 161 |
  • Amplify the Hype - Unite Martians and dominate Mars!
  • 162 |
  • Martian Market: Trade your loot.
  • 163 |
  • Martian Council: Rule the red.
  • 164 |
165 |
166 |
175 |

Phase 4

176 |

Galactic Domination

177 |
    178 |
  • Big Exchange Listings: $WENMars goes universal.
  • 179 |
  • Chain Bridges: Mars everywhere.
  • 180 |
  • Martian Metaverse: Live the red dream.
  • 181 |
  • Mars Summit: The degen meetup.
  • 182 |
183 |
184 |
185 |
186 |
187 | 188 | ); 189 | }; 190 | 191 | export default RoadMap; 192 | -------------------------------------------------------------------------------- /src/providers/toastProvider.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | "use client" 3 | import { ReactElement, createContext } from "react"; 4 | import { Toaster, toast } from "react-hot-toast"; 5 | 6 | interface IToastContext { 7 | showToast: (type: string, str: string) => void; 8 | } 9 | 10 | 11 | export const ToastContext = createContext(undefined); 12 | 13 | const ToastProvider = ({ children }: { children: ReactElement }) => { 14 | const showToast = (str: string, type: string) => { 15 | switch (type) { 16 | case "success": 17 | toast.custom((t) => ( 18 |
toast.dismiss(t.id)} 22 | style={{ zIndex: "100000!important", width: '320px' }} 23 | > 24 |
25 |
26 | 33 |
34 |

{str}

35 |
36 |
37 |
38 |
39 | 55 |
56 |
57 | )); 58 | break; 59 | case "warning": 60 | toast.custom((t) => ( 61 |
toast.dismiss(t.id)} 65 | style={{ zIndex: "100000!important", width: '320px' }} 66 | > 67 |
68 |
69 | 76 |
77 |

{str}

78 |
79 |
80 |
81 |
82 | 98 |
99 |
100 | )); 101 | break; 102 | case "question": 103 | toast.custom((t) => ( 104 |
toast.dismiss(t.id)} 108 | style={{ zIndex: "100000!important", width: '320px' }} 109 | > 110 |
111 |
112 | 119 |
120 |

{str}

121 |
122 |
123 |
124 |
125 | 141 |
142 |
143 | )); 144 | break; 145 | case "error": 146 | toast.custom((t) => ( 147 |
toast.dismiss(t.id)} 151 | style={{ zIndex: "100000!important", width: '320px' }} 152 | > 153 |
154 |
155 | 162 |
163 |

{str}

164 |
165 |
166 |
167 |
168 | 184 |
185 |
186 | )); 187 | break; 188 | } 189 | }; 190 | return ( 191 | 192 | 193 | {children} 194 | 195 | ); 196 | }; 197 | export default ToastProvider; 198 | -------------------------------------------------------------------------------- /src/constants/abis/mars.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "stateMutability": "nonpayable", 5 | "type": "constructor" 6 | }, 7 | { 8 | "anonymous": false, 9 | "inputs": [ 10 | { 11 | "indexed": true, 12 | "internalType": "address", 13 | "name": "owner", 14 | "type": "address" 15 | }, 16 | { 17 | "indexed": true, 18 | "internalType": "address", 19 | "name": "spender", 20 | "type": "address" 21 | }, 22 | { 23 | "indexed": false, 24 | "internalType": "uint256", 25 | "name": "value", 26 | "type": "uint256" 27 | } 28 | ], 29 | "name": "Approval", 30 | "type": "event" 31 | }, 32 | { 33 | "anonymous": false, 34 | "inputs": [ 35 | { 36 | "indexed": true, 37 | "internalType": "address", 38 | "name": "previousOwner", 39 | "type": "address" 40 | }, 41 | { 42 | "indexed": true, 43 | "internalType": "address", 44 | "name": "newOwner", 45 | "type": "address" 46 | } 47 | ], 48 | "name": "OwnershipTransferred", 49 | "type": "event" 50 | }, 51 | { 52 | "anonymous": false, 53 | "inputs": [ 54 | { 55 | "indexed": true, 56 | "internalType": "address", 57 | "name": "from", 58 | "type": "address" 59 | }, 60 | { 61 | "indexed": true, 62 | "internalType": "address", 63 | "name": "to", 64 | "type": "address" 65 | }, 66 | { 67 | "indexed": false, 68 | "internalType": "uint256", 69 | "name": "value", 70 | "type": "uint256" 71 | } 72 | ], 73 | "name": "Transfer", 74 | "type": "event" 75 | }, 76 | { 77 | "inputs": [ 78 | { 79 | "internalType": "address", 80 | "name": "uniswappairv3", 81 | "type": "address" 82 | } 83 | ], 84 | "name": "SetUniswapV3PairAddress", 85 | "outputs": [], 86 | "stateMutability": "nonpayable", 87 | "type": "function" 88 | }, 89 | { 90 | "inputs": [], 91 | "name": "_uniswapPair", 92 | "outputs": [ 93 | { 94 | "internalType": "address", 95 | "name": "", 96 | "type": "address" 97 | } 98 | ], 99 | "stateMutability": "view", 100 | "type": "function" 101 | }, 102 | { 103 | "inputs": [], 104 | "name": "_walletMAX", 105 | "outputs": [ 106 | { 107 | "internalType": "uint256", 108 | "name": "", 109 | "type": "uint256" 110 | } 111 | ], 112 | "stateMutability": "view", 113 | "type": "function" 114 | }, 115 | { 116 | "inputs": [ 117 | { 118 | "internalType": "address", 119 | "name": "owner", 120 | "type": "address" 121 | }, 122 | { 123 | "internalType": "address", 124 | "name": "spender", 125 | "type": "address" 126 | } 127 | ], 128 | "name": "allowance", 129 | "outputs": [ 130 | { 131 | "internalType": "uint256", 132 | "name": "", 133 | "type": "uint256" 134 | } 135 | ], 136 | "stateMutability": "view", 137 | "type": "function" 138 | }, 139 | { 140 | "inputs": [ 141 | { 142 | "internalType": "address", 143 | "name": "spender", 144 | "type": "address" 145 | }, 146 | { 147 | "internalType": "uint256", 148 | "name": "amount", 149 | "type": "uint256" 150 | } 151 | ], 152 | "name": "approve", 153 | "outputs": [ 154 | { 155 | "internalType": "bool", 156 | "name": "", 157 | "type": "bool" 158 | } 159 | ], 160 | "stateMutability": "nonpayable", 161 | "type": "function" 162 | }, 163 | { 164 | "inputs": [ 165 | { 166 | "internalType": "address", 167 | "name": "account", 168 | "type": "address" 169 | } 170 | ], 171 | "name": "balanceOf", 172 | "outputs": [ 173 | { 174 | "internalType": "uint256", 175 | "name": "", 176 | "type": "uint256" 177 | } 178 | ], 179 | "stateMutability": "view", 180 | "type": "function" 181 | }, 182 | { 183 | "inputs": [], 184 | "name": "decimals", 185 | "outputs": [ 186 | { 187 | "internalType": "uint8", 188 | "name": "", 189 | "type": "uint8" 190 | } 191 | ], 192 | "stateMutability": "view", 193 | "type": "function" 194 | }, 195 | { 196 | "inputs": [], 197 | "name": "name", 198 | "outputs": [ 199 | { 200 | "internalType": "string", 201 | "name": "", 202 | "type": "string" 203 | } 204 | ], 205 | "stateMutability": "view", 206 | "type": "function" 207 | }, 208 | { 209 | "inputs": [], 210 | "name": "owner", 211 | "outputs": [ 212 | { 213 | "internalType": "address", 214 | "name": "", 215 | "type": "address" 216 | } 217 | ], 218 | "stateMutability": "view", 219 | "type": "function" 220 | }, 221 | { 222 | "inputs": [], 223 | "name": "renounceOwnership", 224 | "outputs": [], 225 | "stateMutability": "nonpayable", 226 | "type": "function" 227 | }, 228 | { 229 | "inputs": [ 230 | { 231 | "internalType": "uint8", 232 | "name": "percentage", 233 | "type": "uint8" 234 | } 235 | ], 236 | "name": "setWalletMax", 237 | "outputs": [], 238 | "stateMutability": "nonpayable", 239 | "type": "function" 240 | }, 241 | { 242 | "inputs": [], 243 | "name": "symbol", 244 | "outputs": [ 245 | { 246 | "internalType": "string", 247 | "name": "", 248 | "type": "string" 249 | } 250 | ], 251 | "stateMutability": "view", 252 | "type": "function" 253 | }, 254 | { 255 | "inputs": [], 256 | "name": "totalSupply", 257 | "outputs": [ 258 | { 259 | "internalType": "uint256", 260 | "name": "", 261 | "type": "uint256" 262 | } 263 | ], 264 | "stateMutability": "view", 265 | "type": "function" 266 | }, 267 | { 268 | "inputs": [ 269 | { 270 | "internalType": "address", 271 | "name": "recipient", 272 | "type": "address" 273 | }, 274 | { 275 | "internalType": "uint256", 276 | "name": "amount", 277 | "type": "uint256" 278 | } 279 | ], 280 | "name": "transfer", 281 | "outputs": [ 282 | { 283 | "internalType": "bool", 284 | "name": "", 285 | "type": "bool" 286 | } 287 | ], 288 | "stateMutability": "nonpayable", 289 | "type": "function" 290 | }, 291 | { 292 | "inputs": [ 293 | { 294 | "internalType": "address", 295 | "name": "sender", 296 | "type": "address" 297 | }, 298 | { 299 | "internalType": "address", 300 | "name": "recipient", 301 | "type": "address" 302 | }, 303 | { 304 | "internalType": "uint256", 305 | "name": "amount", 306 | "type": "uint256" 307 | } 308 | ], 309 | "name": "transferFrom", 310 | "outputs": [ 311 | { 312 | "internalType": "bool", 313 | "name": "", 314 | "type": "bool" 315 | } 316 | ], 317 | "stateMutability": "nonpayable", 318 | "type": "function" 319 | }, 320 | { 321 | "inputs": [ 322 | { 323 | "internalType": "address", 324 | "name": "newOwner", 325 | "type": "address" 326 | } 327 | ], 328 | "name": "transferOwnership", 329 | "outputs": [], 330 | "stateMutability": "nonpayable", 331 | "type": "function" 332 | } 333 | ] -------------------------------------------------------------------------------- /src/constants/abis/usdc.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "stateMutability": "nonpayable", 5 | "type": "constructor" 6 | }, 7 | { 8 | "inputs": [ 9 | { 10 | "internalType": "address", 11 | "name": "spender", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "uint256", 16 | "name": "allowance", 17 | "type": "uint256" 18 | }, 19 | { 20 | "internalType": "uint256", 21 | "name": "needed", 22 | "type": "uint256" 23 | } 24 | ], 25 | "name": "ERC20InsufficientAllowance", 26 | "type": "error" 27 | }, 28 | { 29 | "inputs": [ 30 | { 31 | "internalType": "address", 32 | "name": "sender", 33 | "type": "address" 34 | }, 35 | { 36 | "internalType": "uint256", 37 | "name": "balance", 38 | "type": "uint256" 39 | }, 40 | { 41 | "internalType": "uint256", 42 | "name": "needed", 43 | "type": "uint256" 44 | } 45 | ], 46 | "name": "ERC20InsufficientBalance", 47 | "type": "error" 48 | }, 49 | { 50 | "inputs": [ 51 | { 52 | "internalType": "address", 53 | "name": "approver", 54 | "type": "address" 55 | } 56 | ], 57 | "name": "ERC20InvalidApprover", 58 | "type": "error" 59 | }, 60 | { 61 | "inputs": [ 62 | { 63 | "internalType": "address", 64 | "name": "receiver", 65 | "type": "address" 66 | } 67 | ], 68 | "name": "ERC20InvalidReceiver", 69 | "type": "error" 70 | }, 71 | { 72 | "inputs": [ 73 | { 74 | "internalType": "address", 75 | "name": "sender", 76 | "type": "address" 77 | } 78 | ], 79 | "name": "ERC20InvalidSender", 80 | "type": "error" 81 | }, 82 | { 83 | "inputs": [ 84 | { 85 | "internalType": "address", 86 | "name": "spender", 87 | "type": "address" 88 | } 89 | ], 90 | "name": "ERC20InvalidSpender", 91 | "type": "error" 92 | }, 93 | { 94 | "anonymous": false, 95 | "inputs": [ 96 | { 97 | "indexed": true, 98 | "internalType": "address", 99 | "name": "owner", 100 | "type": "address" 101 | }, 102 | { 103 | "indexed": true, 104 | "internalType": "address", 105 | "name": "spender", 106 | "type": "address" 107 | }, 108 | { 109 | "indexed": false, 110 | "internalType": "uint256", 111 | "name": "value", 112 | "type": "uint256" 113 | } 114 | ], 115 | "name": "Approval", 116 | "type": "event" 117 | }, 118 | { 119 | "anonymous": false, 120 | "inputs": [ 121 | { 122 | "indexed": true, 123 | "internalType": "address", 124 | "name": "from", 125 | "type": "address" 126 | }, 127 | { 128 | "indexed": true, 129 | "internalType": "address", 130 | "name": "to", 131 | "type": "address" 132 | }, 133 | { 134 | "indexed": false, 135 | "internalType": "uint256", 136 | "name": "value", 137 | "type": "uint256" 138 | } 139 | ], 140 | "name": "Transfer", 141 | "type": "event" 142 | }, 143 | { 144 | "inputs": [ 145 | { 146 | "internalType": "address", 147 | "name": "owner", 148 | "type": "address" 149 | }, 150 | { 151 | "internalType": "address", 152 | "name": "spender", 153 | "type": "address" 154 | } 155 | ], 156 | "name": "allowance", 157 | "outputs": [ 158 | { 159 | "internalType": "uint256", 160 | "name": "", 161 | "type": "uint256" 162 | } 163 | ], 164 | "stateMutability": "view", 165 | "type": "function" 166 | }, 167 | { 168 | "inputs": [ 169 | { 170 | "internalType": "address", 171 | "name": "spender", 172 | "type": "address" 173 | }, 174 | { 175 | "internalType": "uint256", 176 | "name": "value", 177 | "type": "uint256" 178 | } 179 | ], 180 | "name": "approve", 181 | "outputs": [ 182 | { 183 | "internalType": "bool", 184 | "name": "", 185 | "type": "bool" 186 | } 187 | ], 188 | "stateMutability": "nonpayable", 189 | "type": "function" 190 | }, 191 | { 192 | "inputs": [ 193 | { 194 | "internalType": "address", 195 | "name": "account", 196 | "type": "address" 197 | } 198 | ], 199 | "name": "balanceOf", 200 | "outputs": [ 201 | { 202 | "internalType": "uint256", 203 | "name": "", 204 | "type": "uint256" 205 | } 206 | ], 207 | "stateMutability": "view", 208 | "type": "function" 209 | }, 210 | { 211 | "inputs": [ 212 | { 213 | "internalType": "address", 214 | "name": "account", 215 | "type": "address" 216 | }, 217 | { 218 | "internalType": "uint256", 219 | "name": "amount", 220 | "type": "uint256" 221 | } 222 | ], 223 | "name": "burn", 224 | "outputs": [], 225 | "stateMutability": "nonpayable", 226 | "type": "function" 227 | }, 228 | { 229 | "inputs": [], 230 | "name": "decimals", 231 | "outputs": [ 232 | { 233 | "internalType": "uint8", 234 | "name": "", 235 | "type": "uint8" 236 | } 237 | ], 238 | "stateMutability": "view", 239 | "type": "function" 240 | }, 241 | { 242 | "inputs": [ 243 | { 244 | "internalType": "address", 245 | "name": "account", 246 | "type": "address" 247 | }, 248 | { 249 | "internalType": "uint256", 250 | "name": "amount", 251 | "type": "uint256" 252 | } 253 | ], 254 | "name": "mint", 255 | "outputs": [], 256 | "stateMutability": "nonpayable", 257 | "type": "function" 258 | }, 259 | { 260 | "inputs": [], 261 | "name": "name", 262 | "outputs": [ 263 | { 264 | "internalType": "string", 265 | "name": "", 266 | "type": "string" 267 | } 268 | ], 269 | "stateMutability": "view", 270 | "type": "function" 271 | }, 272 | { 273 | "inputs": [], 274 | "name": "symbol", 275 | "outputs": [ 276 | { 277 | "internalType": "string", 278 | "name": "", 279 | "type": "string" 280 | } 281 | ], 282 | "stateMutability": "view", 283 | "type": "function" 284 | }, 285 | { 286 | "inputs": [], 287 | "name": "totalSupply", 288 | "outputs": [ 289 | { 290 | "internalType": "uint256", 291 | "name": "", 292 | "type": "uint256" 293 | } 294 | ], 295 | "stateMutability": "view", 296 | "type": "function" 297 | }, 298 | { 299 | "inputs": [ 300 | { 301 | "internalType": "address", 302 | "name": "to", 303 | "type": "address" 304 | }, 305 | { 306 | "internalType": "uint256", 307 | "name": "value", 308 | "type": "uint256" 309 | } 310 | ], 311 | "name": "transfer", 312 | "outputs": [ 313 | { 314 | "internalType": "bool", 315 | "name": "", 316 | "type": "bool" 317 | } 318 | ], 319 | "stateMutability": "nonpayable", 320 | "type": "function" 321 | }, 322 | { 323 | "inputs": [ 324 | { 325 | "internalType": "address", 326 | "name": "from", 327 | "type": "address" 328 | }, 329 | { 330 | "internalType": "address", 331 | "name": "to", 332 | "type": "address" 333 | }, 334 | { 335 | "internalType": "uint256", 336 | "name": "value", 337 | "type": "uint256" 338 | } 339 | ], 340 | "name": "transferFrom", 341 | "outputs": [ 342 | { 343 | "internalType": "bool", 344 | "name": "", 345 | "type": "bool" 346 | } 347 | ], 348 | "stateMutability": "nonpayable", 349 | "type": "function" 350 | } 351 | ] -------------------------------------------------------------------------------- /src/components/main/header.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | import React from "react"; 3 | import Marquee from "react-fast-marquee"; 4 | import { useRouter } from 'next/navigation'; 5 | import axios from "axios"; 6 | import dynamic from "next/dynamic"; 7 | import { _renderNumber } from "@/utils/methods"; 8 | const Sparkles = dynamic(() => import("@/components/ui/sparkle"), { ssr: false }); 9 | import { BASE_URL, chains, contracts } from "@/constants/config"; 10 | import FreeMint from "./mint"; 11 | import { Contract, providers, utils } from "ethers"; 12 | 13 | 14 | const Header = () => { 15 | 16 | const router = useRouter(); 17 | const progressRef = React.useRef(null); 18 | 19 | 20 | const [presaleSoldMars, setPresaleSoldMars] = React.useState(0); 21 | const [presaleTotal, setPresaleTotal] = React.useState(0); 22 | 23 | const [currentPrice, setCurrentPrice] = React.useState(0); 24 | const [soldAmount, setSoldAmount] = React.useState(0); 25 | const [saleAmount, setSaleAmount] = React.useState(0); 26 | 27 | const initialize = async (_contract: Contract) => { 28 | if (!_contract) return; 29 | // view only 30 | const [ 31 | _sold, 32 | _sale, 33 | _currentPrice, 34 | // _presaleBalance, 35 | ] = await Promise.all([ 36 | _contract.soldAmount(), 37 | _contract.presaleAmount(), 38 | _contract.getCurrentTokenPrice(), 39 | ]); 40 | setSoldAmount(Number(utils.formatEther(_sold))); 41 | setSaleAmount(Number(utils.formatEther(_sale))); 42 | setCurrentPrice(Number(utils.formatUnits(_currentPrice, 6))); 43 | } 44 | 45 | React.useEffect(() => { 46 | const chainId = 11155111; 47 | const _chain = chains[chainId]; 48 | // web3 provider 49 | const provider = new providers.JsonRpcProvider(_chain.rpc); 50 | // presale contract 51 | const { address: presaleContractAddress, abi: presaleContractABI } = contracts[chainId].presale; 52 | const _presaleReadContract = new Contract(presaleContractAddress, presaleContractABI, provider); 53 | initialize(_presaleReadContract); 54 | // eslint-disable-next-line react-hooks/exhaustive-deps 55 | }, []); 56 | 57 | React.useEffect(() => { 58 | let percent = soldAmount * 100 / saleAmount; 59 | if (isNaN(percent)) { 60 | percent = 0; 61 | } else if (percent > 100) { 62 | percent = 100; 63 | } 64 | if (!progressRef.current) return; 65 | var initialWidth = percent; 66 | var currentWidth = 0; 67 | var animationSpeed = 1; 68 | var intervalDuration = 10; 69 | var interval = setInterval(frame, intervalDuration); 70 | 71 | function frame() { 72 | 73 | if (currentWidth >= initialWidth) { 74 | clearInterval(interval); 75 | } else { 76 | currentWidth += animationSpeed; 77 | if (currentWidth > initialWidth) { 78 | currentWidth = initialWidth; 79 | } 80 | if (!progressRef.current) return; 81 | console.log(initialWidth, currentWidth) 82 | progressRef.current.style.width = currentWidth + "%"; 83 | if (initialWidth > 0) { 84 | progressRef.current.style.background = 85 | "linear-gradient(8.6deg, #B5360C 6.57%, #DD5919 93.43%)"; 86 | } 87 | } 88 | } 89 | // eslint-disable-next-line react-hooks/exhaustive-deps 90 | }, [soldAmount, saleAmount]); 91 | 92 | return ( 93 | 94 |
95 |
96 |
97 |
106 | 118 |
119 |
128 |

$MARSWTF

129 |
130 | 145 |
146 |
155 | 156 | 157 | 158 |
159 |
160 |
161 |
170 |
171 |
172 |
173 |
174 | 175 |
176 |
177 | $MARSWTF 101 178 |

CURRENT PRICE = ${currentPrice}

179 |
180 |
181 |
182 | 183 |
184 |
185 | PRESALE LIVE NOW! 186 |

STAGE 1

187 |
188 |
189 |
190 |
191 |
192 |

Total MARS sold: {_renderNumber(soldAmount)}

193 |
194 |
195 |

Sale Target: {_renderNumber(saleAmount)} $MARS

196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 | 205 | 206 | 207 |
208 |
209 |
210 | 211 |
220 | 221 |
222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 |
233 |
234 |
235 |
236 | ); 237 | }; 238 | 239 | export default Header; 240 | -------------------------------------------------------------------------------- /src/constants/abis.js: -------------------------------------------------------------------------------- 1 | export const MARS_WTF_ABI = [ 2 | { inputs: [], stateMutability: "nonpayable", type: "constructor" }, 3 | { 4 | anonymous: false, 5 | inputs: [ 6 | { 7 | indexed: true, 8 | internalType: "address", 9 | name: "owner", 10 | type: "address", 11 | }, 12 | { 13 | indexed: true, 14 | internalType: "address", 15 | name: "spender", 16 | type: "address", 17 | }, 18 | { 19 | indexed: false, 20 | internalType: "uint256", 21 | name: "value", 22 | type: "uint256", 23 | }, 24 | ], 25 | name: "Approval", 26 | type: "event", 27 | }, 28 | { 29 | anonymous: false, 30 | inputs: [ 31 | { 32 | indexed: true, 33 | internalType: "address", 34 | name: "previousOwner", 35 | type: "address", 36 | }, 37 | { 38 | indexed: true, 39 | internalType: "address", 40 | name: "newOwner", 41 | type: "address", 42 | }, 43 | ], 44 | name: "OwnershipTransferred", 45 | type: "event", 46 | }, 47 | { 48 | anonymous: false, 49 | inputs: [ 50 | { indexed: true, internalType: "address", name: "from", type: "address" }, 51 | { indexed: true, internalType: "address", name: "to", type: "address" }, 52 | { 53 | indexed: false, 54 | internalType: "uint256", 55 | name: "value", 56 | type: "uint256", 57 | }, 58 | ], 59 | name: "Transfer", 60 | type: "event", 61 | }, 62 | { 63 | inputs: [ 64 | { internalType: "address", name: "uniswappairv3", type: "address" }, 65 | ], 66 | name: "SetUniswapV3PairAddress", 67 | outputs: [], 68 | stateMutability: "nonpayable", 69 | type: "function", 70 | }, 71 | { 72 | inputs: [], 73 | name: "_uniswapPair", 74 | outputs: [{ internalType: "address", name: "", type: "address" }], 75 | stateMutability: "view", 76 | type: "function", 77 | }, 78 | { 79 | inputs: [], 80 | name: "_walletMAX", 81 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 82 | stateMutability: "view", 83 | type: "function", 84 | }, 85 | { 86 | inputs: [ 87 | { internalType: "address", name: "owner", type: "address" }, 88 | { internalType: "address", name: "spender", type: "address" }, 89 | ], 90 | name: "allowance", 91 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 92 | stateMutability: "view", 93 | type: "function", 94 | }, 95 | { 96 | inputs: [ 97 | { internalType: "address", name: "spender", type: "address" }, 98 | { internalType: "uint256", name: "amount", type: "uint256" }, 99 | ], 100 | name: "approve", 101 | outputs: [{ internalType: "bool", name: "", type: "bool" }], 102 | stateMutability: "nonpayable", 103 | type: "function", 104 | }, 105 | { 106 | inputs: [{ internalType: "address", name: "account", type: "address" }], 107 | name: "balanceOf", 108 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 109 | stateMutability: "view", 110 | type: "function", 111 | }, 112 | { 113 | inputs: [], 114 | name: "decimals", 115 | outputs: [{ internalType: "uint8", name: "", type: "uint8" }], 116 | stateMutability: "view", 117 | type: "function", 118 | }, 119 | { 120 | inputs: [], 121 | name: "name", 122 | outputs: [{ internalType: "string", name: "", type: "string" }], 123 | stateMutability: "view", 124 | type: "function", 125 | }, 126 | { 127 | inputs: [], 128 | name: "owner", 129 | outputs: [{ internalType: "address", name: "", type: "address" }], 130 | stateMutability: "view", 131 | type: "function", 132 | }, 133 | { 134 | inputs: [], 135 | name: "renounceOwnership", 136 | outputs: [], 137 | stateMutability: "nonpayable", 138 | type: "function", 139 | }, 140 | { 141 | inputs: [{ internalType: "uint8", name: "percentage", type: "uint8" }], 142 | name: "setWalletMax", 143 | outputs: [], 144 | stateMutability: "nonpayable", 145 | type: "function", 146 | }, 147 | { 148 | inputs: [], 149 | name: "symbol", 150 | outputs: [{ internalType: "string", name: "", type: "string" }], 151 | stateMutability: "view", 152 | type: "function", 153 | }, 154 | { 155 | inputs: [], 156 | name: "totalSupply", 157 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 158 | stateMutability: "view", 159 | type: "function", 160 | }, 161 | { 162 | inputs: [ 163 | { internalType: "address", name: "recipient", type: "address" }, 164 | { internalType: "uint256", name: "amount", type: "uint256" }, 165 | ], 166 | name: "transfer", 167 | outputs: [{ internalType: "bool", name: "", type: "bool" }], 168 | stateMutability: "nonpayable", 169 | type: "function", 170 | }, 171 | { 172 | inputs: [ 173 | { internalType: "address", name: "sender", type: "address" }, 174 | { internalType: "address", name: "recipient", type: "address" }, 175 | { internalType: "uint256", name: "amount", type: "uint256" }, 176 | ], 177 | name: "transferFrom", 178 | outputs: [{ internalType: "bool", name: "", type: "bool" }], 179 | stateMutability: "nonpayable", 180 | type: "function", 181 | }, 182 | { 183 | inputs: [{ internalType: "address", name: "newOwner", type: "address" }], 184 | name: "transferOwnership", 185 | outputs: [], 186 | stateMutability: "nonpayable", 187 | type: "function", 188 | }, 189 | ]; 190 | 191 | export const ERC20_ABI = [ 192 | { 193 | constant: true, 194 | inputs: [], 195 | name: "name", 196 | outputs: [ 197 | { 198 | name: "", 199 | type: "string", 200 | }, 201 | ], 202 | payable: false, 203 | stateMutability: "view", 204 | type: "function", 205 | }, 206 | { 207 | constant: false, 208 | inputs: [ 209 | { 210 | name: "_spender", 211 | type: "address", 212 | }, 213 | { 214 | name: "_value", 215 | type: "uint256", 216 | }, 217 | ], 218 | name: "approve", 219 | outputs: [ 220 | { 221 | name: "", 222 | type: "bool", 223 | }, 224 | ], 225 | payable: false, 226 | stateMutability: "nonpayable", 227 | type: "function", 228 | }, 229 | { 230 | constant: true, 231 | inputs: [], 232 | name: "totalSupply", 233 | outputs: [ 234 | { 235 | name: "", 236 | type: "uint256", 237 | }, 238 | ], 239 | payable: false, 240 | stateMutability: "view", 241 | type: "function", 242 | }, 243 | { 244 | constant: false, 245 | inputs: [ 246 | { 247 | name: "_from", 248 | type: "address", 249 | }, 250 | { 251 | name: "_to", 252 | type: "address", 253 | }, 254 | { 255 | name: "_value", 256 | type: "uint256", 257 | }, 258 | ], 259 | name: "transferFrom", 260 | outputs: [ 261 | { 262 | name: "", 263 | type: "bool", 264 | }, 265 | ], 266 | payable: false, 267 | stateMutability: "nonpayable", 268 | type: "function", 269 | }, 270 | { 271 | constant: true, 272 | inputs: [], 273 | name: "decimals", 274 | outputs: [ 275 | { 276 | name: "", 277 | type: "uint8", 278 | }, 279 | ], 280 | payable: false, 281 | stateMutability: "view", 282 | type: "function", 283 | }, 284 | { 285 | constant: true, 286 | inputs: [ 287 | { 288 | name: "_owner", 289 | type: "address", 290 | }, 291 | ], 292 | name: "balanceOf", 293 | outputs: [ 294 | { 295 | name: "balance", 296 | type: "uint256", 297 | }, 298 | ], 299 | payable: false, 300 | stateMutability: "view", 301 | type: "function", 302 | }, 303 | { 304 | constant: true, 305 | inputs: [], 306 | name: "symbol", 307 | outputs: [ 308 | { 309 | name: "", 310 | type: "string", 311 | }, 312 | ], 313 | payable: false, 314 | stateMutability: "view", 315 | type: "function", 316 | }, 317 | { 318 | constant: false, 319 | inputs: [ 320 | { 321 | name: "_to", 322 | type: "address", 323 | }, 324 | { 325 | name: "_value", 326 | type: "uint256", 327 | }, 328 | ], 329 | name: "transfer", 330 | outputs: [ 331 | { 332 | name: "", 333 | type: "bool", 334 | }, 335 | ], 336 | payable: false, 337 | stateMutability: "nonpayable", 338 | type: "function", 339 | }, 340 | { 341 | constant: true, 342 | inputs: [ 343 | { 344 | name: "_owner", 345 | type: "address", 346 | }, 347 | { 348 | name: "_spender", 349 | type: "address", 350 | }, 351 | ], 352 | name: "allowance", 353 | outputs: [ 354 | { 355 | name: "", 356 | type: "uint256", 357 | }, 358 | ], 359 | payable: false, 360 | stateMutability: "view", 361 | type: "function", 362 | }, 363 | { 364 | payable: true, 365 | stateMutability: "payable", 366 | type: "fallback", 367 | }, 368 | { 369 | anonymous: false, 370 | inputs: [ 371 | { 372 | indexed: true, 373 | name: "owner", 374 | type: "address", 375 | }, 376 | { 377 | indexed: true, 378 | name: "spender", 379 | type: "address", 380 | }, 381 | { 382 | indexed: false, 383 | name: "value", 384 | type: "uint256", 385 | }, 386 | ], 387 | name: "Approval", 388 | type: "event", 389 | }, 390 | { 391 | anonymous: false, 392 | inputs: [ 393 | { 394 | indexed: true, 395 | name: "from", 396 | type: "address", 397 | }, 398 | { 399 | indexed: true, 400 | name: "to", 401 | type: "address", 402 | }, 403 | { 404 | indexed: false, 405 | name: "value", 406 | type: "uint256", 407 | }, 408 | ], 409 | name: "Transfer", 410 | type: "event", 411 | }, 412 | ]; 413 | -------------------------------------------------------------------------------- /src/constants/abis/marsNft.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { "internalType": "string", "name": "_name", "type": "string" }, 5 | { "internalType": "string", "name": "_symbol", "type": "string" }, 6 | { "internalType": "string", "name": "_description", "type": "string" }, 7 | { "internalType": "uint256", "name": "_mintFee", "type": "uint256" }, 8 | { "internalType": "address", "name": "_team", "type": "address" } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "inputs": [ 15 | { "internalType": "address", "name": "sender", "type": "address" }, 16 | { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, 17 | { "internalType": "address", "name": "owner", "type": "address" } 18 | ], 19 | "name": "ERC721IncorrectOwner", 20 | "type": "error" 21 | }, 22 | { 23 | "inputs": [ 24 | { "internalType": "address", "name": "operator", "type": "address" }, 25 | { "internalType": "uint256", "name": "tokenId", "type": "uint256" } 26 | ], 27 | "name": "ERC721InsufficientApproval", 28 | "type": "error" 29 | }, 30 | { 31 | "inputs": [ 32 | { "internalType": "address", "name": "approver", "type": "address" } 33 | ], 34 | "name": "ERC721InvalidApprover", 35 | "type": "error" 36 | }, 37 | { 38 | "inputs": [ 39 | { "internalType": "address", "name": "operator", "type": "address" } 40 | ], 41 | "name": "ERC721InvalidOperator", 42 | "type": "error" 43 | }, 44 | { 45 | "inputs": [ 46 | { "internalType": "address", "name": "owner", "type": "address" } 47 | ], 48 | "name": "ERC721InvalidOwner", 49 | "type": "error" 50 | }, 51 | { 52 | "inputs": [ 53 | { "internalType": "address", "name": "receiver", "type": "address" } 54 | ], 55 | "name": "ERC721InvalidReceiver", 56 | "type": "error" 57 | }, 58 | { 59 | "inputs": [ 60 | { "internalType": "address", "name": "sender", "type": "address" } 61 | ], 62 | "name": "ERC721InvalidSender", 63 | "type": "error" 64 | }, 65 | { 66 | "inputs": [ 67 | { "internalType": "uint256", "name": "tokenId", "type": "uint256" } 68 | ], 69 | "name": "ERC721NonexistentToken", 70 | "type": "error" 71 | }, 72 | { 73 | "anonymous": false, 74 | "inputs": [ 75 | { 76 | "indexed": true, 77 | "internalType": "address", 78 | "name": "owner", 79 | "type": "address" 80 | }, 81 | { 82 | "indexed": true, 83 | "internalType": "address", 84 | "name": "approved", 85 | "type": "address" 86 | }, 87 | { 88 | "indexed": true, 89 | "internalType": "uint256", 90 | "name": "tokenId", 91 | "type": "uint256" 92 | } 93 | ], 94 | "name": "Approval", 95 | "type": "event" 96 | }, 97 | { 98 | "anonymous": false, 99 | "inputs": [ 100 | { 101 | "indexed": true, 102 | "internalType": "address", 103 | "name": "owner", 104 | "type": "address" 105 | }, 106 | { 107 | "indexed": true, 108 | "internalType": "address", 109 | "name": "operator", 110 | "type": "address" 111 | }, 112 | { 113 | "indexed": false, 114 | "internalType": "bool", 115 | "name": "approved", 116 | "type": "bool" 117 | } 118 | ], 119 | "name": "ApprovalForAll", 120 | "type": "event" 121 | }, 122 | { 123 | "anonymous": false, 124 | "inputs": [ 125 | { 126 | "indexed": true, 127 | "internalType": "address", 128 | "name": "from", 129 | "type": "address" 130 | }, 131 | { 132 | "indexed": true, 133 | "internalType": "address", 134 | "name": "to", 135 | "type": "address" 136 | }, 137 | { 138 | "indexed": true, 139 | "internalType": "uint256", 140 | "name": "tokenId", 141 | "type": "uint256" 142 | } 143 | ], 144 | "name": "Transfer", 145 | "type": "event" 146 | }, 147 | { 148 | "inputs": [ 149 | { "internalType": "address", "name": "to", "type": "address" }, 150 | { "internalType": "uint256", "name": "tokenId", "type": "uint256" } 151 | ], 152 | "name": "approve", 153 | "outputs": [], 154 | "stateMutability": "nonpayable", 155 | "type": "function" 156 | }, 157 | { 158 | "inputs": [ 159 | { "internalType": "address", "name": "owner", "type": "address" } 160 | ], 161 | "name": "balanceOf", 162 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 163 | "stateMutability": "view", 164 | "type": "function" 165 | }, 166 | { 167 | "inputs": [ 168 | { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } 169 | ], 170 | "name": "burn", 171 | "outputs": [], 172 | "stateMutability": "nonpayable", 173 | "type": "function" 174 | }, 175 | { 176 | "inputs": [], 177 | "name": "description", 178 | "outputs": [{ "internalType": "string", "name": "", "type": "string" }], 179 | "stateMutability": "view", 180 | "type": "function" 181 | }, 182 | { 183 | "inputs": [{ "internalType": "address", "name": "", "type": "address" }], 184 | "name": "feeCreations", 185 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 186 | "stateMutability": "view", 187 | "type": "function" 188 | }, 189 | { 190 | "inputs": [{ "internalType": "address", "name": "", "type": "address" }], 191 | "name": "freeCreations", 192 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 193 | "stateMutability": "view", 194 | "type": "function" 195 | }, 196 | { 197 | "inputs": [ 198 | { "internalType": "uint256", "name": "tokenId", "type": "uint256" } 199 | ], 200 | "name": "getApproved", 201 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 202 | "stateMutability": "view", 203 | "type": "function" 204 | }, 205 | { 206 | "inputs": [], 207 | "name": "getCurrentMintFee", 208 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 209 | "stateMutability": "view", 210 | "type": "function" 211 | }, 212 | { 213 | "inputs": [ 214 | { "internalType": "address", "name": "owner", "type": "address" }, 215 | { "internalType": "address", "name": "operator", "type": "address" } 216 | ], 217 | "name": "isApprovedForAll", 218 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 219 | "stateMutability": "view", 220 | "type": "function" 221 | }, 222 | { 223 | "inputs": [ 224 | { "internalType": "string", "name": "_nftURI", "type": "string" } 225 | ], 226 | "name": "mint", 227 | "outputs": [], 228 | "stateMutability": "payable", 229 | "type": "function" 230 | }, 231 | { 232 | "inputs": [], 233 | "name": "mintFee", 234 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 235 | "stateMutability": "view", 236 | "type": "function" 237 | }, 238 | { 239 | "inputs": [], 240 | "name": "name", 241 | "outputs": [{ "internalType": "string", "name": "", "type": "string" }], 242 | "stateMutability": "view", 243 | "type": "function" 244 | }, 245 | { 246 | "inputs": [], 247 | "name": "owner", 248 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 249 | "stateMutability": "view", 250 | "type": "function" 251 | }, 252 | { 253 | "inputs": [ 254 | { "internalType": "uint256", "name": "tokenId", "type": "uint256" } 255 | ], 256 | "name": "ownerOf", 257 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 258 | "stateMutability": "view", 259 | "type": "function" 260 | }, 261 | { 262 | "inputs": [ 263 | { "internalType": "address", "name": "from", "type": "address" }, 264 | { "internalType": "address", "name": "to", "type": "address" }, 265 | { "internalType": "uint256", "name": "tokenId", "type": "uint256" } 266 | ], 267 | "name": "safeTransferFrom", 268 | "outputs": [], 269 | "stateMutability": "nonpayable", 270 | "type": "function" 271 | }, 272 | { 273 | "inputs": [ 274 | { "internalType": "address", "name": "from", "type": "address" }, 275 | { "internalType": "address", "name": "to", "type": "address" }, 276 | { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, 277 | { "internalType": "bytes", "name": "data", "type": "bytes" } 278 | ], 279 | "name": "safeTransferFrom", 280 | "outputs": [], 281 | "stateMutability": "nonpayable", 282 | "type": "function" 283 | }, 284 | { 285 | "inputs": [ 286 | { "internalType": "address", "name": "operator", "type": "address" }, 287 | { "internalType": "bool", "name": "approved", "type": "bool" } 288 | ], 289 | "name": "setApprovalForAll", 290 | "outputs": [], 291 | "stateMutability": "nonpayable", 292 | "type": "function" 293 | }, 294 | { 295 | "inputs": [ 296 | { "internalType": "uint256", "name": "_amount", "type": "uint256" } 297 | ], 298 | "name": "setMintFee", 299 | "outputs": [], 300 | "stateMutability": "nonpayable", 301 | "type": "function" 302 | }, 303 | { 304 | "inputs": [ 305 | { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } 306 | ], 307 | "name": "supportsInterface", 308 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 309 | "stateMutability": "view", 310 | "type": "function" 311 | }, 312 | { 313 | "inputs": [], 314 | "name": "symbol", 315 | "outputs": [{ "internalType": "string", "name": "", "type": "string" }], 316 | "stateMutability": "view", 317 | "type": "function" 318 | }, 319 | { 320 | "inputs": [], 321 | "name": "team", 322 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 323 | "stateMutability": "view", 324 | "type": "function" 325 | }, 326 | { 327 | "inputs": [], 328 | "name": "tokenNumber", 329 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 330 | "stateMutability": "view", 331 | "type": "function" 332 | }, 333 | { 334 | "inputs": [ 335 | { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } 336 | ], 337 | "name": "tokenURI", 338 | "outputs": [{ "internalType": "string", "name": "", "type": "string" }], 339 | "stateMutability": "view", 340 | "type": "function" 341 | }, 342 | { 343 | "inputs": [ 344 | { "internalType": "address", "name": "from", "type": "address" }, 345 | { "internalType": "address", "name": "to", "type": "address" }, 346 | { "internalType": "uint256", "name": "tokenId", "type": "uint256" } 347 | ], 348 | "name": "transferFrom", 349 | "outputs": [], 350 | "stateMutability": "nonpayable", 351 | "type": "function" 352 | }, 353 | { 354 | "inputs": [ 355 | { "internalType": "address", "name": "newOwner", "type": "address" } 356 | ], 357 | "name": "transferOwnership", 358 | "outputs": [], 359 | "stateMutability": "nonpayable", 360 | "type": "function" 361 | } 362 | ] 363 | -------------------------------------------------------------------------------- /src/constants/abis/presale.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "stateMutability": "nonpayable", 5 | "type": "constructor" 6 | }, 7 | { 8 | "inputs": [ 9 | { 10 | "internalType": "address", 11 | "name": "owner", 12 | "type": "address" 13 | } 14 | ], 15 | "name": "OwnableInvalidOwner", 16 | "type": "error" 17 | }, 18 | { 19 | "inputs": [ 20 | { 21 | "internalType": "address", 22 | "name": "account", 23 | "type": "address" 24 | } 25 | ], 26 | "name": "OwnableUnauthorizedAccount", 27 | "type": "error" 28 | }, 29 | { 30 | "anonymous": false, 31 | "inputs": [ 32 | { 33 | "indexed": true, 34 | "internalType": "address", 35 | "name": "previousOwner", 36 | "type": "address" 37 | }, 38 | { 39 | "indexed": true, 40 | "internalType": "address", 41 | "name": "newOwner", 42 | "type": "address" 43 | } 44 | ], 45 | "name": "OwnershipTransferred", 46 | "type": "event" 47 | }, 48 | { 49 | "inputs": [], 50 | "name": "INCREASEMENT", 51 | "outputs": [ 52 | { 53 | "internalType": "uint256", 54 | "name": "", 55 | "type": "uint256" 56 | } 57 | ], 58 | "stateMutability": "view", 59 | "type": "function" 60 | }, 61 | { 62 | "inputs": [], 63 | "name": "INITIAL_TOKEN_PRICE", 64 | "outputs": [ 65 | { 66 | "internalType": "uint256", 67 | "name": "", 68 | "type": "uint256" 69 | } 70 | ], 71 | "stateMutability": "view", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "address", 78 | "name": "", 79 | "type": "address" 80 | } 81 | ], 82 | "name": "balanceOf", 83 | "outputs": [ 84 | { 85 | "internalType": "uint256", 86 | "name": "", 87 | "type": "uint256" 88 | } 89 | ], 90 | "stateMutability": "view", 91 | "type": "function" 92 | }, 93 | { 94 | "inputs": [ 95 | { 96 | "internalType": "uint256", 97 | "name": "_amount", 98 | "type": "uint256" 99 | } 100 | ], 101 | "name": "buyEstimationWithEth", 102 | "outputs": [ 103 | { 104 | "internalType": "uint256", 105 | "name": "", 106 | "type": "uint256" 107 | } 108 | ], 109 | "stateMutability": "view", 110 | "type": "function" 111 | }, 112 | { 113 | "inputs": [ 114 | { 115 | "internalType": "uint256", 116 | "name": "_amount", 117 | "type": "uint256" 118 | } 119 | ], 120 | "name": "buyEstimationWithUsdc", 121 | "outputs": [ 122 | { 123 | "internalType": "uint256", 124 | "name": "", 125 | "type": "uint256" 126 | } 127 | ], 128 | "stateMutability": "view", 129 | "type": "function" 130 | }, 131 | { 132 | "inputs": [], 133 | "name": "buyTokenWithETH", 134 | "outputs": [], 135 | "stateMutability": "payable", 136 | "type": "function" 137 | }, 138 | { 139 | "inputs": [ 140 | { 141 | "internalType": "uint256", 142 | "name": "_usdcAmount", 143 | "type": "uint256" 144 | } 145 | ], 146 | "name": "buyTokenWithUSDC", 147 | "outputs": [], 148 | "stateMutability": "nonpayable", 149 | "type": "function" 150 | }, 151 | { 152 | "inputs": [], 153 | "name": "calculateRemainingTime", 154 | "outputs": [ 155 | { 156 | "internalType": "uint256", 157 | "name": "", 158 | "type": "uint256" 159 | } 160 | ], 161 | "stateMutability": "view", 162 | "type": "function" 163 | }, 164 | { 165 | "inputs": [], 166 | "name": "claim", 167 | "outputs": [], 168 | "stateMutability": "nonpayable", 169 | "type": "function" 170 | }, 171 | { 172 | "inputs": [], 173 | "name": "endTimeStamp", 174 | "outputs": [ 175 | { 176 | "internalType": "uint256", 177 | "name": "", 178 | "type": "uint256" 179 | } 180 | ], 181 | "stateMutability": "view", 182 | "type": "function" 183 | }, 184 | { 185 | "inputs": [ 186 | { 187 | "internalType": "uint256", 188 | "name": "_amount", 189 | "type": "uint256" 190 | } 191 | ], 192 | "name": "estimateWithToken", 193 | "outputs": [ 194 | { 195 | "internalType": "uint256[]", 196 | "name": "", 197 | "type": "uint256[]" 198 | } 199 | ], 200 | "stateMutability": "view", 201 | "type": "function" 202 | }, 203 | { 204 | "inputs": [], 205 | "name": "fundsRaised", 206 | "outputs": [ 207 | { 208 | "internalType": "uint256", 209 | "name": "", 210 | "type": "uint256" 211 | } 212 | ], 213 | "stateMutability": "view", 214 | "type": "function" 215 | }, 216 | { 217 | "inputs": [], 218 | "name": "getCurrentStep", 219 | "outputs": [ 220 | { 221 | "internalType": "uint256", 222 | "name": "", 223 | "type": "uint256" 224 | } 225 | ], 226 | "stateMutability": "view", 227 | "type": "function" 228 | }, 229 | { 230 | "inputs": [], 231 | "name": "getCurrentTokenPrice", 232 | "outputs": [ 233 | { 234 | "internalType": "uint256", 235 | "name": "", 236 | "type": "uint256" 237 | } 238 | ], 239 | "stateMutability": "view", 240 | "type": "function" 241 | }, 242 | { 243 | "inputs": [], 244 | "name": "getHardcap", 245 | "outputs": [ 246 | { 247 | "internalType": "uint256", 248 | "name": "", 249 | "type": "uint256" 250 | } 251 | ], 252 | "stateMutability": "view", 253 | "type": "function" 254 | }, 255 | { 256 | "inputs": [ 257 | { 258 | "internalType": "address", 259 | "name": "_account", 260 | "type": "address" 261 | } 262 | ], 263 | "name": "marsBalance", 264 | "outputs": [ 265 | { 266 | "internalType": "uint256", 267 | "name": "", 268 | "type": "uint256" 269 | } 270 | ], 271 | "stateMutability": "view", 272 | "type": "function" 273 | }, 274 | { 275 | "inputs": [], 276 | "name": "owner", 277 | "outputs": [ 278 | { 279 | "internalType": "address", 280 | "name": "", 281 | "type": "address" 282 | } 283 | ], 284 | "stateMutability": "view", 285 | "type": "function" 286 | }, 287 | { 288 | "inputs": [], 289 | "name": "presaleAmount", 290 | "outputs": [ 291 | { 292 | "internalType": "uint256", 293 | "name": "", 294 | "type": "uint256" 295 | } 296 | ], 297 | "stateMutability": "view", 298 | "type": "function" 299 | }, 300 | { 301 | "inputs": [], 302 | "name": "presaleStarted", 303 | "outputs": [ 304 | { 305 | "internalType": "bool", 306 | "name": "", 307 | "type": "bool" 308 | } 309 | ], 310 | "stateMutability": "view", 311 | "type": "function" 312 | }, 313 | { 314 | "inputs": [], 315 | "name": "renounceOwnership", 316 | "outputs": [], 317 | "stateMutability": "nonpayable", 318 | "type": "function" 319 | }, 320 | { 321 | "inputs": [], 322 | "name": "router", 323 | "outputs": [ 324 | { 325 | "internalType": "contract IUniswapV2Router02", 326 | "name": "", 327 | "type": "address" 328 | } 329 | ], 330 | "stateMutability": "view", 331 | "type": "function" 332 | }, 333 | { 334 | "inputs": [], 335 | "name": "sale", 336 | "outputs": [ 337 | { 338 | "internalType": "uint256", 339 | "name": "", 340 | "type": "uint256" 341 | } 342 | ], 343 | "stateMutability": "view", 344 | "type": "function" 345 | }, 346 | { 347 | "inputs": [ 348 | { 349 | "internalType": "uint256", 350 | "name": "_increment", 351 | "type": "uint256" 352 | } 353 | ], 354 | "name": "setIncreasement", 355 | "outputs": [], 356 | "stateMutability": "nonpayable", 357 | "type": "function" 358 | }, 359 | { 360 | "inputs": [ 361 | { 362 | "internalType": "uint256", 363 | "name": "_initialTokenPrice", 364 | "type": "uint256" 365 | } 366 | ], 367 | "name": "setInitialTokenPrice", 368 | "outputs": [], 369 | "stateMutability": "nonpayable", 370 | "type": "function" 371 | }, 372 | { 373 | "inputs": [], 374 | "name": "soldAmount", 375 | "outputs": [ 376 | { 377 | "internalType": "uint256", 378 | "name": "", 379 | "type": "uint256" 380 | } 381 | ], 382 | "stateMutability": "view", 383 | "type": "function" 384 | }, 385 | { 386 | "inputs": [ 387 | { 388 | "internalType": "uint256", 389 | "name": "_endTimeStamp", 390 | "type": "uint256" 391 | } 392 | ], 393 | "name": "startPresale", 394 | "outputs": [], 395 | "stateMutability": "nonpayable", 396 | "type": "function" 397 | }, 398 | { 399 | "inputs": [], 400 | "name": "startTimeStamp", 401 | "outputs": [ 402 | { 403 | "internalType": "uint256", 404 | "name": "", 405 | "type": "uint256" 406 | } 407 | ], 408 | "stateMutability": "view", 409 | "type": "function" 410 | }, 411 | { 412 | "inputs": [ 413 | { 414 | "internalType": "address", 415 | "name": "newOwner", 416 | "type": "address" 417 | } 418 | ], 419 | "name": "transferOwnership", 420 | "outputs": [], 421 | "stateMutability": "nonpayable", 422 | "type": "function" 423 | }, 424 | { 425 | "inputs": [ 426 | { 427 | "internalType": "uint256", 428 | "name": "_endTimeStamp", 429 | "type": "uint256" 430 | } 431 | ], 432 | "name": "updateEndTimeStamp", 433 | "outputs": [], 434 | "stateMutability": "nonpayable", 435 | "type": "function" 436 | }, 437 | { 438 | "inputs": [ 439 | { 440 | "internalType": "address", 441 | "name": "_account", 442 | "type": "address" 443 | } 444 | ], 445 | "name": "usdcBalance", 446 | "outputs": [ 447 | { 448 | "internalType": "uint256", 449 | "name": "", 450 | "type": "uint256" 451 | } 452 | ], 453 | "stateMutability": "view", 454 | "type": "function" 455 | }, 456 | { 457 | "inputs": [ 458 | { 459 | "internalType": "address", 460 | "name": "_to", 461 | "type": "address" 462 | } 463 | ], 464 | "name": "withdraw", 465 | "outputs": [], 466 | "stateMutability": "payable", 467 | "type": "function" 468 | }, 469 | { 470 | "stateMutability": "payable", 471 | "type": "receive" 472 | } 473 | ] -------------------------------------------------------------------------------- /src/components/ui/sparkles.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React from "react"; 3 | import { useEffect, useState } from "react"; 4 | import Particles, { initParticlesEngine } from "@tsparticles/react"; 5 | import type { Container, SingleOrMultiple } from "@tsparticles/engine"; 6 | import { loadSlim } from "@tsparticles/slim"; 7 | import { cn } from "@/utils/cn"; 8 | import { motion, useAnimation } from "framer-motion"; 9 | 10 | type ParticlesProps = { 11 | id?: string; 12 | className?: string; 13 | background?: string; 14 | particleSize?: number; 15 | minSize?: number; 16 | maxSize?: number; 17 | speed?: number; 18 | particleColor?: string; 19 | particleDensity?: number; 20 | }; 21 | const SparklesCore = (props: ParticlesProps) => { 22 | const { 23 | id, 24 | className, 25 | background, 26 | minSize, 27 | maxSize, 28 | speed, 29 | particleColor, 30 | particleDensity, 31 | } = props; 32 | const [init, setInit] = useState(false); 33 | useEffect(() => { 34 | initParticlesEngine(async (engine) => { 35 | await loadSlim(engine); 36 | }).then(() => { 37 | setInit(true); 38 | }); 39 | // eslint-disable-next-line react-hooks/exhaustive-deps 40 | }, []); 41 | const controls = useAnimation(); 42 | 43 | const particlesLoaded = async (container?: Container) => { 44 | if (container) { 45 | controls.start({ 46 | opacity: 1, 47 | transition: { 48 | duration: 1, 49 | }, 50 | }); 51 | } 52 | }; 53 | 54 | return ( 55 | 56 | {init && ( 57 | | undefined, 161 | }, 162 | groups: {}, 163 | move: { 164 | angle: { 165 | offset: 0, 166 | value: 90, 167 | }, 168 | attract: { 169 | distance: 200, 170 | enable: false, 171 | rotate: { 172 | x: 3000, 173 | y: 3000, 174 | }, 175 | }, 176 | center: { 177 | x: 50, 178 | y: 50, 179 | mode: "percent", 180 | radius: 0, 181 | }, 182 | decay: 0, 183 | distance: {}, 184 | direction: "none", 185 | drift: 0, 186 | enable: true, 187 | gravity: { 188 | acceleration: 9.81, 189 | enable: false, 190 | inverse: false, 191 | maxSpeed: 50, 192 | }, 193 | path: { 194 | clamp: true, 195 | delay: { 196 | value: 0, 197 | }, 198 | enable: false, 199 | options: {}, 200 | }, 201 | outModes: { 202 | default: "out", 203 | }, 204 | random: false, 205 | size: false, 206 | speed: { 207 | min: 0.1, 208 | max: 1, 209 | }, 210 | spin: { 211 | acceleration: 0, 212 | enable: false, 213 | }, 214 | straight: false, 215 | trail: { 216 | enable: false, 217 | length: 10, 218 | fill: {}, 219 | }, 220 | vibrate: false, 221 | warp: false, 222 | }, 223 | number: { 224 | density: { 225 | enable: true, 226 | width: 400, 227 | height: 400, 228 | }, 229 | limit: { 230 | mode: "delete", 231 | value: 0, 232 | }, 233 | value: particleDensity || 120, 234 | }, 235 | opacity: { 236 | value: { 237 | min: 0.1, 238 | max: 1, 239 | }, 240 | animation: { 241 | count: 0, 242 | enable: true, 243 | speed: speed || 4, 244 | decay: 0, 245 | delay: 0, 246 | sync: false, 247 | mode: "auto", 248 | startValue: "random", 249 | destroy: "none", 250 | }, 251 | }, 252 | reduceDuplicates: false, 253 | shadow: { 254 | blur: 0, 255 | color: { 256 | value: "#000", 257 | }, 258 | enable: false, 259 | offset: { 260 | x: 0, 261 | y: 0, 262 | }, 263 | }, 264 | shape: { 265 | close: true, 266 | fill: true, 267 | options: {}, 268 | type: "circle", 269 | }, 270 | size: { 271 | value: { 272 | min: minSize || 1, 273 | max: maxSize || 3, 274 | }, 275 | animation: { 276 | count: 0, 277 | enable: false, 278 | speed: 5, 279 | decay: 0, 280 | delay: 0, 281 | sync: false, 282 | mode: "auto", 283 | startValue: "random", 284 | destroy: "none", 285 | }, 286 | }, 287 | stroke: { 288 | width: 0, 289 | }, 290 | zIndex: { 291 | value: 0, 292 | opacityRate: 1, 293 | sizeRate: 1, 294 | velocityRate: 1, 295 | }, 296 | destroy: { 297 | bounds: {}, 298 | mode: "none", 299 | split: { 300 | count: 1, 301 | factor: { 302 | value: 3, 303 | }, 304 | rate: { 305 | value: { 306 | min: 4, 307 | max: 9, 308 | }, 309 | }, 310 | sizeOffset: true, 311 | }, 312 | }, 313 | roll: { 314 | darken: { 315 | enable: false, 316 | value: 0, 317 | }, 318 | enable: false, 319 | enlighten: { 320 | enable: false, 321 | value: 0, 322 | }, 323 | mode: "vertical", 324 | speed: 25, 325 | }, 326 | tilt: { 327 | value: 0, 328 | animation: { 329 | enable: false, 330 | speed: 0, 331 | decay: 0, 332 | sync: false, 333 | }, 334 | direction: "clockwise", 335 | enable: false, 336 | }, 337 | twinkle: { 338 | lines: { 339 | enable: false, 340 | frequency: 0.05, 341 | opacity: 1, 342 | }, 343 | particles: { 344 | enable: false, 345 | frequency: 0.05, 346 | opacity: 1, 347 | }, 348 | }, 349 | wobble: { 350 | distance: 5, 351 | enable: false, 352 | speed: { 353 | angle: 50, 354 | move: 10, 355 | }, 356 | }, 357 | life: { 358 | count: 0, 359 | delay: { 360 | value: 0, 361 | sync: false, 362 | }, 363 | duration: { 364 | value: 0, 365 | sync: false, 366 | }, 367 | }, 368 | rotate: { 369 | value: 0, 370 | animation: { 371 | enable: false, 372 | speed: 0, 373 | decay: 0, 374 | sync: false, 375 | }, 376 | direction: "clockwise", 377 | path: false, 378 | }, 379 | orbit: { 380 | animation: { 381 | count: 0, 382 | enable: false, 383 | speed: 1, 384 | decay: 0, 385 | delay: 0, 386 | sync: false, 387 | }, 388 | enable: false, 389 | opacity: 1, 390 | rotation: { 391 | value: 45, 392 | }, 393 | width: 1, 394 | }, 395 | links: { 396 | blink: false, 397 | color: { 398 | value: "#fff", 399 | }, 400 | consent: false, 401 | distance: 100, 402 | enable: false, 403 | frequency: 1, 404 | opacity: 1, 405 | shadow: { 406 | blur: 5, 407 | color: { 408 | value: "#000", 409 | }, 410 | enable: false, 411 | }, 412 | triangles: { 413 | enable: false, 414 | frequency: 1, 415 | }, 416 | width: 1, 417 | warp: false, 418 | }, 419 | repulse: { 420 | value: 0, 421 | enabled: false, 422 | distance: 1, 423 | duration: 1, 424 | factor: 1, 425 | speed: 1, 426 | }, 427 | }, 428 | detectRetina: true, 429 | }} 430 | /> 431 | )} 432 | 433 | ); 434 | }; 435 | 436 | export default SparklesCore; 437 | --------------------------------------------------------------------------------