diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index fc5063fb..73c7fa6c 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -1,8 +1,10 @@ -name: OUSD Governance +name: Origin DeFi Governance on: pull_request: - types: [opened, reopened] + types: [opened, reopened, synchronize] push: + branches: + - 'master' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -12,37 +14,18 @@ env: jobs: lint: - name: DApp Linter + name: Contracts Linter runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 with: submodules: recursive - - name: Cache Compiler Installations - uses: actions/cache@v2 - with: - path: | - ~/.solcx - ~/.vvm - key: compiler-cache - - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: "16" - cache: "yarn" - cache-dependency-path: | - client/yarn.lock - - - name: Install NPM dependencies - run: yarn - working-directory: client + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 - - name: Client linting - run: yarn run prettier:check - working-directory: client + - name: Run Linter + run: forge fmt --check brownie-tests: name: Brownie tests diff --git a/Procfile b/Procfile deleted file mode 100644 index 5043f2c4..00000000 --- a/Procfile +++ /dev/null @@ -1,2 +0,0 @@ -web: yarn run start:web -worker: yarn run start:listener \ No newline at end of file diff --git a/README.md b/README.md index f9597f09..8ca04492 100644 --- a/README.md +++ b/README.md @@ -83,69 +83,6 @@ In another terminal: brownie console --network hardhat-fork ``` -## Running the DApp and listener - -First, install the dependencies: - -```bash -cd client -yarn install -``` - -Copy `client/sample.env` to `client/.env`. - -Setup postgresql locally and create a database and update the `DATABASE_URL` in your `client/.env` - -_A typical postgres example looks like `postgres://user:secret@localhost:5432/ousdgovernance`._ - -Push the database and generate a client: - -```bash -npx prisma db push -``` - -(these are already defaults in `client/sample.env`) -Set the `NETWORK_ID` env var to 31337. -Set the `WEB3_PROVIDER` variable in your environment. -_The hardhat RPC default is `http://127.0.0.1:8545`._ - -Then, run the development server: - -```bash -npm run dev -# or -yarn dev -``` - -This will start both the NextJS app and a listener script monitoring your local blockchain for changes. - -# Deploying the dApp - -This section details the playbook for deploying the dApp. - -## Environments - -Commits to the following branches will automatically deploying to the associated Heroku environments: - -1. `stable` -> [Production](https://governance.ousd.com/claim) -2. `staging` -> [Staging](https://ousd-governance-goerli.herokuapp.com/) - -The production environment references the mainnet contracts in this repo. The staging environment references contracts deployed to Goerli. - -Note: You shouldn't commit to `stable` directly. Only merge from `master` (where new features are merged via approved pull request). - -## Production Deployment Process - -1. Take a database backup before you start: `heroku pg:backups:capture --app=ousd-governance-production`. Note: You must be authorised with Heroku to run this command. Contact Franck to be added if you're not already. - -1. Take a note of the last commit hash that's confirmed as working in production. You can find this in the `stable` branch's [commit history](https://github.com/OriginProtocol/ousd-governance/commits/stable). - -1. Merge from `master` to `stable` to initiate a deployment. You can check progress in the [Heroku Dashboard](https://dashboard.heroku.com/apps/ousd-governance-production) where you'll find error logs should your deployment fail. - -1. Once deployed, check the [production environment](https://governance.ousd.com/) in your browser to make sure that things are working as expected. If yes, you're done! - -1. If the release causes issues in production, don't be afraid to roll back while you diagnose the issue. Especially if users are impacted. You can do this by reverting your commit: `git revert [commit hash]` and pushing the resulting revert commit to `stable`. Or, if you want to keep a cleaner commit history, reset the `stable` branch to the last commit hash of the previous release: `git reset [commit hash] --hard` and push this to `stable` using `git push stable --force`. Note: You should only force push if you're 100% certain of the change. - ## Deploying contracts Setup environment variables: @@ -241,29 +178,7 @@ If required, follow this process post deployment: Here are some places you may come unstuck when setting up locally. If you find any yourself, please document them here to help your fellow engineers: -## 1. How do we populate the database with proposal data post-transaction submission? - -**Problem:** - -You're adding proposals and the transactions are going through on-chain, but confirmed proposals aren't showing in the UI. You might experience [listener.ts](/client/listener.ts) outputting lots of `info: Got confirmed block` messages, but nothing to confirm the script is picking up `ProposalCreated` events. - -**Explanation:** - -Proposals aren't pushed to the database from the front-end submision handler. Instead, [listener.ts](/client/listener.ts) monitors your local node, detects when the `ProposalCreated` event is fired, then adds the proposal to the database. However, these events can't be picked up when the starting block number is off in your database. - -**Solution:** - -Because we [start from the last seen block saved in the database](/client/listener.ts#L121), you may experience issues if this number is out of sync. To quickly solve: - -1. Comment out the database lookup function -2. Add `ethereumEvents.start(0)` beneath to ensure a start from the beginning -3. Run `yarn run dev` -4. Revert what you changed -5. Run `yarn run dev` again - -You should now see proposals added to the database when you submit transactions. - -## 2. M1 macs (ARM architecture) +## 1. M1 macs (ARM architecture) **Problem:** diff --git a/client/.eslintrc.json b/client/.eslintrc.json deleted file mode 100644 index bffb357a..00000000 --- a/client/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "next/core-web-vitals" -} diff --git a/client/.gitignore b/client/.gitignore deleted file mode 100644 index 824a9cc2..00000000 --- a/client/.gitignore +++ /dev/null @@ -1,43 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env.local -.env.development.local -.env.test.local -.env.production.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo - -# Sentry -.sentryclirc - -# Sentry -next.config.original.js diff --git a/client/.prettierignore b/client/.prettierignore deleted file mode 100644 index 65b715e2..00000000 --- a/client/.prettierignore +++ /dev/null @@ -1,6 +0,0 @@ -**/.git -**/.svn -**/.hg -**/node_modules -**.idea -.next diff --git a/client/components/ActiveLink.tsx b/client/components/ActiveLink.tsx deleted file mode 100644 index 33f7c674..00000000 --- a/client/components/ActiveLink.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { useRouter } from "next/router"; -import PropTypes from "prop-types"; -import Link from "next/link"; -import React, { Children } from "react"; - -const ActiveLink = ({ - children, - activeClassName, - inactiveClassName, - ...props -}) => { - const { asPath } = useRouter(); - const child = Children.only(children); - const childClassName = child.props.className || ""; - - const className = - asPath === props.href || asPath === props.as - ? `${childClassName} ${activeClassName}`.trim() - : `${childClassName} ${inactiveClassName}`.trim(); - - return ( - - {React.cloneElement(child, { - className: className || null, - })} - - ); -}; - -ActiveLink.propTypes = { - activeClassName: PropTypes.string.isRequired, -}; - -export default ActiveLink; diff --git a/client/components/Address.tsx b/client/components/Address.tsx deleted file mode 100644 index 4c249ce8..00000000 --- a/client/components/Address.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { useEffect, useState } from "react"; -import { useStore } from "utils/store"; -import { truncateEthAddress } from "utils"; -import Icon from "@mdi/react"; -import { mdiOpenInNew } from "@mdi/js"; - -export const Address = ({ - address, - noTruncate = false, -}: { - address: string; - noTruncate?: Boolean; -}) => { - const { rpcProvider } = useStore(); - const [addressDisplay, setAddressDisplay] = useState( - noTruncate ? address : truncateEthAddress(address) - ); - - useEffect(() => { - const loadEns = async () => { - try { - const ens = await rpcProvider.lookupAddress(address); - if (ens) { - setAddressDisplay(ens); - } - } catch (error) {} - }; - if (rpcProvider) { - loadEns(); - } - }, [rpcProvider, address]); - - let explorerPrefix; - if (rpcProvider?._network?.chainId === 1) { - explorerPrefix = "https://etherscan.io/"; - } else if (rpcProvider?._network?.chainId === 5) { - explorerPrefix = "https://goerli.etherscan.io/"; - } - - if (explorerPrefix) { - return ( - - {addressDisplay} - - ); - } else { - return <>{addressDisplay}; - } -}; diff --git a/client/components/AdminUtils.js b/client/components/AdminUtils.js deleted file mode 100644 index 690ec0f4..00000000 --- a/client/components/AdminUtils.js +++ /dev/null @@ -1,78 +0,0 @@ -import { useMemo } from "react"; -import { useStore } from "utils/store"; -import { ZERO_ADDRESS } from "constants/index"; - -const AdminUtils = () => { - const { contracts } = useStore(); - - const show = useMemo(() => { - if (process.browser) { - if (localStorage.getItem("admin") === "true") { - return true; - } - } - return false; - }, [process.browser]); - - const setClaimsOpenTs = (claimOpensTs) => { - useStore.setState({ - claim: { - ...useStore.getState().claim, - claimOpensTs, - }, - }); - }; - - const skipEducation = () => { - useStore.setState({ - claim: { - ...useStore.getState().claim, - currentStep: 2, - }, - }); - }; - - const resetDelegation = async () => { - await contracts.OgvStaking.delegate(ZERO_ADDRESS); - }; - - const buttonClass = "px-2 py-1 my-1 border border-black rounded-md"; - return ( - show && ( -
- - - - - -
- ) - ); -}; - -export default AdminUtils; diff --git a/client/components/BarChart.tsx b/client/components/BarChart.tsx deleted file mode 100644 index dab9c1cd..00000000 --- a/client/components/BarChart.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { FunctionComponent } from "react"; -import { - Chart as ChartJS, - CategoryScale, - LinearScale, - BarElement, - Tooltip, - ChartData, - ChartOptions, -} from "chart.js"; -import { Bar } from "react-chartjs-2"; - -ChartJS.register(CategoryScale, LinearScale, BarElement, Tooltip); - -interface BarChartProps { - data: ChartData<"bar">; -} - -const options: ChartOptions<"bar"> = { - plugins: { - tooltip: { - enabled: false, - }, - }, - scales: { - x: { - grid: { - display: false, - }, - ticks: { - color: "#A3AAB5", - font: { - family: "Lato, sans-serif", - }, - }, - }, - y: { - ticks: { - color: "#A3AAB5", - font: { - family: "Lato, sans-serif", - }, - }, - }, - }, -}; - -const BarChart: FunctionComponent = ({ data }) => ( - -); - -export default BarChart; diff --git a/client/components/Button.tsx b/client/components/Button.tsx deleted file mode 100644 index 2b0c60fa..00000000 --- a/client/components/Button.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; -import classNames from "classnames"; - -interface ButtonProps { - children: ReactNode; - onClick?: () => void; - large?: Boolean; - small?: Boolean; - disabled?: Boolean; - fullWidth?: Boolean; - alt?: Boolean; - white?: Boolean; - black?: Boolean; - red?: Boolean; -} - -const Button: FunctionComponent = ({ - children, - onClick, - large, - small, - disabled, - fullWidth, - alt, - white, - black, - red, -}) => { - const className = classNames("btn rounded-full normal-case space-x-2", { - "btn-lg h-[3.25rem] min-h-[3.25rem]": large, - "btn-sm": small, - "w-full": fullWidth, - "btn-primary": !alt, - "btn-primary btn-outline disabled:border-gray-100 disabled:text-gray-300": - alt, - "bg-white hover:bg-gray-100 active:bg-gray-100 focus:bg-gray-100 text-accent": - white, - "bg-black text-white border-black hover:bg-gray-900 hover:border-gray-900": - black, - "bg-[#dd0a0a] border-[#dd0a0a] hover:bg-[#f52424] hover:border-[#f52424]": - red, - }); - - return ( - - ); -}; - -export default Button; diff --git a/client/components/Card.tsx b/client/components/Card.tsx deleted file mode 100644 index ebee32ca..00000000 --- a/client/components/Card.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; -import classNames from "classnames"; - -interface CardProps { - children: ReactNode; - dark?: Boolean; - tightPadding?: Boolean; - noPadding?: Boolean; - alt?: Boolean; - noShadow?: Boolean; - red?: Boolean; - margin?: Boolean; - className?: string; -} - -const Card: FunctionComponent = ({ - children, - dark, - tightPadding, - noPadding, - alt, - noShadow, - red, - margin, - className, -}) => { - const classes = classNames( - "overflow-x-auto w-full rounded-lg border border-accent-content h-full", - { - "bg-secondary-focus text-white border-accent-content": dark && !alt, - "bg-accent-content text-white": !dark && !alt, - "p-4 md:p-5": tightPadding && !noPadding, - "p-6 md:p-10": !tightPadding && !noPadding, - "shadow-lg": !noShadow, - "px-4 py-5 md:px-5 md:py-6": tightPadding && !noPadding && noShadow, - "text-error": red, - "mt-6 h-full": margin, - }, - className - ); - - return
{children}
; -}; - -export default Card; diff --git a/client/components/CardDescription.tsx b/client/components/CardDescription.tsx deleted file mode 100644 index 0401d011..00000000 --- a/client/components/CardDescription.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; -import classNames from "classnames"; - -interface CardDescription { - children: ReactNode; - alt?: Boolean; - large?: Boolean; -} - -const CardDescription: FunctionComponent = ({ - children, - alt, - large, -}) => { - const classes = classNames("text-xs text-neutral", { - "text-base": large, - }); - - return
{children}
; -}; - -export default CardDescription; diff --git a/client/components/CardGroup.tsx b/client/components/CardGroup.tsx deleted file mode 100644 index 4bc7481a..00000000 --- a/client/components/CardGroup.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; -import classNames from "classnames"; - -interface CardGroupProps { - children: ReactNode; - horizontal?: Boolean; - twoCol?: Boolean; - fourCol?: Boolean; - dontStackOnMobile?: Boolean; -} - -const CardGroup: FunctionComponent = ({ - children, - horizontal, - twoCol, - fourCol, - dontStackOnMobile, -}) => { - const classes = classNames("w-full relative", { - "grid gap-2": horizontal, - "space-y-5": !horizontal, - "sm:grid-cols-2": twoCol, - "sm:grid-cols-4": fourCol, - "sm:grid-cols-3": !twoCol && !fourCol, - "grid-cols-2": twoCol && dontStackOnMobile, - "grid-cols-4": fourCol && dontStackOnMobile, - "grid-cols-3": !twoCol && !fourCol && dontStackOnMobile, - }); - - return
{children}
; -}; - -export default CardGroup; diff --git a/client/components/CardLabel.tsx b/client/components/CardLabel.tsx deleted file mode 100644 index e9492a76..00000000 --- a/client/components/CardLabel.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; - -interface CardLabelProps { - children: ReactNode; -} - -const CardLabel: FunctionComponent = ({ children }) => ( -
{children}
-); - -export default CardLabel; diff --git a/client/components/CardStat.tsx b/client/components/CardStat.tsx deleted file mode 100644 index 469a88e4..00000000 --- a/client/components/CardStat.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; -import classnames from "classnames"; - -interface CardStatProps { - children: ReactNode; - large?: Boolean; - small?: Boolean; -} - -const CardStat: FunctionComponent = ({ - children, - large, - small, -}) => ( -
- {children} -
-); - -export default CardStat; diff --git a/client/components/CheckIcon.tsx b/client/components/CheckIcon.tsx deleted file mode 100644 index 6707c4b2..00000000 --- a/client/components/CheckIcon.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FunctionComponent } from "react"; -import Image from "next/image"; - -const CheckIcon: FunctionComponent = () => ( - Eligible -); - -export default CheckIcon; diff --git a/client/components/CheckIconWhite.tsx b/client/components/CheckIconWhite.tsx deleted file mode 100644 index 4c80272e..00000000 --- a/client/components/CheckIconWhite.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FunctionComponent } from "react"; -import Image from "next/image"; - -const CheckIconWhite: FunctionComponent = () => ( - Correct -); - -export default CheckIconWhite; diff --git a/client/components/CrossIcon.tsx b/client/components/CrossIcon.tsx deleted file mode 100644 index 7d00fcf5..00000000 --- a/client/components/CrossIcon.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FunctionComponent } from "react"; -import Image from "next/image"; - -const CrossIcon: FunctionComponent = () => ( - Ineligible -); - -export default CrossIcon; diff --git a/client/components/CrossIconWhite.tsx b/client/components/CrossIconWhite.tsx deleted file mode 100644 index edbccf33..00000000 --- a/client/components/CrossIconWhite.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FunctionComponent } from "react"; -import Image from "next/image"; - -const CrossIconWhite: FunctionComponent = () => ( - Incorrect -); - -export default CrossIconWhite; diff --git a/client/components/DisabledButtonTooltip.tsx b/client/components/DisabledButtonTooltip.tsx deleted file mode 100644 index 97a159ca..00000000 --- a/client/components/DisabledButtonTooltip.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; -import ReactTooltip from "react-tooltip"; - -interface DisabledButtonToolTipProps { - text: string; - children: ReactNode; - show: Boolean; -} - -const DisabledButtonToolTip: FunctionComponent = ({ - text, - children, - show, -}) => { - if (!show) return <>{children}; - - return ( - <> - -

{text}

-
-
- {children} -
- - ); -}; - -export default DisabledButtonToolTip; diff --git a/client/components/Disconnected.tsx b/client/components/Disconnected.tsx deleted file mode 100644 index 85e2c98a..00000000 --- a/client/components/Disconnected.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import Card from "components/Card"; -import Wrapper from "components/Wrapper"; - -export function Disconnected({}) { - return ( - - -
- - - -

No wallet

-

- Click the connect button in the top right to connect a wallet -

-
-
-
- ); -} diff --git a/client/components/EtherscanIcon.tsx b/client/components/EtherscanIcon.tsx deleted file mode 100644 index 4b4aa432..00000000 --- a/client/components/EtherscanIcon.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FunctionComponent } from "react"; -import Image from "next/image"; - -const EtherscanIcon: FunctionComponent = () => ( - Etherscan -); - -export default EtherscanIcon; diff --git a/client/components/ExternalLinkIcon.tsx b/client/components/ExternalLinkIcon.tsx deleted file mode 100644 index 8757d702..00000000 --- a/client/components/ExternalLinkIcon.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { FunctionComponent } from "react"; -import Image from "next/image"; - -interface ExternalLinkIconProps { - isGreen?: boolean; -} - -const ExternalLinkIcon: FunctionComponent = ({ - isGreen, -}) => ( - External link -); - -export default ExternalLinkIcon; diff --git a/client/components/Footer.tsx b/client/components/Footer.tsx deleted file mode 100644 index d154e798..00000000 --- a/client/components/Footer.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { FunctionComponent } from "react"; -import Wrapper from "components/Wrapper"; - -const Footer: FunctionComponent = () => ( - -); - -export default Footer; diff --git a/client/components/GeoFenceCheck.tsx b/client/components/GeoFenceCheck.tsx deleted file mode 100644 index 5c315e9d..00000000 --- a/client/components/GeoFenceCheck.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { useState } from "react"; -import useLocalStorage from "utils/useLocalStorage"; -import classnames from "classnames"; - -const GeoFenceCheck = () => { - const { data: hasConfirmedGeoLocation, onSetItem } = useLocalStorage( - "@originprotocol/governance-geo-check", - false - ); - - const [isChecked, setIsChecked] = useState(false); - - const onAckGeoFence = () => { - onSetItem(true); - }; - - return ( -
-
-
-

Restricted Access

-
-
-

- Origin DeFi Governance is not available to restricted jurisdictions. - Before proceeding, please carefully read the following: -

-
-
    -
  • - You confirm that you are not a resident of, citizen of, located - in, incorporated in, or have a registered office in the United - States or any country or region currently currently subject to - sanctions by the United States. -
  • -
  • - You affirm that you are not a subject of economic or trade - sanctions administered or enforced by any governmental authority - or otherwise designated on any list of prohibited or restricted - parties, including the list maintained by the Office of Foreign - Assets Control of the U.S. Department of the Treasury. -
  • -
  • - You agree not to use any VPN or other privacy or anonymization - tools or techniques to attempt to circumvent these eligibility - restrictions. -
  • -
  • - You are lawfully permitted to access this site. You understand - and accept the risks associated with using Origin DeFi - Governance. -
  • -
-
-
- -
-
- -
-
- ); -}; - -export default GeoFenceCheck; diff --git a/client/components/Header.tsx b/client/components/Header.tsx deleted file mode 100644 index c92e4d15..00000000 --- a/client/components/Header.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import { FunctionComponent, useState } from "react"; -import classNames from "classnames"; -import { Web3Button } from "components/Web3Button"; -import Wrapper from "components/Wrapper"; -import Link from "components/Link"; -import Image from "next/image"; -import { navItems } from "../constants"; -import useStakingAPY from "utils/useStakingAPY"; - -interface HeaderProps { - hideNav?: boolean; -} - -const Header: FunctionComponent = ({ hideNav }) => { - const [menuIsOpen, setMenuIsOpen] = useState(false); - - const { stakingAPY, loading: apyLoading } = useStakingAPY(100, 48); - - const overlayClassNames = classNames( - "bg-black z-20 h-screen w-screen fixed top-0 transition duration-200 lg:hidden", - { - "opacity-0 -left-full": !menuIsOpen, - "opacity-50 left-0": menuIsOpen, - } - ); - - const mobileMenuClassNames = classNames( - "flex flex-col pt-8 bg-secondary z-30 fixed top-0 h-screen w-72 transition transition-right duration-200 lg:hidden", - { - "-right-full": !menuIsOpen, - "right-0": menuIsOpen, - } - ); - - return ( - <> -
- -
-
-
- - OUSD Governance - -
- {!hideNav && ( -
    - {navItems.map(({ href, label, external }) => ( -
  • - - {label} - {href === "/stake" && ( -
    -
    - - {apyLoading ? "--.--" : stakingAPY.toFixed(2)}% - vAPY - -
    - )} - -
  • - ))} -
- )} -
- {!hideNav && ( -
- - -
- )} -
-
-
- {!hideNav && ( - <> -
setMenuIsOpen(false)} - /> -
- -
    - {navItems.map(({ href, label, external }) => ( -
  • - setMenuIsOpen(false) : () => null - } - type={external ? "external" : "internal"} - newWindow={external} - > - {label} - {href === "/stake" && ( -
    -
    - - {apyLoading ? "--.--" : stakingAPY.toFixed(2)}% vAPY - -
    - )} - -
  • - ))} -
-
- - )} - - ); -}; - -export default Header; diff --git a/client/components/LeaderboardTable.tsx b/client/components/LeaderboardTable.tsx deleted file mode 100644 index 50a90fd7..00000000 --- a/client/components/LeaderboardTable.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { ethers } from "ethers"; -import TokenAmount from "components/TokenAmount"; -import { useStore } from "utils/store"; -import { Address } from "components/Address"; - -export const LeaderboardTable = ({ voters }: { voters: Array }) => { - const { totalBalances } = useStore(); - const { totalSupplyVeOgv } = totalBalances; - - if (voters.length < 1) { - return

No voters yet.

; - } - - return ( - - - - - - - - - - - - {voters.map((voter, index) => ( - - - - - - - - ))} - -
RankAddressVotesVote WeightProposals Voted
- {index + 1} - -
-
- - - {((voter.votes / totalSupplyVeOgv) * 100).toFixed(2)}% - - {voter.proposalsVoted} -
- ); -}; diff --git a/client/components/Link.tsx b/client/components/Link.tsx deleted file mode 100644 index 5478a809..00000000 --- a/client/components/Link.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import NextLink from "next/link"; -import { useRouter } from "next/router"; -import classNames from "classnames"; -import { ReactNode, FunctionComponent } from "react"; -import { UrlObject } from "url"; -declare type Url = string | UrlObject; - -interface LinkProps { - children: ReactNode; - href: Url; - type?: "internal" | "external"; - className?: string; - currentClassName?: string; - onClick?: () => void; - newWindow?: boolean; -} - -const Link: FunctionComponent = ({ - children, - href, - type, - className, - currentClassName = "", - newWindow, - onClick, -}) => { - const router = useRouter(); - const { asPath } = router; - const pathTrimmed = asPath.replace("/", ""); - const hrefTrimmed = href.toString().replace("/", ""); - const isCurrent = - asPath === "/" - ? asPath === href - : hrefTrimmed && pathTrimmed.includes(hrefTrimmed); - - const classes = classNames(className, { - [currentClassName]: isCurrent, - }); - - if (type === "external") { - return ( - - {children} - - ); - } - - return ( - - - {children} - - - ); -}; - -export default Link; diff --git a/client/components/Loading.tsx b/client/components/Loading.tsx deleted file mode 100644 index 5fde91b3..00000000 --- a/client/components/Loading.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import classNames from "classnames"; - -const Loading = ({ small = false, large = false }) => { - const className = classNames("", { - "inline mr-2 w-8 h-8 text-gray-200 animate-spin fill-accent": !small, - "w-4 h-4 text-gray-200 animate-spin fill-accent": small, - "w-16 h-16": large, - }); - - return ( -
- - - - -
- ); -}; - -export { Loading }; diff --git a/client/components/Modal.tsx b/client/components/Modal.tsx deleted file mode 100644 index 136e655a..00000000 --- a/client/components/Modal.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { FunctionComponent, ReactNode, Dispatch, SetStateAction } from "react"; -import classNames from "classnames"; -import CrossIcon from "components/CrossIcon"; - -interface ModalProps { - show: Boolean; - handleClose?: Dispatch>; - children: ReactNode; - showCloseIcon?: Boolean; -} - -const Modal: FunctionComponent = ({ - show, - handleClose, - children, - showCloseIcon, -}) => { - const className = classNames("modal", { - "modal-open": show, - }); - - return ( -
-
e.stopPropagation()} - className="modal-box overflow-hidden bg-secondary text-white" - > - {showCloseIcon && handleClose && ( - - )} - {children} -
-
- ); -}; - -export default Modal; diff --git a/client/components/OgvTotalStats.tsx b/client/components/OgvTotalStats.tsx deleted file mode 100644 index 8c3c96ae..00000000 --- a/client/components/OgvTotalStats.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { FunctionComponent } from "react"; -import CardGroup from "components/CardGroup"; -import Card from "components/Card"; -import CardLabel from "components/CardLabel"; -import CardStat from "components/CardStat"; -import CardDescription from "components/CardDescription"; -import TokenIcon from "components/TokenIcon"; -import TokenAmount from "components/TokenAmount"; -import { useStore } from "utils/store"; - -interface OgvTotalStatsProps { - alt?: Boolean; -} - -const OgvTotalStats: FunctionComponent = ({ alt }) => { - const { totalBalances } = useStore(); - const { totalSupplyOfOgv, totalLockedUpOgv, totalPercentageOfLockedUpOgv } = - totalBalances; - - return ( - -
- -
- Total supply -
- - - - -
- OGV -
-
-
-
- -
- Staked -
- - - - -
- OGV -
-
-
-
- -
- % staked -
- - {totalPercentageOfLockedUpOgv.toFixed(2)}% -
- OGV -
-
-
-
- ); -}; - -export default OgvTotalStats; diff --git a/client/components/PageTitle.tsx b/client/components/PageTitle.tsx deleted file mode 100644 index e3a8c9a4..00000000 --- a/client/components/PageTitle.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; - -interface PageTitleProps { - children: ReactNode; - noBottomMargin?: Boolean; -} - -export const PageTitle: FunctionComponent = ({ - children, - noBottomMargin, -}) => ( -
-

- {children} -

-
-); diff --git a/client/components/PlayIcon.tsx b/client/components/PlayIcon.tsx deleted file mode 100644 index c96eae37..00000000 --- a/client/components/PlayIcon.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { FunctionComponent } from "react"; -import Image from "next/image"; - -const PlayIcon: FunctionComponent = () => ( - Play -); - -export default PlayIcon; diff --git a/client/components/RangeInput.tsx b/client/components/RangeInput.tsx deleted file mode 100644 index 912419f6..00000000 --- a/client/components/RangeInput.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { FunctionComponent, ChangeEventHandler } from "react"; -import TokenAmount from "components/TokenAmount"; - -interface RangeInputProps { - label: string; - counterUnit: string; - min: string; - max: string; - value: number | string; - markers?: object[]; - onChange: ChangeEventHandler; - onMarkerClick?: (marker: string) => void; - hideLabel?: Boolean; - hideLabelFormatting?: Boolean; -} - -// @ts-ignore -const RangeInput: FunctionComponent = ({ - label, - counterUnit, - min, - max, - value, - markers, - onChange, - onMarkerClick, - hideLabel, - hideLabelFormatting, -}) => ( - <> - {!hideLabel && ( - - )} -
- - {markers && markers.length > 0 && ( - <> -
- {markers.map((marker, index) => ( - - | - {marker.value ? ( - - ) : ( - {marker.label} - )} - - ))} -
- - )} -
- -); - -export default RangeInput; diff --git a/client/components/SectionTitle.tsx b/client/components/SectionTitle.tsx deleted file mode 100644 index 0c47f186..00000000 --- a/client/components/SectionTitle.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export const SectionTitle = ({ children, noMarginBottom = false }) => ( -
-

- {children} -

-
-); diff --git a/client/components/Seo.tsx b/client/components/Seo.tsx deleted file mode 100644 index 0236129d..00000000 --- a/client/components/Seo.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { FunctionComponent } from "react"; -import { NextSeo } from "next-seo"; - -interface SeoProps { - title?: string; -} - -const Seo: FunctionComponent = ({ title }) => ( - -); - -export default Seo; diff --git a/client/components/SlideControls.tsx b/client/components/SlideControls.tsx deleted file mode 100644 index 0a3ba1b1..00000000 --- a/client/components/SlideControls.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { FunctionComponent } from "react"; -import Image from "next/image"; - -interface SlideNavProps { - currentSlide: number; - slides: Array; - handlePrevSlide?: () => void; - handleNextSlide?: () => void; -} - -const SlideNav: FunctionComponent = ({ - currentSlide, - slides, - handlePrevSlide, - handleNextSlide, -}) => ( -
- {slides[currentSlide - 1] !== undefined && ( -
- -
- )} - {slides[currentSlide + 1] !== undefined && ( -
- -
- )} -
-); - -export default SlideNav; diff --git a/client/components/SlideTracker.tsx b/client/components/SlideTracker.tsx deleted file mode 100644 index 9bbb760f..00000000 --- a/client/components/SlideTracker.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { FunctionComponent } from "react"; - -interface SlideTrackerProps { - currentSlide: number; - slides: Array; - onDotClick?: (dot: number) => void; -} - -const SlideTracker: FunctionComponent = ({ - currentSlide, - slides, - onDotClick, -}) => ( -
    - {slides.map((slide, index) => ( -
  • -
  • - ))} -
-); - -export default SlideTracker; diff --git a/client/components/StepControls.tsx b/client/components/StepControls.tsx deleted file mode 100644 index 31ff398b..00000000 --- a/client/components/StepControls.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FunctionComponent } from "react"; -import Button from "components/Button"; - -interface StepControlsProps { - currentStep: number; - stepControlsLabels: Array; - handleNextStep: () => void; - handlePrevStep: () => void; -} - -const StepControls: FunctionComponent = ({ - currentStep, - stepControlsLabels, - handlePrevStep, - handleNextStep, -}) => ( -
- {stepControlsLabels[currentStep - 1] !== undefined && ( -
- -
- )} - {stepControlsLabels[currentStep + 1] !== undefined && ( -
- -
- )} -
-); - -export default StepControls; diff --git a/client/components/StepTracker.tsx b/client/components/StepTracker.tsx deleted file mode 100644 index 5402c9d2..00000000 --- a/client/components/StepTracker.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { FunctionComponent } from "react"; - -interface StepTrackerProps { - currentStep: number; - steps: Array; -} - -const StepTracker: FunctionComponent = ({ - currentStep, - steps, -}) => ( -
-

- Step {currentStep + 1}:{" "} - {steps[currentStep]} -

-
-
- {currentStep >= 1 && ( -
- )} - {currentStep >= 2 && ( -
- )} -
    -
  • - = 0 - ? "h-5 w-5 rounded-full bg-accent block border border-black -ml-1" - : "h-5 w-5 rounded-full bg-black block border border-black -ml-1" - } - /> - - Check Eligibility - -
  • -
  • - = 1 - ? "h-5 w-5 rounded-full bg-accent block mx-auto border border-black" - : "h-5 w-5 rounded-full bg-black block mx-auto border border-black" - } - /> - - Learn about Origin - -
  • -
  • - = 2 - ? "h-5 w-5 rounded-full bg-accent block ml-auto border border-black -mr-1" - : "h-5 w-5 rounded-full bg-black block ml-auto border border-black -mr-1" - } - /> - - Claim Airdrop - -
  • -
-
-
-); - -export default StepTracker; diff --git a/client/components/TimeToDate.tsx b/client/components/TimeToDate.tsx deleted file mode 100644 index e6190e7d..00000000 --- a/client/components/TimeToDate.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; -import dayjs from "dayjs"; -import relativeTime from "dayjs/plugin/relativeTime"; -import { useStore } from "utils/store"; -import { SECONDS_IN_A_MONTH } from "../constants/index"; - -dayjs.extend(relativeTime); - -interface TimeToDateProps { - epoch: number; -} - -const TimeToDate: FunctionComponent = ({ epoch }) => { - const { blockTimestamp } = useStore(); - - const monthsRemaining = Math.floor( - (epoch - blockTimestamp) / SECONDS_IN_A_MONTH - ); - - return ( - - {monthsRemaining > 1 ? ( - <>{monthsRemaining} months - ) : ( - <> - {monthsRemaining === 1 ? ( - <>{monthsRemaining} month - ) : ( - <> - {epoch < blockTimestamp ? `-` : dayjs.unix(epoch).fromNow(true)} - - )} - - )} - - ); -}; - -export default TimeToDate; diff --git a/client/components/TokenAmount.tsx b/client/components/TokenAmount.tsx deleted file mode 100644 index 7de5b82b..00000000 --- a/client/components/TokenAmount.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { FunctionComponent } from "react"; -import { BigNumber } from "ethers"; -import numeral from "numeraljs"; -import { useAccount } from "wagmi"; - -interface TokenAmount { - amount: BigNumber | string | number; - format?: string; - isWalletBalance?: Boolean; -} - -const TokenAmount: FunctionComponent = ({ - amount, - format, - isWalletBalance, -}) => { - const { isConnected } = useAccount(); - - const formatMap = { - abbreviatedCurrency: "0.00 a", - currency: "0,0.00", - currency_no_decimals: "0,0", - default: "0.00 a", - }; - - const usedFormat = formatMap[format] || formatMap["default"]; - - if (isWalletBalance && !isConnected) { - return --.--; - } - - if (typeof amount == "string" || typeof amount == "number") { - if (typeof amount == "number" && Number.isInteger(amount)) - return ( - - {numeral(+amount).format("0 a").trim()} - - ); - - if (typeof amount == "string") - return ( - - {numeral(+amount).format("0.00 a").trim()} - - ); - - return ( - - {numeral(+amount).format(usedFormat).trim()} - - ); - } - - return ( - - {numeral(+amount / 1e18).format(usedFormat)} - - ); -}; - -export default TokenAmount; diff --git a/client/components/TokenIcon.tsx b/client/components/TokenIcon.tsx deleted file mode 100644 index a88d2256..00000000 --- a/client/components/TokenIcon.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { FunctionComponent } from "react"; -import Image from "next/image"; - -interface TokenIconProps { - src: string; - alt?: string; - large?: Boolean; - small?: Boolean; -} - -const TokenIcon: FunctionComponent = ({ - src, - alt, - large, - small, -}) => ( -
- {alt} -
-); - -export default TokenIcon; diff --git a/client/components/TransactionListener.tsx b/client/components/TransactionListener.tsx deleted file mode 100644 index d5b3bb27..00000000 --- a/client/components/TransactionListener.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { useEffect, useState } from "react"; -import { usePrevious } from "utils/index"; -import { useStore } from "utils/store"; -import { ToastContainer, toast } from "react-toastify"; -import "react-toastify/dist/ReactToastify.css"; -import { isMobile } from "react-device-detect"; -import { useRouter } from "next/router"; - -export const TransactionListener = () => { - const { provider, pendingTransactions } = useStore(); - const router = useRouter(); - const prevPendingTransactions = usePrevious(pendingTransactions); - const [isOnClaimPage, setIsOnClaimPage] = useState(false); - - useEffect(() => { - const newIsOnClaimPage = router.pathname === "/claim"; - // navigating away from the claim page - if (!newIsOnClaimPage && isOnClaimPage) { - // dismiss all toasts that may have been seen on the claim page - toast.dismiss(); - } - setIsOnClaimPage(newIsOnClaimPage); - }, [router.pathname]); - - useEffect(() => { - if (!prevPendingTransactions) return; - const newTransactions = pendingTransactions.filter( - (x) => !prevPendingTransactions.includes(x) - ); - - if (newTransactions.length > 0) { - newTransactions.forEach((transaction) => { - provider.once(transaction.hash, (minedTransaction) => { - if ( - transaction.onComplete && - typeof transaction.onComplete === "function" - ) { - transaction.onComplete(minedTransaction); - } else { - toast.success( - transaction.onComplete || "Transaction is completed", - { - hideProgressBar: true, - } - ); - } - }); - toast.info("Transaction is being mined", { hideProgressBar: true }); - }); - } - }, [pendingTransactions]); - - return ( - - ); -}; diff --git a/client/components/Video.tsx b/client/components/Video.tsx deleted file mode 100644 index 2ca642f7..00000000 --- a/client/components/Video.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { FunctionComponent } from "react"; - -interface VideoProps { - id: string; -} - -const Video: FunctionComponent = ({ id }) => ( -
-