diff --git a/package.json b/package.json
index 9bfea0d..b12a4d3 100644
--- a/package.json
+++ b/package.json
@@ -8,5 +8,14 @@
"keywords": [],
"author": "",
"license": "MIT",
- "packageManager": "yarn@3.2.3"
+ "packageManager": "yarn@3.2.3",
+ "dependencies": {
+ "@emotion/react": "^11.13.3",
+ "@emotion/styled": "^11.13.0",
+ "@mui/icons-material": "^6.0.1",
+ "@mui/material": "^6.0.1",
+ "autoprefixer": "^10.4.20",
+ "postcss": "^8.4.41",
+ "tailwindcss": "^3.4.10"
+ }
}
diff --git a/packages/app/index.css b/packages/app/index.css
index 4bf1c5d..ece3c5e 100644
--- a/packages/app/index.css
+++ b/packages/app/index.css
@@ -1,4 +1,4 @@
-@tailwind base;
+/* @tailwind base;
@tailwind components;
@tailwind utilities;
@@ -14,4 +14,27 @@ body {
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
-}
\ No newline at end of file
+} */
+
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+:root {
+ font-family: "Space Grotesk", sans-serif;
+ background-color: #ffbfbf;
+ background: radial-gradient(70.71% 70.71% at 50% 50%, #FFF 19%, rgba(255, 255, 255, 0.00) 61%), linear-gradient(38deg, rgba(255, 255, 255, 0.00) 60%, rgba(255, 255, 255, 0.69) 100%), linear-gradient(45deg, #FFF 10%, rgba(255, 255, 255, 0.00) 23.5%), linear-gradient(36deg, #FFF 12.52%, rgba(255, 255, 255, 0.00) 76.72%), linear-gradient(214deg, rgba(255, 255, 255, 0.00) 0%, rgba(255, 220, 234, 0.40) 37.53%, rgba(255, 255, 255, 0.00) 71%), linear-gradient(212deg, rgba(255, 255, 255, 0.00) 15%, #E4F1FE 72.5%, rgba(255, 255, 255, 0.00) 91.5%);
+}
+
+body {
+ margin: 0;
+ font-family: "Space Grotesk", sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
+ monospace;
+}
+
diff --git a/packages/app/index.html b/packages/app/index.html
index 10746d0..4aeb9d1 100644
--- a/packages/app/index.html
+++ b/packages/app/index.html
@@ -39,7 +39,17 @@
window.process = process;
window.setImmediate = setImmediate;
+
+
+
+
+
+
+
+
You need to enable JavaScript to run this app.
diff --git a/packages/app/package.json b/packages/app/package.json
index 6c7213b..5aeceb4 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -2,6 +2,10 @@
"name": "@zk-email/twitter-verifier-app",
"version": "4.0.0",
"dependencies": {
+ "@emotion/react": "^11.13.3",
+ "@emotion/styled": "^11.13.0",
+ "@mui/icons-material": "^6.0.1",
+ "@mui/material": "^6.0.1",
"@proof-of-twitter/circuits": "workspace:^",
"@proof-of-twitter/contracts": "workspace:^",
"@rainbow-me/rainbowkit": "^2.1.4",
diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx
index 29676be..1a4c696 100644
--- a/packages/app/src/App.tsx
+++ b/packages/app/src/App.tsx
@@ -1,4 +1,5 @@
import { MainPage } from "./pages/MainPage";
+import AboutPage from './pages/AboutPage'
import "./styles.css";
import {
BrowserRouter as Router,
@@ -10,36 +11,15 @@ import { useLocation } from "react-use";
import styled from "styled-components";
import { ConnectButton } from "@rainbow-me/rainbowkit";
-const NavSection = () => {
- const { pathname } = useLocation();
- return (
-
-
- ZK-Email
-
-
- Docs
-
-
-
- );
-};
const App = () => {
return (
-
-
} />
+ } />
Not found>} />
@@ -48,28 +28,3 @@ const App = () => {
};
export default App;
-
-const Logo = styled(Link)`
- text-transform: uppercase;
- letter-spacing: 0.04em;
- color: #fff;
- text-decoration: none;
- font-size: 1.2rem;
-`;
-
-const Nav = styled.nav`
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin: 12px;
-`;
-
-const DocsLink = styled.a`
- color: rgba(255, 255, 255, 0.8);
- text-decoration: none;
- underline: none;
- transition: all 0.2s ease-in-out;
- &:hover {
- color: rgba(255, 255, 255, 1);
- }
-`;
diff --git a/packages/app/src/components/Accordion.tsx b/packages/app/src/components/Accordion.tsx
new file mode 100644
index 0000000..f179332
--- /dev/null
+++ b/packages/app/src/components/Accordion.tsx
@@ -0,0 +1,97 @@
+import React, { FC } from 'react';
+import {
+ Accordion as MuiAccordion,
+ AccordionSummary,
+ AccordionDetails,
+ Typography,
+ styled,
+} from '@mui/material';
+import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
+
+// Define the props types
+interface AccordionProps {
+ title: string;
+ contents: string;
+ alignment?: 'left' | 'right';
+}
+
+const CustomAccordion = styled(MuiAccordion)(({ theme }) => ({
+ marginBottom: theme.spacing(2),
+ '&:before': {
+ display: 'none',
+ },
+ background: 'inherit',
+ boxShadow: 'none',
+ borderBottom: '1px solid rgba(0, 0, 0, 0.12)',
+ '& .MuiAccordionSummary-root': {
+ backgroundColor: 'rgba(0, 0, 0, 0)',
+ '&:hover .MuiAccordionSummary-expandIconWrapper': {
+ color: theme.palette.secondary.main,
+ },
+ },
+ '& .MuiAccordionSummary-content': {
+ margin: 0,
+ display: 'flex',
+ alignItems: 'center',
+ width: '100%',
+ },
+ '& .MuiAccordionSummary-expandIconWrapper': {
+ marginRight: theme.spacing(1),
+ transition: 'transform 0.2s',
+ },
+ '& .MuiAccordionSummary-expandIconWrapper.Mui-expanded': {
+ transform: 'rotate(180deg)',
+ },
+ '& .MuiAccordionDetails-root': {
+ padding: theme.spacing(2),
+ },
+}));
+
+const Accordion: FC = ({ title, contents, alignment = 'left' }) => {
+ return (
+
+ }
+ aria-controls="panel-content"
+ id="panel-header"
+ sx={{
+ flexDirection: alignment === 'right' ? 'row-reverse' : 'row',
+ justifyContent: alignment === 'right' ? 'space-between' : 'flex-start',
+ '& .MuiAccordionSummary-expandIconWrapper': {
+ order: alignment === 'right' ? 2 : 1,
+ marginRight: alignment === 'right' ? 0 : 1,
+ marginLeft: alignment === 'right' ? 1 : 0,
+ },
+ width: '100%',
+ }}
+ >
+
+ {title}
+
+
+
+
+ {contents}
+
+
+
+ );
+};
+
+export default Accordion;
\ No newline at end of file
diff --git a/packages/app/src/components/Button.tsx b/packages/app/src/components/Button.tsx
index 385498f..f194d84 100644
--- a/packages/app/src/components/Button.tsx
+++ b/packages/app/src/components/Button.tsx
@@ -1,10 +1,22 @@
+
+
+import React from 'react';
import styled from "styled-components";
+import { useTheme, Button as MuiButton } from "@mui/material";
-export const Button = styled.button`
- padding: 0 14px;
- border-radius: 4px;
- background: #8272e4;
- border: none;
+interface ButtonProps {
+ highlighted?: boolean;
+ disabled?: boolean;
+ onClick?: () => void;
+ children: React.ReactNode;
+ endIcon?: React.ReactNode;
+ href?: string;
+ target?: string;
+}
+
+const StyledButton = styled(MuiButton)<{ highlighted: boolean }>`
+ text-transform: none;
+ border-radius: 9px;
display: flex;
align-items: center;
justify-content: center;
@@ -17,58 +29,174 @@ export const Button = styled.button`
width: 100%;
min-width: 32px;
transition: all 0.2s ease-in-out;
+ background: ${({ highlighted, theme }) => (highlighted ? theme.palette.accent.main : '#1C1C1C')};
+
&:hover {
- background: #9b8df2;
+ background: ${({ highlighted, theme }) => (highlighted ? theme.palette.accent.main : '#1C1C1C')};
+ opacity: 0.5;
}
+
&:disabled {
opacity: 0.5;
cursor: not-allowed;
+ color: ${({ highlighted, theme }) => (highlighted ? '#ffffff' : 'grey')};
+ }
+
+ @media (max-width: 600px) {
+ font-size: 0.8rem;
+ padding: 0 12px;
+ }
+
+ @media (max-width: 400px) {
+ font-size: 0.6rem;
+ padding: 0 4px;
+ height: 40px;
}
`;
-export const OutlinedButton = styled.button`
- padding: 0 14px;
- border-radius: 4px;
- border: none;
+const StyledOutlinedButton = styled(MuiButton)<{ highlighted: boolean }>`
+ padding: 0 5px;
+ border-radius: 9px;
display: flex;
align-items: center;
justify-content: center;
font-weight: 500;
font-size: 0.9rem;
letter-spacing: -0.02em;
- color: #8272e4;
+ text-transform: none;
cursor: pointer;
height: 48px;
width: 100%;
- min-width: 32px;
+ min-width: 30px;
transition: all 0.2s ease-in-out;
- background: transparent;
- border: 1px solid #8272e4;
+ background: '#ffffff';
+ border: 1px solid ${({ highlighted, theme }) => (highlighted ? theme.palette.accent.main : '#1C1C1C')};
+ color: ${({ highlighted, theme }) => (highlighted ? theme.palette.accent.main : '#1C1C1C')};
+
&:hover {
- background: #9b8df2;
+ background: ${({ highlighted, theme }) => (highlighted ? theme.palette.accent.main : '#1C1C1C')};
color: white;
}
+
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
+
+ @media (max-width: 600px) {
+ font-size: 0.8rem;
+ padding: 0 12px;
+ }
+
+ @media (max-width: 400px) {
+ font-size: 0.6rem;
+ padding: 0 2px;
+ height: 40px;
+ }
`;
+const StyledTextButton = styled(MuiButton)<{ highlighted: boolean }>`
+ width: fit-content;
+ background: '#ffffff';
+ border: none;
+ color: ${({ highlighted, theme }) => (highlighted ? theme.palette.accent.main : theme.palette.secondary.main)};
+ font-weight: 500;
+ border-radius: 9px;
-export const TextButton = styled.button`
-width: fit-content;
-background: transparent;
-border: none;
-color: white;
-font-weight: 500;
-padding: 4px 16px;
-border-radius: 4px;
&:hover {
- background: #00000020;
- color: white;
+ color: theme.palette.secondary.main;
}
+
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
+
+ @media (max-width: 600px) {
+ font-size: 0.8rem;
+ padding: 2px 12px;
+ }
+
+ @media (max-width: 400px) {
+ font-size: 0.6rem;
+ padding: 0 2px;
+ height: 40px;
+ }
`;
+
+export const Button: React.FC = ({ highlighted = false, disabled, onClick, children, endIcon, href, target }) => {
+ const theme = useTheme();
+
+ const handleClick = (e: React.MouseEvent) => {
+ if (disabled) return;
+ if (href) {
+ window.open(href, target);
+ } else if (onClick) {
+ onClick();
+ }
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const OutlinedButton: React.FC = ({ highlighted = false, disabled, onClick, children, endIcon, href, target }) => {
+ const theme = useTheme();
+
+ const handleClick = (e: React.MouseEvent) => {
+ if (disabled) return;
+ if (href) {
+ window.open(href, target);
+ } else if (onClick) {
+ onClick();
+ }
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const TextButton: React.FC = ({ highlighted = false, disabled, onClick, children, endIcon, href, target }) => {
+ const theme = useTheme();
+
+ const handleClick = (e: React.MouseEvent) => {
+ if (disabled) return;
+ if (href) {
+ window.open(href, target);
+ } else if (onClick) {
+ onClick();
+ }
+ };
+
+ return (
+
+ {children}
+ {endIcon && {endIcon} }
+
+ );
+};
+
diff --git a/packages/app/src/components/DragAndDropTextBox.tsx b/packages/app/src/components/DragAndDropTextBox.tsx
index 9f51137..5402db5 100644
--- a/packages/app/src/components/DragAndDropTextBox.tsx
+++ b/packages/app/src/components/DragAndDropTextBox.tsx
@@ -1,20 +1,79 @@
+// import React from "react";
+// import styled from 'styled-components';
+// import { useDragAndDrop } from '../hooks/useDragAndDrop';
+
+// const DragAndDropTextBoxWrapper = styled.div`
+// display: flex;
+// flex-direction: column;
+// align-items: center;
+// border: 2px dashed #ccc;
+// padding: 20px;
+// `;
+
+// type Props = {
+// onFileDrop: (file: File) => void;
+// };
+
+// const DragAndDropTextBox: React.FC = ({onFileDrop}) => {
+// const {
+// dragging,
+// handleDragEnter,
+// handleDragLeave,
+// handleDragOver,
+// handleDrop,
+// handleDragEnd,
+// } = useDragAndDrop();
+
+// return (
+// handleDrop(e, onFileDrop)}
+// >
+// {dragging ? (
+// Drop here
+// ) : (
+// Drop .eml file here
+// )}
+//
+// );
+// };
+
+// export default DragAndDropTextBox;
+
+
+
+
import React from "react";
-import styled from 'styled-components';
+import styled, { css, ThemeProvider } from 'styled-components';
+import { useTheme } from "@mui/material/styles";
import { useDragAndDrop } from '../hooks/useDragAndDrop';
+import { Typography } from "@mui/material";
-const DragAndDropTextBoxWrapper = styled.div`
+const DragAndDropTextBoxWrapper = styled.div<{ highlighted: boolean }>`
display: flex;
flex-direction: column;
align-items: center;
border: 2px dashed #ccc;
padding: 20px;
+ ${({ highlighted, theme }) =>
+ highlighted
+ ? css`
+ border-color: ${theme.palette.accent.main};
+ color: ${theme.palette.accent.main}
+ `
+ : ''}
`;
type Props = {
onFileDrop: (file: File) => void;
+ highlighted?: boolean;
};
-const DragAndDropTextBox: React.FC = ({onFileDrop}) => {
+const DragAndDropTextBox: React.FC = ({ onFileDrop, highlighted = false }) => {
+ const theme = useTheme();
const {
dragging,
handleDragEnter,
@@ -25,20 +84,24 @@ const DragAndDropTextBox: React.FC = ({onFileDrop}) => {
} = useDragAndDrop();
return (
- handleDrop(e, onFileDrop)}
- >
- {dragging ? (
- Drop here
- ) : (
- Drop .eml file here
- )}
-
+
+ handleDrop(e, onFileDrop)}
+ >
+ {dragging ? (
+ Drop here
+ ) : (
+ Drop .eml file here
+ )}
+
+
);
};
export default DragAndDropTextBox;
+
diff --git a/packages/app/src/components/EmailInputMethod.tsx b/packages/app/src/components/EmailInputMethod.tsx
index 851b661..38f3ff0 100644
--- a/packages/app/src/components/EmailInputMethod.tsx
+++ b/packages/app/src/components/EmailInputMethod.tsx
@@ -1,12 +1,55 @@
-import { useState } from "react";
+// import { useState } from "react";
+// import { Button, OutlinedButton } from "./Button";
+
+// const EmailInputMethod = ({
+// onClickGoogle,
+// onClickEMLFile,
+// }: {
+// onClickGoogle: () => void;
+// onClickEMLFile: () => void;
+// }) => {
+// return (
+//
+// Sign in with Google
+// or
+// {
+// onClickEMLFile();
+// }}
+// >
+// Upload email .eml file{" "}
+//
+//
+// );
+// };
+
+// export default EmailInputMethod;
+
+
+
import { Button, OutlinedButton } from "./Button";
-const EmailInputMethod = ({
- onClickGoogle,
- onClickEMLFile,
-}: {
+interface EmailInputMethodProps {
onClickGoogle: () => void;
onClickEMLFile: () => void;
+ highlighted?: boolean;
+ disabled?: boolean; // Optional disabled prop
+}
+
+const EmailInputMethod: React.FC = ({
+ onClickGoogle,
+ onClickEMLFile,
+ highlighted = false,
+ disabled = false, // Default value set to false
}) => {
return (
- Sign in with Google
- or
- {
- onClickEMLFile();
- }}
- >
- Upload email .eml file{" "}
-
+
+ Sign in with Google
+
+ {!disabled && (
+ <>
+ or
+
+ Upload email .eml file{" "}
+
+ >
+ )}
);
};
diff --git a/packages/app/src/components/LabeledTextArea.tsx b/packages/app/src/components/LabeledTextArea.tsx
index 66112c6..a4dc935 100644
--- a/packages/app/src/components/LabeledTextArea.tsx
+++ b/packages/app/src/components/LabeledTextArea.tsx
@@ -1,7 +1,109 @@
+// import _ from "lodash";
+// import React, { CSSProperties } from "react";
+// import styled from "styled-components";
+// import { Col } from "./Layout";
+
+// export const LabeledTextArea: React.FC<{
+// style?: CSSProperties;
+// className?: string;
+// label: string;
+// value: string;
+// warning?: string;
+// warningColor?: string;
+// disabled?: boolean;
+// disabledReason?: string;
+// secret?: boolean;
+// onChange?: React.ChangeEventHandler;
+// }> = ({
+// style,
+// warning,
+// warningColor,
+// disabled,
+// disabledReason,
+// label,
+// value,
+// onChange,
+// className,
+// secret,
+// }) => {
+// return (
+//
+// {label}
+// {warning && (
+//
+// {warning}
+//
+// )}
+//
+
+// {secret && (
+// Hover to reveal public info sent to chain
+// )}
+//
+// );
+// };
+
+// const Label = styled.label`
+// color: rgba(255, 255, 255, 0.8);
+// `;
+
+// const LabeledTextAreaContainer = styled(Col)`
+// height: 15vh;
+// border-radius: 4px;
+// position: relative;
+// gap: 8px;
+// & .warning {
+// color: #bd3333;
+// font-size: 80%;
+// }
+// .secret {
+// position: absolute;
+// width: 100%;
+// height: 100%;
+// background: #171717;
+// border: 1px dashed rgba(255, 255, 255, 0.5);
+// color: rgba(255, 255, 255, 0.8);
+// user-select: none;
+// pointer-events: none;
+// opacity: 0.95;
+// justify-content: center;
+// display: flex;
+// align-items: center;
+// transition: opacity 0.3s ease-in-out;
+// }
+// &:hover .secret,
+// & :focus + .secret {
+// opacity: 0;
+// }
+// `;
+
+// const TextArea = styled.textarea`
+// border: 1px solid rgba(255, 255, 255, 0.3);
+// background: rgba(0, 0, 0, 0.3);
+// border-radius: 4px;
+// height: 480px;
+// padding: 16px;
+// transition: all 0.2s ease-in-out;
+// resize: none;
+// &:hover {
+// border: 1px solid rgba(255, 255, 255, 0.8);
+// `;
+
+
import _ from "lodash";
import React, { CSSProperties } from "react";
-import styled from "styled-components";
+import styled, { ThemeProvider, css } from "styled-components";
import { Col } from "./Layout";
+import { Box, Typography, useTheme } from "@mui/material";
export const LabeledTextArea: React.FC<{
style?: CSSProperties;
@@ -14,55 +116,61 @@ export const LabeledTextArea: React.FC<{
disabledReason?: string;
secret?: boolean;
onChange?: React.ChangeEventHandler;
+ highlighted?: boolean;
}> = ({
style,
warning,
warningColor,
- disabled,
+ disabled = false, // Default value set to false
disabledReason,
label,
value,
onChange,
className,
secret,
+ highlighted = false,
}) => {
+
+ const theme = useTheme();
+
return (
-
- {label}
- {warning && (
-
- {warning}
-
- )}
-
-
- {secret && (
- Hover to reveal public info sent to chain
- )}
-
+
+
+ {label}
+
+ {warning && (
+
+ {warning}
+
+ )}
+
+
+
+ {secret && (
+ Hover to reveal public info sent to chain
+ )}
+
+
);
};
-const Label = styled.label`
- color: rgba(255, 255, 255, 0.8);
-`;
-
const LabeledTextAreaContainer = styled(Col)`
height: 15vh;
border-radius: 4px;
position: relative;
gap: 8px;
& .warning {
- color: #bd3333;
font-size: 80%;
}
.secret {
@@ -86,14 +194,51 @@ const LabeledTextAreaContainer = styled(Col)`
}
`;
-const TextArea = styled.textarea`
- border: 1px solid rgba(255, 255, 255, 0.3);
- background: rgba(0, 0, 0, 0.3);
- border-radius: 4px;
+const TextArea = styled.textarea<{ highlighted: boolean }>`
+ border: 0px solid #1C1C1C;
+ background: #F3F2F2;
+ border-radius: 10px;
+ color: ${({ theme }) => theme.palette.secondary.main};
height: 480px;
- padding: 16px;
- transition: all 0.2s ease-in-out;
- resize: none;
- &:hover {
- border: 1px solid rgba(255, 255, 255, 0.8);
+ padding: 16px;
+ transition: all 0.2s ease-in-out;
+ resize: none;
+ outline: none;
+
+ /* Apply different font sizes based on breakpoints */
+ ${({ theme }) => css`
+ font-size: 0.5rem; /* Default font size */
+
+ ${theme.breakpoints.up('sm')} {
+ font-size: 0.8rem; /* Font size for small screens and up */
+ }
+
+ ${theme.breakpoints.up('md')} {
+ font-size: 0.9rem; /* Font size for medium screens and up */
+ }
+
+ ${theme.breakpoints.up('lg')} {
+ font-size: 1rem; /* Font size for large screens and up */
+ }
+ `}
+
+ ${({ highlighted, theme }) =>
+ highlighted
+ ? css`
+ border: 2px solid ${theme.palette.accent.main};
+ &:hover {
+ border: 2px solid ${theme.palette.accent.main};
+ }
+ &:focus {
+ border: 1px solid ${theme.palette.accent.main};
+ box-shadow: 0 0 0 2px ${theme.palette.accent.main};
+ }
+ `
+ : css`
+ &:focus {
+ border: 2px solid #1C1C1C;
+ }
+ `}
`;
+
+export default LabeledTextArea;
diff --git a/packages/app/src/components/Layout.tsx b/packages/app/src/components/Layout.tsx
index 24664cc..6bd341f 100644
--- a/packages/app/src/components/Layout.tsx
+++ b/packages/app/src/components/Layout.tsx
@@ -1,3 +1,26 @@
+// import styled from "styled-components";
+
+// export const Row = styled.div`
+// display: flex;
+// align-items: center;
+// `;
+
+// export const Col = styled.div`
+// display: flex;
+// flex-direction: column;
+// `;
+
+// export const RowSpaceBetween = styled(Row)`
+// justify-content: space-between;
+// `;
+
+// export const CenterAllDiv = styled.div`
+// display: flex;
+// align-items: center;
+// justify-content: center;
+// `;
+
+
import styled from "styled-components";
export const Row = styled.div`
diff --git a/packages/app/src/components/Nav.tsx b/packages/app/src/components/Nav.tsx
new file mode 100644
index 0000000..2972c73
--- /dev/null
+++ b/packages/app/src/components/Nav.tsx
@@ -0,0 +1,147 @@
+
+import { Box, Typography, useTheme } from "@mui/material";
+import { ConnectButton } from "@rainbow-me/rainbowkit";
+import PropTypes from 'prop-types';
+import { Link } from 'react-router-dom';
+import React from 'react';
+
+// Define the types for the props
+interface CustomConnectButtonProps {
+ splitscreen?: boolean;
+}
+
+interface NavProps {
+ splitscreen?: boolean;
+}
+
+/* STYLED CONNECT WALLET BUTTON */
+const CustomConnectButton: React.FC = ({ splitscreen = false }) => {
+ const theme = useTheme();
+ return (
+
+ {({
+ account,
+ chain,
+ openAccountModal,
+ openChainModal,
+ openConnectModal,
+ mounted,
+ }) => {
+ const ready = mounted;
+ const connected = ready && account && chain;
+
+ return (
+ {
+ if (!ready) {
+ openConnectModal();
+ } else if (connected) {
+ openAccountModal();
+ } else {
+ openConnectModal();
+ }
+ }}
+ sx={{
+ fontSize: { xs: '12px', md: '14px' },
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ backgroundColor: !connected ? theme.palette.accent.main : '#1f1f1f',
+ color: '#ffffff',
+ padding: { xs: '7px 10px', sm: '10px 16px', md: splitscreen ? '8px 12px' : '10px 16px' },
+ borderRadius: '10px',
+ cursor: 'pointer',
+ '&:hover': {
+ backgroundColor: !connected ? theme.palette.accent.main : '#333333',
+ opacity: !connected ? '95%' : '100%'
+ },
+ }}
+ >
+ {(() => {
+ if (!ready) {
+ return 'Loading...';
+ }
+ if (!connected) {
+ return 'Connect Wallet';
+ }
+ return (
+
+
+ {account.displayBalance ? `${account.displayBalance} ` : ''}
+
+
+
+
+ {account.displayName}
+
+
+
+ );
+ })()}
+
+ );
+ }}
+
+ );
+};
+
+/* THE NAV COMPONENT ITSELF THAT USED THE ABOVE CONNECT BUTTON */
+const Nav: React.FC = ({ splitscreen = false }) => {
+ return (
+
+
+
+ PROOF OF TWITTER
+
+
+
+
+ Docs
+
+
+ Explore
+
+
+
+
+
+ );
+};
+
+Nav.propTypes = {
+ splitscreen: PropTypes.bool,
+};
+
+Nav.defaultProps = {
+ splitscreen: false,
+};
+
+CustomConnectButton.propTypes = {
+ splitscreen: PropTypes.bool,
+};
+
+CustomConnectButton.defaultProps = {
+ splitscreen: false,
+};
+
+export default Nav;
diff --git a/packages/app/src/components/NumberedStep.tsx b/packages/app/src/components/NumberedStep.tsx
index ac0f6bb..ef01744 100644
--- a/packages/app/src/components/NumberedStep.tsx
+++ b/packages/app/src/components/NumberedStep.tsx
@@ -1,3 +1,41 @@
+// import styled from "styled-components";
+// import { CenterAllDiv, Row } from "./Layout";
+
+// export const NumberedStep: React.FC<{
+// step: number;
+// children: React.ReactNode;
+// }> = ({ step, children }) => {
+// return (
+//
+//
+// {step}
+//
+// {children}
+//
+// );
+// };
+
+// const NumberedStepContainer = styled(Row)`
+// background: rgba(255, 255, 255, 0.05);
+// width: 100%;
+// gap: 1rem;
+// border-radius: 4px;
+// padding: 8px;
+// color: #fff;
+// `;
+
+// const NumberedStepLabel = styled(CenterAllDiv)`
+// background: rgba(255, 255, 255, 0.2);
+// border-radius: 4px;
+// width: 24px;
+// height: 24px;
+// min-width: 24px;
+// border: 1px solid rgba(255, 255, 255, 0.3);
+// `;
+
+// const NumberedStepText = styled.span``;
+
+
import styled from "styled-components";
import { CenterAllDiv, Row } from "./Layout";
diff --git a/packages/app/src/components/ProgressBar.tsx b/packages/app/src/components/ProgressBar.tsx
index 43563dd..d137599 100644
--- a/packages/app/src/components/ProgressBar.tsx
+++ b/packages/app/src/components/ProgressBar.tsx
@@ -1,3 +1,58 @@
+// import styled from "styled-components";
+
+// export interface ProgressBarProps {
+// width: number;
+// label?: string;
+// }
+
+// export const ProgressBar: React.FC = ({ width, label }) => {
+// return (
+//
+// {label && (
+//
+// {label}
+//
+// )}
+//
+//
+// );
+// };
+
+// const ProgressBarContainer = styled.div`
+// background: linear-gradient(
+// 90deg,
+// #4860b0 51.26%,
+// #51589f 86.64%,
+// #5a518f 100%
+// );
+// border-radius: 4px;
+// height: 32px;
+// position: relative;
+// width: 100%;
+// `;
+
+// const ProgressBarFill = styled.div<{ width: number }>`
+// background: #7796ff;
+// border-radius: 4px;
+// height: 32px;
+// width: ${(props) => props.width}%;
+// `;
+
+// const LabelContainer = styled.div`
+// display: flex;
+// position: absolute;
+// top: 50%;
+// left: 50%;
+// transform: translate(-50%, -50%);
+// align-items: center;
+// justify-content: center;
+// font-weight: 600;
+// font-size: 0.9rem;
+// letter-spacing: -0.02em;
+// color: #fff;
+// `;
+
+
import styled from "styled-components";
export interface ProgressBarProps {
diff --git a/packages/app/src/components/SingleLineInput.tsx b/packages/app/src/components/SingleLineInput.tsx
index f2c7f91..aa9572d 100644
--- a/packages/app/src/components/SingleLineInput.tsx
+++ b/packages/app/src/components/SingleLineInput.tsx
@@ -1,40 +1,124 @@
+// import styled from "styled-components";
+// import { Col } from "./Layout";
+
+// export const SingleLineInput: React.FC<{
+// label: string;
+// value: any;
+// onChange: (e: any) => void;
+// }> = ({ label, onChange, value }) => {
+// return (
+//
+//
+// {label}
+//
+//
+//
+// );
+// };
+
+// const InputContainer = styled(Col)`
+// gap: 8px;
+// `;
+
+// const Input = styled.input`
+// border: 1px solid rgba(255, 255, 255, 0.4);
+// background: rgba(0, 0, 0, 0.3);
+// border-radius: 4px;
+// padding: 8px;
+// height: 32px;
+// display: flex;
+// align-items: center;
+// color: #fff;
+// transition: all 0.2s ease-in-out;
+// &:hover {
+// border: 1px solid rgba(255, 255, 255, 0.8);
+// }
+// `;
+
+
+import React from 'react';
import styled from "styled-components";
-import { Col } from "./Layout";
+import { useTheme, TextField, Box, Typography } from "@mui/material";
-export const SingleLineInput: React.FC<{
+interface SingleLineInputProps {
label: string;
value: any;
onChange: (e: any) => void;
-}> = ({ label, onChange, value }) => {
+ highlighted?: boolean;
+ disabled?: boolean; // Optional disabled prop
+}
+
+export const SingleLineInput: React.FC = ({
+ label,
+ onChange,
+ value,
+ highlighted = false,
+ disabled = false, // Default value set to false
+}) => {
+
+ const theme = useTheme();
+
return (
-
-
+
{label}
-
-
-
+
+
+
);
};
-
-const InputContainer = styled(Col)`
- gap: 8px;
-`;
-
-const Input = styled.input`
- border: 1px solid rgba(255, 255, 255, 0.4);
- background: rgba(0, 0, 0, 0.3);
- border-radius: 4px;
- padding: 8px;
- height: 32px;
- display: flex;
- align-items: center;
- color: #fff;
- transition: all 0.2s ease-in-out;
- &:hover {
- border: 1px solid rgba(255, 255, 255, 0.8);
- }
-`;
diff --git a/packages/app/src/components/StatusTag.tsx b/packages/app/src/components/StatusTag.tsx
new file mode 100644
index 0000000..72136e5
--- /dev/null
+++ b/packages/app/src/components/StatusTag.tsx
@@ -0,0 +1,35 @@
+// StatusTag.tsx
+import React from 'react';
+import { Typography, Box } from '@mui/material';
+
+interface StatusTagProps {
+ statusMessage: string;
+ statusPassed: boolean;
+}
+
+const StatusTag: React.FC = ({ statusMessage, statusPassed }) => {
+ return (
+
+ {statusMessage}
+
+ );
+};
+
+export default StatusTag;
diff --git a/packages/app/src/components/Stepper.tsx b/packages/app/src/components/Stepper.tsx
new file mode 100644
index 0000000..3f9fdee
--- /dev/null
+++ b/packages/app/src/components/Stepper.tsx
@@ -0,0 +1,741 @@
+// import React, { useState } from 'react';
+// import { Stepper, Step, StepLabel, Button, Box } from '@mui/material';
+
+// const steps = [
+// 'Send Reset Email',
+// 'Copy/Paste DKIM Sig',
+// 'Add Address',
+// 'Prove',
+// 'Verify & Mint'
+// ];
+
+// const StepperComponent: React.FC = () => {
+// const [activeStep, setActiveStep] = useState(0);
+
+// const handleNext = () => {
+// setActiveStep((prevActiveStep) => prevActiveStep + 1);
+// };
+
+// const handleBack = () => {
+// setActiveStep((prevActiveStep) => prevActiveStep - 1);
+// };
+
+// const handleStep = (step: number) => () => {
+// setActiveStep(step);
+// };
+
+// return (
+//
+//
+// {steps.map((label, index) => (
+//
+// {label}
+//
+// ))}
+//
+//
+// {activeStep === steps.length ? (
+//
+//
All steps completed
+//
setActiveStep(0)}>Reset
+//
+// ) : (
+//
+//
+//
+// Back
+//
+//
+// {activeStep === steps.length - 1 ? 'Finish' : 'Next'}
+//
+//
+//
+// )}
+//
+//
+// );
+// };
+
+// export default StepperComponent;
+
+
+
+
+
+
+
+
+
+// import React, { useState } from 'react';
+// import { Stepper, Step, StepLabel, Button, Box, Typography } from '@mui/material';
+// import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
+
+// const steps = [
+// 'Send Reset Email',
+// 'Copy/Paste DKIM Sig',
+// 'Add Address',
+// 'Prove',
+// 'Verify & Mint'
+// ];
+
+// const StepperComponent: React.FC = () => {
+// const [activeStep, setActiveStep] = useState(0);
+
+// const handleNext = () => {
+// setActiveStep((prevActiveStep) => prevActiveStep + 1);
+// };
+
+// const handleBack = () => {
+// setActiveStep((prevActiveStep) => prevActiveStep - 1);
+// };
+
+// const handleStep = (step: number) => () => {
+// setActiveStep(step);
+// };
+
+// return (
+//
+//
+// {steps.map((label, index) => (
+//
+//
+//
+// {label}
+//
+//
+// {index < steps.length - 1 && }
+//
+// ))}
+//
+//
+// {activeStep === steps.length ? (
+//
+//
All steps completed
+//
setActiveStep(0)}>Reset
+//
+// ) : (
+//
+//
+//
+// Back
+//
+//
+// {activeStep === steps.length - 1 ? 'Finish' : 'Next'}
+//
+//
+//
+// )}
+//
+//
+// );
+// };
+
+// export default StepperComponent;
+
+
+
+
+
+
+
+
+// import React, { useState } from 'react';
+// import { Box, Typography, IconButton } from '@mui/material';
+// import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
+
+// const steps = [
+// 'Send Reset Email',
+// 'Copy/Paste DKIM Sig',
+// 'Add Address',
+// 'Prove',
+// 'Verify & Mint'
+// ];
+
+// const StepperComponent: React.FC = () => {
+// const [activeStep, setActiveStep] = useState(0);
+
+// const handleStep = (step: number) => () => {
+// setActiveStep(step);
+// };
+
+// return (
+//
+// {steps.map((label, index) => (
+//
+//
+//
+// {label}
+//
+//
+// {index < steps.length - 1 && (
+//
+// )}
+//
+// ))}
+//
+// );
+// };
+
+// export default StepperComponent;
+
+
+
+
+// import React, { useState } from 'react';
+// import { Box, Typography } from '@mui/material';
+// import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
+
+// const steps = [
+// 'SEND RESET EMAIL',
+// 'COPY/PASTE DKIM SIG',
+// 'ADD ADDRESS',
+// 'PROVE',
+// 'VERIFY & MINT'
+// ];
+
+// const StepperComponent: React.FC = () => {
+// const [activeStep, setActiveStep] = useState(0);
+
+// const handleStep = (step: number) => () => {
+// setActiveStep(step);
+// };
+
+// return (
+//
+// {/* Light grey bar */}
+//
+
+//
+// {steps.map((label, index) => (
+//
+//
+//
+// {label}
+//
+//
+// {index < steps.length - 1 && (
+//
+// )}
+//
+// ))}
+//
+//
+// );
+// };
+
+// export default StepperComponent;
+
+
+
+
+
+
+
+
+
+
+
+
+// import React, { ReactNode } from 'react';
+// import { Box, Typography, Button } from '@mui/material';
+// import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
+
+// interface StepperComponentProps {
+// children: ReactNode;
+// steps: string[];
+// activeStep: number;
+// setActiveStep: (step: number) => void;
+// }
+
+// const StepperComponent: React.FC = ({
+// children,
+// steps,
+// activeStep,
+// setActiveStep
+// }) => {
+// const handleStep = (step: number) => () => {
+// setActiveStep(step);
+// };
+
+// const handleNext = () => {
+// setActiveStep((prevActiveStep) => prevActiveStep + 1);
+// };
+
+// const handleBack = () => {
+// setActiveStep((prevActiveStep) => prevActiveStep - 1);
+// };
+
+// return (
+//
+//
+// {/* Light grey bar */}
+//
+// {steps.map((label, index) => (
+//
+//
+//
+// {label}
+//
+//
+// {index < steps.length - 1 && (
+//
+// )}
+//
+// ))}
+//
+
+//
+// {children}
+//
+
+//
+// {activeStep !== 0 && (
+//
+// Back
+//
+// )}
+
+
+// {activeStep !== 4 && (
+//
+// Next
+//
+// )}
+//
+//
+// );
+// };
+
+// export default StepperComponent;
+
+
+
+
+
+
+// import React, { useState, ReactNode } from 'react';
+// import { Box, Typography, Button } from '@mui/material';
+// import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
+
+// interface StepperComponentProps {
+// children: ReactNode;
+// steps: string[];
+// activeStep: number;
+// setActiveStep: (step: number) => void;
+// }
+
+// const StepperComponent: React.FC = ({
+// children,
+// steps,
+// activeStep,
+// setActiveStep
+// }) => {
+// const [completedSteps, setCompletedSteps] = useState(new Array(steps.length).fill(false));
+
+// const handleStep = (step: number) => () => {
+// if (step <= activeStep || completedSteps[step - 1]) {
+// setActiveStep(step);
+// }
+// };
+
+// const handleNext = () => {
+// if (activeStep < steps.length - 1 && completedSteps.slice(0, activeStep).every(completed => completed)) {
+// setCompletedSteps((prevCompletedSteps) => {
+// const newCompletedSteps = [...prevCompletedSteps];
+// newCompletedSteps[activeStep] = true;
+// return newCompletedSteps;
+// });
+// setActiveStep((prevActiveStep) => prevActiveStep + 1);
+// }
+// };
+
+// const handleBack = () => {
+// setActiveStep((prevActiveStep) => prevActiveStep - 1);
+// };
+
+// return (
+//
+//
+// {/* Light grey bar */}
+//
+// {steps.map((label, index) => {
+// const isStepDisabled = !(index <= activeStep || completedSteps[index - 1]);
+// return (
+//
+//
+//
+// {label}
+//
+//
+// {index < steps.length - 1 && (
+//
+// )}
+//
+// );
+// })}
+//
+
+//
+// {children}
+//
+
+//
+// {activeStep !== 0 && (
+//
+// Back
+//
+// )}
+
+
+// {activeStep !== steps.length - 1 && (
+// completed)}
+// sx={{
+// textTransform: 'none',
+// fontWeight: 'regular',
+// padding: '10px 35px',
+// backgroundColor: '#1C1C1C',
+// border: '1px solid #1C1C1C',
+// marginY: '9px',
+// color: '#ffffff',
+// '&.Mui-disabled': {
+// backgroundColor: '#ffffff', // Change to desired disabled background color
+// color: '#1C1C1C', // Change to desired disabled text color
+// border: '1px solid #757575', // Change to desired disabled border color
+// }
+// }}
+// >
+// Next
+//
+// )}
+//
+//
+// );
+// };
+
+// export default StepperComponent;
+
+import React, { ReactNode } from 'react';
+import { Box, Typography, Button, useTheme } from '@mui/material';
+import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
+
+// Define the types for the props
+interface StepperComponentProps {
+ children: ReactNode;
+ steps: [string, 'completed' | 'uncompleted'][];
+ activeStep: number;
+ setActiveStep: (step: number) => void;
+}
+
+const StepperComponent: React.FC = ({
+ children,
+ steps,
+ activeStep,
+ setActiveStep
+}) => {
+ const theme = useTheme();
+
+ const handleStep = (step: number) => () => {
+ if (step <= activeStep || steps.slice(0, step).every(s => s[1] === 'completed')) {
+ setActiveStep(step);
+ }
+ };
+
+ const handleNext = () => {
+ if (
+ activeStep < steps.length - 1 &&
+ steps.slice(0, activeStep + 1).every(step => step[1] === 'completed')
+ ) {
+ setActiveStep(activeStep + 1);
+ }
+ };
+
+ const handleBack = () => {
+ setActiveStep(activeStep - 1);
+ };
+
+ return (
+
+
+
+ {steps.map((step, index) => {
+ const isStepDisabled = !steps.slice(0, index).every(s => s[1] === 'completed');
+ return (
+
+
+
+ {step[0]}
+
+
+ {index < steps.length - 1 && (
+
+ )}
+
+ );
+ })}
+
+
+
+ {children}
+
+
+
+ {activeStep !== 0 && (
+
+ Back
+
+ )}
+
+ {activeStep !== steps.length - 1 && (
+ step[1] === 'completed')}
+ sx={{
+ textTransform: 'none',
+ fontWeight: 'regular',
+ padding: '10px 35px',
+ backgroundColor: theme.palette.text.primary,
+ border: `1px solid ${theme.palette.text.primary}`,
+ marginY: '9px',
+ color: theme.palette.background.paper,
+ '&.Mui-disabled': {
+ backgroundColor: theme.palette.background.paper,
+ color: theme.palette.text.primary,
+ border: `1px solid ${theme.palette.text.disabled}`,
+ cursor: 'not-allowed',
+ pointerEvents: 'all !important'
+ }
+ }}
+ >
+ Next
+
+ )}
+
+
+ );
+};
+
+export default StepperComponent;
diff --git a/packages/app/src/components/TopBanner.tsx b/packages/app/src/components/TopBanner.tsx
index 9f8fba5..08e1aa0 100644
--- a/packages/app/src/components/TopBanner.tsx
+++ b/packages/app/src/components/TopBanner.tsx
@@ -1,3 +1,24 @@
+// import styled from "styled-components";
+
+// export const TopBanner: React.FC<{ message: string }> = ({ message }) => {
+// return {message} ;
+// };
+
+// const Container = styled.div`
+// display: flex;
+// justify-content: center;
+// align-items: center;
+// position: fixed;
+// top: 0;
+// left: 0;
+// right: 0;
+// width: 100%;
+// padding: 16px;
+// background: #8742f5;
+// color: #fff;
+// font-weight: 500;
+// `;
+
import styled from "styled-components";
export const TopBanner: React.FC<{ message: string }> = ({ message }) => {
diff --git a/packages/app/src/components/Video.tsx b/packages/app/src/components/Video.tsx
new file mode 100644
index 0000000..69c3f16
--- /dev/null
+++ b/packages/app/src/components/Video.tsx
@@ -0,0 +1,52 @@
+/* LOCAL VIDEO VERSION BELOW */
+import React from 'react';
+import { Box } from '@mui/material';
+
+const Video: React.FC = () => {
+ return (
+
+
+
+ Your browser does not support the video tag.
+
+
+ );
+}
+
+export default Video;
+
+
+
+
+
+/* YOUTUBE VIDEO VERSION BELOW */
+
+
+
+
+
+// import React from 'react';
+// import { Box } from '@mui/material';
+
+// const Video: React.FC = () => {
+// return (
+//
+// VIDEO
+//
+// );
+// }
+
+// export default Video;
\ No newline at end of file
diff --git a/packages/app/src/index.tsx b/packages/app/src/index.tsx
index 8e22ba2..6dece6d 100644
--- a/packages/app/src/index.tsx
+++ b/packages/app/src/index.tsx
@@ -3,8 +3,8 @@ import ReactDOM from "react-dom";
import App from "./App";
import { WagmiConfig, WagmiProvider, createConfig } from "wagmi";
import { createPublicClient, http } from "viem";
-import { configureChains } from "wagmi";
-import { publicProvider } from "wagmi/providers/public";
+// import { configureChains } from "wagmi";
+// import { publicProvider } from "wagmi/providers/public";
import { sepolia } from "wagmi/chains";
import {
getDefaultWallets,
@@ -17,6 +17,8 @@ import { GoogleOAuthProvider } from "@react-oauth/google";
import { GoogleAuthProvider } from "./contexts/GoogleAuth";
import { ZkEmailSDKProvider } from "@zk-email/zk-email-sdk";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { ThemeProvider, CssBaseline } from '@mui/material';
+import theme from './theme';
// const { connectors } = getDefaultWallets({
// appName: "ZK Email - Twitter Verifier",
@@ -44,22 +46,24 @@ const queryClient = new QueryClient();
ReactDOM.render(
-
-
-
-
-
-
-
-
-
-
- {" "}
-
-
+
+
+
+
+
+
+
+
+
+
+
+ {" "}
+
+
+
,
document.getElementById("root")
);
diff --git a/packages/app/src/pages/AboutPage.tsx b/packages/app/src/pages/AboutPage.tsx
new file mode 100644
index 0000000..0717e71
--- /dev/null
+++ b/packages/app/src/pages/AboutPage.tsx
@@ -0,0 +1,186 @@
+import React from 'react';
+import Nav from '../components/Nav';
+import { Container, Typography, Box, Grid, Stack, useTheme } from '@mui/material';
+import { Button, OutlinedButton } from '../components/Button';
+import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward';
+import Accordion from '../components/Accordion';
+import { Link } from 'react-router-dom';
+import { useMediaQuery } from "@mui/material";
+
+import LockResetIcon from '@mui/icons-material/LockReset';
+import MailOutlineIcon from '@mui/icons-material/MailOutline';
+import FingerprintIcon from '@mui/icons-material/Fingerprint';
+import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
+import RefreshIcon from '@mui/icons-material/Refresh';
+import ContentPasteIcon from '@mui/icons-material/ContentPaste';
+import DraftsOutlinedIcon from "@mui/icons-material/DraftsOutlined";
+import Video from '../components/Video';
+
+
+const AboutPage: React.FC = () => {
+ const theme = useTheme();
+ const isXs = useMediaQuery(theme.breakpoints.down('xs'));
+ const isSm = useMediaQuery(theme.breakpoints.down('sm'));
+ const isMd = useMediaQuery(theme.breakpoints.down('md'));
+
+ const faqs = [
+ {
+ title: 'How do you selectively reveal content in an email ?',
+ contents: 'We can hide any information or selectively reveal any text, wether that’s the sender, receiver, subject, body etc using Regex. Regex is short for regular expression, this term represents sequence of characters that forms a search pattern, commonly used for string matching within text. It consists of a sequence of characters that define a search pattern, enabling complex searches, substitutions, and string manipulations. For example, in programming and text processing, regex can identify, extract, or replace specific text patterns, such as email addresses, dates, or phone numbers, by defining these patterns through a combination of literal characters and special symbols. In the context of ZK Email it is used to parse email headers and extract relevant information.'
+ },
+ {
+ title: 'How can I do this anonymously',
+ contents: 'ZK Email leverages the principles of Zero Knowledge proofs and serverless execution within the browser to provide a verifiable yet anonymous way to confirm an emails contents and recipents . Zero Knowledge proofs allow provers to prove that they know or possess certain information without revealing the information itself to a verifer. In ZK Email, this technology is used to verify user identity and email content without exposing sensitive data to a server or other users. The serverless architecture means that all proof generation is executed entirely within the user`s browser.'
+ },
+ {
+ title: 'Why don’t I need to trust you?',
+ contents: 'The DKIM email signitures do not contain information we can use to sign other emails, all our code is open source and being audited'
+ },
+ {
+ title: 'How do you verify the email contents and recipents',
+ contents: 'We use the existing DKIM Signiture, almost all emails are signed by the sending domain server using an algorithm called DKIM. It can be summarized as this rsa_sign(sha256(from:..., to:..., subject:..., ,...), private key). Every time an email is sent we can verify the sender, receiver, the subject, the body by checking if the corresponding public key of the email address applied on the DKIM signiture returns the sha256(from:..., to:..., subject:..., ,...) a hash of the from, to subject, email details which we can check by rehashing'
+ },
+ ];
+
+ return (
+
+
+
+
+
+
+
+
+
+ ZKEmail Tech
+
+
+
+
+ Welcome to Proof of Twitter, {' '}
+
+
+
+ a ZK Email Technology
+
+
+
+ Our ZK libraries will allow you to generate zero knowledge proofs proving
+
+
+
+ you received some email and mask out any private data,
+
+
+
+ without trusting our server to keep your privacy.
+
+
+
+ } href='/' highlighted={true}>
+ Try it out
+
+
+ Learn More
+
+
+
+
+
+
+
+ {/* STEPS ROW */}
+
+
+
+ SEND RESET EMAIL
+
+
+
+ COPY/PASTE DKIM SIG
+
+
+
+ ADD ADDRESS
+
+
+
+ GENERATE PROOF
+
+
+
+ VERIFY & MINT
+
+
+
+
+
+
+ {/* VIDEO */}
+
+
+
+
+
+
+
+
+
+
+ {/* FAQ ACCORDION */}
+ {/* */}
+
+
+
+
+
+ Frequently Asked Questions
+
+
+
+
+
+
+ Have a Question that isn’t answered?
+
+
+ Drop Us a Line
+
+
+
+
+ {faqs.map((faq, index) => (
+
+ ))}
+
+
+
+
+
+
+
+ );
+};
+
+export default AboutPage;
diff --git a/packages/app/src/pages/MainPage.tsx b/packages/app/src/pages/MainPage.tsx
index 65d29c1..67351fb 100644
--- a/packages/app/src/pages/MainPage.tsx
+++ b/packages/app/src/pages/MainPage.tsx
@@ -35,6 +35,15 @@ import { useZkEmailSDK } from "@zk-email/zk-email-sdk";
import { calculateSignalLength, circuitOutputToArgs } from "../utils";
import { Hex } from "viem";
+
+import { Box, Grid, Typography } from "@mui/material";
+import Stepper from '../components/Stepper'
+import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward';
+import Video from "../components/Video";
+import Nav from "../components/Nav";
+import {useTheme} from "@mui/material";
+import StatusTag from "../components/StatusTag";
+
const CIRCUIT_NAME = "twitter";
const entry = {
id: "clyhcz1tl0001r4i0t87dk48g",
@@ -409,406 +418,644 @@ export const MainPage: React.FC<{}> = (props) => {
);
};
+
+
+
+
+ const theme = useTheme()
+
+ const [counter, setCounter] = useState(0);
+
+
+ const [steps, setSteps] = useState<[string, 'completed' | 'uncompleted'][]>([
+ ['SEND RESET EMAIL', 'completed'],
+ ['COPY/PASTE DKIM SIG', 'uncompleted'],
+ ['ADD ADDRESS', 'uncompleted'],
+ ['PROVE', 'uncompleted'],
+ ['VERIFY & MINT', 'uncompleted']
+ ]);
+
+ const [activeStep, setActiveStep] = useState(0);
+
+ const markStepCompleted = (index: number) => {
+ setSteps(prevSteps => {
+ const newSteps = [...prevSteps];
+ newSteps[index][1] = 'completed';
+ return newSteps;
+ });
+ };
+
+ const markStepUncompleted = (index: number) => {
+ setSteps(prevSteps => {
+ const newSteps = [...prevSteps];
+ newSteps[index][1] = 'uncompleted';
+ return newSteps;
+ });
+ };
+
+
+ useEffect(() => {
+ let interval: NodeJS.Timeout;
+ if (status === 'generating-proof') {
+ interval = setInterval(() => {
+ setCounter(prevCounter => prevCounter + 1);
+ }, 1000);
+ } else {
+ setCounter(0);
+ }
+ return () => clearInterval(interval);
+ }, [status]);
+
+
+ useEffect(() => {
+ // i'm not sure if this if statement check is correct, after the &&
+ // i want to make sure the user actually put something in the 'Full Email with Headers' section OR if they logged in with Google they actually selected an email and it's not the default localStorage.emailFull=DOMException
+ // this code works but there's probably a better check?
+ if (emailFull != '' && emailFull != 'DOMException') {
+ markStepCompleted(1); // Mark 'COPY/PASTE DKIM SIG' step as completed
+ } else {
+ markStepUncompleted(1); // Mark 'COPY/PASTE DKIM SIG' step as uncompleted
+ }
+ }, [emailFull]);
+
+
+ useEffect(() => {
+ if (ethereumAddress != '') {
+ markStepCompleted(2); // Mark 'ADD ADDRESS' step as completed
+ } else {
+ markStepUncompleted(2); // Mark 'ADD ADDRESS' step as uncompleted
+ }
+ }, [ethereumAddress]);
+
+
+ useEffect(() => {
+ if (status === 'done' || status === 'proof-files-downloaded-successfully') {
+ markStepCompleted(3); // Mark 'PROVE' step as completed
+ } else {
+ // markStepUncompleted(3); // Mark 'PROVE' step as uncompleted
+ }
+ }, [status]);
+
+
+ const [isOverlayVisible, setIsOverlayVisible] = useState(false);
+
+ useEffect(() => {
+ if (status === 'generating-proof') {
+ setIsOverlayVisible(true);
+ } else {
+ setIsOverlayVisible(false);
+ }
+ }, [status]);
+
+
+
+
+
+
+
return (
-
+
+ {isOverlayVisible && }
{showBrowserWarning && (
)}
-
- Proof of Twitter: ZK Email Demo
-
-
-
-
- Welcome to a demo page for ZK-Email technology.{" "}
-
- Our library
- {" "}
- will allow you to generate zero knowledge proofs proving you received
- some email and mask out any private data, without trusting our server
- to keep your privacy. This demo is just one use case that lets you
- prove you own a Twitter username on-chain, by verifying confirmation
- emails (and their normally-hidden headers) from Twitter. Visit{" "}
- our blog or{" "}
- website to learn more about ZK
- Email, and find the technical details on how this demo is built{" "}
- here .
-
-
- If you wish to generate a ZK proof of Twitter badge (NFT), you must:
-
-
- Send yourself a{" "}
-
- password reset email
- {" "}
- from Twitter. (Reminder: Twitter name with emoji might fail to pass
- DKIM verification)
-
-
- In your inbox, find the email from Twitter and click the three dot
- menu, then "Show original" then "Copy to clipboard". If on Outlook,
- download the original email as .eml and copy it instead.
-
-
- Copy paste or drop that into the box below. Note that we cannot use
- this to phish you: we do not know your password, and we never get this
- email info because we have no server at all. We are actively searching
- for a less sketchy email.
-
-
- Paste in your sending Ethereum address. This ensures that no one else
- can "steal" your proof for another account (frontrunning protection!).
-
-
- Click "Prove" . Note it is completely client side and{" "}
-
- open source
-
- , and no server ever sees your private information.
-
-
- Click "Verify" and then "Mint Twitter Badge On-Chain" ,
- and approve to mint the NFT badge that proves Twitter ownership! Note
- that it is 700K gas right now so only feasible on Sepolia, though we
- intend to reduce this soon.
-
-
-
-
- Input
- {inputMethod || !import.meta.env.VITE_GOOGLE_CLIENT_ID ? null : (
- {
- try {
- setIsFetchEmailLoading(true);
- setInputMethod("GOOGLE");
- googleLogIn();
- } catch (e) {
- console.log(e);
- setIsFetchEmailLoading(false);
- }
- }}
- onClickEMLFile={() => {
- setInputMethod("EML_FILE");
- }}
- />
+
+
+
+
+ {/* --------- LEFT HAND SIDE OF SCREEN --------- */}
+
+
+
+
+
+ {/* --------- SEND TWITTER PASSWORD RESET EMAIL SECTION - STEP 0 --------- */}
+ {activeStep ==0 && (
+
+ SEND TWITTER PASSWORD RESET EMAIL
+ Send yourself a password reset email from Twitter. (Reminder: Twitter name with emoji might fail to pass DKIM verification)
+ {/* {message} */}
+
)}
- {inputMethod ? (
- setInputMethod(null)}>
- ←{" "}Go Back
-
- ) : null}
- {inputMethod === "GOOGLE" ? (
-
- {isFetchEmailLoading ? (
-
- ) : (
- fetchedEmails.map((email, index) => (
+ {/* --------- END OF: SEND TWITTER PASSWORD RESET EMAIL SECTION - STEP 0 --------- */}
+
+
+
+
+
+
+ {/* --------- COPY & PASTE THE EMAIL DKIM SIG - STEP 1 --------- */}
+ {activeStep ==1 && (
+
+
+ COPY & PASTE THE EMAIL DKIM SIG
+ In your inbox, find the email from Twitter and click the three dot menu, then "Show original" then "Copy to clipboard". If on Outlook, download the original email as .eml and copy it instead. Copy paste or drop that into the box below. Note that we cannot use this to phish you: we do not know your password, and we never get this email info because we have no server at all. We are actively searching for a less sketchy email.
+
+
+
+ Input
+ {inputMethod || !import.meta.env.VITE_GOOGLE_CLIENT_ID ? null : (
+ {
+ try {
+ setIsFetchEmailLoading(true);
+ setInputMethod("GOOGLE");
+ googleLogIn();
+ } catch (e) {
+ console.log(e);
+ setIsFetchEmailLoading(false);
+ }
+ }}
+ onClickEMLFile={() => {
+ setInputMethod("EML_FILE");
+ }}
+ />
+ )}
+ {inputMethod ? (
+ setInputMethod(null)}>
+ ←{" "}Go Back
+
+ ) : null}
+ {inputMethod === "GOOGLE" ? (
{
- setEmailFull(email.decodedContents);
+ justifyContent: "center",
+ alignItems: "center",
+ flexDirection: "column",
+ padding: "1.25rem",
}}
>
-
{email.subject}
-
{formatDateTime(email.internalDate)}
+ {isFetchEmailLoading ? (
+
+ ) : (
+ <>
+
+ Select the "Password Reset Request" Email from Twitter!
+
+ {fetchedEmails.map((email, index) => (
+
{
+ setEmailFull(email.decodedContents);
+ }}
+ >
+
+ {email.subject}
+
+
+ {formatDateTime(email.internalDate)}
+
+
+ ))}
+ >
+ )}
+
- ))
+ ) : null}
+ {inputMethod === "EML_FILE" ||
+ !import.meta.env.VITE_GOOGLE_CLIENT_ID ? (
+ <>
+ {" "}
+
+
+ OR
+
+ {
+ setEmailFull(e.currentTarget.value);
+ }}
+ />
+ >
+ ) : null}
+
+
+
+ {displayMessage ===
+ "Downloading compressed proving files... (this may take a few minutes)" && (
+
)}
-
- ) : null}
- {inputMethod === "EML_FILE" ||
- !import.meta.env.VITE_GOOGLE_CLIENT_ID ? (
- <>
- {" "}
-
-
- OR
-
- {
- setEmailFull(e.currentTarget.value);
- }}
+
+ {status !== "not-started" ? (
+
+ Status:
+ {status}
+
+ ) : (
+
+ )}
+
+
+
+
+ )}
+ {/* --------- END OF: COPY & PASTE THE EMAIL DKIM SIG - STEP 1 --------- */}
+
+
+
+
+ {/* --------- ADD ETHEREUM ADDRESS TO SECURE PROOF - STEP 2 --------- */}
+ {activeStep ==2 && (
+
+
+ ADD ETHEREUM ADDRESS TO SECURE PROOF
+ Paste in your sending Ethereum address. This ensures that no one else can "steal" your proof for another account (frontrunning protection!). Click "Prove". Note it is completely client side and open source, and no server ever sees your private information.
+
+
+
+ Input
+ <>
+ {
+ setEmailFull(e.currentTarget.value);
+ }}
+ />
+ >
+
+ {
+ setEthereumAddress(e.currentTarget.value);
+ setExternalInputs({...externalInputs,address: e.target.value,});
+ }}
+ />
+
+ {displayMessage ===
+ "Downloading compressed proving files... (this may take a few minutes)" && (
+
+ )}
+
+ {status !== "not-started" ? (
+
+ Status:
+ {status}
+
+ ) : (
+
+ )}
+
+
+
+
+ )}
+ {/* --------- END OF: ADD ETHEREUM ADDRESS TO SECURE PROOF - STEP 2 --------- */}
+
+
+
+
+
+
+ {/* --------- GENERATE PROOF USING INPUTS - STEP 3 --------- */}
+ {activeStep ==3 && (
+
+
+ GENERATE PROOF USING INPUTS
+ Click "Prove". Note it is completely client side and open source, and no server ever sees your private information.
+
+
+
+ Input
+ {
+ setEmailFull(e.currentTarget.value);
+ }}
+ />
+ {
+ setEthereumAddress(e.currentTarget.value);
+ setExternalInputs({...externalInputs, address: e.target.value,});
+ }}
+ />
+ {
+ let input: ITwitterCircuitInputs;
+ try {
+ setDisplayMessage("Generating proof...");
+ setStatus("generating-input");
+
+ input = await generateTwitterVerifierCircuitInputs(
+ Buffer.from(emailFull),
+ ethereumAddress
+ );
+
+ console.log("Generated input:", JSON.stringify(input));
+ } catch (e) {
+ console.log("Error generating input", e);
+ setDisplayMessage("Prove");
+ setStatus("error-bad-input");
+ return;
+ }
+
+ console.time("zk-gen");
+ recordTimeForActivity("startedProving");
+ setDisplayMessage(
+ "Starting proof generation (this will take 6-10 minutes & ~5GB RAM)"
+ );
+ setStatus("generating-proof");
+ console.log("Starting proof generation");
+ // alert("Generating proof, will fail due to input");
+
+
+ const { proof, publicSignals } = await generateProof(
+ input,
+ // @ts-ignore
+ import.meta.env.VITE_CIRCUIT_ARTIFACTS_URL,
+ CIRCUIT_NAME
+ );
+
+
+
+
+ //const proof = JSON.parse('{"pi_a": ["19201501460375869359786976350200749752225831881815567077814357716475109214225", "11505143118120261821370828666956392917988845645366364291926723724764197308214", "1"], "pi_b": [["17114997753466635923095897108905313066875545082621248342234075865495571603410", "7192405994185710518536526038522451195158265656066550519902313122056350381280"], ["13696222194662648890012762427265603087145644894565446235939768763001479304886", "2757027655603295785352548686090997179551660115030413843642436323047552012712"], ["1", "0"]], "pi_c": ["6168386124525054064559735110298802977718009746891233616490776755671099515304", "11077116868070103472532367637450067545191977757024528865783681032080180232316", "1"], "protocol": "groth16", "curve": "bn128"}');
+ //const publicSignals = JSON.parse('["0", "0", "0", "0", "0", "0", "0", "0", "32767059066617856", "30803244233155956", "0", "0", "0", "0", "27917065853693287", "28015", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "113659471951225", "0", "0", "1634582323953821262989958727173988295", "1938094444722442142315201757874145583", "375300260153333632727697921604599470", "1369658125109277828425429339149824874", "1589384595547333389911397650751436647", "1428144289938431173655248321840778928", "1919508490085653366961918211405731923", "2358009612379481320362782200045159837", "518833500408858308962881361452944175", "1163210548821508924802510293967109414", "1361351910698751746280135795885107181", "1445969488612593115566934629427756345", "2457340995040159831545380614838948388", "2612807374136932899648418365680887439", "16021263889082005631675788949457422", "299744519975649772895460843780023483", "3933359104846508935112096715593287", "556307310756571904145052207427031380052712977221"]');
+ console.log("Finished proof generation");
+ console.timeEnd("zk-gen");
+ recordTimeForActivity("finishedProving");
+
+ console.log("publicSignals", publicSignals);
+
+ // alert("Done generating proof");
+ setProof(JSON.stringify(proof));
+ // let kek = publicSignals.map((x: string) => BigInt(x));
+ // let soln = packedNBytesToString(kek.slice(0, 12));
+ // let soln2 = packedNBytesToString(kek.slice(12, 147));
+ // let soln3 = packedNBytesToString(kek.slice(147, 150));
+ // setPublicSignals(`From: ${soln}\nTo: ${soln2}\nUsername: ${soln3}`);
+ setPublicSignals(JSON.stringify(publicSignals));
+
+ if (!input) {
+ setStatus("error-failed-to-prove");
+ return;
+ }
+ setLastAction("sign");
+ setDisplayMessage("Finished computing ZK proof");
+ setStatus("done");
+ try {
+ (window as any).cJson = JSON.stringify(input);
+ console.log(
+ "wrote circuit input to window.cJson. Run copy(cJson)"
+ );
+ } catch (e) {
+ console.error(e);
+ }
+ }}
+ >
+ {displayMessage}
+
+
+ Generate Proof Remotely{" "}
+ {isRemoteProofGenerationLoading || areInputWorkersCreating ?
+ (
+
+ ) : (
+ ""
+ )}
+
+
+ {displayMessage ===
+ "Downloading compressed proving files... (this may take a few minutes)" && (
+
- >
- ) : null}
- {
- setEthereumAddress(e.currentTarget.value);
- setExternalInputs({
- ...externalInputs,
- address: e.target.value,
- });
- }}
- />
- {
- let input: ITwitterCircuitInputs;
- try {
- setDisplayMessage("Generating proof...");
- setStatus("generating-input");
-
- input = await generateTwitterVerifierCircuitInputs(
- Buffer.from(emailFull),
- ethereumAddress
- );
-
- console.log("Generated input:", JSON.stringify(input));
- } catch (e) {
- console.log("Error generating input", e);
- setDisplayMessage("Prove");
- setStatus("error-bad-input");
- return;
- }
-
- console.time("zk-gen");
- recordTimeForActivity("startedProving");
- setDisplayMessage(
- "Starting proof generation... (this will take 6-10 minutes and ~5GB RAM)"
- );
- setStatus("generating-proof");
- console.log("Starting proof generation");
- // alert("Generating proof, will fail due to input");
- const { proof, publicSignals } = await generateProof(
- input,
- // @ts-ignore
- import.meta.env.VITE_CIRCUIT_ARTIFACTS_URL,
- CIRCUIT_NAME
- );
- //const proof = JSON.parse('{"pi_a": ["19201501460375869359786976350200749752225831881815567077814357716475109214225", "11505143118120261821370828666956392917988845645366364291926723724764197308214", "1"], "pi_b": [["17114997753466635923095897108905313066875545082621248342234075865495571603410", "7192405994185710518536526038522451195158265656066550519902313122056350381280"], ["13696222194662648890012762427265603087145644894565446235939768763001479304886", "2757027655603295785352548686090997179551660115030413843642436323047552012712"], ["1", "0"]], "pi_c": ["6168386124525054064559735110298802977718009746891233616490776755671099515304", "11077116868070103472532367637450067545191977757024528865783681032080180232316", "1"], "protocol": "groth16", "curve": "bn128"}');
- //const publicSignals = JSON.parse('["0", "0", "0", "0", "0", "0", "0", "0", "32767059066617856", "30803244233155956", "0", "0", "0", "0", "27917065853693287", "28015", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "113659471951225", "0", "0", "1634582323953821262989958727173988295", "1938094444722442142315201757874145583", "375300260153333632727697921604599470", "1369658125109277828425429339149824874", "1589384595547333389911397650751436647", "1428144289938431173655248321840778928", "1919508490085653366961918211405731923", "2358009612379481320362782200045159837", "518833500408858308962881361452944175", "1163210548821508924802510293967109414", "1361351910698751746280135795885107181", "1445969488612593115566934629427756345", "2457340995040159831545380614838948388", "2612807374136932899648418365680887439", "16021263889082005631675788949457422", "299744519975649772895460843780023483", "3933359104846508935112096715593287", "556307310756571904145052207427031380052712977221"]');
- console.log("Finished proof generation");
- console.timeEnd("zk-gen");
- recordTimeForActivity("finishedProving");
-
- console.log("publicSignals", publicSignals);
-
- // alert("Done generating proof");
- setProof(JSON.stringify(proof));
- // let kek = publicSignals.map((x: string) => BigInt(x));
- // let soln = packedNBytesToString(kek.slice(0, 12));
- // let soln2 = packedNBytesToString(kek.slice(12, 147));
- // let soln3 = packedNBytesToString(kek.slice(147, 150));
- // setPublicSignals(`From: ${soln}\nTo: ${soln2}\nUsername: ${soln3}`);
- setPublicSignals(JSON.stringify(publicSignals));
-
- if (!input) {
- setStatus("error-failed-to-prove");
- return;
- }
- setLastAction("sign");
- setDisplayMessage("Finished computing ZK proof");
- setStatus("done");
- try {
- (window as any).cJson = JSON.stringify(input);
- console.log(
- "wrote circuit input to window.cJson. Run copy(cJson)"
- );
- } catch (e) {
- console.error(e);
- }
- }}
- >
- {displayMessage}
-
-
- Generate Proof Remotely{" "}
- {isRemoteProofGenerationLoading || areInputWorkersCreating ? (
-
- ) : (
- ""
)}
-
- {displayMessage ===
- "Downloading compressed proving files... (this may take a few minutes)" && (
-
+
+ {status !== "not-started" ? (
+
+ Status:
+ {status}
+
+ ) : (
+
+ )}
+
+ {/* {status === 'generating-proof' && Elapsed Time: {counter}s } */}
+
+
+
+
)}
-
- {status !== "not-started" ? (
-
- Status:
- {status}
-
- ) : (
-
- )}
-
-
-
-
- Output
- {
- setProof(e.currentTarget.value);
- }}
- warning={verificationMessage}
- warningColor={verificationPassed ? "green" : "red"}
- />
- {
- setPublicSignals(e.currentTarget.value);
- }}
- // warning={
- // }
- />
- {
- try {
- setLastAction("verify");
- let ok = true;
- const res: boolean = await verifyProof(
- JSON.parse(proof),
- JSON.parse(publicSignals),
- // @ts-ignore
- import.meta.env.VITE_CIRCUIT_ARTIFACTS_URL,
- CIRCUIT_NAME
- );
- console.log(res);
- if (!res) throw Error("Verification failed!");
- setVerificationMessage("Passed!");
- setVerificationPassed(ok);
- } catch (er: any) {
- setVerificationMessage("Failed to verify " + er.toString());
- setVerificationPassed(false);
- }
- }}
- >
- Verify
-
- {
- setStatus("sending-on-chain");
- writeContract({
- // @ts-ignore
- address: import.meta.env.VITE_CONTRACT_ADDRESS,
- abi: abi,
- functionName: "mint",
- args: [
- reformatProofForChain(proof),
- publicSignals ? JSON.parse(publicSignals) : [],
- ],
- });
- }}
- >
- {isSuccess
- ? "Successfully sent to chain!"
- : isPending
- ? "Confirm in wallet"
- : false
- ? "Connect Wallet first, scroll to top!"
- : verificationPassed
- ? "Mint Twitter badge on-chain"
- : "Verify first, before minting on-chain!"}
-
- {
- try {
- verifyRemoteProof(entry.id);
- } catch (er: any) {
- setVerificationMessage("Failed to verify " + er.toString());
- setVerificationPassed(false);
- }
- }}
- >
- Verify Remote proof
- {isRemoteProofVerificationLoading ? (
-
- ) : (
- ""
- )}
-
-
- {isSuccess && (
-
+ {/* --------- END OF: GENERATE PROOF USING INPUTS - STEP 3 --------- */}
+
+
+
+ {/* --------- VERIFY & MINT ON CHAIN TWITTER BADGE - STEP 4 --------- */}
+ {activeStep ==4 && (
+
+
+ VERIFY & MINT ON CHAIN TWITTER BADGE
+ Click "Verify" and then "Mint Twitter Badge On-Chain", and approve to mint the NFT badge that proves Twitter ownership! Note that it is 700K gas right now so only feasible on Sepolia, though we intend to reduce this soon.
+
+
+
+
+ Output
+ {verificationMessage && (
+
+ )}
+ {
+ setProof(e.currentTarget.value);
+ }}
+ />
+ {
+ setPublicSignals(e.currentTarget.value);
+ }}
+ />
+ {
+ try {
+ setLastAction("verify");
+ let ok = true;
+ const res: boolean = await verifyProof(
+ JSON.parse(proof),
+ JSON.parse(publicSignals),
+ // @ts-ignore
+ import.meta.env.VITE_CIRCUIT_ARTIFACTS_URL,
+ CIRCUIT_NAME
+ );
+ console.log(res);
+ if (!res) throw Error("Verification failed!");
+ setVerificationMessage("Passed!");
+ setVerificationPassed(ok);
+ } catch (er: any) {
+ setVerificationMessage("Failed to verify " + er.toString());
+ setVerificationPassed(false);
+ }
+ }}
+ >
+ Verify
+
+ {
+ if (isSuccess) {
+ window.open(`https://sepolia.etherscan.io/tx/${data?.hash}`, "_blank");
+ } else {
+ setStatus("sending-on-chain");
+ writeContract({
+ // @ts-ignore
+ address: import.meta.env.VITE_CONTRACT_ADDRESS,
+ abi: abi,
+ functionName: "mint",
+ args: [
+ reformatProofForChain(proof),
+ publicSignals ? JSON.parse(publicSignals) : [],
+ ],
+ });
+ }
+ }}
+ endIcon={isSuccess ? : null}
+ >
+ {isSuccess
+ ? "SUCCESSFULLY SENT ON CHAIN"
+ : isPending
+ ? "Confirm in wallet"
+ : false
+ ? "Connect Wallet first, scroll to top!"
+ : verificationPassed
+ ? "Mint Twitter badge on-chain"
+ : "Verify first, before minting on-chain!"}
+
+
+ {
+ try {
+ verifyRemoteProof(entry.id);
+ } catch (er: any) {
+ setVerificationMessage("Failed to verify " + er.toString());
+ setVerificationPassed(false);
+ }}}
+ >
+ Verify Remote proof
+ {isRemoteProofVerificationLoading ? (
+
+ ) : (
+ ""
+ )}
+
+ {isSuccess && (
+
+ )}
+
+
)}
-
-
-
+ {/* --------- END OF: VERIFY & MINT ON CHAIN TWITTER BADGE - STEP 4 --------- */}
+
+
+
+
+ {/* --------- END OF: LEFT HAND SIDE OF SCREEN --------- */}
+
+
+
+
+
+ {/* --------- RIGHT HAND SIDE OF SCREEN FOR INSTRUCTION VIDEO OR ACCOMPANING GRAPHICS --------- */}
+
+
+
+ {/* --------- END OF: RIGHT SIDE FOR INSTRUCTION VIDEO OR ACCOMPANING GRAPHICS --------- */}
+
+
);
};
+
+
+
+
+
+
const ProcessStatus = styled.div<{ status: string }>`
font-size: 8px;
padding: 8px;
@@ -850,10 +1097,22 @@ const TimerDisplay = ({ timers }: { timers: Record }) => {
);
};
+
+
+
+
+
+
+const CounterDisplay = styled.div`
+ font-size: 12px;
+ font-weight: bold;
+ color: black;
+`;
+
const Header = styled.span`
font-weight: 600;
margin-bottom: 1em;
- color: #fff;
+ color: #000000;
font-size: 2.25rem;
line-height: 2.5rem;
letter-spacing: -0.02em;
@@ -862,77 +1121,34 @@ const Header = styled.span`
const SubHeader = styled(Header)`
font-size: 1.7em;
margin-bottom: 16px;
- color: rgba(255, 255, 255, 0.9);
+ color: "#000000";
`;
-const Main = styled(Row)`
- width: 100%;
- gap: 1rem;
-`;
+
const Column = styled(Col)`
- width: 100%;
+ width: fit;
gap: 1rem;
align-self: flex-start;
- background: rgba(255, 255, 255, 0.1);
- padding: 1rem;
- border-radius: 4px;
- border: 1px solid rgba(255, 255, 255, 0.2);
+ background: #FFFFFC;
+ padding: 2rem;
+ border-radius: 10px;
+ border: 1px solid #C7C7C7;
`;
-const Container = styled.div`
+
+
+const Overlay = styled.div`
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.5);
+ z-index: 1000;
display: flex;
- flex-direction: column;
- margin: 0 auto;
- & .title {
- display: flex;
- flex-direction: column;
- align-items: center;
- }
- & .main {
- & .signaturePane {
- flex: 1;
- display: flex;
- flex-direction: column;
- & > :first-child {
- height: calc(30vh + 24px);
- }
- }
- }
-
- & .bottom {
- display: flex;
- flex-direction: column;
- align-items: center;
- & p {
- text-align: center;
- }
- & .labeledTextAreaContainer {
- align-self: center;
- max-width: 50vw;
- width: 500px;
- }
- }
-
- a {
- color: rgba(30, 144, 255, 0.9); /* Bright blue color */
- text-decoration: none; /* Optional: Removes the underline */
- }
-
- a:hover {
- color: rgba(65, 105, 225, 0.9); /* Darker blue color on hover */
- }
-
- a:visited {
- color: rgba(153, 50, 204, 0.9); /* Purple color for visited links */
- }
-
- a:active {
- color: rgba(
- 255,
- 69,
- 0,
- 0.9
- ); /* Orange-red color for active (clicked) links */
- }
+ justify-content: center;
+ align-items: center;
+ color: white;
+ font-size: 24px;
`;
diff --git a/packages/app/src/styles.css b/packages/app/src/styles.css
index f3dd762..eb43dcc 100644
--- a/packages/app/src/styles.css
+++ b/packages/app/src/styles.css
@@ -4,20 +4,19 @@
body {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
+ font-family: "Space Grotesk", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
+
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
.App {
- font-family: sans-serif;
+ font-family: "Space Grotesk", sans-serif;
text-align: center;
}
@@ -36,20 +35,7 @@ code {
}
}
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
-}
-.App-link {
- color: #61dafb;
-}
@keyframes App-logo-spin {
from {
@@ -61,9 +47,11 @@ code {
}
a {
- color: #a0c1ff;
text-decoration: none;
- text-decoration: underline;
+}
+
+a:hover {
+ opacity: 85%;
}
@@ -89,18 +77,11 @@ textarea {
color: #fff;
}
-body {
+/* body {
padding: 16px;
-}
+} */
+
-h1 {
- font-weight: 300;
- line-height: 1.1;
-}
-html {
- background: #171717 !important;
- color: #fff;
-}
.loader {
border: 2px solid #f3f3f3;
diff --git a/packages/app/src/theme.tsx b/packages/app/src/theme.tsx
new file mode 100644
index 0000000..69462da
--- /dev/null
+++ b/packages/app/src/theme.tsx
@@ -0,0 +1,163 @@
+import { createTheme } from '@mui/material/styles';
+import { Palette, PaletteOptions } from '@mui/material/styles/createPalette';
+
+// Extend the Palette interface to include custom properties
+declare module '@mui/material/styles' {
+ interface Palette {
+ accent: Palette['primary'];
+ active: Palette['primary'];
+ }
+
+ interface PaletteOptions {
+ accent?: PaletteOptions['primary'];
+ active?: PaletteOptions['primary'];
+ }
+}
+
+// Define your Material UI theme
+const theme = createTheme({
+ palette: {
+ primary: {
+ main: '#000000',
+ },
+ secondary: {
+ main: '#8E8E8E',
+ },
+ accent: {
+ main: '#8372E4', // accent color
+ },
+ active: {
+ main: '#abbeff', // active non accent color
+ }
+ },
+
+ typography: {
+ fontFamily: "Space Grotesk",
+ h1: {
+ fontSize: '1.4rem',
+ letterSpacing: -1,
+ fontWeight: '500',
+ '@media (min-width:600px)': {
+ fontSize: '1.5rem',
+ },
+ '@media (min-width:960px)': {
+ fontSize: '1.7rem',
+ },
+ '@media (min-width:1280px)': {
+ fontSize: '2rem',
+ },
+ },
+ h2: {
+ fontSize: '1.75rem',
+ fontWeight: '700',
+ color: '#333741',
+ letterSpacing: -1,
+ '@media (min-width:600px)': {
+ fontSize: '2.5rem',
+ },
+ '@media (min-width:960px)': {
+ fontSize: '3.0rem',
+ },
+ '@media (min-width:1280px)': {
+ fontSize: '3.5rem',
+ },
+ },
+ h4: {
+ color: '#333741',
+ },
+ h5: {
+ color: '#333741'
+ },
+ h6: {
+ color: '#8E8E8E',
+ fontSize: '.7rem',
+ fontWeight: '500',
+ lineHeight: '140%',
+ '@media (min-width:600px)': {
+ fontSize: '0.85rem',
+ },
+ '@media (min-width:960px)': {
+ fontSize: '1rem',
+ },
+ '@media (min-width:1280px)': {
+ fontSize: '1.2rem',
+ },
+ },
+ body1: {
+ fontSize: '0.6rem',
+ fontWeight: '400',
+ lineHeight: '1.5',
+ color: '#333741',
+ '@media (min-width:600px)': {
+ fontSize: '0.8rem',
+ },
+ '@media (min-width:960px)': {
+ fontSize: '0.9rem',
+ },
+ '@media (min-width:1280px)': {
+ fontSize: '1.0rem',
+ },
+ },
+ body2: {
+ fontSize: '0.5rem',
+ fontWeight: '400',
+ lineHeight: '1.5',
+ color: '#333741',
+ '@media (min-width:600px)': {
+ fontSize: '0.85rem',
+ },
+ '@media (min-width:960px)': {
+ fontSize: '0.9rem',
+ },
+ '@media (min-width:1280px)': {
+ fontSize: '1.0rem',
+ },
+ }
+ },
+
+ components: {
+ MuiInputBase: {
+ styleOverrides: {
+ root: {
+ fontFamily: 'Space Grotesk', // Use the same font family as your theme
+ fontSize: '0.6rem', // Customize the font size for text areas
+ lineHeight: '1.5',
+ color: '#333741',
+ '@media (min-width:600px)': {
+ fontSize: '0.85rem',
+ },
+ '@media (min-width:960px)': {
+ fontSize: '0.9rem',
+ },
+ '@media (min-width:1280px)': {
+ fontSize: '1.0rem',
+ },
+ },
+ },
+ },
+
+ MuiTextField: {
+ styleOverrides: {
+ root: {
+ '& textarea': {
+ fontFamily: 'Space Grotesk',
+ fontSize: '0.2rem', // Customize the font size inside the textarea
+ lineHeight: '1.5',
+ color: '#333741',
+ '@media (min-width:600px)': {
+ fontSize: '0.85rem',
+ },
+ '@media (min-width:960px)': {
+ fontSize: '0.9rem',
+ },
+ '@media (min-width:1280px)': {
+ fontSize: '1.0rem',
+ },
+ },
+ },
+ },
+ },
+ },
+});
+
+export default theme;
diff --git a/packages/app/tailwind.config.js b/packages/app/tailwind.config.js
new file mode 100644
index 0000000..25abb8c
--- /dev/null
+++ b/packages/app/tailwind.config.js
@@ -0,0 +1,12 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [],
+ theme: {
+ extend: {},
+ },
+ plugins: {
+ // tailwindcss: {},
+ // autoprefixer: {},
+ },
+}
+
diff --git a/tsconfig.json b/tsconfig.json
index 730267d..3cfeba2 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -21,5 +21,8 @@
"./node_modules",
"./node_modules/*",
"./node_modules/@types/node/index.d.ts",
- ],
+
+
+ "packages/app/tailwind.config.js",
+ ]
}
diff --git a/yarn.lock b/yarn.lock
index 9ab37f8..c9a9d92 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -19,6 +19,13 @@ __metadata:
languageName: node
linkType: hard
+"@alloc/quick-lru@npm:^5.2.0":
+ version: 5.2.0
+ resolution: "@alloc/quick-lru@npm:5.2.0"
+ checksum: bdc35758b552bcf045733ac047fb7f9a07c4678b944c641adfbd41f798b4b91fffd0fdc0df2578d9b0afc7b4d636aa6e110ead5d6281a2adc1ab90efd7f057f8
+ languageName: node
+ linkType: hard
+
"@ampproject/remapping@npm:^2.2.0":
version: 2.3.0
resolution: "@ampproject/remapping@npm:2.3.0"
@@ -168,7 +175,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helper-module-imports@npm:^7.24.7":
+"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.24.7":
version: 7.24.7
resolution: "@babel/helper-module-imports@npm:7.24.7"
dependencies:
@@ -1447,6 +1454,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7":
+ version: 7.25.6
+ resolution: "@babel/runtime@npm:7.25.6"
+ dependencies:
+ regenerator-runtime: ^0.14.0
+ checksum: ee1a69d3ac7802803f5ee6a96e652b78b8addc28c6a38c725a4ad7d61a059d9e6cb9f6550ed2f63cce67a1bd82e0b1ef66a1079d895be6bfb536a5cfbd9ccc32
+ languageName: node
+ linkType: hard
+
"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0, @babel/template@npm:^7.3.3":
version: 7.25.0
resolution: "@babel/template@npm:7.25.0"
@@ -1522,7 +1538,39 @@ __metadata:
languageName: node
linkType: hard
-"@emotion/hash@npm:^0.9.0":
+"@emotion/babel-plugin@npm:^11.12.0":
+ version: 11.12.0
+ resolution: "@emotion/babel-plugin@npm:11.12.0"
+ dependencies:
+ "@babel/helper-module-imports": ^7.16.7
+ "@babel/runtime": ^7.18.3
+ "@emotion/hash": ^0.9.2
+ "@emotion/memoize": ^0.9.0
+ "@emotion/serialize": ^1.2.0
+ babel-plugin-macros: ^3.1.0
+ convert-source-map: ^1.5.0
+ escape-string-regexp: ^4.0.0
+ find-root: ^1.1.0
+ source-map: ^0.5.7
+ stylis: 4.2.0
+ checksum: b5d4b3dfe97e6763794a42b5c3a027a560caa1aa6dcaf05c18e5969691368dd08245c077bad7397dcc720b53d29caeaaec1888121e68cfd9ab02ff52f6fef662
+ languageName: node
+ linkType: hard
+
+"@emotion/cache@npm:^11.13.0, @emotion/cache@npm:^11.13.1":
+ version: 11.13.1
+ resolution: "@emotion/cache@npm:11.13.1"
+ dependencies:
+ "@emotion/memoize": ^0.9.0
+ "@emotion/sheet": ^1.4.0
+ "@emotion/utils": ^1.4.0
+ "@emotion/weak-memoize": ^0.4.0
+ stylis: 4.2.0
+ checksum: 94b161786a03a08a1e30257478fad9a9be1ac8585ddca0c6410d7411fd474fc8b0d6d1167d7d15bdb012d1fd8a1220ac2bbc79501ad9b292b83c17da0874d7de
+ languageName: node
+ linkType: hard
+
+"@emotion/hash@npm:^0.9.0, @emotion/hash@npm:^0.9.2":
version: 0.9.2
resolution: "@emotion/hash@npm:0.9.2"
checksum: 379bde2830ccb0328c2617ec009642321c0e009a46aa383dfbe75b679c6aea977ca698c832d225a893901f29d7b3eef0e38cf341f560f6b2b56f1ff23c172387
@@ -1538,6 +1586,15 @@ __metadata:
languageName: node
linkType: hard
+"@emotion/is-prop-valid@npm:^1.3.0":
+ version: 1.3.0
+ resolution: "@emotion/is-prop-valid@npm:1.3.0"
+ dependencies:
+ "@emotion/memoize": ^0.9.0
+ checksum: d3e36e493de3b4446634010c46cb8b99fa8ca271a8e7efba9cecf59a672ce1ebcfea8e8c7a0627dcafae87b4ab0d58c70fcf4589b849ca48e0d1e9f6c899e8be
+ languageName: node
+ linkType: hard
+
"@emotion/memoize@npm:^0.8.1":
version: 0.8.1
resolution: "@emotion/memoize@npm:0.8.1"
@@ -1545,6 +1602,74 @@ __metadata:
languageName: node
linkType: hard
+"@emotion/memoize@npm:^0.9.0":
+ version: 0.9.0
+ resolution: "@emotion/memoize@npm:0.9.0"
+ checksum: 038132359397348e378c593a773b1148cd0cf0a2285ffd067a0f63447b945f5278860d9de718f906a74c7c940ba1783ac2ca18f1c06a307b01cc0e3944e783b1
+ languageName: node
+ linkType: hard
+
+"@emotion/react@npm:^11.13.3":
+ version: 11.13.3
+ resolution: "@emotion/react@npm:11.13.3"
+ dependencies:
+ "@babel/runtime": ^7.18.3
+ "@emotion/babel-plugin": ^11.12.0
+ "@emotion/cache": ^11.13.0
+ "@emotion/serialize": ^1.3.1
+ "@emotion/use-insertion-effect-with-fallbacks": ^1.1.0
+ "@emotion/utils": ^1.4.0
+ "@emotion/weak-memoize": ^0.4.0
+ hoist-non-react-statics: ^3.3.1
+ peerDependencies:
+ react: ">=16.8.0"
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 0b58374bf28de914b49881f0060acfb908989869ebab63a2287773fc5e91a39f15552632b03d376c3e9835c5b4f23a5ebac8b0963b29af164d46c0a77ac928f0
+ languageName: node
+ linkType: hard
+
+"@emotion/serialize@npm:^1.2.0, @emotion/serialize@npm:^1.3.0, @emotion/serialize@npm:^1.3.1":
+ version: 1.3.1
+ resolution: "@emotion/serialize@npm:1.3.1"
+ dependencies:
+ "@emotion/hash": ^0.9.2
+ "@emotion/memoize": ^0.9.0
+ "@emotion/unitless": ^0.10.0
+ "@emotion/utils": ^1.4.0
+ csstype: ^3.0.2
+ checksum: 9a488b1ef8b1609a0a80a957c2e9387703c148bb6444e0b097957cfca5c501191e870d11bae32d73ffeb5fd653961b8dbbd1c2c7e371b062029c0ed31d34162e
+ languageName: node
+ linkType: hard
+
+"@emotion/sheet@npm:^1.4.0":
+ version: 1.4.0
+ resolution: "@emotion/sheet@npm:1.4.0"
+ checksum: eeb1212e3289db8e083e72e7e401cd6d1a84deece87e9ce184f7b96b9b5dbd6f070a89057255a6ff14d9865c3ce31f27c39248a053e4cdd875540359042586b4
+ languageName: node
+ linkType: hard
+
+"@emotion/styled@npm:^11.13.0":
+ version: 11.13.0
+ resolution: "@emotion/styled@npm:11.13.0"
+ dependencies:
+ "@babel/runtime": ^7.18.3
+ "@emotion/babel-plugin": ^11.12.0
+ "@emotion/is-prop-valid": ^1.3.0
+ "@emotion/serialize": ^1.3.0
+ "@emotion/use-insertion-effect-with-fallbacks": ^1.1.0
+ "@emotion/utils": ^1.4.0
+ peerDependencies:
+ "@emotion/react": ^11.0.0-rc.0
+ react: ">=16.8.0"
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: f5b951059418f57bc8ea32b238afb25965ece3314f2ffd1b14ce049ba3c066a424990dfbfabbf57bb88e044eaa80bf19f620ac988adda3d2fc483177be6da05e
+ languageName: node
+ linkType: hard
+
"@emotion/unitless@npm:0.8.1":
version: 0.8.1
resolution: "@emotion/unitless@npm:0.8.1"
@@ -1552,6 +1677,36 @@ __metadata:
languageName: node
linkType: hard
+"@emotion/unitless@npm:^0.10.0":
+ version: 0.10.0
+ resolution: "@emotion/unitless@npm:0.10.0"
+ checksum: d79346df31a933e6d33518e92636afeb603ce043f3857d0a39a2ac78a09ef0be8bedff40130930cb25df1beeee12d96ee38613963886fa377c681a89970b787c
+ languageName: node
+ linkType: hard
+
+"@emotion/use-insertion-effect-with-fallbacks@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.1.0"
+ peerDependencies:
+ react: ">=16.8.0"
+ checksum: 63665191773b27de66807c53b90091ef0d10d5161381f62726cfceecfe1d8c944f18594b8021805fc81575b64246fd5ab9c75d60efabec92f940c1c410530949
+ languageName: node
+ linkType: hard
+
+"@emotion/utils@npm:^1.4.0":
+ version: 1.4.0
+ resolution: "@emotion/utils@npm:1.4.0"
+ checksum: 212af0b0d6bcaa63c76e1a36e35bee4d3579359316c03bf970faabb5427a4c0aab3e2346a721bac54f0c8e027958e759c5682be78f308755a1d9753e83963621
+ languageName: node
+ linkType: hard
+
+"@emotion/weak-memoize@npm:^0.4.0":
+ version: 0.4.0
+ resolution: "@emotion/weak-memoize@npm:0.4.0"
+ checksum: db5da0e89bd752c78b6bd65a1e56231f0abebe2f71c0bd8fc47dff96408f7065b02e214080f99924f6a3bfe7ee15afc48dad999d76df86b39b16e513f7a94f52
+ languageName: node
+ linkType: hard
+
"@esbuild-plugins/node-globals-polyfill@npm:^0.2.3":
version: 0.2.3
resolution: "@esbuild-plugins/node-globals-polyfill@npm:0.2.3"
@@ -2495,7 +2650,7 @@ __metadata:
languageName: node
linkType: hard
-"@jridgewell/gen-mapping@npm:^0.3.5":
+"@jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5":
version: 0.3.5
resolution: "@jridgewell/gen-mapping@npm:0.3.5"
dependencies:
@@ -2878,6 +3033,163 @@ __metadata:
languageName: node
linkType: hard
+"@mui/core-downloads-tracker@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "@mui/core-downloads-tracker@npm:6.0.1"
+ checksum: 78e1097939df51998df551367b42fea2011d577947fe12a8c7813aced006cebc6d13199f0894e3cfdcd6351e37c739e815a9c4218d1774d189adf825caa5b2b9
+ languageName: node
+ linkType: hard
+
+"@mui/icons-material@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "@mui/icons-material@npm:6.0.1"
+ dependencies:
+ "@babel/runtime": ^7.25.0
+ peerDependencies:
+ "@mui/material": ^6.0.1
+ "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 53eaeb13789d98ba74d8d3537c74bde4de5189d10db4faed98d88540d57b0261c99d0de72c2ddf280bd7a1405a946302e59c3ffcd950c74b9020e717a6b4d2a3
+ languageName: node
+ linkType: hard
+
+"@mui/material@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "@mui/material@npm:6.0.1"
+ dependencies:
+ "@babel/runtime": ^7.25.0
+ "@mui/core-downloads-tracker": ^6.0.1
+ "@mui/system": ^6.0.1
+ "@mui/types": ^7.2.16
+ "@mui/utils": ^6.0.1
+ "@popperjs/core": ^2.11.8
+ "@types/react-transition-group": ^4.4.11
+ clsx: ^2.1.1
+ csstype: ^3.1.3
+ prop-types: ^15.8.1
+ react-is: ^18.3.1
+ react-transition-group: ^4.4.5
+ peerDependencies:
+ "@emotion/react": ^11.5.0
+ "@emotion/styled": ^11.3.0
+ "@mui/material-pigment-css": ^6.0.1
+ "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ "@emotion/react":
+ optional: true
+ "@emotion/styled":
+ optional: true
+ "@mui/material-pigment-css":
+ optional: true
+ "@types/react":
+ optional: true
+ checksum: d9da009c242c81a0fe2fd2ef9d583d0d887bc69f5e17846009855fc54802141b6374441ef020d064859e65f0754bd3ce2f04400f9513f21106bda0a05c5d1fea
+ languageName: node
+ linkType: hard
+
+"@mui/private-theming@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "@mui/private-theming@npm:6.0.1"
+ dependencies:
+ "@babel/runtime": ^7.25.0
+ "@mui/utils": ^6.0.1
+ prop-types: ^15.8.1
+ peerDependencies:
+ "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 03729ae7f4a4787d62e2b7bac62aa08f859d51fc22f9682862b42f3bda4027e7d49e0b668e91f2c2a95a381acfb0497a864cb829e750648f2c15c14552138d5e
+ languageName: node
+ linkType: hard
+
+"@mui/styled-engine@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "@mui/styled-engine@npm:6.0.1"
+ dependencies:
+ "@babel/runtime": ^7.25.0
+ "@emotion/cache": ^11.13.1
+ csstype: ^3.1.3
+ prop-types: ^15.8.1
+ peerDependencies:
+ "@emotion/react": ^11.4.1
+ "@emotion/styled": ^11.3.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ "@emotion/react":
+ optional: true
+ "@emotion/styled":
+ optional: true
+ checksum: 9a3fdb599607e397ef9677b011cb43b6bd6a8ebaaf3bb1563804d26c7a858b05bbde71d222de2bd91649b025f819f7efb8e8f014e459efb74d95697fbb9a83b3
+ languageName: node
+ linkType: hard
+
+"@mui/system@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "@mui/system@npm:6.0.1"
+ dependencies:
+ "@babel/runtime": ^7.25.0
+ "@mui/private-theming": ^6.0.1
+ "@mui/styled-engine": ^6.0.1
+ "@mui/types": ^7.2.16
+ "@mui/utils": ^6.0.1
+ clsx: ^2.1.1
+ csstype: ^3.1.3
+ prop-types: ^15.8.1
+ peerDependencies:
+ "@emotion/react": ^11.5.0
+ "@emotion/styled": ^11.3.0
+ "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ "@emotion/react":
+ optional: true
+ "@emotion/styled":
+ optional: true
+ "@types/react":
+ optional: true
+ checksum: a586220e68a2d3e9d5eefc2bd3bb3c12154be44e5e8696f9cdfe64136ff22b679a9437aa90b31f7a04a5ddc4501a870fd0eaf9a29620849d67e18c4ced6d4e78
+ languageName: node
+ linkType: hard
+
+"@mui/types@npm:^7.2.16":
+ version: 7.2.16
+ resolution: "@mui/types@npm:7.2.16"
+ peerDependencies:
+ "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 7bb86487be8e55a4e138a6a5878ab272caee71546a7a2368223274afae65229f673334e59b8e3f7717ea7ea8d44af5f068b2eb4c212cddb98fefecfa873b868a
+ languageName: node
+ linkType: hard
+
+"@mui/utils@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "@mui/utils@npm:6.0.1"
+ dependencies:
+ "@babel/runtime": ^7.25.0
+ "@mui/types": ^7.2.16
+ "@types/prop-types": ^15.7.12
+ clsx: ^2.1.1
+ prop-types: ^15.8.1
+ react-is: ^18.3.1
+ peerDependencies:
+ "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: b1c2659210df48fc7980b0d88ff0581a0e0fe7987edb2bfca0663d818fdb2514d0a45789d8c623b16ad934b535c2bfbdce3d3dd7595bb50efd52902ccc4f07bb
+ languageName: node
+ linkType: hard
+
"@noble/curves@npm:1.4.0":
version: 1.4.0
resolution: "@noble/curves@npm:1.4.0"
@@ -3120,6 +3432,13 @@ __metadata:
languageName: node
linkType: hard
+"@popperjs/core@npm:^2.11.8":
+ version: 2.11.8
+ resolution: "@popperjs/core@npm:2.11.8"
+ checksum: e5c69fdebf52a4012f6a1f14817ca8e9599cb1be73dd1387e1785e2ed5e5f0862ff817f420a87c7fc532add1f88a12e25aeb010ffcbdc98eace3d55ce2139cf0
+ languageName: node
+ linkType: hard
+
"@proof-of-twitter/circuits@workspace:^, @proof-of-twitter/circuits@workspace:packages/circuits":
version: 0.0.0-use.local
resolution: "@proof-of-twitter/circuits@workspace:packages/circuits"
@@ -3885,7 +4204,14 @@ __metadata:
languageName: node
linkType: hard
-"@types/prop-types@npm:*":
+"@types/parse-json@npm:^4.0.0":
+ version: 4.0.2
+ resolution: "@types/parse-json@npm:4.0.2"
+ checksum: 5bf62eec37c332ad10059252fc0dab7e7da730764869c980b0714777ad3d065e490627be9f40fc52f238ffa3ac4199b19de4127196910576c2fe34dd47c7a470
+ languageName: node
+ linkType: hard
+
+"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.12":
version: 15.7.12
resolution: "@types/prop-types@npm:15.7.12"
checksum: ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe
@@ -3901,6 +4227,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/react-transition-group@npm:^4.4.11":
+ version: 4.4.11
+ resolution: "@types/react-transition-group@npm:4.4.11"
+ dependencies:
+ "@types/react": "*"
+ checksum: a6e3b2e4363cb019e256ae4f19dadf9d7eb199da1a5e4109bbbf6a132821884044d332e9c74b520b1e5321a7f545502443fd1ce0b18649c8b510fa4220b0e5c2
+ languageName: node
+ linkType: hard
+
"@types/react@npm:*":
version: 18.3.4
resolution: "@types/react@npm:18.3.4"
@@ -4559,8 +4894,12 @@ __metadata:
resolution: "@zk-email/twitter-verifier-app@workspace:packages/app"
dependencies:
"@babel/preset-react": ^7.23.3
+ "@emotion/react": ^11.13.3
+ "@emotion/styled": ^11.13.0
"@esbuild-plugins/node-globals-polyfill": ^0.2.3
"@esbuild-plugins/node-modules-polyfill": ^0.2.2
+ "@mui/icons-material": ^6.0.1
+ "@mui/material": ^6.0.1
"@proof-of-twitter/circuits": "workspace:^"
"@proof-of-twitter/contracts": "workspace:^"
"@rainbow-me/rainbowkit": ^2.1.4
@@ -4808,7 +5147,7 @@ __metadata:
languageName: node
linkType: hard
-"any-promise@npm:^1.1.0":
+"any-promise@npm:^1.0.0, any-promise@npm:^1.1.0":
version: 1.3.0
resolution: "any-promise@npm:1.3.0"
checksum: 0ee8a9bdbe882c90464d75d1f55cf027f5458650c4bd1f0467e65aec38ccccda07ca5844969ee77ed46d04e7dded3eaceb027e8d32f385688523fe305fa7e1de
@@ -4832,6 +5171,13 @@ __metadata:
languageName: node
linkType: hard
+"arg@npm:^5.0.2":
+ version: 5.0.2
+ resolution: "arg@npm:5.0.2"
+ checksum: 6c69ada1a9943d332d9e5382393e897c500908d91d5cb735a01120d5f71daf1b339b7b8980cbeaba8fd1afc68e658a739746179e4315a26e8a28951ff9930078
+ languageName: node
+ linkType: hard
+
"argparse@npm:^1.0.7":
version: 1.0.10
resolution: "argparse@npm:1.0.10"
@@ -4977,6 +5323,24 @@ __metadata:
languageName: node
linkType: hard
+"autoprefixer@npm:^10.4.20":
+ version: 10.4.20
+ resolution: "autoprefixer@npm:10.4.20"
+ dependencies:
+ browserslist: ^4.23.3
+ caniuse-lite: ^1.0.30001646
+ fraction.js: ^4.3.7
+ normalize-range: ^0.1.2
+ picocolors: ^1.0.1
+ postcss-value-parser: ^4.2.0
+ peerDependencies:
+ postcss: ^8.1.0
+ bin:
+ autoprefixer: bin/autoprefixer
+ checksum: 187cec2ec356631932b212f76dc64f4419c117fdb2fb9eeeb40867d38ba5ca5ba734e6ceefc9e3af4eec8258e60accdf5cbf2b7708798598fde35cdc3de562d6
+ languageName: node
+ linkType: hard
+
"available-typed-arrays@npm:^1.0.7":
version: 1.0.7
resolution: "available-typed-arrays@npm:1.0.7"
@@ -5046,6 +5410,17 @@ __metadata:
languageName: node
linkType: hard
+"babel-plugin-macros@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "babel-plugin-macros@npm:3.1.0"
+ dependencies:
+ "@babel/runtime": ^7.12.5
+ cosmiconfig: ^7.0.0
+ resolve: ^1.19.0
+ checksum: 765de4abebd3e4688ebdfbff8571ddc8cd8061f839bb6c3e550b0344a4027b04c60491f843296ce3f3379fb356cc873d57a9ee6694262547eb822c14a25be9a6
+ languageName: node
+ linkType: hard
+
"babel-plugin-polyfill-corejs2@npm:^0.4.10":
version: 0.4.11
resolution: "babel-plugin-polyfill-corejs2@npm:0.4.11"
@@ -5480,6 +5855,13 @@ __metadata:
languageName: node
linkType: hard
+"camelcase-css@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "camelcase-css@npm:2.0.1"
+ checksum: 1cec2b3b3dcb5026688a470b00299a8db7d904c4802845c353dbd12d9d248d3346949a814d83bfd988d4d2e5b9904c07efe76fecd195a1d4f05b543e7c0b56b1
+ languageName: node
+ linkType: hard
+
"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1":
version: 5.3.1
resolution: "camelcase@npm:5.3.1"
@@ -5848,6 +6230,13 @@ __metadata:
languageName: node
linkType: hard
+"clsx@npm:^2.1.1":
+ version: 2.1.1
+ resolution: "clsx@npm:2.1.1"
+ checksum: acd3e1ab9d8a433ecb3cc2f6a05ab95fe50b4a3cfc5ba47abb6cbf3754585fcb87b84e90c822a1f256c4198e3b41c7f6c391577ffc8678ad587fc0976b24fd57
+ languageName: node
+ linkType: hard
+
"co@npm:^4.6.0":
version: 4.6.0
resolution: "co@npm:4.6.0"
@@ -5917,6 +6306,13 @@ __metadata:
languageName: node
linkType: hard
+"commander@npm:^4.0.0":
+ version: 4.1.1
+ resolution: "commander@npm:4.1.1"
+ checksum: d7b9913ff92cae20cb577a4ac6fcc121bd6223319e54a40f51a14740a681ad5c574fd29a57da478a5f234a6fa6c52cbf0b7c641353e03c648b1ae85ba670b977
+ languageName: node
+ linkType: hard
+
"commander@npm:^5.1.0":
version: 5.1.0
resolution: "commander@npm:5.1.0"
@@ -5966,6 +6362,13 @@ __metadata:
languageName: node
linkType: hard
+"convert-source-map@npm:^1.5.0":
+ version: 1.9.0
+ resolution: "convert-source-map@npm:1.9.0"
+ checksum: dc55a1f28ddd0e9485ef13565f8f756b342f9a46c4ae18b843fe3c30c675d058d6a4823eff86d472f187b176f0adf51ea7b69ea38be34be4a63cbbf91b0593c8
+ languageName: node
+ linkType: hard
+
"convert-source-map@npm:^2.0.0":
version: 2.0.0
resolution: "convert-source-map@npm:2.0.0"
@@ -6022,6 +6425,19 @@ __metadata:
languageName: node
linkType: hard
+"cosmiconfig@npm:^7.0.0":
+ version: 7.1.0
+ resolution: "cosmiconfig@npm:7.1.0"
+ dependencies:
+ "@types/parse-json": ^4.0.0
+ import-fresh: ^3.2.1
+ parse-json: ^5.0.0
+ path-type: ^4.0.0
+ yaml: ^1.10.0
+ checksum: c53bf7befc1591b2651a22414a5e786cd5f2eeaa87f3678a3d49d6069835a9d8d1aef223728e98aa8fec9a95bf831120d245096db12abe019fecb51f5696c96f
+ languageName: node
+ linkType: hard
+
"crc-32@npm:^1.2.0":
version: 1.2.2
resolution: "crc-32@npm:1.2.2"
@@ -6237,7 +6653,7 @@ __metadata:
languageName: node
linkType: hard
-"csstype@npm:3.1.3, csstype@npm:^3.0.2, csstype@npm:^3.0.7, csstype@npm:^3.1.2":
+"csstype@npm:3.1.3, csstype@npm:^3.0.2, csstype@npm:^3.0.7, csstype@npm:^3.1.2, csstype@npm:^3.1.3":
version: 3.1.3
resolution: "csstype@npm:3.1.3"
checksum: 8db785cc92d259102725b3c694ec0c823f5619a84741b5c7991b8ad135dfaa66093038a1cc63e03361a6cd28d122be48f2106ae72334e067dd619a51f49eddf7
@@ -6739,6 +7155,13 @@ __metadata:
languageName: node
linkType: hard
+"didyoumean@npm:^1.2.2":
+ version: 1.2.2
+ resolution: "didyoumean@npm:1.2.2"
+ checksum: d5d98719d58b3c2fa59663c4c42ba9716f1fd01245c31d5fce31915bd3aa26e6aac149788e007358f778ebbd68a2256eb5973e8ca6f221df221ba060115acf2e
+ languageName: node
+ linkType: hard
+
"diff-sequences@npm:^29.6.3":
version: 29.6.3
resolution: "diff-sequences@npm:29.6.3"
@@ -6780,6 +7203,13 @@ __metadata:
languageName: node
linkType: hard
+"dlv@npm:^1.1.3":
+ version: 1.1.3
+ resolution: "dlv@npm:1.1.3"
+ checksum: d7381bca22ed11933a1ccf376db7a94bee2c57aa61e490f680124fa2d1cd27e94eba641d9f45be57caab4f9a6579de0983466f620a2cd6230d7ec93312105ae7
+ languageName: node
+ linkType: hard
+
"dom-accessibility-api@npm:^0.5.6, dom-accessibility-api@npm:^0.5.9":
version: 0.5.16
resolution: "dom-accessibility-api@npm:0.5.16"
@@ -6787,6 +7217,16 @@ __metadata:
languageName: node
linkType: hard
+"dom-helpers@npm:^5.0.1":
+ version: 5.2.1
+ resolution: "dom-helpers@npm:5.2.1"
+ dependencies:
+ "@babel/runtime": ^7.8.7
+ csstype: ^3.0.2
+ checksum: 863ba9e086f7093df3376b43e74ce4422571d404fc9828bf2c56140963d5edf0e56160f9b2f3bb61b282c07f8fc8134f023c98fd684bddcb12daf7b0f14d951c
+ languageName: node
+ linkType: hard
+
"domexception@npm:^4.0.0":
version: 4.0.0
resolution: "domexception@npm:4.0.0"
@@ -7502,7 +7942,7 @@ __metadata:
languageName: node
linkType: hard
-"fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.9":
+"fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0":
version: 3.3.2
resolution: "fast-glob@npm:3.3.2"
dependencies:
@@ -7723,6 +8163,13 @@ __metadata:
languageName: node
linkType: hard
+"find-root@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "find-root@npm:1.1.0"
+ checksum: b2a59fe4b6c932eef36c45a048ae8f93c85640212ebe8363164814990ee20f154197505965f3f4f102efc33bfb1cbc26fd17c4a2fc739ebc51b886b137cbefaf
+ languageName: node
+ linkType: hard
+
"find-up@npm:^4.0.0, find-up@npm:^4.1.0":
version: 4.1.0
resolution: "find-up@npm:4.1.0"
@@ -7836,6 +8283,13 @@ __metadata:
languageName: node
linkType: hard
+"fraction.js@npm:^4.3.7":
+ version: 4.3.7
+ resolution: "fraction.js@npm:4.3.7"
+ checksum: e1553ae3f08e3ba0e8c06e43a3ab20b319966dfb7ddb96fd9b5d0ee11a66571af7f993229c88ebbb0d4a816eb813a24ed48207b140d442a8f76f33763b8d1f3f
+ languageName: node
+ linkType: hard
+
"fs-constants@npm:^1.0.0":
version: 1.0.0
resolution: "fs-constants@npm:1.0.0"
@@ -8052,6 +8506,15 @@ __metadata:
languageName: node
linkType: hard
+"glob-parent@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "glob-parent@npm:6.0.2"
+ dependencies:
+ is-glob: ^4.0.3
+ checksum: c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8
+ languageName: node
+ linkType: hard
+
"glob@npm:^10.2.2, glob@npm:^10.3.10":
version: 10.4.5
resolution: "glob@npm:10.4.5"
@@ -8310,7 +8773,7 @@ __metadata:
languageName: node
linkType: hard
-"hoist-non-react-statics@npm:^3.3.0":
+"hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1":
version: 3.3.2
resolution: "hoist-non-react-statics@npm:3.3.2"
dependencies:
@@ -8482,7 +8945,7 @@ __metadata:
languageName: node
linkType: hard
-"import-fresh@npm:^3.3.0":
+"import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0":
version: 3.3.0
resolution: "import-fresh@npm:3.3.0"
dependencies:
@@ -9983,6 +10446,20 @@ __metadata:
languageName: node
linkType: hard
+"lilconfig@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "lilconfig@npm:2.1.0"
+ checksum: 8549bb352b8192375fed4a74694cd61ad293904eee33f9d4866c2192865c44c4eb35d10782966242634e0cbc1e91fe62b1247f148dc5514918e3a966da7ea117
+ languageName: node
+ linkType: hard
+
+"lilconfig@npm:^3.0.0":
+ version: 3.1.2
+ resolution: "lilconfig@npm:3.1.2"
+ checksum: 4e8b83ddd1d0ad722600994e6ba5d858ddca14f0587aa6b9c8185e17548149b5e13d4d583d811e9e9323157fa8c6a527e827739794c7502b59243c58e210b8c3
+ languageName: node
+ linkType: hard
+
"lines-and-columns@npm:^1.1.6":
version: 1.2.4
resolution: "lines-and-columns@npm:1.2.4"
@@ -10115,7 +10592,7 @@ __metadata:
languageName: node
linkType: hard
-"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0":
+"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
dependencies:
@@ -10695,6 +11172,17 @@ __metadata:
languageName: node
linkType: hard
+"mz@npm:^2.7.0":
+ version: 2.7.0
+ resolution: "mz@npm:2.7.0"
+ dependencies:
+ any-promise: ^1.0.0
+ object-assign: ^4.0.1
+ thenify-all: ^1.0.0
+ checksum: 8427de0ece99a07e9faed3c0c6778820d7543e3776f9a84d22cf0ec0a8eb65f6e9aee9c9d353ff9a105ff62d33a9463c6ca638974cc652ee8140cd1e35951c87
+ languageName: node
+ linkType: hard
+
"nano-css@npm:^5.6.2":
version: 5.6.2
resolution: "nano-css@npm:5.6.2"
@@ -10917,6 +11405,13 @@ __metadata:
languageName: node
linkType: hard
+"normalize-range@npm:^0.1.2":
+ version: 0.1.2
+ resolution: "normalize-range@npm:0.1.2"
+ checksum: 9b2f14f093593f367a7a0834267c24f3cb3e887a2d9809c77d8a7e5fd08738bcd15af46f0ab01cc3a3d660386f015816b5c922cea8bf2ee79777f40874063184
+ languageName: node
+ linkType: hard
+
"npm-run-path@npm:^4.0.1":
version: 4.0.1
resolution: "npm-run-path@npm:4.0.1"
@@ -10953,6 +11448,20 @@ __metadata:
languageName: node
linkType: hard
+"object-assign@npm:^4.0.1, object-assign@npm:^4.1.1":
+ version: 4.1.1
+ resolution: "object-assign@npm:4.1.1"
+ checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f
+ languageName: node
+ linkType: hard
+
+"object-hash@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "object-hash@npm:3.0.0"
+ checksum: 80b4904bb3857c52cc1bfd0b52c0352532ca12ed3b8a6ff06a90cd209dfda1b95cee059a7625eb9da29537027f68ac4619363491eedb2f5d3dddbba97494fd6c
+ languageName: node
+ linkType: hard
+
"object-inspect@npm:^1.13.1":
version: 1.13.2
resolution: "object-inspect@npm:1.13.2"
@@ -11219,7 +11728,7 @@ __metadata:
languageName: node
linkType: hard
-"parse-json@npm:^5.2.0":
+"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0":
version: 5.2.0
resolution: "parse-json@npm:5.2.0"
dependencies:
@@ -11354,6 +11863,13 @@ __metadata:
languageName: node
linkType: hard
+"pify@npm:^2.3.0":
+ version: 2.3.0
+ resolution: "pify@npm:2.3.0"
+ checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba
+ languageName: node
+ linkType: hard
+
"pify@npm:^3.0.0":
version: 3.0.0
resolution: "pify@npm:3.0.0"
@@ -11406,7 +11922,7 @@ __metadata:
languageName: node
linkType: hard
-"pirates@npm:^4.0.4":
+"pirates@npm:^4.0.1, pirates@npm:^4.0.4":
version: 4.0.6
resolution: "pirates@npm:4.0.6"
checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6
@@ -11461,7 +11977,70 @@ __metadata:
languageName: node
linkType: hard
-"postcss-value-parser@npm:^4.0.2":
+"postcss-import@npm:^15.1.0":
+ version: 15.1.0
+ resolution: "postcss-import@npm:15.1.0"
+ dependencies:
+ postcss-value-parser: ^4.0.0
+ read-cache: ^1.0.0
+ resolve: ^1.1.7
+ peerDependencies:
+ postcss: ^8.0.0
+ checksum: 7bd04bd8f0235429009d0022cbf00faebc885de1d017f6d12ccb1b021265882efc9302006ba700af6cab24c46bfa2f3bc590be3f9aee89d064944f171b04e2a3
+ languageName: node
+ linkType: hard
+
+"postcss-js@npm:^4.0.1":
+ version: 4.0.1
+ resolution: "postcss-js@npm:4.0.1"
+ dependencies:
+ camelcase-css: ^2.0.1
+ peerDependencies:
+ postcss: ^8.4.21
+ checksum: 5c1e83efeabeb5a42676193f4357aa9c88f4dc1b3c4a0332c132fe88932b33ea58848186db117cf473049fc233a980356f67db490bd0a7832ccba9d0b3fd3491
+ languageName: node
+ linkType: hard
+
+"postcss-load-config@npm:^4.0.1":
+ version: 4.0.2
+ resolution: "postcss-load-config@npm:4.0.2"
+ dependencies:
+ lilconfig: ^3.0.0
+ yaml: ^2.3.4
+ peerDependencies:
+ postcss: ">=8.0.9"
+ ts-node: ">=9.0.0"
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+ checksum: 7c27dd3801db4eae207a5116fed2db6b1ebb780b40c3dd62a3e57e087093a8e6a14ee17ada729fee903152d6ef4826c6339eb135bee6208e0f3140d7e8090185
+ languageName: node
+ linkType: hard
+
+"postcss-nested@npm:^6.0.1":
+ version: 6.2.0
+ resolution: "postcss-nested@npm:6.2.0"
+ dependencies:
+ postcss-selector-parser: ^6.1.1
+ peerDependencies:
+ postcss: ^8.2.14
+ checksum: 2c86ecf2d0ce68f27c87c7e24ae22dc6dd5515a89fcaf372b2627906e11f5c1f36e4a09e4c15c20fd4a23d628b3d945c35839f44496fbee9a25866258006671b
+ languageName: node
+ linkType: hard
+
+"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.1.1":
+ version: 6.1.2
+ resolution: "postcss-selector-parser@npm:6.1.2"
+ dependencies:
+ cssesc: ^3.0.0
+ util-deprecate: ^1.0.2
+ checksum: ce9440fc42a5419d103f4c7c1847cb75488f3ac9cbe81093b408ee9701193a509f664b4d10a2b4d82c694ee7495e022f8f482d254f92b7ffd9ed9dea696c6f84
+ languageName: node
+ linkType: hard
+
+"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.0.2, postcss-value-parser@npm:^4.2.0":
version: 4.2.0
resolution: "postcss-value-parser@npm:4.2.0"
checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f
@@ -11666,6 +12245,17 @@ __metadata:
languageName: node
linkType: hard
+"prop-types@npm:^15.6.2, prop-types@npm:^15.8.1":
+ version: 15.8.1
+ resolution: "prop-types@npm:15.8.1"
+ dependencies:
+ loose-envify: ^1.4.0
+ object-assign: ^4.1.1
+ react-is: ^16.13.1
+ checksum: c056d3f1c057cb7ff8344c645450e14f088a915d078dcda795041765047fa080d38e5d626560ccaac94a4e16e3aa15f3557c1a9a8d1174530955e992c675e459
+ languageName: node
+ linkType: hard
+
"proxy-agent@npm:6.3.1":
version: 6.3.1
resolution: "proxy-agent@npm:6.3.1"
@@ -11961,7 +12551,7 @@ __metadata:
languageName: node
linkType: hard
-"react-is@npm:^16.7.0":
+"react-is@npm:^16.13.1, react-is@npm:^16.7.0":
version: 16.13.1
resolution: "react-is@npm:16.13.1"
checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f
@@ -11975,7 +12565,7 @@ __metadata:
languageName: node
linkType: hard
-"react-is@npm:^18.0.0, react-is@npm:^18.2.0":
+"react-is@npm:^18.0.0, react-is@npm:^18.2.0, react-is@npm:^18.3.1":
version: 18.3.1
resolution: "react-is@npm:18.3.1"
checksum: e20fe84c86ff172fc8d898251b7cc2c43645d108bf96d0b8edf39b98f9a2cae97b40520ee7ed8ee0085ccc94736c4886294456033304151c3f94978cec03df21
@@ -12078,6 +12668,21 @@ __metadata:
languageName: node
linkType: hard
+"react-transition-group@npm:^4.4.5":
+ version: 4.4.5
+ resolution: "react-transition-group@npm:4.4.5"
+ dependencies:
+ "@babel/runtime": ^7.5.5
+ dom-helpers: ^5.0.1
+ loose-envify: ^1.4.0
+ prop-types: ^15.6.2
+ peerDependencies:
+ react: ">=16.6.0"
+ react-dom: ">=16.6.0"
+ checksum: 75602840106aa9c6545149d6d7ae1502fb7b7abadcce70a6954c4b64a438ff1cd16fc77a0a1e5197cdd72da398f39eb929ea06f9005c45b132ed34e056ebdeb1
+ languageName: node
+ linkType: hard
+
"react-universal-interface@npm:^0.6.2":
version: 0.6.2
resolution: "react-universal-interface@npm:0.6.2"
@@ -12122,6 +12727,15 @@ __metadata:
languageName: node
linkType: hard
+"read-cache@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "read-cache@npm:1.0.0"
+ dependencies:
+ pify: ^2.3.0
+ checksum: cffc728b9ede1e0667399903f9ecaf3789888b041c46ca53382fa3a06303e5132774dc0a96d0c16aa702dbac1ea0833d5a868d414f5ab2af1e1438e19e6657c6
+ languageName: node
+ linkType: hard
+
"readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.8, readable-stream@npm:~2.3.6":
version: 2.3.8
resolution: "readable-stream@npm:2.3.8"
@@ -12358,7 +12972,7 @@ __metadata:
languageName: node
linkType: hard
-"resolve@npm:^1.14.2, resolve@npm:^1.20.0, resolve@npm:^1.21.0":
+"resolve@npm:^1.1.7, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.21.0, resolve@npm:^1.22.2":
version: 1.22.8
resolution: "resolve@npm:1.22.8"
dependencies:
@@ -12371,7 +12985,7 @@ __metadata:
languageName: node
linkType: hard
-"resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.21.0#~builtin":
+"resolve@patch:resolve@^1.1.7#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.21.0#~builtin, resolve@patch:resolve@^1.22.2#~builtin":
version: 1.22.8
resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=07638b"
dependencies:
@@ -12543,6 +13157,14 @@ __metadata:
"root-workspace-0b6124@workspace:.":
version: 0.0.0-use.local
resolution: "root-workspace-0b6124@workspace:."
+ dependencies:
+ "@emotion/react": ^11.13.3
+ "@emotion/styled": ^11.13.0
+ "@mui/icons-material": ^6.0.1
+ "@mui/material": ^6.0.1
+ autoprefixer: ^10.4.20
+ postcss: ^8.4.41
+ tailwindcss: ^3.4.10
languageName: unknown
linkType: soft
@@ -12993,6 +13615,13 @@ __metadata:
languageName: node
linkType: hard
+"source-map@npm:^0.5.7":
+ version: 0.5.7
+ resolution: "source-map@npm:0.5.7"
+ checksum: 5dc2043b93d2f194142c7f38f74a24670cd7a0063acdaf4bf01d2964b402257ae843c2a8fa822ad5b71013b5fcafa55af7421383da919752f22ff488bc553f4d
+ languageName: node
+ linkType: hard
+
"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1":
version: 0.6.1
resolution: "source-map@npm:0.6.1"
@@ -13331,6 +13960,13 @@ __metadata:
languageName: node
linkType: hard
+"stylis@npm:4.2.0":
+ version: 4.2.0
+ resolution: "stylis@npm:4.2.0"
+ checksum: 0eb6cc1b866dc17a6037d0a82ac7fa877eba6a757443e79e7c4f35bacedbf6421fadcab4363b39667b43355cbaaa570a3cde850f776498e5450f32ed2f9b7584
+ languageName: node
+ linkType: hard
+
"stylis@npm:4.3.2, stylis@npm:^4.3.0":
version: 4.3.2
resolution: "stylis@npm:4.3.2"
@@ -13350,6 +13986,24 @@ __metadata:
languageName: node
linkType: hard
+"sucrase@npm:^3.32.0":
+ version: 3.35.0
+ resolution: "sucrase@npm:3.35.0"
+ dependencies:
+ "@jridgewell/gen-mapping": ^0.3.2
+ commander: ^4.0.0
+ glob: ^10.3.10
+ lines-and-columns: ^1.1.6
+ mz: ^2.7.0
+ pirates: ^4.0.1
+ ts-interface-checker: ^0.1.9
+ bin:
+ sucrase: bin/sucrase
+ sucrase-node: bin/sucrase-node
+ checksum: 9fc5792a9ab8a14dcf9c47dcb704431d35c1cdff1d17d55d382a31c2e8e3063870ad32ce120a80915498486246d612e30cda44f1624d9d9a10423e1a43487ad1
+ languageName: node
+ linkType: hard
+
"superstruct@npm:^1.0.3":
version: 1.0.4
resolution: "superstruct@npm:1.0.4"
@@ -13405,6 +14059,39 @@ __metadata:
languageName: node
linkType: hard
+"tailwindcss@npm:^3.4.10":
+ version: 3.4.10
+ resolution: "tailwindcss@npm:3.4.10"
+ dependencies:
+ "@alloc/quick-lru": ^5.2.0
+ arg: ^5.0.2
+ chokidar: ^3.5.3
+ didyoumean: ^1.2.2
+ dlv: ^1.1.3
+ fast-glob: ^3.3.0
+ glob-parent: ^6.0.2
+ is-glob: ^4.0.3
+ jiti: ^1.21.0
+ lilconfig: ^2.1.0
+ micromatch: ^4.0.5
+ normalize-path: ^3.0.0
+ object-hash: ^3.0.0
+ picocolors: ^1.0.0
+ postcss: ^8.4.23
+ postcss-import: ^15.1.0
+ postcss-js: ^4.0.1
+ postcss-load-config: ^4.0.1
+ postcss-nested: ^6.0.1
+ postcss-selector-parser: ^6.0.11
+ resolve: ^1.22.2
+ sucrase: ^3.32.0
+ bin:
+ tailwind: lib/cli.js
+ tailwindcss: lib/cli.js
+ checksum: aa8db3514ec5110b2dee0bf5b35b84ebedf0c23a0dcafc870a5176bc2bad7d581956e0692ed6d888d602c114d2c54d7aa8fdb7028456880bd28b326078c8ba6e
+ languageName: node
+ linkType: hard
+
"tapable@npm:^2.2.0":
version: 2.2.1
resolution: "tapable@npm:2.2.1"
@@ -13493,6 +14180,24 @@ __metadata:
languageName: node
linkType: hard
+"thenify-all@npm:^1.0.0":
+ version: 1.6.0
+ resolution: "thenify-all@npm:1.6.0"
+ dependencies:
+ thenify: ">= 3.1.0 < 4"
+ checksum: dba7cc8a23a154cdcb6acb7f51d61511c37a6b077ec5ab5da6e8b874272015937788402fd271fdfc5f187f8cb0948e38d0a42dcc89d554d731652ab458f5343e
+ languageName: node
+ linkType: hard
+
+"thenify@npm:>= 3.1.0 < 4":
+ version: 3.3.1
+ resolution: "thenify@npm:3.3.1"
+ dependencies:
+ any-promise: ^1.0.0
+ checksum: 84e1b804bfec49f3531215f17b4a6e50fd4397b5f7c1bccc427b9c656e1ecfb13ea79d899930184f78bc2f57285c54d9a50a590c8868f4f0cef5c1d9f898b05e
+ languageName: node
+ linkType: hard
+
"thread-stream@npm:^0.15.1":
version: 0.15.2
resolution: "thread-stream@npm:0.15.2"
@@ -13620,6 +14325,13 @@ __metadata:
languageName: node
linkType: hard
+"ts-interface-checker@npm:^0.1.9":
+ version: 0.1.13
+ resolution: "ts-interface-checker@npm:0.1.13"
+ checksum: 20c29189c2dd6067a8775e07823ddf8d59a33e2ffc47a1bd59a5cb28bb0121a2969a816d5e77eda2ed85b18171aa5d1c4005a6b88ae8499ec7cc49f78571cb5e
+ languageName: node
+ linkType: hard
+
"tsconfck@npm:^3.0.3":
version: 3.1.1
resolution: "tsconfck@npm:3.1.1"
@@ -14074,7 +14786,7 @@ __metadata:
languageName: node
linkType: hard
-"util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1":
+"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1":
version: 1.0.2
resolution: "util-deprecate@npm:1.0.2"
checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2
@@ -14748,6 +15460,22 @@ __metadata:
languageName: node
linkType: hard
+"yaml@npm:^1.10.0":
+ version: 1.10.2
+ resolution: "yaml@npm:1.10.2"
+ checksum: ce4ada136e8a78a0b08dc10b4b900936912d15de59905b2bf415b4d33c63df1d555d23acb2a41b23cf9fb5da41c256441afca3d6509de7247daa062fd2c5ea5f
+ languageName: node
+ linkType: hard
+
+"yaml@npm:^2.3.4":
+ version: 2.5.0
+ resolution: "yaml@npm:2.5.0"
+ bin:
+ yaml: bin.mjs
+ checksum: a116dca5c61641d9bf1f1016c6e71daeb1ed4915f5930ed237d45ab7a605aa5d92c332ff64879a6cd088cabede008c778774e3060ffeb4cd617d28088e4b2d83
+ languageName: node
+ linkType: hard
+
"yargs-parser@npm:^18.1.2":
version: 18.1.3
resolution: "yargs-parser@npm:18.1.3"