├── public ├── assets │ └── images │ │ ├── logo.png │ │ └── from-crypto.png └── index.html ├── readme_images ├── guide-site.png └── guide-terminal.png ├── vite.config.js ├── src ├── hooks │ ├── useWallet.js │ ├── useLoading.js │ └── useAlertMessage.js ├── utils │ ├── functions.js │ └── constants.js ├── Routes.jsx ├── index.jsx ├── index.css ├── components │ ├── Loading.jsx │ ├── AlertMessage.jsx │ └── styledComponents.js ├── App.css ├── App.jsx ├── contexts │ ├── LoadingContext.jsx │ ├── AlertMessageContext.jsx │ └── WalletContext.jsx ├── favicon.svg ├── logo.svg └── pages │ └── Home.jsx ├── .gitignore ├── README.md ├── index.html ├── config-overrides.js ├── package.json └── Bridge.sol /public/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejan-Teofilovic/c-charge-private/HEAD/public/assets/images/logo.png -------------------------------------------------------------------------------- /readme_images/guide-site.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejan-Teofilovic/c-charge-private/HEAD/readme_images/guide-site.png -------------------------------------------------------------------------------- /readme_images/guide-terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejan-Teofilovic/c-charge-private/HEAD/readme_images/guide-terminal.png -------------------------------------------------------------------------------- /public/assets/images/from-crypto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejan-Teofilovic/c-charge-private/HEAD/public/assets/images/from-crypto.png -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()] 7 | }) 8 | -------------------------------------------------------------------------------- /src/hooks/useWallet.js: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { WalletContext } from '../contexts/WalletContext'; 3 | 4 | const useWallet = () => useContext(WalletContext); 5 | 6 | export default useWallet; -------------------------------------------------------------------------------- /src/hooks/useLoading.js: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { LoadingContext } from '../contexts/LoadingContext'; 3 | 4 | const useLoading = () => useContext(LoadingContext); 5 | 6 | export default useLoading; -------------------------------------------------------------------------------- /src/utils/functions.js: -------------------------------------------------------------------------------- 1 | export const thousandsSeparators = (num) => { 2 | var num_parts = num.toString().split("."); 3 | num_parts[0] = num_parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); 4 | return num_parts.join("."); 5 | }; -------------------------------------------------------------------------------- /src/hooks/useAlertMessage.js: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { AlertMessageContext } from '../contexts/AlertMessageContext'; 3 | 4 | const useAlertMessage = () => useContext(AlertMessageContext); 5 | 6 | export default useAlertMessage; -------------------------------------------------------------------------------- /src/Routes.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useRoutes } from 'react-router'; 3 | import Home from './pages/Home'; 4 | 5 | export default function Routes() { 6 | return useRoutes([ 7 | { 8 | path: '/', 9 | element: 10 | } 11 | ]); 12 | } -------------------------------------------------------------------------------- /src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')).render( 7 | 8 | 9 | 10 | ) 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | *.env 26 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/components/Loading.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { CircularProgress, DialogContent } from '@mui/material'; 3 | import useLoading from '../hooks/useLoading'; 4 | import { COLOR_PRIMARY } from '../utils/constants'; 5 | import { CustomDialog } from './styledComponents'; 6 | 7 | export default function Loading() { 8 | const { isLoading } = useLoading(); 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C-Charge Token sale 2 | 3 | ## Live site 4 | [![Live site](readme_images/guide-site.png)](https://private.c-charge.io/) 5 | 6 | ## Contact info 7 | - **Email:** dejanteofilovic2@gmail.com 8 | - **Discord:** [dejan_teofilovic](https://discord.gg/PztT2r5U) 9 | 10 | 11 | ## Release date 12 | Jul 11, 2022 13 | 14 | ## Environment 15 | - `Node.js v14.17.0` 16 | 17 | ## Stack 18 | - **Framework:** `React.js v18.0.0` 19 | - **Theme:** `MUI v5.8.6` 20 | 21 | ## How to run the project. 22 | 1. Please open terminal window in the root directory. 23 | 2. Please run command `npm run start` in it. 24 | 25 | ![guide-terminal](readme_images/guide-terminal.png) 26 | 27 | 3. You can see a site like the following image if it is run correctly. 28 | 29 | ![guide-site](readme_images/guide-site.png) -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | 40 | button { 41 | font-size: calc(10px + 2vmin); 42 | } 43 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | Vite App 14 | 15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /config-overrides.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | module.exports = function override(config, env) { 3 | config.resolve.fallback = { 4 | url: require.resolve('url'), 5 | fs: require.resolve('fs'), 6 | assert: require.resolve('assert'), 7 | crypto: require.resolve('crypto-browserify'), 8 | http: require.resolve('stream-http'), 9 | https: require.resolve('https-browserify'), 10 | os: require.resolve('os-browserify/browser'), 11 | buffer: require.resolve('buffer'), 12 | stream: require.resolve('stream-browserify'), 13 | }; 14 | config.plugins.push( 15 | new webpack.ProvidePlugin({ 16 | process: 'process/browser', 17 | Buffer: ['buffer', 'Buffer'], 18 | }), 19 | ); 20 | config.module.rules.push({ 21 | test: /\.m?js/, 22 | resolve: { 23 | fullySpecified: false 24 | } 25 | }); 26 | 27 | return config; 28 | }; -------------------------------------------------------------------------------- /src/components/AlertMessage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Alert, Snackbar } from '@mui/material'; 3 | import useAlertMessage from '../hooks/useAlertMessage'; 4 | 5 | /* -------------------------------------------------------------------- */ 6 | 7 | export default function AlertMessage() { 8 | const { isOpened, severity, message, closeAlert } = useAlertMessage(); 9 | 10 | const handleClose = (event, reason) => { 11 | if (reason === 'clickaway') { 12 | return; 13 | } 14 | closeAlert(); 15 | }; 16 | return ( 17 | 23 | 24 | {message} 25 | 26 | 27 | ); 28 | } -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | C-Charge Private Sale 15 | 16 | 17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BrowserRouter as Router } from 'react-router-dom'; 3 | import { 4 | createTheme, 5 | ThemeProvider 6 | } from '@mui/material'; 7 | import { LoadingProvider } from './contexts/LoadingContext'; 8 | import { AlertMessageProvider } from './contexts/AlertMessageContext'; 9 | import { WalletProvider } from './contexts/WalletContext'; 10 | import Loading from './components/Loading'; 11 | import AlertMessage from './components/AlertMessage'; 12 | import Routes from './Routes'; 13 | 14 | /* --------------------------------------------------------------------------- */ 15 | 16 | const theme = createTheme({}); 17 | 18 | /* --------------------------------------------------------------------------- */ 19 | 20 | function App() { 21 | 22 | return ( 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | ); 37 | } 38 | 39 | export default App; 40 | -------------------------------------------------------------------------------- /src/contexts/LoadingContext.jsx: -------------------------------------------------------------------------------- 1 | import React, { createContext, useReducer } from 'react'; 2 | 3 | const initialState = { 4 | isLoading: false, 5 | }; 6 | 7 | const handlers = { 8 | INITIALIZE: (state, action) => { 9 | return { 10 | ...state, 11 | ...action.payload 12 | }; 13 | }, 14 | SET_IS_LOADING: (state, action) => { 15 | return { 16 | ...state, 17 | isLoading: action.payload 18 | }; 19 | } 20 | }; 21 | 22 | const reducer = (state, action) => 23 | handlers[action.type] ? handlers[action.type](state, action) : state; 24 | 25 | // Context 26 | const LoadingContext = createContext({ 27 | ...initialState, 28 | openLoading: () => Promise.resolve(), 29 | closeLoading: () => Promise.resolve() 30 | }); 31 | 32 | // Provider 33 | function LoadingProvider({ children }) { 34 | const [state, dispatch] = useReducer(reducer, initialState); 35 | 36 | const openLoading = () => { 37 | dispatch({ 38 | type: 'SET_IS_LOADING', 39 | payload: true 40 | }); 41 | }; 42 | 43 | const closeLoading = () => { 44 | dispatch({ 45 | type: 'INITIALIZE', 46 | payload: { 47 | isLoading: false, 48 | } 49 | }); 50 | }; 51 | 52 | return ( 53 | 60 | {children} 61 | 62 | ); 63 | } 64 | 65 | export { LoadingContext, LoadingProvider }; -------------------------------------------------------------------------------- /src/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "c-charge-private", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "start": "react-app-rewired start", 7 | "build": "react-app-rewired build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@emotion/react": "^11.9.3", 12 | "@emotion/styled": "^11.9.3", 13 | "@mui/material": "^5.8.6", 14 | "@walletconnect/web3-provider": "^1.7.8", 15 | "@web3-onboard/core": "^2.8.0", 16 | "@web3-onboard/injected-wallets": "^2.1.0", 17 | "@web3-onboard/walletconnect": "^2.1.0", 18 | "assert": "^2.0.0", 19 | "crypto-browserify": "^3.12.0", 20 | "ethers": "^5.6.9", 21 | "https-browserify": "^1.0.0", 22 | "os-browserify": "^0.3.0", 23 | "react": "^18.0.0", 24 | "react-app-rewired": "^2.2.1", 25 | "react-dom": "^18.0.0", 26 | "react-router": "^6.3.0", 27 | "react-router-dom": "^6.3.0", 28 | "react-scripts": "^5.0.1", 29 | "stream-browserify": "^3.0.0", 30 | "stream-http": "^3.2.0", 31 | "url": "^0.11.0", 32 | "web3": "^1.7.5", 33 | "web3modal": "^1.9.8" 34 | }, 35 | "devDependencies": { 36 | "@iconify/react": "^3.2.2", 37 | "@types/react": "^18.0.0", 38 | "@types/react-dom": "^18.0.0", 39 | "@vitejs/plugin-react": "^1.3.0", 40 | "vite": "^2.9.9" 41 | }, 42 | "browserslist": { 43 | "production": [ 44 | ">0.2%", 45 | "not dead", 46 | "not op_mini all" 47 | ], 48 | "development": [ 49 | "last 1 chrome version", 50 | "last 1 firefox version", 51 | "last 1 safari version" 52 | ] 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/components/styledComponents.js: -------------------------------------------------------------------------------- 1 | import { 2 | Button, 3 | styled, 4 | LinearProgress, 5 | linearProgressClasses, 6 | TextField, 7 | Dialog 8 | } from '@mui/material'; 9 | import { grey } from '@mui/material/colors'; 10 | import { COLOR_PRIMARY, COLOR_WHITE, FONT_FAMILY_SECONDARY } from "../utils/constants"; 11 | 12 | export const PrimaryButton = styled(Button)` 13 | font-family: ${FONT_FAMILY_SECONDARY}; 14 | background-color: ${COLOR_PRIMARY}; 15 | color: ${COLOR_WHITE}; 16 | text-transform: none; 17 | :hover { 18 | background-color: ${COLOR_PRIMARY}; 19 | } 20 | `; 21 | 22 | export const PrimaryLinearProgressbar = styled(LinearProgress)({ 23 | height: 20, 24 | borderRadius: 10, 25 | [`&.${linearProgressClasses.colorPrimary}`]: { 26 | backgroundColor: grey[400], 27 | }, 28 | [`& .${linearProgressClasses.bar}`]: { 29 | borderRadius: 10, 30 | backgroundColor: COLOR_PRIMARY, 31 | }, 32 | }); 33 | 34 | export const ExchangeTextField = styled(TextField)({ 35 | '& label.Mui-focused': { 36 | color: 'black', 37 | }, 38 | '& .MuiInput-underline:after': { 39 | borderBottomColor: 'none', 40 | }, 41 | '& .MuiOutlinedInput-root': { 42 | backgroundColor: COLOR_WHITE, 43 | fontFamily: FONT_FAMILY_SECONDARY, 44 | fontWeight: 900, 45 | border: 'none', 46 | borderRadius: 20, 47 | '& fieldset': { 48 | }, 49 | '&:hover fieldset': { 50 | borderColor: 'rgba(0, 0, 0, 0)', 51 | }, 52 | '&.Mui-focused fieldset': { 53 | border: 'none', 54 | }, 55 | '&.Mui-disabled fieldset': { 56 | border: 'none', 57 | }, 58 | }, 59 | '& .MuiOutlinedInput-input': { 60 | fontSize: 24, 61 | padding: 10 62 | }, 63 | '& .MuiOutlinedInput-input::placeholder': { 64 | fontWeight: 900 65 | }, 66 | '& .MuiFormHelperText-root': { 67 | margin: '10px 0px' 68 | }, 69 | '& .MuiOutlinedInput-notchedOutline': { 70 | borderColor: 'rgba(0, 0, 0, 0)' 71 | } 72 | }); 73 | 74 | export const CustomDialog = styled(Dialog)({ 75 | '& .MuiPaper-root': { 76 | borderRadius: 10, 77 | } 78 | }); -------------------------------------------------------------------------------- /src/contexts/AlertMessageContext.jsx: -------------------------------------------------------------------------------- 1 | import React, { createContext, useReducer } from 'react'; 2 | import { SUCCESS } from '../utils/constants'; 3 | // ---------------------------------------------------------------------- 4 | 5 | const initialState = { 6 | isOpened: false, 7 | severity: 'success', 8 | message: '' 9 | }; 10 | 11 | const handlers = { 12 | INITIALIZE: (state, action) => { 13 | return { 14 | ...state, 15 | ...action.payload 16 | }; 17 | }, 18 | SET_IS_OPENED: (state, action) => { 19 | return { 20 | ...state, 21 | isOpened: action.payload 22 | }; 23 | }, 24 | SET_SEVERITY: (state, action) => { 25 | return { 26 | ...state, 27 | severity: action.payload 28 | }; 29 | }, 30 | SET_MESSAGE: (state, action) => { 31 | return { 32 | ...state, 33 | message: action.payload 34 | }; 35 | } 36 | }; 37 | 38 | const reducer = (state, action) => 39 | handlers[action.type] ? handlers[action.type](state, action) : state; 40 | 41 | // Context 42 | const AlertMessageContext = createContext({ 43 | ...initialState, 44 | openAlert: () => Promise.resolve(), 45 | closeAlert: () => Promise.resolve() 46 | }); 47 | 48 | // Provider 49 | function AlertMessageProvider({ children }) { 50 | const [state, dispatch] = useReducer(reducer, initialState); 51 | 52 | /** 53 | * Visible the alert message 54 | * @param {object} param0 55 | */ 56 | const openAlert = ({ severity, message }) => { 57 | dispatch({ 58 | type: 'SET_IS_OPENED', 59 | payload: true 60 | }); 61 | dispatch({ 62 | type: 'SET_SEVERITY', 63 | payload: severity 64 | }); 65 | dispatch({ 66 | type: 'SET_MESSAGE', 67 | payload: message 68 | }); 69 | }; 70 | 71 | /** 72 | * Unvisible the alert message 73 | */ 74 | const closeAlert = () => { 75 | dispatch({ 76 | type: 'INITIALIZE', 77 | payload: { 78 | isOpened: false, 79 | severity: SUCCESS, 80 | message: '' 81 | } 82 | }); 83 | }; 84 | 85 | return ( 86 | 93 | {children} 94 | 95 | ); 96 | } 97 | 98 | export { AlertMessageContext, AlertMessageProvider }; -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Bridge.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | 4 | abstract contract Context { 5 | function _msgSender() internal view virtual returns (address) { 6 | return msg.sender; 7 | } 8 | 9 | function _msgData() internal view virtual returns (bytes calldata) { 10 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 11 | return msg.data; 12 | } 13 | } 14 | 15 | abstract contract Ownable is Context { 16 | address private _owner; 17 | 18 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 19 | 20 | constructor() { 21 | _setOwner(_msgSender()); 22 | } 23 | 24 | function owner() public view virtual returns (address) { 25 | return _owner; 26 | } 27 | 28 | modifier onlyOwner() { 29 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 30 | _; 31 | } 32 | 33 | function renounceOwnership() public virtual onlyOwner { 34 | _setOwner(address(0)); 35 | } 36 | 37 | function transferOwnership(address newOwner) public virtual onlyOwner { 38 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 39 | _setOwner(newOwner); 40 | } 41 | 42 | function _setOwner(address newOwner) private { 43 | address oldOwner = _owner; 44 | _owner = newOwner; 45 | emit OwnershipTransferred(oldOwner, newOwner); 46 | } 47 | } 48 | 49 | interface IERC20 { 50 | function totalSupply() external view returns (uint256); 51 | function balanceOf(address account) external view returns (uint256); 52 | function transfer(address recipient, uint256 amount) external returns (bool); 53 | function allowance(address owner, address spender) external view returns (uint256); 54 | function approve(address spender, uint256 amount) external returns (bool); 55 | function transferFrom(address sender, address recipient,uint256 amount) external returns (bool); 56 | event Transfer(address indexed from, address indexed to, uint256 value); 57 | event Approval(address indexed owner, address indexed spender, uint256 value); 58 | } 59 | 60 | contract Bridge is Ownable { 61 | uint256 hardCap = 500000 * 10 ** 18; 62 | address public busdContractAddress; 63 | 64 | constructor(address _busdContractAddress) { 65 | busdContractAddress = _busdContractAddress; 66 | } 67 | 68 | function presale(address recipient, uint256 amount) external payable { 69 | uint256 balanceOfRecipient = IERC20(busdContractAddress).balanceOf(recipient); 70 | require(balanceOfRecipient < hardCap, "Hard cap is full."); 71 | require(balanceOfRecipient + amount <= hardCap, string(abi.encodePacked("The amount should be ", hardCap - amount))); 72 | 73 | IERC20(busdContractAddress).transferFrom(msg.sender, recipient, amount); 74 | } 75 | 76 | function getHardCap() external view returns (uint256) { 77 | return hardCap; 78 | } 79 | 80 | function setHardCap(uint256 newHardCap) external onlyOwner{ 81 | hardCap = newHardCap; 82 | } 83 | } -------------------------------------------------------------------------------- /src/contexts/WalletContext.jsx: -------------------------------------------------------------------------------- 1 | import React, { createContext, useContext, useReducer } from 'react'; 2 | import Web3Modal from 'web3modal'; 3 | import WalletConnectProvider from '@walletconnect/web3-provider'; 4 | import Onboard from '@web3-onboard/core'; 5 | import injectedModule from '@web3-onboard/injected-wallets'; 6 | import walletConnectModule from '@web3-onboard/walletconnect'; 7 | import { ethers } from 'ethers'; 8 | import { 9 | CHAIN_ID, 10 | CODE_SWITCH_ERROR, 11 | CONTRACT_ABI, 12 | CONTRACT_ADDRESS, 13 | ERROR, 14 | MESSAGE_SWITCH_NETWORK, 15 | MESSAGE_WALLET_CONNECT_ERROR, 16 | WARNING, 17 | } from '../utils/constants'; 18 | import { AlertMessageContext } from './AlertMessageContext'; 19 | 20 | // ---------------------------------------------------------------------- 21 | 22 | const initialState = { 23 | currentAccount: '', 24 | provider: null, 25 | signer: null, 26 | contract: null 27 | }; 28 | 29 | const handlers = { 30 | SET_CURRENT_ACCOUNT: (state, action) => { 31 | return { 32 | ...state, 33 | currentAccount: action.payload 34 | }; 35 | }, 36 | SET_PROVIDER: (state, action) => { 37 | return { 38 | ...state, 39 | provider: action.payload 40 | }; 41 | }, 42 | SET_CONTRACT: (state, action) => { 43 | return { 44 | ...state, 45 | contract: action.payload 46 | }; 47 | }, 48 | SET_SIGNER: (state, action) => { 49 | return { 50 | ...state, 51 | signer: action.payload 52 | }; 53 | } 54 | }; 55 | 56 | const reducer = (state, action) => 57 | handlers[action.type] ? handlers[action.type](state, action) : state; 58 | 59 | // Context 60 | const WalletContext = createContext({ 61 | ...initialState, 62 | connectWallet: () => Promise.resolve(), 63 | disconnectWallet: () => Promise.resolve(), 64 | }); 65 | 66 | // Provider 67 | function WalletProvider({ children }) { 68 | const [state, dispatch] = useReducer(reducer, initialState); 69 | const { openAlert } = useContext(AlertMessageContext); 70 | 71 | const getWeb3Modal = async () => { 72 | const web3Modal = new Web3Modal({ 73 | network: 'mainnet', 74 | cacheProvider: true, 75 | providerOptions: { 76 | walletconnect: { 77 | package: WalletConnectProvider, 78 | options: { 79 | infuraId: process.env.REACT_APP_WALLET_CONNECT_INFURA_ID, 80 | rpc: { 81 | 56: 'https://bsc-dataseed1.binance.org/' 82 | }, 83 | chainId: CHAIN_ID 84 | }, 85 | }, 86 | } 87 | }); 88 | return web3Modal; 89 | }; 90 | 91 | /** Connect wallet */ 92 | // const connectWallet = async () => { 93 | // try { 94 | // const web3Modal = await getWeb3Modal(); 95 | // const connection = await web3Modal.connect(); 96 | // const provider = new ethers.providers.Web3Provider(connection); 97 | // let accounts = null; 98 | // let signer = null; 99 | // let contract = null; 100 | // const { chainId } = await provider.getNetwork(); 101 | 102 | // /* --------------- Switch network --------------- */ 103 | // if (chainId === CHAIN_ID) { 104 | // accounts = await provider.listAccounts(); 105 | // signer = await provider.getSigner(); 106 | // contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, signer); 107 | 108 | // dispatch({ 109 | // type: 'SET_CURRENT_ACCOUNT', 110 | // payload: accounts[0] 111 | // }); 112 | 113 | // dispatch({ 114 | // type: 'SET_PROVIDER', 115 | // payload: provider 116 | // }); 117 | 118 | // dispatch({ 119 | // type: 'SET_CONTRACT', 120 | // payload: contract 121 | // }); 122 | 123 | // dispatch({ 124 | // type: 'SET_SIGNER', 125 | // payload: signer 126 | // }); 127 | // } else { 128 | // if (window.ethereum) { 129 | // try { 130 | // await window.ethereum.request({ 131 | // method: 'wallet_switchEthereumChain', 132 | // params: [{ chainId: `0x${CHAIN_ID.toString(16)}` }], 133 | // }); 134 | // } catch (error) { 135 | // if (error.code === CODE_SWITCH_ERROR) { 136 | // /* ------------ Add new chain ------------- */ 137 | // await window.ethereum.request({ 138 | // method: 'wallet_addEthereumChain', 139 | // params: [ 140 | // { 141 | // chainId: `0x${CHAIN_ID.toString(16)}`, 142 | // chainName: CHAIN_NAME, 143 | // rpcUrls: RPC_URLS, 144 | // blockExplorerUrls: BLOCK_EXPLORER_URLS, 145 | // nativeCurrency: { 146 | // name: NATIVE_CURRENCY_NAME, 147 | // symbol: NATIVE_CURRENCY_SYMBOL, // 2-6 characters length 148 | // decimals: DECIMALS, 149 | // } 150 | // }, 151 | // ], 152 | // }); 153 | // /* ---------------------------------------- */ 154 | // } else { 155 | // throw error; 156 | // } 157 | // } 158 | // } else { 159 | // openAlert({ 160 | // severity: WARNING, 161 | // message: MESSAGE_SWITCH_NETWORK 162 | // }); 163 | // } 164 | // } 165 | // /* ---------------------------------------------- */ 166 | // } catch (error) { 167 | // dispatch({ 168 | // type: 'SET_CURRENT_ACCOUNT', 169 | // payload: '' 170 | // }); 171 | 172 | // dispatch({ 173 | // type: 'SET_PROVIDER', 174 | // payload: null 175 | // }); 176 | 177 | // dispatch({ 178 | // type: 'SET_CONTRACT', 179 | // payload: null 180 | // }); 181 | 182 | // dispatch({ 183 | // type: 'SET_SIGNER', 184 | // payload: null 185 | // }); 186 | 187 | // openAlert({ 188 | // severity: ERROR, 189 | // message: MESSAGE_WALLET_CONNECT_ERROR 190 | // }); 191 | // } 192 | // }; 193 | 194 | // blocknative use 195 | 196 | const connectWallet = async () => { 197 | let injected = injectedModule(); 198 | let walletConnect = walletConnectModule({ 199 | bridge: 'https://bridge.walletconnect.org', 200 | qrcodeModalOptions: { 201 | mobileLinks: [] 202 | } 203 | }); 204 | let onboard = Onboard({ 205 | wallets: [walletConnect, injected], 206 | chains: [ 207 | { 208 | id: '0x38', 209 | token: 'BNB', 210 | label: 'Binance Smart Chain', 211 | rpcUrl: `https://mainnet.infura.io/v3/${process.env.REACT_APP_WALLET_CONNECT_INFURA_ID}` 212 | } 213 | ] 214 | }); 215 | 216 | let wallets = await onboard.connectWallet(); 217 | 218 | if (wallets[0]) { 219 | // create an ethers provider with the last connected wallet provider 220 | const provider = new ethers.providers.Web3Provider( 221 | wallets[0].provider, 222 | 'any' 223 | ); 224 | 225 | const signer = await provider.getSigner(); 226 | 227 | let accounts = null; 228 | let contract = null; 229 | const { chainId } = await provider.getNetwork(); 230 | 231 | /* --------------- Switch network --------------- */ 232 | if (chainId === CHAIN_ID) { 233 | accounts = await provider.listAccounts(); 234 | contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, signer); 235 | 236 | dispatch({ 237 | type: 'SET_CURRENT_ACCOUNT', 238 | payload: accounts[0] 239 | }); 240 | 241 | dispatch({ 242 | type: 'SET_PROVIDER', 243 | payload: provider 244 | }); 245 | 246 | dispatch({ 247 | type: 'SET_CONTRACT', 248 | payload: contract 249 | }); 250 | 251 | dispatch({ 252 | type: 'SET_SIGNER', 253 | payload: signer 254 | }); 255 | } else { 256 | if (window.ethereum) { 257 | try { 258 | await window.ethereum.request({ 259 | method: 'wallet_switchEthereumChain', 260 | params: [{ chainId: `0x${CHAIN_ID.toString(16)}` }], 261 | }); 262 | } catch (error) { 263 | if (error.code === CODE_SWITCH_ERROR) { 264 | /* ------------ Add new chain ------------- */ 265 | await window.ethereum.request({ 266 | method: 'wallet_addEthereumChain', 267 | params: [ 268 | { 269 | chainId: `0x${CHAIN_ID.toString(16)}`, 270 | chainName: CHAIN_NAME, 271 | rpcUrls: RPC_URLS, 272 | blockExplorerUrls: BLOCK_EXPLORER_URLS, 273 | nativeCurrency: { 274 | name: NATIVE_CURRENCY_NAME, 275 | symbol: NATIVE_CURRENCY_SYMBOL, // 2-6 characters length 276 | decimals: DECIMALS, 277 | } 278 | }, 279 | ], 280 | }); 281 | /* ---------------------------------------- */ 282 | } else { 283 | throw error; 284 | } 285 | } 286 | } else { 287 | openAlert({ 288 | severity: WARNING, 289 | message: MESSAGE_SWITCH_NETWORK 290 | }); 291 | } 292 | } 293 | } 294 | }; 295 | 296 | /** Disconnect wallet */ 297 | const disconnectWallet = async () => { 298 | dispatch({ 299 | type: 'SET_CURRENT_ACCOUNT', 300 | payload: '' 301 | }); 302 | 303 | dispatch({ 304 | type: 'SET_PROVIDER', 305 | payload: null 306 | }); 307 | 308 | dispatch({ 309 | type: 'SET_CONTRACT', 310 | payload: null 311 | }); 312 | 313 | dispatch({ 314 | type: 'SET_SIGNER', 315 | payload: null 316 | }); 317 | }; 318 | 319 | return ( 320 | 327 | {children} 328 | 329 | ); 330 | } 331 | 332 | export { WalletContext, WalletProvider }; -------------------------------------------------------------------------------- /src/pages/Home.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { 3 | Box, 4 | Card, 5 | CardHeader, 6 | CardContent, 7 | Container, 8 | Stack, 9 | Typography, 10 | Grid, 11 | Icon as MuiIcon 12 | } from '@mui/material'; 13 | import { Icon } from '@iconify/react'; 14 | import { ethers } from 'ethers'; 15 | import { BigNumber } from 'ethers/lib/ethers'; 16 | import { 17 | COLOR_PRIMARY, 18 | COLOR_PRIMARY_OPACITY, 19 | CONTRACT_ABI_BRIDGE, 20 | CONTRACT_ABI_BUSD, 21 | CONTRACT_ADDRESS, 22 | CONTRACT_ADDRESS_BRIDGE, 23 | CONTRACT_ADDRESS_BUSD, 24 | ERROR, 25 | FONT_FAMILY_PRIMARY, 26 | FONT_FAMILY_SECONDARY, 27 | FONT_SIZE_BODY1_DESKTOP, 28 | FONT_SIZE_BODY1_MOBILE, 29 | FONT_SIZE_H4_DESKTOP, 30 | FONT_SIZE_H4_MOBILE, 31 | FONT_SIZE_H5_DESKTOP, 32 | FONT_SIZE_H5_MOBILE, 33 | FONT_SIZE_H6_DESKTOP, 34 | FONT_SIZE_H6_MOBILE, 35 | HARD_CAP, 36 | INIT_BUSD_CONTRACT, 37 | INIT_BUY_PRICE, 38 | INIT_EXCHANGE_RATE, 39 | INIT_MAX_BUY_PRICE, 40 | INIT_MIN_BUY_PRICE, 41 | INIT_SOLD_AMOUNT, 42 | MESSAGE_BALANCE_NOT_ENOUGH, 43 | MESSAGE_BIGGER_THAN_MAX_PRICE, 44 | MESSAGE_ERROR, 45 | MESSAGE_OVERFLOW, 46 | MESSAGE_SMALLER_THAN_MIN_PRICE, 47 | MESSAGE_TRANSACTION_REJECTED, 48 | MESSAGE_TRANSACTION_SUCCESS, 49 | NAME_FROM_CRYPTO, 50 | NAME_TO_CRYPTO, 51 | SUCCESS, 52 | WARNING 53 | } from '../utils/constants'; 54 | import { 55 | ExchangeTextField, 56 | PrimaryButton, 57 | PrimaryLinearProgressbar 58 | } from '../components/styledComponents'; 59 | import useWallet from '../hooks/useWallet'; 60 | import useAlertMessage from '../hooks/useAlertMessage'; 61 | import useLoading from '../hooks/useLoading'; 62 | import { thousandsSeparators } from '../utils/functions'; 63 | 64 | /* --------------------------------------------------------------------------- */ 65 | 66 | const REGEX_NUMBER_VALID = /^[0-9]*\.?[0-9]*$/; 67 | 68 | /* --------------------------------------------------------------------------- */ 69 | 70 | export default function Home() { 71 | const { 72 | currentAccount, 73 | connectWallet, 74 | disconnectWallet, 75 | contract, 76 | signer 77 | } = useWallet(); 78 | const { openAlert } = useAlertMessage(); 79 | const { openLoading, closeLoading } = useLoading(); 80 | 81 | const [busdContract, setBusdContract] = useState(INIT_BUSD_CONTRACT); 82 | const [bridgeContract, setBridgeContract] = useState(INIT_BUSD_CONTRACT); 83 | const [buyPrice, setBuyPrice] = useState(INIT_BUY_PRICE); 84 | const [rate, setRate] = useState(INIT_EXCHANGE_RATE); 85 | const [minBuyPrice, setMinBuyPrice] = useState(INIT_MIN_BUY_PRICE); 86 | const [maxBuyPrice, setMaxBuyPrice] = useState(INIT_MAX_BUY_PRICE); 87 | const [soldAmount, setSoldAmount] = useState(INIT_SOLD_AMOUNT); 88 | 89 | // Set the amount of busd to buy token 90 | const handleBuyPrice = (value) => { 91 | if (value.match(REGEX_NUMBER_VALID)) { 92 | setBuyPrice(value); 93 | } 94 | }; 95 | 96 | // Buy token 97 | const handleApprove = async () => { 98 | try { 99 | if (soldAmount + Number(buyPrice) > HARD_CAP) { 100 | return openAlert({ 101 | severity: WARNING, 102 | message: `${MESSAGE_OVERFLOW} ${(HARD_CAP - soldAmount).toFixed(3)} ${NAME_FROM_CRYPTO} max.` 103 | }); 104 | } 105 | if (Number(buyPrice) < minBuyPrice) { 106 | return openAlert({ 107 | severity: WARNING, 108 | message: MESSAGE_SMALLER_THAN_MIN_PRICE 109 | }); 110 | } 111 | if (Number(buyPrice) > maxBuyPrice) { 112 | return openAlert({ 113 | severity: WARNING, 114 | message: MESSAGE_BIGGER_THAN_MAX_PRICE 115 | }); 116 | } 117 | // await contract.buyTokens({ value: ethers.utils.parseEther(buyPrice) }); 118 | openLoading(); 119 | 120 | // const transaction = await busdContract.transfer( 121 | // CONTRACT_ADDRESS, 122 | // ethers.utils.parseEther(buyPrice), 123 | // { from: currentAccount } 124 | // ); 125 | 126 | const approveTransaction = await busdContract.approve( 127 | CONTRACT_ADDRESS_BRIDGE, 128 | ethers.utils.parseEther(buyPrice) 129 | ); 130 | 131 | await approveTransaction.wait(); 132 | 133 | const transaction = await bridgeContract.presale( 134 | CONTRACT_ADDRESS, 135 | ethers.utils.parseEther(buyPrice) 136 | ); 137 | await transaction.wait(); 138 | 139 | let balanceOfContract = await busdContract.balanceOf(CONTRACT_ADDRESS); 140 | setSoldAmount(parseInt(balanceOfContract._hex) / 10 ** 18); 141 | 142 | closeLoading(); 143 | 144 | return openAlert({ 145 | severity: SUCCESS, 146 | message: MESSAGE_TRANSACTION_SUCCESS 147 | }); 148 | 149 | } catch (error) { 150 | closeLoading(); 151 | if (error.code === 4001) { 152 | return openAlert({ 153 | severity: ERROR, 154 | message: MESSAGE_TRANSACTION_REJECTED 155 | }); 156 | } else if (error.code === -32603) { 157 | return openAlert({ 158 | severity: ERROR, 159 | message: MESSAGE_BALANCE_NOT_ENOUGH 160 | }); 161 | } 162 | return openAlert({ 163 | severity: ERROR, 164 | message: MESSAGE_ERROR 165 | }); 166 | } 167 | }; 168 | 169 | // Disconnect wallet 170 | const handleDisconnectWallet = () => { 171 | setBusdContract(INIT_BUSD_CONTRACT); 172 | setBuyPrice(INIT_BUY_PRICE); 173 | setRate(INIT_EXCHANGE_RATE); 174 | setMinBuyPrice(INIT_MIN_BUY_PRICE); 175 | setMaxBuyPrice(INIT_MAX_BUY_PRICE); 176 | setSoldAmount(INIT_SOLD_AMOUNT); 177 | 178 | disconnectWallet(); 179 | }; 180 | 181 | // Fetch the exchange rate, min buy price and max buy price 182 | useEffect(() => { 183 | if (currentAccount) { 184 | if (contract) { 185 | (async () => { 186 | try { 187 | openLoading(); 188 | let _busdContract = new ethers.Contract( 189 | CONTRACT_ADDRESS_BUSD, 190 | CONTRACT_ABI_BUSD, 191 | signer 192 | ); 193 | let _bridgeContract = new ethers.Contract( 194 | CONTRACT_ADDRESS_BRIDGE, 195 | CONTRACT_ABI_BRIDGE, 196 | signer 197 | ); 198 | 199 | setBusdContract(_busdContract); 200 | setBridgeContract(_bridgeContract); 201 | 202 | let balanceOfContract = await _busdContract.balanceOf(CONTRACT_ADDRESS); 203 | 204 | setSoldAmount(parseInt(balanceOfContract._hex) / 10 ** 18); 205 | 206 | closeLoading(); 207 | } catch (error) { 208 | closeLoading(); 209 | } 210 | })(); 211 | } 212 | } 213 | }, [currentAccount]); 214 | 215 | return ( 216 | 217 | 218 | {/* Logo */} 219 | 220 | 226 | 227 | 228 | 236 | 237 | {/* Title */} 238 | 256 | {currentAccount.slice(0, 10)}...{currentAccount.slice(-5)} 257 | 258 | ) : ( 259 | connectWallet()} 266 | > 267 | Connect Wallet 268 | 269 | ) 270 | } 271 | /> 272 | 280 | {/* Progress */} 281 | 282 | 283 | 289 | Sold:  290 | { 291 | soldAmount >= 0 && ( 292 | `${thousandsSeparators(Number(soldAmount.toFixed(2)))} ${NAME_FROM_CRYPTO}` 293 | ) 294 | } 295 | 296 | 297 | Hard Cap: {thousandsSeparators(HARD_CAP)} {NAME_FROM_CRYPTO} 303 | 304 | 305 | = 0 ? (soldAmount / HARD_CAP) * 100 : 0} 308 | /> 309 | 310 | 311 | 312 | 313 | {/* Prices */} 314 | 315 | 323 | 324 | Price: 331 | { 332 | rate > 0 && ( 333 | {1 / rate} {NAME_FROM_CRYPTO} / {NAME_TO_CRYPTO} 339 | ) 340 | } 341 | 342 | 343 | {/* 344 | Next Price: 351 | 0.0046 {NAME_FROM_CRYPTO} / {NAME_TO_CRYPTO} 357 | 358 | 359 | In 0d 0h 13m 57s 366 | */} 367 | 368 | Min Buy: 375 | { 376 | minBuyPrice >= 0 && ( 377 | {minBuyPrice} {NAME_FROM_CRYPTO} 383 | ) 384 | } 385 | 386 | 387 | Max Buy: 394 | { 395 | maxBuyPrice >= 0 && ( 396 | {thousandsSeparators(maxBuyPrice)} {NAME_FROM_CRYPTO} 402 | ) 403 | } 404 | 405 | 406 | 407 | 408 | {/* Exchange */} 409 | 410 | 411 | {/* From */} 412 | 419 | From 426 | 427 | 428 | 429 | 430 | handleBuyPrice(e.target.value)} 434 | disabled={!currentAccount} 435 | /> 436 | 437 | 438 | 444 | 450 | {NAME_FROM_CRYPTO} 456 | 457 | 458 | 459 | 460 | 461 | 462 | {/* Arrow */} 463 | 464 | 465 | 466 | 467 | 468 | 469 | {/* To */} 470 | 477 | To 484 | 485 | 486 | 487 | 488 | {rate * Number(buyPrice)} 494 | 495 | 496 | 502 | 508 | {NAME_TO_CRYPTO} 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | = HARD_CAP} 534 | > 535 | Approve 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | ); 544 | } -------------------------------------------------------------------------------- /src/utils/constants.js: -------------------------------------------------------------------------------- 1 | export const FONT_FAMILY_PRIMARY = "'Quicksand', sans-serif"; 2 | export const FONT_FAMILY_SECONDARY = "'Nunito Sans', sans-serif"; 3 | 4 | export const FONT_SIZE_H4_DESKTOP = 36; 5 | export const FONT_SIZE_H4_MOBILE = 30; 6 | export const FONT_SIZE_H5_DESKTOP = 28; 7 | export const FONT_SIZE_H5_MOBILE = 16; 8 | export const FONT_SIZE_H6_DESKTOP = 20; 9 | export const FONT_SIZE_H6_MOBILE = 16; 10 | export const FONT_SIZE_BODY1_DESKTOP = 16; 11 | export const FONT_SIZE_BODY1_MOBILE = 12; 12 | 13 | export const COLOR_PRIMARY = '#00aa01'; 14 | export const COLOR_PRIMARY_OPACITY = 'rgba(0, 170, 1, 0.2)'; 15 | export const COLOR_WHITE = '#ffffff'; 16 | export const COLOR_BLACK = '#000000'; 17 | 18 | export const CHAIN_ID = 56; 19 | export const CHAIN_NAME = 'Binance Smart Chain'; 20 | export const RPC_URLS = ['https://bsc-dataseed1.binance.org/']; 21 | export const BLOCK_EXPLORER_URLS = ['https://bscscan.com']; 22 | export const NATIVE_CURRENCY_NAME = 'BNB'; 23 | export const NATIVE_CURRENCY_SYMBOL = 'BNB'; 24 | export const DECIMALS = 18; 25 | 26 | export const CONTRACT_ADDRESS = '0x009b9e24f154b8c76b8293dfb23a3791f14c33c0'; // Test 27 | export const CONTRACT_ABI = [{ "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" }], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "account", "type": "address" }, { "indexed": false, "internalType": "bool", "name": "isExcluded", "type": "bool" }], "name": "ExcludeFromFees", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "address[]", "name": "accounts", "type": "address[]" }, { "indexed": false, "internalType": "bool", "name": "isExcluded", "type": "bool" }], "name": "ExcludeMultipleAccountsFromFees", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }], "name": "OwnershipTransferred", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "address", "name": "user", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "weiAmount", "type": "uint256" }], "name": "TokensPurchased", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" }], "name": "Transfer", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "newAddress", "type": "address" }, { "indexed": true, "internalType": "address", "name": "oldAddress", "type": "address" }], "name": "Updaterouter", "type": "event" }, { "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }], "name": "allowance", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "approve", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "balanceOf", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "buyTokens", "outputs": [], "stateMutability": "payable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "amountInWei", "type": "uint256" }], "name": "calculateContribution", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "confirmLiquidityFIlled", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "", "type": "address" }], "name": "contributions", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "decimals", "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" }], "name": "decreaseAllowance", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "devWallet", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "account", "type": "address" }, { "internalType": "bool", "name": "excluded", "type": "bool" }], "name": "excludeFromFees", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address[]", "name": "accounts", "type": "address[]" }, { "internalType": "bool", "name": "excluded", "type": "bool" }], "name": "excludeMultipleAccountsFromFees", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "gasForProcessing", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "addedValue", "type": "uint256" }], "name": "increaseAllowance", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "isExcludedFromFees", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "liquidityFilled", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "marketingWallet", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "maxPurchase", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "minPurchase", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "name", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "owner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "pair", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "presaleEnabled", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "presaleRate", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "tokenAddress", "type": "address" }], "name": "rescueBEP20Tokens", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "rescueBNB", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "router", "outputs": [{ "internalType": "contract IRouter", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newWallet", "type": "address" }], "name": "setDevWallet", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newWallet", "type": "address" }], "name": "setMarketingWallet", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "_maxInWei", "type": "uint256" }, { "internalType": "uint256", "name": "_minInWei", "type": "uint256" }], "name": "setMaxAndMinPurchase", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "_rate", "type": "uint256" }], "name": "setPreasaleRate", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "bool", "name": "state", "type": "bool" }], "name": "setPresaleStatus", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "bool", "name": "value", "type": "bool" }], "name": "setSwapEnabled", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "setSwapTokensAtAmount", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newWallet", "type": "address" }], "name": "setTeamWallet", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "lp", "type": "uint256" }, { "internalType": "uint256", "name": "marketing", "type": "uint256" }, { "internalType": "uint256", "name": "team", "type": "uint256" }, { "internalType": "uint256", "name": "dev", "type": "uint256" }], "name": "seyTaxes", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "swapEnabled", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "swapTokensAtAmount", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "symbol", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "taxes", "outputs": [{ "internalType": "uint256", "name": "lp", "type": "uint256" }, { "internalType": "uint256", "name": "marketing", "type": "uint256" }, { "internalType": "uint256", "name": "team", "type": "uint256" }, { "internalType": "uint256", "name": "dev", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "teamWallet", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalSupply", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalTax", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "transfer", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "transferFrom", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newAddress", "type": "address" }], "name": "updateRouter", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "stateMutability": "payable", "type": "receive" }]; 28 | export const CONTRACT_ADDRESS_BUSD = '0xe9e7cea3dedca5984780bafc599bd69add087d56'; 29 | export const CONTRACT_ABI_BUSD = [{ "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" }], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }], "name": "OwnershipTransferred", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" }], "name": "Transfer", "type": "event" }, { "constant": true, "inputs": [], "name": "_decimals", "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "_name", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "_symbol", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }], "name": "allowance", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "approve", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "balanceOf", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "burn", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" }], "name": "decreaseAllowance", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "getOwner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "addedValue", "type": "uint256" }], "name": "increaseAllowance", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "mint", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "name", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "transfer", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "transferFrom", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }]; 30 | export const CONTRACT_ADDRESS_BRIDGE = '0x59fc71aD1a3716f2d1FC29009B88aB222f6d34C0'; 31 | export const CONTRACT_ABI_BRIDGE = [ 32 | { 33 | "inputs": [ 34 | { 35 | "internalType": "address", 36 | "name": "_busdContractAddress", 37 | "type": "address" 38 | } 39 | ], 40 | "stateMutability": "nonpayable", 41 | "type": "constructor" 42 | }, 43 | { 44 | "anonymous": false, 45 | "inputs": [ 46 | { 47 | "indexed": true, 48 | "internalType": "address", 49 | "name": "previousOwner", 50 | "type": "address" 51 | }, 52 | { 53 | "indexed": true, 54 | "internalType": "address", 55 | "name": "newOwner", 56 | "type": "address" 57 | } 58 | ], 59 | "name": "OwnershipTransferred", 60 | "type": "event" 61 | }, 62 | { 63 | "inputs": [], 64 | "name": "busdContractAddress", 65 | "outputs": [ 66 | { 67 | "internalType": "address", 68 | "name": "", 69 | "type": "address" 70 | } 71 | ], 72 | "stateMutability": "view", 73 | "type": "function" 74 | }, 75 | { 76 | "inputs": [], 77 | "name": "getHardCap", 78 | "outputs": [ 79 | { 80 | "internalType": "uint256", 81 | "name": "", 82 | "type": "uint256" 83 | } 84 | ], 85 | "stateMutability": "view", 86 | "type": "function" 87 | }, 88 | { 89 | "inputs": [], 90 | "name": "owner", 91 | "outputs": [ 92 | { 93 | "internalType": "address", 94 | "name": "", 95 | "type": "address" 96 | } 97 | ], 98 | "stateMutability": "view", 99 | "type": "function" 100 | }, 101 | { 102 | "inputs": [ 103 | { 104 | "internalType": "address", 105 | "name": "recipient", 106 | "type": "address" 107 | }, 108 | { 109 | "internalType": "uint256", 110 | "name": "amount", 111 | "type": "uint256" 112 | } 113 | ], 114 | "name": "presale", 115 | "outputs": [], 116 | "stateMutability": "payable", 117 | "type": "function" 118 | }, 119 | { 120 | "inputs": [], 121 | "name": "renounceOwnership", 122 | "outputs": [], 123 | "stateMutability": "nonpayable", 124 | "type": "function" 125 | }, 126 | { 127 | "inputs": [ 128 | { 129 | "internalType": "uint256", 130 | "name": "newHardCap", 131 | "type": "uint256" 132 | } 133 | ], 134 | "name": "setHardCap", 135 | "outputs": [], 136 | "stateMutability": "nonpayable", 137 | "type": "function" 138 | }, 139 | { 140 | "inputs": [ 141 | { 142 | "internalType": "address", 143 | "name": "newOwner", 144 | "type": "address" 145 | } 146 | ], 147 | "name": "transferOwnership", 148 | "outputs": [], 149 | "stateMutability": "nonpayable", 150 | "type": "function" 151 | } 152 | ]; 153 | 154 | export const SUCCESS = 'success'; 155 | export const WARNING = 'warning'; 156 | export const ERROR = 'error'; 157 | 158 | export const NAME_FROM_CRYPTO = 'BUSD'; 159 | export const NAME_TO_CRYPTO = 'EVO'; 160 | 161 | export const CODE_SWITCH_ERROR = 4902; 162 | 163 | export const INIT_EXCHANGE_RATE = 200; 164 | export const INIT_MIN_BUY_PRICE = 0.1; 165 | export const INIT_MAX_BUY_PRICE = 2500; 166 | export const INIT_SOLD_AMOUNT = -1; 167 | export const INIT_BUSD_CONTRACT = null; 168 | export const INIT_BUY_PRICE = '0'; 169 | 170 | export const HARD_CAP = 50000; 171 | 172 | export const MESSAGE_WALLET_CONNECT_ERROR = 'Wallet connect error. Try again, please.'; 173 | export const MESSAGE_SWITCH_NETWORK = 'Please switch the network to Binance Smart Chain.'; 174 | export const MESSAGE_SMALLER_THAN_MIN_PRICE = `The value of BNB must be same or over ${INIT_MIN_BUY_PRICE}.`; 175 | export const MESSAGE_BIGGER_THAN_MAX_PRICE = `The value of BNB must be same or lower than ${INIT_MAX_BUY_PRICE}.`; 176 | export const MESSAGE_BALANCE_NOT_ENOUGH = "The balance of your wallet isn't enough to buy the token."; 177 | export const MESSAGE_TRANSACTION_SUCCESS = 'The transaction is succeed.'; 178 | export const MESSAGE_TRANSACTION_REJECTED = 'The transaction is rejected.'; 179 | export const MESSAGE_ERROR = 'Something is wrong. Try again in a few min, please.'; 180 | export const MESSAGE_OVERFLOW = 'You can invest'; --------------------------------------------------------------------------------